MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / scsi / BusLogic.c
blob06faeb228887e5be4c5a41d0cc50365be5f45b79
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/config.h>
33 #include <linux/module.h>
34 #include <linux/init.h>
35 #include <linux/interrupt.h>
36 #include <linux/types.h>
37 #include <linux/blkdev.h>
38 #include <linux/delay.h>
39 #include <linux/ioport.h>
40 #include <linux/mm.h>
41 #include <linux/stat.h>
42 #include <linux/pci.h>
43 #include <linux/spinlock.h>
44 #include <scsi/scsicam.h>
46 #include <asm/dma.h>
47 #include <asm/io.h>
48 #include <asm/system.h>
50 #include "scsi.h"
51 #include <scsi/scsi_host.h>
52 #include "BusLogic.h"
53 #include "FlashPoint.c"
55 #ifndef FAILURE
56 #define FAILURE (-1)
57 #endif
60 BusLogic_DriverOptionsCount is a count of the number of BusLogic Driver
61 Options specifications provided via the Linux Kernel Command Line or via
62 the Loadable Kernel Module Installation Facility.
65 static int BusLogic_DriverOptionsCount;
69 BusLogic_DriverOptions is an array of Driver Options structures representing
70 BusLogic Driver Options specifications provided via the Linux Kernel Command
71 Line or via the Loadable Kernel Module Installation Facility.
74 static struct BusLogic_DriverOptions BusLogic_DriverOptions[BusLogic_MaxHostAdapters];
78 BusLogic can be assigned a string by insmod.
81 MODULE_LICENSE("GPL");
82 #ifdef MODULE
83 static char *BusLogic;
84 MODULE_PARM(BusLogic, "s");
85 #endif
89 BusLogic_ProbeOptions is a set of Probe Options to be applied across
90 all BusLogic Host Adapters.
93 static struct BusLogic_ProbeOptions BusLogic_ProbeOptions;
97 BusLogic_GlobalOptions is a set of Global Options to be applied across
98 all BusLogic Host Adapters.
101 static struct BusLogic_GlobalOptions BusLogic_GlobalOptions;
105 BusLogic_FirstRegisteredHostAdapter and BusLogic_LastRegisteredHostAdapter
106 are pointers to the first and last registered BusLogic Host Adapters.
109 static struct BusLogic_HostAdapter *BusLogic_FirstRegisteredHostAdapter;
110 static struct BusLogic_HostAdapter *BusLogic_LastRegisteredHostAdapter;
114 BusLogic_ProbeInfoCount is the number of entries in BusLogic_ProbeInfoList.
117 static int BusLogic_ProbeInfoCount;
121 BusLogic_ProbeInfoList is the list of I/O Addresses and Bus Probe Information
122 to be checked for potential BusLogic Host Adapters. It is initialized by
123 interrogating the PCI Configuration Space on PCI machines as well as from the
124 list of standard BusLogic I/O Addresses.
127 static struct BusLogic_ProbeInfo *BusLogic_ProbeInfoList;
131 BusLogic_CommandFailureReason holds a string identifying the reason why a
132 call to BusLogic_Command failed. It is only non-NULL when BusLogic_Command
133 returns a failure code.
136 static char *BusLogic_CommandFailureReason;
139 BusLogic_AnnounceDriver announces the Driver Version and Date, Author's
140 Name, Copyright Notice, and Electronic Mail Address.
143 static void BusLogic_AnnounceDriver(struct BusLogic_HostAdapter *HostAdapter)
145 BusLogic_Announce("***** BusLogic SCSI Driver Version " BusLogic_DriverVersion " of " BusLogic_DriverDate " *****\n", HostAdapter);
146 BusLogic_Announce("Copyright 1995-1998 by Leonard N. Zubkoff " "<lnz@dandelion.com>\n", HostAdapter);
151 BusLogic_DriverInfo returns the Host Adapter Name to identify this SCSI
152 Driver and Host Adapter.
155 static const char *BusLogic_DriverInfo(struct Scsi_Host *Host)
157 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata;
158 return HostAdapter->FullModelName;
163 BusLogic_RegisterHostAdapter adds Host Adapter to the list of registered
164 BusLogic Host Adapters.
167 static void __init BusLogic_RegisterHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
169 HostAdapter->Next = NULL;
170 if (BusLogic_FirstRegisteredHostAdapter == NULL) {
171 BusLogic_FirstRegisteredHostAdapter = HostAdapter;
172 BusLogic_LastRegisteredHostAdapter = HostAdapter;
173 } else {
174 BusLogic_LastRegisteredHostAdapter->Next = HostAdapter;
175 BusLogic_LastRegisteredHostAdapter = HostAdapter;
181 BusLogic_UnregisterHostAdapter removes Host Adapter from the list of
182 registered BusLogic Host Adapters.
185 static void BusLogic_UnregisterHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
187 if (HostAdapter == BusLogic_FirstRegisteredHostAdapter) {
188 BusLogic_FirstRegisteredHostAdapter = BusLogic_FirstRegisteredHostAdapter->Next;
189 if (HostAdapter == BusLogic_LastRegisteredHostAdapter)
190 BusLogic_LastRegisteredHostAdapter = NULL;
191 } else {
192 struct BusLogic_HostAdapter *PreviousHostAdapter = BusLogic_FirstRegisteredHostAdapter;
193 while (PreviousHostAdapter != NULL && PreviousHostAdapter->Next != HostAdapter)
194 PreviousHostAdapter = PreviousHostAdapter->Next;
195 if (PreviousHostAdapter != NULL)
196 PreviousHostAdapter->Next = HostAdapter->Next;
198 HostAdapter->Next = NULL;
203 BusLogic_InitializeCCBs initializes a group of Command Control Blocks (CCBs)
204 for Host Adapter from the BlockSize bytes located at BlockPointer. The newly
205 created CCBs are added to Host Adapter's free list.
208 static void BusLogic_InitializeCCBs(struct BusLogic_HostAdapter *HostAdapter, void *BlockPointer, int BlockSize, dma_addr_t BlockPointerHandle)
210 struct BusLogic_CCB *CCB = (struct BusLogic_CCB *) BlockPointer;
211 unsigned int offset = 0;
212 memset(BlockPointer, 0, BlockSize);
213 CCB->AllocationGroupHead = BlockPointerHandle;
214 CCB->AllocationGroupSize = BlockSize;
215 while ((BlockSize -= sizeof(struct BusLogic_CCB)) >= 0) {
216 CCB->Status = BusLogic_CCB_Free;
217 CCB->HostAdapter = HostAdapter;
218 CCB->DMA_Handle = (u32) BlockPointerHandle + offset;
219 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
220 CCB->CallbackFunction = BusLogic_QueueCompletedCCB;
221 CCB->BaseAddress = HostAdapter->FlashPointInfo.BaseAddress;
223 CCB->Next = HostAdapter->Free_CCBs;
224 CCB->NextAll = HostAdapter->All_CCBs;
225 HostAdapter->Free_CCBs = CCB;
226 HostAdapter->All_CCBs = CCB;
227 HostAdapter->AllocatedCCBs++;
228 CCB++;
229 offset += sizeof(struct BusLogic_CCB);
235 BusLogic_CreateInitialCCBs allocates the initial CCBs for Host Adapter.
238 static boolean __init BusLogic_CreateInitialCCBs(struct BusLogic_HostAdapter *HostAdapter)
240 int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB);
241 void *BlockPointer;
242 dma_addr_t BlockPointerHandle;
243 while (HostAdapter->AllocatedCCBs < HostAdapter->InitialCCBs) {
244 BlockPointer = pci_alloc_consistent(HostAdapter->PCI_Device, BlockSize, &BlockPointerHandle);
245 if (BlockPointer == NULL) {
246 BusLogic_Error("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n", HostAdapter);
247 return false;
249 BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize, BlockPointerHandle);
251 return true;
256 BusLogic_DestroyCCBs deallocates the CCBs for Host Adapter.
259 static void BusLogic_DestroyCCBs(struct BusLogic_HostAdapter *HostAdapter)
261 struct BusLogic_CCB *NextCCB = HostAdapter->All_CCBs, *CCB, *Last_CCB = NULL;
262 HostAdapter->All_CCBs = NULL;
263 HostAdapter->Free_CCBs = NULL;
264 while ((CCB = NextCCB) != NULL) {
265 NextCCB = CCB->NextAll;
266 if (CCB->AllocationGroupHead) {
267 if (Last_CCB)
268 pci_free_consistent(HostAdapter->PCI_Device, Last_CCB->AllocationGroupSize, Last_CCB, Last_CCB->AllocationGroupHead);
269 Last_CCB = CCB;
272 if (Last_CCB)
273 pci_free_consistent(HostAdapter->PCI_Device, Last_CCB->AllocationGroupSize, Last_CCB, Last_CCB->AllocationGroupHead);
278 BusLogic_CreateAdditionalCCBs allocates Additional CCBs for Host Adapter. If
279 allocation fails and there are no remaining CCBs available, the Driver Queue
280 Depth is decreased to a known safe value to avoid potential deadlocks when
281 multiple host adapters share the same IRQ Channel.
284 static void BusLogic_CreateAdditionalCCBs(struct BusLogic_HostAdapter *HostAdapter, int AdditionalCCBs, boolean SuccessMessageP)
286 int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB);
287 int PreviouslyAllocated = HostAdapter->AllocatedCCBs;
288 void *BlockPointer;
289 dma_addr_t BlockPointerHandle;
290 if (AdditionalCCBs <= 0)
291 return;
292 while (HostAdapter->AllocatedCCBs - PreviouslyAllocated < AdditionalCCBs) {
293 BlockPointer = pci_alloc_consistent(HostAdapter->PCI_Device, BlockSize, &BlockPointerHandle);
294 if (BlockPointer == NULL)
295 break;
296 BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize, BlockPointerHandle);
298 if (HostAdapter->AllocatedCCBs > PreviouslyAllocated) {
299 if (SuccessMessageP)
300 BusLogic_Notice("Allocated %d additional CCBs (total now %d)\n", HostAdapter, HostAdapter->AllocatedCCBs - PreviouslyAllocated, HostAdapter->AllocatedCCBs);
301 return;
303 BusLogic_Notice("Failed to allocate additional CCBs\n", HostAdapter);
304 if (HostAdapter->DriverQueueDepth > HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount) {
305 HostAdapter->DriverQueueDepth = HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount;
306 HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth;
311 BusLogic_AllocateCCB allocates a CCB from Host Adapter's free list,
312 allocating more memory from the Kernel if necessary. The Host Adapter's
313 Lock should already have been acquired by the caller.
316 static struct BusLogic_CCB *BusLogic_AllocateCCB(struct BusLogic_HostAdapter
317 *HostAdapter)
319 static unsigned long SerialNumber = 0;
320 struct BusLogic_CCB *CCB;
321 CCB = HostAdapter->Free_CCBs;
322 if (CCB != NULL) {
323 CCB->SerialNumber = ++SerialNumber;
324 HostAdapter->Free_CCBs = CCB->Next;
325 CCB->Next = NULL;
326 if (HostAdapter->Free_CCBs == NULL)
327 BusLogic_CreateAdditionalCCBs(HostAdapter, HostAdapter->IncrementalCCBs, true);
328 return CCB;
330 BusLogic_CreateAdditionalCCBs(HostAdapter, HostAdapter->IncrementalCCBs, true);
331 CCB = HostAdapter->Free_CCBs;
332 if (CCB == NULL)
333 return NULL;
334 CCB->SerialNumber = ++SerialNumber;
335 HostAdapter->Free_CCBs = CCB->Next;
336 CCB->Next = NULL;
337 return CCB;
342 BusLogic_DeallocateCCB deallocates a CCB, returning it to the Host Adapter's
343 free list. The Host Adapter's Lock should already have been acquired by the
344 caller.
347 static void BusLogic_DeallocateCCB(struct BusLogic_CCB *CCB)
349 struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter;
350 if (CCB->Command->use_sg != 0) {
351 pci_unmap_sg(HostAdapter->PCI_Device, (struct scatterlist *) CCB->Command->request_buffer, CCB->Command->use_sg, scsi_to_pci_dma_dir(CCB->Command->sc_data_direction));
352 } else if (CCB->Command->request_bufflen != 0) {
353 pci_unmap_single(HostAdapter->PCI_Device, CCB->DataPointer, CCB->DataLength, scsi_to_pci_dma_dir(CCB->Command->sc_data_direction));
355 pci_unmap_single(HostAdapter->PCI_Device, CCB->SenseDataPointer, CCB->SenseDataLength, PCI_DMA_FROMDEVICE);
356 CCB->Command = NULL;
357 CCB->Status = BusLogic_CCB_Free;
358 CCB->Next = HostAdapter->Free_CCBs;
359 HostAdapter->Free_CCBs = CCB;
364 BusLogic_Command sends the command OperationCode to HostAdapter, optionally
365 providing ParameterLength bytes of ParameterData and receiving at most
366 ReplyLength bytes of ReplyData; any excess reply data is received but
367 discarded.
369 On success, this function returns the number of reply bytes read from
370 the Host Adapter (including any discarded data); on failure, it returns
371 -1 if the command was invalid, or -2 if a timeout occurred.
373 BusLogic_Command is called exclusively during host adapter detection and
374 initialization, so performance and latency are not critical, and exclusive
375 access to the Host Adapter hardware is assumed. Once the host adapter and
376 driver are initialized, the only Host Adapter command that is issued is the
377 single byte Execute Mailbox Command operation code, which does not require
378 waiting for the Host Adapter Ready bit to be set in the Status Register.
381 static int BusLogic_Command(struct BusLogic_HostAdapter *HostAdapter, enum BusLogic_OperationCode OperationCode, void *ParameterData, int ParameterLength, void *ReplyData, int ReplyLength)
383 unsigned char *ParameterPointer = (unsigned char *) ParameterData;
384 unsigned char *ReplyPointer = (unsigned char *) ReplyData;
385 union BusLogic_StatusRegister StatusRegister;
386 union BusLogic_InterruptRegister InterruptRegister;
387 unsigned long ProcessorFlags = 0;
388 int ReplyBytes = 0, Result;
389 long TimeoutCounter;
391 Clear out the Reply Data if provided.
393 if (ReplyLength > 0)
394 memset(ReplyData, 0, ReplyLength);
396 If the IRQ Channel has not yet been acquired, then interrupts must be
397 disabled while issuing host adapter commands since a Command Complete
398 interrupt could occur if the IRQ Channel was previously enabled by another
399 BusLogic Host Adapter or another driver sharing the same IRQ Channel.
401 if (!HostAdapter->IRQ_ChannelAcquired) {
402 local_irq_save(ProcessorFlags);
403 local_irq_disable();
406 Wait for the Host Adapter Ready bit to be set and the Command/Parameter
407 Register Busy bit to be reset in the Status Register.
409 TimeoutCounter = 10000;
410 while (--TimeoutCounter >= 0) {
411 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
412 if (StatusRegister.sr.HostAdapterReady && !StatusRegister.sr.CommandParameterRegisterBusy)
413 break;
414 udelay(100);
416 if (TimeoutCounter < 0) {
417 BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";
418 Result = -2;
419 goto Done;
422 Write the OperationCode to the Command/Parameter Register.
424 HostAdapter->HostAdapterCommandCompleted = false;
425 BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);
427 Write any additional Parameter Bytes.
429 TimeoutCounter = 10000;
430 while (ParameterLength > 0 && --TimeoutCounter >= 0) {
432 Wait 100 microseconds to give the Host Adapter enough time to determine
433 whether the last value written to the Command/Parameter Register was
434 valid or not. If the Command Complete bit is set in the Interrupt
435 Register, then the Command Invalid bit in the Status Register will be
436 reset if the Operation Code or Parameter was valid and the command
437 has completed, or set if the Operation Code or Parameter was invalid.
438 If the Data In Register Ready bit is set in the Status Register, then
439 the Operation Code was valid, and data is waiting to be read back
440 from the Host Adapter. Otherwise, wait for the Command/Parameter
441 Register Busy bit in the Status Register to be reset.
443 udelay(100);
444 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
445 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
446 if (InterruptRegister.ir.CommandComplete)
447 break;
448 if (HostAdapter->HostAdapterCommandCompleted)
449 break;
450 if (StatusRegister.sr.DataInRegisterReady)
451 break;
452 if (StatusRegister.sr.CommandParameterRegisterBusy)
453 continue;
454 BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++);
455 ParameterLength--;
457 if (TimeoutCounter < 0) {
458 BusLogic_CommandFailureReason = "Timeout waiting for Parameter Acceptance";
459 Result = -2;
460 goto Done;
463 The Modify I/O Address command does not cause a Command Complete Interrupt.
465 if (OperationCode == BusLogic_ModifyIOAddress) {
466 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
467 if (StatusRegister.sr.CommandInvalid) {
468 BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
469 Result = -1;
470 goto Done;
472 if (BusLogic_GlobalOptions.TraceConfiguration)
473 BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: " "(Modify I/O Address)\n", HostAdapter, OperationCode, StatusRegister.All);
474 Result = 0;
475 goto Done;
478 Select an appropriate timeout value for awaiting command completion.
480 switch (OperationCode) {
481 case BusLogic_InquireInstalledDevicesID0to7:
482 case BusLogic_InquireInstalledDevicesID8to15:
483 case BusLogic_InquireTargetDevices:
484 /* Approximately 60 seconds. */
485 TimeoutCounter = 60 * 10000;
486 break;
487 default:
488 /* Approximately 1 second. */
489 TimeoutCounter = 10000;
490 break;
493 Receive any Reply Bytes, waiting for either the Command Complete bit to
494 be set in the Interrupt Register, or for the Interrupt Handler to set the
495 Host Adapter Command Completed bit in the Host Adapter structure.
497 while (--TimeoutCounter >= 0) {
498 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
499 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
500 if (InterruptRegister.ir.CommandComplete)
501 break;
502 if (HostAdapter->HostAdapterCommandCompleted)
503 break;
504 if (StatusRegister.sr.DataInRegisterReady) {
505 if (++ReplyBytes <= ReplyLength)
506 *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
507 else
508 BusLogic_ReadDataInRegister(HostAdapter);
510 if (OperationCode == BusLogic_FetchHostAdapterLocalRAM && StatusRegister.sr.HostAdapterReady)
511 break;
512 udelay(100);
514 if (TimeoutCounter < 0) {
515 BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";
516 Result = -2;
517 goto Done;
520 Clear any pending Command Complete Interrupt.
522 BusLogic_InterruptReset(HostAdapter);
524 Provide tracing information if requested.
526 if (BusLogic_GlobalOptions.TraceConfiguration) {
527 int i;
528 BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:", HostAdapter, OperationCode, StatusRegister.All, ReplyLength, ReplyBytes);
529 if (ReplyLength > ReplyBytes)
530 ReplyLength = ReplyBytes;
531 for (i = 0; i < ReplyLength; i++)
532 BusLogic_Notice(" %02X", HostAdapter, ((unsigned char *) ReplyData)[i]);
533 BusLogic_Notice("\n", HostAdapter);
536 Process Command Invalid conditions.
538 if (StatusRegister.sr.CommandInvalid) {
540 Some early BusLogic Host Adapters may not recover properly from
541 a Command Invalid condition, so if this appears to be the case,
542 a Soft Reset is issued to the Host Adapter. Potentially invalid
543 commands are never attempted after Mailbox Initialization is
544 performed, so there should be no Host Adapter state lost by a
545 Soft Reset in response to a Command Invalid condition.
547 udelay(1000);
548 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
549 if (StatusRegister.sr.CommandInvalid ||
550 StatusRegister.sr.Reserved ||
551 StatusRegister.sr.DataInRegisterReady ||
552 StatusRegister.sr.CommandParameterRegisterBusy || !StatusRegister.sr.HostAdapterReady || !StatusRegister.sr.InitializationRequired || StatusRegister.sr.DiagnosticActive || StatusRegister.sr.DiagnosticFailure) {
553 BusLogic_SoftReset(HostAdapter);
554 udelay(1000);
556 BusLogic_CommandFailureReason = "Command Invalid";
557 Result = -1;
558 goto Done;
561 Handle Excess Parameters Supplied conditions.
563 if (ParameterLength > 0) {
564 BusLogic_CommandFailureReason = "Excess Parameters Supplied";
565 Result = -1;
566 goto Done;
569 Indicate the command completed successfully.
571 BusLogic_CommandFailureReason = NULL;
572 Result = ReplyBytes;
574 Restore the interrupt status if necessary and return.
576 Done:
577 if (!HostAdapter->IRQ_ChannelAcquired)
578 local_irq_restore(ProcessorFlags);
579 return Result;
584 BusLogic_AppendProbeAddressISA appends a single ISA I/O Address to the list
585 of I/O Address and Bus Probe Information to be checked for potential BusLogic
586 Host Adapters.
589 static void __init BusLogic_AppendProbeAddressISA(unsigned long IO_Address)
591 struct BusLogic_ProbeInfo *ProbeInfo;
592 if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters)
593 return;
594 ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
595 ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
596 ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
597 ProbeInfo->IO_Address = IO_Address;
598 ProbeInfo->PCI_Device = NULL;
603 BusLogic_InitializeProbeInfoListISA initializes the list of I/O Address and
604 Bus Probe Information to be checked for potential BusLogic SCSI Host Adapters
605 only from the list of standard BusLogic MultiMaster ISA I/O Addresses.
608 static void __init BusLogic_InitializeProbeInfoListISA(struct BusLogic_HostAdapter
609 *PrototypeHostAdapter)
612 If BusLogic Driver Options specifications requested that ISA Bus Probes
613 be inhibited, do not proceed further.
615 if (BusLogic_ProbeOptions.NoProbeISA)
616 return;
618 Append the list of standard BusLogic MultiMaster ISA I/O Addresses.
620 if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe330 : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0)
621 BusLogic_AppendProbeAddressISA(0x330);
622 if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe334 : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0)
623 BusLogic_AppendProbeAddressISA(0x334);
624 if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe230 : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0)
625 BusLogic_AppendProbeAddressISA(0x230);
626 if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe234 : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0)
627 BusLogic_AppendProbeAddressISA(0x234);
628 if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe130 : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0)
629 BusLogic_AppendProbeAddressISA(0x130);
630 if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe134 : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0)
631 BusLogic_AppendProbeAddressISA(0x134);
635 #ifdef CONFIG_PCI
639 BusLogic_SortProbeInfo sorts a section of BusLogic_ProbeInfoList in order
640 of increasing PCI Bus and Device Number.
643 static void __init BusLogic_SortProbeInfo(struct BusLogic_ProbeInfo *ProbeInfoList, int ProbeInfoCount)
645 int LastInterchange = ProbeInfoCount - 1, Bound, j;
646 while (LastInterchange > 0) {
647 Bound = LastInterchange;
648 LastInterchange = 0;
649 for (j = 0; j < Bound; j++) {
650 struct BusLogic_ProbeInfo *ProbeInfo1 = &ProbeInfoList[j];
651 struct BusLogic_ProbeInfo *ProbeInfo2 = &ProbeInfoList[j + 1];
652 if (ProbeInfo1->Bus > ProbeInfo2->Bus || (ProbeInfo1->Bus == ProbeInfo2->Bus && (ProbeInfo1->Device > ProbeInfo2->Device))) {
653 struct BusLogic_ProbeInfo TempProbeInfo;
654 memcpy(&TempProbeInfo, ProbeInfo1, sizeof(struct BusLogic_ProbeInfo));
655 memcpy(ProbeInfo1, ProbeInfo2, sizeof(struct BusLogic_ProbeInfo));
656 memcpy(ProbeInfo2, &TempProbeInfo, sizeof(struct BusLogic_ProbeInfo));
657 LastInterchange = j;
665 BusLogic_InitializeMultiMasterProbeInfo initializes the list of I/O Address
666 and Bus Probe Information to be checked for potential BusLogic MultiMaster
667 SCSI Host Adapters by interrogating the PCI Configuration Space on PCI
668 machines as well as from the list of standard BusLogic MultiMaster ISA
669 I/O Addresses. It returns the number of PCI MultiMaster Host Adapters found.
672 static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAdapter
673 *PrototypeHostAdapter)
675 struct BusLogic_ProbeInfo *PrimaryProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount];
676 int NonPrimaryPCIMultiMasterIndex = BusLogic_ProbeInfoCount + 1;
677 int NonPrimaryPCIMultiMasterCount = 0, PCIMultiMasterCount = 0;
678 boolean ForceBusDeviceScanningOrder = false;
679 boolean ForceBusDeviceScanningOrderChecked = false;
680 boolean StandardAddressSeen[6];
681 struct pci_dev *PCI_Device = NULL;
682 int i;
683 if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters)
684 return 0;
685 BusLogic_ProbeInfoCount++;
686 for (i = 0; i < 6; i++)
687 StandardAddressSeen[i] = false;
689 Iterate over the MultiMaster PCI Host Adapters. For each enumerated host
690 adapter, determine whether its ISA Compatible I/O Port is enabled and if
691 so, whether it is assigned the Primary I/O Address. A host adapter that is
692 assigned the Primary I/O Address will always be the preferred boot device.
693 The MultiMaster BIOS will first recognize a host adapter at the Primary I/O
694 Address, then any other PCI host adapters, and finally any host adapters
695 located at the remaining standard ISA I/O Addresses. When a PCI host
696 adapter is found with its ISA Compatible I/O Port enabled, a command is
697 issued to disable the ISA Compatible I/O Port, and it is noted that the
698 particular standard ISA I/O Address need not be probed.
700 PrimaryProbeInfo->IO_Address = 0;
701 while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER, PCI_Device)) != NULL) {
702 struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter;
703 struct BusLogic_PCIHostAdapterInformation PCIHostAdapterInformation;
704 enum BusLogic_ISACompatibleIOPort ModifyIOAddressRequest;
705 unsigned char Bus;
706 unsigned char Device;
707 unsigned int IRQ_Channel;
708 unsigned long BaseAddress0;
709 unsigned long BaseAddress1;
710 unsigned long IO_Address;
711 unsigned long PCI_Address;
713 if (pci_enable_device(PCI_Device))
714 continue;
716 if (pci_set_dma_mask(PCI_Device, (u64) 0xffffffff))
717 continue;
719 Bus = PCI_Device->bus->number;
720 Device = PCI_Device->devfn >> 3;
721 IRQ_Channel = PCI_Device->irq;
722 IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0);
723 PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1);
725 if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) {
726 BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "MultiMaster Host Adapter\n", NULL, BaseAddress0);
727 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
728 continue;
730 if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO) {
731 BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for " "MultiMaster Host Adapter\n", NULL, BaseAddress1);
732 BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, Bus, Device, PCI_Address);
733 continue;
735 if (IRQ_Channel == 0) {
736 BusLogic_Error("BusLogic: IRQ Channel %d invalid for " "MultiMaster Host Adapter\n", NULL, IRQ_Channel);
737 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
738 continue;
740 if (BusLogic_GlobalOptions.TraceProbe) {
741 BusLogic_Notice("BusLogic: PCI MultiMaster Host Adapter " "detected at\n", NULL);
742 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);
745 Issue the Inquire PCI Host Adapter Information command to determine
746 the ISA Compatible I/O Port. If the ISA Compatible I/O Port is
747 known and enabled, note that the particular Standard ISA I/O
748 Address should not be probed.
750 HostAdapter->IO_Address = IO_Address;
751 BusLogic_InterruptReset(HostAdapter);
752 if (BusLogic_Command(HostAdapter, BusLogic_InquirePCIHostAdapterInformation, NULL, 0, &PCIHostAdapterInformation, sizeof(PCIHostAdapterInformation))
753 == sizeof(PCIHostAdapterInformation)) {
754 if (PCIHostAdapterInformation.ISACompatibleIOPort < 6)
755 StandardAddressSeen[PCIHostAdapterInformation.ISACompatibleIOPort] = true;
756 } else
757 PCIHostAdapterInformation.ISACompatibleIOPort = BusLogic_IO_Disable;
759 * Issue the Modify I/O Address command to disable the ISA Compatible
760 * I/O Port. On PCI Host Adapters, the Modify I/O Address command
761 * allows modification of the ISA compatible I/O Address that the Host
762 * Adapter responds to; it does not affect the PCI compliant I/O Address
763 * assigned at system initialization.
765 ModifyIOAddressRequest = BusLogic_IO_Disable;
766 BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress, &ModifyIOAddressRequest, sizeof(ModifyIOAddressRequest), NULL, 0);
768 For the first MultiMaster Host Adapter enumerated, issue the Fetch
769 Host Adapter Local RAM command to read byte 45 of the AutoSCSI area,
770 for the setting of the "Use Bus And Device # For PCI Scanning Seq."
771 option. Issue the Inquire Board ID command since this option is
772 only valid for the BT-948/958/958D.
774 if (!ForceBusDeviceScanningOrderChecked) {
775 struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest;
776 struct BusLogic_AutoSCSIByte45 AutoSCSIByte45;
777 struct BusLogic_BoardID BoardID;
778 FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_AutoSCSI_BaseOffset + 45;
779 FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIByte45);
780 BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &AutoSCSIByte45, sizeof(AutoSCSIByte45));
781 BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0, &BoardID, sizeof(BoardID));
782 if (BoardID.FirmwareVersion1stDigit == '5')
783 ForceBusDeviceScanningOrder = AutoSCSIByte45.ForceBusDeviceScanningOrder;
784 ForceBusDeviceScanningOrderChecked = true;
787 Determine whether this MultiMaster Host Adapter has its ISA
788 Compatible I/O Port enabled and is assigned the Primary I/O Address.
789 If it does, then it is the Primary MultiMaster Host Adapter and must
790 be recognized first. If it does not, then it is added to the list
791 for probing after any Primary MultiMaster Host Adapter is probed.
793 if (PCIHostAdapterInformation.ISACompatibleIOPort == BusLogic_IO_330) {
794 PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
795 PrimaryProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
796 PrimaryProbeInfo->IO_Address = IO_Address;
797 PrimaryProbeInfo->PCI_Address = PCI_Address;
798 PrimaryProbeInfo->Bus = Bus;
799 PrimaryProbeInfo->Device = Device;
800 PrimaryProbeInfo->IRQ_Channel = IRQ_Channel;
801 PrimaryProbeInfo->PCI_Device = PCI_Device;
802 PCIMultiMasterCount++;
803 } else if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters) {
804 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
805 ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
806 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
807 ProbeInfo->IO_Address = IO_Address;
808 ProbeInfo->PCI_Address = PCI_Address;
809 ProbeInfo->Bus = Bus;
810 ProbeInfo->Device = Device;
811 ProbeInfo->IRQ_Channel = IRQ_Channel;
812 ProbeInfo->PCI_Device = PCI_Device;
813 NonPrimaryPCIMultiMasterCount++;
814 PCIMultiMasterCount++;
815 } else
816 BusLogic_Warning("BusLogic: Too many Host Adapters " "detected\n", NULL);
819 If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option is ON
820 for the first enumerated MultiMaster Host Adapter, and if that host adapter
821 is a BT-948/958/958D, then the MultiMaster BIOS will recognize MultiMaster
822 Host Adapters in the order of increasing PCI Bus and Device Number. In
823 that case, sort the probe information into the same order the BIOS uses.
824 If this option is OFF, then the MultiMaster BIOS will recognize MultiMaster
825 Host Adapters in the order they are enumerated by the PCI BIOS, and hence
826 no sorting is necessary.
828 if (ForceBusDeviceScanningOrder)
829 BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[NonPrimaryPCIMultiMasterIndex], NonPrimaryPCIMultiMasterCount);
831 If no PCI MultiMaster Host Adapter is assigned the Primary I/O Address,
832 then the Primary I/O Address must be probed explicitly before any PCI
833 host adapters are probed.
835 if (!BusLogic_ProbeOptions.NoProbeISA)
836 if (PrimaryProbeInfo->IO_Address == 0 && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe330 : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0)) {
837 PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
838 PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
839 PrimaryProbeInfo->IO_Address = 0x330;
842 Append the list of standard BusLogic MultiMaster ISA I/O Addresses,
843 omitting the Primary I/O Address which has already been handled.
845 if (!BusLogic_ProbeOptions.NoProbeISA) {
846 if (!StandardAddressSeen[1] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe334 : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0))
847 BusLogic_AppendProbeAddressISA(0x334);
848 if (!StandardAddressSeen[2] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe230 : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0))
849 BusLogic_AppendProbeAddressISA(0x230);
850 if (!StandardAddressSeen[3] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe234 : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0))
851 BusLogic_AppendProbeAddressISA(0x234);
852 if (!StandardAddressSeen[4] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe130 : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0))
853 BusLogic_AppendProbeAddressISA(0x130);
854 if (!StandardAddressSeen[5] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe134 : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0))
855 BusLogic_AppendProbeAddressISA(0x134);
858 Iterate over the older non-compliant MultiMaster PCI Host Adapters,
859 noting the PCI bus location and assigned IRQ Channel.
861 PCI_Device = NULL;
862 while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC, PCI_Device)) != NULL) {
863 unsigned char Bus;
864 unsigned char Device;
865 unsigned int IRQ_Channel;
866 unsigned long IO_Address;
868 if (pci_enable_device(PCI_Device))
869 continue;
871 if (pci_set_dma_mask(PCI_Device, (u64) 0xffffffff))
872 continue;
874 Bus = PCI_Device->bus->number;
875 Device = PCI_Device->devfn >> 3;
876 IRQ_Channel = PCI_Device->irq;
877 IO_Address = pci_resource_start(PCI_Device, 0);
879 if (IO_Address == 0 || IRQ_Channel == 0)
880 continue;
881 for (i = 0; i < BusLogic_ProbeInfoCount; i++) {
882 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[i];
883 if (ProbeInfo->IO_Address == IO_Address && ProbeInfo->HostAdapterType == BusLogic_MultiMaster) {
884 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
885 ProbeInfo->PCI_Address = 0;
886 ProbeInfo->Bus = Bus;
887 ProbeInfo->Device = Device;
888 ProbeInfo->IRQ_Channel = IRQ_Channel;
889 ProbeInfo->PCI_Device = PCI_Device;
890 break;
894 return PCIMultiMasterCount;
899 BusLogic_InitializeFlashPointProbeInfo initializes the list of I/O Address
900 and Bus Probe Information to be checked for potential BusLogic FlashPoint
901 Host Adapters by interrogating the PCI Configuration Space. It returns the
902 number of FlashPoint Host Adapters found.
905 static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAdapter
906 *PrototypeHostAdapter)
908 int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0;
909 struct pci_dev *PCI_Device = NULL;
911 Interrogate PCI Configuration Space for any FlashPoint Host Adapters.
913 while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT, PCI_Device)) != NULL) {
914 unsigned char Bus;
915 unsigned char Device;
916 unsigned int IRQ_Channel;
917 unsigned long BaseAddress0;
918 unsigned long BaseAddress1;
919 unsigned long IO_Address;
920 unsigned long PCI_Address;
922 if (pci_enable_device(PCI_Device))
923 continue;
925 if (pci_set_dma_mask(PCI_Device, (u64) 0xffffffff))
926 continue;
928 Bus = PCI_Device->bus->number;
929 Device = PCI_Device->devfn >> 3;
930 IRQ_Channel = PCI_Device->irq;
931 IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0);
932 PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1);
933 #ifndef CONFIG_SCSI_OMIT_FLASHPOINT
934 if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) {
935 BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, BaseAddress0);
936 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
937 continue;
939 if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO) {
940 BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for " "FlashPoint Host Adapter\n", NULL, BaseAddress1);
941 BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, Bus, Device, PCI_Address);
942 continue;
944 if (IRQ_Channel == 0) {
945 BusLogic_Error("BusLogic: IRQ Channel %d invalid for " "FlashPoint Host Adapter\n", NULL, IRQ_Channel);
946 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
947 continue;
949 if (BusLogic_GlobalOptions.TraceProbe) {
950 BusLogic_Notice("BusLogic: FlashPoint Host Adapter " "detected at\n", NULL);
951 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);
953 if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters) {
954 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
955 ProbeInfo->HostAdapterType = BusLogic_FlashPoint;
956 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
957 ProbeInfo->IO_Address = IO_Address;
958 ProbeInfo->PCI_Address = PCI_Address;
959 ProbeInfo->Bus = Bus;
960 ProbeInfo->Device = Device;
961 ProbeInfo->IRQ_Channel = IRQ_Channel;
962 ProbeInfo->PCI_Device = PCI_Device;
963 FlashPointCount++;
964 } else
965 BusLogic_Warning("BusLogic: Too many Host Adapters " "detected\n", NULL);
966 #else
967 BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", NULL, Bus, Device);
968 BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, irq %d, " "but FlashPoint\n", NULL, IO_Address, PCI_Address, IRQ_Channel);
969 BusLogic_Error("BusLogic: support was omitted in this kernel " "configuration.\n", NULL);
970 #endif
973 The FlashPoint BIOS will scan for FlashPoint Host Adapters in the order of
974 increasing PCI Bus and Device Number, so sort the probe information into
975 the same order the BIOS uses.
977 BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[FlashPointIndex], FlashPointCount);
978 return FlashPointCount;
983 BusLogic_InitializeProbeInfoList initializes the list of I/O Address and Bus
984 Probe Information to be checked for potential BusLogic SCSI Host Adapters by
985 interrogating the PCI Configuration Space on PCI machines as well as from the
986 list of standard BusLogic MultiMaster ISA I/O Addresses. By default, if both
987 FlashPoint and PCI MultiMaster Host Adapters are present, this driver will
988 probe for FlashPoint Host Adapters first unless the BIOS primary disk is
989 controlled by the first PCI MultiMaster Host Adapter, in which case
990 MultiMaster Host Adapters will be probed first. The BusLogic Driver Options
991 specifications "MultiMasterFirst" and "FlashPointFirst" can be used to force
992 a particular probe order.
995 static void __init BusLogic_InitializeProbeInfoList(struct BusLogic_HostAdapter
996 *PrototypeHostAdapter)
999 If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint
1000 Host Adapters; otherwise, default to the standard ISA MultiMaster probe.
1002 if (!BusLogic_ProbeOptions.NoProbePCI) {
1003 if (BusLogic_ProbeOptions.MultiMasterFirst) {
1004 BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
1005 BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
1006 } else if (BusLogic_ProbeOptions.FlashPointFirst) {
1007 BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
1008 BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
1009 } else {
1010 int FlashPointCount = BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
1011 int PCIMultiMasterCount = BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
1012 if (FlashPointCount > 0 && PCIMultiMasterCount > 0) {
1013 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[FlashPointCount];
1014 struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter;
1015 struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest;
1016 struct BusLogic_BIOSDriveMapByte Drive0MapByte;
1017 while (ProbeInfo->HostAdapterBusType != BusLogic_PCI_Bus)
1018 ProbeInfo++;
1019 HostAdapter->IO_Address = ProbeInfo->IO_Address;
1020 FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_BIOS_BaseOffset + BusLogic_BIOS_DriveMapOffset + 0;
1021 FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(Drive0MapByte);
1022 BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &Drive0MapByte, sizeof(Drive0MapByte));
1024 If the Map Byte for BIOS Drive 0 indicates that BIOS Drive 0
1025 is controlled by this PCI MultiMaster Host Adapter, then
1026 reverse the probe order so that MultiMaster Host Adapters are
1027 probed before FlashPoint Host Adapters.
1029 if (Drive0MapByte.DiskGeometry != BusLogic_BIOS_Disk_Not_Installed) {
1030 struct BusLogic_ProbeInfo SavedProbeInfo[BusLogic_MaxHostAdapters];
1031 int MultiMasterCount = BusLogic_ProbeInfoCount - FlashPointCount;
1032 memcpy(SavedProbeInfo, BusLogic_ProbeInfoList, BusLogic_ProbeInfoCount * sizeof(struct BusLogic_ProbeInfo));
1033 memcpy(&BusLogic_ProbeInfoList[0], &SavedProbeInfo[FlashPointCount], MultiMasterCount * sizeof(struct BusLogic_ProbeInfo));
1034 memcpy(&BusLogic_ProbeInfoList[MultiMasterCount], &SavedProbeInfo[0], FlashPointCount * sizeof(struct BusLogic_ProbeInfo));
1038 } else
1039 BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter);
1043 #endif /* CONFIG_PCI */
1047 BusLogic_Failure prints a standardized error message, and then returns false.
1050 static boolean BusLogic_Failure(struct BusLogic_HostAdapter *HostAdapter, char *ErrorMessage)
1052 BusLogic_AnnounceDriver(HostAdapter);
1053 if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus) {
1054 BusLogic_Error("While configuring BusLogic PCI Host Adapter at\n", HostAdapter);
1055 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);
1056 } else
1057 BusLogic_Error("While configuring BusLogic Host Adapter at " "I/O Address 0x%X:\n", HostAdapter, HostAdapter->IO_Address);
1058 BusLogic_Error("%s FAILED - DETACHING\n", HostAdapter, ErrorMessage);
1059 if (BusLogic_CommandFailureReason != NULL)
1060 BusLogic_Error("ADDITIONAL FAILURE INFO - %s\n", HostAdapter, BusLogic_CommandFailureReason);
1061 return false;
1066 BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter.
1069 static boolean __init BusLogic_ProbeHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
1071 union BusLogic_StatusRegister StatusRegister;
1072 union BusLogic_InterruptRegister InterruptRegister;
1073 union BusLogic_GeometryRegister GeometryRegister;
1075 FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager.
1077 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1078 struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
1079 FlashPointInfo->BaseAddress = (u32) HostAdapter->IO_Address;
1080 FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel;
1081 FlashPointInfo->Present = false;
1082 if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 && FlashPointInfo->Present)) {
1083 BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", HostAdapter, HostAdapter->Bus, HostAdapter->Device);
1084 BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, " "but FlashPoint\n", HostAdapter, HostAdapter->IO_Address, HostAdapter->PCI_Address);
1085 BusLogic_Error("BusLogic: Probe Function failed to validate it.\n", HostAdapter);
1086 return false;
1088 if (BusLogic_GlobalOptions.TraceProbe)
1089 BusLogic_Notice("BusLogic_Probe(0x%X): FlashPoint Found\n", HostAdapter, HostAdapter->IO_Address);
1091 Indicate the Host Adapter Probe completed successfully.
1093 return true;
1096 Read the Status, Interrupt, and Geometry Registers to test if there are I/O
1097 ports that respond, and to check the values to determine if they are from a
1098 BusLogic Host Adapter. A nonexistent I/O port will return 0xFF, in which
1099 case there is definitely no BusLogic Host Adapter at this base I/O Address.
1100 The test here is a subset of that used by the BusLogic Host Adapter BIOS.
1102 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1103 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
1104 GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1105 if (BusLogic_GlobalOptions.TraceProbe)
1106 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);
1107 if (StatusRegister.All == 0 || StatusRegister.sr.DiagnosticActive || StatusRegister.sr.CommandParameterRegisterBusy || StatusRegister.sr.Reserved || StatusRegister.sr.CommandInvalid || InterruptRegister.ir.Reserved != 0)
1108 return false;
1110 Check the undocumented Geometry Register to test if there is an I/O port
1111 that responded. Adaptec Host Adapters do not implement the Geometry
1112 Register, so this test helps serve to avoid incorrectly recognizing an
1113 Adaptec 1542A or 1542B as a BusLogic. Unfortunately, the Adaptec 1542C
1114 series does respond to the Geometry Register I/O port, but it will be
1115 rejected later when the Inquire Extended Setup Information command is
1116 issued in BusLogic_CheckHostAdapter. The AMI FastDisk Host Adapter is a
1117 BusLogic clone that implements the same interface as earlier BusLogic
1118 Host Adapters, including the undocumented commands, and is therefore
1119 supported by this driver. However, the AMI FastDisk always returns 0x00
1120 upon reading the Geometry Register, so the extended translation option
1121 should always be left disabled on the AMI FastDisk.
1123 if (GeometryRegister.All == 0xFF)
1124 return false;
1126 Indicate the Host Adapter Probe completed successfully.
1128 return true;
1133 BusLogic_HardwareResetHostAdapter issues a Hardware Reset to the Host Adapter
1134 and waits for Host Adapter Diagnostics to complete. If HardReset is true, a
1135 Hard Reset is performed which also initiates a SCSI Bus Reset. Otherwise, a
1136 Soft Reset is performed which only resets the Host Adapter without forcing a
1137 SCSI Bus Reset.
1140 static boolean BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter
1141 *HostAdapter, boolean HardReset)
1143 union BusLogic_StatusRegister StatusRegister;
1144 int TimeoutCounter;
1146 FlashPoint Host Adapters are Hard Reset by the FlashPoint SCCB Manager.
1148 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1149 struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
1150 FlashPointInfo->HostSoftReset = !HardReset;
1151 FlashPointInfo->ReportDataUnderrun = true;
1152 HostAdapter->CardHandle = FlashPoint_HardwareResetHostAdapter(FlashPointInfo);
1153 if (HostAdapter->CardHandle == FlashPoint_BadCardHandle)
1154 return false;
1156 Indicate the Host Adapter Hard Reset completed successfully.
1158 return true;
1161 Issue a Hard Reset or Soft Reset Command to the Host Adapter. The Host
1162 Adapter should respond by setting Diagnostic Active in the Status Register.
1164 if (HardReset)
1165 BusLogic_HardReset(HostAdapter);
1166 else
1167 BusLogic_SoftReset(HostAdapter);
1169 Wait until Diagnostic Active is set in the Status Register.
1171 TimeoutCounter = 5 * 10000;
1172 while (--TimeoutCounter >= 0) {
1173 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1174 if (StatusRegister.sr.DiagnosticActive)
1175 break;
1176 udelay(100);
1178 if (BusLogic_GlobalOptions.TraceHardwareReset)
1179 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All);
1180 if (TimeoutCounter < 0)
1181 return false;
1183 Wait 100 microseconds to allow completion of any initial diagnostic
1184 activity which might leave the contents of the Status Register
1185 unpredictable.
1187 udelay(100);
1189 Wait until Diagnostic Active is reset in the Status Register.
1191 TimeoutCounter = 10 * 10000;
1192 while (--TimeoutCounter >= 0) {
1193 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1194 if (!StatusRegister.sr.DiagnosticActive)
1195 break;
1196 udelay(100);
1198 if (BusLogic_GlobalOptions.TraceHardwareReset)
1199 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All);
1200 if (TimeoutCounter < 0)
1201 return false;
1203 Wait until at least one of the Diagnostic Failure, Host Adapter Ready,
1204 or Data In Register Ready bits is set in the Status Register.
1206 TimeoutCounter = 10000;
1207 while (--TimeoutCounter >= 0) {
1208 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1209 if (StatusRegister.sr.DiagnosticFailure || StatusRegister.sr.HostAdapterReady || StatusRegister.sr.DataInRegisterReady)
1210 break;
1211 udelay(100);
1213 if (BusLogic_GlobalOptions.TraceHardwareReset)
1214 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All);
1215 if (TimeoutCounter < 0)
1216 return false;
1218 If Diagnostic Failure is set or Host Adapter Ready is reset, then an
1219 error occurred during the Host Adapter diagnostics. If Data In Register
1220 Ready is set, then there is an Error Code available.
1222 if (StatusRegister.sr.DiagnosticFailure || !StatusRegister.sr.HostAdapterReady) {
1223 BusLogic_CommandFailureReason = NULL;
1224 BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
1225 BusLogic_Error("HOST ADAPTER STATUS REGISTER = %02X\n", HostAdapter, StatusRegister.All);
1226 if (StatusRegister.sr.DataInRegisterReady) {
1227 unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
1228 BusLogic_Error("HOST ADAPTER ERROR CODE = %d\n", HostAdapter, ErrorCode);
1230 return false;
1233 Indicate the Host Adapter Hard Reset completed successfully.
1235 return true;
1240 BusLogic_CheckHostAdapter checks to be sure this really is a BusLogic
1241 Host Adapter.
1244 static boolean __init BusLogic_CheckHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
1246 struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation;
1247 unsigned char RequestedReplyLength;
1248 boolean Result = true;
1250 FlashPoint Host Adapters do not require this protection.
1252 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1253 return true;
1255 Issue the Inquire Extended Setup Information command. Only genuine
1256 BusLogic Host Adapters and true clones support this command. Adaptec 1542C
1257 series Host Adapters that respond to the Geometry Register I/O port will
1258 fail this command.
1260 RequestedReplyLength = sizeof(ExtendedSetupInformation);
1261 if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &ExtendedSetupInformation, sizeof(ExtendedSetupInformation))
1262 != sizeof(ExtendedSetupInformation))
1263 Result = false;
1265 Provide tracing information if requested and return.
1267 if (BusLogic_GlobalOptions.TraceProbe)
1268 BusLogic_Notice("BusLogic_Check(0x%X): MultiMaster %s\n", HostAdapter, HostAdapter->IO_Address, (Result ? "Found" : "Not Found"));
1269 return Result;
1274 BusLogic_ReadHostAdapterConfiguration reads the Configuration Information
1275 from Host Adapter and initializes the Host Adapter structure.
1278 static boolean __init BusLogic_ReadHostAdapterConfiguration(struct BusLogic_HostAdapter
1279 *HostAdapter)
1281 struct BusLogic_BoardID BoardID;
1282 struct BusLogic_Configuration Configuration;
1283 struct BusLogic_SetupInformation SetupInformation;
1284 struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation;
1285 unsigned char HostAdapterModelNumber[5];
1286 unsigned char FirmwareVersion3rdDigit;
1287 unsigned char FirmwareVersionLetter;
1288 struct BusLogic_PCIHostAdapterInformation PCIHostAdapterInformation;
1289 struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest;
1290 struct BusLogic_AutoSCSIData AutoSCSIData;
1291 union BusLogic_GeometryRegister GeometryRegister;
1292 unsigned char RequestedReplyLength;
1293 unsigned char *TargetPointer, Character;
1294 int TargetID, i;
1296 Configuration Information for FlashPoint Host Adapters is provided in the
1297 FlashPoint_Info structure by the FlashPoint SCCB Manager's Probe Function.
1298 Initialize fields in the Host Adapter structure from the FlashPoint_Info
1299 structure.
1301 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1302 struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
1303 TargetPointer = HostAdapter->ModelName;
1304 *TargetPointer++ = 'B';
1305 *TargetPointer++ = 'T';
1306 *TargetPointer++ = '-';
1307 for (i = 0; i < sizeof(FlashPointInfo->ModelNumber); i++)
1308 *TargetPointer++ = FlashPointInfo->ModelNumber[i];
1309 *TargetPointer++ = '\0';
1310 strcpy(HostAdapter->FirmwareVersion, FlashPoint_FirmwareVersion);
1311 HostAdapter->SCSI_ID = FlashPointInfo->SCSI_ID;
1312 HostAdapter->ExtendedTranslationEnabled = FlashPointInfo->ExtendedTranslationEnabled;
1313 HostAdapter->ParityCheckingEnabled = FlashPointInfo->ParityCheckingEnabled;
1314 HostAdapter->BusResetEnabled = !FlashPointInfo->HostSoftReset;
1315 HostAdapter->LevelSensitiveInterrupt = true;
1316 HostAdapter->HostWideSCSI = FlashPointInfo->HostWideSCSI;
1317 HostAdapter->HostDifferentialSCSI = false;
1318 HostAdapter->HostSupportsSCAM = true;
1319 HostAdapter->HostUltraSCSI = true;
1320 HostAdapter->ExtendedLUNSupport = true;
1321 HostAdapter->TerminationInfoValid = true;
1322 HostAdapter->LowByteTerminated = FlashPointInfo->LowByteTerminated;
1323 HostAdapter->HighByteTerminated = FlashPointInfo->HighByteTerminated;
1324 HostAdapter->SCAM_Enabled = FlashPointInfo->SCAM_Enabled;
1325 HostAdapter->SCAM_Level2 = FlashPointInfo->SCAM_Level2;
1326 HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1327 HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1328 HostAdapter->MaxLogicalUnits = 32;
1329 HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1330 HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1331 HostAdapter->DriverQueueDepth = 255;
1332 HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth;
1333 HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted;
1334 HostAdapter->FastPermitted = FlashPointInfo->FastPermitted;
1335 HostAdapter->UltraPermitted = FlashPointInfo->UltraPermitted;
1336 HostAdapter->WidePermitted = FlashPointInfo->WidePermitted;
1337 HostAdapter->DisconnectPermitted = FlashPointInfo->DisconnectPermitted;
1338 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1339 goto Common;
1342 Issue the Inquire Board ID command.
1344 if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0, &BoardID, sizeof(BoardID)) != sizeof(BoardID))
1345 return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
1347 Issue the Inquire Configuration command.
1349 if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0, &Configuration, sizeof(Configuration))
1350 != sizeof(Configuration))
1351 return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
1353 Issue the Inquire Setup Information command.
1355 RequestedReplyLength = sizeof(SetupInformation);
1356 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &SetupInformation, sizeof(SetupInformation))
1357 != sizeof(SetupInformation))
1358 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
1360 Issue the Inquire Extended Setup Information command.
1362 RequestedReplyLength = sizeof(ExtendedSetupInformation);
1363 if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &ExtendedSetupInformation, sizeof(ExtendedSetupInformation))
1364 != sizeof(ExtendedSetupInformation))
1365 return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
1367 Issue the Inquire Firmware Version 3rd Digit command.
1369 FirmwareVersion3rdDigit = '\0';
1370 if (BoardID.FirmwareVersion1stDigit > '0')
1371 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit, NULL, 0, &FirmwareVersion3rdDigit, sizeof(FirmwareVersion3rdDigit))
1372 != sizeof(FirmwareVersion3rdDigit))
1373 return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
1375 Issue the Inquire Host Adapter Model Number command.
1377 if (ExtendedSetupInformation.BusType == 'A' && BoardID.FirmwareVersion1stDigit == '2')
1378 /* BusLogic BT-542B ISA 2.xx */
1379 strcpy(HostAdapterModelNumber, "542B");
1380 else if (ExtendedSetupInformation.BusType == 'E' && BoardID.FirmwareVersion1stDigit == '2' && (BoardID.FirmwareVersion2ndDigit <= '1' || (BoardID.FirmwareVersion2ndDigit == '2' && FirmwareVersion3rdDigit == '0')))
1381 /* BusLogic BT-742A EISA 2.1x or 2.20 */
1382 strcpy(HostAdapterModelNumber, "742A");
1383 else if (ExtendedSetupInformation.BusType == 'E' && BoardID.FirmwareVersion1stDigit == '0')
1384 /* AMI FastDisk EISA Series 441 0.x */
1385 strcpy(HostAdapterModelNumber, "747A");
1386 else {
1387 RequestedReplyLength = sizeof(HostAdapterModelNumber);
1388 if (BusLogic_Command(HostAdapter, BusLogic_InquireHostAdapterModelNumber, &RequestedReplyLength, sizeof(RequestedReplyLength), &HostAdapterModelNumber, sizeof(HostAdapterModelNumber))
1389 != sizeof(HostAdapterModelNumber))
1390 return BusLogic_Failure(HostAdapter, "INQUIRE HOST ADAPTER MODEL NUMBER");
1393 BusLogic MultiMaster Host Adapters can be identified by their model number
1394 and the major version number of their firmware as follows:
1396 5.xx BusLogic "W" Series Host Adapters:
1397 BT-948/958/958D
1398 4.xx BusLogic "C" Series Host Adapters:
1399 BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
1400 3.xx BusLogic "S" Series Host Adapters:
1401 BT-747S/747D/757S/757D/445S/545S/542D
1402 BT-542B/742A (revision H)
1403 2.xx BusLogic "A" Series Host Adapters:
1404 BT-542B/742A (revision G and below)
1405 0.xx AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
1408 Save the Model Name and Host Adapter Name in the Host Adapter structure.
1410 TargetPointer = HostAdapter->ModelName;
1411 *TargetPointer++ = 'B';
1412 *TargetPointer++ = 'T';
1413 *TargetPointer++ = '-';
1414 for (i = 0; i < sizeof(HostAdapterModelNumber); i++) {
1415 Character = HostAdapterModelNumber[i];
1416 if (Character == ' ' || Character == '\0')
1417 break;
1418 *TargetPointer++ = Character;
1420 *TargetPointer++ = '\0';
1422 Save the Firmware Version in the Host Adapter structure.
1424 TargetPointer = HostAdapter->FirmwareVersion;
1425 *TargetPointer++ = BoardID.FirmwareVersion1stDigit;
1426 *TargetPointer++ = '.';
1427 *TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
1428 if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0')
1429 *TargetPointer++ = FirmwareVersion3rdDigit;
1430 *TargetPointer = '\0';
1432 Issue the Inquire Firmware Version Letter command.
1434 if (strcmp(HostAdapter->FirmwareVersion, "3.3") >= 0) {
1435 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter, NULL, 0, &FirmwareVersionLetter, sizeof(FirmwareVersionLetter))
1436 != sizeof(FirmwareVersionLetter))
1437 return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE VERSION LETTER");
1438 if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0')
1439 *TargetPointer++ = FirmwareVersionLetter;
1440 *TargetPointer = '\0';
1443 Save the Host Adapter SCSI ID in the Host Adapter structure.
1445 HostAdapter->SCSI_ID = Configuration.HostAdapterID;
1447 Determine the Bus Type and save it in the Host Adapter structure, determine
1448 and save the IRQ Channel if necessary, and determine and save the DMA
1449 Channel for ISA Host Adapters.
1451 HostAdapter->HostAdapterBusType = BusLogic_HostAdapterBusTypes[HostAdapter->ModelName[3] - '4'];
1452 if (HostAdapter->IRQ_Channel == 0) {
1453 if (Configuration.IRQ_Channel9)
1454 HostAdapter->IRQ_Channel = 9;
1455 else if (Configuration.IRQ_Channel10)
1456 HostAdapter->IRQ_Channel = 10;
1457 else if (Configuration.IRQ_Channel11)
1458 HostAdapter->IRQ_Channel = 11;
1459 else if (Configuration.IRQ_Channel12)
1460 HostAdapter->IRQ_Channel = 12;
1461 else if (Configuration.IRQ_Channel14)
1462 HostAdapter->IRQ_Channel = 14;
1463 else if (Configuration.IRQ_Channel15)
1464 HostAdapter->IRQ_Channel = 15;
1466 if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus) {
1467 if (Configuration.DMA_Channel5)
1468 HostAdapter->DMA_Channel = 5;
1469 else if (Configuration.DMA_Channel6)
1470 HostAdapter->DMA_Channel = 6;
1471 else if (Configuration.DMA_Channel7)
1472 HostAdapter->DMA_Channel = 7;
1475 Determine whether Extended Translation is enabled and save it in
1476 the Host Adapter structure.
1478 GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1479 HostAdapter->ExtendedTranslationEnabled = GeometryRegister.gr.ExtendedTranslationEnabled;
1481 Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide
1482 SCSI flag, Differential SCSI flag, SCAM Supported flag, and
1483 Ultra SCSI flag in the Host Adapter structure.
1485 HostAdapter->HostAdapterScatterGatherLimit = ExtendedSetupInformation.ScatterGatherLimit;
1486 HostAdapter->DriverScatterGatherLimit = HostAdapter->HostAdapterScatterGatherLimit;
1487 if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
1488 HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1489 if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupt)
1490 HostAdapter->LevelSensitiveInterrupt = true;
1491 HostAdapter->HostWideSCSI = ExtendedSetupInformation.HostWideSCSI;
1492 HostAdapter->HostDifferentialSCSI = ExtendedSetupInformation.HostDifferentialSCSI;
1493 HostAdapter->HostSupportsSCAM = ExtendedSetupInformation.HostSupportsSCAM;
1494 HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI;
1496 Determine whether Extended LUN Format CCBs are supported and save the
1497 information in the Host Adapter structure.
1499 if (HostAdapter->FirmwareVersion[0] == '5' || (HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI))
1500 HostAdapter->ExtendedLUNSupport = true;
1502 Issue the Inquire PCI Host Adapter Information command to read the
1503 Termination Information from "W" series MultiMaster Host Adapters.
1505 if (HostAdapter->FirmwareVersion[0] == '5') {
1506 if (BusLogic_Command(HostAdapter, BusLogic_InquirePCIHostAdapterInformation, NULL, 0, &PCIHostAdapterInformation, sizeof(PCIHostAdapterInformation))
1507 != sizeof(PCIHostAdapterInformation))
1508 return BusLogic_Failure(HostAdapter, "INQUIRE PCI HOST ADAPTER INFORMATION");
1510 Save the Termination Information in the Host Adapter structure.
1512 if (PCIHostAdapterInformation.GenericInfoValid) {
1513 HostAdapter->TerminationInfoValid = true;
1514 HostAdapter->LowByteTerminated = PCIHostAdapterInformation.LowByteTerminated;
1515 HostAdapter->HighByteTerminated = PCIHostAdapterInformation.HighByteTerminated;
1519 Issue the Fetch Host Adapter Local RAM command to read the AutoSCSI data
1520 from "W" and "C" series MultiMaster Host Adapters.
1522 if (HostAdapter->FirmwareVersion[0] >= '4') {
1523 FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_AutoSCSI_BaseOffset;
1524 FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIData);
1525 if (BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &AutoSCSIData, sizeof(AutoSCSIData))
1526 != sizeof(AutoSCSIData))
1527 return BusLogic_Failure(HostAdapter, "FETCH HOST ADAPTER LOCAL RAM");
1529 Save the Parity Checking Enabled, Bus Reset Enabled, and Termination
1530 Information in the Host Adapter structure.
1532 HostAdapter->ParityCheckingEnabled = AutoSCSIData.ParityCheckingEnabled;
1533 HostAdapter->BusResetEnabled = AutoSCSIData.BusResetEnabled;
1534 if (HostAdapter->FirmwareVersion[0] == '4') {
1535 HostAdapter->TerminationInfoValid = true;
1536 HostAdapter->LowByteTerminated = AutoSCSIData.LowByteTerminated;
1537 HostAdapter->HighByteTerminated = AutoSCSIData.HighByteTerminated;
1540 Save the Wide Permitted, Fast Permitted, Synchronous Permitted,
1541 Disconnect Permitted, Ultra Permitted, and SCAM Information in the
1542 Host Adapter structure.
1544 HostAdapter->WidePermitted = AutoSCSIData.WidePermitted;
1545 HostAdapter->FastPermitted = AutoSCSIData.FastPermitted;
1546 HostAdapter->SynchronousPermitted = AutoSCSIData.SynchronousPermitted;
1547 HostAdapter->DisconnectPermitted = AutoSCSIData.DisconnectPermitted;
1548 if (HostAdapter->HostUltraSCSI)
1549 HostAdapter->UltraPermitted = AutoSCSIData.UltraPermitted;
1550 if (HostAdapter->HostSupportsSCAM) {
1551 HostAdapter->SCAM_Enabled = AutoSCSIData.SCAM_Enabled;
1552 HostAdapter->SCAM_Level2 = AutoSCSIData.SCAM_Level2;
1556 Initialize fields in the Host Adapter structure for "S" and "A" series
1557 MultiMaster Host Adapters.
1559 if (HostAdapter->FirmwareVersion[0] < '4') {
1560 if (SetupInformation.SynchronousInitiationEnabled) {
1561 HostAdapter->SynchronousPermitted = 0xFF;
1562 if (HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus) {
1563 if (ExtendedSetupInformation.Misc.FastOnEISA)
1564 HostAdapter->FastPermitted = 0xFF;
1565 if (strcmp(HostAdapter->ModelName, "BT-757") == 0)
1566 HostAdapter->WidePermitted = 0xFF;
1569 HostAdapter->DisconnectPermitted = 0xFF;
1570 HostAdapter->ParityCheckingEnabled = SetupInformation.ParityCheckingEnabled;
1571 HostAdapter->BusResetEnabled = true;
1574 Determine the maximum number of Target IDs and Logical Units supported by
1575 this driver for Wide and Narrow Host Adapters.
1577 HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1578 HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8);
1580 Select appropriate values for the Mailbox Count, Driver Queue Depth,
1581 Initial CCBs, and Incremental CCBs variables based on whether or not Strict
1582 Round Robin Mode is supported. If Strict Round Robin Mode is supported,
1583 then there is no performance degradation in using the maximum possible
1584 number of Outgoing and Incoming Mailboxes and allowing the Tagged and
1585 Untagged Queue Depths to determine the actual utilization. If Strict Round
1586 Robin Mode is not supported, then the Host Adapter must scan all the
1587 Outgoing Mailboxes whenever an Outgoing Mailbox entry is made, which can
1588 cause a substantial performance penalty. The host adapters actually have
1589 room to store the following number of CCBs internally; that is, they can
1590 internally queue and manage this many active commands on the SCSI bus
1591 simultaneously. Performance measurements demonstrate that the Driver Queue
1592 Depth should be set to the Mailbox Count, rather than the Host Adapter
1593 Queue Depth (internal CCB capacity), as it is more efficient to have the
1594 queued commands waiting in Outgoing Mailboxes if necessary than to block
1595 the process in the higher levels of the SCSI Subsystem.
1597 192 BT-948/958/958D
1598 100 BT-946C/956C/956CD/747C/757C/757CD/445C
1599 50 BT-545C/540CF
1600 30 BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
1602 if (HostAdapter->FirmwareVersion[0] == '5')
1603 HostAdapter->HostAdapterQueueDepth = 192;
1604 else if (HostAdapter->FirmwareVersion[0] == '4')
1605 HostAdapter->HostAdapterQueueDepth = (HostAdapter->HostAdapterBusType != BusLogic_ISA_Bus ? 100 : 50);
1606 else
1607 HostAdapter->HostAdapterQueueDepth = 30;
1608 if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0) {
1609 HostAdapter->StrictRoundRobinModeSupport = true;
1610 HostAdapter->MailboxCount = BusLogic_MaxMailboxes;
1611 } else {
1612 HostAdapter->StrictRoundRobinModeSupport = false;
1613 HostAdapter->MailboxCount = 32;
1615 HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount;
1616 HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1617 HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1619 Tagged Queuing support is available and operates properly on all "W" series
1620 MultiMaster Host Adapters, on "C" series MultiMaster Host Adapters with
1621 firmware version 4.22 and above, and on "S" series MultiMaster Host
1622 Adapters with firmware version 3.35 and above.
1624 HostAdapter->TaggedQueuingPermitted = 0;
1625 switch (HostAdapter->FirmwareVersion[0]) {
1626 case '5':
1627 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1628 break;
1629 case '4':
1630 if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0)
1631 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1632 break;
1633 case '3':
1634 if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0)
1635 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1636 break;
1639 Determine the Host Adapter BIOS Address if the BIOS is enabled and
1640 save it in the Host Adapter structure. The BIOS is disabled if the
1641 BIOS_Address is 0.
1643 HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
1645 ISA Host Adapters require Bounce Buffers if there is more than 16MB memory.
1647 if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus && (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1648 HostAdapter->BounceBuffersRequired = true;
1650 BusLogic BT-445S Host Adapters prior to board revision E have a hardware
1651 bug whereby when the BIOS is enabled, transfers to/from the same address
1652 range the BIOS occupies modulo 16MB are handled incorrectly. Only properly
1653 functioning BT-445S Host Adapters have firmware version 3.37, so require
1654 that ISA Bounce Buffers be used for the buggy BT-445S models if there is
1655 more than 16MB memory.
1657 if (HostAdapter->BIOS_Address > 0 && strcmp(HostAdapter->ModelName, "BT-445S") == 0 && strcmp(HostAdapter->FirmwareVersion, "3.37") < 0 && (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1658 HostAdapter->BounceBuffersRequired = true;
1660 Initialize parameters common to MultiMaster and FlashPoint Host Adapters.
1662 Common:
1664 Initialize the Host Adapter Full Model Name from the Model Name.
1666 strcpy(HostAdapter->FullModelName, "BusLogic ");
1667 strcat(HostAdapter->FullModelName, HostAdapter->ModelName);
1669 Select an appropriate value for the Tagged Queue Depth either from a
1670 BusLogic Driver Options specification, or based on whether this Host
1671 Adapter requires that ISA Bounce Buffers be used. The Tagged Queue Depth
1672 is left at 0 for automatic determination in BusLogic_SelectQueueDepths.
1673 Initialize the Untagged Queue Depth.
1675 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) {
1676 unsigned char QueueDepth = 0;
1677 if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->QueueDepth[TargetID] > 0)
1678 QueueDepth = HostAdapter->DriverOptions->QueueDepth[TargetID];
1679 else if (HostAdapter->BounceBuffersRequired)
1680 QueueDepth = BusLogic_TaggedQueueDepthBB;
1681 HostAdapter->QueueDepth[TargetID] = QueueDepth;
1683 if (HostAdapter->BounceBuffersRequired)
1684 HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepthBB;
1685 else
1686 HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth;
1687 if (HostAdapter->DriverOptions != NULL)
1688 HostAdapter->CommonQueueDepth = HostAdapter->DriverOptions->CommonQueueDepth;
1689 if (HostAdapter->CommonQueueDepth > 0 && HostAdapter->CommonQueueDepth < HostAdapter->UntaggedQueueDepth)
1690 HostAdapter->UntaggedQueueDepth = HostAdapter->CommonQueueDepth;
1692 Tagged Queuing is only allowed if Disconnect/Reconnect is permitted.
1693 Therefore, mask the Tagged Queuing Permitted Default bits with the
1694 Disconnect/Reconnect Permitted bits.
1696 HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted;
1698 Combine the default Tagged Queuing Permitted bits with any BusLogic Driver
1699 Options Tagged Queuing specification.
1701 if (HostAdapter->DriverOptions != NULL)
1702 HostAdapter->TaggedQueuingPermitted =
1703 (HostAdapter->DriverOptions->TaggedQueuingPermitted & HostAdapter->DriverOptions->TaggedQueuingPermittedMask) | (HostAdapter->TaggedQueuingPermitted & ~HostAdapter->DriverOptions->TaggedQueuingPermittedMask);
1706 Select an appropriate value for Bus Settle Time either from a BusLogic
1707 Driver Options specification, or from BusLogic_DefaultBusSettleTime.
1709 if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->BusSettleTime > 0)
1710 HostAdapter->BusSettleTime = HostAdapter->DriverOptions->BusSettleTime;
1711 else
1712 HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
1714 Indicate reading the Host Adapter Configuration completed successfully.
1716 return true;
1721 BusLogic_ReportHostAdapterConfiguration reports the configuration of
1722 Host Adapter.
1725 static boolean __init BusLogic_ReportHostAdapterConfiguration(struct BusLogic_HostAdapter
1726 *HostAdapter)
1728 unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1;
1729 unsigned short SynchronousPermitted, FastPermitted;
1730 unsigned short UltraPermitted, WidePermitted;
1731 unsigned short DisconnectPermitted, TaggedQueuingPermitted;
1732 boolean CommonSynchronousNegotiation, CommonTaggedQueueDepth;
1733 char SynchronousString[BusLogic_MaxTargetDevices + 1];
1734 char WideString[BusLogic_MaxTargetDevices + 1];
1735 char DisconnectString[BusLogic_MaxTargetDevices + 1];
1736 char TaggedQueuingString[BusLogic_MaxTargetDevices + 1];
1737 char *SynchronousMessage = SynchronousString;
1738 char *WideMessage = WideString;
1739 char *DisconnectMessage = DisconnectString;
1740 char *TaggedQueuingMessage = TaggedQueuingString;
1741 int TargetID;
1742 BusLogic_Info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n",
1743 HostAdapter, HostAdapter->ModelName,
1744 BusLogic_HostAdapterBusNames[HostAdapter->HostAdapterBusType], (HostAdapter->HostWideSCSI ? " Wide" : ""), (HostAdapter->HostDifferentialSCSI ? " Differential" : ""), (HostAdapter->HostUltraSCSI ? " Ultra" : ""));
1745 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"));
1746 if (HostAdapter->HostAdapterBusType != BusLogic_PCI_Bus) {
1747 BusLogic_Info(" DMA Channel: ", HostAdapter);
1748 if (HostAdapter->DMA_Channel > 0)
1749 BusLogic_Info("%d, ", HostAdapter, HostAdapter->DMA_Channel);
1750 else
1751 BusLogic_Info("None, ", HostAdapter);
1752 if (HostAdapter->BIOS_Address > 0)
1753 BusLogic_Info("BIOS Address: 0x%X, ", HostAdapter, HostAdapter->BIOS_Address);
1754 else
1755 BusLogic_Info("BIOS Address: None, ", HostAdapter);
1756 } else {
1757 BusLogic_Info(" PCI Bus: %d, Device: %d, Address: ", HostAdapter, HostAdapter->Bus, HostAdapter->Device);
1758 if (HostAdapter->PCI_Address > 0)
1759 BusLogic_Info("0x%X, ", HostAdapter, HostAdapter->PCI_Address);
1760 else
1761 BusLogic_Info("Unassigned, ", HostAdapter);
1763 BusLogic_Info("Host Adapter SCSI ID: %d\n", HostAdapter, HostAdapter->SCSI_ID);
1764 BusLogic_Info(" Parity Checking: %s, Extended Translation: %s\n", HostAdapter, (HostAdapter->ParityCheckingEnabled ? "Enabled" : "Disabled"), (HostAdapter->ExtendedTranslationEnabled ? "Enabled" : "Disabled"));
1765 AllTargetsMask &= ~(1 << HostAdapter->SCSI_ID);
1766 SynchronousPermitted = HostAdapter->SynchronousPermitted & AllTargetsMask;
1767 FastPermitted = HostAdapter->FastPermitted & AllTargetsMask;
1768 UltraPermitted = HostAdapter->UltraPermitted & AllTargetsMask;
1769 if ((BusLogic_MultiMasterHostAdapterP(HostAdapter) && (HostAdapter->FirmwareVersion[0] >= '4' || HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)) || BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1770 CommonSynchronousNegotiation = false;
1771 if (SynchronousPermitted == 0) {
1772 SynchronousMessage = "Disabled";
1773 CommonSynchronousNegotiation = true;
1774 } else if (SynchronousPermitted == AllTargetsMask) {
1775 if (FastPermitted == 0) {
1776 SynchronousMessage = "Slow";
1777 CommonSynchronousNegotiation = true;
1778 } else if (FastPermitted == AllTargetsMask) {
1779 if (UltraPermitted == 0) {
1780 SynchronousMessage = "Fast";
1781 CommonSynchronousNegotiation = true;
1782 } else if (UltraPermitted == AllTargetsMask) {
1783 SynchronousMessage = "Ultra";
1784 CommonSynchronousNegotiation = true;
1788 if (!CommonSynchronousNegotiation) {
1789 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1790 SynchronousString[TargetID] = ((!(SynchronousPermitted & (1 << TargetID))) ? 'N' : (!(FastPermitted & (1 << TargetID)) ? 'S' : (!(UltraPermitted & (1 << TargetID)) ? 'F' : 'U')));
1791 SynchronousString[HostAdapter->SCSI_ID] = '#';
1792 SynchronousString[HostAdapter->MaxTargetDevices] = '\0';
1794 } else
1795 SynchronousMessage = (SynchronousPermitted == 0 ? "Disabled" : "Enabled");
1796 WidePermitted = HostAdapter->WidePermitted & AllTargetsMask;
1797 if (WidePermitted == 0)
1798 WideMessage = "Disabled";
1799 else if (WidePermitted == AllTargetsMask)
1800 WideMessage = "Enabled";
1801 else {
1802 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1803 WideString[TargetID] = ((WidePermitted & (1 << TargetID)) ? 'Y' : 'N');
1804 WideString[HostAdapter->SCSI_ID] = '#';
1805 WideString[HostAdapter->MaxTargetDevices] = '\0';
1807 DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
1808 if (DisconnectPermitted == 0)
1809 DisconnectMessage = "Disabled";
1810 else if (DisconnectPermitted == AllTargetsMask)
1811 DisconnectMessage = "Enabled";
1812 else {
1813 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1814 DisconnectString[TargetID] = ((DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
1815 DisconnectString[HostAdapter->SCSI_ID] = '#';
1816 DisconnectString[HostAdapter->MaxTargetDevices] = '\0';
1818 TaggedQueuingPermitted = HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
1819 if (TaggedQueuingPermitted == 0)
1820 TaggedQueuingMessage = "Disabled";
1821 else if (TaggedQueuingPermitted == AllTargetsMask)
1822 TaggedQueuingMessage = "Enabled";
1823 else {
1824 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1825 TaggedQueuingString[TargetID] = ((TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
1826 TaggedQueuingString[HostAdapter->SCSI_ID] = '#';
1827 TaggedQueuingString[HostAdapter->MaxTargetDevices] = '\0';
1829 BusLogic_Info(" Synchronous Negotiation: %s, Wide Negotiation: %s\n", HostAdapter, SynchronousMessage, WideMessage);
1830 BusLogic_Info(" Disconnect/Reconnect: %s, Tagged Queuing: %s\n", HostAdapter, DisconnectMessage, TaggedQueuingMessage);
1831 if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
1832 BusLogic_Info(" Scatter/Gather Limit: %d of %d segments, " "Mailboxes: %d\n", HostAdapter, HostAdapter->DriverScatterGatherLimit, HostAdapter->HostAdapterScatterGatherLimit, HostAdapter->MailboxCount);
1833 BusLogic_Info(" Driver Queue Depth: %d, " "Host Adapter Queue Depth: %d\n", HostAdapter, HostAdapter->DriverQueueDepth, HostAdapter->HostAdapterQueueDepth);
1834 } else
1835 BusLogic_Info(" Driver Queue Depth: %d, " "Scatter/Gather Limit: %d segments\n", HostAdapter, HostAdapter->DriverQueueDepth, HostAdapter->DriverScatterGatherLimit);
1836 BusLogic_Info(" Tagged Queue Depth: ", HostAdapter);
1837 CommonTaggedQueueDepth = true;
1838 for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1839 if (HostAdapter->QueueDepth[TargetID] != HostAdapter->QueueDepth[0]) {
1840 CommonTaggedQueueDepth = false;
1841 break;
1843 if (CommonTaggedQueueDepth) {
1844 if (HostAdapter->QueueDepth[0] > 0)
1845 BusLogic_Info("%d", HostAdapter, HostAdapter->QueueDepth[0]);
1846 else
1847 BusLogic_Info("Automatic", HostAdapter);
1848 } else
1849 BusLogic_Info("Individual", HostAdapter);
1850 BusLogic_Info(", Untagged Queue Depth: %d\n", HostAdapter, HostAdapter->UntaggedQueueDepth);
1851 if (HostAdapter->TerminationInfoValid) {
1852 if (HostAdapter->HostWideSCSI)
1853 BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter, (HostAdapter->LowByteTerminated ? (HostAdapter->HighByteTerminated ? "Both Enabled" : "Low Enabled")
1854 : (HostAdapter->HighByteTerminated ? "High Enabled" : "Both Disabled")));
1855 else
1856 BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter, (HostAdapter->LowByteTerminated ? "Enabled" : "Disabled"));
1857 if (HostAdapter->HostSupportsSCAM)
1858 BusLogic_Info(", SCAM: %s", HostAdapter, (HostAdapter->SCAM_Enabled ? (HostAdapter->SCAM_Level2 ? "Enabled, Level 2" : "Enabled, Level 1")
1859 : "Disabled"));
1860 BusLogic_Info("\n", HostAdapter);
1863 Indicate reporting the Host Adapter configuration completed successfully.
1865 return true;
1870 BusLogic_AcquireResources acquires the system resources necessary to use
1871 Host Adapter.
1874 static boolean __init BusLogic_AcquireResources(struct BusLogic_HostAdapter *HostAdapter)
1876 if (HostAdapter->IRQ_Channel == 0) {
1877 BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n", HostAdapter);
1878 return false;
1881 Acquire shared access to the IRQ Channel.
1883 if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler, SA_SHIRQ, HostAdapter->FullModelName, HostAdapter) < 0) {
1884 BusLogic_Error("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n", HostAdapter, HostAdapter->IRQ_Channel);
1885 return false;
1887 HostAdapter->IRQ_ChannelAcquired = true;
1889 Acquire exclusive access to the DMA Channel.
1891 if (HostAdapter->DMA_Channel > 0) {
1892 if (request_dma(HostAdapter->DMA_Channel, HostAdapter->FullModelName) < 0) {
1893 BusLogic_Error("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n", HostAdapter, HostAdapter->DMA_Channel);
1894 return false;
1896 set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
1897 enable_dma(HostAdapter->DMA_Channel);
1898 HostAdapter->DMA_ChannelAcquired = true;
1901 Indicate the System Resource Acquisition completed successfully,
1903 return true;
1908 BusLogic_ReleaseResources releases any system resources previously acquired
1909 by BusLogic_AcquireResources.
1912 static void BusLogic_ReleaseResources(struct BusLogic_HostAdapter *HostAdapter)
1915 Release shared access to the IRQ Channel.
1917 if (HostAdapter->IRQ_ChannelAcquired)
1918 free_irq(HostAdapter->IRQ_Channel, HostAdapter);
1920 Release exclusive access to the DMA Channel.
1922 if (HostAdapter->DMA_ChannelAcquired)
1923 free_dma(HostAdapter->DMA_Channel);
1925 Release any allocated memory structs not released elsewhere
1927 if (HostAdapter->MailboxSpace)
1928 pci_free_consistent(HostAdapter->PCI_Device, HostAdapter->MailboxSize, HostAdapter->MailboxSpace, HostAdapter->MailboxSpaceHandle);
1929 HostAdapter->MailboxSpace = NULL;
1930 HostAdapter->MailboxSpaceHandle = 0;
1931 HostAdapter->MailboxSize = 0;
1936 BusLogic_InitializeHostAdapter initializes Host Adapter. This is the only
1937 function called during SCSI Host Adapter detection which modifies the state
1938 of the Host Adapter from its initial power on or hard reset state.
1941 static boolean BusLogic_InitializeHostAdapter(struct BusLogic_HostAdapter
1942 *HostAdapter)
1944 struct BusLogic_ExtendedMailboxRequest ExtendedMailboxRequest;
1945 enum BusLogic_RoundRobinModeRequest RoundRobinModeRequest;
1946 enum BusLogic_SetCCBFormatRequest SetCCBFormatRequest;
1947 int TargetID;
1949 Initialize the pointers to the first and last CCBs that are queued for
1950 completion processing.
1952 HostAdapter->FirstCompletedCCB = NULL;
1953 HostAdapter->LastCompletedCCB = NULL;
1955 Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active,
1956 Command Successful Flag, Active Commands, and Commands Since Reset
1957 for each Target Device.
1959 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
1960 HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
1961 HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
1962 HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
1963 HostAdapter->ActiveCommands[TargetID] = 0;
1964 HostAdapter->CommandsSinceReset[TargetID] = 0;
1967 FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes.
1969 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1970 goto Done;
1972 Initialize the Outgoing and Incoming Mailbox pointers.
1974 HostAdapter->MailboxSize = HostAdapter->MailboxCount * (sizeof(struct BusLogic_OutgoingMailbox) + sizeof(struct BusLogic_IncomingMailbox));
1975 HostAdapter->MailboxSpace = pci_alloc_consistent(HostAdapter->PCI_Device, HostAdapter->MailboxSize, &HostAdapter->MailboxSpaceHandle);
1976 if (HostAdapter->MailboxSpace == NULL)
1977 return BusLogic_Failure(HostAdapter, "MAILBOX ALLOCATION");
1978 HostAdapter->FirstOutgoingMailbox = (struct BusLogic_OutgoingMailbox *) HostAdapter->MailboxSpace;
1979 HostAdapter->LastOutgoingMailbox = HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1;
1980 HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
1981 HostAdapter->FirstIncomingMailbox = (struct BusLogic_IncomingMailbox *) (HostAdapter->LastOutgoingMailbox + 1);
1982 HostAdapter->LastIncomingMailbox = HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1;
1983 HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
1986 Initialize the Outgoing and Incoming Mailbox structures.
1988 memset(HostAdapter->FirstOutgoingMailbox, 0, HostAdapter->MailboxCount * sizeof(struct BusLogic_OutgoingMailbox));
1989 memset(HostAdapter->FirstIncomingMailbox, 0, HostAdapter->MailboxCount * sizeof(struct BusLogic_IncomingMailbox));
1991 Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes.
1993 ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount;
1994 ExtendedMailboxRequest.BaseMailboxAddress = (u32) HostAdapter->MailboxSpaceHandle;
1995 if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox, &ExtendedMailboxRequest, sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
1996 return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION");
1998 Enable Strict Round Robin Mode if supported by the Host Adapter. In
1999 Strict Round Robin Mode, the Host Adapter only looks at the next Outgoing
2000 Mailbox for each new command, rather than scanning through all the
2001 Outgoing Mailboxes to find any that have new commands in them. Strict
2002 Round Robin Mode is significantly more efficient.
2004 if (HostAdapter->StrictRoundRobinModeSupport) {
2005 RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
2006 if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode, &RoundRobinModeRequest, sizeof(RoundRobinModeRequest), NULL, 0) < 0)
2007 return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
2010 For Host Adapters that support Extended LUN Format CCBs, issue the Set CCB
2011 Format command to allow 32 Logical Units per Target Device.
2013 if (HostAdapter->ExtendedLUNSupport) {
2014 SetCCBFormatRequest = BusLogic_ExtendedLUNFormatCCB;
2015 if (BusLogic_Command(HostAdapter, BusLogic_SetCCBFormat, &SetCCBFormatRequest, sizeof(SetCCBFormatRequest), NULL, 0) < 0)
2016 return BusLogic_Failure(HostAdapter, "SET CCB FORMAT");
2019 Announce Successful Initialization.
2021 Done:
2022 if (!HostAdapter->HostAdapterInitialized) {
2023 BusLogic_Info("*** %s Initialized Successfully ***\n", HostAdapter, HostAdapter->FullModelName);
2024 BusLogic_Info("\n", HostAdapter);
2025 } else
2026 BusLogic_Warning("*** %s Initialized Successfully ***\n", HostAdapter, HostAdapter->FullModelName);
2027 HostAdapter->HostAdapterInitialized = true;
2029 Indicate the Host Adapter Initialization completed successfully.
2031 return true;
2036 BusLogic_TargetDeviceInquiry inquires about the Target Devices accessible
2037 through Host Adapter.
2040 static boolean __init BusLogic_TargetDeviceInquiry(struct BusLogic_HostAdapter
2041 *HostAdapter)
2043 u16 InstalledDevices;
2044 u8 InstalledDevicesID0to7[8];
2045 struct BusLogic_SetupInformation SetupInformation;
2046 u8 SynchronousPeriod[BusLogic_MaxTargetDevices];
2047 unsigned char RequestedReplyLength;
2048 int TargetID;
2050 Wait a few seconds between the Host Adapter Hard Reset which initiates
2051 a SCSI Bus Reset and issuing any SCSI Commands. Some SCSI devices get
2052 confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
2054 BusLogic_Delay(HostAdapter->BusSettleTime);
2056 FlashPoint Host Adapters do not provide for Target Device Inquiry.
2058 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
2059 return true;
2061 Inhibit the Target Device Inquiry if requested.
2063 if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
2064 return true;
2066 Issue the Inquire Target Devices command for host adapters with firmware
2067 version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command
2068 for older host adapters. This is necessary to force Synchronous Transfer
2069 Negotiation so that the Inquire Setup Information and Inquire Synchronous
2070 Period commands will return valid data. The Inquire Target Devices command
2071 is preferable to Inquire Installed Devices ID 0 to 7 since it only probes
2072 Logical Unit 0 of each Target Device.
2074 if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0) {
2077 * Issue a Inquire Target Devices command. Inquire Target Devices only
2078 * tests Logical Unit 0 of each Target Device unlike the Inquire Installed
2079 * Devices commands which test Logical Units 0 - 7. Two bytes are
2080 * returned, where byte 0 bit 0 set indicates that Target Device 0 exists,
2081 * and so on.
2084 if (BusLogic_Command(HostAdapter, BusLogic_InquireTargetDevices, NULL, 0, &InstalledDevices, sizeof(InstalledDevices))
2085 != sizeof(InstalledDevices))
2086 return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES");
2087 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2088 HostAdapter->TargetFlags[TargetID].TargetExists = (InstalledDevices & (1 << TargetID) ? true : false);
2089 } else {
2092 * Issue an Inquire Installed Devices command. For each Target Device,
2093 * a byte is returned where bit 0 set indicates that Logical Unit 0
2094 * exists, bit 1 set indicates that Logical Unit 1 exists, and so on.
2097 if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7, NULL, 0, &InstalledDevicesID0to7, sizeof(InstalledDevicesID0to7))
2098 != sizeof(InstalledDevicesID0to7))
2099 return BusLogic_Failure(HostAdapter, "INQUIRE INSTALLED DEVICES ID 0 TO 7");
2100 for (TargetID = 0; TargetID < 8; TargetID++)
2101 HostAdapter->TargetFlags[TargetID].TargetExists = (InstalledDevicesID0to7[TargetID] != 0 ? true : false);
2104 Issue the Inquire Setup Information command.
2106 RequestedReplyLength = sizeof(SetupInformation);
2107 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &SetupInformation, sizeof(SetupInformation))
2108 != sizeof(SetupInformation))
2109 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
2110 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2111 HostAdapter->SynchronousOffset[TargetID] = (TargetID < 8 ? SetupInformation.SynchronousValuesID0to7[TargetID].Offset : SetupInformation.SynchronousValuesID8to15[TargetID - 8].Offset);
2112 if (strcmp(HostAdapter->FirmwareVersion, "5.06L") >= 0)
2113 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2114 HostAdapter->TargetFlags[TargetID].WideTransfersActive = (TargetID < 8 ? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID)
2115 ? true : false)
2116 : (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID - 8))
2117 ? true : false));
2119 Issue the Inquire Synchronous Period command.
2121 if (HostAdapter->FirmwareVersion[0] >= '3') {
2123 /* Issue a Inquire Synchronous Period command. For each Target Device,
2124 * a byte is returned which represents the Synchronous Transfer Period
2125 * in units of 10 nanoseconds.
2128 RequestedReplyLength = sizeof(SynchronousPeriod);
2129 if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod, &RequestedReplyLength, sizeof(RequestedReplyLength), &SynchronousPeriod, sizeof(SynchronousPeriod))
2130 != sizeof(SynchronousPeriod))
2131 return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
2132 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2133 HostAdapter->SynchronousPeriod[TargetID] = SynchronousPeriod[TargetID];
2134 } else
2135 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2136 if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
2137 HostAdapter->SynchronousPeriod[TargetID] = 20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
2138 .TransferPeriod;
2140 Indicate the Target Device Inquiry completed successfully.
2142 return true;
2146 BusLogic_InitializeHostStructure initializes the fields in the SCSI Host
2147 structure. The base, io_port, n_io_ports, irq, and dma_channel fields in the
2148 SCSI Host structure are intentionally left uninitialized, as this driver
2149 handles acquisition and release of these resources explicitly, as well as
2150 ensuring exclusive access to the Host Adapter hardware and data structures
2151 through explicit acquisition and release of the Host Adapter's Lock.
2154 static void __init BusLogic_InitializeHostStructure(struct BusLogic_HostAdapter
2155 *HostAdapter, struct Scsi_Host *Host)
2157 Host->max_id = HostAdapter->MaxTargetDevices;
2158 Host->max_lun = HostAdapter->MaxLogicalUnits;
2159 Host->max_channel = 0;
2160 Host->unique_id = HostAdapter->IO_Address;
2161 Host->this_id = HostAdapter->SCSI_ID;
2162 Host->can_queue = HostAdapter->DriverQueueDepth;
2163 Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
2164 Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
2165 Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth;
2169 BusLogic_SlaveConfigure will actually set the queue depth on individual
2170 scsi devices as they are permanently added to the device chain. We
2171 shamelessly rip off the SelectQueueDepths code to make this work mostly
2172 like it used to. Since we don't get called once at the end of the scan
2173 but instead get called for each device, we have to do things a bit
2174 differently.
2176 static int BusLogic_SlaveConfigure(struct scsi_device *Device)
2178 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Device->host->hostdata;
2179 int TargetID = Device->id;
2180 int QueueDepth = HostAdapter->QueueDepth[TargetID];
2182 if (HostAdapter->TargetFlags[TargetID].TaggedQueuingSupported && (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) {
2183 if (QueueDepth == 0)
2184 QueueDepth = BusLogic_MaxAutomaticTaggedQueueDepth;
2185 HostAdapter->QueueDepth[TargetID] = QueueDepth;
2186 scsi_adjust_queue_depth(Device, MSG_SIMPLE_TAG, QueueDepth);
2187 } else {
2188 HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
2189 QueueDepth = HostAdapter->UntaggedQueueDepth;
2190 HostAdapter->QueueDepth[TargetID] = QueueDepth;
2191 scsi_adjust_queue_depth(Device, 0, QueueDepth);
2193 QueueDepth = 0;
2194 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2195 if (HostAdapter->TargetFlags[TargetID].TargetExists) {
2196 QueueDepth += HostAdapter->QueueDepth[TargetID];
2198 if (QueueDepth > HostAdapter->AllocatedCCBs)
2199 BusLogic_CreateAdditionalCCBs(HostAdapter, QueueDepth - HostAdapter->AllocatedCCBs, false);
2200 return 0;
2204 BusLogic_DetectHostAdapter probes for BusLogic Host Adapters at the standard
2205 I/O Addresses where they may be located, initializing, registering, and
2206 reporting the configuration of each BusLogic Host Adapter it finds. It
2207 returns the number of BusLogic Host Adapters successfully initialized and
2208 registered.
2211 static int __init BusLogic_DetectHostAdapter(struct scsi_host_template *HostTemplate)
2213 int BusLogicHostAdapterCount = 0, DriverOptionsIndex = 0, ProbeIndex;
2214 struct BusLogic_HostAdapter *PrototypeHostAdapter;
2215 if (BusLogic_ProbeOptions.NoProbe)
2216 return 0;
2217 BusLogic_ProbeInfoList = (struct BusLogic_ProbeInfo *)
2218 kmalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo), GFP_ATOMIC);
2219 if (BusLogic_ProbeInfoList == NULL) {
2220 BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL);
2221 return 0;
2223 memset(BusLogic_ProbeInfoList, 0, BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo));
2224 PrototypeHostAdapter = (struct BusLogic_HostAdapter *)
2225 kmalloc(sizeof(struct BusLogic_HostAdapter), GFP_ATOMIC);
2226 if (PrototypeHostAdapter == NULL) {
2227 kfree(BusLogic_ProbeInfoList);
2228 BusLogic_Error("BusLogic: Unable to allocate Prototype " "Host Adapter\n", NULL);
2229 return 0;
2231 memset(PrototypeHostAdapter, 0, sizeof(struct BusLogic_HostAdapter));
2232 #ifdef MODULE
2233 if (BusLogic != NULL)
2234 BusLogic_Setup(BusLogic);
2235 #endif
2236 BusLogic_InitializeProbeInfoList(PrototypeHostAdapter);
2237 for (ProbeIndex = 0; ProbeIndex < BusLogic_ProbeInfoCount; ProbeIndex++) {
2238 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[ProbeIndex];
2239 struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter;
2240 struct Scsi_Host *Host;
2241 if (ProbeInfo->IO_Address == 0)
2242 continue;
2243 memset(HostAdapter, 0, sizeof(struct BusLogic_HostAdapter));
2244 HostAdapter->HostAdapterType = ProbeInfo->HostAdapterType;
2245 HostAdapter->HostAdapterBusType = ProbeInfo->HostAdapterBusType;
2246 HostAdapter->IO_Address = ProbeInfo->IO_Address;
2247 HostAdapter->PCI_Address = ProbeInfo->PCI_Address;
2248 HostAdapter->Bus = ProbeInfo->Bus;
2249 HostAdapter->Device = ProbeInfo->Device;
2250 HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel;
2251 HostAdapter->AddressCount = BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType];
2253 Probe the Host Adapter. If unsuccessful, abort further initialization.
2255 if (!BusLogic_ProbeHostAdapter(HostAdapter))
2256 continue;
2258 Hard Reset the Host Adapter. If unsuccessful, abort further
2259 initialization.
2261 if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true))
2262 continue;
2264 Check the Host Adapter. If unsuccessful, abort further initialization.
2266 if (!BusLogic_CheckHostAdapter(HostAdapter))
2267 continue;
2269 Initialize the Driver Options field if provided.
2271 if (DriverOptionsIndex < BusLogic_DriverOptionsCount)
2272 HostAdapter->DriverOptions = &BusLogic_DriverOptions[DriverOptionsIndex++];
2274 Announce the Driver Version and Date, Author's Name, Copyright Notice,
2275 and Electronic Mail Address.
2277 BusLogic_AnnounceDriver(HostAdapter);
2279 Register usage of the I/O Address range. From this point onward, any
2280 failure will be assumed to be due to a problem with the Host Adapter,
2281 rather than due to having mistakenly identified this port as belonging
2282 to a BusLogic Host Adapter. The I/O Address range will not be
2283 released, thereby preventing it from being incorrectly identified as
2284 any other type of Host Adapter.
2286 if (!request_region(HostAdapter->IO_Address, HostAdapter->AddressCount, "BusLogic"))
2287 continue;
2289 Register the SCSI Host structure.
2292 Host = scsi_host_alloc(HostTemplate, sizeof(struct BusLogic_HostAdapter));
2293 if (Host == NULL) {
2294 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2295 continue;
2297 HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata;
2298 memcpy(HostAdapter, PrototypeHostAdapter, sizeof(struct BusLogic_HostAdapter));
2299 HostAdapter->SCSI_Host = Host;
2300 HostAdapter->HostNumber = Host->host_no;
2302 Add Host Adapter to the end of the list of registered BusLogic
2303 Host Adapters.
2305 BusLogic_RegisterHostAdapter(HostAdapter);
2307 Read the Host Adapter Configuration, Configure the Host Adapter,
2308 Acquire the System Resources necessary to use the Host Adapter, then
2309 Create the Initial CCBs, Initialize the Host Adapter, and finally
2310 perform Target Device Inquiry.
2312 if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
2313 BusLogic_ReportHostAdapterConfiguration(HostAdapter) && BusLogic_AcquireResources(HostAdapter) && BusLogic_CreateInitialCCBs(HostAdapter) && BusLogic_InitializeHostAdapter(HostAdapter) && BusLogic_TargetDeviceInquiry(HostAdapter)) {
2315 Initialization has been completed successfully. Release and
2316 re-register usage of the I/O Address range so that the Model
2317 Name of the Host Adapter will appear, and initialize the SCSI
2318 Host structure.
2320 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2321 if (!request_region(HostAdapter->IO_Address, HostAdapter->AddressCount, HostAdapter->FullModelName)) {
2322 printk(KERN_WARNING "BusLogic: Release and re-register of " "port 0x%04lx failed \n", (unsigned long) HostAdapter->IO_Address);
2323 BusLogic_DestroyCCBs(HostAdapter);
2324 BusLogic_ReleaseResources(HostAdapter);
2325 BusLogic_UnregisterHostAdapter(HostAdapter);
2326 scsi_host_put(Host);
2327 } else {
2328 BusLogic_InitializeHostStructure(HostAdapter, Host);
2329 scsi_add_host(Host, NULL);
2330 scsi_scan_host(Host);
2331 BusLogicHostAdapterCount++;
2333 } else {
2335 An error occurred during Host Adapter Configuration Querying, Host
2336 Adapter Configuration, Resource Acquisition, CCB Creation, Host
2337 Adapter Initialization, or Target Device Inquiry, so remove Host
2338 Adapter from the list of registered BusLogic Host Adapters, destroy
2339 the CCBs, Release the System Resources, and Unregister the SCSI
2340 Host.
2342 BusLogic_DestroyCCBs(HostAdapter);
2343 BusLogic_ReleaseResources(HostAdapter);
2344 BusLogic_UnregisterHostAdapter(HostAdapter);
2345 scsi_host_put(Host);
2348 kfree(PrototypeHostAdapter);
2349 kfree(BusLogic_ProbeInfoList);
2350 BusLogic_ProbeInfoList = NULL;
2351 return BusLogicHostAdapterCount;
2356 BusLogic_ReleaseHostAdapter releases all resources previously acquired to
2357 support a specific Host Adapter, including the I/O Address range, and
2358 unregisters the BusLogic Host Adapter.
2361 static int __exit BusLogic_ReleaseHostAdapter(struct Scsi_Host *Host)
2363 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata;
2365 FlashPoint Host Adapters must first be released by the FlashPoint
2366 SCCB Manager.
2368 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
2369 FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle);
2371 Destroy the CCBs and release any system resources acquired to
2372 support Host Adapter.
2374 BusLogic_DestroyCCBs(HostAdapter);
2375 BusLogic_ReleaseResources(HostAdapter);
2377 Release usage of the I/O Address range.
2379 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2381 Remove Host Adapter from the list of registered BusLogic Host Adapters.
2383 BusLogic_UnregisterHostAdapter(HostAdapter);
2384 return 0;
2389 BusLogic_QueueCompletedCCB queues CCB for completion processing.
2392 static void BusLogic_QueueCompletedCCB(struct BusLogic_CCB *CCB)
2394 struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter;
2395 CCB->Status = BusLogic_CCB_Completed;
2396 CCB->Next = NULL;
2397 if (HostAdapter->FirstCompletedCCB == NULL) {
2398 HostAdapter->FirstCompletedCCB = CCB;
2399 HostAdapter->LastCompletedCCB = CCB;
2400 } else {
2401 HostAdapter->LastCompletedCCB->Next = CCB;
2402 HostAdapter->LastCompletedCCB = CCB;
2404 HostAdapter->ActiveCommands[CCB->TargetID]--;
2409 BusLogic_ComputeResultCode computes a SCSI Subsystem Result Code from
2410 the Host Adapter Status and Target Device Status.
2413 static int BusLogic_ComputeResultCode(struct BusLogic_HostAdapter *HostAdapter, enum BusLogic_HostAdapterStatus HostAdapterStatus, enum BusLogic_TargetDeviceStatus TargetDeviceStatus)
2415 int HostStatus;
2416 switch (HostAdapterStatus) {
2417 case BusLogic_CommandCompletedNormally:
2418 case BusLogic_LinkedCommandCompleted:
2419 case BusLogic_LinkedCommandCompletedWithFlag:
2420 HostStatus = DID_OK;
2421 break;
2422 case BusLogic_SCSISelectionTimeout:
2423 HostStatus = DID_TIME_OUT;
2424 break;
2425 case BusLogic_InvalidOutgoingMailboxActionCode:
2426 case BusLogic_InvalidCommandOperationCode:
2427 case BusLogic_InvalidCommandParameter:
2428 BusLogic_Warning("BusLogic Driver Protocol Error 0x%02X\n", HostAdapter, HostAdapterStatus);
2429 case BusLogic_DataUnderRun:
2430 case BusLogic_DataOverRun:
2431 case BusLogic_UnexpectedBusFree:
2432 case BusLogic_LinkedCCBhasInvalidLUN:
2433 case BusLogic_AutoRequestSenseFailed:
2434 case BusLogic_TaggedQueuingMessageRejected:
2435 case BusLogic_UnsupportedMessageReceived:
2436 case BusLogic_HostAdapterHardwareFailed:
2437 case BusLogic_TargetDeviceReconnectedImproperly:
2438 case BusLogic_AbortQueueGenerated:
2439 case BusLogic_HostAdapterSoftwareError:
2440 case BusLogic_HostAdapterHardwareTimeoutError:
2441 case BusLogic_SCSIParityErrorDetected:
2442 HostStatus = DID_ERROR;
2443 break;
2444 case BusLogic_InvalidBusPhaseRequested:
2445 case BusLogic_TargetFailedResponseToATN:
2446 case BusLogic_HostAdapterAssertedRST:
2447 case BusLogic_OtherDeviceAssertedRST:
2448 case BusLogic_HostAdapterAssertedBusDeviceReset:
2449 HostStatus = DID_RESET;
2450 break;
2451 default:
2452 BusLogic_Warning("Unknown Host Adapter Status 0x%02X\n", HostAdapter, HostAdapterStatus);
2453 HostStatus = DID_ERROR;
2454 break;
2456 return (HostStatus << 16) | TargetDeviceStatus;
2461 BusLogic_ScanIncomingMailboxes scans the Incoming Mailboxes saving any
2462 Incoming Mailbox entries for completion processing.
2465 static void BusLogic_ScanIncomingMailboxes(struct BusLogic_HostAdapter *HostAdapter)
2468 Scan through the Incoming Mailboxes in Strict Round Robin fashion, saving
2469 any completed CCBs for further processing. It is essential that for each
2470 CCB and SCSI Command issued, command completion processing is performed
2471 exactly once. Therefore, only Incoming Mailboxes with completion code
2472 Command Completed Without Error, Command Completed With Error, or Command
2473 Aborted At Host Request are saved for completion processing. When an
2474 Incoming Mailbox has a completion code of Aborted Command Not Found, the
2475 CCB had already completed or been aborted before the current Abort request
2476 was processed, and so completion processing has already occurred and no
2477 further action should be taken.
2479 struct BusLogic_IncomingMailbox *NextIncomingMailbox = HostAdapter->NextIncomingMailbox;
2480 enum BusLogic_CompletionCode CompletionCode;
2481 while ((CompletionCode = NextIncomingMailbox->CompletionCode) != BusLogic_IncomingMailboxFree) {
2483 We are only allowed to do this because we limit our architectures we
2484 run on to machines where bus_to_virt() actually works. There *needs*
2485 to be a dma_addr_to_virt() in the new PCI DMA mapping interface to
2486 replace bus_to_virt() or else this code is going to become very
2487 innefficient.
2489 struct BusLogic_CCB *CCB = (struct BusLogic_CCB *) Bus_to_Virtual(NextIncomingMailbox->CCB);
2490 if (CompletionCode != BusLogic_AbortedCommandNotFound) {
2491 if (CCB->Status == BusLogic_CCB_Active || CCB->Status == BusLogic_CCB_Reset) {
2493 Save the Completion Code for this CCB and queue the CCB
2494 for completion processing.
2496 CCB->CompletionCode = CompletionCode;
2497 BusLogic_QueueCompletedCCB(CCB);
2498 } else {
2500 If a CCB ever appears in an Incoming Mailbox and is not marked
2501 as status Active or Reset, then there is most likely a bug in
2502 the Host Adapter firmware.
2504 BusLogic_Warning("Illegal CCB #%ld status %d in " "Incoming Mailbox\n", HostAdapter, CCB->SerialNumber, CCB->Status);
2507 NextIncomingMailbox->CompletionCode = BusLogic_IncomingMailboxFree;
2508 if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
2509 NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
2511 HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
2516 BusLogic_ProcessCompletedCCBs iterates over the completed CCBs for Host
2517 Adapter setting the SCSI Command Result Codes, deallocating the CCBs, and
2518 calling the SCSI Subsystem Completion Routines. The Host Adapter's Lock
2519 should already have been acquired by the caller.
2522 static void BusLogic_ProcessCompletedCCBs(struct BusLogic_HostAdapter *HostAdapter)
2524 if (HostAdapter->ProcessCompletedCCBsActive)
2525 return;
2526 HostAdapter->ProcessCompletedCCBsActive = true;
2527 while (HostAdapter->FirstCompletedCCB != NULL) {
2528 struct BusLogic_CCB *CCB = HostAdapter->FirstCompletedCCB;
2529 struct scsi_cmnd *Command = CCB->Command;
2530 HostAdapter->FirstCompletedCCB = CCB->Next;
2531 if (HostAdapter->FirstCompletedCCB == NULL)
2532 HostAdapter->LastCompletedCCB = NULL;
2534 Process the Completed CCB.
2536 if (CCB->Opcode == BusLogic_BusDeviceReset) {
2537 int TargetID = CCB->TargetID;
2538 BusLogic_Warning("Bus Device Reset CCB #%ld to Target " "%d Completed\n", HostAdapter, CCB->SerialNumber, TargetID);
2539 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].BusDeviceResetsCompleted);
2540 HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
2541 HostAdapter->CommandsSinceReset[TargetID] = 0;
2542 HostAdapter->LastResetCompleted[TargetID] = jiffies;
2544 Place CCB back on the Host Adapter's free list.
2546 BusLogic_DeallocateCCB(CCB);
2547 #if 0 /* this needs to be redone different for new EH */
2549 Bus Device Reset CCBs have the Command field non-NULL only when a
2550 Bus Device Reset was requested for a Command that did not have a
2551 currently active CCB in the Host Adapter (i.e., a Synchronous
2552 Bus Device Reset), and hence would not have its Completion Routine
2553 called otherwise.
2555 while (Command != NULL) {
2556 struct scsi_cmnd *NextCommand = Command->reset_chain;
2557 Command->reset_chain = NULL;
2558 Command->result = DID_RESET << 16;
2559 Command->scsi_done(Command);
2560 Command = NextCommand;
2562 #endif
2564 Iterate over the CCBs for this Host Adapter performing completion
2565 processing for any CCBs marked as Reset for this Target.
2567 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2568 if (CCB->Status == BusLogic_CCB_Reset && CCB->TargetID == TargetID) {
2569 Command = CCB->Command;
2570 BusLogic_DeallocateCCB(CCB);
2571 HostAdapter->ActiveCommands[TargetID]--;
2572 Command->result = DID_RESET << 16;
2573 Command->scsi_done(Command);
2575 HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
2576 } else {
2578 Translate the Completion Code, Host Adapter Status, and Target
2579 Device Status into a SCSI Subsystem Result Code.
2581 switch (CCB->CompletionCode) {
2582 case BusLogic_IncomingMailboxFree:
2583 case BusLogic_AbortedCommandNotFound:
2584 case BusLogic_InvalidCCB:
2585 BusLogic_Warning("CCB #%ld to Target %d Impossible State\n", HostAdapter, CCB->SerialNumber, CCB->TargetID);
2586 break;
2587 case BusLogic_CommandCompletedWithoutError:
2588 HostAdapter->TargetStatistics[CCB->TargetID]
2589 .CommandsCompleted++;
2590 HostAdapter->TargetFlags[CCB->TargetID]
2591 .CommandSuccessfulFlag = true;
2592 Command->result = DID_OK << 16;
2593 break;
2594 case BusLogic_CommandAbortedAtHostRequest:
2595 BusLogic_Warning("CCB #%ld to Target %d Aborted\n", HostAdapter, CCB->SerialNumber, CCB->TargetID);
2596 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[CCB->TargetID]
2597 .CommandAbortsCompleted);
2598 Command->result = DID_ABORT << 16;
2599 break;
2600 case BusLogic_CommandCompletedWithError:
2601 Command->result = BusLogic_ComputeResultCode(HostAdapter, CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
2602 if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout) {
2603 HostAdapter->TargetStatistics[CCB->TargetID]
2604 .CommandsCompleted++;
2605 if (BusLogic_GlobalOptions.TraceErrors) {
2606 int i;
2607 BusLogic_Notice("CCB #%ld Target %d: Result %X Host "
2608 "Adapter Status %02X " "Target Status %02X\n", HostAdapter, CCB->SerialNumber, CCB->TargetID, Command->result, CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
2609 BusLogic_Notice("CDB ", HostAdapter);
2610 for (i = 0; i < CCB->CDB_Length; i++)
2611 BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]);
2612 BusLogic_Notice("\n", HostAdapter);
2613 BusLogic_Notice("Sense ", HostAdapter);
2614 for (i = 0; i < CCB->SenseDataLength; i++)
2615 BusLogic_Notice(" %02X", HostAdapter, Command->sense_buffer[i]);
2616 BusLogic_Notice("\n", HostAdapter);
2619 break;
2622 When an INQUIRY command completes normally, save the
2623 CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit
2624 Wide Data Transfers Supported) bits.
2626 if (CCB->CDB[0] == INQUIRY && CCB->CDB[1] == 0 && CCB->HostAdapterStatus == BusLogic_CommandCompletedNormally) {
2627 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[CCB->TargetID];
2628 struct SCSI_Inquiry *InquiryResult = (struct SCSI_Inquiry *) Command->request_buffer;
2629 TargetFlags->TargetExists = true;
2630 TargetFlags->TaggedQueuingSupported = InquiryResult->CmdQue;
2631 TargetFlags->WideTransfersSupported = InquiryResult->WBus16;
2634 Place CCB back on the Host Adapter's free list.
2636 BusLogic_DeallocateCCB(CCB);
2638 Call the SCSI Command Completion Routine.
2640 Command->scsi_done(Command);
2643 HostAdapter->ProcessCompletedCCBsActive = false;
2648 BusLogic_InterruptHandler handles hardware interrupts from BusLogic Host
2649 Adapters.
2652 static irqreturn_t BusLogic_InterruptHandler(int IRQ_Channel, void *DeviceIdentifier, struct pt_regs *InterruptRegisters)
2654 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) DeviceIdentifier;
2655 unsigned long ProcessorFlags;
2657 Acquire exclusive access to Host Adapter.
2659 BusLogic_AcquireHostAdapterLockIH(HostAdapter, &ProcessorFlags);
2661 Handle Interrupts appropriately for each Host Adapter type.
2663 if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
2664 union BusLogic_InterruptRegister InterruptRegister;
2666 Read the Host Adapter Interrupt Register.
2668 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
2669 if (InterruptRegister.ir.InterruptValid) {
2671 Acknowledge the interrupt and reset the Host Adapter
2672 Interrupt Register.
2674 BusLogic_InterruptReset(HostAdapter);
2676 Process valid External SCSI Bus Reset and Incoming Mailbox
2677 Loaded Interrupts. Command Complete Interrupts are noted,
2678 and Outgoing Mailbox Available Interrupts are ignored, as
2679 they are never enabled.
2681 if (InterruptRegister.ir.ExternalBusReset)
2682 HostAdapter->HostAdapterExternalReset = true;
2683 else if (InterruptRegister.ir.IncomingMailboxLoaded)
2684 BusLogic_ScanIncomingMailboxes(HostAdapter);
2685 else if (InterruptRegister.ir.CommandComplete)
2686 HostAdapter->HostAdapterCommandCompleted = true;
2688 } else {
2690 Check if there is a pending interrupt for this Host Adapter.
2692 if (FlashPoint_InterruptPending(HostAdapter->CardHandle))
2693 switch (FlashPoint_HandleInterrupt(HostAdapter->CardHandle)) {
2694 case FlashPoint_NormalInterrupt:
2695 break;
2696 case FlashPoint_ExternalBusReset:
2697 HostAdapter->HostAdapterExternalReset = true;
2698 break;
2699 case FlashPoint_InternalError:
2700 BusLogic_Warning("Internal FlashPoint Error detected" " - Resetting Host Adapter\n", HostAdapter);
2701 HostAdapter->HostAdapterInternalError = true;
2702 break;
2706 Process any completed CCBs.
2708 if (HostAdapter->FirstCompletedCCB != NULL)
2709 BusLogic_ProcessCompletedCCBs(HostAdapter);
2711 Reset the Host Adapter if requested.
2713 if (HostAdapter->HostAdapterExternalReset) {
2714 BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n", HostAdapter, HostAdapter->FullModelName);
2715 BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets);
2716 BusLogic_ResetHostAdapter(HostAdapter, false);
2717 HostAdapter->HostAdapterExternalReset = false;
2718 } else if (HostAdapter->HostAdapterInternalError) {
2719 BusLogic_Warning("Resetting %s due to Host Adapter Internal Error\n", HostAdapter, HostAdapter->FullModelName);
2720 BusLogic_IncrementErrorCounter(&HostAdapter->HostAdapterInternalErrors);
2721 BusLogic_ResetHostAdapter(HostAdapter, true);
2722 HostAdapter->HostAdapterInternalError = false;
2725 Release exclusive access to Host Adapter.
2727 BusLogic_ReleaseHostAdapterLockIH(HostAdapter, &ProcessorFlags);
2728 return IRQ_HANDLED;
2733 BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
2734 Mailbox for execution by Host Adapter. The Host Adapter's Lock should
2735 already have been acquired by the caller.
2738 static boolean BusLogic_WriteOutgoingMailbox(struct BusLogic_HostAdapter
2739 *HostAdapter, enum BusLogic_ActionCode ActionCode, struct BusLogic_CCB *CCB)
2741 struct BusLogic_OutgoingMailbox *NextOutgoingMailbox;
2742 NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
2743 if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree) {
2744 CCB->Status = BusLogic_CCB_Active;
2746 The CCB field must be written before the Action Code field since
2747 the Host Adapter is operating asynchronously and the locking code
2748 does not protect against simultaneous access by the Host Adapter.
2750 NextOutgoingMailbox->CCB = CCB->DMA_Handle;
2751 NextOutgoingMailbox->ActionCode = ActionCode;
2752 BusLogic_StartMailboxCommand(HostAdapter);
2753 if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
2754 NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
2755 HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
2756 if (ActionCode == BusLogic_MailboxStartCommand) {
2757 HostAdapter->ActiveCommands[CCB->TargetID]++;
2758 if (CCB->Opcode != BusLogic_BusDeviceReset)
2759 HostAdapter->TargetStatistics[CCB->TargetID].CommandsAttempted++;
2761 return true;
2763 return false;
2766 /* Error Handling (EH) support */
2768 static int BusLogic_host_reset(Scsi_Cmnd * SCpnt)
2770 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) SCpnt->device->host->hostdata;
2772 unsigned int id = SCpnt->device->id;
2773 struct BusLogic_TargetStatistics *stats = &HostAdapter->TargetStatistics[id];
2774 BusLogic_IncrementErrorCounter(&stats->HostAdapterResetsRequested);
2776 return BusLogic_ResetHostAdapter(HostAdapter, false);
2780 BusLogic_QueueCommand creates a CCB for Command and places it into an
2781 Outgoing Mailbox for execution by the associated Host Adapter.
2784 static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRoutine) (struct scsi_cmnd *))
2786 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata;
2787 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[Command->device->id];
2788 struct BusLogic_TargetStatistics *TargetStatistics = HostAdapter->TargetStatistics;
2789 unsigned char *CDB = Command->cmnd;
2790 int CDB_Length = Command->cmd_len;
2791 int TargetID = Command->device->id;
2792 int LogicalUnit = Command->device->lun;
2793 void *BufferPointer = Command->request_buffer;
2794 int BufferLength = Command->request_bufflen;
2795 int SegmentCount = Command->use_sg;
2796 struct BusLogic_CCB *CCB;
2798 SCSI REQUEST_SENSE commands will be executed automatically by the Host
2799 Adapter for any errors, so they should not be executed explicitly unless
2800 the Sense Data is zero indicating that no error occurred.
2802 if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0) {
2803 Command->result = DID_OK << 16;
2804 CompletionRoutine(Command);
2805 return 0;
2808 Allocate a CCB from the Host Adapter's free list. In the unlikely event
2809 that there are none available and memory allocation fails, wait 1 second
2810 and try again. If that fails, the Host Adapter is probably hung so signal
2811 an error as a Host Adapter Hard Reset should be initiated soon.
2813 CCB = BusLogic_AllocateCCB(HostAdapter);
2814 if (CCB == NULL) {
2815 BusLogic_ReleaseHostAdapterLock(HostAdapter);
2816 BusLogic_Delay(1);
2817 BusLogic_AcquireHostAdapterLock(HostAdapter);
2818 CCB = BusLogic_AllocateCCB(HostAdapter);
2819 if (CCB == NULL) {
2820 Command->result = DID_ERROR << 16;
2821 CompletionRoutine(Command);
2822 return 0;
2826 Initialize the fields in the BusLogic Command Control Block (CCB).
2828 if (SegmentCount == 0 && BufferLength != 0) {
2829 CCB->Opcode = BusLogic_InitiatorCCB;
2830 CCB->DataLength = BufferLength;
2831 CCB->DataPointer = pci_map_single(HostAdapter->PCI_Device, BufferPointer, BufferLength, scsi_to_pci_dma_dir(Command->sc_data_direction));
2832 } else if (SegmentCount != 0) {
2833 struct scatterlist *ScatterList = (struct scatterlist *) BufferPointer;
2834 int Segment, Count;
2836 Count = pci_map_sg(HostAdapter->PCI_Device, ScatterList, SegmentCount, scsi_to_pci_dma_dir(Command->sc_data_direction));
2837 CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
2838 CCB->DataLength = Count * sizeof(struct BusLogic_ScatterGatherSegment);
2839 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
2840 CCB->DataPointer = (unsigned int) CCB->DMA_Handle + ((unsigned long) &CCB->ScatterGatherList - (unsigned long) CCB);
2841 else
2842 CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList);
2843 for (Segment = 0; Segment < Count; Segment++) {
2844 CCB->ScatterGatherList[Segment].SegmentByteCount = sg_dma_len(ScatterList + Segment);
2845 CCB->ScatterGatherList[Segment].SegmentDataPointer = sg_dma_address(ScatterList + Segment);
2847 } else {
2848 CCB->Opcode = BusLogic_InitiatorCCB;
2849 CCB->DataLength = BufferLength;
2850 CCB->DataPointer = 0;
2852 switch (CDB[0]) {
2853 case READ_6:
2854 case READ_10:
2855 CCB->DataDirection = BusLogic_DataInLengthChecked;
2856 TargetStatistics[TargetID].ReadCommands++;
2857 BusLogic_IncrementByteCounter(&TargetStatistics[TargetID].TotalBytesRead, BufferLength);
2858 BusLogic_IncrementSizeBucket(TargetStatistics[TargetID].ReadCommandSizeBuckets, BufferLength);
2859 break;
2860 case WRITE_6:
2861 case WRITE_10:
2862 CCB->DataDirection = BusLogic_DataOutLengthChecked;
2863 TargetStatistics[TargetID].WriteCommands++;
2864 BusLogic_IncrementByteCounter(&TargetStatistics[TargetID].TotalBytesWritten, BufferLength);
2865 BusLogic_IncrementSizeBucket(TargetStatistics[TargetID].WriteCommandSizeBuckets, BufferLength);
2866 break;
2867 default:
2868 CCB->DataDirection = BusLogic_UncheckedDataTransfer;
2869 break;
2871 CCB->CDB_Length = CDB_Length;
2872 CCB->HostAdapterStatus = 0;
2873 CCB->TargetDeviceStatus = 0;
2874 CCB->TargetID = TargetID;
2875 CCB->LogicalUnit = LogicalUnit;
2876 CCB->TagEnable = false;
2877 CCB->LegacyTagEnable = false;
2879 BusLogic recommends that after a Reset the first couple of commands that
2880 are sent to a Target Device be sent in a non Tagged Queue fashion so that
2881 the Host Adapter and Target Device can establish Synchronous and Wide
2882 Transfer before Queue Tag messages can interfere with the Synchronous and
2883 Wide Negotiation messages. By waiting to enable Tagged Queuing until after
2884 the first BusLogic_MaxTaggedQueueDepth commands have been queued, it is
2885 assured that after a Reset any pending commands are requeued before Tagged
2886 Queuing is enabled and that the Tagged Queuing message will not occur while
2887 the partition table is being printed. In addition, some devices do not
2888 properly handle the transition from non-tagged to tagged commands, so it is
2889 necessary to wait until there are no pending commands for a target device
2890 before queuing tagged commands.
2892 if (HostAdapter->CommandsSinceReset[TargetID]++ >=
2893 BusLogic_MaxTaggedQueueDepth && !TargetFlags->TaggedQueuingActive && HostAdapter->ActiveCommands[TargetID] == 0 && TargetFlags->TaggedQueuingSupported && (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) {
2894 TargetFlags->TaggedQueuingActive = true;
2895 BusLogic_Notice("Tagged Queuing now active for Target %d\n", HostAdapter, TargetID);
2897 if (TargetFlags->TaggedQueuingActive) {
2898 enum BusLogic_QueueTag QueueTag = BusLogic_SimpleQueueTag;
2900 When using Tagged Queuing with Simple Queue Tags, it appears that disk
2901 drive controllers do not guarantee that a queued command will not
2902 remain in a disconnected state indefinitely if commands that read or
2903 write nearer the head position continue to arrive without interruption.
2904 Therefore, for each Target Device this driver keeps track of the last
2905 time either the queue was empty or an Ordered Queue Tag was issued. If
2906 more than 4 seconds (one fifth of the 20 second disk timeout) have
2907 elapsed since this last sequence point, this command will be issued
2908 with an Ordered Queue Tag rather than a Simple Queue Tag, which forces
2909 the Target Device to complete all previously queued commands before
2910 this command may be executed.
2912 if (HostAdapter->ActiveCommands[TargetID] == 0)
2913 HostAdapter->LastSequencePoint[TargetID] = jiffies;
2914 else if (jiffies - HostAdapter->LastSequencePoint[TargetID] > 4 * HZ) {
2915 HostAdapter->LastSequencePoint[TargetID] = jiffies;
2916 QueueTag = BusLogic_OrderedQueueTag;
2918 if (HostAdapter->ExtendedLUNSupport) {
2919 CCB->TagEnable = true;
2920 CCB->QueueTag = QueueTag;
2921 } else {
2922 CCB->LegacyTagEnable = true;
2923 CCB->LegacyQueueTag = QueueTag;
2926 memcpy(CCB->CDB, CDB, CDB_Length);
2927 CCB->SenseDataLength = sizeof(Command->sense_buffer);
2928 CCB->SenseDataPointer = pci_map_single(HostAdapter->PCI_Device, Command->sense_buffer, CCB->SenseDataLength, PCI_DMA_FROMDEVICE);
2929 CCB->Command = Command;
2930 Command->scsi_done = CompletionRoutine;
2931 if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
2933 Place the CCB in an Outgoing Mailbox. The higher levels of the SCSI
2934 Subsystem should not attempt to queue more commands than can be placed
2935 in Outgoing Mailboxes, so there should always be one free. In the
2936 unlikely event that there are none available, wait 1 second and try
2937 again. If that fails, the Host Adapter is probably hung so signal an
2938 error as a Host Adapter Hard Reset should be initiated soon.
2940 if (!BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxStartCommand, CCB)) {
2941 BusLogic_ReleaseHostAdapterLock(HostAdapter);
2942 BusLogic_Warning("Unable to write Outgoing Mailbox - " "Pausing for 1 second\n", HostAdapter);
2943 BusLogic_Delay(1);
2944 BusLogic_AcquireHostAdapterLock(HostAdapter);
2945 if (!BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxStartCommand, CCB)) {
2946 BusLogic_Warning("Still unable to write Outgoing Mailbox - " "Host Adapter Dead?\n", HostAdapter);
2947 BusLogic_DeallocateCCB(CCB);
2948 Command->result = DID_ERROR << 16;
2949 Command->scsi_done(Command);
2952 } else {
2954 Call the FlashPoint SCCB Manager to start execution of the CCB.
2956 CCB->Status = BusLogic_CCB_Active;
2957 HostAdapter->ActiveCommands[TargetID]++;
2958 TargetStatistics[TargetID].CommandsAttempted++;
2959 FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
2961 The Command may have already completed and BusLogic_QueueCompletedCCB
2962 been called, or it may still be pending.
2964 if (CCB->Status == BusLogic_CCB_Completed)
2965 BusLogic_ProcessCompletedCCBs(HostAdapter);
2967 return 0;
2972 BusLogic_AbortCommand aborts Command if possible.
2975 static int BusLogic_AbortCommand(struct scsi_cmnd *Command)
2977 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata;
2979 int TargetID = Command->device->id;
2980 struct BusLogic_CCB *CCB;
2981 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsRequested);
2983 If this Command has already completed, then no Abort is necessary.
2985 if (Command->serial_number != Command->serial_number_at_timeout) {
2986 BusLogic_Warning("Unable to Abort Command to Target %d - " "Already Completed\n", HostAdapter, TargetID);
2987 return SUCCESS;
2990 Attempt to find an Active CCB for this Command. If no Active CCB for this
2991 Command is found, then no Abort is necessary.
2993 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2994 if (CCB->Command == Command)
2995 break;
2996 if (CCB == NULL) {
2997 BusLogic_Warning("Unable to Abort Command to Target %d - " "No CCB Found\n", HostAdapter, TargetID);
2998 return SUCCESS;
2999 } else if (CCB->Status == BusLogic_CCB_Completed) {
3000 BusLogic_Warning("Unable to Abort Command to Target %d - " "CCB Completed\n", HostAdapter, TargetID);
3001 return SUCCESS;
3002 } else if (CCB->Status == BusLogic_CCB_Reset) {
3003 BusLogic_Warning("Unable to Abort Command to Target %d - " "CCB Reset\n", HostAdapter, TargetID);
3004 return SUCCESS;
3006 if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
3008 Attempt to Abort this CCB. MultiMaster Firmware versions prior to 5.xx
3009 do not generate Abort Tag messages, but only generate the non-tagged
3010 Abort message. Since non-tagged commands are not sent by the Host
3011 Adapter until the queue of outstanding tagged commands has completed,
3012 and the Abort message is treated as a non-tagged command, it is
3013 effectively impossible to abort commands when Tagged Queuing is active.
3014 Firmware version 5.xx does generate Abort Tag messages, so it is
3015 possible to abort commands when Tagged Queuing is active.
3017 if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive && HostAdapter->FirmwareVersion[0] < '5') {
3018 BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - " "Abort Tag Not Supported\n", HostAdapter, CCB->SerialNumber, TargetID);
3019 return FAILURE;
3020 } else if (BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxAbortCommand, CCB)) {
3021 BusLogic_Warning("Aborting CCB #%ld to Target %d\n", HostAdapter, CCB->SerialNumber, TargetID);
3022 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
3023 return SUCCESS;
3024 } else {
3025 BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - " "No Outgoing Mailboxes\n", HostAdapter, CCB->SerialNumber, TargetID);
3026 return FAILURE;
3028 } else {
3030 Call the FlashPoint SCCB Manager to abort execution of the CCB.
3032 BusLogic_Warning("Aborting CCB #%ld to Target %d\n", HostAdapter, CCB->SerialNumber, TargetID);
3033 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
3034 FlashPoint_AbortCCB(HostAdapter->CardHandle, CCB);
3036 The Abort may have already been completed and
3037 BusLogic_QueueCompletedCCB been called, or it
3038 may still be pending.
3040 if (CCB->Status == BusLogic_CCB_Completed) {
3041 BusLogic_ProcessCompletedCCBs(HostAdapter);
3043 return SUCCESS;
3045 return SUCCESS;
3049 BusLogic_ResetHostAdapter resets Host Adapter if possible, marking all
3050 currently executing SCSI Commands as having been Reset.
3053 static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter, boolean HardReset)
3055 struct BusLogic_CCB *CCB;
3056 int TargetID;
3059 * Attempt to Reset and Reinitialize the Host Adapter.
3062 if (!(BusLogic_HardwareResetHostAdapter(HostAdapter, HardReset) && BusLogic_InitializeHostAdapter(HostAdapter))) {
3063 BusLogic_Error("Resetting %s Failed\n", HostAdapter, HostAdapter->FullModelName);
3064 return FAILURE;
3068 * Deallocate all currently executing CCBs.
3071 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3072 if (CCB->Status == BusLogic_CCB_Active)
3073 BusLogic_DeallocateCCB(CCB);
3075 * Wait a few seconds between the Host Adapter Hard Reset which
3076 * initiates a SCSI Bus Reset and issuing any SCSI Commands. Some
3077 * SCSI devices get confused if they receive SCSI Commands too soon
3078 * after a SCSI Bus Reset.
3081 if (HardReset) {
3082 BusLogic_ReleaseHostAdapterLock(HostAdapter);
3083 BusLogic_Delay(HostAdapter->BusSettleTime);
3084 BusLogic_AcquireHostAdapterLock(HostAdapter);
3087 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3088 HostAdapter->LastResetAttempted[TargetID] = jiffies;
3089 HostAdapter->LastResetCompleted[TargetID] = jiffies;
3091 return SUCCESS;
3095 BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk
3096 Parameters for Disk. The default disk geometry is 64 heads, 32 sectors, and
3097 the appropriate number of cylinders so as not to exceed drive capacity. In
3098 order for disks equal to or larger than 1 GB to be addressable by the BIOS
3099 without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
3100 may be enabled in AutoSCSI on FlashPoint Host Adapters and on "W" and "C"
3101 series MultiMaster Host Adapters, or by a dip switch setting on "S" and "A"
3102 series MultiMaster Host Adapters. With Extended Translation enabled, drives
3103 between 1 GB inclusive and 2 GB exclusive are given a disk geometry of 128
3104 heads and 32 sectors, and drives above 2 GB inclusive are given a disk
3105 geometry of 255 heads and 63 sectors. However, if the BIOS detects that the
3106 Extended Translation setting does not match the geometry in the partition
3107 table, then the translation inferred from the partition table will be used by
3108 the BIOS, and a warning may be displayed.
3111 static int BusLogic_BIOSDiskParameters(struct scsi_device *sdev, struct block_device *Device, sector_t capacity, int *Parameters)
3113 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) sdev->host->hostdata;
3114 struct BIOS_DiskParameters *DiskParameters = (struct BIOS_DiskParameters *) Parameters;
3115 unsigned char *buf;
3116 if (HostAdapter->ExtendedTranslationEnabled && capacity >= 2 * 1024 * 1024 /* 1 GB in 512 byte sectors */ ) {
3117 if (capacity >= 4 * 1024 * 1024 /* 2 GB in 512 byte sectors */ ) {
3118 DiskParameters->Heads = 255;
3119 DiskParameters->Sectors = 63;
3120 } else {
3121 DiskParameters->Heads = 128;
3122 DiskParameters->Sectors = 32;
3124 } else {
3125 DiskParameters->Heads = 64;
3126 DiskParameters->Sectors = 32;
3128 DiskParameters->Cylinders = (unsigned long) capacity / (DiskParameters->Heads * DiskParameters->Sectors);
3129 buf = scsi_bios_ptable(Device);
3130 if (buf == NULL)
3131 return 0;
3133 If the boot sector partition table flag is valid, search for a partition
3134 table entry whose end_head matches one of the standard BusLogic geometry
3135 translations (64/32, 128/32, or 255/63).
3137 if (*(unsigned short *) (buf + 64) == 0xAA55) {
3138 struct partition *FirstPartitionEntry = (struct partition *) buf;
3139 struct partition *PartitionEntry = FirstPartitionEntry;
3140 int SavedCylinders = DiskParameters->Cylinders, PartitionNumber;
3141 unsigned char PartitionEntryEndHead = 0, PartitionEntryEndSector = 0;
3142 for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++) {
3143 PartitionEntryEndHead = PartitionEntry->end_head;
3144 PartitionEntryEndSector = PartitionEntry->end_sector & 0x3F;
3145 if (PartitionEntryEndHead == 64 - 1) {
3146 DiskParameters->Heads = 64;
3147 DiskParameters->Sectors = 32;
3148 break;
3149 } else if (PartitionEntryEndHead == 128 - 1) {
3150 DiskParameters->Heads = 128;
3151 DiskParameters->Sectors = 32;
3152 break;
3153 } else if (PartitionEntryEndHead == 255 - 1) {
3154 DiskParameters->Heads = 255;
3155 DiskParameters->Sectors = 63;
3156 break;
3158 PartitionEntry++;
3160 if (PartitionNumber == 4) {
3161 PartitionEntryEndHead = FirstPartitionEntry->end_head;
3162 PartitionEntryEndSector = FirstPartitionEntry->end_sector & 0x3F;
3164 DiskParameters->Cylinders = (unsigned long) capacity / (DiskParameters->Heads * DiskParameters->Sectors);
3165 if (PartitionNumber < 4 && PartitionEntryEndSector == DiskParameters->Sectors) {
3166 if (DiskParameters->Cylinders != SavedCylinders)
3167 BusLogic_Warning("Adopting Geometry %d/%d from Partition Table\n", HostAdapter, DiskParameters->Heads, DiskParameters->Sectors);
3168 } else if (PartitionEntryEndHead > 0 || PartitionEntryEndSector > 0) {
3169 BusLogic_Warning("Warning: Partition Table appears to " "have Geometry %d/%d which is\n", HostAdapter, PartitionEntryEndHead + 1, PartitionEntryEndSector);
3170 BusLogic_Warning("not compatible with current BusLogic " "Host Adapter Geometry %d/%d\n", HostAdapter, DiskParameters->Heads, DiskParameters->Sectors);
3173 kfree(buf);
3174 return 0;
3179 BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>.
3182 static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *shost, char *ProcBuffer, char **StartPointer, off_t Offset, int BytesAvailable, int WriteFlag)
3184 struct BusLogic_HostAdapter *HostAdapter;
3185 struct BusLogic_TargetStatistics *TargetStatistics;
3186 int TargetID, Length;
3187 char *Buffer;
3188 for (HostAdapter = BusLogic_FirstRegisteredHostAdapter; HostAdapter != NULL; HostAdapter = HostAdapter->Next)
3189 if (HostAdapter->HostNumber == shost->host_no)
3190 break;
3191 if (HostAdapter == NULL) {
3192 BusLogic_Error("Cannot find Host Adapter for SCSI Host %d\n", NULL, shost->host_no);
3193 return 0;
3195 TargetStatistics = HostAdapter->TargetStatistics;
3196 if (WriteFlag) {
3197 HostAdapter->ExternalHostAdapterResets = 0;
3198 HostAdapter->HostAdapterInternalErrors = 0;
3199 memset(TargetStatistics, 0, BusLogic_MaxTargetDevices * sizeof(struct BusLogic_TargetStatistics));
3200 return 0;
3202 Buffer = HostAdapter->MessageBuffer;
3203 Length = HostAdapter->MessageBufferLength;
3204 Length += sprintf(&Buffer[Length], "\n\
3205 Current Driver Queue Depth: %d\n\
3206 Currently Allocated CCBs: %d\n", HostAdapter->DriverQueueDepth, HostAdapter->AllocatedCCBs);
3207 Length += sprintf(&Buffer[Length], "\n\n\
3208 DATA TRANSFER STATISTICS\n\
3210 Target Tagged Queuing Queue Depth Active Attempted Completed\n\
3211 ====== ============== =========== ====== ========= =========\n");
3212 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3213 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3214 if (!TargetFlags->TargetExists)
3215 continue;
3216 Length += sprintf(&Buffer[Length], " %2d %s", TargetID, (TargetFlags->TaggedQueuingSupported ? (TargetFlags->TaggedQueuingActive ? " Active" : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)
3217 ? " Permitted" : " Disabled"))
3218 : "Not Supported"));
3219 Length += sprintf(&Buffer[Length],
3220 " %3d %3u %9u %9u\n", HostAdapter->QueueDepth[TargetID], HostAdapter->ActiveCommands[TargetID], TargetStatistics[TargetID].CommandsAttempted, TargetStatistics[TargetID].CommandsCompleted);
3222 Length += sprintf(&Buffer[Length], "\n\
3223 Target Read Commands Write Commands Total Bytes Read Total Bytes Written\n\
3224 ====== ============= ============== =================== ===================\n");
3225 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3226 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3227 if (!TargetFlags->TargetExists)
3228 continue;
3229 Length += sprintf(&Buffer[Length], " %2d %9u %9u", TargetID, TargetStatistics[TargetID].ReadCommands, TargetStatistics[TargetID].WriteCommands);
3230 if (TargetStatistics[TargetID].TotalBytesRead.Billions > 0)
3231 Length += sprintf(&Buffer[Length], " %9u%09u", TargetStatistics[TargetID].TotalBytesRead.Billions, TargetStatistics[TargetID].TotalBytesRead.Units);
3232 else
3233 Length += sprintf(&Buffer[Length], " %9u", TargetStatistics[TargetID].TotalBytesRead.Units);
3234 if (TargetStatistics[TargetID].TotalBytesWritten.Billions > 0)
3235 Length += sprintf(&Buffer[Length], " %9u%09u\n", TargetStatistics[TargetID].TotalBytesWritten.Billions, TargetStatistics[TargetID].TotalBytesWritten.Units);
3236 else
3237 Length += sprintf(&Buffer[Length], " %9u\n", TargetStatistics[TargetID].TotalBytesWritten.Units);
3239 Length += sprintf(&Buffer[Length], "\n\
3240 Target Command 0-1KB 1-2KB 2-4KB 4-8KB 8-16KB\n\
3241 ====== ======= ========= ========= ========= ========= =========\n");
3242 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3243 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3244 if (!TargetFlags->TargetExists)
3245 continue;
3246 Length +=
3247 sprintf(&Buffer[Length],
3248 " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
3249 TargetStatistics[TargetID].ReadCommandSizeBuckets[0],
3250 TargetStatistics[TargetID].ReadCommandSizeBuckets[1], TargetStatistics[TargetID].ReadCommandSizeBuckets[2], TargetStatistics[TargetID].ReadCommandSizeBuckets[3], TargetStatistics[TargetID].ReadCommandSizeBuckets[4]);
3251 Length +=
3252 sprintf(&Buffer[Length],
3253 " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
3254 TargetStatistics[TargetID].WriteCommandSizeBuckets[0],
3255 TargetStatistics[TargetID].WriteCommandSizeBuckets[1], TargetStatistics[TargetID].WriteCommandSizeBuckets[2], TargetStatistics[TargetID].WriteCommandSizeBuckets[3], TargetStatistics[TargetID].WriteCommandSizeBuckets[4]);
3257 Length += sprintf(&Buffer[Length], "\n\
3258 Target Command 16-32KB 32-64KB 64-128KB 128-256KB 256KB+\n\
3259 ====== ======= ========= ========= ========= ========= =========\n");
3260 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3261 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3262 if (!TargetFlags->TargetExists)
3263 continue;
3264 Length +=
3265 sprintf(&Buffer[Length],
3266 " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
3267 TargetStatistics[TargetID].ReadCommandSizeBuckets[5],
3268 TargetStatistics[TargetID].ReadCommandSizeBuckets[6], TargetStatistics[TargetID].ReadCommandSizeBuckets[7], TargetStatistics[TargetID].ReadCommandSizeBuckets[8], TargetStatistics[TargetID].ReadCommandSizeBuckets[9]);
3269 Length +=
3270 sprintf(&Buffer[Length],
3271 " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
3272 TargetStatistics[TargetID].WriteCommandSizeBuckets[5],
3273 TargetStatistics[TargetID].WriteCommandSizeBuckets[6], TargetStatistics[TargetID].WriteCommandSizeBuckets[7], TargetStatistics[TargetID].WriteCommandSizeBuckets[8], TargetStatistics[TargetID].WriteCommandSizeBuckets[9]);
3275 Length += sprintf(&Buffer[Length], "\n\n\
3276 ERROR RECOVERY STATISTICS\n\
3278 Command Aborts Bus Device Resets Host Adapter Resets\n\
3279 Target Requested Completed Requested Completed Requested Completed\n\
3280 ID \\\\\\\\ Attempted //// \\\\\\\\ Attempted //// \\\\\\\\ Attempted ////\n\
3281 ====== ===== ===== ===== ===== ===== ===== ===== ===== =====\n");
3282 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3283 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3284 if (!TargetFlags->TargetExists)
3285 continue;
3286 Length += sprintf(&Buffer[Length], "\
3287 %2d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n", TargetID, TargetStatistics[TargetID].CommandAbortsRequested, TargetStatistics[TargetID].CommandAbortsAttempted, TargetStatistics[TargetID].CommandAbortsCompleted, TargetStatistics[TargetID].BusDeviceResetsRequested, TargetStatistics[TargetID].BusDeviceResetsAttempted, TargetStatistics[TargetID].BusDeviceResetsCompleted, TargetStatistics[TargetID].HostAdapterResetsRequested, TargetStatistics[TargetID].HostAdapterResetsAttempted, TargetStatistics[TargetID].HostAdapterResetsCompleted);
3289 Length += sprintf(&Buffer[Length], "\nExternal Host Adapter Resets: %d\n", HostAdapter->ExternalHostAdapterResets);
3290 Length += sprintf(&Buffer[Length], "Host Adapter Internal Errors: %d\n", HostAdapter->HostAdapterInternalErrors);
3291 if (Length >= BusLogic_MessageBufferSize)
3292 BusLogic_Error("Message Buffer length %d exceeds size %d\n", HostAdapter, Length, BusLogic_MessageBufferSize);
3293 if ((Length -= Offset) <= 0)
3294 return 0;
3295 if (Length >= BytesAvailable)
3296 Length = BytesAvailable;
3297 memcpy(ProcBuffer, HostAdapter->MessageBuffer + Offset, Length);
3298 *StartPointer = ProcBuffer;
3299 return Length;
3304 BusLogic_Message prints Driver Messages.
3307 static void BusLogic_Message(enum BusLogic_MessageLevel MessageLevel, char *Format, struct BusLogic_HostAdapter *HostAdapter, ...)
3309 static char Buffer[BusLogic_LineBufferSize];
3310 static boolean BeginningOfLine = true;
3311 va_list Arguments;
3312 int Length = 0;
3313 va_start(Arguments, HostAdapter);
3314 Length = vsprintf(Buffer, Format, Arguments);
3315 va_end(Arguments);
3316 if (MessageLevel == BusLogic_AnnounceLevel) {
3317 static int AnnouncementLines = 0;
3318 strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength], Buffer);
3319 HostAdapter->MessageBufferLength += Length;
3320 if (++AnnouncementLines <= 2)
3321 printk("%sscsi: %s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
3322 } else if (MessageLevel == BusLogic_InfoLevel) {
3323 strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength], Buffer);
3324 HostAdapter->MessageBufferLength += Length;
3325 if (BeginningOfLine) {
3326 if (Buffer[0] != '\n' || Length > 1)
3327 printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel], HostAdapter->HostNumber, Buffer);
3328 } else
3329 printk("%s", Buffer);
3330 } else {
3331 if (BeginningOfLine) {
3332 if (HostAdapter != NULL && HostAdapter->HostAdapterInitialized)
3333 printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel], HostAdapter->HostNumber, Buffer);
3334 else
3335 printk("%s%s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
3336 } else
3337 printk("%s", Buffer);
3339 BeginningOfLine = (Buffer[Length - 1] == '\n');
3344 BusLogic_ParseKeyword parses an individual option keyword. It returns true
3345 and updates the pointer if the keyword is recognized and false otherwise.
3348 static boolean __init BusLogic_ParseKeyword(char **StringPointer, char *Keyword)
3350 char *Pointer = *StringPointer;
3351 while (*Keyword != '\0') {
3352 char StringChar = *Pointer++;
3353 char KeywordChar = *Keyword++;
3354 if (StringChar >= 'A' && StringChar <= 'Z')
3355 StringChar += 'a' - 'Z';
3356 if (KeywordChar >= 'A' && KeywordChar <= 'Z')
3357 KeywordChar += 'a' - 'Z';
3358 if (StringChar != KeywordChar)
3359 return false;
3361 *StringPointer = Pointer;
3362 return true;
3367 BusLogic_ParseDriverOptions handles processing of BusLogic Driver Options
3368 specifications.
3370 BusLogic Driver Options may be specified either via the Linux Kernel Command
3371 Line or via the Loadable Kernel Module Installation Facility. Driver Options
3372 for multiple host adapters may be specified either by separating the option
3373 strings by a semicolon, or by specifying multiple "BusLogic=" strings on the
3374 command line. Individual option specifications for a single host adapter are
3375 separated by commas. The Probing and Debugging Options apply to all host
3376 adapters whereas the remaining options apply individually only to the
3377 selected host adapter.
3379 The BusLogic Driver Probing Options are described in
3380 <file:Documentation/scsi/BusLogic.txt>.
3383 static int __init BusLogic_ParseDriverOptions(char *OptionsString)
3385 while (true) {
3386 struct BusLogic_DriverOptions *DriverOptions = &BusLogic_DriverOptions[BusLogic_DriverOptionsCount++];
3387 int TargetID;
3388 memset(DriverOptions, 0, sizeof(struct BusLogic_DriverOptions));
3389 while (*OptionsString != '\0' && *OptionsString != ';') {
3390 /* Probing Options. */
3391 if (BusLogic_ParseKeyword(&OptionsString, "IO:")) {
3392 unsigned long IO_Address = simple_strtoul(OptionsString, &OptionsString, 0);
3393 BusLogic_ProbeOptions.LimitedProbeISA = true;
3394 switch (IO_Address) {
3395 case 0x330:
3396 BusLogic_ProbeOptions.Probe330 = true;
3397 break;
3398 case 0x334:
3399 BusLogic_ProbeOptions.Probe334 = true;
3400 break;
3401 case 0x230:
3402 BusLogic_ProbeOptions.Probe230 = true;
3403 break;
3404 case 0x234:
3405 BusLogic_ProbeOptions.Probe234 = true;
3406 break;
3407 case 0x130:
3408 BusLogic_ProbeOptions.Probe130 = true;
3409 break;
3410 case 0x134:
3411 BusLogic_ProbeOptions.Probe134 = true;
3412 break;
3413 default:
3414 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid I/O Address 0x%X)\n", NULL, IO_Address);
3415 return 0;
3417 } else if (BusLogic_ParseKeyword(&OptionsString, "NoProbeISA"))
3418 BusLogic_ProbeOptions.NoProbeISA = true;
3419 else if (BusLogic_ParseKeyword(&OptionsString, "NoProbePCI"))
3420 BusLogic_ProbeOptions.NoProbePCI = true;
3421 else if (BusLogic_ParseKeyword(&OptionsString, "NoProbe"))
3422 BusLogic_ProbeOptions.NoProbe = true;
3423 else if (BusLogic_ParseKeyword(&OptionsString, "NoSortPCI"))
3424 BusLogic_ProbeOptions.NoSortPCI = true;
3425 else if (BusLogic_ParseKeyword(&OptionsString, "MultiMasterFirst"))
3426 BusLogic_ProbeOptions.MultiMasterFirst = true;
3427 else if (BusLogic_ParseKeyword(&OptionsString, "FlashPointFirst"))
3428 BusLogic_ProbeOptions.FlashPointFirst = true;
3429 /* Tagged Queuing Options. */
3430 else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:[") || BusLogic_ParseKeyword(&OptionsString, "QD:[")) {
3431 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) {
3432 unsigned short QueueDepth = simple_strtoul(OptionsString, &OptionsString, 0);
3433 if (QueueDepth > BusLogic_MaxTaggedQueueDepth) {
3434 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, QueueDepth);
3435 return 0;
3437 DriverOptions->QueueDepth[TargetID] = QueueDepth;
3438 if (*OptionsString == ',')
3439 OptionsString++;
3440 else if (*OptionsString == ']')
3441 break;
3442 else {
3443 BusLogic_Error("BusLogic: Invalid Driver Options " "(',' or ']' expected at '%s')\n", NULL, OptionsString);
3444 return 0;
3447 if (*OptionsString != ']') {
3448 BusLogic_Error("BusLogic: Invalid Driver Options " "(']' expected at '%s')\n", NULL, OptionsString);
3449 return 0;
3450 } else
3451 OptionsString++;
3452 } else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:") || BusLogic_ParseKeyword(&OptionsString, "QD:")) {
3453 unsigned short QueueDepth = simple_strtoul(OptionsString, &OptionsString, 0);
3454 if (QueueDepth == 0 || QueueDepth > BusLogic_MaxTaggedQueueDepth) {
3455 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, QueueDepth);
3456 return 0;
3458 DriverOptions->CommonQueueDepth = QueueDepth;
3459 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
3460 DriverOptions->QueueDepth[TargetID] = QueueDepth;
3461 } else if (BusLogic_ParseKeyword(&OptionsString, "TaggedQueuing:") || BusLogic_ParseKeyword(&OptionsString, "TQ:")) {
3462 if (BusLogic_ParseKeyword(&OptionsString, "Default")) {
3463 DriverOptions->TaggedQueuingPermitted = 0x0000;
3464 DriverOptions->TaggedQueuingPermittedMask = 0x0000;
3465 } else if (BusLogic_ParseKeyword(&OptionsString, "Enable")) {
3466 DriverOptions->TaggedQueuingPermitted = 0xFFFF;
3467 DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
3468 } else if (BusLogic_ParseKeyword(&OptionsString, "Disable")) {
3469 DriverOptions->TaggedQueuingPermitted = 0x0000;
3470 DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
3471 } else {
3472 unsigned short TargetBit;
3473 for (TargetID = 0, TargetBit = 1; TargetID < BusLogic_MaxTargetDevices; TargetID++, TargetBit <<= 1)
3474 switch (*OptionsString++) {
3475 case 'Y':
3476 DriverOptions->TaggedQueuingPermitted |= TargetBit;
3477 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
3478 break;
3479 case 'N':
3480 DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
3481 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
3482 break;
3483 case 'X':
3484 break;
3485 default:
3486 OptionsString--;
3487 TargetID = BusLogic_MaxTargetDevices;
3488 break;
3492 /* Miscellaneous Options. */
3493 else if (BusLogic_ParseKeyword(&OptionsString, "BusSettleTime:") || BusLogic_ParseKeyword(&OptionsString, "BST:")) {
3494 unsigned short BusSettleTime = simple_strtoul(OptionsString, &OptionsString, 0);
3495 if (BusSettleTime > 5 * 60) {
3496 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Bus Settle Time %d)\n", NULL, BusSettleTime);
3497 return 0;
3499 DriverOptions->BusSettleTime = BusSettleTime;
3500 } else if (BusLogic_ParseKeyword(&OptionsString, "InhibitTargetInquiry"))
3501 DriverOptions->LocalOptions.InhibitTargetInquiry = true;
3502 /* Debugging Options. */
3503 else if (BusLogic_ParseKeyword(&OptionsString, "TraceProbe"))
3504 BusLogic_GlobalOptions.TraceProbe = true;
3505 else if (BusLogic_ParseKeyword(&OptionsString, "TraceHardwareReset"))
3506 BusLogic_GlobalOptions.TraceHardwareReset = true;
3507 else if (BusLogic_ParseKeyword(&OptionsString, "TraceConfiguration"))
3508 BusLogic_GlobalOptions.TraceConfiguration = true;
3509 else if (BusLogic_ParseKeyword(&OptionsString, "TraceErrors"))
3510 BusLogic_GlobalOptions.TraceErrors = true;
3511 else if (BusLogic_ParseKeyword(&OptionsString, "Debug")) {
3512 BusLogic_GlobalOptions.TraceProbe = true;
3513 BusLogic_GlobalOptions.TraceHardwareReset = true;
3514 BusLogic_GlobalOptions.TraceConfiguration = true;
3515 BusLogic_GlobalOptions.TraceErrors = true;
3517 if (*OptionsString == ',')
3518 OptionsString++;
3519 else if (*OptionsString != ';' && *OptionsString != '\0') {
3520 BusLogic_Error("BusLogic: Unexpected Driver Option '%s' " "ignored\n", NULL, OptionsString);
3521 *OptionsString = '\0';
3524 if (!(BusLogic_DriverOptionsCount == 0 || BusLogic_ProbeInfoCount == 0 || BusLogic_DriverOptionsCount == BusLogic_ProbeInfoCount)) {
3525 BusLogic_Error("BusLogic: Invalid Driver Options " "(all or no I/O Addresses must be specified)\n", NULL);
3526 return 0;
3529 Tagged Queuing is disabled when the Queue Depth is 1 since queuing
3530 multiple commands is not possible.
3532 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
3533 if (DriverOptions->QueueDepth[TargetID] == 1) {
3534 unsigned short TargetBit = 1 << TargetID;
3535 DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
3536 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
3538 if (*OptionsString == ';')
3539 OptionsString++;
3540 if (*OptionsString == '\0')
3541 return 0;
3543 return 1;
3547 Get it all started
3550 static struct scsi_host_template driver_template = {
3551 .module = THIS_MODULE,
3552 .proc_name = "BusLogic",
3553 .proc_info = BusLogic_ProcDirectoryInfo,
3554 .name = "BusLogic",
3555 .info = BusLogic_DriverInfo,
3556 .queuecommand = BusLogic_QueueCommand,
3557 .slave_configure = BusLogic_SlaveConfigure,
3558 .bios_param = BusLogic_BIOSDiskParameters,
3559 .eh_host_reset_handler = BusLogic_host_reset,
3560 #if 0
3561 .eh_abort_handler = BusLogic_AbortCommand,
3562 #endif
3563 .unchecked_isa_dma = 1,
3564 .max_sectors = 128,
3565 .use_clustering = ENABLE_CLUSTERING,
3569 BusLogic_Setup handles processing of Kernel Command Line Arguments.
3572 static int __init BusLogic_Setup(char *str)
3574 int ints[3];
3576 (void) get_options(str, ARRAY_SIZE(ints), ints);
3578 if (ints[0] != 0) {
3579 BusLogic_Error("BusLogic: Obsolete Command Line Entry " "Format Ignored\n", NULL);
3580 return 0;
3582 if (str == NULL || *str == '\0')
3583 return 0;
3584 return BusLogic_ParseDriverOptions(str);
3588 * Initialization function
3591 static int __init BusLogic_init(void)
3594 #ifdef MODULE
3595 if (BusLogic)
3596 BusLogic_Setup(BusLogic);
3597 #endif
3599 return BusLogic_DetectHostAdapter(&driver_template) ? 0 : -ENODEV;
3603 * Exit function. Deletes all hosts associated with this driver.
3606 static void __exit BusLogic_exit(void)
3608 struct BusLogic_HostAdapter *HostAdapter;
3609 for (HostAdapter = BusLogic_FirstRegisteredHostAdapter; HostAdapter != NULL; HostAdapter = HostAdapter->Next) {
3610 struct Scsi_Host *host = HostAdapter->SCSI_Host;
3611 scsi_remove_host(host);
3614 for (HostAdapter = BusLogic_FirstRegisteredHostAdapter; HostAdapter != NULL; HostAdapter = HostAdapter->Next) {
3615 struct Scsi_Host *host = HostAdapter->SCSI_Host;
3616 BusLogic_ReleaseHostAdapter(host);
3620 __setup("BusLogic=", BusLogic_Setup);
3622 module_init(BusLogic_init);
3623 module_exit(BusLogic_exit);