mm: optimize kill_bdev()
[linux-2.6/mini2440.git] / drivers / scsi / BusLogic.c
blob96f4cab07614802613baf2564bd414beddfbc0b6
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)
583 BusLogic_AppendProbeAddressISA(0x330);
584 if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe334)
585 BusLogic_AppendProbeAddressISA(0x334);
586 if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe230)
587 BusLogic_AppendProbeAddressISA(0x230);
588 if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe234)
589 BusLogic_AppendProbeAddressISA(0x234);
590 if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe130)
591 BusLogic_AppendProbeAddressISA(0x130);
592 if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe134)
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 &&
799 (!BusLogic_ProbeOptions.LimitedProbeISA ||
800 BusLogic_ProbeOptions.Probe330)) {
801 PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
802 PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
803 PrimaryProbeInfo->IO_Address = 0x330;
806 Append the list of standard BusLogic MultiMaster ISA I/O Addresses,
807 omitting the Primary I/O Address which has already been handled.
809 if (!BusLogic_ProbeOptions.NoProbeISA) {
810 if (!StandardAddressSeen[1] &&
811 (!BusLogic_ProbeOptions.LimitedProbeISA ||
812 BusLogic_ProbeOptions.Probe334))
813 BusLogic_AppendProbeAddressISA(0x334);
814 if (!StandardAddressSeen[2] &&
815 (!BusLogic_ProbeOptions.LimitedProbeISA ||
816 BusLogic_ProbeOptions.Probe230))
817 BusLogic_AppendProbeAddressISA(0x230);
818 if (!StandardAddressSeen[3] &&
819 (!BusLogic_ProbeOptions.LimitedProbeISA ||
820 BusLogic_ProbeOptions.Probe234))
821 BusLogic_AppendProbeAddressISA(0x234);
822 if (!StandardAddressSeen[4] &&
823 (!BusLogic_ProbeOptions.LimitedProbeISA ||
824 BusLogic_ProbeOptions.Probe130))
825 BusLogic_AppendProbeAddressISA(0x130);
826 if (!StandardAddressSeen[5] &&
827 (!BusLogic_ProbeOptions.LimitedProbeISA ||
828 BusLogic_ProbeOptions.Probe134))
829 BusLogic_AppendProbeAddressISA(0x134);
832 Iterate over the older non-compliant MultiMaster PCI Host Adapters,
833 noting the PCI bus location and assigned IRQ Channel.
835 PCI_Device = NULL;
836 while ((PCI_Device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC, PCI_Device)) != NULL) {
837 unsigned char Bus;
838 unsigned char Device;
839 unsigned int IRQ_Channel;
840 unsigned long IO_Address;
842 if (pci_enable_device(PCI_Device))
843 continue;
845 if (pci_set_dma_mask(PCI_Device, DMA_32BIT_MASK))
846 continue;
848 Bus = PCI_Device->bus->number;
849 Device = PCI_Device->devfn >> 3;
850 IRQ_Channel = PCI_Device->irq;
851 IO_Address = pci_resource_start(PCI_Device, 0);
853 if (IO_Address == 0 || IRQ_Channel == 0)
854 continue;
855 for (i = 0; i < BusLogic_ProbeInfoCount; i++) {
856 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[i];
857 if (ProbeInfo->IO_Address == IO_Address && ProbeInfo->HostAdapterType == BusLogic_MultiMaster) {
858 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
859 ProbeInfo->PCI_Address = 0;
860 ProbeInfo->Bus = Bus;
861 ProbeInfo->Device = Device;
862 ProbeInfo->IRQ_Channel = IRQ_Channel;
863 ProbeInfo->PCI_Device = pci_dev_get(PCI_Device);
864 break;
868 return PCIMultiMasterCount;
873 BusLogic_InitializeFlashPointProbeInfo initializes the list of I/O Address
874 and Bus Probe Information to be checked for potential BusLogic FlashPoint
875 Host Adapters by interrogating the PCI Configuration Space. It returns the
876 number of FlashPoint Host Adapters found.
879 static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAdapter
880 *PrototypeHostAdapter)
882 int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0;
883 struct pci_dev *PCI_Device = NULL;
885 Interrogate PCI Configuration Space for any FlashPoint Host Adapters.
887 while ((PCI_Device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT, PCI_Device)) != NULL) {
888 unsigned char Bus;
889 unsigned char Device;
890 unsigned int IRQ_Channel;
891 unsigned long BaseAddress0;
892 unsigned long BaseAddress1;
893 unsigned long IO_Address;
894 unsigned long PCI_Address;
896 if (pci_enable_device(PCI_Device))
897 continue;
899 if (pci_set_dma_mask(PCI_Device, DMA_32BIT_MASK))
900 continue;
902 Bus = PCI_Device->bus->number;
903 Device = PCI_Device->devfn >> 3;
904 IRQ_Channel = PCI_Device->irq;
905 IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0);
906 PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1);
907 #ifndef CONFIG_SCSI_OMIT_FLASHPOINT
908 if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) {
909 BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, BaseAddress0);
910 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
911 continue;
913 if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO) {
914 BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for " "FlashPoint Host Adapter\n", NULL, BaseAddress1);
915 BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, Bus, Device, PCI_Address);
916 continue;
918 if (IRQ_Channel == 0) {
919 BusLogic_Error("BusLogic: IRQ Channel %d invalid for " "FlashPoint Host Adapter\n", NULL, IRQ_Channel);
920 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
921 continue;
923 if (BusLogic_GlobalOptions.TraceProbe) {
924 BusLogic_Notice("BusLogic: FlashPoint Host Adapter " "detected at\n", NULL);
925 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);
927 if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters) {
928 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
929 ProbeInfo->HostAdapterType = BusLogic_FlashPoint;
930 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
931 ProbeInfo->IO_Address = IO_Address;
932 ProbeInfo->PCI_Address = PCI_Address;
933 ProbeInfo->Bus = Bus;
934 ProbeInfo->Device = Device;
935 ProbeInfo->IRQ_Channel = IRQ_Channel;
936 ProbeInfo->PCI_Device = pci_dev_get(PCI_Device);
937 FlashPointCount++;
938 } else
939 BusLogic_Warning("BusLogic: Too many Host Adapters " "detected\n", NULL);
940 #else
941 BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", NULL, Bus, Device);
942 BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, irq %d, " "but FlashPoint\n", NULL, IO_Address, PCI_Address, IRQ_Channel);
943 BusLogic_Error("BusLogic: support was omitted in this kernel " "configuration.\n", NULL);
944 #endif
947 The FlashPoint BIOS will scan for FlashPoint Host Adapters in the order of
948 increasing PCI Bus and Device Number, so sort the probe information into
949 the same order the BIOS uses.
951 BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[FlashPointIndex], FlashPointCount);
952 return FlashPointCount;
957 BusLogic_InitializeProbeInfoList initializes the list of I/O Address and Bus
958 Probe Information to be checked for potential BusLogic SCSI Host Adapters by
959 interrogating the PCI Configuration Space on PCI machines as well as from the
960 list of standard BusLogic MultiMaster ISA I/O Addresses. By default, if both
961 FlashPoint and PCI MultiMaster Host Adapters are present, this driver will
962 probe for FlashPoint Host Adapters first unless the BIOS primary disk is
963 controlled by the first PCI MultiMaster Host Adapter, in which case
964 MultiMaster Host Adapters will be probed first. The BusLogic Driver Options
965 specifications "MultiMasterFirst" and "FlashPointFirst" can be used to force
966 a particular probe order.
969 static void __init BusLogic_InitializeProbeInfoList(struct BusLogic_HostAdapter
970 *PrototypeHostAdapter)
973 If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint
974 Host Adapters; otherwise, default to the standard ISA MultiMaster probe.
976 if (!BusLogic_ProbeOptions.NoProbePCI) {
977 if (BusLogic_ProbeOptions.MultiMasterFirst) {
978 BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
979 BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
980 } else if (BusLogic_ProbeOptions.FlashPointFirst) {
981 BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
982 BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
983 } else {
984 int FlashPointCount = BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
985 int PCIMultiMasterCount = BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
986 if (FlashPointCount > 0 && PCIMultiMasterCount > 0) {
987 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[FlashPointCount];
988 struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter;
989 struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest;
990 struct BusLogic_BIOSDriveMapByte Drive0MapByte;
991 while (ProbeInfo->HostAdapterBusType != BusLogic_PCI_Bus)
992 ProbeInfo++;
993 HostAdapter->IO_Address = ProbeInfo->IO_Address;
994 FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_BIOS_BaseOffset + BusLogic_BIOS_DriveMapOffset + 0;
995 FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(Drive0MapByte);
996 BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &Drive0MapByte, sizeof(Drive0MapByte));
998 If the Map Byte for BIOS Drive 0 indicates that BIOS Drive 0
999 is controlled by this PCI MultiMaster Host Adapter, then
1000 reverse the probe order so that MultiMaster Host Adapters are
1001 probed before FlashPoint Host Adapters.
1003 if (Drive0MapByte.DiskGeometry != BusLogic_BIOS_Disk_Not_Installed) {
1004 struct BusLogic_ProbeInfo SavedProbeInfo[BusLogic_MaxHostAdapters];
1005 int MultiMasterCount = BusLogic_ProbeInfoCount - FlashPointCount;
1006 memcpy(SavedProbeInfo, BusLogic_ProbeInfoList, BusLogic_ProbeInfoCount * sizeof(struct BusLogic_ProbeInfo));
1007 memcpy(&BusLogic_ProbeInfoList[0], &SavedProbeInfo[FlashPointCount], MultiMasterCount * sizeof(struct BusLogic_ProbeInfo));
1008 memcpy(&BusLogic_ProbeInfoList[MultiMasterCount], &SavedProbeInfo[0], FlashPointCount * sizeof(struct BusLogic_ProbeInfo));
1012 } else
1013 BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter);
1017 #endif /* CONFIG_PCI */
1021 BusLogic_Failure prints a standardized error message, and then returns false.
1024 static bool BusLogic_Failure(struct BusLogic_HostAdapter *HostAdapter, char *ErrorMessage)
1026 BusLogic_AnnounceDriver(HostAdapter);
1027 if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus) {
1028 BusLogic_Error("While configuring BusLogic PCI Host Adapter at\n", HostAdapter);
1029 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);
1030 } else
1031 BusLogic_Error("While configuring BusLogic Host Adapter at " "I/O Address 0x%X:\n", HostAdapter, HostAdapter->IO_Address);
1032 BusLogic_Error("%s FAILED - DETACHING\n", HostAdapter, ErrorMessage);
1033 if (BusLogic_CommandFailureReason != NULL)
1034 BusLogic_Error("ADDITIONAL FAILURE INFO - %s\n", HostAdapter, BusLogic_CommandFailureReason);
1035 return false;
1040 BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter.
1043 static bool __init BusLogic_ProbeHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
1045 union BusLogic_StatusRegister StatusRegister;
1046 union BusLogic_InterruptRegister InterruptRegister;
1047 union BusLogic_GeometryRegister GeometryRegister;
1049 FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager.
1051 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1052 struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
1053 FlashPointInfo->BaseAddress = (u32) HostAdapter->IO_Address;
1054 FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel;
1055 FlashPointInfo->Present = false;
1056 if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 && FlashPointInfo->Present)) {
1057 BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", HostAdapter, HostAdapter->Bus, HostAdapter->Device);
1058 BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, " "but FlashPoint\n", HostAdapter, HostAdapter->IO_Address, HostAdapter->PCI_Address);
1059 BusLogic_Error("BusLogic: Probe Function failed to validate it.\n", HostAdapter);
1060 return false;
1062 if (BusLogic_GlobalOptions.TraceProbe)
1063 BusLogic_Notice("BusLogic_Probe(0x%X): FlashPoint Found\n", HostAdapter, HostAdapter->IO_Address);
1065 Indicate the Host Adapter Probe completed successfully.
1067 return true;
1070 Read the Status, Interrupt, and Geometry Registers to test if there are I/O
1071 ports that respond, and to check the values to determine if they are from a
1072 BusLogic Host Adapter. A nonexistent I/O port will return 0xFF, in which
1073 case there is definitely no BusLogic Host Adapter at this base I/O Address.
1074 The test here is a subset of that used by the BusLogic Host Adapter BIOS.
1076 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1077 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
1078 GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1079 if (BusLogic_GlobalOptions.TraceProbe)
1080 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);
1081 if (StatusRegister.All == 0 || StatusRegister.sr.DiagnosticActive || StatusRegister.sr.CommandParameterRegisterBusy || StatusRegister.sr.Reserved || StatusRegister.sr.CommandInvalid || InterruptRegister.ir.Reserved != 0)
1082 return false;
1084 Check the undocumented Geometry Register to test if there is an I/O port
1085 that responded. Adaptec Host Adapters do not implement the Geometry
1086 Register, so this test helps serve to avoid incorrectly recognizing an
1087 Adaptec 1542A or 1542B as a BusLogic. Unfortunately, the Adaptec 1542C
1088 series does respond to the Geometry Register I/O port, but it will be
1089 rejected later when the Inquire Extended Setup Information command is
1090 issued in BusLogic_CheckHostAdapter. The AMI FastDisk Host Adapter is a
1091 BusLogic clone that implements the same interface as earlier BusLogic
1092 Host Adapters, including the undocumented commands, and is therefore
1093 supported by this driver. However, the AMI FastDisk always returns 0x00
1094 upon reading the Geometry Register, so the extended translation option
1095 should always be left disabled on the AMI FastDisk.
1097 if (GeometryRegister.All == 0xFF)
1098 return false;
1100 Indicate the Host Adapter Probe completed successfully.
1102 return true;
1107 BusLogic_HardwareResetHostAdapter issues a Hardware Reset to the Host Adapter
1108 and waits for Host Adapter Diagnostics to complete. If HardReset is true, a
1109 Hard Reset is performed which also initiates a SCSI Bus Reset. Otherwise, a
1110 Soft Reset is performed which only resets the Host Adapter without forcing a
1111 SCSI Bus Reset.
1114 static bool BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter
1115 *HostAdapter, bool HardReset)
1117 union BusLogic_StatusRegister StatusRegister;
1118 int TimeoutCounter;
1120 FlashPoint Host Adapters are Hard Reset by the FlashPoint SCCB Manager.
1122 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1123 struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
1124 FlashPointInfo->HostSoftReset = !HardReset;
1125 FlashPointInfo->ReportDataUnderrun = true;
1126 HostAdapter->CardHandle = FlashPoint_HardwareResetHostAdapter(FlashPointInfo);
1127 if (HostAdapter->CardHandle == FlashPoint_BadCardHandle)
1128 return false;
1130 Indicate the Host Adapter Hard Reset completed successfully.
1132 return true;
1135 Issue a Hard Reset or Soft Reset Command to the Host Adapter. The Host
1136 Adapter should respond by setting Diagnostic Active in the Status Register.
1138 if (HardReset)
1139 BusLogic_HardReset(HostAdapter);
1140 else
1141 BusLogic_SoftReset(HostAdapter);
1143 Wait until Diagnostic Active is set in the Status Register.
1145 TimeoutCounter = 5 * 10000;
1146 while (--TimeoutCounter >= 0) {
1147 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1148 if (StatusRegister.sr.DiagnosticActive)
1149 break;
1150 udelay(100);
1152 if (BusLogic_GlobalOptions.TraceHardwareReset)
1153 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All);
1154 if (TimeoutCounter < 0)
1155 return false;
1157 Wait 100 microseconds to allow completion of any initial diagnostic
1158 activity which might leave the contents of the Status Register
1159 unpredictable.
1161 udelay(100);
1163 Wait until Diagnostic Active is reset in the Status Register.
1165 TimeoutCounter = 10 * 10000;
1166 while (--TimeoutCounter >= 0) {
1167 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1168 if (!StatusRegister.sr.DiagnosticActive)
1169 break;
1170 udelay(100);
1172 if (BusLogic_GlobalOptions.TraceHardwareReset)
1173 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All);
1174 if (TimeoutCounter < 0)
1175 return false;
1177 Wait until at least one of the Diagnostic Failure, Host Adapter Ready,
1178 or Data In Register Ready bits is set in the Status Register.
1180 TimeoutCounter = 10000;
1181 while (--TimeoutCounter >= 0) {
1182 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1183 if (StatusRegister.sr.DiagnosticFailure || StatusRegister.sr.HostAdapterReady || StatusRegister.sr.DataInRegisterReady)
1184 break;
1185 udelay(100);
1187 if (BusLogic_GlobalOptions.TraceHardwareReset)
1188 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All);
1189 if (TimeoutCounter < 0)
1190 return false;
1192 If Diagnostic Failure is set or Host Adapter Ready is reset, then an
1193 error occurred during the Host Adapter diagnostics. If Data In Register
1194 Ready is set, then there is an Error Code available.
1196 if (StatusRegister.sr.DiagnosticFailure || !StatusRegister.sr.HostAdapterReady) {
1197 BusLogic_CommandFailureReason = NULL;
1198 BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
1199 BusLogic_Error("HOST ADAPTER STATUS REGISTER = %02X\n", HostAdapter, StatusRegister.All);
1200 if (StatusRegister.sr.DataInRegisterReady) {
1201 unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
1202 BusLogic_Error("HOST ADAPTER ERROR CODE = %d\n", HostAdapter, ErrorCode);
1204 return false;
1207 Indicate the Host Adapter Hard Reset completed successfully.
1209 return true;
1214 BusLogic_CheckHostAdapter checks to be sure this really is a BusLogic
1215 Host Adapter.
1218 static bool __init BusLogic_CheckHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
1220 struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation;
1221 unsigned char RequestedReplyLength;
1222 bool Result = true;
1224 FlashPoint Host Adapters do not require this protection.
1226 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1227 return true;
1229 Issue the Inquire Extended Setup Information command. Only genuine
1230 BusLogic Host Adapters and true clones support this command. Adaptec 1542C
1231 series Host Adapters that respond to the Geometry Register I/O port will
1232 fail this command.
1234 RequestedReplyLength = sizeof(ExtendedSetupInformation);
1235 if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &ExtendedSetupInformation, sizeof(ExtendedSetupInformation))
1236 != sizeof(ExtendedSetupInformation))
1237 Result = false;
1239 Provide tracing information if requested and return.
1241 if (BusLogic_GlobalOptions.TraceProbe)
1242 BusLogic_Notice("BusLogic_Check(0x%X): MultiMaster %s\n", HostAdapter, HostAdapter->IO_Address, (Result ? "Found" : "Not Found"));
1243 return Result;
1248 BusLogic_ReadHostAdapterConfiguration reads the Configuration Information
1249 from Host Adapter and initializes the Host Adapter structure.
1252 static bool __init BusLogic_ReadHostAdapterConfiguration(struct BusLogic_HostAdapter
1253 *HostAdapter)
1255 struct BusLogic_BoardID BoardID;
1256 struct BusLogic_Configuration Configuration;
1257 struct BusLogic_SetupInformation SetupInformation;
1258 struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation;
1259 unsigned char HostAdapterModelNumber[5];
1260 unsigned char FirmwareVersion3rdDigit;
1261 unsigned char FirmwareVersionLetter;
1262 struct BusLogic_PCIHostAdapterInformation PCIHostAdapterInformation;
1263 struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest;
1264 struct BusLogic_AutoSCSIData AutoSCSIData;
1265 union BusLogic_GeometryRegister GeometryRegister;
1266 unsigned char RequestedReplyLength;
1267 unsigned char *TargetPointer, Character;
1268 int TargetID, i;
1270 Configuration Information for FlashPoint Host Adapters is provided in the
1271 FlashPoint_Info structure by the FlashPoint SCCB Manager's Probe Function.
1272 Initialize fields in the Host Adapter structure from the FlashPoint_Info
1273 structure.
1275 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1276 struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
1277 TargetPointer = HostAdapter->ModelName;
1278 *TargetPointer++ = 'B';
1279 *TargetPointer++ = 'T';
1280 *TargetPointer++ = '-';
1281 for (i = 0; i < sizeof(FlashPointInfo->ModelNumber); i++)
1282 *TargetPointer++ = FlashPointInfo->ModelNumber[i];
1283 *TargetPointer++ = '\0';
1284 strcpy(HostAdapter->FirmwareVersion, FlashPoint_FirmwareVersion);
1285 HostAdapter->SCSI_ID = FlashPointInfo->SCSI_ID;
1286 HostAdapter->ExtendedTranslationEnabled = FlashPointInfo->ExtendedTranslationEnabled;
1287 HostAdapter->ParityCheckingEnabled = FlashPointInfo->ParityCheckingEnabled;
1288 HostAdapter->BusResetEnabled = !FlashPointInfo->HostSoftReset;
1289 HostAdapter->LevelSensitiveInterrupt = true;
1290 HostAdapter->HostWideSCSI = FlashPointInfo->HostWideSCSI;
1291 HostAdapter->HostDifferentialSCSI = false;
1292 HostAdapter->HostSupportsSCAM = true;
1293 HostAdapter->HostUltraSCSI = true;
1294 HostAdapter->ExtendedLUNSupport = true;
1295 HostAdapter->TerminationInfoValid = true;
1296 HostAdapter->LowByteTerminated = FlashPointInfo->LowByteTerminated;
1297 HostAdapter->HighByteTerminated = FlashPointInfo->HighByteTerminated;
1298 HostAdapter->SCAM_Enabled = FlashPointInfo->SCAM_Enabled;
1299 HostAdapter->SCAM_Level2 = FlashPointInfo->SCAM_Level2;
1300 HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1301 HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1302 HostAdapter->MaxLogicalUnits = 32;
1303 HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1304 HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1305 HostAdapter->DriverQueueDepth = 255;
1306 HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth;
1307 HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted;
1308 HostAdapter->FastPermitted = FlashPointInfo->FastPermitted;
1309 HostAdapter->UltraPermitted = FlashPointInfo->UltraPermitted;
1310 HostAdapter->WidePermitted = FlashPointInfo->WidePermitted;
1311 HostAdapter->DisconnectPermitted = FlashPointInfo->DisconnectPermitted;
1312 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1313 goto Common;
1316 Issue the Inquire Board ID command.
1318 if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0, &BoardID, sizeof(BoardID)) != sizeof(BoardID))
1319 return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
1321 Issue the Inquire Configuration command.
1323 if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0, &Configuration, sizeof(Configuration))
1324 != sizeof(Configuration))
1325 return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
1327 Issue the Inquire Setup Information command.
1329 RequestedReplyLength = sizeof(SetupInformation);
1330 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &SetupInformation, sizeof(SetupInformation))
1331 != sizeof(SetupInformation))
1332 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
1334 Issue the Inquire Extended Setup Information command.
1336 RequestedReplyLength = sizeof(ExtendedSetupInformation);
1337 if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &ExtendedSetupInformation, sizeof(ExtendedSetupInformation))
1338 != sizeof(ExtendedSetupInformation))
1339 return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
1341 Issue the Inquire Firmware Version 3rd Digit command.
1343 FirmwareVersion3rdDigit = '\0';
1344 if (BoardID.FirmwareVersion1stDigit > '0')
1345 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit, NULL, 0, &FirmwareVersion3rdDigit, sizeof(FirmwareVersion3rdDigit))
1346 != sizeof(FirmwareVersion3rdDigit))
1347 return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
1349 Issue the Inquire Host Adapter Model Number command.
1351 if (ExtendedSetupInformation.BusType == 'A' && BoardID.FirmwareVersion1stDigit == '2')
1352 /* BusLogic BT-542B ISA 2.xx */
1353 strcpy(HostAdapterModelNumber, "542B");
1354 else if (ExtendedSetupInformation.BusType == 'E' && BoardID.FirmwareVersion1stDigit == '2' && (BoardID.FirmwareVersion2ndDigit <= '1' || (BoardID.FirmwareVersion2ndDigit == '2' && FirmwareVersion3rdDigit == '0')))
1355 /* BusLogic BT-742A EISA 2.1x or 2.20 */
1356 strcpy(HostAdapterModelNumber, "742A");
1357 else if (ExtendedSetupInformation.BusType == 'E' && BoardID.FirmwareVersion1stDigit == '0')
1358 /* AMI FastDisk EISA Series 441 0.x */
1359 strcpy(HostAdapterModelNumber, "747A");
1360 else {
1361 RequestedReplyLength = sizeof(HostAdapterModelNumber);
1362 if (BusLogic_Command(HostAdapter, BusLogic_InquireHostAdapterModelNumber, &RequestedReplyLength, sizeof(RequestedReplyLength), &HostAdapterModelNumber, sizeof(HostAdapterModelNumber))
1363 != sizeof(HostAdapterModelNumber))
1364 return BusLogic_Failure(HostAdapter, "INQUIRE HOST ADAPTER MODEL NUMBER");
1367 BusLogic MultiMaster Host Adapters can be identified by their model number
1368 and the major version number of their firmware as follows:
1370 5.xx BusLogic "W" Series Host Adapters:
1371 BT-948/958/958D
1372 4.xx BusLogic "C" Series Host Adapters:
1373 BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
1374 3.xx BusLogic "S" Series Host Adapters:
1375 BT-747S/747D/757S/757D/445S/545S/542D
1376 BT-542B/742A (revision H)
1377 2.xx BusLogic "A" Series Host Adapters:
1378 BT-542B/742A (revision G and below)
1379 0.xx AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
1382 Save the Model Name and Host Adapter Name in the Host Adapter structure.
1384 TargetPointer = HostAdapter->ModelName;
1385 *TargetPointer++ = 'B';
1386 *TargetPointer++ = 'T';
1387 *TargetPointer++ = '-';
1388 for (i = 0; i < sizeof(HostAdapterModelNumber); i++) {
1389 Character = HostAdapterModelNumber[i];
1390 if (Character == ' ' || Character == '\0')
1391 break;
1392 *TargetPointer++ = Character;
1394 *TargetPointer++ = '\0';
1396 Save the Firmware Version in the Host Adapter structure.
1398 TargetPointer = HostAdapter->FirmwareVersion;
1399 *TargetPointer++ = BoardID.FirmwareVersion1stDigit;
1400 *TargetPointer++ = '.';
1401 *TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
1402 if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0')
1403 *TargetPointer++ = FirmwareVersion3rdDigit;
1404 *TargetPointer = '\0';
1406 Issue the Inquire Firmware Version Letter command.
1408 if (strcmp(HostAdapter->FirmwareVersion, "3.3") >= 0) {
1409 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter, NULL, 0, &FirmwareVersionLetter, sizeof(FirmwareVersionLetter))
1410 != sizeof(FirmwareVersionLetter))
1411 return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE VERSION LETTER");
1412 if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0')
1413 *TargetPointer++ = FirmwareVersionLetter;
1414 *TargetPointer = '\0';
1417 Save the Host Adapter SCSI ID in the Host Adapter structure.
1419 HostAdapter->SCSI_ID = Configuration.HostAdapterID;
1421 Determine the Bus Type and save it in the Host Adapter structure, determine
1422 and save the IRQ Channel if necessary, and determine and save the DMA
1423 Channel for ISA Host Adapters.
1425 HostAdapter->HostAdapterBusType = BusLogic_HostAdapterBusTypes[HostAdapter->ModelName[3] - '4'];
1426 if (HostAdapter->IRQ_Channel == 0) {
1427 if (Configuration.IRQ_Channel9)
1428 HostAdapter->IRQ_Channel = 9;
1429 else if (Configuration.IRQ_Channel10)
1430 HostAdapter->IRQ_Channel = 10;
1431 else if (Configuration.IRQ_Channel11)
1432 HostAdapter->IRQ_Channel = 11;
1433 else if (Configuration.IRQ_Channel12)
1434 HostAdapter->IRQ_Channel = 12;
1435 else if (Configuration.IRQ_Channel14)
1436 HostAdapter->IRQ_Channel = 14;
1437 else if (Configuration.IRQ_Channel15)
1438 HostAdapter->IRQ_Channel = 15;
1440 if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus) {
1441 if (Configuration.DMA_Channel5)
1442 HostAdapter->DMA_Channel = 5;
1443 else if (Configuration.DMA_Channel6)
1444 HostAdapter->DMA_Channel = 6;
1445 else if (Configuration.DMA_Channel7)
1446 HostAdapter->DMA_Channel = 7;
1449 Determine whether Extended Translation is enabled and save it in
1450 the Host Adapter structure.
1452 GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1453 HostAdapter->ExtendedTranslationEnabled = GeometryRegister.gr.ExtendedTranslationEnabled;
1455 Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide
1456 SCSI flag, Differential SCSI flag, SCAM Supported flag, and
1457 Ultra SCSI flag in the Host Adapter structure.
1459 HostAdapter->HostAdapterScatterGatherLimit = ExtendedSetupInformation.ScatterGatherLimit;
1460 HostAdapter->DriverScatterGatherLimit = HostAdapter->HostAdapterScatterGatherLimit;
1461 if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
1462 HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1463 if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupt)
1464 HostAdapter->LevelSensitiveInterrupt = true;
1465 HostAdapter->HostWideSCSI = ExtendedSetupInformation.HostWideSCSI;
1466 HostAdapter->HostDifferentialSCSI = ExtendedSetupInformation.HostDifferentialSCSI;
1467 HostAdapter->HostSupportsSCAM = ExtendedSetupInformation.HostSupportsSCAM;
1468 HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI;
1470 Determine whether Extended LUN Format CCBs are supported and save the
1471 information in the Host Adapter structure.
1473 if (HostAdapter->FirmwareVersion[0] == '5' || (HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI))
1474 HostAdapter->ExtendedLUNSupport = true;
1476 Issue the Inquire PCI Host Adapter Information command to read the
1477 Termination Information from "W" series MultiMaster Host Adapters.
1479 if (HostAdapter->FirmwareVersion[0] == '5') {
1480 if (BusLogic_Command(HostAdapter, BusLogic_InquirePCIHostAdapterInformation, NULL, 0, &PCIHostAdapterInformation, sizeof(PCIHostAdapterInformation))
1481 != sizeof(PCIHostAdapterInformation))
1482 return BusLogic_Failure(HostAdapter, "INQUIRE PCI HOST ADAPTER INFORMATION");
1484 Save the Termination Information in the Host Adapter structure.
1486 if (PCIHostAdapterInformation.GenericInfoValid) {
1487 HostAdapter->TerminationInfoValid = true;
1488 HostAdapter->LowByteTerminated = PCIHostAdapterInformation.LowByteTerminated;
1489 HostAdapter->HighByteTerminated = PCIHostAdapterInformation.HighByteTerminated;
1493 Issue the Fetch Host Adapter Local RAM command to read the AutoSCSI data
1494 from "W" and "C" series MultiMaster Host Adapters.
1496 if (HostAdapter->FirmwareVersion[0] >= '4') {
1497 FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_AutoSCSI_BaseOffset;
1498 FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIData);
1499 if (BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &AutoSCSIData, sizeof(AutoSCSIData))
1500 != sizeof(AutoSCSIData))
1501 return BusLogic_Failure(HostAdapter, "FETCH HOST ADAPTER LOCAL RAM");
1503 Save the Parity Checking Enabled, Bus Reset Enabled, and Termination
1504 Information in the Host Adapter structure.
1506 HostAdapter->ParityCheckingEnabled = AutoSCSIData.ParityCheckingEnabled;
1507 HostAdapter->BusResetEnabled = AutoSCSIData.BusResetEnabled;
1508 if (HostAdapter->FirmwareVersion[0] == '4') {
1509 HostAdapter->TerminationInfoValid = true;
1510 HostAdapter->LowByteTerminated = AutoSCSIData.LowByteTerminated;
1511 HostAdapter->HighByteTerminated = AutoSCSIData.HighByteTerminated;
1514 Save the Wide Permitted, Fast Permitted, Synchronous Permitted,
1515 Disconnect Permitted, Ultra Permitted, and SCAM Information in the
1516 Host Adapter structure.
1518 HostAdapter->WidePermitted = AutoSCSIData.WidePermitted;
1519 HostAdapter->FastPermitted = AutoSCSIData.FastPermitted;
1520 HostAdapter->SynchronousPermitted = AutoSCSIData.SynchronousPermitted;
1521 HostAdapter->DisconnectPermitted = AutoSCSIData.DisconnectPermitted;
1522 if (HostAdapter->HostUltraSCSI)
1523 HostAdapter->UltraPermitted = AutoSCSIData.UltraPermitted;
1524 if (HostAdapter->HostSupportsSCAM) {
1525 HostAdapter->SCAM_Enabled = AutoSCSIData.SCAM_Enabled;
1526 HostAdapter->SCAM_Level2 = AutoSCSIData.SCAM_Level2;
1530 Initialize fields in the Host Adapter structure for "S" and "A" series
1531 MultiMaster Host Adapters.
1533 if (HostAdapter->FirmwareVersion[0] < '4') {
1534 if (SetupInformation.SynchronousInitiationEnabled) {
1535 HostAdapter->SynchronousPermitted = 0xFF;
1536 if (HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus) {
1537 if (ExtendedSetupInformation.Misc.FastOnEISA)
1538 HostAdapter->FastPermitted = 0xFF;
1539 if (strcmp(HostAdapter->ModelName, "BT-757") == 0)
1540 HostAdapter->WidePermitted = 0xFF;
1543 HostAdapter->DisconnectPermitted = 0xFF;
1544 HostAdapter->ParityCheckingEnabled = SetupInformation.ParityCheckingEnabled;
1545 HostAdapter->BusResetEnabled = true;
1548 Determine the maximum number of Target IDs and Logical Units supported by
1549 this driver for Wide and Narrow Host Adapters.
1551 HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1552 HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8);
1554 Select appropriate values for the Mailbox Count, Driver Queue Depth,
1555 Initial CCBs, and Incremental CCBs variables based on whether or not Strict
1556 Round Robin Mode is supported. If Strict Round Robin Mode is supported,
1557 then there is no performance degradation in using the maximum possible
1558 number of Outgoing and Incoming Mailboxes and allowing the Tagged and
1559 Untagged Queue Depths to determine the actual utilization. If Strict Round
1560 Robin Mode is not supported, then the Host Adapter must scan all the
1561 Outgoing Mailboxes whenever an Outgoing Mailbox entry is made, which can
1562 cause a substantial performance penalty. The host adapters actually have
1563 room to store the following number of CCBs internally; that is, they can
1564 internally queue and manage this many active commands on the SCSI bus
1565 simultaneously. Performance measurements demonstrate that the Driver Queue
1566 Depth should be set to the Mailbox Count, rather than the Host Adapter
1567 Queue Depth (internal CCB capacity), as it is more efficient to have the
1568 queued commands waiting in Outgoing Mailboxes if necessary than to block
1569 the process in the higher levels of the SCSI Subsystem.
1571 192 BT-948/958/958D
1572 100 BT-946C/956C/956CD/747C/757C/757CD/445C
1573 50 BT-545C/540CF
1574 30 BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
1576 if (HostAdapter->FirmwareVersion[0] == '5')
1577 HostAdapter->HostAdapterQueueDepth = 192;
1578 else if (HostAdapter->FirmwareVersion[0] == '4')
1579 HostAdapter->HostAdapterQueueDepth = (HostAdapter->HostAdapterBusType != BusLogic_ISA_Bus ? 100 : 50);
1580 else
1581 HostAdapter->HostAdapterQueueDepth = 30;
1582 if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0) {
1583 HostAdapter->StrictRoundRobinModeSupport = true;
1584 HostAdapter->MailboxCount = BusLogic_MaxMailboxes;
1585 } else {
1586 HostAdapter->StrictRoundRobinModeSupport = false;
1587 HostAdapter->MailboxCount = 32;
1589 HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount;
1590 HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1591 HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1593 Tagged Queuing support is available and operates properly on all "W" series
1594 MultiMaster Host Adapters, on "C" series MultiMaster Host Adapters with
1595 firmware version 4.22 and above, and on "S" series MultiMaster Host
1596 Adapters with firmware version 3.35 and above.
1598 HostAdapter->TaggedQueuingPermitted = 0;
1599 switch (HostAdapter->FirmwareVersion[0]) {
1600 case '5':
1601 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1602 break;
1603 case '4':
1604 if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0)
1605 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1606 break;
1607 case '3':
1608 if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0)
1609 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1610 break;
1613 Determine the Host Adapter BIOS Address if the BIOS is enabled and
1614 save it in the Host Adapter structure. The BIOS is disabled if the
1615 BIOS_Address is 0.
1617 HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
1619 ISA Host Adapters require Bounce Buffers if there is more than 16MB memory.
1621 if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus && (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1622 HostAdapter->BounceBuffersRequired = true;
1624 BusLogic BT-445S Host Adapters prior to board revision E have a hardware
1625 bug whereby when the BIOS is enabled, transfers to/from the same address
1626 range the BIOS occupies modulo 16MB are handled incorrectly. Only properly
1627 functioning BT-445S Host Adapters have firmware version 3.37, so require
1628 that ISA Bounce Buffers be used for the buggy BT-445S models if there is
1629 more than 16MB memory.
1631 if (HostAdapter->BIOS_Address > 0 && strcmp(HostAdapter->ModelName, "BT-445S") == 0 && strcmp(HostAdapter->FirmwareVersion, "3.37") < 0 && (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1632 HostAdapter->BounceBuffersRequired = true;
1634 Initialize parameters common to MultiMaster and FlashPoint Host Adapters.
1636 Common:
1638 Initialize the Host Adapter Full Model Name from the Model Name.
1640 strcpy(HostAdapter->FullModelName, "BusLogic ");
1641 strcat(HostAdapter->FullModelName, HostAdapter->ModelName);
1643 Select an appropriate value for the Tagged Queue Depth either from a
1644 BusLogic Driver Options specification, or based on whether this Host
1645 Adapter requires that ISA Bounce Buffers be used. The Tagged Queue Depth
1646 is left at 0 for automatic determination in BusLogic_SelectQueueDepths.
1647 Initialize the Untagged Queue Depth.
1649 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) {
1650 unsigned char QueueDepth = 0;
1651 if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->QueueDepth[TargetID] > 0)
1652 QueueDepth = HostAdapter->DriverOptions->QueueDepth[TargetID];
1653 else if (HostAdapter->BounceBuffersRequired)
1654 QueueDepth = BusLogic_TaggedQueueDepthBB;
1655 HostAdapter->QueueDepth[TargetID] = QueueDepth;
1657 if (HostAdapter->BounceBuffersRequired)
1658 HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepthBB;
1659 else
1660 HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth;
1661 if (HostAdapter->DriverOptions != NULL)
1662 HostAdapter->CommonQueueDepth = HostAdapter->DriverOptions->CommonQueueDepth;
1663 if (HostAdapter->CommonQueueDepth > 0 && HostAdapter->CommonQueueDepth < HostAdapter->UntaggedQueueDepth)
1664 HostAdapter->UntaggedQueueDepth = HostAdapter->CommonQueueDepth;
1666 Tagged Queuing is only allowed if Disconnect/Reconnect is permitted.
1667 Therefore, mask the Tagged Queuing Permitted Default bits with the
1668 Disconnect/Reconnect Permitted bits.
1670 HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted;
1672 Combine the default Tagged Queuing Permitted bits with any BusLogic Driver
1673 Options Tagged Queuing specification.
1675 if (HostAdapter->DriverOptions != NULL)
1676 HostAdapter->TaggedQueuingPermitted =
1677 (HostAdapter->DriverOptions->TaggedQueuingPermitted & HostAdapter->DriverOptions->TaggedQueuingPermittedMask) | (HostAdapter->TaggedQueuingPermitted & ~HostAdapter->DriverOptions->TaggedQueuingPermittedMask);
1680 Select an appropriate value for Bus Settle Time either from a BusLogic
1681 Driver Options specification, or from BusLogic_DefaultBusSettleTime.
1683 if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->BusSettleTime > 0)
1684 HostAdapter->BusSettleTime = HostAdapter->DriverOptions->BusSettleTime;
1685 else
1686 HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
1688 Indicate reading the Host Adapter Configuration completed successfully.
1690 return true;
1695 BusLogic_ReportHostAdapterConfiguration reports the configuration of
1696 Host Adapter.
1699 static bool __init BusLogic_ReportHostAdapterConfiguration(struct BusLogic_HostAdapter
1700 *HostAdapter)
1702 unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1;
1703 unsigned short SynchronousPermitted, FastPermitted;
1704 unsigned short UltraPermitted, WidePermitted;
1705 unsigned short DisconnectPermitted, TaggedQueuingPermitted;
1706 bool CommonSynchronousNegotiation, CommonTaggedQueueDepth;
1707 char SynchronousString[BusLogic_MaxTargetDevices + 1];
1708 char WideString[BusLogic_MaxTargetDevices + 1];
1709 char DisconnectString[BusLogic_MaxTargetDevices + 1];
1710 char TaggedQueuingString[BusLogic_MaxTargetDevices + 1];
1711 char *SynchronousMessage = SynchronousString;
1712 char *WideMessage = WideString;
1713 char *DisconnectMessage = DisconnectString;
1714 char *TaggedQueuingMessage = TaggedQueuingString;
1715 int TargetID;
1716 BusLogic_Info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n",
1717 HostAdapter, HostAdapter->ModelName,
1718 BusLogic_HostAdapterBusNames[HostAdapter->HostAdapterBusType], (HostAdapter->HostWideSCSI ? " Wide" : ""), (HostAdapter->HostDifferentialSCSI ? " Differential" : ""), (HostAdapter->HostUltraSCSI ? " Ultra" : ""));
1719 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"));
1720 if (HostAdapter->HostAdapterBusType != BusLogic_PCI_Bus) {
1721 BusLogic_Info(" DMA Channel: ", HostAdapter);
1722 if (HostAdapter->DMA_Channel > 0)
1723 BusLogic_Info("%d, ", HostAdapter, HostAdapter->DMA_Channel);
1724 else
1725 BusLogic_Info("None, ", HostAdapter);
1726 if (HostAdapter->BIOS_Address > 0)
1727 BusLogic_Info("BIOS Address: 0x%X, ", HostAdapter, HostAdapter->BIOS_Address);
1728 else
1729 BusLogic_Info("BIOS Address: None, ", HostAdapter);
1730 } else {
1731 BusLogic_Info(" PCI Bus: %d, Device: %d, Address: ", HostAdapter, HostAdapter->Bus, HostAdapter->Device);
1732 if (HostAdapter->PCI_Address > 0)
1733 BusLogic_Info("0x%X, ", HostAdapter, HostAdapter->PCI_Address);
1734 else
1735 BusLogic_Info("Unassigned, ", HostAdapter);
1737 BusLogic_Info("Host Adapter SCSI ID: %d\n", HostAdapter, HostAdapter->SCSI_ID);
1738 BusLogic_Info(" Parity Checking: %s, Extended Translation: %s\n", HostAdapter, (HostAdapter->ParityCheckingEnabled ? "Enabled" : "Disabled"), (HostAdapter->ExtendedTranslationEnabled ? "Enabled" : "Disabled"));
1739 AllTargetsMask &= ~(1 << HostAdapter->SCSI_ID);
1740 SynchronousPermitted = HostAdapter->SynchronousPermitted & AllTargetsMask;
1741 FastPermitted = HostAdapter->FastPermitted & AllTargetsMask;
1742 UltraPermitted = HostAdapter->UltraPermitted & AllTargetsMask;
1743 if ((BusLogic_MultiMasterHostAdapterP(HostAdapter) && (HostAdapter->FirmwareVersion[0] >= '4' || HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)) || BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1744 CommonSynchronousNegotiation = false;
1745 if (SynchronousPermitted == 0) {
1746 SynchronousMessage = "Disabled";
1747 CommonSynchronousNegotiation = true;
1748 } else if (SynchronousPermitted == AllTargetsMask) {
1749 if (FastPermitted == 0) {
1750 SynchronousMessage = "Slow";
1751 CommonSynchronousNegotiation = true;
1752 } else if (FastPermitted == AllTargetsMask) {
1753 if (UltraPermitted == 0) {
1754 SynchronousMessage = "Fast";
1755 CommonSynchronousNegotiation = true;
1756 } else if (UltraPermitted == AllTargetsMask) {
1757 SynchronousMessage = "Ultra";
1758 CommonSynchronousNegotiation = true;
1762 if (!CommonSynchronousNegotiation) {
1763 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1764 SynchronousString[TargetID] = ((!(SynchronousPermitted & (1 << TargetID))) ? 'N' : (!(FastPermitted & (1 << TargetID)) ? 'S' : (!(UltraPermitted & (1 << TargetID)) ? 'F' : 'U')));
1765 SynchronousString[HostAdapter->SCSI_ID] = '#';
1766 SynchronousString[HostAdapter->MaxTargetDevices] = '\0';
1768 } else
1769 SynchronousMessage = (SynchronousPermitted == 0 ? "Disabled" : "Enabled");
1770 WidePermitted = HostAdapter->WidePermitted & AllTargetsMask;
1771 if (WidePermitted == 0)
1772 WideMessage = "Disabled";
1773 else if (WidePermitted == AllTargetsMask)
1774 WideMessage = "Enabled";
1775 else {
1776 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1777 WideString[TargetID] = ((WidePermitted & (1 << TargetID)) ? 'Y' : 'N');
1778 WideString[HostAdapter->SCSI_ID] = '#';
1779 WideString[HostAdapter->MaxTargetDevices] = '\0';
1781 DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
1782 if (DisconnectPermitted == 0)
1783 DisconnectMessage = "Disabled";
1784 else if (DisconnectPermitted == AllTargetsMask)
1785 DisconnectMessage = "Enabled";
1786 else {
1787 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1788 DisconnectString[TargetID] = ((DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
1789 DisconnectString[HostAdapter->SCSI_ID] = '#';
1790 DisconnectString[HostAdapter->MaxTargetDevices] = '\0';
1792 TaggedQueuingPermitted = HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
1793 if (TaggedQueuingPermitted == 0)
1794 TaggedQueuingMessage = "Disabled";
1795 else if (TaggedQueuingPermitted == AllTargetsMask)
1796 TaggedQueuingMessage = "Enabled";
1797 else {
1798 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1799 TaggedQueuingString[TargetID] = ((TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
1800 TaggedQueuingString[HostAdapter->SCSI_ID] = '#';
1801 TaggedQueuingString[HostAdapter->MaxTargetDevices] = '\0';
1803 BusLogic_Info(" Synchronous Negotiation: %s, Wide Negotiation: %s\n", HostAdapter, SynchronousMessage, WideMessage);
1804 BusLogic_Info(" Disconnect/Reconnect: %s, Tagged Queuing: %s\n", HostAdapter, DisconnectMessage, TaggedQueuingMessage);
1805 if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
1806 BusLogic_Info(" Scatter/Gather Limit: %d of %d segments, " "Mailboxes: %d\n", HostAdapter, HostAdapter->DriverScatterGatherLimit, HostAdapter->HostAdapterScatterGatherLimit, HostAdapter->MailboxCount);
1807 BusLogic_Info(" Driver Queue Depth: %d, " "Host Adapter Queue Depth: %d\n", HostAdapter, HostAdapter->DriverQueueDepth, HostAdapter->HostAdapterQueueDepth);
1808 } else
1809 BusLogic_Info(" Driver Queue Depth: %d, " "Scatter/Gather Limit: %d segments\n", HostAdapter, HostAdapter->DriverQueueDepth, HostAdapter->DriverScatterGatherLimit);
1810 BusLogic_Info(" Tagged Queue Depth: ", HostAdapter);
1811 CommonTaggedQueueDepth = true;
1812 for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1813 if (HostAdapter->QueueDepth[TargetID] != HostAdapter->QueueDepth[0]) {
1814 CommonTaggedQueueDepth = false;
1815 break;
1817 if (CommonTaggedQueueDepth) {
1818 if (HostAdapter->QueueDepth[0] > 0)
1819 BusLogic_Info("%d", HostAdapter, HostAdapter->QueueDepth[0]);
1820 else
1821 BusLogic_Info("Automatic", HostAdapter);
1822 } else
1823 BusLogic_Info("Individual", HostAdapter);
1824 BusLogic_Info(", Untagged Queue Depth: %d\n", HostAdapter, HostAdapter->UntaggedQueueDepth);
1825 if (HostAdapter->TerminationInfoValid) {
1826 if (HostAdapter->HostWideSCSI)
1827 BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter, (HostAdapter->LowByteTerminated ? (HostAdapter->HighByteTerminated ? "Both Enabled" : "Low Enabled")
1828 : (HostAdapter->HighByteTerminated ? "High Enabled" : "Both Disabled")));
1829 else
1830 BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter, (HostAdapter->LowByteTerminated ? "Enabled" : "Disabled"));
1831 if (HostAdapter->HostSupportsSCAM)
1832 BusLogic_Info(", SCAM: %s", HostAdapter, (HostAdapter->SCAM_Enabled ? (HostAdapter->SCAM_Level2 ? "Enabled, Level 2" : "Enabled, Level 1")
1833 : "Disabled"));
1834 BusLogic_Info("\n", HostAdapter);
1837 Indicate reporting the Host Adapter configuration completed successfully.
1839 return true;
1844 BusLogic_AcquireResources acquires the system resources necessary to use
1845 Host Adapter.
1848 static bool __init BusLogic_AcquireResources(struct BusLogic_HostAdapter *HostAdapter)
1850 if (HostAdapter->IRQ_Channel == 0) {
1851 BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n", HostAdapter);
1852 return false;
1855 Acquire shared access to the IRQ Channel.
1857 if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler, IRQF_SHARED, HostAdapter->FullModelName, HostAdapter) < 0) {
1858 BusLogic_Error("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n", HostAdapter, HostAdapter->IRQ_Channel);
1859 return false;
1861 HostAdapter->IRQ_ChannelAcquired = true;
1863 Acquire exclusive access to the DMA Channel.
1865 if (HostAdapter->DMA_Channel > 0) {
1866 if (request_dma(HostAdapter->DMA_Channel, HostAdapter->FullModelName) < 0) {
1867 BusLogic_Error("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n", HostAdapter, HostAdapter->DMA_Channel);
1868 return false;
1870 set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
1871 enable_dma(HostAdapter->DMA_Channel);
1872 HostAdapter->DMA_ChannelAcquired = true;
1875 Indicate the System Resource Acquisition completed successfully,
1877 return true;
1882 BusLogic_ReleaseResources releases any system resources previously acquired
1883 by BusLogic_AcquireResources.
1886 static void BusLogic_ReleaseResources(struct BusLogic_HostAdapter *HostAdapter)
1889 Release shared access to the IRQ Channel.
1891 if (HostAdapter->IRQ_ChannelAcquired)
1892 free_irq(HostAdapter->IRQ_Channel, HostAdapter);
1894 Release exclusive access to the DMA Channel.
1896 if (HostAdapter->DMA_ChannelAcquired)
1897 free_dma(HostAdapter->DMA_Channel);
1899 Release any allocated memory structs not released elsewhere
1901 if (HostAdapter->MailboxSpace)
1902 pci_free_consistent(HostAdapter->PCI_Device, HostAdapter->MailboxSize, HostAdapter->MailboxSpace, HostAdapter->MailboxSpaceHandle);
1903 pci_dev_put(HostAdapter->PCI_Device);
1904 HostAdapter->MailboxSpace = NULL;
1905 HostAdapter->MailboxSpaceHandle = 0;
1906 HostAdapter->MailboxSize = 0;
1911 BusLogic_InitializeHostAdapter initializes Host Adapter. This is the only
1912 function called during SCSI Host Adapter detection which modifies the state
1913 of the Host Adapter from its initial power on or hard reset state.
1916 static bool BusLogic_InitializeHostAdapter(struct BusLogic_HostAdapter
1917 *HostAdapter)
1919 struct BusLogic_ExtendedMailboxRequest ExtendedMailboxRequest;
1920 enum BusLogic_RoundRobinModeRequest RoundRobinModeRequest;
1921 enum BusLogic_SetCCBFormatRequest SetCCBFormatRequest;
1922 int TargetID;
1924 Initialize the pointers to the first and last CCBs that are queued for
1925 completion processing.
1927 HostAdapter->FirstCompletedCCB = NULL;
1928 HostAdapter->LastCompletedCCB = NULL;
1930 Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active,
1931 Command Successful Flag, Active Commands, and Commands Since Reset
1932 for each Target Device.
1934 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
1935 HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
1936 HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
1937 HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
1938 HostAdapter->ActiveCommands[TargetID] = 0;
1939 HostAdapter->CommandsSinceReset[TargetID] = 0;
1942 FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes.
1944 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1945 goto Done;
1947 Initialize the Outgoing and Incoming Mailbox pointers.
1949 HostAdapter->MailboxSize = HostAdapter->MailboxCount * (sizeof(struct BusLogic_OutgoingMailbox) + sizeof(struct BusLogic_IncomingMailbox));
1950 HostAdapter->MailboxSpace = pci_alloc_consistent(HostAdapter->PCI_Device, HostAdapter->MailboxSize, &HostAdapter->MailboxSpaceHandle);
1951 if (HostAdapter->MailboxSpace == NULL)
1952 return BusLogic_Failure(HostAdapter, "MAILBOX ALLOCATION");
1953 HostAdapter->FirstOutgoingMailbox = (struct BusLogic_OutgoingMailbox *) HostAdapter->MailboxSpace;
1954 HostAdapter->LastOutgoingMailbox = HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1;
1955 HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
1956 HostAdapter->FirstIncomingMailbox = (struct BusLogic_IncomingMailbox *) (HostAdapter->LastOutgoingMailbox + 1);
1957 HostAdapter->LastIncomingMailbox = HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1;
1958 HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
1961 Initialize the Outgoing and Incoming Mailbox structures.
1963 memset(HostAdapter->FirstOutgoingMailbox, 0, HostAdapter->MailboxCount * sizeof(struct BusLogic_OutgoingMailbox));
1964 memset(HostAdapter->FirstIncomingMailbox, 0, HostAdapter->MailboxCount * sizeof(struct BusLogic_IncomingMailbox));
1966 Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes.
1968 ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount;
1969 ExtendedMailboxRequest.BaseMailboxAddress = (u32) HostAdapter->MailboxSpaceHandle;
1970 if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox, &ExtendedMailboxRequest, sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
1971 return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION");
1973 Enable Strict Round Robin Mode if supported by the Host Adapter. In
1974 Strict Round Robin Mode, the Host Adapter only looks at the next Outgoing
1975 Mailbox for each new command, rather than scanning through all the
1976 Outgoing Mailboxes to find any that have new commands in them. Strict
1977 Round Robin Mode is significantly more efficient.
1979 if (HostAdapter->StrictRoundRobinModeSupport) {
1980 RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
1981 if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode, &RoundRobinModeRequest, sizeof(RoundRobinModeRequest), NULL, 0) < 0)
1982 return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
1985 For Host Adapters that support Extended LUN Format CCBs, issue the Set CCB
1986 Format command to allow 32 Logical Units per Target Device.
1988 if (HostAdapter->ExtendedLUNSupport) {
1989 SetCCBFormatRequest = BusLogic_ExtendedLUNFormatCCB;
1990 if (BusLogic_Command(HostAdapter, BusLogic_SetCCBFormat, &SetCCBFormatRequest, sizeof(SetCCBFormatRequest), NULL, 0) < 0)
1991 return BusLogic_Failure(HostAdapter, "SET CCB FORMAT");
1994 Announce Successful Initialization.
1996 Done:
1997 if (!HostAdapter->HostAdapterInitialized) {
1998 BusLogic_Info("*** %s Initialized Successfully ***\n", HostAdapter, HostAdapter->FullModelName);
1999 BusLogic_Info("\n", HostAdapter);
2000 } else
2001 BusLogic_Warning("*** %s Initialized Successfully ***\n", HostAdapter, HostAdapter->FullModelName);
2002 HostAdapter->HostAdapterInitialized = true;
2004 Indicate the Host Adapter Initialization completed successfully.
2006 return true;
2011 BusLogic_TargetDeviceInquiry inquires about the Target Devices accessible
2012 through Host Adapter.
2015 static bool __init BusLogic_TargetDeviceInquiry(struct BusLogic_HostAdapter
2016 *HostAdapter)
2018 u16 InstalledDevices;
2019 u8 InstalledDevicesID0to7[8];
2020 struct BusLogic_SetupInformation SetupInformation;
2021 u8 SynchronousPeriod[BusLogic_MaxTargetDevices];
2022 unsigned char RequestedReplyLength;
2023 int TargetID;
2025 Wait a few seconds between the Host Adapter Hard Reset which initiates
2026 a SCSI Bus Reset and issuing any SCSI Commands. Some SCSI devices get
2027 confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
2029 BusLogic_Delay(HostAdapter->BusSettleTime);
2031 FlashPoint Host Adapters do not provide for Target Device Inquiry.
2033 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
2034 return true;
2036 Inhibit the Target Device Inquiry if requested.
2038 if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
2039 return true;
2041 Issue the Inquire Target Devices command for host adapters with firmware
2042 version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command
2043 for older host adapters. This is necessary to force Synchronous Transfer
2044 Negotiation so that the Inquire Setup Information and Inquire Synchronous
2045 Period commands will return valid data. The Inquire Target Devices command
2046 is preferable to Inquire Installed Devices ID 0 to 7 since it only probes
2047 Logical Unit 0 of each Target Device.
2049 if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0) {
2052 * Issue a Inquire Target Devices command. Inquire Target Devices only
2053 * tests Logical Unit 0 of each Target Device unlike the Inquire Installed
2054 * Devices commands which test Logical Units 0 - 7. Two bytes are
2055 * returned, where byte 0 bit 0 set indicates that Target Device 0 exists,
2056 * and so on.
2059 if (BusLogic_Command(HostAdapter, BusLogic_InquireTargetDevices, NULL, 0, &InstalledDevices, sizeof(InstalledDevices))
2060 != sizeof(InstalledDevices))
2061 return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES");
2062 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2063 HostAdapter->TargetFlags[TargetID].TargetExists = (InstalledDevices & (1 << TargetID) ? true : false);
2064 } else {
2067 * Issue an Inquire Installed Devices command. For each Target Device,
2068 * a byte is returned where bit 0 set indicates that Logical Unit 0
2069 * exists, bit 1 set indicates that Logical Unit 1 exists, and so on.
2072 if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7, NULL, 0, &InstalledDevicesID0to7, sizeof(InstalledDevicesID0to7))
2073 != sizeof(InstalledDevicesID0to7))
2074 return BusLogic_Failure(HostAdapter, "INQUIRE INSTALLED DEVICES ID 0 TO 7");
2075 for (TargetID = 0; TargetID < 8; TargetID++)
2076 HostAdapter->TargetFlags[TargetID].TargetExists = (InstalledDevicesID0to7[TargetID] != 0 ? true : false);
2079 Issue the Inquire Setup Information command.
2081 RequestedReplyLength = sizeof(SetupInformation);
2082 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &SetupInformation, sizeof(SetupInformation))
2083 != sizeof(SetupInformation))
2084 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
2085 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2086 HostAdapter->SynchronousOffset[TargetID] = (TargetID < 8 ? SetupInformation.SynchronousValuesID0to7[TargetID].Offset : SetupInformation.SynchronousValuesID8to15[TargetID - 8].Offset);
2087 if (strcmp(HostAdapter->FirmwareVersion, "5.06L") >= 0)
2088 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2089 HostAdapter->TargetFlags[TargetID].WideTransfersActive = (TargetID < 8 ? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID)
2090 ? true : false)
2091 : (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID - 8))
2092 ? true : false));
2094 Issue the Inquire Synchronous Period command.
2096 if (HostAdapter->FirmwareVersion[0] >= '3') {
2098 /* Issue a Inquire Synchronous Period command. For each Target Device,
2099 * a byte is returned which represents the Synchronous Transfer Period
2100 * in units of 10 nanoseconds.
2103 RequestedReplyLength = sizeof(SynchronousPeriod);
2104 if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod, &RequestedReplyLength, sizeof(RequestedReplyLength), &SynchronousPeriod, sizeof(SynchronousPeriod))
2105 != sizeof(SynchronousPeriod))
2106 return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
2107 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2108 HostAdapter->SynchronousPeriod[TargetID] = SynchronousPeriod[TargetID];
2109 } else
2110 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2111 if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
2112 HostAdapter->SynchronousPeriod[TargetID] = 20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
2113 .TransferPeriod;
2115 Indicate the Target Device Inquiry completed successfully.
2117 return true;
2121 BusLogic_InitializeHostStructure initializes the fields in the SCSI Host
2122 structure. The base, io_port, n_io_ports, irq, and dma_channel fields in the
2123 SCSI Host structure are intentionally left uninitialized, as this driver
2124 handles acquisition and release of these resources explicitly, as well as
2125 ensuring exclusive access to the Host Adapter hardware and data structures
2126 through explicit acquisition and release of the Host Adapter's Lock.
2129 static void __init BusLogic_InitializeHostStructure(struct BusLogic_HostAdapter
2130 *HostAdapter, struct Scsi_Host *Host)
2132 Host->max_id = HostAdapter->MaxTargetDevices;
2133 Host->max_lun = HostAdapter->MaxLogicalUnits;
2134 Host->max_channel = 0;
2135 Host->unique_id = HostAdapter->IO_Address;
2136 Host->this_id = HostAdapter->SCSI_ID;
2137 Host->can_queue = HostAdapter->DriverQueueDepth;
2138 Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
2139 Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
2140 Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth;
2144 BusLogic_SlaveConfigure will actually set the queue depth on individual
2145 scsi devices as they are permanently added to the device chain. We
2146 shamelessly rip off the SelectQueueDepths code to make this work mostly
2147 like it used to. Since we don't get called once at the end of the scan
2148 but instead get called for each device, we have to do things a bit
2149 differently.
2151 static int BusLogic_SlaveConfigure(struct scsi_device *Device)
2153 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Device->host->hostdata;
2154 int TargetID = Device->id;
2155 int QueueDepth = HostAdapter->QueueDepth[TargetID];
2157 if (HostAdapter->TargetFlags[TargetID].TaggedQueuingSupported && (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) {
2158 if (QueueDepth == 0)
2159 QueueDepth = BusLogic_MaxAutomaticTaggedQueueDepth;
2160 HostAdapter->QueueDepth[TargetID] = QueueDepth;
2161 scsi_adjust_queue_depth(Device, MSG_SIMPLE_TAG, QueueDepth);
2162 } else {
2163 HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
2164 QueueDepth = HostAdapter->UntaggedQueueDepth;
2165 HostAdapter->QueueDepth[TargetID] = QueueDepth;
2166 scsi_adjust_queue_depth(Device, 0, QueueDepth);
2168 QueueDepth = 0;
2169 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2170 if (HostAdapter->TargetFlags[TargetID].TargetExists) {
2171 QueueDepth += HostAdapter->QueueDepth[TargetID];
2173 if (QueueDepth > HostAdapter->AllocatedCCBs)
2174 BusLogic_CreateAdditionalCCBs(HostAdapter, QueueDepth - HostAdapter->AllocatedCCBs, false);
2175 return 0;
2179 BusLogic_DetectHostAdapter probes for BusLogic Host Adapters at the standard
2180 I/O Addresses where they may be located, initializing, registering, and
2181 reporting the configuration of each BusLogic Host Adapter it finds. It
2182 returns the number of BusLogic Host Adapters successfully initialized and
2183 registered.
2186 static int __init BusLogic_init(void)
2188 int BusLogicHostAdapterCount = 0, DriverOptionsIndex = 0, ProbeIndex;
2189 struct BusLogic_HostAdapter *PrototypeHostAdapter;
2190 int ret = 0;
2192 #ifdef MODULE
2193 if (BusLogic)
2194 BusLogic_Setup(BusLogic);
2195 #endif
2197 if (BusLogic_ProbeOptions.NoProbe)
2198 return -ENODEV;
2199 BusLogic_ProbeInfoList =
2200 kzalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo), GFP_KERNEL);
2201 if (BusLogic_ProbeInfoList == NULL) {
2202 BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL);
2203 return -ENOMEM;
2206 PrototypeHostAdapter =
2207 kzalloc(sizeof(struct BusLogic_HostAdapter), GFP_KERNEL);
2208 if (PrototypeHostAdapter == NULL) {
2209 kfree(BusLogic_ProbeInfoList);
2210 BusLogic_Error("BusLogic: Unable to allocate Prototype " "Host Adapter\n", NULL);
2211 return -ENOMEM;
2214 #ifdef MODULE
2215 if (BusLogic != NULL)
2216 BusLogic_Setup(BusLogic);
2217 #endif
2218 BusLogic_InitializeProbeInfoList(PrototypeHostAdapter);
2219 for (ProbeIndex = 0; ProbeIndex < BusLogic_ProbeInfoCount; ProbeIndex++) {
2220 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[ProbeIndex];
2221 struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter;
2222 struct Scsi_Host *Host;
2223 if (ProbeInfo->IO_Address == 0)
2224 continue;
2225 memset(HostAdapter, 0, sizeof(struct BusLogic_HostAdapter));
2226 HostAdapter->HostAdapterType = ProbeInfo->HostAdapterType;
2227 HostAdapter->HostAdapterBusType = ProbeInfo->HostAdapterBusType;
2228 HostAdapter->IO_Address = ProbeInfo->IO_Address;
2229 HostAdapter->PCI_Address = ProbeInfo->PCI_Address;
2230 HostAdapter->Bus = ProbeInfo->Bus;
2231 HostAdapter->Device = ProbeInfo->Device;
2232 HostAdapter->PCI_Device = ProbeInfo->PCI_Device;
2233 HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel;
2234 HostAdapter->AddressCount = BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType];
2237 Make sure region is free prior to probing.
2239 if (!request_region(HostAdapter->IO_Address, HostAdapter->AddressCount,
2240 "BusLogic"))
2241 continue;
2243 Probe the Host Adapter. If unsuccessful, abort further initialization.
2245 if (!BusLogic_ProbeHostAdapter(HostAdapter)) {
2246 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2247 continue;
2250 Hard Reset the Host Adapter. If unsuccessful, abort further
2251 initialization.
2253 if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) {
2254 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2255 continue;
2258 Check the Host Adapter. If unsuccessful, abort further initialization.
2260 if (!BusLogic_CheckHostAdapter(HostAdapter)) {
2261 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2262 continue;
2265 Initialize the Driver Options field if provided.
2267 if (DriverOptionsIndex < BusLogic_DriverOptionsCount)
2268 HostAdapter->DriverOptions = &BusLogic_DriverOptions[DriverOptionsIndex++];
2270 Announce the Driver Version and Date, Author's Name, Copyright Notice,
2271 and Electronic Mail Address.
2273 BusLogic_AnnounceDriver(HostAdapter);
2275 Register the SCSI Host structure.
2278 Host = scsi_host_alloc(&Bus_Logic_template, sizeof(struct BusLogic_HostAdapter));
2279 if (Host == NULL) {
2280 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2281 continue;
2283 HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata;
2284 memcpy(HostAdapter, PrototypeHostAdapter, sizeof(struct BusLogic_HostAdapter));
2285 HostAdapter->SCSI_Host = Host;
2286 HostAdapter->HostNumber = Host->host_no;
2288 Add Host Adapter to the end of the list of registered BusLogic
2289 Host Adapters.
2291 list_add_tail(&HostAdapter->host_list, &BusLogic_host_list);
2294 Read the Host Adapter Configuration, Configure the Host Adapter,
2295 Acquire the System Resources necessary to use the Host Adapter, then
2296 Create the Initial CCBs, Initialize the Host Adapter, and finally
2297 perform Target Device Inquiry.
2299 From this point onward, any failure will be assumed to be due to a
2300 problem with the Host Adapter, rather than due to having mistakenly
2301 identified this port as belonging to a BusLogic Host Adapter. The
2302 I/O Address range will not be released, thereby preventing it from
2303 being incorrectly identified as any other type of Host Adapter.
2305 if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
2306 BusLogic_ReportHostAdapterConfiguration(HostAdapter) &&
2307 BusLogic_AcquireResources(HostAdapter) &&
2308 BusLogic_CreateInitialCCBs(HostAdapter) &&
2309 BusLogic_InitializeHostAdapter(HostAdapter) &&
2310 BusLogic_TargetDeviceInquiry(HostAdapter)) {
2312 Initialization has been completed successfully. Release and
2313 re-register usage of the I/O Address range so that the Model
2314 Name of the Host Adapter will appear, and initialize the SCSI
2315 Host structure.
2317 release_region(HostAdapter->IO_Address,
2318 HostAdapter->AddressCount);
2319 if (!request_region(HostAdapter->IO_Address,
2320 HostAdapter->AddressCount,
2321 HostAdapter->FullModelName)) {
2322 printk(KERN_WARNING
2323 "BusLogic: Release and re-register of "
2324 "port 0x%04lx failed \n",
2325 (unsigned long)HostAdapter->IO_Address);
2326 BusLogic_DestroyCCBs(HostAdapter);
2327 BusLogic_ReleaseResources(HostAdapter);
2328 list_del(&HostAdapter->host_list);
2329 scsi_host_put(Host);
2330 ret = -ENOMEM;
2331 } else {
2332 BusLogic_InitializeHostStructure(HostAdapter,
2333 Host);
2334 if (scsi_add_host(Host, HostAdapter->PCI_Device
2335 ? &HostAdapter->PCI_Device->dev
2336 : NULL)) {
2337 printk(KERN_WARNING
2338 "BusLogic: scsi_add_host()"
2339 "failed!\n");
2340 BusLogic_DestroyCCBs(HostAdapter);
2341 BusLogic_ReleaseResources(HostAdapter);
2342 list_del(&HostAdapter->host_list);
2343 scsi_host_put(Host);
2344 ret = -ENODEV;
2345 } else {
2346 scsi_scan_host(Host);
2347 BusLogicHostAdapterCount++;
2350 } else {
2352 An error occurred during Host Adapter Configuration Querying, Host
2353 Adapter Configuration, Resource Acquisition, CCB Creation, Host
2354 Adapter Initialization, or Target Device Inquiry, so remove Host
2355 Adapter from the list of registered BusLogic Host Adapters, destroy
2356 the CCBs, Release the System Resources, and Unregister the SCSI
2357 Host.
2359 BusLogic_DestroyCCBs(HostAdapter);
2360 BusLogic_ReleaseResources(HostAdapter);
2361 list_del(&HostAdapter->host_list);
2362 scsi_host_put(Host);
2363 ret = -ENODEV;
2366 kfree(PrototypeHostAdapter);
2367 kfree(BusLogic_ProbeInfoList);
2368 BusLogic_ProbeInfoList = NULL;
2369 return ret;
2374 BusLogic_ReleaseHostAdapter releases all resources previously acquired to
2375 support a specific Host Adapter, including the I/O Address range, and
2376 unregisters the BusLogic Host Adapter.
2379 static int __exit BusLogic_ReleaseHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
2381 struct Scsi_Host *Host = HostAdapter->SCSI_Host;
2383 scsi_remove_host(Host);
2386 FlashPoint Host Adapters must first be released by the FlashPoint
2387 SCCB Manager.
2389 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
2390 FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle);
2392 Destroy the CCBs and release any system resources acquired to
2393 support Host Adapter.
2395 BusLogic_DestroyCCBs(HostAdapter);
2396 BusLogic_ReleaseResources(HostAdapter);
2398 Release usage of the I/O Address range.
2400 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2402 Remove Host Adapter from the list of registered BusLogic Host Adapters.
2404 list_del(&HostAdapter->host_list);
2406 scsi_host_put(Host);
2407 return 0;
2412 BusLogic_QueueCompletedCCB queues CCB for completion processing.
2415 static void BusLogic_QueueCompletedCCB(struct BusLogic_CCB *CCB)
2417 struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter;
2418 CCB->Status = BusLogic_CCB_Completed;
2419 CCB->Next = NULL;
2420 if (HostAdapter->FirstCompletedCCB == NULL) {
2421 HostAdapter->FirstCompletedCCB = CCB;
2422 HostAdapter->LastCompletedCCB = CCB;
2423 } else {
2424 HostAdapter->LastCompletedCCB->Next = CCB;
2425 HostAdapter->LastCompletedCCB = CCB;
2427 HostAdapter->ActiveCommands[CCB->TargetID]--;
2432 BusLogic_ComputeResultCode computes a SCSI Subsystem Result Code from
2433 the Host Adapter Status and Target Device Status.
2436 static int BusLogic_ComputeResultCode(struct BusLogic_HostAdapter *HostAdapter, enum BusLogic_HostAdapterStatus HostAdapterStatus, enum BusLogic_TargetDeviceStatus TargetDeviceStatus)
2438 int HostStatus;
2439 switch (HostAdapterStatus) {
2440 case BusLogic_CommandCompletedNormally:
2441 case BusLogic_LinkedCommandCompleted:
2442 case BusLogic_LinkedCommandCompletedWithFlag:
2443 HostStatus = DID_OK;
2444 break;
2445 case BusLogic_SCSISelectionTimeout:
2446 HostStatus = DID_TIME_OUT;
2447 break;
2448 case BusLogic_InvalidOutgoingMailboxActionCode:
2449 case BusLogic_InvalidCommandOperationCode:
2450 case BusLogic_InvalidCommandParameter:
2451 BusLogic_Warning("BusLogic Driver Protocol Error 0x%02X\n", HostAdapter, HostAdapterStatus);
2452 case BusLogic_DataUnderRun:
2453 case BusLogic_DataOverRun:
2454 case BusLogic_UnexpectedBusFree:
2455 case BusLogic_LinkedCCBhasInvalidLUN:
2456 case BusLogic_AutoRequestSenseFailed:
2457 case BusLogic_TaggedQueuingMessageRejected:
2458 case BusLogic_UnsupportedMessageReceived:
2459 case BusLogic_HostAdapterHardwareFailed:
2460 case BusLogic_TargetDeviceReconnectedImproperly:
2461 case BusLogic_AbortQueueGenerated:
2462 case BusLogic_HostAdapterSoftwareError:
2463 case BusLogic_HostAdapterHardwareTimeoutError:
2464 case BusLogic_SCSIParityErrorDetected:
2465 HostStatus = DID_ERROR;
2466 break;
2467 case BusLogic_InvalidBusPhaseRequested:
2468 case BusLogic_TargetFailedResponseToATN:
2469 case BusLogic_HostAdapterAssertedRST:
2470 case BusLogic_OtherDeviceAssertedRST:
2471 case BusLogic_HostAdapterAssertedBusDeviceReset:
2472 HostStatus = DID_RESET;
2473 break;
2474 default:
2475 BusLogic_Warning("Unknown Host Adapter Status 0x%02X\n", HostAdapter, HostAdapterStatus);
2476 HostStatus = DID_ERROR;
2477 break;
2479 return (HostStatus << 16) | TargetDeviceStatus;
2484 BusLogic_ScanIncomingMailboxes scans the Incoming Mailboxes saving any
2485 Incoming Mailbox entries for completion processing.
2488 static void BusLogic_ScanIncomingMailboxes(struct BusLogic_HostAdapter *HostAdapter)
2491 Scan through the Incoming Mailboxes in Strict Round Robin fashion, saving
2492 any completed CCBs for further processing. It is essential that for each
2493 CCB and SCSI Command issued, command completion processing is performed
2494 exactly once. Therefore, only Incoming Mailboxes with completion code
2495 Command Completed Without Error, Command Completed With Error, or Command
2496 Aborted At Host Request are saved for completion processing. When an
2497 Incoming Mailbox has a completion code of Aborted Command Not Found, the
2498 CCB had already completed or been aborted before the current Abort request
2499 was processed, and so completion processing has already occurred and no
2500 further action should be taken.
2502 struct BusLogic_IncomingMailbox *NextIncomingMailbox = HostAdapter->NextIncomingMailbox;
2503 enum BusLogic_CompletionCode CompletionCode;
2504 while ((CompletionCode = NextIncomingMailbox->CompletionCode) != BusLogic_IncomingMailboxFree) {
2506 We are only allowed to do this because we limit our architectures we
2507 run on to machines where bus_to_virt() actually works. There *needs*
2508 to be a dma_addr_to_virt() in the new PCI DMA mapping interface to
2509 replace bus_to_virt() or else this code is going to become very
2510 innefficient.
2512 struct BusLogic_CCB *CCB = (struct BusLogic_CCB *) Bus_to_Virtual(NextIncomingMailbox->CCB);
2513 if (CompletionCode != BusLogic_AbortedCommandNotFound) {
2514 if (CCB->Status == BusLogic_CCB_Active || CCB->Status == BusLogic_CCB_Reset) {
2516 Save the Completion Code for this CCB and queue the CCB
2517 for completion processing.
2519 CCB->CompletionCode = CompletionCode;
2520 BusLogic_QueueCompletedCCB(CCB);
2521 } else {
2523 If a CCB ever appears in an Incoming Mailbox and is not marked
2524 as status Active or Reset, then there is most likely a bug in
2525 the Host Adapter firmware.
2527 BusLogic_Warning("Illegal CCB #%ld status %d in " "Incoming Mailbox\n", HostAdapter, CCB->SerialNumber, CCB->Status);
2530 NextIncomingMailbox->CompletionCode = BusLogic_IncomingMailboxFree;
2531 if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
2532 NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
2534 HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
2539 BusLogic_ProcessCompletedCCBs iterates over the completed CCBs for Host
2540 Adapter setting the SCSI Command Result Codes, deallocating the CCBs, and
2541 calling the SCSI Subsystem Completion Routines. The Host Adapter's Lock
2542 should already have been acquired by the caller.
2545 static void BusLogic_ProcessCompletedCCBs(struct BusLogic_HostAdapter *HostAdapter)
2547 if (HostAdapter->ProcessCompletedCCBsActive)
2548 return;
2549 HostAdapter->ProcessCompletedCCBsActive = true;
2550 while (HostAdapter->FirstCompletedCCB != NULL) {
2551 struct BusLogic_CCB *CCB = HostAdapter->FirstCompletedCCB;
2552 struct scsi_cmnd *Command = CCB->Command;
2553 HostAdapter->FirstCompletedCCB = CCB->Next;
2554 if (HostAdapter->FirstCompletedCCB == NULL)
2555 HostAdapter->LastCompletedCCB = NULL;
2557 Process the Completed CCB.
2559 if (CCB->Opcode == BusLogic_BusDeviceReset) {
2560 int TargetID = CCB->TargetID;
2561 BusLogic_Warning("Bus Device Reset CCB #%ld to Target " "%d Completed\n", HostAdapter, CCB->SerialNumber, TargetID);
2562 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].BusDeviceResetsCompleted);
2563 HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
2564 HostAdapter->CommandsSinceReset[TargetID] = 0;
2565 HostAdapter->LastResetCompleted[TargetID] = jiffies;
2567 Place CCB back on the Host Adapter's free list.
2569 BusLogic_DeallocateCCB(CCB);
2570 #if 0 /* this needs to be redone different for new EH */
2572 Bus Device Reset CCBs have the Command field non-NULL only when a
2573 Bus Device Reset was requested for a Command that did not have a
2574 currently active CCB in the Host Adapter (i.e., a Synchronous
2575 Bus Device Reset), and hence would not have its Completion Routine
2576 called otherwise.
2578 while (Command != NULL) {
2579 struct scsi_cmnd *NextCommand = Command->reset_chain;
2580 Command->reset_chain = NULL;
2581 Command->result = DID_RESET << 16;
2582 Command->scsi_done(Command);
2583 Command = NextCommand;
2585 #endif
2587 Iterate over the CCBs for this Host Adapter performing completion
2588 processing for any CCBs marked as Reset for this Target.
2590 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2591 if (CCB->Status == BusLogic_CCB_Reset && CCB->TargetID == TargetID) {
2592 Command = CCB->Command;
2593 BusLogic_DeallocateCCB(CCB);
2594 HostAdapter->ActiveCommands[TargetID]--;
2595 Command->result = DID_RESET << 16;
2596 Command->scsi_done(Command);
2598 HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
2599 } else {
2601 Translate the Completion Code, Host Adapter Status, and Target
2602 Device Status into a SCSI Subsystem Result Code.
2604 switch (CCB->CompletionCode) {
2605 case BusLogic_IncomingMailboxFree:
2606 case BusLogic_AbortedCommandNotFound:
2607 case BusLogic_InvalidCCB:
2608 BusLogic_Warning("CCB #%ld to Target %d Impossible State\n", HostAdapter, CCB->SerialNumber, CCB->TargetID);
2609 break;
2610 case BusLogic_CommandCompletedWithoutError:
2611 HostAdapter->TargetStatistics[CCB->TargetID]
2612 .CommandsCompleted++;
2613 HostAdapter->TargetFlags[CCB->TargetID]
2614 .CommandSuccessfulFlag = true;
2615 Command->result = DID_OK << 16;
2616 break;
2617 case BusLogic_CommandAbortedAtHostRequest:
2618 BusLogic_Warning("CCB #%ld to Target %d Aborted\n", HostAdapter, CCB->SerialNumber, CCB->TargetID);
2619 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[CCB->TargetID]
2620 .CommandAbortsCompleted);
2621 Command->result = DID_ABORT << 16;
2622 break;
2623 case BusLogic_CommandCompletedWithError:
2624 Command->result = BusLogic_ComputeResultCode(HostAdapter, CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
2625 if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout) {
2626 HostAdapter->TargetStatistics[CCB->TargetID]
2627 .CommandsCompleted++;
2628 if (BusLogic_GlobalOptions.TraceErrors) {
2629 int i;
2630 BusLogic_Notice("CCB #%ld Target %d: Result %X Host "
2631 "Adapter Status %02X " "Target Status %02X\n", HostAdapter, CCB->SerialNumber, CCB->TargetID, Command->result, CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
2632 BusLogic_Notice("CDB ", HostAdapter);
2633 for (i = 0; i < CCB->CDB_Length; i++)
2634 BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]);
2635 BusLogic_Notice("\n", HostAdapter);
2636 BusLogic_Notice("Sense ", HostAdapter);
2637 for (i = 0; i < CCB->SenseDataLength; i++)
2638 BusLogic_Notice(" %02X", HostAdapter, Command->sense_buffer[i]);
2639 BusLogic_Notice("\n", HostAdapter);
2642 break;
2645 When an INQUIRY command completes normally, save the
2646 CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit
2647 Wide Data Transfers Supported) bits.
2649 if (CCB->CDB[0] == INQUIRY && CCB->CDB[1] == 0 && CCB->HostAdapterStatus == BusLogic_CommandCompletedNormally) {
2650 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[CCB->TargetID];
2651 struct SCSI_Inquiry *InquiryResult = (struct SCSI_Inquiry *) Command->request_buffer;
2652 TargetFlags->TargetExists = true;
2653 TargetFlags->TaggedQueuingSupported = InquiryResult->CmdQue;
2654 TargetFlags->WideTransfersSupported = InquiryResult->WBus16;
2657 Place CCB back on the Host Adapter's free list.
2659 BusLogic_DeallocateCCB(CCB);
2661 Call the SCSI Command Completion Routine.
2663 Command->scsi_done(Command);
2666 HostAdapter->ProcessCompletedCCBsActive = false;
2671 BusLogic_InterruptHandler handles hardware interrupts from BusLogic Host
2672 Adapters.
2675 static irqreturn_t BusLogic_InterruptHandler(int IRQ_Channel, void *DeviceIdentifier)
2677 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) DeviceIdentifier;
2678 unsigned long ProcessorFlags;
2680 Acquire exclusive access to Host Adapter.
2682 spin_lock_irqsave(HostAdapter->SCSI_Host->host_lock, ProcessorFlags);
2684 Handle Interrupts appropriately for each Host Adapter type.
2686 if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
2687 union BusLogic_InterruptRegister InterruptRegister;
2689 Read the Host Adapter Interrupt Register.
2691 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
2692 if (InterruptRegister.ir.InterruptValid) {
2694 Acknowledge the interrupt and reset the Host Adapter
2695 Interrupt Register.
2697 BusLogic_InterruptReset(HostAdapter);
2699 Process valid External SCSI Bus Reset and Incoming Mailbox
2700 Loaded Interrupts. Command Complete Interrupts are noted,
2701 and Outgoing Mailbox Available Interrupts are ignored, as
2702 they are never enabled.
2704 if (InterruptRegister.ir.ExternalBusReset)
2705 HostAdapter->HostAdapterExternalReset = true;
2706 else if (InterruptRegister.ir.IncomingMailboxLoaded)
2707 BusLogic_ScanIncomingMailboxes(HostAdapter);
2708 else if (InterruptRegister.ir.CommandComplete)
2709 HostAdapter->HostAdapterCommandCompleted = true;
2711 } else {
2713 Check if there is a pending interrupt for this Host Adapter.
2715 if (FlashPoint_InterruptPending(HostAdapter->CardHandle))
2716 switch (FlashPoint_HandleInterrupt(HostAdapter->CardHandle)) {
2717 case FlashPoint_NormalInterrupt:
2718 break;
2719 case FlashPoint_ExternalBusReset:
2720 HostAdapter->HostAdapterExternalReset = true;
2721 break;
2722 case FlashPoint_InternalError:
2723 BusLogic_Warning("Internal FlashPoint Error detected" " - Resetting Host Adapter\n", HostAdapter);
2724 HostAdapter->HostAdapterInternalError = true;
2725 break;
2729 Process any completed CCBs.
2731 if (HostAdapter->FirstCompletedCCB != NULL)
2732 BusLogic_ProcessCompletedCCBs(HostAdapter);
2734 Reset the Host Adapter if requested.
2736 if (HostAdapter->HostAdapterExternalReset) {
2737 BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n", HostAdapter, HostAdapter->FullModelName);
2738 BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets);
2739 BusLogic_ResetHostAdapter(HostAdapter, false);
2740 HostAdapter->HostAdapterExternalReset = false;
2741 } else if (HostAdapter->HostAdapterInternalError) {
2742 BusLogic_Warning("Resetting %s due to Host Adapter Internal Error\n", HostAdapter, HostAdapter->FullModelName);
2743 BusLogic_IncrementErrorCounter(&HostAdapter->HostAdapterInternalErrors);
2744 BusLogic_ResetHostAdapter(HostAdapter, true);
2745 HostAdapter->HostAdapterInternalError = false;
2748 Release exclusive access to Host Adapter.
2750 spin_unlock_irqrestore(HostAdapter->SCSI_Host->host_lock, ProcessorFlags);
2751 return IRQ_HANDLED;
2756 BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
2757 Mailbox for execution by Host Adapter. The Host Adapter's Lock should
2758 already have been acquired by the caller.
2761 static bool BusLogic_WriteOutgoingMailbox(struct BusLogic_HostAdapter
2762 *HostAdapter, enum BusLogic_ActionCode ActionCode, struct BusLogic_CCB *CCB)
2764 struct BusLogic_OutgoingMailbox *NextOutgoingMailbox;
2765 NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
2766 if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree) {
2767 CCB->Status = BusLogic_CCB_Active;
2769 The CCB field must be written before the Action Code field since
2770 the Host Adapter is operating asynchronously and the locking code
2771 does not protect against simultaneous access by the Host Adapter.
2773 NextOutgoingMailbox->CCB = CCB->DMA_Handle;
2774 NextOutgoingMailbox->ActionCode = ActionCode;
2775 BusLogic_StartMailboxCommand(HostAdapter);
2776 if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
2777 NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
2778 HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
2779 if (ActionCode == BusLogic_MailboxStartCommand) {
2780 HostAdapter->ActiveCommands[CCB->TargetID]++;
2781 if (CCB->Opcode != BusLogic_BusDeviceReset)
2782 HostAdapter->TargetStatistics[CCB->TargetID].CommandsAttempted++;
2784 return true;
2786 return false;
2789 /* Error Handling (EH) support */
2791 static int BusLogic_host_reset(struct scsi_cmnd * SCpnt)
2793 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) SCpnt->device->host->hostdata;
2795 unsigned int id = SCpnt->device->id;
2796 struct BusLogic_TargetStatistics *stats = &HostAdapter->TargetStatistics[id];
2797 int rc;
2799 spin_lock_irq(SCpnt->device->host->host_lock);
2801 BusLogic_IncrementErrorCounter(&stats->HostAdapterResetsRequested);
2803 rc = BusLogic_ResetHostAdapter(HostAdapter, false);
2804 spin_unlock_irq(SCpnt->device->host->host_lock);
2805 return rc;
2809 BusLogic_QueueCommand creates a CCB for Command and places it into an
2810 Outgoing Mailbox for execution by the associated Host Adapter.
2813 static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRoutine) (struct scsi_cmnd *))
2815 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata;
2816 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[Command->device->id];
2817 struct BusLogic_TargetStatistics *TargetStatistics = HostAdapter->TargetStatistics;
2818 unsigned char *CDB = Command->cmnd;
2819 int CDB_Length = Command->cmd_len;
2820 int TargetID = Command->device->id;
2821 int LogicalUnit = Command->device->lun;
2822 void *BufferPointer = Command->request_buffer;
2823 int BufferLength = Command->request_bufflen;
2824 int SegmentCount = Command->use_sg;
2825 struct BusLogic_CCB *CCB;
2827 SCSI REQUEST_SENSE commands will be executed automatically by the Host
2828 Adapter for any errors, so they should not be executed explicitly unless
2829 the Sense Data is zero indicating that no error occurred.
2831 if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0) {
2832 Command->result = DID_OK << 16;
2833 CompletionRoutine(Command);
2834 return 0;
2837 Allocate a CCB from the Host Adapter's free list. In the unlikely event
2838 that there are none available and memory allocation fails, wait 1 second
2839 and try again. If that fails, the Host Adapter is probably hung so signal
2840 an error as a Host Adapter Hard Reset should be initiated soon.
2842 CCB = BusLogic_AllocateCCB(HostAdapter);
2843 if (CCB == NULL) {
2844 spin_unlock_irq(HostAdapter->SCSI_Host->host_lock);
2845 BusLogic_Delay(1);
2846 spin_lock_irq(HostAdapter->SCSI_Host->host_lock);
2847 CCB = BusLogic_AllocateCCB(HostAdapter);
2848 if (CCB == NULL) {
2849 Command->result = DID_ERROR << 16;
2850 CompletionRoutine(Command);
2851 return 0;
2855 Initialize the fields in the BusLogic Command Control Block (CCB).
2857 if (SegmentCount == 0 && BufferLength != 0) {
2858 CCB->Opcode = BusLogic_InitiatorCCB;
2859 CCB->DataLength = BufferLength;
2860 CCB->DataPointer = pci_map_single(HostAdapter->PCI_Device,
2861 BufferPointer, BufferLength,
2862 Command->sc_data_direction);
2863 } else if (SegmentCount != 0) {
2864 struct scatterlist *ScatterList = (struct scatterlist *) BufferPointer;
2865 int Segment, Count;
2867 Count = pci_map_sg(HostAdapter->PCI_Device, ScatterList, SegmentCount,
2868 Command->sc_data_direction);
2869 CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
2870 CCB->DataLength = Count * sizeof(struct BusLogic_ScatterGatherSegment);
2871 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
2872 CCB->DataPointer = (unsigned int) CCB->DMA_Handle + ((unsigned long) &CCB->ScatterGatherList - (unsigned long) CCB);
2873 else
2874 CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList);
2875 for (Segment = 0; Segment < Count; Segment++) {
2876 CCB->ScatterGatherList[Segment].SegmentByteCount = sg_dma_len(ScatterList + Segment);
2877 CCB->ScatterGatherList[Segment].SegmentDataPointer = sg_dma_address(ScatterList + Segment);
2879 } else {
2880 CCB->Opcode = BusLogic_InitiatorCCB;
2881 CCB->DataLength = BufferLength;
2882 CCB->DataPointer = 0;
2884 switch (CDB[0]) {
2885 case READ_6:
2886 case READ_10:
2887 CCB->DataDirection = BusLogic_DataInLengthChecked;
2888 TargetStatistics[TargetID].ReadCommands++;
2889 BusLogic_IncrementByteCounter(&TargetStatistics[TargetID].TotalBytesRead, BufferLength);
2890 BusLogic_IncrementSizeBucket(TargetStatistics[TargetID].ReadCommandSizeBuckets, BufferLength);
2891 break;
2892 case WRITE_6:
2893 case WRITE_10:
2894 CCB->DataDirection = BusLogic_DataOutLengthChecked;
2895 TargetStatistics[TargetID].WriteCommands++;
2896 BusLogic_IncrementByteCounter(&TargetStatistics[TargetID].TotalBytesWritten, BufferLength);
2897 BusLogic_IncrementSizeBucket(TargetStatistics[TargetID].WriteCommandSizeBuckets, BufferLength);
2898 break;
2899 default:
2900 CCB->DataDirection = BusLogic_UncheckedDataTransfer;
2901 break;
2903 CCB->CDB_Length = CDB_Length;
2904 CCB->HostAdapterStatus = 0;
2905 CCB->TargetDeviceStatus = 0;
2906 CCB->TargetID = TargetID;
2907 CCB->LogicalUnit = LogicalUnit;
2908 CCB->TagEnable = false;
2909 CCB->LegacyTagEnable = false;
2911 BusLogic recommends that after a Reset the first couple of commands that
2912 are sent to a Target Device be sent in a non Tagged Queue fashion so that
2913 the Host Adapter and Target Device can establish Synchronous and Wide
2914 Transfer before Queue Tag messages can interfere with the Synchronous and
2915 Wide Negotiation messages. By waiting to enable Tagged Queuing until after
2916 the first BusLogic_MaxTaggedQueueDepth commands have been queued, it is
2917 assured that after a Reset any pending commands are requeued before Tagged
2918 Queuing is enabled and that the Tagged Queuing message will not occur while
2919 the partition table is being printed. In addition, some devices do not
2920 properly handle the transition from non-tagged to tagged commands, so it is
2921 necessary to wait until there are no pending commands for a target device
2922 before queuing tagged commands.
2924 if (HostAdapter->CommandsSinceReset[TargetID]++ >=
2925 BusLogic_MaxTaggedQueueDepth && !TargetFlags->TaggedQueuingActive && HostAdapter->ActiveCommands[TargetID] == 0 && TargetFlags->TaggedQueuingSupported && (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) {
2926 TargetFlags->TaggedQueuingActive = true;
2927 BusLogic_Notice("Tagged Queuing now active for Target %d\n", HostAdapter, TargetID);
2929 if (TargetFlags->TaggedQueuingActive) {
2930 enum BusLogic_QueueTag QueueTag = BusLogic_SimpleQueueTag;
2932 When using Tagged Queuing with Simple Queue Tags, it appears that disk
2933 drive controllers do not guarantee that a queued command will not
2934 remain in a disconnected state indefinitely if commands that read or
2935 write nearer the head position continue to arrive without interruption.
2936 Therefore, for each Target Device this driver keeps track of the last
2937 time either the queue was empty or an Ordered Queue Tag was issued. If
2938 more than 4 seconds (one fifth of the 20 second disk timeout) have
2939 elapsed since this last sequence point, this command will be issued
2940 with an Ordered Queue Tag rather than a Simple Queue Tag, which forces
2941 the Target Device to complete all previously queued commands before
2942 this command may be executed.
2944 if (HostAdapter->ActiveCommands[TargetID] == 0)
2945 HostAdapter->LastSequencePoint[TargetID] = jiffies;
2946 else if (time_after(jiffies, HostAdapter->LastSequencePoint[TargetID] + 4 * HZ)) {
2947 HostAdapter->LastSequencePoint[TargetID] = jiffies;
2948 QueueTag = BusLogic_OrderedQueueTag;
2950 if (HostAdapter->ExtendedLUNSupport) {
2951 CCB->TagEnable = true;
2952 CCB->QueueTag = QueueTag;
2953 } else {
2954 CCB->LegacyTagEnable = true;
2955 CCB->LegacyQueueTag = QueueTag;
2958 memcpy(CCB->CDB, CDB, CDB_Length);
2959 CCB->SenseDataLength = sizeof(Command->sense_buffer);
2960 CCB->SenseDataPointer = pci_map_single(HostAdapter->PCI_Device, Command->sense_buffer, CCB->SenseDataLength, PCI_DMA_FROMDEVICE);
2961 CCB->Command = Command;
2962 Command->scsi_done = CompletionRoutine;
2963 if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
2965 Place the CCB in an Outgoing Mailbox. The higher levels of the SCSI
2966 Subsystem should not attempt to queue more commands than can be placed
2967 in Outgoing Mailboxes, so there should always be one free. In the
2968 unlikely event that there are none available, wait 1 second and try
2969 again. If that fails, the Host Adapter is probably hung so signal an
2970 error as a Host Adapter Hard Reset should be initiated soon.
2972 if (!BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxStartCommand, CCB)) {
2973 spin_unlock_irq(HostAdapter->SCSI_Host->host_lock);
2974 BusLogic_Warning("Unable to write Outgoing Mailbox - " "Pausing for 1 second\n", HostAdapter);
2975 BusLogic_Delay(1);
2976 spin_lock_irq(HostAdapter->SCSI_Host->host_lock);
2977 if (!BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxStartCommand, CCB)) {
2978 BusLogic_Warning("Still unable to write Outgoing Mailbox - " "Host Adapter Dead?\n", HostAdapter);
2979 BusLogic_DeallocateCCB(CCB);
2980 Command->result = DID_ERROR << 16;
2981 Command->scsi_done(Command);
2984 } else {
2986 Call the FlashPoint SCCB Manager to start execution of the CCB.
2988 CCB->Status = BusLogic_CCB_Active;
2989 HostAdapter->ActiveCommands[TargetID]++;
2990 TargetStatistics[TargetID].CommandsAttempted++;
2991 FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
2993 The Command may have already completed and BusLogic_QueueCompletedCCB
2994 been called, or it may still be pending.
2996 if (CCB->Status == BusLogic_CCB_Completed)
2997 BusLogic_ProcessCompletedCCBs(HostAdapter);
2999 return 0;
3003 #if 0
3005 BusLogic_AbortCommand aborts Command if possible.
3008 static int BusLogic_AbortCommand(struct scsi_cmnd *Command)
3010 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata;
3012 int TargetID = Command->device->id;
3013 struct BusLogic_CCB *CCB;
3014 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsRequested);
3016 Attempt to find an Active CCB for this Command. If no Active CCB for this
3017 Command is found, then no Abort is necessary.
3019 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3020 if (CCB->Command == Command)
3021 break;
3022 if (CCB == NULL) {
3023 BusLogic_Warning("Unable to Abort Command to Target %d - " "No CCB Found\n", HostAdapter, TargetID);
3024 return SUCCESS;
3025 } else if (CCB->Status == BusLogic_CCB_Completed) {
3026 BusLogic_Warning("Unable to Abort Command to Target %d - " "CCB Completed\n", HostAdapter, TargetID);
3027 return SUCCESS;
3028 } else if (CCB->Status == BusLogic_CCB_Reset) {
3029 BusLogic_Warning("Unable to Abort Command to Target %d - " "CCB Reset\n", HostAdapter, TargetID);
3030 return SUCCESS;
3032 if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
3034 Attempt to Abort this CCB. MultiMaster Firmware versions prior to 5.xx
3035 do not generate Abort Tag messages, but only generate the non-tagged
3036 Abort message. Since non-tagged commands are not sent by the Host
3037 Adapter until the queue of outstanding tagged commands has completed,
3038 and the Abort message is treated as a non-tagged command, it is
3039 effectively impossible to abort commands when Tagged Queuing is active.
3040 Firmware version 5.xx does generate Abort Tag messages, so it is
3041 possible to abort commands when Tagged Queuing is active.
3043 if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive && HostAdapter->FirmwareVersion[0] < '5') {
3044 BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - " "Abort Tag Not Supported\n", HostAdapter, CCB->SerialNumber, TargetID);
3045 return FAILURE;
3046 } else if (BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxAbortCommand, CCB)) {
3047 BusLogic_Warning("Aborting CCB #%ld to Target %d\n", HostAdapter, CCB->SerialNumber, TargetID);
3048 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
3049 return SUCCESS;
3050 } else {
3051 BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - " "No Outgoing Mailboxes\n", HostAdapter, CCB->SerialNumber, TargetID);
3052 return FAILURE;
3054 } else {
3056 Call the FlashPoint SCCB Manager to abort execution of the CCB.
3058 BusLogic_Warning("Aborting CCB #%ld to Target %d\n", HostAdapter, CCB->SerialNumber, TargetID);
3059 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
3060 FlashPoint_AbortCCB(HostAdapter->CardHandle, CCB);
3062 The Abort may have already been completed and
3063 BusLogic_QueueCompletedCCB been called, or it
3064 may still be pending.
3066 if (CCB->Status == BusLogic_CCB_Completed) {
3067 BusLogic_ProcessCompletedCCBs(HostAdapter);
3069 return SUCCESS;
3071 return SUCCESS;
3074 #endif
3076 BusLogic_ResetHostAdapter resets Host Adapter if possible, marking all
3077 currently executing SCSI Commands as having been Reset.
3080 static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter, bool HardReset)
3082 struct BusLogic_CCB *CCB;
3083 int TargetID;
3086 * Attempt to Reset and Reinitialize the Host Adapter.
3089 if (!(BusLogic_HardwareResetHostAdapter(HostAdapter, HardReset) && BusLogic_InitializeHostAdapter(HostAdapter))) {
3090 BusLogic_Error("Resetting %s Failed\n", HostAdapter, HostAdapter->FullModelName);
3091 return FAILURE;
3095 * Deallocate all currently executing CCBs.
3098 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3099 if (CCB->Status == BusLogic_CCB_Active)
3100 BusLogic_DeallocateCCB(CCB);
3102 * Wait a few seconds between the Host Adapter Hard Reset which
3103 * initiates a SCSI Bus Reset and issuing any SCSI Commands. Some
3104 * SCSI devices get confused if they receive SCSI Commands too soon
3105 * after a SCSI Bus Reset.
3108 if (HardReset) {
3109 spin_unlock_irq(HostAdapter->SCSI_Host->host_lock);
3110 BusLogic_Delay(HostAdapter->BusSettleTime);
3111 spin_lock_irq(HostAdapter->SCSI_Host->host_lock);
3114 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3115 HostAdapter->LastResetAttempted[TargetID] = jiffies;
3116 HostAdapter->LastResetCompleted[TargetID] = jiffies;
3118 return SUCCESS;
3122 BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk
3123 Parameters for Disk. The default disk geometry is 64 heads, 32 sectors, and
3124 the appropriate number of cylinders so as not to exceed drive capacity. In
3125 order for disks equal to or larger than 1 GB to be addressable by the BIOS
3126 without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
3127 may be enabled in AutoSCSI on FlashPoint Host Adapters and on "W" and "C"
3128 series MultiMaster Host Adapters, or by a dip switch setting on "S" and "A"
3129 series MultiMaster Host Adapters. With Extended Translation enabled, drives
3130 between 1 GB inclusive and 2 GB exclusive are given a disk geometry of 128
3131 heads and 32 sectors, and drives above 2 GB inclusive are given a disk
3132 geometry of 255 heads and 63 sectors. However, if the BIOS detects that the
3133 Extended Translation setting does not match the geometry in the partition
3134 table, then the translation inferred from the partition table will be used by
3135 the BIOS, and a warning may be displayed.
3138 static int BusLogic_BIOSDiskParameters(struct scsi_device *sdev, struct block_device *Device, sector_t capacity, int *Parameters)
3140 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) sdev->host->hostdata;
3141 struct BIOS_DiskParameters *DiskParameters = (struct BIOS_DiskParameters *) Parameters;
3142 unsigned char *buf;
3143 if (HostAdapter->ExtendedTranslationEnabled && capacity >= 2 * 1024 * 1024 /* 1 GB in 512 byte sectors */ ) {
3144 if (capacity >= 4 * 1024 * 1024 /* 2 GB in 512 byte sectors */ ) {
3145 DiskParameters->Heads = 255;
3146 DiskParameters->Sectors = 63;
3147 } else {
3148 DiskParameters->Heads = 128;
3149 DiskParameters->Sectors = 32;
3151 } else {
3152 DiskParameters->Heads = 64;
3153 DiskParameters->Sectors = 32;
3155 DiskParameters->Cylinders = (unsigned long) capacity / (DiskParameters->Heads * DiskParameters->Sectors);
3156 buf = scsi_bios_ptable(Device);
3157 if (buf == NULL)
3158 return 0;
3160 If the boot sector partition table flag is valid, search for a partition
3161 table entry whose end_head matches one of the standard BusLogic geometry
3162 translations (64/32, 128/32, or 255/63).
3164 if (*(unsigned short *) (buf + 64) == 0xAA55) {
3165 struct partition *FirstPartitionEntry = (struct partition *) buf;
3166 struct partition *PartitionEntry = FirstPartitionEntry;
3167 int SavedCylinders = DiskParameters->Cylinders, PartitionNumber;
3168 unsigned char PartitionEntryEndHead = 0, PartitionEntryEndSector = 0;
3169 for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++) {
3170 PartitionEntryEndHead = PartitionEntry->end_head;
3171 PartitionEntryEndSector = PartitionEntry->end_sector & 0x3F;
3172 if (PartitionEntryEndHead == 64 - 1) {
3173 DiskParameters->Heads = 64;
3174 DiskParameters->Sectors = 32;
3175 break;
3176 } else if (PartitionEntryEndHead == 128 - 1) {
3177 DiskParameters->Heads = 128;
3178 DiskParameters->Sectors = 32;
3179 break;
3180 } else if (PartitionEntryEndHead == 255 - 1) {
3181 DiskParameters->Heads = 255;
3182 DiskParameters->Sectors = 63;
3183 break;
3185 PartitionEntry++;
3187 if (PartitionNumber == 4) {
3188 PartitionEntryEndHead = FirstPartitionEntry->end_head;
3189 PartitionEntryEndSector = FirstPartitionEntry->end_sector & 0x3F;
3191 DiskParameters->Cylinders = (unsigned long) capacity / (DiskParameters->Heads * DiskParameters->Sectors);
3192 if (PartitionNumber < 4 && PartitionEntryEndSector == DiskParameters->Sectors) {
3193 if (DiskParameters->Cylinders != SavedCylinders)
3194 BusLogic_Warning("Adopting Geometry %d/%d from Partition Table\n", HostAdapter, DiskParameters->Heads, DiskParameters->Sectors);
3195 } else if (PartitionEntryEndHead > 0 || PartitionEntryEndSector > 0) {
3196 BusLogic_Warning("Warning: Partition Table appears to " "have Geometry %d/%d which is\n", HostAdapter, PartitionEntryEndHead + 1, PartitionEntryEndSector);
3197 BusLogic_Warning("not compatible with current BusLogic " "Host Adapter Geometry %d/%d\n", HostAdapter, DiskParameters->Heads, DiskParameters->Sectors);
3200 kfree(buf);
3201 return 0;
3206 BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>.
3209 static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *shost, char *ProcBuffer, char **StartPointer, off_t Offset, int BytesAvailable, int WriteFlag)
3211 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) shost->hostdata;
3212 struct BusLogic_TargetStatistics *TargetStatistics;
3213 int TargetID, Length;
3214 char *Buffer;
3216 TargetStatistics = HostAdapter->TargetStatistics;
3217 if (WriteFlag) {
3218 HostAdapter->ExternalHostAdapterResets = 0;
3219 HostAdapter->HostAdapterInternalErrors = 0;
3220 memset(TargetStatistics, 0, BusLogic_MaxTargetDevices * sizeof(struct BusLogic_TargetStatistics));
3221 return 0;
3223 Buffer = HostAdapter->MessageBuffer;
3224 Length = HostAdapter->MessageBufferLength;
3225 Length += sprintf(&Buffer[Length], "\n\
3226 Current Driver Queue Depth: %d\n\
3227 Currently Allocated CCBs: %d\n", HostAdapter->DriverQueueDepth, HostAdapter->AllocatedCCBs);
3228 Length += sprintf(&Buffer[Length], "\n\n\
3229 DATA TRANSFER STATISTICS\n\
3231 Target Tagged Queuing Queue Depth Active Attempted Completed\n\
3232 ====== ============== =========== ====== ========= =========\n");
3233 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3234 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3235 if (!TargetFlags->TargetExists)
3236 continue;
3237 Length += sprintf(&Buffer[Length], " %2d %s", TargetID, (TargetFlags->TaggedQueuingSupported ? (TargetFlags->TaggedQueuingActive ? " Active" : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)
3238 ? " Permitted" : " Disabled"))
3239 : "Not Supported"));
3240 Length += sprintf(&Buffer[Length],
3241 " %3d %3u %9u %9u\n", HostAdapter->QueueDepth[TargetID], HostAdapter->ActiveCommands[TargetID], TargetStatistics[TargetID].CommandsAttempted, TargetStatistics[TargetID].CommandsCompleted);
3243 Length += sprintf(&Buffer[Length], "\n\
3244 Target Read Commands Write Commands Total Bytes Read Total Bytes Written\n\
3245 ====== ============= ============== =================== ===================\n");
3246 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3247 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3248 if (!TargetFlags->TargetExists)
3249 continue;
3250 Length += sprintf(&Buffer[Length], " %2d %9u %9u", TargetID, TargetStatistics[TargetID].ReadCommands, TargetStatistics[TargetID].WriteCommands);
3251 if (TargetStatistics[TargetID].TotalBytesRead.Billions > 0)
3252 Length += sprintf(&Buffer[Length], " %9u%09u", TargetStatistics[TargetID].TotalBytesRead.Billions, TargetStatistics[TargetID].TotalBytesRead.Units);
3253 else
3254 Length += sprintf(&Buffer[Length], " %9u", TargetStatistics[TargetID].TotalBytesRead.Units);
3255 if (TargetStatistics[TargetID].TotalBytesWritten.Billions > 0)
3256 Length += sprintf(&Buffer[Length], " %9u%09u\n", TargetStatistics[TargetID].TotalBytesWritten.Billions, TargetStatistics[TargetID].TotalBytesWritten.Units);
3257 else
3258 Length += sprintf(&Buffer[Length], " %9u\n", TargetStatistics[TargetID].TotalBytesWritten.Units);
3260 Length += sprintf(&Buffer[Length], "\n\
3261 Target Command 0-1KB 1-2KB 2-4KB 4-8KB 8-16KB\n\
3262 ====== ======= ========= ========= ========= ========= =========\n");
3263 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3264 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3265 if (!TargetFlags->TargetExists)
3266 continue;
3267 Length +=
3268 sprintf(&Buffer[Length],
3269 " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
3270 TargetStatistics[TargetID].ReadCommandSizeBuckets[0],
3271 TargetStatistics[TargetID].ReadCommandSizeBuckets[1], TargetStatistics[TargetID].ReadCommandSizeBuckets[2], TargetStatistics[TargetID].ReadCommandSizeBuckets[3], TargetStatistics[TargetID].ReadCommandSizeBuckets[4]);
3272 Length +=
3273 sprintf(&Buffer[Length],
3274 " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
3275 TargetStatistics[TargetID].WriteCommandSizeBuckets[0],
3276 TargetStatistics[TargetID].WriteCommandSizeBuckets[1], TargetStatistics[TargetID].WriteCommandSizeBuckets[2], TargetStatistics[TargetID].WriteCommandSizeBuckets[3], TargetStatistics[TargetID].WriteCommandSizeBuckets[4]);
3278 Length += sprintf(&Buffer[Length], "\n\
3279 Target Command 16-32KB 32-64KB 64-128KB 128-256KB 256KB+\n\
3280 ====== ======= ========= ========= ========= ========= =========\n");
3281 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3282 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3283 if (!TargetFlags->TargetExists)
3284 continue;
3285 Length +=
3286 sprintf(&Buffer[Length],
3287 " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
3288 TargetStatistics[TargetID].ReadCommandSizeBuckets[5],
3289 TargetStatistics[TargetID].ReadCommandSizeBuckets[6], TargetStatistics[TargetID].ReadCommandSizeBuckets[7], TargetStatistics[TargetID].ReadCommandSizeBuckets[8], TargetStatistics[TargetID].ReadCommandSizeBuckets[9]);
3290 Length +=
3291 sprintf(&Buffer[Length],
3292 " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
3293 TargetStatistics[TargetID].WriteCommandSizeBuckets[5],
3294 TargetStatistics[TargetID].WriteCommandSizeBuckets[6], TargetStatistics[TargetID].WriteCommandSizeBuckets[7], TargetStatistics[TargetID].WriteCommandSizeBuckets[8], TargetStatistics[TargetID].WriteCommandSizeBuckets[9]);
3296 Length += sprintf(&Buffer[Length], "\n\n\
3297 ERROR RECOVERY STATISTICS\n\
3299 Command Aborts Bus Device Resets Host Adapter Resets\n\
3300 Target Requested Completed Requested Completed Requested Completed\n\
3301 ID \\\\\\\\ Attempted //// \\\\\\\\ Attempted //// \\\\\\\\ Attempted ////\n\
3302 ====== ===== ===== ===== ===== ===== ===== ===== ===== =====\n");
3303 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3304 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3305 if (!TargetFlags->TargetExists)
3306 continue;
3307 Length += sprintf(&Buffer[Length], "\
3308 %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);
3310 Length += sprintf(&Buffer[Length], "\nExternal Host Adapter Resets: %d\n", HostAdapter->ExternalHostAdapterResets);
3311 Length += sprintf(&Buffer[Length], "Host Adapter Internal Errors: %d\n", HostAdapter->HostAdapterInternalErrors);
3312 if (Length >= BusLogic_MessageBufferSize)
3313 BusLogic_Error("Message Buffer length %d exceeds size %d\n", HostAdapter, Length, BusLogic_MessageBufferSize);
3314 if ((Length -= Offset) <= 0)
3315 return 0;
3316 if (Length >= BytesAvailable)
3317 Length = BytesAvailable;
3318 memcpy(ProcBuffer, HostAdapter->MessageBuffer + Offset, Length);
3319 *StartPointer = ProcBuffer;
3320 return Length;
3325 BusLogic_Message prints Driver Messages.
3328 static void BusLogic_Message(enum BusLogic_MessageLevel MessageLevel, char *Format, struct BusLogic_HostAdapter *HostAdapter, ...)
3330 static char Buffer[BusLogic_LineBufferSize];
3331 static bool BeginningOfLine = true;
3332 va_list Arguments;
3333 int Length = 0;
3334 va_start(Arguments, HostAdapter);
3335 Length = vsprintf(Buffer, Format, Arguments);
3336 va_end(Arguments);
3337 if (MessageLevel == BusLogic_AnnounceLevel) {
3338 static int AnnouncementLines = 0;
3339 strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength], Buffer);
3340 HostAdapter->MessageBufferLength += Length;
3341 if (++AnnouncementLines <= 2)
3342 printk("%sscsi: %s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
3343 } else if (MessageLevel == BusLogic_InfoLevel) {
3344 strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength], Buffer);
3345 HostAdapter->MessageBufferLength += Length;
3346 if (BeginningOfLine) {
3347 if (Buffer[0] != '\n' || Length > 1)
3348 printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel], HostAdapter->HostNumber, Buffer);
3349 } else
3350 printk("%s", Buffer);
3351 } else {
3352 if (BeginningOfLine) {
3353 if (HostAdapter != NULL && HostAdapter->HostAdapterInitialized)
3354 printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel], HostAdapter->HostNumber, Buffer);
3355 else
3356 printk("%s%s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
3357 } else
3358 printk("%s", Buffer);
3360 BeginningOfLine = (Buffer[Length - 1] == '\n');
3365 BusLogic_ParseKeyword parses an individual option keyword. It returns true
3366 and updates the pointer if the keyword is recognized and false otherwise.
3369 static bool __init BusLogic_ParseKeyword(char **StringPointer, char *Keyword)
3371 char *Pointer = *StringPointer;
3372 while (*Keyword != '\0') {
3373 char StringChar = *Pointer++;
3374 char KeywordChar = *Keyword++;
3375 if (StringChar >= 'A' && StringChar <= 'Z')
3376 StringChar += 'a' - 'Z';
3377 if (KeywordChar >= 'A' && KeywordChar <= 'Z')
3378 KeywordChar += 'a' - 'Z';
3379 if (StringChar != KeywordChar)
3380 return false;
3382 *StringPointer = Pointer;
3383 return true;
3388 BusLogic_ParseDriverOptions handles processing of BusLogic Driver Options
3389 specifications.
3391 BusLogic Driver Options may be specified either via the Linux Kernel Command
3392 Line or via the Loadable Kernel Module Installation Facility. Driver Options
3393 for multiple host adapters may be specified either by separating the option
3394 strings by a semicolon, or by specifying multiple "BusLogic=" strings on the
3395 command line. Individual option specifications for a single host adapter are
3396 separated by commas. The Probing and Debugging Options apply to all host
3397 adapters whereas the remaining options apply individually only to the
3398 selected host adapter.
3400 The BusLogic Driver Probing Options are described in
3401 <file:Documentation/scsi/BusLogic.txt>.
3404 static int __init BusLogic_ParseDriverOptions(char *OptionsString)
3406 while (true) {
3407 struct BusLogic_DriverOptions *DriverOptions = &BusLogic_DriverOptions[BusLogic_DriverOptionsCount++];
3408 int TargetID;
3409 memset(DriverOptions, 0, sizeof(struct BusLogic_DriverOptions));
3410 while (*OptionsString != '\0' && *OptionsString != ';') {
3411 /* Probing Options. */
3412 if (BusLogic_ParseKeyword(&OptionsString, "IO:")) {
3413 unsigned long IO_Address = simple_strtoul(OptionsString, &OptionsString, 0);
3414 BusLogic_ProbeOptions.LimitedProbeISA = true;
3415 switch (IO_Address) {
3416 case 0x330:
3417 BusLogic_ProbeOptions.Probe330 = true;
3418 break;
3419 case 0x334:
3420 BusLogic_ProbeOptions.Probe334 = true;
3421 break;
3422 case 0x230:
3423 BusLogic_ProbeOptions.Probe230 = true;
3424 break;
3425 case 0x234:
3426 BusLogic_ProbeOptions.Probe234 = true;
3427 break;
3428 case 0x130:
3429 BusLogic_ProbeOptions.Probe130 = true;
3430 break;
3431 case 0x134:
3432 BusLogic_ProbeOptions.Probe134 = true;
3433 break;
3434 default:
3435 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid I/O Address 0x%X)\n", NULL, IO_Address);
3436 return 0;
3438 } else if (BusLogic_ParseKeyword(&OptionsString, "NoProbeISA"))
3439 BusLogic_ProbeOptions.NoProbeISA = true;
3440 else if (BusLogic_ParseKeyword(&OptionsString, "NoProbePCI"))
3441 BusLogic_ProbeOptions.NoProbePCI = true;
3442 else if (BusLogic_ParseKeyword(&OptionsString, "NoProbe"))
3443 BusLogic_ProbeOptions.NoProbe = true;
3444 else if (BusLogic_ParseKeyword(&OptionsString, "NoSortPCI"))
3445 BusLogic_ProbeOptions.NoSortPCI = true;
3446 else if (BusLogic_ParseKeyword(&OptionsString, "MultiMasterFirst"))
3447 BusLogic_ProbeOptions.MultiMasterFirst = true;
3448 else if (BusLogic_ParseKeyword(&OptionsString, "FlashPointFirst"))
3449 BusLogic_ProbeOptions.FlashPointFirst = true;
3450 /* Tagged Queuing Options. */
3451 else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:[") || BusLogic_ParseKeyword(&OptionsString, "QD:[")) {
3452 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) {
3453 unsigned short QueueDepth = simple_strtoul(OptionsString, &OptionsString, 0);
3454 if (QueueDepth > BusLogic_MaxTaggedQueueDepth) {
3455 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, QueueDepth);
3456 return 0;
3458 DriverOptions->QueueDepth[TargetID] = QueueDepth;
3459 if (*OptionsString == ',')
3460 OptionsString++;
3461 else if (*OptionsString == ']')
3462 break;
3463 else {
3464 BusLogic_Error("BusLogic: Invalid Driver Options " "(',' or ']' expected at '%s')\n", NULL, OptionsString);
3465 return 0;
3468 if (*OptionsString != ']') {
3469 BusLogic_Error("BusLogic: Invalid Driver Options " "(']' expected at '%s')\n", NULL, OptionsString);
3470 return 0;
3471 } else
3472 OptionsString++;
3473 } else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:") || BusLogic_ParseKeyword(&OptionsString, "QD:")) {
3474 unsigned short QueueDepth = simple_strtoul(OptionsString, &OptionsString, 0);
3475 if (QueueDepth == 0 || QueueDepth > BusLogic_MaxTaggedQueueDepth) {
3476 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, QueueDepth);
3477 return 0;
3479 DriverOptions->CommonQueueDepth = QueueDepth;
3480 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
3481 DriverOptions->QueueDepth[TargetID] = QueueDepth;
3482 } else if (BusLogic_ParseKeyword(&OptionsString, "TaggedQueuing:") || BusLogic_ParseKeyword(&OptionsString, "TQ:")) {
3483 if (BusLogic_ParseKeyword(&OptionsString, "Default")) {
3484 DriverOptions->TaggedQueuingPermitted = 0x0000;
3485 DriverOptions->TaggedQueuingPermittedMask = 0x0000;
3486 } else if (BusLogic_ParseKeyword(&OptionsString, "Enable")) {
3487 DriverOptions->TaggedQueuingPermitted = 0xFFFF;
3488 DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
3489 } else if (BusLogic_ParseKeyword(&OptionsString, "Disable")) {
3490 DriverOptions->TaggedQueuingPermitted = 0x0000;
3491 DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
3492 } else {
3493 unsigned short TargetBit;
3494 for (TargetID = 0, TargetBit = 1; TargetID < BusLogic_MaxTargetDevices; TargetID++, TargetBit <<= 1)
3495 switch (*OptionsString++) {
3496 case 'Y':
3497 DriverOptions->TaggedQueuingPermitted |= TargetBit;
3498 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
3499 break;
3500 case 'N':
3501 DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
3502 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
3503 break;
3504 case 'X':
3505 break;
3506 default:
3507 OptionsString--;
3508 TargetID = BusLogic_MaxTargetDevices;
3509 break;
3513 /* Miscellaneous Options. */
3514 else if (BusLogic_ParseKeyword(&OptionsString, "BusSettleTime:") || BusLogic_ParseKeyword(&OptionsString, "BST:")) {
3515 unsigned short BusSettleTime = simple_strtoul(OptionsString, &OptionsString, 0);
3516 if (BusSettleTime > 5 * 60) {
3517 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Bus Settle Time %d)\n", NULL, BusSettleTime);
3518 return 0;
3520 DriverOptions->BusSettleTime = BusSettleTime;
3521 } else if (BusLogic_ParseKeyword(&OptionsString, "InhibitTargetInquiry"))
3522 DriverOptions->LocalOptions.InhibitTargetInquiry = true;
3523 /* Debugging Options. */
3524 else if (BusLogic_ParseKeyword(&OptionsString, "TraceProbe"))
3525 BusLogic_GlobalOptions.TraceProbe = true;
3526 else if (BusLogic_ParseKeyword(&OptionsString, "TraceHardwareReset"))
3527 BusLogic_GlobalOptions.TraceHardwareReset = true;
3528 else if (BusLogic_ParseKeyword(&OptionsString, "TraceConfiguration"))
3529 BusLogic_GlobalOptions.TraceConfiguration = true;
3530 else if (BusLogic_ParseKeyword(&OptionsString, "TraceErrors"))
3531 BusLogic_GlobalOptions.TraceErrors = true;
3532 else if (BusLogic_ParseKeyword(&OptionsString, "Debug")) {
3533 BusLogic_GlobalOptions.TraceProbe = true;
3534 BusLogic_GlobalOptions.TraceHardwareReset = true;
3535 BusLogic_GlobalOptions.TraceConfiguration = true;
3536 BusLogic_GlobalOptions.TraceErrors = true;
3538 if (*OptionsString == ',')
3539 OptionsString++;
3540 else if (*OptionsString != ';' && *OptionsString != '\0') {
3541 BusLogic_Error("BusLogic: Unexpected Driver Option '%s' " "ignored\n", NULL, OptionsString);
3542 *OptionsString = '\0';
3545 if (!(BusLogic_DriverOptionsCount == 0 || BusLogic_ProbeInfoCount == 0 || BusLogic_DriverOptionsCount == BusLogic_ProbeInfoCount)) {
3546 BusLogic_Error("BusLogic: Invalid Driver Options " "(all or no I/O Addresses must be specified)\n", NULL);
3547 return 0;
3550 Tagged Queuing is disabled when the Queue Depth is 1 since queuing
3551 multiple commands is not possible.
3553 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
3554 if (DriverOptions->QueueDepth[TargetID] == 1) {
3555 unsigned short TargetBit = 1 << TargetID;
3556 DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
3557 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
3559 if (*OptionsString == ';')
3560 OptionsString++;
3561 if (*OptionsString == '\0')
3562 return 0;
3564 return 1;
3568 Get it all started
3571 static struct scsi_host_template Bus_Logic_template = {
3572 .module = THIS_MODULE,
3573 .proc_name = "BusLogic",
3574 .proc_info = BusLogic_ProcDirectoryInfo,
3575 .name = "BusLogic",
3576 .info = BusLogic_DriverInfo,
3577 .queuecommand = BusLogic_QueueCommand,
3578 .slave_configure = BusLogic_SlaveConfigure,
3579 .bios_param = BusLogic_BIOSDiskParameters,
3580 .eh_host_reset_handler = BusLogic_host_reset,
3581 #if 0
3582 .eh_abort_handler = BusLogic_AbortCommand,
3583 #endif
3584 .unchecked_isa_dma = 1,
3585 .max_sectors = 128,
3586 .use_clustering = ENABLE_CLUSTERING,
3590 BusLogic_Setup handles processing of Kernel Command Line Arguments.
3593 static int __init BusLogic_Setup(char *str)
3595 int ints[3];
3597 (void) get_options(str, ARRAY_SIZE(ints), ints);
3599 if (ints[0] != 0) {
3600 BusLogic_Error("BusLogic: Obsolete Command Line Entry " "Format Ignored\n", NULL);
3601 return 0;
3603 if (str == NULL || *str == '\0')
3604 return 0;
3605 return BusLogic_ParseDriverOptions(str);
3609 * Exit function. Deletes all hosts associated with this driver.
3612 static void __exit BusLogic_exit(void)
3614 struct BusLogic_HostAdapter *ha, *next;
3616 list_for_each_entry_safe(ha, next, &BusLogic_host_list, host_list)
3617 BusLogic_ReleaseHostAdapter(ha);
3620 __setup("BusLogic=", BusLogic_Setup);
3622 #ifdef MODULE
3623 static struct pci_device_id BusLogic_pci_tbl[] __devinitdata = {
3624 { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
3625 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
3626 { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
3627 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
3628 { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
3629 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
3632 #endif
3633 MODULE_DEVICE_TABLE(pci, BusLogic_pci_tbl);
3635 module_init(BusLogic_init);
3636 module_exit(BusLogic_exit);