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