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