[libata] sata_mv: remove extra braces
[linux-2.6/x86.git] / drivers / scsi / BusLogic.c
blobe874b8944875c77cb1d41df5004fbfa5eae08e9f
2 /*
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
15 for complete details.
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/module.h>
33 #include <linux/init.h>
34 #include <linux/interrupt.h>
35 #include <linux/types.h>
36 #include <linux/blkdev.h>
37 #include <linux/delay.h>
38 #include <linux/ioport.h>
39 #include <linux/mm.h>
40 #include <linux/stat.h>
41 #include <linux/pci.h>
42 #include <linux/spinlock.h>
43 #include <linux/jiffies.h>
44 #include <linux/dma-mapping.h>
45 #include <scsi/scsicam.h>
47 #include <asm/dma.h>
48 #include <asm/io.h>
49 #include <asm/system.h>
51 #include <scsi/scsi.h>
52 #include <scsi/scsi_cmnd.h>
53 #include <scsi/scsi_device.h>
54 #include <scsi/scsi_host.h>
55 #include <scsi/scsi_tcq.h>
56 #include "BusLogic.h"
57 #include "FlashPoint.c"
59 #ifndef FAILURE
60 #define FAILURE (-1)
61 #endif
63 static struct scsi_host_template Bus_Logic_template;
66 BusLogic_DriverOptionsCount is a count of the number of BusLogic Driver
67 Options specifications provided via the Linux Kernel Command Line or via
68 the Loadable Kernel Module Installation Facility.
71 static int BusLogic_DriverOptionsCount;
75 BusLogic_DriverOptions is an array of Driver Options structures representing
76 BusLogic Driver Options specifications provided via the Linux Kernel Command
77 Line or via the Loadable Kernel Module Installation Facility.
80 static struct BusLogic_DriverOptions BusLogic_DriverOptions[BusLogic_MaxHostAdapters];
84 BusLogic can be assigned a string by insmod.
87 MODULE_LICENSE("GPL");
88 #ifdef MODULE
89 static char *BusLogic;
90 module_param(BusLogic, charp, 0);
91 #endif
95 BusLogic_ProbeOptions is a set of Probe Options to be applied across
96 all BusLogic Host Adapters.
99 static struct BusLogic_ProbeOptions BusLogic_ProbeOptions;
103 BusLogic_GlobalOptions is a set of Global Options to be applied across
104 all BusLogic Host Adapters.
107 static struct BusLogic_GlobalOptions BusLogic_GlobalOptions;
109 static LIST_HEAD(BusLogic_host_list);
112 BusLogic_ProbeInfoCount is the number of entries in BusLogic_ProbeInfoList.
115 static int BusLogic_ProbeInfoCount;
119 BusLogic_ProbeInfoList is the list of I/O Addresses and Bus Probe Information
120 to be checked for potential BusLogic Host Adapters. It is initialized by
121 interrogating the PCI Configuration Space on PCI machines as well as from the
122 list of standard BusLogic I/O Addresses.
125 static struct BusLogic_ProbeInfo *BusLogic_ProbeInfoList;
129 BusLogic_CommandFailureReason holds a string identifying the reason why a
130 call to BusLogic_Command failed. It is only non-NULL when BusLogic_Command
131 returns a failure code.
134 static char *BusLogic_CommandFailureReason;
137 BusLogic_AnnounceDriver announces the Driver Version and Date, Author's
138 Name, Copyright Notice, and Electronic Mail Address.
141 static void BusLogic_AnnounceDriver(struct BusLogic_HostAdapter *HostAdapter)
143 BusLogic_Announce("***** BusLogic SCSI Driver Version " BusLogic_DriverVersion " of " BusLogic_DriverDate " *****\n", HostAdapter);
144 BusLogic_Announce("Copyright 1995-1998 by Leonard N. Zubkoff " "<lnz@dandelion.com>\n", HostAdapter);
149 BusLogic_DriverInfo returns the Host Adapter Name to identify this SCSI
150 Driver and Host Adapter.
153 static const char *BusLogic_DriverInfo(struct Scsi_Host *Host)
155 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata;
156 return HostAdapter->FullModelName;
160 BusLogic_InitializeCCBs initializes a group of Command Control Blocks (CCBs)
161 for Host Adapter from the BlockSize bytes located at BlockPointer. The newly
162 created CCBs are added to Host Adapter's free list.
165 static void BusLogic_InitializeCCBs(struct BusLogic_HostAdapter *HostAdapter, void *BlockPointer, int BlockSize, dma_addr_t BlockPointerHandle)
167 struct BusLogic_CCB *CCB = (struct BusLogic_CCB *) BlockPointer;
168 unsigned int offset = 0;
169 memset(BlockPointer, 0, BlockSize);
170 CCB->AllocationGroupHead = BlockPointerHandle;
171 CCB->AllocationGroupSize = BlockSize;
172 while ((BlockSize -= sizeof(struct BusLogic_CCB)) >= 0) {
173 CCB->Status = BusLogic_CCB_Free;
174 CCB->HostAdapter = HostAdapter;
175 CCB->DMA_Handle = (u32) BlockPointerHandle + offset;
176 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
177 CCB->CallbackFunction = BusLogic_QueueCompletedCCB;
178 CCB->BaseAddress = HostAdapter->FlashPointInfo.BaseAddress;
180 CCB->Next = HostAdapter->Free_CCBs;
181 CCB->NextAll = HostAdapter->All_CCBs;
182 HostAdapter->Free_CCBs = CCB;
183 HostAdapter->All_CCBs = CCB;
184 HostAdapter->AllocatedCCBs++;
185 CCB++;
186 offset += sizeof(struct BusLogic_CCB);
192 BusLogic_CreateInitialCCBs allocates the initial CCBs for Host Adapter.
195 static bool __init BusLogic_CreateInitialCCBs(struct BusLogic_HostAdapter *HostAdapter)
197 int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB);
198 void *BlockPointer;
199 dma_addr_t BlockPointerHandle;
200 while (HostAdapter->AllocatedCCBs < HostAdapter->InitialCCBs) {
201 BlockPointer = pci_alloc_consistent(HostAdapter->PCI_Device, BlockSize, &BlockPointerHandle);
202 if (BlockPointer == NULL) {
203 BusLogic_Error("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n", HostAdapter);
204 return false;
206 BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize, BlockPointerHandle);
208 return true;
213 BusLogic_DestroyCCBs deallocates the CCBs for Host Adapter.
216 static void BusLogic_DestroyCCBs(struct BusLogic_HostAdapter *HostAdapter)
218 struct BusLogic_CCB *NextCCB = HostAdapter->All_CCBs, *CCB, *Last_CCB = NULL;
219 HostAdapter->All_CCBs = NULL;
220 HostAdapter->Free_CCBs = NULL;
221 while ((CCB = NextCCB) != NULL) {
222 NextCCB = CCB->NextAll;
223 if (CCB->AllocationGroupHead) {
224 if (Last_CCB)
225 pci_free_consistent(HostAdapter->PCI_Device, Last_CCB->AllocationGroupSize, Last_CCB, Last_CCB->AllocationGroupHead);
226 Last_CCB = CCB;
229 if (Last_CCB)
230 pci_free_consistent(HostAdapter->PCI_Device, Last_CCB->AllocationGroupSize, Last_CCB, Last_CCB->AllocationGroupHead);
235 BusLogic_CreateAdditionalCCBs allocates Additional CCBs for Host Adapter. If
236 allocation fails and there are no remaining CCBs available, the Driver Queue
237 Depth is decreased to a known safe value to avoid potential deadlocks when
238 multiple host adapters share the same IRQ Channel.
241 static void BusLogic_CreateAdditionalCCBs(struct BusLogic_HostAdapter *HostAdapter, int AdditionalCCBs, bool SuccessMessageP)
243 int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB);
244 int PreviouslyAllocated = HostAdapter->AllocatedCCBs;
245 void *BlockPointer;
246 dma_addr_t BlockPointerHandle;
247 if (AdditionalCCBs <= 0)
248 return;
249 while (HostAdapter->AllocatedCCBs - PreviouslyAllocated < AdditionalCCBs) {
250 BlockPointer = pci_alloc_consistent(HostAdapter->PCI_Device, BlockSize, &BlockPointerHandle);
251 if (BlockPointer == NULL)
252 break;
253 BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize, BlockPointerHandle);
255 if (HostAdapter->AllocatedCCBs > PreviouslyAllocated) {
256 if (SuccessMessageP)
257 BusLogic_Notice("Allocated %d additional CCBs (total now %d)\n", HostAdapter, HostAdapter->AllocatedCCBs - PreviouslyAllocated, HostAdapter->AllocatedCCBs);
258 return;
260 BusLogic_Notice("Failed to allocate additional CCBs\n", HostAdapter);
261 if (HostAdapter->DriverQueueDepth > HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount) {
262 HostAdapter->DriverQueueDepth = HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount;
263 HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth;
268 BusLogic_AllocateCCB allocates a CCB from Host Adapter's free list,
269 allocating more memory from the Kernel if necessary. The Host Adapter's
270 Lock should already have been acquired by the caller.
273 static struct BusLogic_CCB *BusLogic_AllocateCCB(struct BusLogic_HostAdapter
274 *HostAdapter)
276 static unsigned long SerialNumber = 0;
277 struct BusLogic_CCB *CCB;
278 CCB = HostAdapter->Free_CCBs;
279 if (CCB != NULL) {
280 CCB->SerialNumber = ++SerialNumber;
281 HostAdapter->Free_CCBs = CCB->Next;
282 CCB->Next = NULL;
283 if (HostAdapter->Free_CCBs == NULL)
284 BusLogic_CreateAdditionalCCBs(HostAdapter, HostAdapter->IncrementalCCBs, true);
285 return CCB;
287 BusLogic_CreateAdditionalCCBs(HostAdapter, HostAdapter->IncrementalCCBs, true);
288 CCB = HostAdapter->Free_CCBs;
289 if (CCB == NULL)
290 return NULL;
291 CCB->SerialNumber = ++SerialNumber;
292 HostAdapter->Free_CCBs = CCB->Next;
293 CCB->Next = NULL;
294 return CCB;
299 BusLogic_DeallocateCCB deallocates a CCB, returning it to the Host Adapter's
300 free list. The Host Adapter's Lock should already have been acquired by the
301 caller.
304 static void BusLogic_DeallocateCCB(struct BusLogic_CCB *CCB)
306 struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter;
307 struct scsi_cmnd *cmd = CCB->Command;
309 if (cmd->use_sg != 0) {
310 pci_unmap_sg(HostAdapter->PCI_Device,
311 (struct scatterlist *)cmd->request_buffer,
312 cmd->use_sg, cmd->sc_data_direction);
313 } else if (cmd->request_bufflen != 0) {
314 pci_unmap_single(HostAdapter->PCI_Device, CCB->DataPointer,
315 CCB->DataLength, cmd->sc_data_direction);
317 pci_unmap_single(HostAdapter->PCI_Device, CCB->SenseDataPointer,
318 CCB->SenseDataLength, PCI_DMA_FROMDEVICE);
320 CCB->Command = NULL;
321 CCB->Status = BusLogic_CCB_Free;
322 CCB->Next = HostAdapter->Free_CCBs;
323 HostAdapter->Free_CCBs = CCB;
328 BusLogic_Command sends the command OperationCode to HostAdapter, optionally
329 providing ParameterLength bytes of ParameterData and receiving at most
330 ReplyLength bytes of ReplyData; any excess reply data is received but
331 discarded.
333 On success, this function returns the number of reply bytes read from
334 the Host Adapter (including any discarded data); on failure, it returns
335 -1 if the command was invalid, or -2 if a timeout occurred.
337 BusLogic_Command is called exclusively during host adapter detection and
338 initialization, so performance and latency are not critical, and exclusive
339 access to the Host Adapter hardware is assumed. Once the host adapter and
340 driver are initialized, the only Host Adapter command that is issued is the
341 single byte Execute Mailbox Command operation code, which does not require
342 waiting for the Host Adapter Ready bit to be set in the Status Register.
345 static int BusLogic_Command(struct BusLogic_HostAdapter *HostAdapter, enum BusLogic_OperationCode OperationCode, void *ParameterData, int ParameterLength, void *ReplyData, int ReplyLength)
347 unsigned char *ParameterPointer = (unsigned char *) ParameterData;
348 unsigned char *ReplyPointer = (unsigned char *) ReplyData;
349 union BusLogic_StatusRegister StatusRegister;
350 union BusLogic_InterruptRegister InterruptRegister;
351 unsigned long ProcessorFlags = 0;
352 int ReplyBytes = 0, Result;
353 long TimeoutCounter;
355 Clear out the Reply Data if provided.
357 if (ReplyLength > 0)
358 memset(ReplyData, 0, ReplyLength);
360 If the IRQ Channel has not yet been acquired, then interrupts must be
361 disabled while issuing host adapter commands since a Command Complete
362 interrupt could occur if the IRQ Channel was previously enabled by another
363 BusLogic Host Adapter or another driver sharing the same IRQ Channel.
365 if (!HostAdapter->IRQ_ChannelAcquired)
366 local_irq_save(ProcessorFlags);
368 Wait for the Host Adapter Ready bit to be set and the Command/Parameter
369 Register Busy bit to be reset in the Status Register.
371 TimeoutCounter = 10000;
372 while (--TimeoutCounter >= 0) {
373 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
374 if (StatusRegister.sr.HostAdapterReady && !StatusRegister.sr.CommandParameterRegisterBusy)
375 break;
376 udelay(100);
378 if (TimeoutCounter < 0) {
379 BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";
380 Result = -2;
381 goto Done;
384 Write the OperationCode to the Command/Parameter Register.
386 HostAdapter->HostAdapterCommandCompleted = false;
387 BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);
389 Write any additional Parameter Bytes.
391 TimeoutCounter = 10000;
392 while (ParameterLength > 0 && --TimeoutCounter >= 0) {
394 Wait 100 microseconds to give the Host Adapter enough time to determine
395 whether the last value written to the Command/Parameter Register was
396 valid or not. If the Command Complete bit is set in the Interrupt
397 Register, then the Command Invalid bit in the Status Register will be
398 reset if the Operation Code or Parameter was valid and the command
399 has completed, or set if the Operation Code or Parameter was invalid.
400 If the Data In Register Ready bit is set in the Status Register, then
401 the Operation Code was valid, and data is waiting to be read back
402 from the Host Adapter. Otherwise, wait for the Command/Parameter
403 Register Busy bit in the Status Register to be reset.
405 udelay(100);
406 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
407 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
408 if (InterruptRegister.ir.CommandComplete)
409 break;
410 if (HostAdapter->HostAdapterCommandCompleted)
411 break;
412 if (StatusRegister.sr.DataInRegisterReady)
413 break;
414 if (StatusRegister.sr.CommandParameterRegisterBusy)
415 continue;
416 BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++);
417 ParameterLength--;
419 if (TimeoutCounter < 0) {
420 BusLogic_CommandFailureReason = "Timeout waiting for Parameter Acceptance";
421 Result = -2;
422 goto Done;
425 The Modify I/O Address command does not cause a Command Complete Interrupt.
427 if (OperationCode == BusLogic_ModifyIOAddress) {
428 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
429 if (StatusRegister.sr.CommandInvalid) {
430 BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
431 Result = -1;
432 goto Done;
434 if (BusLogic_GlobalOptions.TraceConfiguration)
435 BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: " "(Modify I/O Address)\n", HostAdapter, OperationCode, StatusRegister.All);
436 Result = 0;
437 goto Done;
440 Select an appropriate timeout value for awaiting command completion.
442 switch (OperationCode) {
443 case BusLogic_InquireInstalledDevicesID0to7:
444 case BusLogic_InquireInstalledDevicesID8to15:
445 case BusLogic_InquireTargetDevices:
446 /* Approximately 60 seconds. */
447 TimeoutCounter = 60 * 10000;
448 break;
449 default:
450 /* Approximately 1 second. */
451 TimeoutCounter = 10000;
452 break;
455 Receive any Reply Bytes, waiting for either the Command Complete bit to
456 be set in the Interrupt Register, or for the Interrupt Handler to set the
457 Host Adapter Command Completed bit in the Host Adapter structure.
459 while (--TimeoutCounter >= 0) {
460 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
461 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
462 if (InterruptRegister.ir.CommandComplete)
463 break;
464 if (HostAdapter->HostAdapterCommandCompleted)
465 break;
466 if (StatusRegister.sr.DataInRegisterReady) {
467 if (++ReplyBytes <= ReplyLength)
468 *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
469 else
470 BusLogic_ReadDataInRegister(HostAdapter);
472 if (OperationCode == BusLogic_FetchHostAdapterLocalRAM && StatusRegister.sr.HostAdapterReady)
473 break;
474 udelay(100);
476 if (TimeoutCounter < 0) {
477 BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";
478 Result = -2;
479 goto Done;
482 Clear any pending Command Complete Interrupt.
484 BusLogic_InterruptReset(HostAdapter);
486 Provide tracing information if requested.
488 if (BusLogic_GlobalOptions.TraceConfiguration) {
489 int i;
490 BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:", HostAdapter, OperationCode, StatusRegister.All, ReplyLength, ReplyBytes);
491 if (ReplyLength > ReplyBytes)
492 ReplyLength = ReplyBytes;
493 for (i = 0; i < ReplyLength; i++)
494 BusLogic_Notice(" %02X", HostAdapter, ((unsigned char *) ReplyData)[i]);
495 BusLogic_Notice("\n", HostAdapter);
498 Process Command Invalid conditions.
500 if (StatusRegister.sr.CommandInvalid) {
502 Some early BusLogic Host Adapters may not recover properly from
503 a Command Invalid condition, so if this appears to be the case,
504 a Soft Reset is issued to the Host Adapter. Potentially invalid
505 commands are never attempted after Mailbox Initialization is
506 performed, so there should be no Host Adapter state lost by a
507 Soft Reset in response to a Command Invalid condition.
509 udelay(1000);
510 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
511 if (StatusRegister.sr.CommandInvalid ||
512 StatusRegister.sr.Reserved ||
513 StatusRegister.sr.DataInRegisterReady ||
514 StatusRegister.sr.CommandParameterRegisterBusy || !StatusRegister.sr.HostAdapterReady || !StatusRegister.sr.InitializationRequired || StatusRegister.sr.DiagnosticActive || StatusRegister.sr.DiagnosticFailure) {
515 BusLogic_SoftReset(HostAdapter);
516 udelay(1000);
518 BusLogic_CommandFailureReason = "Command Invalid";
519 Result = -1;
520 goto Done;
523 Handle Excess Parameters Supplied conditions.
525 if (ParameterLength > 0) {
526 BusLogic_CommandFailureReason = "Excess Parameters Supplied";
527 Result = -1;
528 goto Done;
531 Indicate the command completed successfully.
533 BusLogic_CommandFailureReason = NULL;
534 Result = ReplyBytes;
536 Restore the interrupt status if necessary and return.
538 Done:
539 if (!HostAdapter->IRQ_ChannelAcquired)
540 local_irq_restore(ProcessorFlags);
541 return Result;
546 BusLogic_AppendProbeAddressISA appends a single ISA I/O Address to the list
547 of I/O Address and Bus Probe Information to be checked for potential BusLogic
548 Host Adapters.
551 static void __init BusLogic_AppendProbeAddressISA(unsigned long IO_Address)
553 struct BusLogic_ProbeInfo *ProbeInfo;
554 if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters)
555 return;
556 ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
557 ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
558 ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
559 ProbeInfo->IO_Address = IO_Address;
560 ProbeInfo->PCI_Device = NULL;
565 BusLogic_InitializeProbeInfoListISA initializes the list of I/O Address and
566 Bus Probe Information to be checked for potential BusLogic SCSI Host Adapters
567 only from the list of standard BusLogic MultiMaster ISA I/O Addresses.
570 static void __init BusLogic_InitializeProbeInfoListISA(struct BusLogic_HostAdapter
571 *PrototypeHostAdapter)
574 If BusLogic Driver Options specifications requested that ISA Bus Probes
575 be inhibited, do not proceed further.
577 if (BusLogic_ProbeOptions.NoProbeISA)
578 return;
580 Append the list of standard BusLogic MultiMaster ISA I/O Addresses.
582 if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe330 : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0)
583 BusLogic_AppendProbeAddressISA(0x330);
584 if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe334 : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0)
585 BusLogic_AppendProbeAddressISA(0x334);
586 if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe230 : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0)
587 BusLogic_AppendProbeAddressISA(0x230);
588 if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe234 : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0)
589 BusLogic_AppendProbeAddressISA(0x234);
590 if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe130 : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0)
591 BusLogic_AppendProbeAddressISA(0x130);
592 if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe134 : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0)
593 BusLogic_AppendProbeAddressISA(0x134);
597 #ifdef CONFIG_PCI
601 BusLogic_SortProbeInfo sorts a section of BusLogic_ProbeInfoList in order
602 of increasing PCI Bus and Device Number.
605 static void __init BusLogic_SortProbeInfo(struct BusLogic_ProbeInfo *ProbeInfoList, int ProbeInfoCount)
607 int LastInterchange = ProbeInfoCount - 1, Bound, j;
608 while (LastInterchange > 0) {
609 Bound = LastInterchange;
610 LastInterchange = 0;
611 for (j = 0; j < Bound; j++) {
612 struct BusLogic_ProbeInfo *ProbeInfo1 = &ProbeInfoList[j];
613 struct BusLogic_ProbeInfo *ProbeInfo2 = &ProbeInfoList[j + 1];
614 if (ProbeInfo1->Bus > ProbeInfo2->Bus || (ProbeInfo1->Bus == ProbeInfo2->Bus && (ProbeInfo1->Device > ProbeInfo2->Device))) {
615 struct BusLogic_ProbeInfo TempProbeInfo;
616 memcpy(&TempProbeInfo, ProbeInfo1, sizeof(struct BusLogic_ProbeInfo));
617 memcpy(ProbeInfo1, ProbeInfo2, sizeof(struct BusLogic_ProbeInfo));
618 memcpy(ProbeInfo2, &TempProbeInfo, sizeof(struct BusLogic_ProbeInfo));
619 LastInterchange = j;
627 BusLogic_InitializeMultiMasterProbeInfo initializes the list of I/O Address
628 and Bus Probe Information to be checked for potential BusLogic MultiMaster
629 SCSI Host Adapters by interrogating the PCI Configuration Space on PCI
630 machines as well as from the list of standard BusLogic MultiMaster ISA
631 I/O Addresses. It returns the number of PCI MultiMaster Host Adapters found.
634 static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAdapter
635 *PrototypeHostAdapter)
637 struct BusLogic_ProbeInfo *PrimaryProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount];
638 int NonPrimaryPCIMultiMasterIndex = BusLogic_ProbeInfoCount + 1;
639 int NonPrimaryPCIMultiMasterCount = 0, PCIMultiMasterCount = 0;
640 bool ForceBusDeviceScanningOrder = false;
641 bool ForceBusDeviceScanningOrderChecked = false;
642 bool StandardAddressSeen[6];
643 struct pci_dev *PCI_Device = NULL;
644 int i;
645 if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters)
646 return 0;
647 BusLogic_ProbeInfoCount++;
648 for (i = 0; i < 6; i++)
649 StandardAddressSeen[i] = false;
651 Iterate over the MultiMaster PCI Host Adapters. For each enumerated host
652 adapter, determine whether its ISA Compatible I/O Port is enabled and if
653 so, whether it is assigned the Primary I/O Address. A host adapter that is
654 assigned the Primary I/O Address will always be the preferred boot device.
655 The MultiMaster BIOS will first recognize a host adapter at the Primary I/O
656 Address, then any other PCI host adapters, and finally any host adapters
657 located at the remaining standard ISA I/O Addresses. When a PCI host
658 adapter is found with its ISA Compatible I/O Port enabled, a command is
659 issued to disable the ISA Compatible I/O Port, and it is noted that the
660 particular standard ISA I/O Address need not be probed.
662 PrimaryProbeInfo->IO_Address = 0;
663 while ((PCI_Device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER, PCI_Device)) != NULL) {
664 struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter;
665 struct BusLogic_PCIHostAdapterInformation PCIHostAdapterInformation;
666 enum BusLogic_ISACompatibleIOPort ModifyIOAddressRequest;
667 unsigned char Bus;
668 unsigned char Device;
669 unsigned int IRQ_Channel;
670 unsigned long BaseAddress0;
671 unsigned long BaseAddress1;
672 unsigned long IO_Address;
673 unsigned long PCI_Address;
675 if (pci_enable_device(PCI_Device))
676 continue;
678 if (pci_set_dma_mask(PCI_Device, DMA_32BIT_MASK ))
679 continue;
681 Bus = PCI_Device->bus->number;
682 Device = PCI_Device->devfn >> 3;
683 IRQ_Channel = PCI_Device->irq;
684 IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0);
685 PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1);
687 if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) {
688 BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "MultiMaster Host Adapter\n", NULL, BaseAddress0);
689 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
690 continue;
692 if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO) {
693 BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for " "MultiMaster Host Adapter\n", NULL, BaseAddress1);
694 BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, Bus, Device, PCI_Address);
695 continue;
697 if (IRQ_Channel == 0) {
698 BusLogic_Error("BusLogic: IRQ Channel %d invalid for " "MultiMaster Host Adapter\n", NULL, IRQ_Channel);
699 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
700 continue;
702 if (BusLogic_GlobalOptions.TraceProbe) {
703 BusLogic_Notice("BusLogic: PCI MultiMaster Host Adapter " "detected at\n", NULL);
704 BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address " "0x%X PCI Address 0x%X\n", NULL, Bus, Device, IO_Address, PCI_Address);
707 Issue the Inquire PCI Host Adapter Information command to determine
708 the ISA Compatible I/O Port. If the ISA Compatible I/O Port is
709 known and enabled, note that the particular Standard ISA I/O
710 Address should not be probed.
712 HostAdapter->IO_Address = IO_Address;
713 BusLogic_InterruptReset(HostAdapter);
714 if (BusLogic_Command(HostAdapter, BusLogic_InquirePCIHostAdapterInformation, NULL, 0, &PCIHostAdapterInformation, sizeof(PCIHostAdapterInformation))
715 == sizeof(PCIHostAdapterInformation)) {
716 if (PCIHostAdapterInformation.ISACompatibleIOPort < 6)
717 StandardAddressSeen[PCIHostAdapterInformation.ISACompatibleIOPort] = true;
718 } else
719 PCIHostAdapterInformation.ISACompatibleIOPort = BusLogic_IO_Disable;
721 * Issue the Modify I/O Address command to disable the ISA Compatible
722 * I/O Port. On PCI Host Adapters, the Modify I/O Address command
723 * allows modification of the ISA compatible I/O Address that the Host
724 * Adapter responds to; it does not affect the PCI compliant I/O Address
725 * assigned at system initialization.
727 ModifyIOAddressRequest = BusLogic_IO_Disable;
728 BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress, &ModifyIOAddressRequest, sizeof(ModifyIOAddressRequest), NULL, 0);
730 For the first MultiMaster Host Adapter enumerated, issue the Fetch
731 Host Adapter Local RAM command to read byte 45 of the AutoSCSI area,
732 for the setting of the "Use Bus And Device # For PCI Scanning Seq."
733 option. Issue the Inquire Board ID command since this option is
734 only valid for the BT-948/958/958D.
736 if (!ForceBusDeviceScanningOrderChecked) {
737 struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest;
738 struct BusLogic_AutoSCSIByte45 AutoSCSIByte45;
739 struct BusLogic_BoardID BoardID;
740 FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_AutoSCSI_BaseOffset + 45;
741 FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIByte45);
742 BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &AutoSCSIByte45, sizeof(AutoSCSIByte45));
743 BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0, &BoardID, sizeof(BoardID));
744 if (BoardID.FirmwareVersion1stDigit == '5')
745 ForceBusDeviceScanningOrder = AutoSCSIByte45.ForceBusDeviceScanningOrder;
746 ForceBusDeviceScanningOrderChecked = true;
749 Determine whether this MultiMaster Host Adapter has its ISA
750 Compatible I/O Port enabled and is assigned the Primary I/O Address.
751 If it does, then it is the Primary MultiMaster Host Adapter and must
752 be recognized first. If it does not, then it is added to the list
753 for probing after any Primary MultiMaster Host Adapter is probed.
755 if (PCIHostAdapterInformation.ISACompatibleIOPort == BusLogic_IO_330) {
756 PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
757 PrimaryProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
758 PrimaryProbeInfo->IO_Address = IO_Address;
759 PrimaryProbeInfo->PCI_Address = PCI_Address;
760 PrimaryProbeInfo->Bus = Bus;
761 PrimaryProbeInfo->Device = Device;
762 PrimaryProbeInfo->IRQ_Channel = IRQ_Channel;
763 PrimaryProbeInfo->PCI_Device = pci_dev_get(PCI_Device);
764 PCIMultiMasterCount++;
765 } else if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters) {
766 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
767 ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
768 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
769 ProbeInfo->IO_Address = IO_Address;
770 ProbeInfo->PCI_Address = PCI_Address;
771 ProbeInfo->Bus = Bus;
772 ProbeInfo->Device = Device;
773 ProbeInfo->IRQ_Channel = IRQ_Channel;
774 ProbeInfo->PCI_Device = pci_dev_get(PCI_Device);
775 NonPrimaryPCIMultiMasterCount++;
776 PCIMultiMasterCount++;
777 } else
778 BusLogic_Warning("BusLogic: Too many Host Adapters " "detected\n", NULL);
781 If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option is ON
782 for the first enumerated MultiMaster Host Adapter, and if that host adapter
783 is a BT-948/958/958D, then the MultiMaster BIOS will recognize MultiMaster
784 Host Adapters in the order of increasing PCI Bus and Device Number. In
785 that case, sort the probe information into the same order the BIOS uses.
786 If this option is OFF, then the MultiMaster BIOS will recognize MultiMaster
787 Host Adapters in the order they are enumerated by the PCI BIOS, and hence
788 no sorting is necessary.
790 if (ForceBusDeviceScanningOrder)
791 BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[NonPrimaryPCIMultiMasterIndex], NonPrimaryPCIMultiMasterCount);
793 If no PCI MultiMaster Host Adapter is assigned the Primary I/O Address,
794 then the Primary I/O Address must be probed explicitly before any PCI
795 host adapters are probed.
797 if (!BusLogic_ProbeOptions.NoProbeISA)
798 if (PrimaryProbeInfo->IO_Address == 0 && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe330 : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0)) {
799 PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
800 PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
801 PrimaryProbeInfo->IO_Address = 0x330;
804 Append the list of standard BusLogic MultiMaster ISA I/O Addresses,
805 omitting the Primary I/O Address which has already been handled.
807 if (!BusLogic_ProbeOptions.NoProbeISA) {
808 if (!StandardAddressSeen[1] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe334 : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0))
809 BusLogic_AppendProbeAddressISA(0x334);
810 if (!StandardAddressSeen[2] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe230 : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0))
811 BusLogic_AppendProbeAddressISA(0x230);
812 if (!StandardAddressSeen[3] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe234 : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0))
813 BusLogic_AppendProbeAddressISA(0x234);
814 if (!StandardAddressSeen[4] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe130 : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0))
815 BusLogic_AppendProbeAddressISA(0x130);
816 if (!StandardAddressSeen[5] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe134 : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0))
817 BusLogic_AppendProbeAddressISA(0x134);
820 Iterate over the older non-compliant MultiMaster PCI Host Adapters,
821 noting the PCI bus location and assigned IRQ Channel.
823 PCI_Device = NULL;
824 while ((PCI_Device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC, PCI_Device)) != NULL) {
825 unsigned char Bus;
826 unsigned char Device;
827 unsigned int IRQ_Channel;
828 unsigned long IO_Address;
830 if (pci_enable_device(PCI_Device))
831 continue;
833 if (pci_set_dma_mask(PCI_Device, DMA_32BIT_MASK))
834 continue;
836 Bus = PCI_Device->bus->number;
837 Device = PCI_Device->devfn >> 3;
838 IRQ_Channel = PCI_Device->irq;
839 IO_Address = pci_resource_start(PCI_Device, 0);
841 if (IO_Address == 0 || IRQ_Channel == 0)
842 continue;
843 for (i = 0; i < BusLogic_ProbeInfoCount; i++) {
844 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[i];
845 if (ProbeInfo->IO_Address == IO_Address && ProbeInfo->HostAdapterType == BusLogic_MultiMaster) {
846 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
847 ProbeInfo->PCI_Address = 0;
848 ProbeInfo->Bus = Bus;
849 ProbeInfo->Device = Device;
850 ProbeInfo->IRQ_Channel = IRQ_Channel;
851 ProbeInfo->PCI_Device = pci_dev_get(PCI_Device);
852 break;
856 return PCIMultiMasterCount;
861 BusLogic_InitializeFlashPointProbeInfo initializes the list of I/O Address
862 and Bus Probe Information to be checked for potential BusLogic FlashPoint
863 Host Adapters by interrogating the PCI Configuration Space. It returns the
864 number of FlashPoint Host Adapters found.
867 static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAdapter
868 *PrototypeHostAdapter)
870 int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0;
871 struct pci_dev *PCI_Device = NULL;
873 Interrogate PCI Configuration Space for any FlashPoint Host Adapters.
875 while ((PCI_Device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT, PCI_Device)) != NULL) {
876 unsigned char Bus;
877 unsigned char Device;
878 unsigned int IRQ_Channel;
879 unsigned long BaseAddress0;
880 unsigned long BaseAddress1;
881 unsigned long IO_Address;
882 unsigned long PCI_Address;
884 if (pci_enable_device(PCI_Device))
885 continue;
887 if (pci_set_dma_mask(PCI_Device, DMA_32BIT_MASK))
888 continue;
890 Bus = PCI_Device->bus->number;
891 Device = PCI_Device->devfn >> 3;
892 IRQ_Channel = PCI_Device->irq;
893 IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0);
894 PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1);
895 #ifndef CONFIG_SCSI_OMIT_FLASHPOINT
896 if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) {
897 BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, BaseAddress0);
898 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
899 continue;
901 if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO) {
902 BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for " "FlashPoint Host Adapter\n", NULL, BaseAddress1);
903 BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, Bus, Device, PCI_Address);
904 continue;
906 if (IRQ_Channel == 0) {
907 BusLogic_Error("BusLogic: IRQ Channel %d invalid for " "FlashPoint Host Adapter\n", NULL, IRQ_Channel);
908 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
909 continue;
911 if (BusLogic_GlobalOptions.TraceProbe) {
912 BusLogic_Notice("BusLogic: FlashPoint Host Adapter " "detected at\n", NULL);
913 BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address " "0x%X PCI Address 0x%X\n", NULL, Bus, Device, IO_Address, PCI_Address);
915 if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters) {
916 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
917 ProbeInfo->HostAdapterType = BusLogic_FlashPoint;
918 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
919 ProbeInfo->IO_Address = IO_Address;
920 ProbeInfo->PCI_Address = PCI_Address;
921 ProbeInfo->Bus = Bus;
922 ProbeInfo->Device = Device;
923 ProbeInfo->IRQ_Channel = IRQ_Channel;
924 ProbeInfo->PCI_Device = pci_dev_get(PCI_Device);
925 FlashPointCount++;
926 } else
927 BusLogic_Warning("BusLogic: Too many Host Adapters " "detected\n", NULL);
928 #else
929 BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", NULL, Bus, Device);
930 BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, irq %d, " "but FlashPoint\n", NULL, IO_Address, PCI_Address, IRQ_Channel);
931 BusLogic_Error("BusLogic: support was omitted in this kernel " "configuration.\n", NULL);
932 #endif
935 The FlashPoint BIOS will scan for FlashPoint Host Adapters in the order of
936 increasing PCI Bus and Device Number, so sort the probe information into
937 the same order the BIOS uses.
939 BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[FlashPointIndex], FlashPointCount);
940 return FlashPointCount;
945 BusLogic_InitializeProbeInfoList initializes the list of I/O Address and Bus
946 Probe Information to be checked for potential BusLogic SCSI Host Adapters by
947 interrogating the PCI Configuration Space on PCI machines as well as from the
948 list of standard BusLogic MultiMaster ISA I/O Addresses. By default, if both
949 FlashPoint and PCI MultiMaster Host Adapters are present, this driver will
950 probe for FlashPoint Host Adapters first unless the BIOS primary disk is
951 controlled by the first PCI MultiMaster Host Adapter, in which case
952 MultiMaster Host Adapters will be probed first. The BusLogic Driver Options
953 specifications "MultiMasterFirst" and "FlashPointFirst" can be used to force
954 a particular probe order.
957 static void __init BusLogic_InitializeProbeInfoList(struct BusLogic_HostAdapter
958 *PrototypeHostAdapter)
961 If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint
962 Host Adapters; otherwise, default to the standard ISA MultiMaster probe.
964 if (!BusLogic_ProbeOptions.NoProbePCI) {
965 if (BusLogic_ProbeOptions.MultiMasterFirst) {
966 BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
967 BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
968 } else if (BusLogic_ProbeOptions.FlashPointFirst) {
969 BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
970 BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
971 } else {
972 int FlashPointCount = BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
973 int PCIMultiMasterCount = BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
974 if (FlashPointCount > 0 && PCIMultiMasterCount > 0) {
975 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[FlashPointCount];
976 struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter;
977 struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest;
978 struct BusLogic_BIOSDriveMapByte Drive0MapByte;
979 while (ProbeInfo->HostAdapterBusType != BusLogic_PCI_Bus)
980 ProbeInfo++;
981 HostAdapter->IO_Address = ProbeInfo->IO_Address;
982 FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_BIOS_BaseOffset + BusLogic_BIOS_DriveMapOffset + 0;
983 FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(Drive0MapByte);
984 BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &Drive0MapByte, sizeof(Drive0MapByte));
986 If the Map Byte for BIOS Drive 0 indicates that BIOS Drive 0
987 is controlled by this PCI MultiMaster Host Adapter, then
988 reverse the probe order so that MultiMaster Host Adapters are
989 probed before FlashPoint Host Adapters.
991 if (Drive0MapByte.DiskGeometry != BusLogic_BIOS_Disk_Not_Installed) {
992 struct BusLogic_ProbeInfo SavedProbeInfo[BusLogic_MaxHostAdapters];
993 int MultiMasterCount = BusLogic_ProbeInfoCount - FlashPointCount;
994 memcpy(SavedProbeInfo, BusLogic_ProbeInfoList, BusLogic_ProbeInfoCount * sizeof(struct BusLogic_ProbeInfo));
995 memcpy(&BusLogic_ProbeInfoList[0], &SavedProbeInfo[FlashPointCount], MultiMasterCount * sizeof(struct BusLogic_ProbeInfo));
996 memcpy(&BusLogic_ProbeInfoList[MultiMasterCount], &SavedProbeInfo[0], FlashPointCount * sizeof(struct BusLogic_ProbeInfo));
1000 } else
1001 BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter);
1005 #endif /* CONFIG_PCI */
1009 BusLogic_Failure prints a standardized error message, and then returns false.
1012 static bool BusLogic_Failure(struct BusLogic_HostAdapter *HostAdapter, char *ErrorMessage)
1014 BusLogic_AnnounceDriver(HostAdapter);
1015 if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus) {
1016 BusLogic_Error("While configuring BusLogic PCI Host Adapter at\n", HostAdapter);
1017 BusLogic_Error("Bus %d Device %d I/O Address 0x%X PCI Address 0x%X:\n", HostAdapter, HostAdapter->Bus, HostAdapter->Device, HostAdapter->IO_Address, HostAdapter->PCI_Address);
1018 } else
1019 BusLogic_Error("While configuring BusLogic Host Adapter at " "I/O Address 0x%X:\n", HostAdapter, HostAdapter->IO_Address);
1020 BusLogic_Error("%s FAILED - DETACHING\n", HostAdapter, ErrorMessage);
1021 if (BusLogic_CommandFailureReason != NULL)
1022 BusLogic_Error("ADDITIONAL FAILURE INFO - %s\n", HostAdapter, BusLogic_CommandFailureReason);
1023 return false;
1028 BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter.
1031 static bool __init BusLogic_ProbeHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
1033 union BusLogic_StatusRegister StatusRegister;
1034 union BusLogic_InterruptRegister InterruptRegister;
1035 union BusLogic_GeometryRegister GeometryRegister;
1037 FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager.
1039 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1040 struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
1041 FlashPointInfo->BaseAddress = (u32) HostAdapter->IO_Address;
1042 FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel;
1043 FlashPointInfo->Present = false;
1044 if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 && FlashPointInfo->Present)) {
1045 BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", HostAdapter, HostAdapter->Bus, HostAdapter->Device);
1046 BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, " "but FlashPoint\n", HostAdapter, HostAdapter->IO_Address, HostAdapter->PCI_Address);
1047 BusLogic_Error("BusLogic: Probe Function failed to validate it.\n", HostAdapter);
1048 return false;
1050 if (BusLogic_GlobalOptions.TraceProbe)
1051 BusLogic_Notice("BusLogic_Probe(0x%X): FlashPoint Found\n", HostAdapter, HostAdapter->IO_Address);
1053 Indicate the Host Adapter Probe completed successfully.
1055 return true;
1058 Read the Status, Interrupt, and Geometry Registers to test if there are I/O
1059 ports that respond, and to check the values to determine if they are from a
1060 BusLogic Host Adapter. A nonexistent I/O port will return 0xFF, in which
1061 case there is definitely no BusLogic Host Adapter at this base I/O Address.
1062 The test here is a subset of that used by the BusLogic Host Adapter BIOS.
1064 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1065 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
1066 GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1067 if (BusLogic_GlobalOptions.TraceProbe)
1068 BusLogic_Notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, " "Geometry 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All, InterruptRegister.All, GeometryRegister.All);
1069 if (StatusRegister.All == 0 || StatusRegister.sr.DiagnosticActive || StatusRegister.sr.CommandParameterRegisterBusy || StatusRegister.sr.Reserved || StatusRegister.sr.CommandInvalid || InterruptRegister.ir.Reserved != 0)
1070 return false;
1072 Check the undocumented Geometry Register to test if there is an I/O port
1073 that responded. Adaptec Host Adapters do not implement the Geometry
1074 Register, so this test helps serve to avoid incorrectly recognizing an
1075 Adaptec 1542A or 1542B as a BusLogic. Unfortunately, the Adaptec 1542C
1076 series does respond to the Geometry Register I/O port, but it will be
1077 rejected later when the Inquire Extended Setup Information command is
1078 issued in BusLogic_CheckHostAdapter. The AMI FastDisk Host Adapter is a
1079 BusLogic clone that implements the same interface as earlier BusLogic
1080 Host Adapters, including the undocumented commands, and is therefore
1081 supported by this driver. However, the AMI FastDisk always returns 0x00
1082 upon reading the Geometry Register, so the extended translation option
1083 should always be left disabled on the AMI FastDisk.
1085 if (GeometryRegister.All == 0xFF)
1086 return false;
1088 Indicate the Host Adapter Probe completed successfully.
1090 return true;
1095 BusLogic_HardwareResetHostAdapter issues a Hardware Reset to the Host Adapter
1096 and waits for Host Adapter Diagnostics to complete. If HardReset is true, a
1097 Hard Reset is performed which also initiates a SCSI Bus Reset. Otherwise, a
1098 Soft Reset is performed which only resets the Host Adapter without forcing a
1099 SCSI Bus Reset.
1102 static bool BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter
1103 *HostAdapter, bool HardReset)
1105 union BusLogic_StatusRegister StatusRegister;
1106 int TimeoutCounter;
1108 FlashPoint Host Adapters are Hard Reset by the FlashPoint SCCB Manager.
1110 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1111 struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
1112 FlashPointInfo->HostSoftReset = !HardReset;
1113 FlashPointInfo->ReportDataUnderrun = true;
1114 HostAdapter->CardHandle = FlashPoint_HardwareResetHostAdapter(FlashPointInfo);
1115 if (HostAdapter->CardHandle == FlashPoint_BadCardHandle)
1116 return false;
1118 Indicate the Host Adapter Hard Reset completed successfully.
1120 return true;
1123 Issue a Hard Reset or Soft Reset Command to the Host Adapter. The Host
1124 Adapter should respond by setting Diagnostic Active in the Status Register.
1126 if (HardReset)
1127 BusLogic_HardReset(HostAdapter);
1128 else
1129 BusLogic_SoftReset(HostAdapter);
1131 Wait until Diagnostic Active is set in the Status Register.
1133 TimeoutCounter = 5 * 10000;
1134 while (--TimeoutCounter >= 0) {
1135 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1136 if (StatusRegister.sr.DiagnosticActive)
1137 break;
1138 udelay(100);
1140 if (BusLogic_GlobalOptions.TraceHardwareReset)
1141 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All);
1142 if (TimeoutCounter < 0)
1143 return false;
1145 Wait 100 microseconds to allow completion of any initial diagnostic
1146 activity which might leave the contents of the Status Register
1147 unpredictable.
1149 udelay(100);
1151 Wait until Diagnostic Active is reset in the Status Register.
1153 TimeoutCounter = 10 * 10000;
1154 while (--TimeoutCounter >= 0) {
1155 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1156 if (!StatusRegister.sr.DiagnosticActive)
1157 break;
1158 udelay(100);
1160 if (BusLogic_GlobalOptions.TraceHardwareReset)
1161 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All);
1162 if (TimeoutCounter < 0)
1163 return false;
1165 Wait until at least one of the Diagnostic Failure, Host Adapter Ready,
1166 or Data In Register Ready bits is set in the Status Register.
1168 TimeoutCounter = 10000;
1169 while (--TimeoutCounter >= 0) {
1170 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1171 if (StatusRegister.sr.DiagnosticFailure || StatusRegister.sr.HostAdapterReady || StatusRegister.sr.DataInRegisterReady)
1172 break;
1173 udelay(100);
1175 if (BusLogic_GlobalOptions.TraceHardwareReset)
1176 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All);
1177 if (TimeoutCounter < 0)
1178 return false;
1180 If Diagnostic Failure is set or Host Adapter Ready is reset, then an
1181 error occurred during the Host Adapter diagnostics. If Data In Register
1182 Ready is set, then there is an Error Code available.
1184 if (StatusRegister.sr.DiagnosticFailure || !StatusRegister.sr.HostAdapterReady) {
1185 BusLogic_CommandFailureReason = NULL;
1186 BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
1187 BusLogic_Error("HOST ADAPTER STATUS REGISTER = %02X\n", HostAdapter, StatusRegister.All);
1188 if (StatusRegister.sr.DataInRegisterReady) {
1189 unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
1190 BusLogic_Error("HOST ADAPTER ERROR CODE = %d\n", HostAdapter, ErrorCode);
1192 return false;
1195 Indicate the Host Adapter Hard Reset completed successfully.
1197 return true;
1202 BusLogic_CheckHostAdapter checks to be sure this really is a BusLogic
1203 Host Adapter.
1206 static bool __init BusLogic_CheckHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
1208 struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation;
1209 unsigned char RequestedReplyLength;
1210 bool Result = true;
1212 FlashPoint Host Adapters do not require this protection.
1214 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1215 return true;
1217 Issue the Inquire Extended Setup Information command. Only genuine
1218 BusLogic Host Adapters and true clones support this command. Adaptec 1542C
1219 series Host Adapters that respond to the Geometry Register I/O port will
1220 fail this command.
1222 RequestedReplyLength = sizeof(ExtendedSetupInformation);
1223 if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &ExtendedSetupInformation, sizeof(ExtendedSetupInformation))
1224 != sizeof(ExtendedSetupInformation))
1225 Result = false;
1227 Provide tracing information if requested and return.
1229 if (BusLogic_GlobalOptions.TraceProbe)
1230 BusLogic_Notice("BusLogic_Check(0x%X): MultiMaster %s\n", HostAdapter, HostAdapter->IO_Address, (Result ? "Found" : "Not Found"));
1231 return Result;
1236 BusLogic_ReadHostAdapterConfiguration reads the Configuration Information
1237 from Host Adapter and initializes the Host Adapter structure.
1240 static bool __init BusLogic_ReadHostAdapterConfiguration(struct BusLogic_HostAdapter
1241 *HostAdapter)
1243 struct BusLogic_BoardID BoardID;
1244 struct BusLogic_Configuration Configuration;
1245 struct BusLogic_SetupInformation SetupInformation;
1246 struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation;
1247 unsigned char HostAdapterModelNumber[5];
1248 unsigned char FirmwareVersion3rdDigit;
1249 unsigned char FirmwareVersionLetter;
1250 struct BusLogic_PCIHostAdapterInformation PCIHostAdapterInformation;
1251 struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest;
1252 struct BusLogic_AutoSCSIData AutoSCSIData;
1253 union BusLogic_GeometryRegister GeometryRegister;
1254 unsigned char RequestedReplyLength;
1255 unsigned char *TargetPointer, Character;
1256 int TargetID, i;
1258 Configuration Information for FlashPoint Host Adapters is provided in the
1259 FlashPoint_Info structure by the FlashPoint SCCB Manager's Probe Function.
1260 Initialize fields in the Host Adapter structure from the FlashPoint_Info
1261 structure.
1263 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1264 struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
1265 TargetPointer = HostAdapter->ModelName;
1266 *TargetPointer++ = 'B';
1267 *TargetPointer++ = 'T';
1268 *TargetPointer++ = '-';
1269 for (i = 0; i < sizeof(FlashPointInfo->ModelNumber); i++)
1270 *TargetPointer++ = FlashPointInfo->ModelNumber[i];
1271 *TargetPointer++ = '\0';
1272 strcpy(HostAdapter->FirmwareVersion, FlashPoint_FirmwareVersion);
1273 HostAdapter->SCSI_ID = FlashPointInfo->SCSI_ID;
1274 HostAdapter->ExtendedTranslationEnabled = FlashPointInfo->ExtendedTranslationEnabled;
1275 HostAdapter->ParityCheckingEnabled = FlashPointInfo->ParityCheckingEnabled;
1276 HostAdapter->BusResetEnabled = !FlashPointInfo->HostSoftReset;
1277 HostAdapter->LevelSensitiveInterrupt = true;
1278 HostAdapter->HostWideSCSI = FlashPointInfo->HostWideSCSI;
1279 HostAdapter->HostDifferentialSCSI = false;
1280 HostAdapter->HostSupportsSCAM = true;
1281 HostAdapter->HostUltraSCSI = true;
1282 HostAdapter->ExtendedLUNSupport = true;
1283 HostAdapter->TerminationInfoValid = true;
1284 HostAdapter->LowByteTerminated = FlashPointInfo->LowByteTerminated;
1285 HostAdapter->HighByteTerminated = FlashPointInfo->HighByteTerminated;
1286 HostAdapter->SCAM_Enabled = FlashPointInfo->SCAM_Enabled;
1287 HostAdapter->SCAM_Level2 = FlashPointInfo->SCAM_Level2;
1288 HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1289 HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1290 HostAdapter->MaxLogicalUnits = 32;
1291 HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1292 HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1293 HostAdapter->DriverQueueDepth = 255;
1294 HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth;
1295 HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted;
1296 HostAdapter->FastPermitted = FlashPointInfo->FastPermitted;
1297 HostAdapter->UltraPermitted = FlashPointInfo->UltraPermitted;
1298 HostAdapter->WidePermitted = FlashPointInfo->WidePermitted;
1299 HostAdapter->DisconnectPermitted = FlashPointInfo->DisconnectPermitted;
1300 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1301 goto Common;
1304 Issue the Inquire Board ID command.
1306 if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0, &BoardID, sizeof(BoardID)) != sizeof(BoardID))
1307 return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
1309 Issue the Inquire Configuration command.
1311 if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0, &Configuration, sizeof(Configuration))
1312 != sizeof(Configuration))
1313 return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
1315 Issue the Inquire Setup Information command.
1317 RequestedReplyLength = sizeof(SetupInformation);
1318 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &SetupInformation, sizeof(SetupInformation))
1319 != sizeof(SetupInformation))
1320 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
1322 Issue the Inquire Extended Setup Information command.
1324 RequestedReplyLength = sizeof(ExtendedSetupInformation);
1325 if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &ExtendedSetupInformation, sizeof(ExtendedSetupInformation))
1326 != sizeof(ExtendedSetupInformation))
1327 return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
1329 Issue the Inquire Firmware Version 3rd Digit command.
1331 FirmwareVersion3rdDigit = '\0';
1332 if (BoardID.FirmwareVersion1stDigit > '0')
1333 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit, NULL, 0, &FirmwareVersion3rdDigit, sizeof(FirmwareVersion3rdDigit))
1334 != sizeof(FirmwareVersion3rdDigit))
1335 return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
1337 Issue the Inquire Host Adapter Model Number command.
1339 if (ExtendedSetupInformation.BusType == 'A' && BoardID.FirmwareVersion1stDigit == '2')
1340 /* BusLogic BT-542B ISA 2.xx */
1341 strcpy(HostAdapterModelNumber, "542B");
1342 else if (ExtendedSetupInformation.BusType == 'E' && BoardID.FirmwareVersion1stDigit == '2' && (BoardID.FirmwareVersion2ndDigit <= '1' || (BoardID.FirmwareVersion2ndDigit == '2' && FirmwareVersion3rdDigit == '0')))
1343 /* BusLogic BT-742A EISA 2.1x or 2.20 */
1344 strcpy(HostAdapterModelNumber, "742A");
1345 else if (ExtendedSetupInformation.BusType == 'E' && BoardID.FirmwareVersion1stDigit == '0')
1346 /* AMI FastDisk EISA Series 441 0.x */
1347 strcpy(HostAdapterModelNumber, "747A");
1348 else {
1349 RequestedReplyLength = sizeof(HostAdapterModelNumber);
1350 if (BusLogic_Command(HostAdapter, BusLogic_InquireHostAdapterModelNumber, &RequestedReplyLength, sizeof(RequestedReplyLength), &HostAdapterModelNumber, sizeof(HostAdapterModelNumber))
1351 != sizeof(HostAdapterModelNumber))
1352 return BusLogic_Failure(HostAdapter, "INQUIRE HOST ADAPTER MODEL NUMBER");
1355 BusLogic MultiMaster Host Adapters can be identified by their model number
1356 and the major version number of their firmware as follows:
1358 5.xx BusLogic "W" Series Host Adapters:
1359 BT-948/958/958D
1360 4.xx BusLogic "C" Series Host Adapters:
1361 BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
1362 3.xx BusLogic "S" Series Host Adapters:
1363 BT-747S/747D/757S/757D/445S/545S/542D
1364 BT-542B/742A (revision H)
1365 2.xx BusLogic "A" Series Host Adapters:
1366 BT-542B/742A (revision G and below)
1367 0.xx AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
1370 Save the Model Name and Host Adapter Name in the Host Adapter structure.
1372 TargetPointer = HostAdapter->ModelName;
1373 *TargetPointer++ = 'B';
1374 *TargetPointer++ = 'T';
1375 *TargetPointer++ = '-';
1376 for (i = 0; i < sizeof(HostAdapterModelNumber); i++) {
1377 Character = HostAdapterModelNumber[i];
1378 if (Character == ' ' || Character == '\0')
1379 break;
1380 *TargetPointer++ = Character;
1382 *TargetPointer++ = '\0';
1384 Save the Firmware Version in the Host Adapter structure.
1386 TargetPointer = HostAdapter->FirmwareVersion;
1387 *TargetPointer++ = BoardID.FirmwareVersion1stDigit;
1388 *TargetPointer++ = '.';
1389 *TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
1390 if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0')
1391 *TargetPointer++ = FirmwareVersion3rdDigit;
1392 *TargetPointer = '\0';
1394 Issue the Inquire Firmware Version Letter command.
1396 if (strcmp(HostAdapter->FirmwareVersion, "3.3") >= 0) {
1397 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter, NULL, 0, &FirmwareVersionLetter, sizeof(FirmwareVersionLetter))
1398 != sizeof(FirmwareVersionLetter))
1399 return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE VERSION LETTER");
1400 if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0')
1401 *TargetPointer++ = FirmwareVersionLetter;
1402 *TargetPointer = '\0';
1405 Save the Host Adapter SCSI ID in the Host Adapter structure.
1407 HostAdapter->SCSI_ID = Configuration.HostAdapterID;
1409 Determine the Bus Type and save it in the Host Adapter structure, determine
1410 and save the IRQ Channel if necessary, and determine and save the DMA
1411 Channel for ISA Host Adapters.
1413 HostAdapter->HostAdapterBusType = BusLogic_HostAdapterBusTypes[HostAdapter->ModelName[3] - '4'];
1414 if (HostAdapter->IRQ_Channel == 0) {
1415 if (Configuration.IRQ_Channel9)
1416 HostAdapter->IRQ_Channel = 9;
1417 else if (Configuration.IRQ_Channel10)
1418 HostAdapter->IRQ_Channel = 10;
1419 else if (Configuration.IRQ_Channel11)
1420 HostAdapter->IRQ_Channel = 11;
1421 else if (Configuration.IRQ_Channel12)
1422 HostAdapter->IRQ_Channel = 12;
1423 else if (Configuration.IRQ_Channel14)
1424 HostAdapter->IRQ_Channel = 14;
1425 else if (Configuration.IRQ_Channel15)
1426 HostAdapter->IRQ_Channel = 15;
1428 if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus) {
1429 if (Configuration.DMA_Channel5)
1430 HostAdapter->DMA_Channel = 5;
1431 else if (Configuration.DMA_Channel6)
1432 HostAdapter->DMA_Channel = 6;
1433 else if (Configuration.DMA_Channel7)
1434 HostAdapter->DMA_Channel = 7;
1437 Determine whether Extended Translation is enabled and save it in
1438 the Host Adapter structure.
1440 GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1441 HostAdapter->ExtendedTranslationEnabled = GeometryRegister.gr.ExtendedTranslationEnabled;
1443 Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide
1444 SCSI flag, Differential SCSI flag, SCAM Supported flag, and
1445 Ultra SCSI flag in the Host Adapter structure.
1447 HostAdapter->HostAdapterScatterGatherLimit = ExtendedSetupInformation.ScatterGatherLimit;
1448 HostAdapter->DriverScatterGatherLimit = HostAdapter->HostAdapterScatterGatherLimit;
1449 if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
1450 HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1451 if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupt)
1452 HostAdapter->LevelSensitiveInterrupt = true;
1453 HostAdapter->HostWideSCSI = ExtendedSetupInformation.HostWideSCSI;
1454 HostAdapter->HostDifferentialSCSI = ExtendedSetupInformation.HostDifferentialSCSI;
1455 HostAdapter->HostSupportsSCAM = ExtendedSetupInformation.HostSupportsSCAM;
1456 HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI;
1458 Determine whether Extended LUN Format CCBs are supported and save the
1459 information in the Host Adapter structure.
1461 if (HostAdapter->FirmwareVersion[0] == '5' || (HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI))
1462 HostAdapter->ExtendedLUNSupport = true;
1464 Issue the Inquire PCI Host Adapter Information command to read the
1465 Termination Information from "W" series MultiMaster Host Adapters.
1467 if (HostAdapter->FirmwareVersion[0] == '5') {
1468 if (BusLogic_Command(HostAdapter, BusLogic_InquirePCIHostAdapterInformation, NULL, 0, &PCIHostAdapterInformation, sizeof(PCIHostAdapterInformation))
1469 != sizeof(PCIHostAdapterInformation))
1470 return BusLogic_Failure(HostAdapter, "INQUIRE PCI HOST ADAPTER INFORMATION");
1472 Save the Termination Information in the Host Adapter structure.
1474 if (PCIHostAdapterInformation.GenericInfoValid) {
1475 HostAdapter->TerminationInfoValid = true;
1476 HostAdapter->LowByteTerminated = PCIHostAdapterInformation.LowByteTerminated;
1477 HostAdapter->HighByteTerminated = PCIHostAdapterInformation.HighByteTerminated;
1481 Issue the Fetch Host Adapter Local RAM command to read the AutoSCSI data
1482 from "W" and "C" series MultiMaster Host Adapters.
1484 if (HostAdapter->FirmwareVersion[0] >= '4') {
1485 FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_AutoSCSI_BaseOffset;
1486 FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIData);
1487 if (BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &AutoSCSIData, sizeof(AutoSCSIData))
1488 != sizeof(AutoSCSIData))
1489 return BusLogic_Failure(HostAdapter, "FETCH HOST ADAPTER LOCAL RAM");
1491 Save the Parity Checking Enabled, Bus Reset Enabled, and Termination
1492 Information in the Host Adapter structure.
1494 HostAdapter->ParityCheckingEnabled = AutoSCSIData.ParityCheckingEnabled;
1495 HostAdapter->BusResetEnabled = AutoSCSIData.BusResetEnabled;
1496 if (HostAdapter->FirmwareVersion[0] == '4') {
1497 HostAdapter->TerminationInfoValid = true;
1498 HostAdapter->LowByteTerminated = AutoSCSIData.LowByteTerminated;
1499 HostAdapter->HighByteTerminated = AutoSCSIData.HighByteTerminated;
1502 Save the Wide Permitted, Fast Permitted, Synchronous Permitted,
1503 Disconnect Permitted, Ultra Permitted, and SCAM Information in the
1504 Host Adapter structure.
1506 HostAdapter->WidePermitted = AutoSCSIData.WidePermitted;
1507 HostAdapter->FastPermitted = AutoSCSIData.FastPermitted;
1508 HostAdapter->SynchronousPermitted = AutoSCSIData.SynchronousPermitted;
1509 HostAdapter->DisconnectPermitted = AutoSCSIData.DisconnectPermitted;
1510 if (HostAdapter->HostUltraSCSI)
1511 HostAdapter->UltraPermitted = AutoSCSIData.UltraPermitted;
1512 if (HostAdapter->HostSupportsSCAM) {
1513 HostAdapter->SCAM_Enabled = AutoSCSIData.SCAM_Enabled;
1514 HostAdapter->SCAM_Level2 = AutoSCSIData.SCAM_Level2;
1518 Initialize fields in the Host Adapter structure for "S" and "A" series
1519 MultiMaster Host Adapters.
1521 if (HostAdapter->FirmwareVersion[0] < '4') {
1522 if (SetupInformation.SynchronousInitiationEnabled) {
1523 HostAdapter->SynchronousPermitted = 0xFF;
1524 if (HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus) {
1525 if (ExtendedSetupInformation.Misc.FastOnEISA)
1526 HostAdapter->FastPermitted = 0xFF;
1527 if (strcmp(HostAdapter->ModelName, "BT-757") == 0)
1528 HostAdapter->WidePermitted = 0xFF;
1531 HostAdapter->DisconnectPermitted = 0xFF;
1532 HostAdapter->ParityCheckingEnabled = SetupInformation.ParityCheckingEnabled;
1533 HostAdapter->BusResetEnabled = true;
1536 Determine the maximum number of Target IDs and Logical Units supported by
1537 this driver for Wide and Narrow Host Adapters.
1539 HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1540 HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8);
1542 Select appropriate values for the Mailbox Count, Driver Queue Depth,
1543 Initial CCBs, and Incremental CCBs variables based on whether or not Strict
1544 Round Robin Mode is supported. If Strict Round Robin Mode is supported,
1545 then there is no performance degradation in using the maximum possible
1546 number of Outgoing and Incoming Mailboxes and allowing the Tagged and
1547 Untagged Queue Depths to determine the actual utilization. If Strict Round
1548 Robin Mode is not supported, then the Host Adapter must scan all the
1549 Outgoing Mailboxes whenever an Outgoing Mailbox entry is made, which can
1550 cause a substantial performance penalty. The host adapters actually have
1551 room to store the following number of CCBs internally; that is, they can
1552 internally queue and manage this many active commands on the SCSI bus
1553 simultaneously. Performance measurements demonstrate that the Driver Queue
1554 Depth should be set to the Mailbox Count, rather than the Host Adapter
1555 Queue Depth (internal CCB capacity), as it is more efficient to have the
1556 queued commands waiting in Outgoing Mailboxes if necessary than to block
1557 the process in the higher levels of the SCSI Subsystem.
1559 192 BT-948/958/958D
1560 100 BT-946C/956C/956CD/747C/757C/757CD/445C
1561 50 BT-545C/540CF
1562 30 BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
1564 if (HostAdapter->FirmwareVersion[0] == '5')
1565 HostAdapter->HostAdapterQueueDepth = 192;
1566 else if (HostAdapter->FirmwareVersion[0] == '4')
1567 HostAdapter->HostAdapterQueueDepth = (HostAdapter->HostAdapterBusType != BusLogic_ISA_Bus ? 100 : 50);
1568 else
1569 HostAdapter->HostAdapterQueueDepth = 30;
1570 if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0) {
1571 HostAdapter->StrictRoundRobinModeSupport = true;
1572 HostAdapter->MailboxCount = BusLogic_MaxMailboxes;
1573 } else {
1574 HostAdapter->StrictRoundRobinModeSupport = false;
1575 HostAdapter->MailboxCount = 32;
1577 HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount;
1578 HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1579 HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1581 Tagged Queuing support is available and operates properly on all "W" series
1582 MultiMaster Host Adapters, on "C" series MultiMaster Host Adapters with
1583 firmware version 4.22 and above, and on "S" series MultiMaster Host
1584 Adapters with firmware version 3.35 and above.
1586 HostAdapter->TaggedQueuingPermitted = 0;
1587 switch (HostAdapter->FirmwareVersion[0]) {
1588 case '5':
1589 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1590 break;
1591 case '4':
1592 if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0)
1593 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1594 break;
1595 case '3':
1596 if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0)
1597 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1598 break;
1601 Determine the Host Adapter BIOS Address if the BIOS is enabled and
1602 save it in the Host Adapter structure. The BIOS is disabled if the
1603 BIOS_Address is 0.
1605 HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
1607 ISA Host Adapters require Bounce Buffers if there is more than 16MB memory.
1609 if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus && (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1610 HostAdapter->BounceBuffersRequired = true;
1612 BusLogic BT-445S Host Adapters prior to board revision E have a hardware
1613 bug whereby when the BIOS is enabled, transfers to/from the same address
1614 range the BIOS occupies modulo 16MB are handled incorrectly. Only properly
1615 functioning BT-445S Host Adapters have firmware version 3.37, so require
1616 that ISA Bounce Buffers be used for the buggy BT-445S models if there is
1617 more than 16MB memory.
1619 if (HostAdapter->BIOS_Address > 0 && strcmp(HostAdapter->ModelName, "BT-445S") == 0 && strcmp(HostAdapter->FirmwareVersion, "3.37") < 0 && (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1620 HostAdapter->BounceBuffersRequired = true;
1622 Initialize parameters common to MultiMaster and FlashPoint Host Adapters.
1624 Common:
1626 Initialize the Host Adapter Full Model Name from the Model Name.
1628 strcpy(HostAdapter->FullModelName, "BusLogic ");
1629 strcat(HostAdapter->FullModelName, HostAdapter->ModelName);
1631 Select an appropriate value for the Tagged Queue Depth either from a
1632 BusLogic Driver Options specification, or based on whether this Host
1633 Adapter requires that ISA Bounce Buffers be used. The Tagged Queue Depth
1634 is left at 0 for automatic determination in BusLogic_SelectQueueDepths.
1635 Initialize the Untagged Queue Depth.
1637 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) {
1638 unsigned char QueueDepth = 0;
1639 if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->QueueDepth[TargetID] > 0)
1640 QueueDepth = HostAdapter->DriverOptions->QueueDepth[TargetID];
1641 else if (HostAdapter->BounceBuffersRequired)
1642 QueueDepth = BusLogic_TaggedQueueDepthBB;
1643 HostAdapter->QueueDepth[TargetID] = QueueDepth;
1645 if (HostAdapter->BounceBuffersRequired)
1646 HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepthBB;
1647 else
1648 HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth;
1649 if (HostAdapter->DriverOptions != NULL)
1650 HostAdapter->CommonQueueDepth = HostAdapter->DriverOptions->CommonQueueDepth;
1651 if (HostAdapter->CommonQueueDepth > 0 && HostAdapter->CommonQueueDepth < HostAdapter->UntaggedQueueDepth)
1652 HostAdapter->UntaggedQueueDepth = HostAdapter->CommonQueueDepth;
1654 Tagged Queuing is only allowed if Disconnect/Reconnect is permitted.
1655 Therefore, mask the Tagged Queuing Permitted Default bits with the
1656 Disconnect/Reconnect Permitted bits.
1658 HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted;
1660 Combine the default Tagged Queuing Permitted bits with any BusLogic Driver
1661 Options Tagged Queuing specification.
1663 if (HostAdapter->DriverOptions != NULL)
1664 HostAdapter->TaggedQueuingPermitted =
1665 (HostAdapter->DriverOptions->TaggedQueuingPermitted & HostAdapter->DriverOptions->TaggedQueuingPermittedMask) | (HostAdapter->TaggedQueuingPermitted & ~HostAdapter->DriverOptions->TaggedQueuingPermittedMask);
1668 Select an appropriate value for Bus Settle Time either from a BusLogic
1669 Driver Options specification, or from BusLogic_DefaultBusSettleTime.
1671 if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->BusSettleTime > 0)
1672 HostAdapter->BusSettleTime = HostAdapter->DriverOptions->BusSettleTime;
1673 else
1674 HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
1676 Indicate reading the Host Adapter Configuration completed successfully.
1678 return true;
1683 BusLogic_ReportHostAdapterConfiguration reports the configuration of
1684 Host Adapter.
1687 static bool __init BusLogic_ReportHostAdapterConfiguration(struct BusLogic_HostAdapter
1688 *HostAdapter)
1690 unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1;
1691 unsigned short SynchronousPermitted, FastPermitted;
1692 unsigned short UltraPermitted, WidePermitted;
1693 unsigned short DisconnectPermitted, TaggedQueuingPermitted;
1694 bool CommonSynchronousNegotiation, CommonTaggedQueueDepth;
1695 char SynchronousString[BusLogic_MaxTargetDevices + 1];
1696 char WideString[BusLogic_MaxTargetDevices + 1];
1697 char DisconnectString[BusLogic_MaxTargetDevices + 1];
1698 char TaggedQueuingString[BusLogic_MaxTargetDevices + 1];
1699 char *SynchronousMessage = SynchronousString;
1700 char *WideMessage = WideString;
1701 char *DisconnectMessage = DisconnectString;
1702 char *TaggedQueuingMessage = TaggedQueuingString;
1703 int TargetID;
1704 BusLogic_Info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n",
1705 HostAdapter, HostAdapter->ModelName,
1706 BusLogic_HostAdapterBusNames[HostAdapter->HostAdapterBusType], (HostAdapter->HostWideSCSI ? " Wide" : ""), (HostAdapter->HostDifferentialSCSI ? " Differential" : ""), (HostAdapter->HostUltraSCSI ? " Ultra" : ""));
1707 BusLogic_Info(" Firmware Version: %s, I/O Address: 0x%X, " "IRQ Channel: %d/%s\n", HostAdapter, HostAdapter->FirmwareVersion, HostAdapter->IO_Address, HostAdapter->IRQ_Channel, (HostAdapter->LevelSensitiveInterrupt ? "Level" : "Edge"));
1708 if (HostAdapter->HostAdapterBusType != BusLogic_PCI_Bus) {
1709 BusLogic_Info(" DMA Channel: ", HostAdapter);
1710 if (HostAdapter->DMA_Channel > 0)
1711 BusLogic_Info("%d, ", HostAdapter, HostAdapter->DMA_Channel);
1712 else
1713 BusLogic_Info("None, ", HostAdapter);
1714 if (HostAdapter->BIOS_Address > 0)
1715 BusLogic_Info("BIOS Address: 0x%X, ", HostAdapter, HostAdapter->BIOS_Address);
1716 else
1717 BusLogic_Info("BIOS Address: None, ", HostAdapter);
1718 } else {
1719 BusLogic_Info(" PCI Bus: %d, Device: %d, Address: ", HostAdapter, HostAdapter->Bus, HostAdapter->Device);
1720 if (HostAdapter->PCI_Address > 0)
1721 BusLogic_Info("0x%X, ", HostAdapter, HostAdapter->PCI_Address);
1722 else
1723 BusLogic_Info("Unassigned, ", HostAdapter);
1725 BusLogic_Info("Host Adapter SCSI ID: %d\n", HostAdapter, HostAdapter->SCSI_ID);
1726 BusLogic_Info(" Parity Checking: %s, Extended Translation: %s\n", HostAdapter, (HostAdapter->ParityCheckingEnabled ? "Enabled" : "Disabled"), (HostAdapter->ExtendedTranslationEnabled ? "Enabled" : "Disabled"));
1727 AllTargetsMask &= ~(1 << HostAdapter->SCSI_ID);
1728 SynchronousPermitted = HostAdapter->SynchronousPermitted & AllTargetsMask;
1729 FastPermitted = HostAdapter->FastPermitted & AllTargetsMask;
1730 UltraPermitted = HostAdapter->UltraPermitted & AllTargetsMask;
1731 if ((BusLogic_MultiMasterHostAdapterP(HostAdapter) && (HostAdapter->FirmwareVersion[0] >= '4' || HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)) || BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1732 CommonSynchronousNegotiation = false;
1733 if (SynchronousPermitted == 0) {
1734 SynchronousMessage = "Disabled";
1735 CommonSynchronousNegotiation = true;
1736 } else if (SynchronousPermitted == AllTargetsMask) {
1737 if (FastPermitted == 0) {
1738 SynchronousMessage = "Slow";
1739 CommonSynchronousNegotiation = true;
1740 } else if (FastPermitted == AllTargetsMask) {
1741 if (UltraPermitted == 0) {
1742 SynchronousMessage = "Fast";
1743 CommonSynchronousNegotiation = true;
1744 } else if (UltraPermitted == AllTargetsMask) {
1745 SynchronousMessage = "Ultra";
1746 CommonSynchronousNegotiation = true;
1750 if (!CommonSynchronousNegotiation) {
1751 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1752 SynchronousString[TargetID] = ((!(SynchronousPermitted & (1 << TargetID))) ? 'N' : (!(FastPermitted & (1 << TargetID)) ? 'S' : (!(UltraPermitted & (1 << TargetID)) ? 'F' : 'U')));
1753 SynchronousString[HostAdapter->SCSI_ID] = '#';
1754 SynchronousString[HostAdapter->MaxTargetDevices] = '\0';
1756 } else
1757 SynchronousMessage = (SynchronousPermitted == 0 ? "Disabled" : "Enabled");
1758 WidePermitted = HostAdapter->WidePermitted & AllTargetsMask;
1759 if (WidePermitted == 0)
1760 WideMessage = "Disabled";
1761 else if (WidePermitted == AllTargetsMask)
1762 WideMessage = "Enabled";
1763 else {
1764 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1765 WideString[TargetID] = ((WidePermitted & (1 << TargetID)) ? 'Y' : 'N');
1766 WideString[HostAdapter->SCSI_ID] = '#';
1767 WideString[HostAdapter->MaxTargetDevices] = '\0';
1769 DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
1770 if (DisconnectPermitted == 0)
1771 DisconnectMessage = "Disabled";
1772 else if (DisconnectPermitted == AllTargetsMask)
1773 DisconnectMessage = "Enabled";
1774 else {
1775 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1776 DisconnectString[TargetID] = ((DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
1777 DisconnectString[HostAdapter->SCSI_ID] = '#';
1778 DisconnectString[HostAdapter->MaxTargetDevices] = '\0';
1780 TaggedQueuingPermitted = HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
1781 if (TaggedQueuingPermitted == 0)
1782 TaggedQueuingMessage = "Disabled";
1783 else if (TaggedQueuingPermitted == AllTargetsMask)
1784 TaggedQueuingMessage = "Enabled";
1785 else {
1786 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1787 TaggedQueuingString[TargetID] = ((TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
1788 TaggedQueuingString[HostAdapter->SCSI_ID] = '#';
1789 TaggedQueuingString[HostAdapter->MaxTargetDevices] = '\0';
1791 BusLogic_Info(" Synchronous Negotiation: %s, Wide Negotiation: %s\n", HostAdapter, SynchronousMessage, WideMessage);
1792 BusLogic_Info(" Disconnect/Reconnect: %s, Tagged Queuing: %s\n", HostAdapter, DisconnectMessage, TaggedQueuingMessage);
1793 if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
1794 BusLogic_Info(" Scatter/Gather Limit: %d of %d segments, " "Mailboxes: %d\n", HostAdapter, HostAdapter->DriverScatterGatherLimit, HostAdapter->HostAdapterScatterGatherLimit, HostAdapter->MailboxCount);
1795 BusLogic_Info(" Driver Queue Depth: %d, " "Host Adapter Queue Depth: %d\n", HostAdapter, HostAdapter->DriverQueueDepth, HostAdapter->HostAdapterQueueDepth);
1796 } else
1797 BusLogic_Info(" Driver Queue Depth: %d, " "Scatter/Gather Limit: %d segments\n", HostAdapter, HostAdapter->DriverQueueDepth, HostAdapter->DriverScatterGatherLimit);
1798 BusLogic_Info(" Tagged Queue Depth: ", HostAdapter);
1799 CommonTaggedQueueDepth = true;
1800 for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1801 if (HostAdapter->QueueDepth[TargetID] != HostAdapter->QueueDepth[0]) {
1802 CommonTaggedQueueDepth = false;
1803 break;
1805 if (CommonTaggedQueueDepth) {
1806 if (HostAdapter->QueueDepth[0] > 0)
1807 BusLogic_Info("%d", HostAdapter, HostAdapter->QueueDepth[0]);
1808 else
1809 BusLogic_Info("Automatic", HostAdapter);
1810 } else
1811 BusLogic_Info("Individual", HostAdapter);
1812 BusLogic_Info(", Untagged Queue Depth: %d\n", HostAdapter, HostAdapter->UntaggedQueueDepth);
1813 if (HostAdapter->TerminationInfoValid) {
1814 if (HostAdapter->HostWideSCSI)
1815 BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter, (HostAdapter->LowByteTerminated ? (HostAdapter->HighByteTerminated ? "Both Enabled" : "Low Enabled")
1816 : (HostAdapter->HighByteTerminated ? "High Enabled" : "Both Disabled")));
1817 else
1818 BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter, (HostAdapter->LowByteTerminated ? "Enabled" : "Disabled"));
1819 if (HostAdapter->HostSupportsSCAM)
1820 BusLogic_Info(", SCAM: %s", HostAdapter, (HostAdapter->SCAM_Enabled ? (HostAdapter->SCAM_Level2 ? "Enabled, Level 2" : "Enabled, Level 1")
1821 : "Disabled"));
1822 BusLogic_Info("\n", HostAdapter);
1825 Indicate reporting the Host Adapter configuration completed successfully.
1827 return true;
1832 BusLogic_AcquireResources acquires the system resources necessary to use
1833 Host Adapter.
1836 static bool __init BusLogic_AcquireResources(struct BusLogic_HostAdapter *HostAdapter)
1838 if (HostAdapter->IRQ_Channel == 0) {
1839 BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n", HostAdapter);
1840 return false;
1843 Acquire shared access to the IRQ Channel.
1845 if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler, IRQF_SHARED, HostAdapter->FullModelName, HostAdapter) < 0) {
1846 BusLogic_Error("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n", HostAdapter, HostAdapter->IRQ_Channel);
1847 return false;
1849 HostAdapter->IRQ_ChannelAcquired = true;
1851 Acquire exclusive access to the DMA Channel.
1853 if (HostAdapter->DMA_Channel > 0) {
1854 if (request_dma(HostAdapter->DMA_Channel, HostAdapter->FullModelName) < 0) {
1855 BusLogic_Error("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n", HostAdapter, HostAdapter->DMA_Channel);
1856 return false;
1858 set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
1859 enable_dma(HostAdapter->DMA_Channel);
1860 HostAdapter->DMA_ChannelAcquired = true;
1863 Indicate the System Resource Acquisition completed successfully,
1865 return true;
1870 BusLogic_ReleaseResources releases any system resources previously acquired
1871 by BusLogic_AcquireResources.
1874 static void BusLogic_ReleaseResources(struct BusLogic_HostAdapter *HostAdapter)
1877 Release shared access to the IRQ Channel.
1879 if (HostAdapter->IRQ_ChannelAcquired)
1880 free_irq(HostAdapter->IRQ_Channel, HostAdapter);
1882 Release exclusive access to the DMA Channel.
1884 if (HostAdapter->DMA_ChannelAcquired)
1885 free_dma(HostAdapter->DMA_Channel);
1887 Release any allocated memory structs not released elsewhere
1889 if (HostAdapter->MailboxSpace)
1890 pci_free_consistent(HostAdapter->PCI_Device, HostAdapter->MailboxSize, HostAdapter->MailboxSpace, HostAdapter->MailboxSpaceHandle);
1891 pci_dev_put(HostAdapter->PCI_Device);
1892 HostAdapter->MailboxSpace = NULL;
1893 HostAdapter->MailboxSpaceHandle = 0;
1894 HostAdapter->MailboxSize = 0;
1899 BusLogic_InitializeHostAdapter initializes Host Adapter. This is the only
1900 function called during SCSI Host Adapter detection which modifies the state
1901 of the Host Adapter from its initial power on or hard reset state.
1904 static bool BusLogic_InitializeHostAdapter(struct BusLogic_HostAdapter
1905 *HostAdapter)
1907 struct BusLogic_ExtendedMailboxRequest ExtendedMailboxRequest;
1908 enum BusLogic_RoundRobinModeRequest RoundRobinModeRequest;
1909 enum BusLogic_SetCCBFormatRequest SetCCBFormatRequest;
1910 int TargetID;
1912 Initialize the pointers to the first and last CCBs that are queued for
1913 completion processing.
1915 HostAdapter->FirstCompletedCCB = NULL;
1916 HostAdapter->LastCompletedCCB = NULL;
1918 Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active,
1919 Command Successful Flag, Active Commands, and Commands Since Reset
1920 for each Target Device.
1922 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
1923 HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
1924 HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
1925 HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
1926 HostAdapter->ActiveCommands[TargetID] = 0;
1927 HostAdapter->CommandsSinceReset[TargetID] = 0;
1930 FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes.
1932 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1933 goto Done;
1935 Initialize the Outgoing and Incoming Mailbox pointers.
1937 HostAdapter->MailboxSize = HostAdapter->MailboxCount * (sizeof(struct BusLogic_OutgoingMailbox) + sizeof(struct BusLogic_IncomingMailbox));
1938 HostAdapter->MailboxSpace = pci_alloc_consistent(HostAdapter->PCI_Device, HostAdapter->MailboxSize, &HostAdapter->MailboxSpaceHandle);
1939 if (HostAdapter->MailboxSpace == NULL)
1940 return BusLogic_Failure(HostAdapter, "MAILBOX ALLOCATION");
1941 HostAdapter->FirstOutgoingMailbox = (struct BusLogic_OutgoingMailbox *) HostAdapter->MailboxSpace;
1942 HostAdapter->LastOutgoingMailbox = HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1;
1943 HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
1944 HostAdapter->FirstIncomingMailbox = (struct BusLogic_IncomingMailbox *) (HostAdapter->LastOutgoingMailbox + 1);
1945 HostAdapter->LastIncomingMailbox = HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1;
1946 HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
1949 Initialize the Outgoing and Incoming Mailbox structures.
1951 memset(HostAdapter->FirstOutgoingMailbox, 0, HostAdapter->MailboxCount * sizeof(struct BusLogic_OutgoingMailbox));
1952 memset(HostAdapter->FirstIncomingMailbox, 0, HostAdapter->MailboxCount * sizeof(struct BusLogic_IncomingMailbox));
1954 Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes.
1956 ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount;
1957 ExtendedMailboxRequest.BaseMailboxAddress = (u32) HostAdapter->MailboxSpaceHandle;
1958 if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox, &ExtendedMailboxRequest, sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
1959 return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION");
1961 Enable Strict Round Robin Mode if supported by the Host Adapter. In
1962 Strict Round Robin Mode, the Host Adapter only looks at the next Outgoing
1963 Mailbox for each new command, rather than scanning through all the
1964 Outgoing Mailboxes to find any that have new commands in them. Strict
1965 Round Robin Mode is significantly more efficient.
1967 if (HostAdapter->StrictRoundRobinModeSupport) {
1968 RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
1969 if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode, &RoundRobinModeRequest, sizeof(RoundRobinModeRequest), NULL, 0) < 0)
1970 return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
1973 For Host Adapters that support Extended LUN Format CCBs, issue the Set CCB
1974 Format command to allow 32 Logical Units per Target Device.
1976 if (HostAdapter->ExtendedLUNSupport) {
1977 SetCCBFormatRequest = BusLogic_ExtendedLUNFormatCCB;
1978 if (BusLogic_Command(HostAdapter, BusLogic_SetCCBFormat, &SetCCBFormatRequest, sizeof(SetCCBFormatRequest), NULL, 0) < 0)
1979 return BusLogic_Failure(HostAdapter, "SET CCB FORMAT");
1982 Announce Successful Initialization.
1984 Done:
1985 if (!HostAdapter->HostAdapterInitialized) {
1986 BusLogic_Info("*** %s Initialized Successfully ***\n", HostAdapter, HostAdapter->FullModelName);
1987 BusLogic_Info("\n", HostAdapter);
1988 } else
1989 BusLogic_Warning("*** %s Initialized Successfully ***\n", HostAdapter, HostAdapter->FullModelName);
1990 HostAdapter->HostAdapterInitialized = true;
1992 Indicate the Host Adapter Initialization completed successfully.
1994 return true;
1999 BusLogic_TargetDeviceInquiry inquires about the Target Devices accessible
2000 through Host Adapter.
2003 static bool __init BusLogic_TargetDeviceInquiry(struct BusLogic_HostAdapter
2004 *HostAdapter)
2006 u16 InstalledDevices;
2007 u8 InstalledDevicesID0to7[8];
2008 struct BusLogic_SetupInformation SetupInformation;
2009 u8 SynchronousPeriod[BusLogic_MaxTargetDevices];
2010 unsigned char RequestedReplyLength;
2011 int TargetID;
2013 Wait a few seconds between the Host Adapter Hard Reset which initiates
2014 a SCSI Bus Reset and issuing any SCSI Commands. Some SCSI devices get
2015 confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
2017 BusLogic_Delay(HostAdapter->BusSettleTime);
2019 FlashPoint Host Adapters do not provide for Target Device Inquiry.
2021 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
2022 return true;
2024 Inhibit the Target Device Inquiry if requested.
2026 if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
2027 return true;
2029 Issue the Inquire Target Devices command for host adapters with firmware
2030 version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command
2031 for older host adapters. This is necessary to force Synchronous Transfer
2032 Negotiation so that the Inquire Setup Information and Inquire Synchronous
2033 Period commands will return valid data. The Inquire Target Devices command
2034 is preferable to Inquire Installed Devices ID 0 to 7 since it only probes
2035 Logical Unit 0 of each Target Device.
2037 if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0) {
2040 * Issue a Inquire Target Devices command. Inquire Target Devices only
2041 * tests Logical Unit 0 of each Target Device unlike the Inquire Installed
2042 * Devices commands which test Logical Units 0 - 7. Two bytes are
2043 * returned, where byte 0 bit 0 set indicates that Target Device 0 exists,
2044 * and so on.
2047 if (BusLogic_Command(HostAdapter, BusLogic_InquireTargetDevices, NULL, 0, &InstalledDevices, sizeof(InstalledDevices))
2048 != sizeof(InstalledDevices))
2049 return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES");
2050 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2051 HostAdapter->TargetFlags[TargetID].TargetExists = (InstalledDevices & (1 << TargetID) ? true : false);
2052 } else {
2055 * Issue an Inquire Installed Devices command. For each Target Device,
2056 * a byte is returned where bit 0 set indicates that Logical Unit 0
2057 * exists, bit 1 set indicates that Logical Unit 1 exists, and so on.
2060 if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7, NULL, 0, &InstalledDevicesID0to7, sizeof(InstalledDevicesID0to7))
2061 != sizeof(InstalledDevicesID0to7))
2062 return BusLogic_Failure(HostAdapter, "INQUIRE INSTALLED DEVICES ID 0 TO 7");
2063 for (TargetID = 0; TargetID < 8; TargetID++)
2064 HostAdapter->TargetFlags[TargetID].TargetExists = (InstalledDevicesID0to7[TargetID] != 0 ? true : false);
2067 Issue the Inquire Setup Information command.
2069 RequestedReplyLength = sizeof(SetupInformation);
2070 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &SetupInformation, sizeof(SetupInformation))
2071 != sizeof(SetupInformation))
2072 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
2073 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2074 HostAdapter->SynchronousOffset[TargetID] = (TargetID < 8 ? SetupInformation.SynchronousValuesID0to7[TargetID].Offset : SetupInformation.SynchronousValuesID8to15[TargetID - 8].Offset);
2075 if (strcmp(HostAdapter->FirmwareVersion, "5.06L") >= 0)
2076 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2077 HostAdapter->TargetFlags[TargetID].WideTransfersActive = (TargetID < 8 ? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID)
2078 ? true : false)
2079 : (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID - 8))
2080 ? true : false));
2082 Issue the Inquire Synchronous Period command.
2084 if (HostAdapter->FirmwareVersion[0] >= '3') {
2086 /* Issue a Inquire Synchronous Period command. For each Target Device,
2087 * a byte is returned which represents the Synchronous Transfer Period
2088 * in units of 10 nanoseconds.
2091 RequestedReplyLength = sizeof(SynchronousPeriod);
2092 if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod, &RequestedReplyLength, sizeof(RequestedReplyLength), &SynchronousPeriod, sizeof(SynchronousPeriod))
2093 != sizeof(SynchronousPeriod))
2094 return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
2095 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2096 HostAdapter->SynchronousPeriod[TargetID] = SynchronousPeriod[TargetID];
2097 } else
2098 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2099 if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
2100 HostAdapter->SynchronousPeriod[TargetID] = 20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
2101 .TransferPeriod;
2103 Indicate the Target Device Inquiry completed successfully.
2105 return true;
2109 BusLogic_InitializeHostStructure initializes the fields in the SCSI Host
2110 structure. The base, io_port, n_io_ports, irq, and dma_channel fields in the
2111 SCSI Host structure are intentionally left uninitialized, as this driver
2112 handles acquisition and release of these resources explicitly, as well as
2113 ensuring exclusive access to the Host Adapter hardware and data structures
2114 through explicit acquisition and release of the Host Adapter's Lock.
2117 static void __init BusLogic_InitializeHostStructure(struct BusLogic_HostAdapter
2118 *HostAdapter, struct Scsi_Host *Host)
2120 Host->max_id = HostAdapter->MaxTargetDevices;
2121 Host->max_lun = HostAdapter->MaxLogicalUnits;
2122 Host->max_channel = 0;
2123 Host->unique_id = HostAdapter->IO_Address;
2124 Host->this_id = HostAdapter->SCSI_ID;
2125 Host->can_queue = HostAdapter->DriverQueueDepth;
2126 Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
2127 Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
2128 Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth;
2132 BusLogic_SlaveConfigure will actually set the queue depth on individual
2133 scsi devices as they are permanently added to the device chain. We
2134 shamelessly rip off the SelectQueueDepths code to make this work mostly
2135 like it used to. Since we don't get called once at the end of the scan
2136 but instead get called for each device, we have to do things a bit
2137 differently.
2139 static int BusLogic_SlaveConfigure(struct scsi_device *Device)
2141 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Device->host->hostdata;
2142 int TargetID = Device->id;
2143 int QueueDepth = HostAdapter->QueueDepth[TargetID];
2145 if (HostAdapter->TargetFlags[TargetID].TaggedQueuingSupported && (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) {
2146 if (QueueDepth == 0)
2147 QueueDepth = BusLogic_MaxAutomaticTaggedQueueDepth;
2148 HostAdapter->QueueDepth[TargetID] = QueueDepth;
2149 scsi_adjust_queue_depth(Device, MSG_SIMPLE_TAG, QueueDepth);
2150 } else {
2151 HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
2152 QueueDepth = HostAdapter->UntaggedQueueDepth;
2153 HostAdapter->QueueDepth[TargetID] = QueueDepth;
2154 scsi_adjust_queue_depth(Device, 0, QueueDepth);
2156 QueueDepth = 0;
2157 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2158 if (HostAdapter->TargetFlags[TargetID].TargetExists) {
2159 QueueDepth += HostAdapter->QueueDepth[TargetID];
2161 if (QueueDepth > HostAdapter->AllocatedCCBs)
2162 BusLogic_CreateAdditionalCCBs(HostAdapter, QueueDepth - HostAdapter->AllocatedCCBs, false);
2163 return 0;
2167 BusLogic_DetectHostAdapter probes for BusLogic Host Adapters at the standard
2168 I/O Addresses where they may be located, initializing, registering, and
2169 reporting the configuration of each BusLogic Host Adapter it finds. It
2170 returns the number of BusLogic Host Adapters successfully initialized and
2171 registered.
2174 static int __init BusLogic_init(void)
2176 int BusLogicHostAdapterCount = 0, DriverOptionsIndex = 0, ProbeIndex;
2177 struct BusLogic_HostAdapter *PrototypeHostAdapter;
2178 int ret = 0;
2180 #ifdef MODULE
2181 if (BusLogic)
2182 BusLogic_Setup(BusLogic);
2183 #endif
2185 if (BusLogic_ProbeOptions.NoProbe)
2186 return -ENODEV;
2187 BusLogic_ProbeInfoList =
2188 kzalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo), GFP_KERNEL);
2189 if (BusLogic_ProbeInfoList == NULL) {
2190 BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL);
2191 return -ENOMEM;
2194 PrototypeHostAdapter =
2195 kzalloc(sizeof(struct BusLogic_HostAdapter), GFP_KERNEL);
2196 if (PrototypeHostAdapter == NULL) {
2197 kfree(BusLogic_ProbeInfoList);
2198 BusLogic_Error("BusLogic: Unable to allocate Prototype " "Host Adapter\n", NULL);
2199 return -ENOMEM;
2202 #ifdef MODULE
2203 if (BusLogic != NULL)
2204 BusLogic_Setup(BusLogic);
2205 #endif
2206 BusLogic_InitializeProbeInfoList(PrototypeHostAdapter);
2207 for (ProbeIndex = 0; ProbeIndex < BusLogic_ProbeInfoCount; ProbeIndex++) {
2208 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[ProbeIndex];
2209 struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter;
2210 struct Scsi_Host *Host;
2211 if (ProbeInfo->IO_Address == 0)
2212 continue;
2213 memset(HostAdapter, 0, sizeof(struct BusLogic_HostAdapter));
2214 HostAdapter->HostAdapterType = ProbeInfo->HostAdapterType;
2215 HostAdapter->HostAdapterBusType = ProbeInfo->HostAdapterBusType;
2216 HostAdapter->IO_Address = ProbeInfo->IO_Address;
2217 HostAdapter->PCI_Address = ProbeInfo->PCI_Address;
2218 HostAdapter->Bus = ProbeInfo->Bus;
2219 HostAdapter->Device = ProbeInfo->Device;
2220 HostAdapter->PCI_Device = ProbeInfo->PCI_Device;
2221 HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel;
2222 HostAdapter->AddressCount = BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType];
2224 Probe the Host Adapter. If unsuccessful, abort further initialization.
2226 if (!BusLogic_ProbeHostAdapter(HostAdapter))
2227 continue;
2229 Hard Reset the Host Adapter. If unsuccessful, abort further
2230 initialization.
2232 if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true))
2233 continue;
2235 Check the Host Adapter. If unsuccessful, abort further initialization.
2237 if (!BusLogic_CheckHostAdapter(HostAdapter))
2238 continue;
2240 Initialize the Driver Options field if provided.
2242 if (DriverOptionsIndex < BusLogic_DriverOptionsCount)
2243 HostAdapter->DriverOptions = &BusLogic_DriverOptions[DriverOptionsIndex++];
2245 Announce the Driver Version and Date, Author's Name, Copyright Notice,
2246 and Electronic Mail Address.
2248 BusLogic_AnnounceDriver(HostAdapter);
2250 Register usage of the I/O Address range. From this point onward, any
2251 failure will be assumed to be due to a problem with the Host Adapter,
2252 rather than due to having mistakenly identified this port as belonging
2253 to a BusLogic Host Adapter. The I/O Address range will not be
2254 released, thereby preventing it from being incorrectly identified as
2255 any other type of Host Adapter.
2257 if (!request_region(HostAdapter->IO_Address, HostAdapter->AddressCount, "BusLogic"))
2258 continue;
2260 Register the SCSI Host structure.
2263 Host = scsi_host_alloc(&Bus_Logic_template, sizeof(struct BusLogic_HostAdapter));
2264 if (Host == NULL) {
2265 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2266 continue;
2268 HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata;
2269 memcpy(HostAdapter, PrototypeHostAdapter, sizeof(struct BusLogic_HostAdapter));
2270 HostAdapter->SCSI_Host = Host;
2271 HostAdapter->HostNumber = Host->host_no;
2273 Add Host Adapter to the end of the list of registered BusLogic
2274 Host Adapters.
2276 list_add_tail(&HostAdapter->host_list, &BusLogic_host_list);
2279 Read the Host Adapter Configuration, Configure the Host Adapter,
2280 Acquire the System Resources necessary to use the Host Adapter, then
2281 Create the Initial CCBs, Initialize the Host Adapter, and finally
2282 perform Target Device Inquiry.
2284 if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
2285 BusLogic_ReportHostAdapterConfiguration(HostAdapter) &&
2286 BusLogic_AcquireResources(HostAdapter) &&
2287 BusLogic_CreateInitialCCBs(HostAdapter) &&
2288 BusLogic_InitializeHostAdapter(HostAdapter) &&
2289 BusLogic_TargetDeviceInquiry(HostAdapter)) {
2291 Initialization has been completed successfully. Release and
2292 re-register usage of the I/O Address range so that the Model
2293 Name of the Host Adapter will appear, and initialize the SCSI
2294 Host structure.
2296 release_region(HostAdapter->IO_Address,
2297 HostAdapter->AddressCount);
2298 if (!request_region(HostAdapter->IO_Address,
2299 HostAdapter->AddressCount,
2300 HostAdapter->FullModelName)) {
2301 printk(KERN_WARNING
2302 "BusLogic: Release and re-register of "
2303 "port 0x%04lx failed \n",
2304 (unsigned long)HostAdapter->IO_Address);
2305 BusLogic_DestroyCCBs(HostAdapter);
2306 BusLogic_ReleaseResources(HostAdapter);
2307 list_del(&HostAdapter->host_list);
2308 scsi_host_put(Host);
2309 ret = -ENOMEM;
2310 } else {
2311 BusLogic_InitializeHostStructure(HostAdapter,
2312 Host);
2313 if (scsi_add_host(Host, HostAdapter->PCI_Device
2314 ? &HostAdapter->PCI_Device->dev
2315 : NULL)) {
2316 printk(KERN_WARNING
2317 "BusLogic: scsi_add_host()"
2318 "failed!\n");
2319 BusLogic_DestroyCCBs(HostAdapter);
2320 BusLogic_ReleaseResources(HostAdapter);
2321 list_del(&HostAdapter->host_list);
2322 scsi_host_put(Host);
2323 ret = -ENODEV;
2324 } else {
2325 scsi_scan_host(Host);
2326 BusLogicHostAdapterCount++;
2329 } else {
2331 An error occurred during Host Adapter Configuration Querying, Host
2332 Adapter Configuration, Resource Acquisition, CCB Creation, Host
2333 Adapter Initialization, or Target Device Inquiry, so remove Host
2334 Adapter from the list of registered BusLogic Host Adapters, destroy
2335 the CCBs, Release the System Resources, and Unregister the SCSI
2336 Host.
2338 BusLogic_DestroyCCBs(HostAdapter);
2339 BusLogic_ReleaseResources(HostAdapter);
2340 list_del(&HostAdapter->host_list);
2341 scsi_host_put(Host);
2342 ret = -ENODEV;
2345 kfree(PrototypeHostAdapter);
2346 kfree(BusLogic_ProbeInfoList);
2347 BusLogic_ProbeInfoList = NULL;
2348 return ret;
2353 BusLogic_ReleaseHostAdapter releases all resources previously acquired to
2354 support a specific Host Adapter, including the I/O Address range, and
2355 unregisters the BusLogic Host Adapter.
2358 static int __exit BusLogic_ReleaseHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
2360 struct Scsi_Host *Host = HostAdapter->SCSI_Host;
2362 scsi_remove_host(Host);
2365 FlashPoint Host Adapters must first be released by the FlashPoint
2366 SCCB Manager.
2368 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
2369 FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle);
2371 Destroy the CCBs and release any system resources acquired to
2372 support Host Adapter.
2374 BusLogic_DestroyCCBs(HostAdapter);
2375 BusLogic_ReleaseResources(HostAdapter);
2377 Release usage of the I/O Address range.
2379 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2381 Remove Host Adapter from the list of registered BusLogic Host Adapters.
2383 list_del(&HostAdapter->host_list);
2385 scsi_host_put(Host);
2386 return 0;
2391 BusLogic_QueueCompletedCCB queues CCB for completion processing.
2394 static void BusLogic_QueueCompletedCCB(struct BusLogic_CCB *CCB)
2396 struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter;
2397 CCB->Status = BusLogic_CCB_Completed;
2398 CCB->Next = NULL;
2399 if (HostAdapter->FirstCompletedCCB == NULL) {
2400 HostAdapter->FirstCompletedCCB = CCB;
2401 HostAdapter->LastCompletedCCB = CCB;
2402 } else {
2403 HostAdapter->LastCompletedCCB->Next = CCB;
2404 HostAdapter->LastCompletedCCB = CCB;
2406 HostAdapter->ActiveCommands[CCB->TargetID]--;
2411 BusLogic_ComputeResultCode computes a SCSI Subsystem Result Code from
2412 the Host Adapter Status and Target Device Status.
2415 static int BusLogic_ComputeResultCode(struct BusLogic_HostAdapter *HostAdapter, enum BusLogic_HostAdapterStatus HostAdapterStatus, enum BusLogic_TargetDeviceStatus TargetDeviceStatus)
2417 int HostStatus;
2418 switch (HostAdapterStatus) {
2419 case BusLogic_CommandCompletedNormally:
2420 case BusLogic_LinkedCommandCompleted:
2421 case BusLogic_LinkedCommandCompletedWithFlag:
2422 HostStatus = DID_OK;
2423 break;
2424 case BusLogic_SCSISelectionTimeout:
2425 HostStatus = DID_TIME_OUT;
2426 break;
2427 case BusLogic_InvalidOutgoingMailboxActionCode:
2428 case BusLogic_InvalidCommandOperationCode:
2429 case BusLogic_InvalidCommandParameter:
2430 BusLogic_Warning("BusLogic Driver Protocol Error 0x%02X\n", HostAdapter, HostAdapterStatus);
2431 case BusLogic_DataUnderRun:
2432 case BusLogic_DataOverRun:
2433 case BusLogic_UnexpectedBusFree:
2434 case BusLogic_LinkedCCBhasInvalidLUN:
2435 case BusLogic_AutoRequestSenseFailed:
2436 case BusLogic_TaggedQueuingMessageRejected:
2437 case BusLogic_UnsupportedMessageReceived:
2438 case BusLogic_HostAdapterHardwareFailed:
2439 case BusLogic_TargetDeviceReconnectedImproperly:
2440 case BusLogic_AbortQueueGenerated:
2441 case BusLogic_HostAdapterSoftwareError:
2442 case BusLogic_HostAdapterHardwareTimeoutError:
2443 case BusLogic_SCSIParityErrorDetected:
2444 HostStatus = DID_ERROR;
2445 break;
2446 case BusLogic_InvalidBusPhaseRequested:
2447 case BusLogic_TargetFailedResponseToATN:
2448 case BusLogic_HostAdapterAssertedRST:
2449 case BusLogic_OtherDeviceAssertedRST:
2450 case BusLogic_HostAdapterAssertedBusDeviceReset:
2451 HostStatus = DID_RESET;
2452 break;
2453 default:
2454 BusLogic_Warning("Unknown Host Adapter Status 0x%02X\n", HostAdapter, HostAdapterStatus);
2455 HostStatus = DID_ERROR;
2456 break;
2458 return (HostStatus << 16) | TargetDeviceStatus;
2463 BusLogic_ScanIncomingMailboxes scans the Incoming Mailboxes saving any
2464 Incoming Mailbox entries for completion processing.
2467 static void BusLogic_ScanIncomingMailboxes(struct BusLogic_HostAdapter *HostAdapter)
2470 Scan through the Incoming Mailboxes in Strict Round Robin fashion, saving
2471 any completed CCBs for further processing. It is essential that for each
2472 CCB and SCSI Command issued, command completion processing is performed
2473 exactly once. Therefore, only Incoming Mailboxes with completion code
2474 Command Completed Without Error, Command Completed With Error, or Command
2475 Aborted At Host Request are saved for completion processing. When an
2476 Incoming Mailbox has a completion code of Aborted Command Not Found, the
2477 CCB had already completed or been aborted before the current Abort request
2478 was processed, and so completion processing has already occurred and no
2479 further action should be taken.
2481 struct BusLogic_IncomingMailbox *NextIncomingMailbox = HostAdapter->NextIncomingMailbox;
2482 enum BusLogic_CompletionCode CompletionCode;
2483 while ((CompletionCode = NextIncomingMailbox->CompletionCode) != BusLogic_IncomingMailboxFree) {
2485 We are only allowed to do this because we limit our architectures we
2486 run on to machines where bus_to_virt() actually works. There *needs*
2487 to be a dma_addr_to_virt() in the new PCI DMA mapping interface to
2488 replace bus_to_virt() or else this code is going to become very
2489 innefficient.
2491 struct BusLogic_CCB *CCB = (struct BusLogic_CCB *) Bus_to_Virtual(NextIncomingMailbox->CCB);
2492 if (CompletionCode != BusLogic_AbortedCommandNotFound) {
2493 if (CCB->Status == BusLogic_CCB_Active || CCB->Status == BusLogic_CCB_Reset) {
2495 Save the Completion Code for this CCB and queue the CCB
2496 for completion processing.
2498 CCB->CompletionCode = CompletionCode;
2499 BusLogic_QueueCompletedCCB(CCB);
2500 } else {
2502 If a CCB ever appears in an Incoming Mailbox and is not marked
2503 as status Active or Reset, then there is most likely a bug in
2504 the Host Adapter firmware.
2506 BusLogic_Warning("Illegal CCB #%ld status %d in " "Incoming Mailbox\n", HostAdapter, CCB->SerialNumber, CCB->Status);
2509 NextIncomingMailbox->CompletionCode = BusLogic_IncomingMailboxFree;
2510 if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
2511 NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
2513 HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
2518 BusLogic_ProcessCompletedCCBs iterates over the completed CCBs for Host
2519 Adapter setting the SCSI Command Result Codes, deallocating the CCBs, and
2520 calling the SCSI Subsystem Completion Routines. The Host Adapter's Lock
2521 should already have been acquired by the caller.
2524 static void BusLogic_ProcessCompletedCCBs(struct BusLogic_HostAdapter *HostAdapter)
2526 if (HostAdapter->ProcessCompletedCCBsActive)
2527 return;
2528 HostAdapter->ProcessCompletedCCBsActive = true;
2529 while (HostAdapter->FirstCompletedCCB != NULL) {
2530 struct BusLogic_CCB *CCB = HostAdapter->FirstCompletedCCB;
2531 struct scsi_cmnd *Command = CCB->Command;
2532 HostAdapter->FirstCompletedCCB = CCB->Next;
2533 if (HostAdapter->FirstCompletedCCB == NULL)
2534 HostAdapter->LastCompletedCCB = NULL;
2536 Process the Completed CCB.
2538 if (CCB->Opcode == BusLogic_BusDeviceReset) {
2539 int TargetID = CCB->TargetID;
2540 BusLogic_Warning("Bus Device Reset CCB #%ld to Target " "%d Completed\n", HostAdapter, CCB->SerialNumber, TargetID);
2541 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].BusDeviceResetsCompleted);
2542 HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
2543 HostAdapter->CommandsSinceReset[TargetID] = 0;
2544 HostAdapter->LastResetCompleted[TargetID] = jiffies;
2546 Place CCB back on the Host Adapter's free list.
2548 BusLogic_DeallocateCCB(CCB);
2549 #if 0 /* this needs to be redone different for new EH */
2551 Bus Device Reset CCBs have the Command field non-NULL only when a
2552 Bus Device Reset was requested for a Command that did not have a
2553 currently active CCB in the Host Adapter (i.e., a Synchronous
2554 Bus Device Reset), and hence would not have its Completion Routine
2555 called otherwise.
2557 while (Command != NULL) {
2558 struct scsi_cmnd *NextCommand = Command->reset_chain;
2559 Command->reset_chain = NULL;
2560 Command->result = DID_RESET << 16;
2561 Command->scsi_done(Command);
2562 Command = NextCommand;
2564 #endif
2566 Iterate over the CCBs for this Host Adapter performing completion
2567 processing for any CCBs marked as Reset for this Target.
2569 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2570 if (CCB->Status == BusLogic_CCB_Reset && CCB->TargetID == TargetID) {
2571 Command = CCB->Command;
2572 BusLogic_DeallocateCCB(CCB);
2573 HostAdapter->ActiveCommands[TargetID]--;
2574 Command->result = DID_RESET << 16;
2575 Command->scsi_done(Command);
2577 HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
2578 } else {
2580 Translate the Completion Code, Host Adapter Status, and Target
2581 Device Status into a SCSI Subsystem Result Code.
2583 switch (CCB->CompletionCode) {
2584 case BusLogic_IncomingMailboxFree:
2585 case BusLogic_AbortedCommandNotFound:
2586 case BusLogic_InvalidCCB:
2587 BusLogic_Warning("CCB #%ld to Target %d Impossible State\n", HostAdapter, CCB->SerialNumber, CCB->TargetID);
2588 break;
2589 case BusLogic_CommandCompletedWithoutError:
2590 HostAdapter->TargetStatistics[CCB->TargetID]
2591 .CommandsCompleted++;
2592 HostAdapter->TargetFlags[CCB->TargetID]
2593 .CommandSuccessfulFlag = true;
2594 Command->result = DID_OK << 16;
2595 break;
2596 case BusLogic_CommandAbortedAtHostRequest:
2597 BusLogic_Warning("CCB #%ld to Target %d Aborted\n", HostAdapter, CCB->SerialNumber, CCB->TargetID);
2598 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[CCB->TargetID]
2599 .CommandAbortsCompleted);
2600 Command->result = DID_ABORT << 16;
2601 break;
2602 case BusLogic_CommandCompletedWithError:
2603 Command->result = BusLogic_ComputeResultCode(HostAdapter, CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
2604 if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout) {
2605 HostAdapter->TargetStatistics[CCB->TargetID]
2606 .CommandsCompleted++;
2607 if (BusLogic_GlobalOptions.TraceErrors) {
2608 int i;
2609 BusLogic_Notice("CCB #%ld Target %d: Result %X Host "
2610 "Adapter Status %02X " "Target Status %02X\n", HostAdapter, CCB->SerialNumber, CCB->TargetID, Command->result, CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
2611 BusLogic_Notice("CDB ", HostAdapter);
2612 for (i = 0; i < CCB->CDB_Length; i++)
2613 BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]);
2614 BusLogic_Notice("\n", HostAdapter);
2615 BusLogic_Notice("Sense ", HostAdapter);
2616 for (i = 0; i < CCB->SenseDataLength; i++)
2617 BusLogic_Notice(" %02X", HostAdapter, Command->sense_buffer[i]);
2618 BusLogic_Notice("\n", HostAdapter);
2621 break;
2624 When an INQUIRY command completes normally, save the
2625 CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit
2626 Wide Data Transfers Supported) bits.
2628 if (CCB->CDB[0] == INQUIRY && CCB->CDB[1] == 0 && CCB->HostAdapterStatus == BusLogic_CommandCompletedNormally) {
2629 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[CCB->TargetID];
2630 struct SCSI_Inquiry *InquiryResult = (struct SCSI_Inquiry *) Command->request_buffer;
2631 TargetFlags->TargetExists = true;
2632 TargetFlags->TaggedQueuingSupported = InquiryResult->CmdQue;
2633 TargetFlags->WideTransfersSupported = InquiryResult->WBus16;
2636 Place CCB back on the Host Adapter's free list.
2638 BusLogic_DeallocateCCB(CCB);
2640 Call the SCSI Command Completion Routine.
2642 Command->scsi_done(Command);
2645 HostAdapter->ProcessCompletedCCBsActive = false;
2650 BusLogic_InterruptHandler handles hardware interrupts from BusLogic Host
2651 Adapters.
2654 static irqreturn_t BusLogic_InterruptHandler(int IRQ_Channel, void *DeviceIdentifier)
2656 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) DeviceIdentifier;
2657 unsigned long ProcessorFlags;
2659 Acquire exclusive access to Host Adapter.
2661 spin_lock_irqsave(HostAdapter->SCSI_Host->host_lock, ProcessorFlags);
2663 Handle Interrupts appropriately for each Host Adapter type.
2665 if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
2666 union BusLogic_InterruptRegister InterruptRegister;
2668 Read the Host Adapter Interrupt Register.
2670 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
2671 if (InterruptRegister.ir.InterruptValid) {
2673 Acknowledge the interrupt and reset the Host Adapter
2674 Interrupt Register.
2676 BusLogic_InterruptReset(HostAdapter);
2678 Process valid External SCSI Bus Reset and Incoming Mailbox
2679 Loaded Interrupts. Command Complete Interrupts are noted,
2680 and Outgoing Mailbox Available Interrupts are ignored, as
2681 they are never enabled.
2683 if (InterruptRegister.ir.ExternalBusReset)
2684 HostAdapter->HostAdapterExternalReset = true;
2685 else if (InterruptRegister.ir.IncomingMailboxLoaded)
2686 BusLogic_ScanIncomingMailboxes(HostAdapter);
2687 else if (InterruptRegister.ir.CommandComplete)
2688 HostAdapter->HostAdapterCommandCompleted = true;
2690 } else {
2692 Check if there is a pending interrupt for this Host Adapter.
2694 if (FlashPoint_InterruptPending(HostAdapter->CardHandle))
2695 switch (FlashPoint_HandleInterrupt(HostAdapter->CardHandle)) {
2696 case FlashPoint_NormalInterrupt:
2697 break;
2698 case FlashPoint_ExternalBusReset:
2699 HostAdapter->HostAdapterExternalReset = true;
2700 break;
2701 case FlashPoint_InternalError:
2702 BusLogic_Warning("Internal FlashPoint Error detected" " - Resetting Host Adapter\n", HostAdapter);
2703 HostAdapter->HostAdapterInternalError = true;
2704 break;
2708 Process any completed CCBs.
2710 if (HostAdapter->FirstCompletedCCB != NULL)
2711 BusLogic_ProcessCompletedCCBs(HostAdapter);
2713 Reset the Host Adapter if requested.
2715 if (HostAdapter->HostAdapterExternalReset) {
2716 BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n", HostAdapter, HostAdapter->FullModelName);
2717 BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets);
2718 BusLogic_ResetHostAdapter(HostAdapter, false);
2719 HostAdapter->HostAdapterExternalReset = false;
2720 } else if (HostAdapter->HostAdapterInternalError) {
2721 BusLogic_Warning("Resetting %s due to Host Adapter Internal Error\n", HostAdapter, HostAdapter->FullModelName);
2722 BusLogic_IncrementErrorCounter(&HostAdapter->HostAdapterInternalErrors);
2723 BusLogic_ResetHostAdapter(HostAdapter, true);
2724 HostAdapter->HostAdapterInternalError = false;
2727 Release exclusive access to Host Adapter.
2729 spin_unlock_irqrestore(HostAdapter->SCSI_Host->host_lock, ProcessorFlags);
2730 return IRQ_HANDLED;
2735 BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
2736 Mailbox for execution by Host Adapter. The Host Adapter's Lock should
2737 already have been acquired by the caller.
2740 static bool BusLogic_WriteOutgoingMailbox(struct BusLogic_HostAdapter
2741 *HostAdapter, enum BusLogic_ActionCode ActionCode, struct BusLogic_CCB *CCB)
2743 struct BusLogic_OutgoingMailbox *NextOutgoingMailbox;
2744 NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
2745 if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree) {
2746 CCB->Status = BusLogic_CCB_Active;
2748 The CCB field must be written before the Action Code field since
2749 the Host Adapter is operating asynchronously and the locking code
2750 does not protect against simultaneous access by the Host Adapter.
2752 NextOutgoingMailbox->CCB = CCB->DMA_Handle;
2753 NextOutgoingMailbox->ActionCode = ActionCode;
2754 BusLogic_StartMailboxCommand(HostAdapter);
2755 if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
2756 NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
2757 HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
2758 if (ActionCode == BusLogic_MailboxStartCommand) {
2759 HostAdapter->ActiveCommands[CCB->TargetID]++;
2760 if (CCB->Opcode != BusLogic_BusDeviceReset)
2761 HostAdapter->TargetStatistics[CCB->TargetID].CommandsAttempted++;
2763 return true;
2765 return false;
2768 /* Error Handling (EH) support */
2770 static int BusLogic_host_reset(struct scsi_cmnd * SCpnt)
2772 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) SCpnt->device->host->hostdata;
2774 unsigned int id = SCpnt->device->id;
2775 struct BusLogic_TargetStatistics *stats = &HostAdapter->TargetStatistics[id];
2776 int rc;
2778 spin_lock_irq(SCpnt->device->host->host_lock);
2780 BusLogic_IncrementErrorCounter(&stats->HostAdapterResetsRequested);
2782 rc = BusLogic_ResetHostAdapter(HostAdapter, false);
2783 spin_unlock_irq(SCpnt->device->host->host_lock);
2784 return rc;
2788 BusLogic_QueueCommand creates a CCB for Command and places it into an
2789 Outgoing Mailbox for execution by the associated Host Adapter.
2792 static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRoutine) (struct scsi_cmnd *))
2794 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata;
2795 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[Command->device->id];
2796 struct BusLogic_TargetStatistics *TargetStatistics = HostAdapter->TargetStatistics;
2797 unsigned char *CDB = Command->cmnd;
2798 int CDB_Length = Command->cmd_len;
2799 int TargetID = Command->device->id;
2800 int LogicalUnit = Command->device->lun;
2801 void *BufferPointer = Command->request_buffer;
2802 int BufferLength = Command->request_bufflen;
2803 int SegmentCount = Command->use_sg;
2804 struct BusLogic_CCB *CCB;
2806 SCSI REQUEST_SENSE commands will be executed automatically by the Host
2807 Adapter for any errors, so they should not be executed explicitly unless
2808 the Sense Data is zero indicating that no error occurred.
2810 if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0) {
2811 Command->result = DID_OK << 16;
2812 CompletionRoutine(Command);
2813 return 0;
2816 Allocate a CCB from the Host Adapter's free list. In the unlikely event
2817 that there are none available and memory allocation fails, wait 1 second
2818 and try again. If that fails, the Host Adapter is probably hung so signal
2819 an error as a Host Adapter Hard Reset should be initiated soon.
2821 CCB = BusLogic_AllocateCCB(HostAdapter);
2822 if (CCB == NULL) {
2823 spin_unlock_irq(HostAdapter->SCSI_Host->host_lock);
2824 BusLogic_Delay(1);
2825 spin_lock_irq(HostAdapter->SCSI_Host->host_lock);
2826 CCB = BusLogic_AllocateCCB(HostAdapter);
2827 if (CCB == NULL) {
2828 Command->result = DID_ERROR << 16;
2829 CompletionRoutine(Command);
2830 return 0;
2834 Initialize the fields in the BusLogic Command Control Block (CCB).
2836 if (SegmentCount == 0 && BufferLength != 0) {
2837 CCB->Opcode = BusLogic_InitiatorCCB;
2838 CCB->DataLength = BufferLength;
2839 CCB->DataPointer = pci_map_single(HostAdapter->PCI_Device,
2840 BufferPointer, BufferLength,
2841 Command->sc_data_direction);
2842 } else if (SegmentCount != 0) {
2843 struct scatterlist *ScatterList = (struct scatterlist *) BufferPointer;
2844 int Segment, Count;
2846 Count = pci_map_sg(HostAdapter->PCI_Device, ScatterList, SegmentCount,
2847 Command->sc_data_direction);
2848 CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
2849 CCB->DataLength = Count * sizeof(struct BusLogic_ScatterGatherSegment);
2850 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
2851 CCB->DataPointer = (unsigned int) CCB->DMA_Handle + ((unsigned long) &CCB->ScatterGatherList - (unsigned long) CCB);
2852 else
2853 CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList);
2854 for (Segment = 0; Segment < Count; Segment++) {
2855 CCB->ScatterGatherList[Segment].SegmentByteCount = sg_dma_len(ScatterList + Segment);
2856 CCB->ScatterGatherList[Segment].SegmentDataPointer = sg_dma_address(ScatterList + Segment);
2858 } else {
2859 CCB->Opcode = BusLogic_InitiatorCCB;
2860 CCB->DataLength = BufferLength;
2861 CCB->DataPointer = 0;
2863 switch (CDB[0]) {
2864 case READ_6:
2865 case READ_10:
2866 CCB->DataDirection = BusLogic_DataInLengthChecked;
2867 TargetStatistics[TargetID].ReadCommands++;
2868 BusLogic_IncrementByteCounter(&TargetStatistics[TargetID].TotalBytesRead, BufferLength);
2869 BusLogic_IncrementSizeBucket(TargetStatistics[TargetID].ReadCommandSizeBuckets, BufferLength);
2870 break;
2871 case WRITE_6:
2872 case WRITE_10:
2873 CCB->DataDirection = BusLogic_DataOutLengthChecked;
2874 TargetStatistics[TargetID].WriteCommands++;
2875 BusLogic_IncrementByteCounter(&TargetStatistics[TargetID].TotalBytesWritten, BufferLength);
2876 BusLogic_IncrementSizeBucket(TargetStatistics[TargetID].WriteCommandSizeBuckets, BufferLength);
2877 break;
2878 default:
2879 CCB->DataDirection = BusLogic_UncheckedDataTransfer;
2880 break;
2882 CCB->CDB_Length = CDB_Length;
2883 CCB->HostAdapterStatus = 0;
2884 CCB->TargetDeviceStatus = 0;
2885 CCB->TargetID = TargetID;
2886 CCB->LogicalUnit = LogicalUnit;
2887 CCB->TagEnable = false;
2888 CCB->LegacyTagEnable = false;
2890 BusLogic recommends that after a Reset the first couple of commands that
2891 are sent to a Target Device be sent in a non Tagged Queue fashion so that
2892 the Host Adapter and Target Device can establish Synchronous and Wide
2893 Transfer before Queue Tag messages can interfere with the Synchronous and
2894 Wide Negotiation messages. By waiting to enable Tagged Queuing until after
2895 the first BusLogic_MaxTaggedQueueDepth commands have been queued, it is
2896 assured that after a Reset any pending commands are requeued before Tagged
2897 Queuing is enabled and that the Tagged Queuing message will not occur while
2898 the partition table is being printed. In addition, some devices do not
2899 properly handle the transition from non-tagged to tagged commands, so it is
2900 necessary to wait until there are no pending commands for a target device
2901 before queuing tagged commands.
2903 if (HostAdapter->CommandsSinceReset[TargetID]++ >=
2904 BusLogic_MaxTaggedQueueDepth && !TargetFlags->TaggedQueuingActive && HostAdapter->ActiveCommands[TargetID] == 0 && TargetFlags->TaggedQueuingSupported && (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) {
2905 TargetFlags->TaggedQueuingActive = true;
2906 BusLogic_Notice("Tagged Queuing now active for Target %d\n", HostAdapter, TargetID);
2908 if (TargetFlags->TaggedQueuingActive) {
2909 enum BusLogic_QueueTag QueueTag = BusLogic_SimpleQueueTag;
2911 When using Tagged Queuing with Simple Queue Tags, it appears that disk
2912 drive controllers do not guarantee that a queued command will not
2913 remain in a disconnected state indefinitely if commands that read or
2914 write nearer the head position continue to arrive without interruption.
2915 Therefore, for each Target Device this driver keeps track of the last
2916 time either the queue was empty or an Ordered Queue Tag was issued. If
2917 more than 4 seconds (one fifth of the 20 second disk timeout) have
2918 elapsed since this last sequence point, this command will be issued
2919 with an Ordered Queue Tag rather than a Simple Queue Tag, which forces
2920 the Target Device to complete all previously queued commands before
2921 this command may be executed.
2923 if (HostAdapter->ActiveCommands[TargetID] == 0)
2924 HostAdapter->LastSequencePoint[TargetID] = jiffies;
2925 else if (time_after(jiffies, HostAdapter->LastSequencePoint[TargetID] + 4 * HZ)) {
2926 HostAdapter->LastSequencePoint[TargetID] = jiffies;
2927 QueueTag = BusLogic_OrderedQueueTag;
2929 if (HostAdapter->ExtendedLUNSupport) {
2930 CCB->TagEnable = true;
2931 CCB->QueueTag = QueueTag;
2932 } else {
2933 CCB->LegacyTagEnable = true;
2934 CCB->LegacyQueueTag = QueueTag;
2937 memcpy(CCB->CDB, CDB, CDB_Length);
2938 CCB->SenseDataLength = sizeof(Command->sense_buffer);
2939 CCB->SenseDataPointer = pci_map_single(HostAdapter->PCI_Device, Command->sense_buffer, CCB->SenseDataLength, PCI_DMA_FROMDEVICE);
2940 CCB->Command = Command;
2941 Command->scsi_done = CompletionRoutine;
2942 if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
2944 Place the CCB in an Outgoing Mailbox. The higher levels of the SCSI
2945 Subsystem should not attempt to queue more commands than can be placed
2946 in Outgoing Mailboxes, so there should always be one free. In the
2947 unlikely event that there are none available, wait 1 second and try
2948 again. If that fails, the Host Adapter is probably hung so signal an
2949 error as a Host Adapter Hard Reset should be initiated soon.
2951 if (!BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxStartCommand, CCB)) {
2952 spin_unlock_irq(HostAdapter->SCSI_Host->host_lock);
2953 BusLogic_Warning("Unable to write Outgoing Mailbox - " "Pausing for 1 second\n", HostAdapter);
2954 BusLogic_Delay(1);
2955 spin_lock_irq(HostAdapter->SCSI_Host->host_lock);
2956 if (!BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxStartCommand, CCB)) {
2957 BusLogic_Warning("Still unable to write Outgoing Mailbox - " "Host Adapter Dead?\n", HostAdapter);
2958 BusLogic_DeallocateCCB(CCB);
2959 Command->result = DID_ERROR << 16;
2960 Command->scsi_done(Command);
2963 } else {
2965 Call the FlashPoint SCCB Manager to start execution of the CCB.
2967 CCB->Status = BusLogic_CCB_Active;
2968 HostAdapter->ActiveCommands[TargetID]++;
2969 TargetStatistics[TargetID].CommandsAttempted++;
2970 FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
2972 The Command may have already completed and BusLogic_QueueCompletedCCB
2973 been called, or it may still be pending.
2975 if (CCB->Status == BusLogic_CCB_Completed)
2976 BusLogic_ProcessCompletedCCBs(HostAdapter);
2978 return 0;
2982 #if 0
2984 BusLogic_AbortCommand aborts Command if possible.
2987 static int BusLogic_AbortCommand(struct scsi_cmnd *Command)
2989 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata;
2991 int TargetID = Command->device->id;
2992 struct BusLogic_CCB *CCB;
2993 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsRequested);
2995 Attempt to find an Active CCB for this Command. If no Active CCB for this
2996 Command is found, then no Abort is necessary.
2998 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2999 if (CCB->Command == Command)
3000 break;
3001 if (CCB == NULL) {
3002 BusLogic_Warning("Unable to Abort Command to Target %d - " "No CCB Found\n", HostAdapter, TargetID);
3003 return SUCCESS;
3004 } else if (CCB->Status == BusLogic_CCB_Completed) {
3005 BusLogic_Warning("Unable to Abort Command to Target %d - " "CCB Completed\n", HostAdapter, TargetID);
3006 return SUCCESS;
3007 } else if (CCB->Status == BusLogic_CCB_Reset) {
3008 BusLogic_Warning("Unable to Abort Command to Target %d - " "CCB Reset\n", HostAdapter, TargetID);
3009 return SUCCESS;
3011 if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
3013 Attempt to Abort this CCB. MultiMaster Firmware versions prior to 5.xx
3014 do not generate Abort Tag messages, but only generate the non-tagged
3015 Abort message. Since non-tagged commands are not sent by the Host
3016 Adapter until the queue of outstanding tagged commands has completed,
3017 and the Abort message is treated as a non-tagged command, it is
3018 effectively impossible to abort commands when Tagged Queuing is active.
3019 Firmware version 5.xx does generate Abort Tag messages, so it is
3020 possible to abort commands when Tagged Queuing is active.
3022 if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive && HostAdapter->FirmwareVersion[0] < '5') {
3023 BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - " "Abort Tag Not Supported\n", HostAdapter, CCB->SerialNumber, TargetID);
3024 return FAILURE;
3025 } else if (BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxAbortCommand, CCB)) {
3026 BusLogic_Warning("Aborting CCB #%ld to Target %d\n", HostAdapter, CCB->SerialNumber, TargetID);
3027 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
3028 return SUCCESS;
3029 } else {
3030 BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - " "No Outgoing Mailboxes\n", HostAdapter, CCB->SerialNumber, TargetID);
3031 return FAILURE;
3033 } else {
3035 Call the FlashPoint SCCB Manager to abort execution of the CCB.
3037 BusLogic_Warning("Aborting CCB #%ld to Target %d\n", HostAdapter, CCB->SerialNumber, TargetID);
3038 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
3039 FlashPoint_AbortCCB(HostAdapter->CardHandle, CCB);
3041 The Abort may have already been completed and
3042 BusLogic_QueueCompletedCCB been called, or it
3043 may still be pending.
3045 if (CCB->Status == BusLogic_CCB_Completed) {
3046 BusLogic_ProcessCompletedCCBs(HostAdapter);
3048 return SUCCESS;
3050 return SUCCESS;
3053 #endif
3055 BusLogic_ResetHostAdapter resets Host Adapter if possible, marking all
3056 currently executing SCSI Commands as having been Reset.
3059 static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter, bool HardReset)
3061 struct BusLogic_CCB *CCB;
3062 int TargetID;
3065 * Attempt to Reset and Reinitialize the Host Adapter.
3068 if (!(BusLogic_HardwareResetHostAdapter(HostAdapter, HardReset) && BusLogic_InitializeHostAdapter(HostAdapter))) {
3069 BusLogic_Error("Resetting %s Failed\n", HostAdapter, HostAdapter->FullModelName);
3070 return FAILURE;
3074 * Deallocate all currently executing CCBs.
3077 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3078 if (CCB->Status == BusLogic_CCB_Active)
3079 BusLogic_DeallocateCCB(CCB);
3081 * Wait a few seconds between the Host Adapter Hard Reset which
3082 * initiates a SCSI Bus Reset and issuing any SCSI Commands. Some
3083 * SCSI devices get confused if they receive SCSI Commands too soon
3084 * after a SCSI Bus Reset.
3087 if (HardReset) {
3088 spin_unlock_irq(HostAdapter->SCSI_Host->host_lock);
3089 BusLogic_Delay(HostAdapter->BusSettleTime);
3090 spin_lock_irq(HostAdapter->SCSI_Host->host_lock);
3093 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3094 HostAdapter->LastResetAttempted[TargetID] = jiffies;
3095 HostAdapter->LastResetCompleted[TargetID] = jiffies;
3097 return SUCCESS;
3101 BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk
3102 Parameters for Disk. The default disk geometry is 64 heads, 32 sectors, and
3103 the appropriate number of cylinders so as not to exceed drive capacity. In
3104 order for disks equal to or larger than 1 GB to be addressable by the BIOS
3105 without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
3106 may be enabled in AutoSCSI on FlashPoint Host Adapters and on "W" and "C"
3107 series MultiMaster Host Adapters, or by a dip switch setting on "S" and "A"
3108 series MultiMaster Host Adapters. With Extended Translation enabled, drives
3109 between 1 GB inclusive and 2 GB exclusive are given a disk geometry of 128
3110 heads and 32 sectors, and drives above 2 GB inclusive are given a disk
3111 geometry of 255 heads and 63 sectors. However, if the BIOS detects that the
3112 Extended Translation setting does not match the geometry in the partition
3113 table, then the translation inferred from the partition table will be used by
3114 the BIOS, and a warning may be displayed.
3117 static int BusLogic_BIOSDiskParameters(struct scsi_device *sdev, struct block_device *Device, sector_t capacity, int *Parameters)
3119 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) sdev->host->hostdata;
3120 struct BIOS_DiskParameters *DiskParameters = (struct BIOS_DiskParameters *) Parameters;
3121 unsigned char *buf;
3122 if (HostAdapter->ExtendedTranslationEnabled && capacity >= 2 * 1024 * 1024 /* 1 GB in 512 byte sectors */ ) {
3123 if (capacity >= 4 * 1024 * 1024 /* 2 GB in 512 byte sectors */ ) {
3124 DiskParameters->Heads = 255;
3125 DiskParameters->Sectors = 63;
3126 } else {
3127 DiskParameters->Heads = 128;
3128 DiskParameters->Sectors = 32;
3130 } else {
3131 DiskParameters->Heads = 64;
3132 DiskParameters->Sectors = 32;
3134 DiskParameters->Cylinders = (unsigned long) capacity / (DiskParameters->Heads * DiskParameters->Sectors);
3135 buf = scsi_bios_ptable(Device);
3136 if (buf == NULL)
3137 return 0;
3139 If the boot sector partition table flag is valid, search for a partition
3140 table entry whose end_head matches one of the standard BusLogic geometry
3141 translations (64/32, 128/32, or 255/63).
3143 if (*(unsigned short *) (buf + 64) == 0xAA55) {
3144 struct partition *FirstPartitionEntry = (struct partition *) buf;
3145 struct partition *PartitionEntry = FirstPartitionEntry;
3146 int SavedCylinders = DiskParameters->Cylinders, PartitionNumber;
3147 unsigned char PartitionEntryEndHead = 0, PartitionEntryEndSector = 0;
3148 for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++) {
3149 PartitionEntryEndHead = PartitionEntry->end_head;
3150 PartitionEntryEndSector = PartitionEntry->end_sector & 0x3F;
3151 if (PartitionEntryEndHead == 64 - 1) {
3152 DiskParameters->Heads = 64;
3153 DiskParameters->Sectors = 32;
3154 break;
3155 } else if (PartitionEntryEndHead == 128 - 1) {
3156 DiskParameters->Heads = 128;
3157 DiskParameters->Sectors = 32;
3158 break;
3159 } else if (PartitionEntryEndHead == 255 - 1) {
3160 DiskParameters->Heads = 255;
3161 DiskParameters->Sectors = 63;
3162 break;
3164 PartitionEntry++;
3166 if (PartitionNumber == 4) {
3167 PartitionEntryEndHead = FirstPartitionEntry->end_head;
3168 PartitionEntryEndSector = FirstPartitionEntry->end_sector & 0x3F;
3170 DiskParameters->Cylinders = (unsigned long) capacity / (DiskParameters->Heads * DiskParameters->Sectors);
3171 if (PartitionNumber < 4 && PartitionEntryEndSector == DiskParameters->Sectors) {
3172 if (DiskParameters->Cylinders != SavedCylinders)
3173 BusLogic_Warning("Adopting Geometry %d/%d from Partition Table\n", HostAdapter, DiskParameters->Heads, DiskParameters->Sectors);
3174 } else if (PartitionEntryEndHead > 0 || PartitionEntryEndSector > 0) {
3175 BusLogic_Warning("Warning: Partition Table appears to " "have Geometry %d/%d which is\n", HostAdapter, PartitionEntryEndHead + 1, PartitionEntryEndSector);
3176 BusLogic_Warning("not compatible with current BusLogic " "Host Adapter Geometry %d/%d\n", HostAdapter, DiskParameters->Heads, DiskParameters->Sectors);
3179 kfree(buf);
3180 return 0;
3185 BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>.
3188 static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *shost, char *ProcBuffer, char **StartPointer, off_t Offset, int BytesAvailable, int WriteFlag)
3190 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) shost->hostdata;
3191 struct BusLogic_TargetStatistics *TargetStatistics;
3192 int TargetID, Length;
3193 char *Buffer;
3195 TargetStatistics = HostAdapter->TargetStatistics;
3196 if (WriteFlag) {
3197 HostAdapter->ExternalHostAdapterResets = 0;
3198 HostAdapter->HostAdapterInternalErrors = 0;
3199 memset(TargetStatistics, 0, BusLogic_MaxTargetDevices * sizeof(struct BusLogic_TargetStatistics));
3200 return 0;
3202 Buffer = HostAdapter->MessageBuffer;
3203 Length = HostAdapter->MessageBufferLength;
3204 Length += sprintf(&Buffer[Length], "\n\
3205 Current Driver Queue Depth: %d\n\
3206 Currently Allocated CCBs: %d\n", HostAdapter->DriverQueueDepth, HostAdapter->AllocatedCCBs);
3207 Length += sprintf(&Buffer[Length], "\n\n\
3208 DATA TRANSFER STATISTICS\n\
3210 Target Tagged Queuing Queue Depth Active Attempted Completed\n\
3211 ====== ============== =========== ====== ========= =========\n");
3212 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3213 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3214 if (!TargetFlags->TargetExists)
3215 continue;
3216 Length += sprintf(&Buffer[Length], " %2d %s", TargetID, (TargetFlags->TaggedQueuingSupported ? (TargetFlags->TaggedQueuingActive ? " Active" : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)
3217 ? " Permitted" : " Disabled"))
3218 : "Not Supported"));
3219 Length += sprintf(&Buffer[Length],
3220 " %3d %3u %9u %9u\n", HostAdapter->QueueDepth[TargetID], HostAdapter->ActiveCommands[TargetID], TargetStatistics[TargetID].CommandsAttempted, TargetStatistics[TargetID].CommandsCompleted);
3222 Length += sprintf(&Buffer[Length], "\n\
3223 Target Read Commands Write Commands Total Bytes Read Total Bytes Written\n\
3224 ====== ============= ============== =================== ===================\n");
3225 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3226 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3227 if (!TargetFlags->TargetExists)
3228 continue;
3229 Length += sprintf(&Buffer[Length], " %2d %9u %9u", TargetID, TargetStatistics[TargetID].ReadCommands, TargetStatistics[TargetID].WriteCommands);
3230 if (TargetStatistics[TargetID].TotalBytesRead.Billions > 0)
3231 Length += sprintf(&Buffer[Length], " %9u%09u", TargetStatistics[TargetID].TotalBytesRead.Billions, TargetStatistics[TargetID].TotalBytesRead.Units);
3232 else
3233 Length += sprintf(&Buffer[Length], " %9u", TargetStatistics[TargetID].TotalBytesRead.Units);
3234 if (TargetStatistics[TargetID].TotalBytesWritten.Billions > 0)
3235 Length += sprintf(&Buffer[Length], " %9u%09u\n", TargetStatistics[TargetID].TotalBytesWritten.Billions, TargetStatistics[TargetID].TotalBytesWritten.Units);
3236 else
3237 Length += sprintf(&Buffer[Length], " %9u\n", TargetStatistics[TargetID].TotalBytesWritten.Units);
3239 Length += sprintf(&Buffer[Length], "\n\
3240 Target Command 0-1KB 1-2KB 2-4KB 4-8KB 8-16KB\n\
3241 ====== ======= ========= ========= ========= ========= =========\n");
3242 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3243 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3244 if (!TargetFlags->TargetExists)
3245 continue;
3246 Length +=
3247 sprintf(&Buffer[Length],
3248 " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
3249 TargetStatistics[TargetID].ReadCommandSizeBuckets[0],
3250 TargetStatistics[TargetID].ReadCommandSizeBuckets[1], TargetStatistics[TargetID].ReadCommandSizeBuckets[2], TargetStatistics[TargetID].ReadCommandSizeBuckets[3], TargetStatistics[TargetID].ReadCommandSizeBuckets[4]);
3251 Length +=
3252 sprintf(&Buffer[Length],
3253 " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
3254 TargetStatistics[TargetID].WriteCommandSizeBuckets[0],
3255 TargetStatistics[TargetID].WriteCommandSizeBuckets[1], TargetStatistics[TargetID].WriteCommandSizeBuckets[2], TargetStatistics[TargetID].WriteCommandSizeBuckets[3], TargetStatistics[TargetID].WriteCommandSizeBuckets[4]);
3257 Length += sprintf(&Buffer[Length], "\n\
3258 Target Command 16-32KB 32-64KB 64-128KB 128-256KB 256KB+\n\
3259 ====== ======= ========= ========= ========= ========= =========\n");
3260 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3261 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3262 if (!TargetFlags->TargetExists)
3263 continue;
3264 Length +=
3265 sprintf(&Buffer[Length],
3266 " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
3267 TargetStatistics[TargetID].ReadCommandSizeBuckets[5],
3268 TargetStatistics[TargetID].ReadCommandSizeBuckets[6], TargetStatistics[TargetID].ReadCommandSizeBuckets[7], TargetStatistics[TargetID].ReadCommandSizeBuckets[8], TargetStatistics[TargetID].ReadCommandSizeBuckets[9]);
3269 Length +=
3270 sprintf(&Buffer[Length],
3271 " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
3272 TargetStatistics[TargetID].WriteCommandSizeBuckets[5],
3273 TargetStatistics[TargetID].WriteCommandSizeBuckets[6], TargetStatistics[TargetID].WriteCommandSizeBuckets[7], TargetStatistics[TargetID].WriteCommandSizeBuckets[8], TargetStatistics[TargetID].WriteCommandSizeBuckets[9]);
3275 Length += sprintf(&Buffer[Length], "\n\n\
3276 ERROR RECOVERY STATISTICS\n\
3278 Command Aborts Bus Device Resets Host Adapter Resets\n\
3279 Target Requested Completed Requested Completed Requested Completed\n\
3280 ID \\\\\\\\ Attempted //// \\\\\\\\ Attempted //// \\\\\\\\ Attempted ////\n\
3281 ====== ===== ===== ===== ===== ===== ===== ===== ===== =====\n");
3282 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3283 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3284 if (!TargetFlags->TargetExists)
3285 continue;
3286 Length += sprintf(&Buffer[Length], "\
3287 %2d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n", TargetID, TargetStatistics[TargetID].CommandAbortsRequested, TargetStatistics[TargetID].CommandAbortsAttempted, TargetStatistics[TargetID].CommandAbortsCompleted, TargetStatistics[TargetID].BusDeviceResetsRequested, TargetStatistics[TargetID].BusDeviceResetsAttempted, TargetStatistics[TargetID].BusDeviceResetsCompleted, TargetStatistics[TargetID].HostAdapterResetsRequested, TargetStatistics[TargetID].HostAdapterResetsAttempted, TargetStatistics[TargetID].HostAdapterResetsCompleted);
3289 Length += sprintf(&Buffer[Length], "\nExternal Host Adapter Resets: %d\n", HostAdapter->ExternalHostAdapterResets);
3290 Length += sprintf(&Buffer[Length], "Host Adapter Internal Errors: %d\n", HostAdapter->HostAdapterInternalErrors);
3291 if (Length >= BusLogic_MessageBufferSize)
3292 BusLogic_Error("Message Buffer length %d exceeds size %d\n", HostAdapter, Length, BusLogic_MessageBufferSize);
3293 if ((Length -= Offset) <= 0)
3294 return 0;
3295 if (Length >= BytesAvailable)
3296 Length = BytesAvailable;
3297 memcpy(ProcBuffer, HostAdapter->MessageBuffer + Offset, Length);
3298 *StartPointer = ProcBuffer;
3299 return Length;
3304 BusLogic_Message prints Driver Messages.
3307 static void BusLogic_Message(enum BusLogic_MessageLevel MessageLevel, char *Format, struct BusLogic_HostAdapter *HostAdapter, ...)
3309 static char Buffer[BusLogic_LineBufferSize];
3310 static bool BeginningOfLine = true;
3311 va_list Arguments;
3312 int Length = 0;
3313 va_start(Arguments, HostAdapter);
3314 Length = vsprintf(Buffer, Format, Arguments);
3315 va_end(Arguments);
3316 if (MessageLevel == BusLogic_AnnounceLevel) {
3317 static int AnnouncementLines = 0;
3318 strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength], Buffer);
3319 HostAdapter->MessageBufferLength += Length;
3320 if (++AnnouncementLines <= 2)
3321 printk("%sscsi: %s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
3322 } else if (MessageLevel == BusLogic_InfoLevel) {
3323 strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength], Buffer);
3324 HostAdapter->MessageBufferLength += Length;
3325 if (BeginningOfLine) {
3326 if (Buffer[0] != '\n' || Length > 1)
3327 printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel], HostAdapter->HostNumber, Buffer);
3328 } else
3329 printk("%s", Buffer);
3330 } else {
3331 if (BeginningOfLine) {
3332 if (HostAdapter != NULL && HostAdapter->HostAdapterInitialized)
3333 printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel], HostAdapter->HostNumber, Buffer);
3334 else
3335 printk("%s%s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
3336 } else
3337 printk("%s", Buffer);
3339 BeginningOfLine = (Buffer[Length - 1] == '\n');
3344 BusLogic_ParseKeyword parses an individual option keyword. It returns true
3345 and updates the pointer if the keyword is recognized and false otherwise.
3348 static bool __init BusLogic_ParseKeyword(char **StringPointer, char *Keyword)
3350 char *Pointer = *StringPointer;
3351 while (*Keyword != '\0') {
3352 char StringChar = *Pointer++;
3353 char KeywordChar = *Keyword++;
3354 if (StringChar >= 'A' && StringChar <= 'Z')
3355 StringChar += 'a' - 'Z';
3356 if (KeywordChar >= 'A' && KeywordChar <= 'Z')
3357 KeywordChar += 'a' - 'Z';
3358 if (StringChar != KeywordChar)
3359 return false;
3361 *StringPointer = Pointer;
3362 return true;
3367 BusLogic_ParseDriverOptions handles processing of BusLogic Driver Options
3368 specifications.
3370 BusLogic Driver Options may be specified either via the Linux Kernel Command
3371 Line or via the Loadable Kernel Module Installation Facility. Driver Options
3372 for multiple host adapters may be specified either by separating the option
3373 strings by a semicolon, or by specifying multiple "BusLogic=" strings on the
3374 command line. Individual option specifications for a single host adapter are
3375 separated by commas. The Probing and Debugging Options apply to all host
3376 adapters whereas the remaining options apply individually only to the
3377 selected host adapter.
3379 The BusLogic Driver Probing Options are described in
3380 <file:Documentation/scsi/BusLogic.txt>.
3383 static int __init BusLogic_ParseDriverOptions(char *OptionsString)
3385 while (true) {
3386 struct BusLogic_DriverOptions *DriverOptions = &BusLogic_DriverOptions[BusLogic_DriverOptionsCount++];
3387 int TargetID;
3388 memset(DriverOptions, 0, sizeof(struct BusLogic_DriverOptions));
3389 while (*OptionsString != '\0' && *OptionsString != ';') {
3390 /* Probing Options. */
3391 if (BusLogic_ParseKeyword(&OptionsString, "IO:")) {
3392 unsigned long IO_Address = simple_strtoul(OptionsString, &OptionsString, 0);
3393 BusLogic_ProbeOptions.LimitedProbeISA = true;
3394 switch (IO_Address) {
3395 case 0x330:
3396 BusLogic_ProbeOptions.Probe330 = true;
3397 break;
3398 case 0x334:
3399 BusLogic_ProbeOptions.Probe334 = true;
3400 break;
3401 case 0x230:
3402 BusLogic_ProbeOptions.Probe230 = true;
3403 break;
3404 case 0x234:
3405 BusLogic_ProbeOptions.Probe234 = true;
3406 break;
3407 case 0x130:
3408 BusLogic_ProbeOptions.Probe130 = true;
3409 break;
3410 case 0x134:
3411 BusLogic_ProbeOptions.Probe134 = true;
3412 break;
3413 default:
3414 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid I/O Address 0x%X)\n", NULL, IO_Address);
3415 return 0;
3417 } else if (BusLogic_ParseKeyword(&OptionsString, "NoProbeISA"))
3418 BusLogic_ProbeOptions.NoProbeISA = true;
3419 else if (BusLogic_ParseKeyword(&OptionsString, "NoProbePCI"))
3420 BusLogic_ProbeOptions.NoProbePCI = true;
3421 else if (BusLogic_ParseKeyword(&OptionsString, "NoProbe"))
3422 BusLogic_ProbeOptions.NoProbe = true;
3423 else if (BusLogic_ParseKeyword(&OptionsString, "NoSortPCI"))
3424 BusLogic_ProbeOptions.NoSortPCI = true;
3425 else if (BusLogic_ParseKeyword(&OptionsString, "MultiMasterFirst"))
3426 BusLogic_ProbeOptions.MultiMasterFirst = true;
3427 else if (BusLogic_ParseKeyword(&OptionsString, "FlashPointFirst"))
3428 BusLogic_ProbeOptions.FlashPointFirst = true;
3429 /* Tagged Queuing Options. */
3430 else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:[") || BusLogic_ParseKeyword(&OptionsString, "QD:[")) {
3431 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) {
3432 unsigned short QueueDepth = simple_strtoul(OptionsString, &OptionsString, 0);
3433 if (QueueDepth > BusLogic_MaxTaggedQueueDepth) {
3434 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, QueueDepth);
3435 return 0;
3437 DriverOptions->QueueDepth[TargetID] = QueueDepth;
3438 if (*OptionsString == ',')
3439 OptionsString++;
3440 else if (*OptionsString == ']')
3441 break;
3442 else {
3443 BusLogic_Error("BusLogic: Invalid Driver Options " "(',' or ']' expected at '%s')\n", NULL, OptionsString);
3444 return 0;
3447 if (*OptionsString != ']') {
3448 BusLogic_Error("BusLogic: Invalid Driver Options " "(']' expected at '%s')\n", NULL, OptionsString);
3449 return 0;
3450 } else
3451 OptionsString++;
3452 } else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:") || BusLogic_ParseKeyword(&OptionsString, "QD:")) {
3453 unsigned short QueueDepth = simple_strtoul(OptionsString, &OptionsString, 0);
3454 if (QueueDepth == 0 || QueueDepth > BusLogic_MaxTaggedQueueDepth) {
3455 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, QueueDepth);
3456 return 0;
3458 DriverOptions->CommonQueueDepth = QueueDepth;
3459 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
3460 DriverOptions->QueueDepth[TargetID] = QueueDepth;
3461 } else if (BusLogic_ParseKeyword(&OptionsString, "TaggedQueuing:") || BusLogic_ParseKeyword(&OptionsString, "TQ:")) {
3462 if (BusLogic_ParseKeyword(&OptionsString, "Default")) {
3463 DriverOptions->TaggedQueuingPermitted = 0x0000;
3464 DriverOptions->TaggedQueuingPermittedMask = 0x0000;
3465 } else if (BusLogic_ParseKeyword(&OptionsString, "Enable")) {
3466 DriverOptions->TaggedQueuingPermitted = 0xFFFF;
3467 DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
3468 } else if (BusLogic_ParseKeyword(&OptionsString, "Disable")) {
3469 DriverOptions->TaggedQueuingPermitted = 0x0000;
3470 DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
3471 } else {
3472 unsigned short TargetBit;
3473 for (TargetID = 0, TargetBit = 1; TargetID < BusLogic_MaxTargetDevices; TargetID++, TargetBit <<= 1)
3474 switch (*OptionsString++) {
3475 case 'Y':
3476 DriverOptions->TaggedQueuingPermitted |= TargetBit;
3477 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
3478 break;
3479 case 'N':
3480 DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
3481 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
3482 break;
3483 case 'X':
3484 break;
3485 default:
3486 OptionsString--;
3487 TargetID = BusLogic_MaxTargetDevices;
3488 break;
3492 /* Miscellaneous Options. */
3493 else if (BusLogic_ParseKeyword(&OptionsString, "BusSettleTime:") || BusLogic_ParseKeyword(&OptionsString, "BST:")) {
3494 unsigned short BusSettleTime = simple_strtoul(OptionsString, &OptionsString, 0);
3495 if (BusSettleTime > 5 * 60) {
3496 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Bus Settle Time %d)\n", NULL, BusSettleTime);
3497 return 0;
3499 DriverOptions->BusSettleTime = BusSettleTime;
3500 } else if (BusLogic_ParseKeyword(&OptionsString, "InhibitTargetInquiry"))
3501 DriverOptions->LocalOptions.InhibitTargetInquiry = true;
3502 /* Debugging Options. */
3503 else if (BusLogic_ParseKeyword(&OptionsString, "TraceProbe"))
3504 BusLogic_GlobalOptions.TraceProbe = true;
3505 else if (BusLogic_ParseKeyword(&OptionsString, "TraceHardwareReset"))
3506 BusLogic_GlobalOptions.TraceHardwareReset = true;
3507 else if (BusLogic_ParseKeyword(&OptionsString, "TraceConfiguration"))
3508 BusLogic_GlobalOptions.TraceConfiguration = true;
3509 else if (BusLogic_ParseKeyword(&OptionsString, "TraceErrors"))
3510 BusLogic_GlobalOptions.TraceErrors = true;
3511 else if (BusLogic_ParseKeyword(&OptionsString, "Debug")) {
3512 BusLogic_GlobalOptions.TraceProbe = true;
3513 BusLogic_GlobalOptions.TraceHardwareReset = true;
3514 BusLogic_GlobalOptions.TraceConfiguration = true;
3515 BusLogic_GlobalOptions.TraceErrors = true;
3517 if (*OptionsString == ',')
3518 OptionsString++;
3519 else if (*OptionsString != ';' && *OptionsString != '\0') {
3520 BusLogic_Error("BusLogic: Unexpected Driver Option '%s' " "ignored\n", NULL, OptionsString);
3521 *OptionsString = '\0';
3524 if (!(BusLogic_DriverOptionsCount == 0 || BusLogic_ProbeInfoCount == 0 || BusLogic_DriverOptionsCount == BusLogic_ProbeInfoCount)) {
3525 BusLogic_Error("BusLogic: Invalid Driver Options " "(all or no I/O Addresses must be specified)\n", NULL);
3526 return 0;
3529 Tagged Queuing is disabled when the Queue Depth is 1 since queuing
3530 multiple commands is not possible.
3532 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
3533 if (DriverOptions->QueueDepth[TargetID] == 1) {
3534 unsigned short TargetBit = 1 << TargetID;
3535 DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
3536 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
3538 if (*OptionsString == ';')
3539 OptionsString++;
3540 if (*OptionsString == '\0')
3541 return 0;
3543 return 1;
3547 Get it all started
3550 static struct scsi_host_template Bus_Logic_template = {
3551 .module = THIS_MODULE,
3552 .proc_name = "BusLogic",
3553 .proc_info = BusLogic_ProcDirectoryInfo,
3554 .name = "BusLogic",
3555 .info = BusLogic_DriverInfo,
3556 .queuecommand = BusLogic_QueueCommand,
3557 .slave_configure = BusLogic_SlaveConfigure,
3558 .bios_param = BusLogic_BIOSDiskParameters,
3559 .eh_host_reset_handler = BusLogic_host_reset,
3560 #if 0
3561 .eh_abort_handler = BusLogic_AbortCommand,
3562 #endif
3563 .unchecked_isa_dma = 1,
3564 .max_sectors = 128,
3565 .use_clustering = ENABLE_CLUSTERING,
3569 BusLogic_Setup handles processing of Kernel Command Line Arguments.
3572 static int __init BusLogic_Setup(char *str)
3574 int ints[3];
3576 (void) get_options(str, ARRAY_SIZE(ints), ints);
3578 if (ints[0] != 0) {
3579 BusLogic_Error("BusLogic: Obsolete Command Line Entry " "Format Ignored\n", NULL);
3580 return 0;
3582 if (str == NULL || *str == '\0')
3583 return 0;
3584 return BusLogic_ParseDriverOptions(str);
3588 * Exit function. Deletes all hosts associated with this driver.
3591 static void __exit BusLogic_exit(void)
3593 struct BusLogic_HostAdapter *ha, *next;
3595 list_for_each_entry_safe(ha, next, &BusLogic_host_list, host_list)
3596 BusLogic_ReleaseHostAdapter(ha);
3599 __setup("BusLogic=", BusLogic_Setup);
3601 static struct pci_device_id BusLogic_pci_tbl[] __devinitdata = {
3602 { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
3603 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
3604 { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
3605 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
3606 { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
3607 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
3610 MODULE_DEVICE_TABLE(pci, BusLogic_pci_tbl);
3612 module_init(BusLogic_init);
3613 module_exit(BusLogic_exit);