1 /*
2
3 Linux Driver for BusLogic MultiMaster and FlashPoint SCSI Host Adapters
4
5 Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>
6
7 This program is free software; you may redistribute and/or modify it under
8 the terms of the GNU General Public License Version 2 as published by the
9 Free Software Foundation.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for complete details.
15
16 The author respectfully requests that any modifications to this software be
17 sent directly to him for evaluation and testing.
18
19 Special thanks to Wayne Yen, Jin-Lon Hon, and Alex Win of BusLogic, whose
20 advice has been invaluable, to David Gentzel, for writing the original Linux
21 BusLogic driver, and to Paul Gortmaker, for being such a dedicated test site.
22
23 Finally, special thanks to Mylex/BusLogic for making the FlashPoint SCCB
24 Manager available as freely redistributable source code.
25
26 */
27
28
29 #define BusLogic_DriverVersion "2.1.15"
30 #define BusLogic_DriverDate "17 August 1998"
31
32
33 #include <linux/version.h>
34 #include <linux/module.h>
35 #include <linux/config.h>
36 #include <linux/init.h>
37 #include <linux/types.h>
38 #include <linux/blk.h>
39 #include <linux/blkdev.h>
40 #include <linux/delay.h>
41 #include <linux/ioport.h>
42 #include <linux/mm.h>
43 #include <linux/sched.h>
44 #include <linux/stat.h>
45 #include <linux/pci.h>
46 #include <linux/spinlock.h>
47 #include <asm/dma.h>
48 #include <asm/io.h>
49 #include <asm/system.h>
50 #include "scsi.h"
51 #include "hosts.h"
52 #include "sd.h"
53 #include "BusLogic.h"
54 #include "FlashPoint.c"
55
56
57 /*
58 BusLogic_DriverOptionsCount is a count of the number of BusLogic Driver
59 Options specifications provided via the Linux Kernel Command Line or via
60 the Loadable Kernel Module Installation Facility.
61 */
62
63 static int
64 BusLogic_DriverOptionsCount;
65
66
67 /*
68 BusLogic_DriverOptions is an array of Driver Options structures representing
69 BusLogic Driver Options specifications provided via the Linux Kernel Command
70 Line or via the Loadable Kernel Module Installation Facility.
71 */
72
73 static BusLogic_DriverOptions_T
74 BusLogic_DriverOptions[BusLogic_MaxHostAdapters];
75
76
77 /*
78 BusLogic can be assigned a string by insmod.
79 */
80
81 #ifdef MODULE
82 static char *BusLogic;
83 MODULE_PARM(BusLogic, "s");
84 #endif
85
86
87 /*
88 BusLogic_ProbeOptions is a set of Probe Options to be applied across
89 all BusLogic Host Adapters.
90 */
91
92 static BusLogic_ProbeOptions_T
93 BusLogic_ProbeOptions;
94
95
96 /*
97 BusLogic_GlobalOptions is a set of Global Options to be applied across
98 all BusLogic Host Adapters.
99 */
100
101 static BusLogic_GlobalOptions_T
102 BusLogic_GlobalOptions;
103
104
105 /*
106 BusLogic_FirstRegisteredHostAdapter and BusLogic_LastRegisteredHostAdapter
107 are pointers to the first and last registered BusLogic Host Adapters.
108 */
109
110 static BusLogic_HostAdapter_T
111 *BusLogic_FirstRegisteredHostAdapter,
112 *BusLogic_LastRegisteredHostAdapter;
113
114
115 /*
116 BusLogic_ProbeInfoCount is the number of entries in BusLogic_ProbeInfoList.
117 */
118
119 static int
120 BusLogic_ProbeInfoCount;
121
122
123 /*
124 BusLogic_ProbeInfoList is the list of I/O Addresses and Bus Probe Information
125 to be checked for potential BusLogic Host Adapters. It is initialized by
126 interrogating the PCI Configuration Space on PCI machines as well as from the
127 list of standard BusLogic I/O Addresses.
128 */
129
130 static BusLogic_ProbeInfo_T
131 *BusLogic_ProbeInfoList;
132
133
134 /*
135 BusLogic_CommandFailureReason holds a string identifying the reason why a
136 call to BusLogic_Command failed. It is only non-NULL when BusLogic_Command
137 returns a failure code.
138 */
139
140 static char
141 *BusLogic_CommandFailureReason;
142
143 /*
144 BusLogic_AnnounceDriver announces the Driver Version and Date, Author's
145 Name, Copyright Notice, and Electronic Mail Address.
146 */
147
BusLogic_AnnounceDriver(BusLogic_HostAdapter_T * HostAdapter)148 static void BusLogic_AnnounceDriver(BusLogic_HostAdapter_T *HostAdapter)
149 {
150 BusLogic_Announce("***** BusLogic SCSI Driver Version "
151 BusLogic_DriverVersion " of "
152 BusLogic_DriverDate " *****\n", HostAdapter);
153 BusLogic_Announce("Copyright 1995-1998 by Leonard N. Zubkoff "
154 "<lnz@dandelion.com>\n", HostAdapter);
155 }
156
157
158 /*
159 BusLogic_DriverInfo returns the Host Adapter Name to identify this SCSI
160 Driver and Host Adapter.
161 */
162
BusLogic_DriverInfo(SCSI_Host_T * Host)163 const char *BusLogic_DriverInfo(SCSI_Host_T *Host)
164 {
165 BusLogic_HostAdapter_T *HostAdapter =
166 (BusLogic_HostAdapter_T *) Host->hostdata;
167 return HostAdapter->FullModelName;
168 }
169
170
171 /*
172 BusLogic_RegisterHostAdapter adds Host Adapter to the list of registered
173 BusLogic Host Adapters.
174 */
175
BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T * HostAdapter)176 static void BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
177 {
178 HostAdapter->Next = NULL;
179 if (BusLogic_FirstRegisteredHostAdapter == NULL)
180 {
181 BusLogic_FirstRegisteredHostAdapter = HostAdapter;
182 BusLogic_LastRegisteredHostAdapter = HostAdapter;
183 }
184 else
185 {
186 BusLogic_LastRegisteredHostAdapter->Next = HostAdapter;
187 BusLogic_LastRegisteredHostAdapter = HostAdapter;
188 }
189 }
190
191
192 /*
193 BusLogic_UnregisterHostAdapter removes Host Adapter from the list of
194 registered BusLogic Host Adapters.
195 */
196
BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T * HostAdapter)197 static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
198 {
199 if (HostAdapter == BusLogic_FirstRegisteredHostAdapter)
200 {
201 BusLogic_FirstRegisteredHostAdapter =
202 BusLogic_FirstRegisteredHostAdapter->Next;
203 if (HostAdapter == BusLogic_LastRegisteredHostAdapter)
204 BusLogic_LastRegisteredHostAdapter = NULL;
205 }
206 else
207 {
208 BusLogic_HostAdapter_T *PreviousHostAdapter =
209 BusLogic_FirstRegisteredHostAdapter;
210 while (PreviousHostAdapter != NULL &&
211 PreviousHostAdapter->Next != HostAdapter)
212 PreviousHostAdapter = PreviousHostAdapter->Next;
213 if (PreviousHostAdapter != NULL)
214 PreviousHostAdapter->Next = HostAdapter->Next;
215 }
216 HostAdapter->Next = NULL;
217 }
218
219
220 /*
221 BusLogic_InitializeCCBs initializes a group of Command Control Blocks (CCBs)
222 for Host Adapter from the BlockSize bytes located at BlockPointer. The newly
223 created CCBs are added to Host Adapter's free list.
224 */
225
BusLogic_InitializeCCBs(BusLogic_HostAdapter_T * HostAdapter,void * BlockPointer,int BlockSize)226 static void BusLogic_InitializeCCBs(BusLogic_HostAdapter_T *HostAdapter,
227 void *BlockPointer, int BlockSize)
228 {
229 BusLogic_CCB_T *CCB = (BusLogic_CCB_T *) BlockPointer;
230 memset(BlockPointer, 0, BlockSize);
231 CCB->AllocationGroupHead = true;
232 while ((BlockSize -= sizeof(BusLogic_CCB_T)) >= 0)
233 {
234 CCB->Status = BusLogic_CCB_Free;
235 CCB->HostAdapter = HostAdapter;
236 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
237 {
238 CCB->CallbackFunction = BusLogic_QueueCompletedCCB;
239 CCB->BaseAddress = HostAdapter->FlashPointInfo.BaseAddress;
240 }
241 CCB->Next = HostAdapter->Free_CCBs;
242 CCB->NextAll = HostAdapter->All_CCBs;
243 HostAdapter->Free_CCBs = CCB;
244 HostAdapter->All_CCBs = CCB;
245 HostAdapter->AllocatedCCBs++;
246 CCB++;
247 }
248 }
249
250
251 /*
252 BusLogic_CreateInitialCCBs allocates the initial CCBs for Host Adapter.
253 */
254
BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T * HostAdapter)255 static boolean BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T *HostAdapter)
256 {
257 int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(BusLogic_CCB_T);
258 while (HostAdapter->AllocatedCCBs < HostAdapter->InitialCCBs)
259 {
260 void *BlockPointer = kmalloc(BlockSize,
261 (HostAdapter->BounceBuffersRequired
262 ? GFP_ATOMIC | GFP_DMA
263 : GFP_ATOMIC));
264 if (BlockPointer == NULL)
265 {
266 BusLogic_Error("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n",
267 HostAdapter);
268 return false;
269 }
270 BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize);
271 }
272 return true;
273 }
274
275
276 /*
277 BusLogic_DestroyCCBs deallocates the CCBs for Host Adapter.
278 */
279
BusLogic_DestroyCCBs(BusLogic_HostAdapter_T * HostAdapter)280 static void BusLogic_DestroyCCBs(BusLogic_HostAdapter_T *HostAdapter)
281 {
282 BusLogic_CCB_T *NextCCB = HostAdapter->All_CCBs, *CCB;
283 HostAdapter->All_CCBs = NULL;
284 HostAdapter->Free_CCBs = NULL;
285 while ((CCB = NextCCB) != NULL)
286 {
287 NextCCB = CCB->NextAll;
288 if (CCB->AllocationGroupHead)
289 kfree(CCB);
290 }
291 }
292
293
294 /*
295 BusLogic_CreateAdditionalCCBs allocates Additional CCBs for Host Adapter. If
296 allocation fails and there are no remaining CCBs available, the Driver Queue
297 Depth is decreased to a known safe value to avoid potential deadlocks when
298 multiple host adapters share the same IRQ Channel.
299 */
300
BusLogic_CreateAdditionalCCBs(BusLogic_HostAdapter_T * HostAdapter,int AdditionalCCBs,boolean SuccessMessageP)301 static void BusLogic_CreateAdditionalCCBs(BusLogic_HostAdapter_T *HostAdapter,
302 int AdditionalCCBs,
303 boolean SuccessMessageP)
304 {
305 int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(BusLogic_CCB_T);
306 int PreviouslyAllocated = HostAdapter->AllocatedCCBs;
307 if (AdditionalCCBs <= 0) return;
308 while (HostAdapter->AllocatedCCBs - PreviouslyAllocated < AdditionalCCBs)
309 {
310 void *BlockPointer = kmalloc(BlockSize,
311 (HostAdapter->BounceBuffersRequired
312 ? GFP_ATOMIC | GFP_DMA
313 : GFP_ATOMIC));
314 if (BlockPointer == NULL) break;
315 BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize);
316 }
317 if (HostAdapter->AllocatedCCBs > PreviouslyAllocated)
318 {
319 if (SuccessMessageP)
320 BusLogic_Notice("Allocated %d additional CCBs (total now %d)\n",
321 HostAdapter,
322 HostAdapter->AllocatedCCBs - PreviouslyAllocated,
323 HostAdapter->AllocatedCCBs);
324 return;
325 }
326 BusLogic_Notice("Failed to allocate additional CCBs\n", HostAdapter);
327 if (HostAdapter->DriverQueueDepth >
328 HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount)
329 {
330 HostAdapter->DriverQueueDepth =
331 HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount;
332 HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth;
333 }
334 }
335
336
337 /*
338 BusLogic_AllocateCCB allocates a CCB from Host Adapter's free list,
339 allocating more memory from the Kernel if necessary. The Host Adapter's
340 Lock should already have been acquired by the caller.
341 */
342
BusLogic_AllocateCCB(BusLogic_HostAdapter_T * HostAdapter)343 static BusLogic_CCB_T *BusLogic_AllocateCCB(BusLogic_HostAdapter_T
344 *HostAdapter)
345 {
346 static unsigned long SerialNumber = 0;
347 BusLogic_CCB_T *CCB;
348 CCB = HostAdapter->Free_CCBs;
349 if (CCB != NULL)
350 {
351 CCB->SerialNumber = ++SerialNumber;
352 HostAdapter->Free_CCBs = CCB->Next;
353 CCB->Next = NULL;
354 if (HostAdapter->Free_CCBs == NULL)
355 BusLogic_CreateAdditionalCCBs(HostAdapter,
356 HostAdapter->IncrementalCCBs,
357 true);
358 return CCB;
359 }
360 BusLogic_CreateAdditionalCCBs(HostAdapter,
361 HostAdapter->IncrementalCCBs,
362 true);
363 CCB = HostAdapter->Free_CCBs;
364 if (CCB == NULL) return NULL;
365 CCB->SerialNumber = ++SerialNumber;
366 HostAdapter->Free_CCBs = CCB->Next;
367 CCB->Next = NULL;
368 return CCB;
369 }
370
371
372 /*
373 BusLogic_DeallocateCCB deallocates a CCB, returning it to the Host Adapter's
374 free list. The Host Adapter's Lock should already have been acquired by the
375 caller.
376 */
377
BusLogic_DeallocateCCB(BusLogic_CCB_T * CCB)378 static void BusLogic_DeallocateCCB(BusLogic_CCB_T *CCB)
379 {
380 BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
381 CCB->Command = NULL;
382 CCB->Status = BusLogic_CCB_Free;
383 CCB->Next = HostAdapter->Free_CCBs;
384 HostAdapter->Free_CCBs = CCB;
385 }
386
387
388 /*
389 BusLogic_Command sends the command OperationCode to HostAdapter, optionally
390 providing ParameterLength bytes of ParameterData and receiving at most
391 ReplyLength bytes of ReplyData; any excess reply data is received but
392 discarded.
393
394 On success, this function returns the number of reply bytes read from
395 the Host Adapter (including any discarded data); on failure, it returns
396 -1 if the command was invalid, or -2 if a timeout occurred.
397
398 BusLogic_Command is called exclusively during host adapter detection and
399 initialization, so performance and latency are not critical, and exclusive
400 access to the Host Adapter hardware is assumed. Once the host adapter and
401 driver are initialized, the only Host Adapter command that is issued is the
402 single byte Execute Mailbox Command operation code, which does not require
403 waiting for the Host Adapter Ready bit to be set in the Status Register.
404 */
405
BusLogic_Command(BusLogic_HostAdapter_T * HostAdapter,BusLogic_OperationCode_T OperationCode,void * ParameterData,int ParameterLength,void * ReplyData,int ReplyLength)406 static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter,
407 BusLogic_OperationCode_T OperationCode,
408 void *ParameterData,
409 int ParameterLength,
410 void *ReplyData,
411 int ReplyLength)
412 {
413 unsigned char *ParameterPointer = (unsigned char *) ParameterData;
414 unsigned char *ReplyPointer = (unsigned char *) ReplyData;
415 BusLogic_StatusRegister_T StatusRegister;
416 BusLogic_InterruptRegister_T InterruptRegister;
417 ProcessorFlags_T ProcessorFlags = 0;
418 int ReplyBytes = 0, Result;
419 long TimeoutCounter;
420 /*
421 Clear out the Reply Data if provided.
422 */
423 if (ReplyLength > 0)
424 memset(ReplyData, 0, ReplyLength);
425 /*
426 If the IRQ Channel has not yet been acquired, then interrupts must be
427 disabled while issuing host adapter commands since a Command Complete
428 interrupt could occur if the IRQ Channel was previously enabled by another
429 BusLogic Host Adapter or another driver sharing the same IRQ Channel.
430 */
431 if (!HostAdapter->IRQ_ChannelAcquired)
432 {
433 save_flags(ProcessorFlags);
434 cli();
435 }
436 /*
437 Wait for the Host Adapter Ready bit to be set and the Command/Parameter
438 Register Busy bit to be reset in the Status Register.
439 */
440 TimeoutCounter = 10000;
441 while (--TimeoutCounter >= 0)
442 {
443 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
444 if (StatusRegister.Bits.HostAdapterReady &&
445 !StatusRegister.Bits.CommandParameterRegisterBusy)
446 break;
447 udelay(100);
448 }
449 if (TimeoutCounter < 0)
450 {
451 BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";
452 Result = -2;
453 goto Done;
454 }
455 /*
456 Write the OperationCode to the Command/Parameter Register.
457 */
458 HostAdapter->HostAdapterCommandCompleted = false;
459 BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);
460 /*
461 Write any additional Parameter Bytes.
462 */
463 TimeoutCounter = 10000;
464 while (ParameterLength > 0 && --TimeoutCounter >= 0)
465 {
466 /*
467 Wait 100 microseconds to give the Host Adapter enough time to determine
468 whether the last value written to the Command/Parameter Register was
469 valid or not. If the Command Complete bit is set in the Interrupt
470 Register, then the Command Invalid bit in the Status Register will be
471 reset if the Operation Code or Parameter was valid and the command
472 has completed, or set if the Operation Code or Parameter was invalid.
473 If the Data In Register Ready bit is set in the Status Register, then
474 the Operation Code was valid, and data is waiting to be read back
475 from the Host Adapter. Otherwise, wait for the Command/Parameter
476 Register Busy bit in the Status Register to be reset.
477 */
478 udelay(100);
479 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
480 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
481 if (InterruptRegister.Bits.CommandComplete) break;
482 if (HostAdapter->HostAdapterCommandCompleted) break;
483 if (StatusRegister.Bits.DataInRegisterReady) break;
484 if (StatusRegister.Bits.CommandParameterRegisterBusy) continue;
485 BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++);
486 ParameterLength--;
487 }
488 if (TimeoutCounter < 0)
489 {
490 BusLogic_CommandFailureReason =
491 "Timeout waiting for Parameter Acceptance";
492 Result = -2;
493 goto Done;
494 }
495 /*
496 The Modify I/O Address command does not cause a Command Complete Interrupt.
497 */
498 if (OperationCode == BusLogic_ModifyIOAddress)
499 {
500 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
501 if (StatusRegister.Bits.CommandInvalid)
502 {
503 BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
504 Result = -1;
505 goto Done;
506 }
507 if (BusLogic_GlobalOptions.TraceConfiguration)
508 BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: "
509 "(Modify I/O Address)\n", HostAdapter,
510 OperationCode, StatusRegister.All);
511 Result = 0;
512 goto Done;
513 }
514 /*
515 Select an appropriate timeout value for awaiting command completion.
516 */
517 switch (OperationCode)
518 {
519 case BusLogic_InquireInstalledDevicesID0to7:
520 case BusLogic_InquireInstalledDevicesID8to15:
521 case BusLogic_InquireTargetDevices:
522 /* Approximately 60 seconds. */
523 TimeoutCounter = 60*10000;
524 break;
525 default:
526 /* Approximately 1 second. */
527 TimeoutCounter = 10000;
528 break;
529 }
530 /*
531 Receive any Reply Bytes, waiting for either the Command Complete bit to
532 be set in the Interrupt Register, or for the Interrupt Handler to set the
533 Host Adapter Command Completed bit in the Host Adapter structure.
534 */
535 while (--TimeoutCounter >= 0)
536 {
537 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
538 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
539 if (InterruptRegister.Bits.CommandComplete) break;
540 if (HostAdapter->HostAdapterCommandCompleted) break;
541 if (StatusRegister.Bits.DataInRegisterReady)
542 {
543 if (++ReplyBytes <= ReplyLength)
544 *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
545 else BusLogic_ReadDataInRegister(HostAdapter);
546 }
547 if (OperationCode == BusLogic_FetchHostAdapterLocalRAM &&
548 StatusRegister.Bits.HostAdapterReady) break;
549 udelay(100);
550 }
551 if (TimeoutCounter < 0)
552 {
553 BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";
554 Result = -2;
555 goto Done;
556 }
557 /*
558 Clear any pending Command Complete Interrupt.
559 */
560 BusLogic_InterruptReset(HostAdapter);
561 /*
562 Provide tracing information if requested.
563 */
564 if (BusLogic_GlobalOptions.TraceConfiguration)
565 {
566 int i;
567 BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:",
568 HostAdapter, OperationCode,
569 StatusRegister.All, ReplyLength, ReplyBytes);
570 if (ReplyLength > ReplyBytes) ReplyLength = ReplyBytes;
571 for (i = 0; i < ReplyLength; i++)
572 BusLogic_Notice(" %02X", HostAdapter,
573 ((unsigned char *) ReplyData)[i]);
574 BusLogic_Notice("\n", HostAdapter);
575 }
576 /*
577 Process Command Invalid conditions.
578 */
579 if (StatusRegister.Bits.CommandInvalid)
580 {
581 /*
582 Some early BusLogic Host Adapters may not recover properly from
583 a Command Invalid condition, so if this appears to be the case,
584 a Soft Reset is issued to the Host Adapter. Potentially invalid
585 commands are never attempted after Mailbox Initialization is
586 performed, so there should be no Host Adapter state lost by a
587 Soft Reset in response to a Command Invalid condition.
588 */
589 udelay(1000);
590 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
591 if (StatusRegister.Bits.CommandInvalid ||
592 StatusRegister.Bits.Reserved ||
593 StatusRegister.Bits.DataInRegisterReady ||
594 StatusRegister.Bits.CommandParameterRegisterBusy ||
595 !StatusRegister.Bits.HostAdapterReady ||
596 !StatusRegister.Bits.InitializationRequired ||
597 StatusRegister.Bits.DiagnosticActive ||
598 StatusRegister.Bits.DiagnosticFailure)
599 {
600 BusLogic_SoftReset(HostAdapter);
601 udelay(1000);
602 }
603 BusLogic_CommandFailureReason = "Command Invalid";
604 Result = -1;
605 goto Done;
606 }
607 /*
608 Handle Excess Parameters Supplied conditions.
609 */
610 if (ParameterLength > 0)
611 {
612 BusLogic_CommandFailureReason = "Excess Parameters Supplied";
613 Result = -1;
614 goto Done;
615 }
616 /*
617 Indicate the command completed successfully.
618 */
619 BusLogic_CommandFailureReason = NULL;
620 Result = ReplyBytes;
621 /*
622 Restore the interrupt status if necessary and return.
623 */
624 Done:
625 if (!HostAdapter->IRQ_ChannelAcquired)
626 restore_flags(ProcessorFlags);
627 return Result;
628 }
629
630
631 /*
632 BusLogic_AppendProbeAddressISA appends a single ISA I/O Address to the list
633 of I/O Address and Bus Probe Information to be checked for potential BusLogic
634 Host Adapters.
635 */
636
BusLogic_AppendProbeAddressISA(BusLogic_IO_Address_T IO_Address)637 static void BusLogic_AppendProbeAddressISA(BusLogic_IO_Address_T IO_Address)
638 {
639 BusLogic_ProbeInfo_T *ProbeInfo;
640 if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) return;
641 ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
642 ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
643 ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
644 ProbeInfo->IO_Address = IO_Address;
645 }
646
647
648 /*
649 BusLogic_InitializeProbeInfoListISA initializes the list of I/O Address and
650 Bus Probe Information to be checked for potential BusLogic SCSI Host Adapters
651 only from the list of standard BusLogic MultiMaster ISA I/O Addresses.
652 */
653
BusLogic_InitializeProbeInfoListISA(BusLogic_HostAdapter_T * PrototypeHostAdapter)654 static void BusLogic_InitializeProbeInfoListISA(BusLogic_HostAdapter_T
655 *PrototypeHostAdapter)
656 {
657 /*
658 If BusLogic Driver Options specifications requested that ISA Bus Probes
659 be inhibited, do not proceed further.
660 */
661 if (BusLogic_ProbeOptions.NoProbeISA) return;
662 /*
663 Append the list of standard BusLogic MultiMaster ISA I/O Addresses.
664 */
665 if (BusLogic_ProbeOptions.LimitedProbeISA
666 ? BusLogic_ProbeOptions.Probe330
667 : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0)
668 BusLogic_AppendProbeAddressISA(0x330);
669 if (BusLogic_ProbeOptions.LimitedProbeISA
670 ? BusLogic_ProbeOptions.Probe334
671 : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0)
672 BusLogic_AppendProbeAddressISA(0x334);
673 if (BusLogic_ProbeOptions.LimitedProbeISA
674 ? BusLogic_ProbeOptions.Probe230
675 : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0)
676 BusLogic_AppendProbeAddressISA(0x230);
677 if (BusLogic_ProbeOptions.LimitedProbeISA
678 ? BusLogic_ProbeOptions.Probe234
679 : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0)
680 BusLogic_AppendProbeAddressISA(0x234);
681 if (BusLogic_ProbeOptions.LimitedProbeISA
682 ? BusLogic_ProbeOptions.Probe130
683 : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0)
684 BusLogic_AppendProbeAddressISA(0x130);
685 if (BusLogic_ProbeOptions.LimitedProbeISA
686 ? BusLogic_ProbeOptions.Probe134
687 : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0)
688 BusLogic_AppendProbeAddressISA(0x134);
689 }
690
691
692 #ifdef CONFIG_PCI
693
694
695 /*
696 BusLogic_SortProbeInfo sorts a section of BusLogic_ProbeInfoList in order
697 of increasing PCI Bus and Device Number.
698 */
699
BusLogic_SortProbeInfo(BusLogic_ProbeInfo_T * ProbeInfoList,int ProbeInfoCount)700 static void BusLogic_SortProbeInfo(BusLogic_ProbeInfo_T *ProbeInfoList,
701 int ProbeInfoCount)
702 {
703 int LastInterchange = ProbeInfoCount-1, Bound, j;
704 while (LastInterchange > 0)
705 {
706 Bound = LastInterchange;
707 LastInterchange = 0;
708 for (j = 0; j < Bound; j++)
709 {
710 BusLogic_ProbeInfo_T *ProbeInfo1 = &ProbeInfoList[j];
711 BusLogic_ProbeInfo_T *ProbeInfo2 = &ProbeInfoList[j+1];
712 if (ProbeInfo1->Bus > ProbeInfo2->Bus ||
713 (ProbeInfo1->Bus == ProbeInfo2->Bus &&
714 (ProbeInfo1->Device > ProbeInfo2->Device)))
715 {
716 BusLogic_ProbeInfo_T TempProbeInfo;
717 memcpy(&TempProbeInfo, ProbeInfo1, sizeof(BusLogic_ProbeInfo_T));
718 memcpy(ProbeInfo1, ProbeInfo2, sizeof(BusLogic_ProbeInfo_T));
719 memcpy(ProbeInfo2, &TempProbeInfo, sizeof(BusLogic_ProbeInfo_T));
720 LastInterchange = j;
721 }
722 }
723 }
724 }
725
726
727 /*
728 BusLogic_InitializeMultiMasterProbeInfo initializes the list of I/O Address
729 and Bus Probe Information to be checked for potential BusLogic MultiMaster
730 SCSI Host Adapters by interrogating the PCI Configuration Space on PCI
731 machines as well as from the list of standard BusLogic MultiMaster ISA
732 I/O Addresses. It returns the number of PCI MultiMaster Host Adapters found.
733 */
734
BusLogic_InitializeMultiMasterProbeInfo(BusLogic_HostAdapter_T * PrototypeHostAdapter)735 static int BusLogic_InitializeMultiMasterProbeInfo(BusLogic_HostAdapter_T
736 *PrototypeHostAdapter)
737 {
738 BusLogic_ProbeInfo_T *PrimaryProbeInfo =
739 &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount];
740 int NonPrimaryPCIMultiMasterIndex = BusLogic_ProbeInfoCount + 1;
741 int NonPrimaryPCIMultiMasterCount = 0, PCIMultiMasterCount = 0;
742 boolean ForceBusDeviceScanningOrder = false;
743 boolean ForceBusDeviceScanningOrderChecked = false;
744 boolean StandardAddressSeen[6];
745 PCI_Device_T *PCI_Device = NULL;
746 int i;
747 if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) return 0;
748 BusLogic_ProbeInfoCount++;
749 for (i = 0; i < 6; i++)
750 StandardAddressSeen[i] = false;
751 /*
752 Iterate over the MultiMaster PCI Host Adapters. For each enumerated host
753 adapter, determine whether its ISA Compatible I/O Port is enabled and if
754 so, whether it is assigned the Primary I/O Address. A host adapter that is
755 assigned the Primary I/O Address will always be the preferred boot device.
756 The MultiMaster BIOS will first recognize a host adapter at the Primary I/O
757 Address, then any other PCI host adapters, and finally any host adapters
758 located at the remaining standard ISA I/O Addresses. When a PCI host
759 adapter is found with its ISA Compatible I/O Port enabled, a command is
760 issued to disable the ISA Compatible I/O Port, and it is noted that the
761 particular standard ISA I/O Address need not be probed.
762 */
763 PrimaryProbeInfo->IO_Address = 0;
764 while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC,
765 PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
766 PCI_Device)) != NULL)
767 {
768 BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
769 BusLogic_PCIHostAdapterInformation_T PCIHostAdapterInformation;
770 BusLogic_ModifyIOAddressRequest_T ModifyIOAddressRequest;
771 unsigned char Bus = PCI_Device->bus->number;
772 unsigned char Device = PCI_Device->devfn >> 3;
773 unsigned int IRQ_Channel;
774 unsigned long BaseAddress0;
775 unsigned long BaseAddress1;
776 BusLogic_IO_Address_T IO_Address;
777 BusLogic_PCI_Address_T PCI_Address;
778
779 if (pci_enable_device(PCI_Device))
780 continue;
781
782 IRQ_Channel = PCI_Device->irq;
783 IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0);
784 PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1);
785
786 if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM)
787 {
788 BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for "
789 "MultiMaster Host Adapter\n", NULL, BaseAddress0);
790 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
791 NULL, Bus, Device, IO_Address);
792 continue;
793 }
794 if (pci_resource_flags(PCI_Device,1) & IORESOURCE_IO)
795 {
796 BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for "
797 "MultiMaster Host Adapter\n", NULL, BaseAddress1);
798 BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n",
799 NULL, Bus, Device, PCI_Address);
800 continue;
801 }
802 if (IRQ_Channel == 0)
803 {
804 BusLogic_Error("BusLogic: IRQ Channel %d illegal for "
805 "MultiMaster Host Adapter\n", NULL, IRQ_Channel);
806 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
807 NULL, Bus, Device, IO_Address);
808 continue;
809 }
810 if (BusLogic_GlobalOptions.TraceProbe)
811 {
812 BusLogic_Notice("BusLogic: PCI MultiMaster Host Adapter "
813 "detected at\n", NULL);
814 BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address "
815 "0x%X PCI Address 0x%X\n", NULL,
816 Bus, Device, IO_Address, PCI_Address);
817 }
818 /*
819 Issue the Inquire PCI Host Adapter Information command to determine
820 the ISA Compatible I/O Port. If the ISA Compatible I/O Port is
821 known and enabled, note that the particular Standard ISA I/O
822 Address should not be probed.
823 */
824 HostAdapter->IO_Address = IO_Address;
825 BusLogic_InterruptReset(HostAdapter);
826 if (BusLogic_Command(HostAdapter,
827 BusLogic_InquirePCIHostAdapterInformation,
828 NULL, 0, &PCIHostAdapterInformation,
829 sizeof(PCIHostAdapterInformation))
830 == sizeof(PCIHostAdapterInformation))
831 {
832 if (PCIHostAdapterInformation.ISACompatibleIOPort < 6)
833 StandardAddressSeen[PCIHostAdapterInformation
834 .ISACompatibleIOPort] = true;
835 }
836 else PCIHostAdapterInformation.ISACompatibleIOPort =
837 BusLogic_IO_Disable;
838 /*
839 Issue the Modify I/O Address command to disable the ISA Compatible
840 I/O Port.
841 */
842 ModifyIOAddressRequest = BusLogic_IO_Disable;
843 BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress,
844 &ModifyIOAddressRequest,
845 sizeof(ModifyIOAddressRequest), NULL, 0);
846 /*
847 For the first MultiMaster Host Adapter enumerated, issue the Fetch
848 Host Adapter Local RAM command to read byte 45 of the AutoSCSI area,
849 for the setting of the "Use Bus And Device # For PCI Scanning Seq."
850 option. Issue the Inquire Board ID command since this option is
851 only valid for the BT-948/958/958D.
852 */
853 if (!ForceBusDeviceScanningOrderChecked)
854 {
855 BusLogic_FetchHostAdapterLocalRAMRequest_T
856 FetchHostAdapterLocalRAMRequest;
857 BusLogic_AutoSCSIByte45_T AutoSCSIByte45;
858 BusLogic_BoardID_T BoardID;
859 FetchHostAdapterLocalRAMRequest.ByteOffset =
860 BusLogic_AutoSCSI_BaseOffset + 45;
861 FetchHostAdapterLocalRAMRequest.ByteCount =
862 sizeof(AutoSCSIByte45);
863 BusLogic_Command(HostAdapter,
864 BusLogic_FetchHostAdapterLocalRAM,
865 &FetchHostAdapterLocalRAMRequest,
866 sizeof(FetchHostAdapterLocalRAMRequest),
867 &AutoSCSIByte45, sizeof(AutoSCSIByte45));
868 BusLogic_Command(HostAdapter, BusLogic_InquireBoardID,
869 NULL, 0, &BoardID, sizeof(BoardID));
870 if (BoardID.FirmwareVersion1stDigit == '5')
871 ForceBusDeviceScanningOrder =
872 AutoSCSIByte45.ForceBusDeviceScanningOrder;
873 ForceBusDeviceScanningOrderChecked = true;
874 }
875 /*
876 Determine whether this MultiMaster Host Adapter has its ISA
877 Compatible I/O Port enabled and is assigned the Primary I/O Address.
878 If it does, then it is the Primary MultiMaster Host Adapter and must
879 be recognized first. If it does not, then it is added to the list
880 for probing after any Primary MultiMaster Host Adapter is probed.
881 */
882 if (PCIHostAdapterInformation.ISACompatibleIOPort == BusLogic_IO_330)
883 {
884 PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
885 PrimaryProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
886 PrimaryProbeInfo->IO_Address = IO_Address;
887 PrimaryProbeInfo->PCI_Address = PCI_Address;
888 PrimaryProbeInfo->Bus = Bus;
889 PrimaryProbeInfo->Device = Device;
890 PrimaryProbeInfo->IRQ_Channel = IRQ_Channel;
891 PCIMultiMasterCount++;
892 }
893 else if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters)
894 {
895 BusLogic_ProbeInfo_T *ProbeInfo =
896 &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
897 ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
898 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
899 ProbeInfo->IO_Address = IO_Address;
900 ProbeInfo->PCI_Address = PCI_Address;
901 ProbeInfo->Bus = Bus;
902 ProbeInfo->Device = Device;
903 ProbeInfo->IRQ_Channel = IRQ_Channel;
904 NonPrimaryPCIMultiMasterCount++;
905 PCIMultiMasterCount++;
906 }
907 else BusLogic_Warning("BusLogic: Too many Host Adapters "
908 "detected\n", NULL);
909 }
910 /*
911 If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option is ON
912 for the first enumerated MultiMaster Host Adapter, and if that host adapter
913 is a BT-948/958/958D, then the MultiMaster BIOS will recognize MultiMaster
914 Host Adapters in the order of increasing PCI Bus and Device Number. In
915 that case, sort the probe information into the same order the BIOS uses.
916 If this option is OFF, then the MultiMaster BIOS will recognize MultiMaster
917 Host Adapters in the order they are enumerated by the PCI BIOS, and hence
918 no sorting is necessary.
919 */
920 if (ForceBusDeviceScanningOrder)
921 BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[
922 NonPrimaryPCIMultiMasterIndex],
923 NonPrimaryPCIMultiMasterCount);
924 /*
925 If no PCI MultiMaster Host Adapter is assigned the Primary I/O Address,
926 then the Primary I/O Address must be probed explicitly before any PCI
927 host adapters are probed.
928 */
929 if (!BusLogic_ProbeOptions.NoProbeISA)
930 if (PrimaryProbeInfo->IO_Address == 0 &&
931 (BusLogic_ProbeOptions.LimitedProbeISA
932 ? BusLogic_ProbeOptions.Probe330
933 : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0))
934 {
935 PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
936 PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
937 PrimaryProbeInfo->IO_Address = 0x330;
938 }
939 /*
940 Append the list of standard BusLogic MultiMaster ISA I/O Addresses,
941 omitting the Primary I/O Address which has already been handled.
942 */
943 if (!BusLogic_ProbeOptions.NoProbeISA)
944 {
945 if (!StandardAddressSeen[1] &&
946 (BusLogic_ProbeOptions.LimitedProbeISA
947 ? BusLogic_ProbeOptions.Probe334
948 : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0))
949 BusLogic_AppendProbeAddressISA(0x334);
950 if (!StandardAddressSeen[2] &&
951 (BusLogic_ProbeOptions.LimitedProbeISA
952 ? BusLogic_ProbeOptions.Probe230
953 : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0))
954 BusLogic_AppendProbeAddressISA(0x230);
955 if (!StandardAddressSeen[3] &&
956 (BusLogic_ProbeOptions.LimitedProbeISA
957 ? BusLogic_ProbeOptions.Probe234
958 : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0))
959 BusLogic_AppendProbeAddressISA(0x234);
960 if (!StandardAddressSeen[4] &&
961 (BusLogic_ProbeOptions.LimitedProbeISA
962 ? BusLogic_ProbeOptions.Probe130
963 : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0))
964 BusLogic_AppendProbeAddressISA(0x130);
965 if (!StandardAddressSeen[5] &&
966 (BusLogic_ProbeOptions.LimitedProbeISA
967 ? BusLogic_ProbeOptions.Probe134
968 : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0))
969 BusLogic_AppendProbeAddressISA(0x134);
970 }
971 /*
972 Iterate over the older non-compliant MultiMaster PCI Host Adapters,
973 noting the PCI bus location and assigned IRQ Channel.
974 */
975 PCI_Device = NULL;
976 while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC,
977 PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
978 PCI_Device)) != NULL)
979 {
980 unsigned char Bus = PCI_Device->bus->number;
981 unsigned char Device = PCI_Device->devfn >> 3;
982 unsigned int IRQ_Channel = PCI_Device->irq;
983 BusLogic_IO_Address_T IO_Address = pci_resource_start(PCI_Device, 0);
984
985 if (pci_enable_device(PCI_Device))
986 continue;
987
988 if (IO_Address == 0 || IRQ_Channel == 0) continue;
989 for (i = 0; i < BusLogic_ProbeInfoCount; i++)
990 {
991 BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[i];
992 if (ProbeInfo->IO_Address == IO_Address &&
993 ProbeInfo->HostAdapterType == BusLogic_MultiMaster)
994 {
995 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
996 ProbeInfo->PCI_Address = 0;
997 ProbeInfo->Bus = Bus;
998 ProbeInfo->Device = Device;
999 ProbeInfo->IRQ_Channel = IRQ_Channel;
1000 break;
1001 }
1002 }
1003 }
1004 return PCIMultiMasterCount;
1005 }
1006
1007
1008 /*
1009 BusLogic_InitializeFlashPointProbeInfo initializes the list of I/O Address
1010 and Bus Probe Information to be checked for potential BusLogic FlashPoint
1011 Host Adapters by interrogating the PCI Configuration Space. It returns the
1012 number of FlashPoint Host Adapters found.
1013 */
1014
BusLogic_InitializeFlashPointProbeInfo(BusLogic_HostAdapter_T * PrototypeHostAdapter)1015 static int BusLogic_InitializeFlashPointProbeInfo(BusLogic_HostAdapter_T
1016 *PrototypeHostAdapter)
1017 {
1018 int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0;
1019 PCI_Device_T *PCI_Device = NULL;
1020 /*
1021 Interrogate PCI Configuration Space for any FlashPoint Host Adapters.
1022 */
1023 while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC,
1024 PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
1025 PCI_Device)) != NULL)
1026 {
1027 unsigned char Bus = PCI_Device->bus->number;
1028 unsigned char Device = PCI_Device->devfn >> 3;
1029 unsigned int IRQ_Channel = PCI_Device->irq;
1030 unsigned long BaseAddress0 = pci_resource_start(PCI_Device, 0);
1031 unsigned long BaseAddress1 = pci_resource_start(PCI_Device, 1);
1032 BusLogic_IO_Address_T IO_Address = BaseAddress0;
1033 BusLogic_PCI_Address_T PCI_Address = BaseAddress1;
1034
1035 if (pci_enable_device(PCI_Device))
1036 continue;
1037
1038 #ifndef CONFIG_SCSI_OMIT_FLASHPOINT
1039 if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM)
1040 {
1041 BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for "
1042 "FlashPoint Host Adapter\n", NULL, BaseAddress0);
1043 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
1044 NULL, Bus, Device, IO_Address);
1045 continue;
1046 }
1047 if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO)
1048 {
1049 BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for "
1050 "FlashPoint Host Adapter\n", NULL, BaseAddress1);
1051 BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n",
1052 NULL, Bus, Device, PCI_Address);
1053 continue;
1054 }
1055 if (IRQ_Channel == 0)
1056 {
1057 BusLogic_Error("BusLogic: IRQ Channel %d illegal for "
1058 "FlashPoint Host Adapter\n", NULL, IRQ_Channel);
1059 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
1060 NULL, Bus, Device, IO_Address);
1061 continue;
1062 }
1063 if (BusLogic_GlobalOptions.TraceProbe)
1064 {
1065 BusLogic_Notice("BusLogic: FlashPoint Host Adapter "
1066 "detected at\n", NULL);
1067 BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address "
1068 "0x%X PCI Address 0x%X\n", NULL,
1069 Bus, Device, IO_Address, PCI_Address);
1070 }
1071 if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters)
1072 {
1073 BusLogic_ProbeInfo_T *ProbeInfo =
1074 &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
1075 ProbeInfo->HostAdapterType = BusLogic_FlashPoint;
1076 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
1077 ProbeInfo->IO_Address = IO_Address;
1078 ProbeInfo->PCI_Address = PCI_Address;
1079 ProbeInfo->Bus = Bus;
1080 ProbeInfo->Device = Device;
1081 ProbeInfo->IRQ_Channel = IRQ_Channel;
1082 FlashPointCount++;
1083 }
1084 else BusLogic_Warning("BusLogic: Too many Host Adapters "
1085 "detected\n", NULL);
1086 #else
1087 BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at "
1088 "PCI Bus %d Device %d\n", NULL, Bus, Device);
1089 BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, irq %d, "
1090 "but FlashPoint\n", NULL, IO_Address, PCI_Address, IRQ_Channel);
1091 BusLogic_Error("BusLogic: support was omitted in this kernel "
1092 "configuration.\n", NULL);
1093 #endif
1094 }
1095 /*
1096 The FlashPoint BIOS will scan for FlashPoint Host Adapters in the order of
1097 increasing PCI Bus and Device Number, so sort the probe information into
1098 the same order the BIOS uses.
1099 */
1100 BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[FlashPointIndex],
1101 FlashPointCount);
1102 return FlashPointCount;
1103 }
1104
1105
1106 /*
1107 BusLogic_InitializeProbeInfoList initializes the list of I/O Address and Bus
1108 Probe Information to be checked for potential BusLogic SCSI Host Adapters by
1109 interrogating the PCI Configuration Space on PCI machines as well as from the
1110 list of standard BusLogic MultiMaster ISA I/O Addresses. By default, if both
1111 FlashPoint and PCI MultiMaster Host Adapters are present, this driver will
1112 probe for FlashPoint Host Adapters first unless the BIOS primary disk is
1113 controlled by the first PCI MultiMaster Host Adapter, in which case
1114 MultiMaster Host Adapters will be probed first. The BusLogic Driver Options
1115 specifications "MultiMasterFirst" and "FlashPointFirst" can be used to force
1116 a particular probe order.
1117 */
1118
BusLogic_InitializeProbeInfoList(BusLogic_HostAdapter_T * PrototypeHostAdapter)1119 static void BusLogic_InitializeProbeInfoList(BusLogic_HostAdapter_T
1120 *PrototypeHostAdapter)
1121 {
1122 /*
1123 If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint
1124 Host Adapters; otherwise, default to the standard ISA MultiMaster probe.
1125 */
1126 if (!BusLogic_ProbeOptions.NoProbePCI && pci_present())
1127 {
1128 if (BusLogic_ProbeOptions.MultiMasterFirst)
1129 {
1130 BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
1131 BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
1132 }
1133 else if (BusLogic_ProbeOptions.FlashPointFirst)
1134 {
1135 BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
1136 BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
1137 }
1138 else
1139 {
1140 int FlashPointCount =
1141 BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
1142 int PCIMultiMasterCount =
1143 BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
1144 if (FlashPointCount > 0 && PCIMultiMasterCount > 0)
1145 {
1146 BusLogic_ProbeInfo_T *ProbeInfo =
1147 &BusLogic_ProbeInfoList[FlashPointCount];
1148 BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
1149 BusLogic_FetchHostAdapterLocalRAMRequest_T
1150 FetchHostAdapterLocalRAMRequest;
1151 BusLogic_BIOSDriveMapByte_T Drive0MapByte;
1152 while (ProbeInfo->HostAdapterBusType != BusLogic_PCI_Bus)
1153 ProbeInfo++;
1154 HostAdapter->IO_Address = ProbeInfo->IO_Address;
1155 FetchHostAdapterLocalRAMRequest.ByteOffset =
1156 BusLogic_BIOS_BaseOffset + BusLogic_BIOS_DriveMapOffset + 0;
1157 FetchHostAdapterLocalRAMRequest.ByteCount =
1158 sizeof(Drive0MapByte);
1159 BusLogic_Command(HostAdapter,
1160 BusLogic_FetchHostAdapterLocalRAM,
1161 &FetchHostAdapterLocalRAMRequest,
1162 sizeof(FetchHostAdapterLocalRAMRequest),
1163 &Drive0MapByte, sizeof(Drive0MapByte));
1164 /*
1165 If the Map Byte for BIOS Drive 0 indicates that BIOS Drive 0
1166 is controlled by this PCI MultiMaster Host Adapter, then
1167 reverse the probe order so that MultiMaster Host Adapters are
1168 probed before FlashPoint Host Adapters.
1169 */
1170 if (Drive0MapByte.DiskGeometry !=
1171 BusLogic_BIOS_Disk_Not_Installed)
1172 {
1173 BusLogic_ProbeInfo_T
1174 SavedProbeInfo[BusLogic_MaxHostAdapters];
1175 int MultiMasterCount =
1176 BusLogic_ProbeInfoCount - FlashPointCount;
1177 memcpy(SavedProbeInfo,
1178 BusLogic_ProbeInfoList,
1179 BusLogic_ProbeInfoCount
1180 * sizeof(BusLogic_ProbeInfo_T));
1181 memcpy(&BusLogic_ProbeInfoList[0],
1182 &SavedProbeInfo[FlashPointCount],
1183 MultiMasterCount * sizeof(BusLogic_ProbeInfo_T));
1184 memcpy(&BusLogic_ProbeInfoList[MultiMasterCount],
1185 &SavedProbeInfo[0],
1186 FlashPointCount * sizeof(BusLogic_ProbeInfo_T));
1187 }
1188 }
1189 }
1190 }
1191 else BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter);
1192 }
1193
1194
1195 #endif /* CONFIG_PCI */
1196
1197
1198 /*
1199 BusLogic_Failure prints a standardized error message, and then returns false.
1200 */
1201
BusLogic_Failure(BusLogic_HostAdapter_T * HostAdapter,char * ErrorMessage)1202 static boolean BusLogic_Failure(BusLogic_HostAdapter_T *HostAdapter,
1203 char *ErrorMessage)
1204 {
1205 BusLogic_AnnounceDriver(HostAdapter);
1206 if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus)
1207 {
1208 BusLogic_Error("While configuring BusLogic PCI Host Adapter at\n",
1209 HostAdapter);
1210 BusLogic_Error("Bus %d Device %d I/O Address 0x%X PCI Address 0x%X:\n",
1211 HostAdapter, HostAdapter->Bus, HostAdapter->Device,
1212 HostAdapter->IO_Address, HostAdapter->PCI_Address);
1213 }
1214 else BusLogic_Error("While configuring BusLogic Host Adapter at "
1215 "I/O Address 0x%X:\n", HostAdapter,
1216 HostAdapter->IO_Address);
1217 BusLogic_Error("%s FAILED - DETACHING\n", HostAdapter, ErrorMessage);
1218 if (BusLogic_CommandFailureReason != NULL)
1219 BusLogic_Error("ADDITIONAL FAILURE INFO - %s\n", HostAdapter,
1220 BusLogic_CommandFailureReason);
1221 return false;
1222 }
1223
1224
1225 /*
1226 BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter.
1227 */
1228
BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T * HostAdapter)1229 static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
1230 {
1231 BusLogic_StatusRegister_T StatusRegister;
1232 BusLogic_InterruptRegister_T InterruptRegister;
1233 BusLogic_GeometryRegister_T GeometryRegister;
1234 /*
1235 FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager.
1236 */
1237 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1238 {
1239 FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
1240 FlashPointInfo->BaseAddress =
1241 (BusLogic_Base_Address_T) HostAdapter->IO_Address;
1242 FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel;
1243 FlashPointInfo->Present = false;
1244 if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 &&
1245 FlashPointInfo->Present))
1246 {
1247 BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at "
1248 "PCI Bus %d Device %d\n", HostAdapter,
1249 HostAdapter->Bus, HostAdapter->Device);
1250 BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, "
1251 "but FlashPoint\n", HostAdapter,
1252 HostAdapter->IO_Address, HostAdapter->PCI_Address);
1253 BusLogic_Error("BusLogic: Probe Function failed to validate it.\n",
1254 HostAdapter);
1255 return false;
1256 }
1257 if (BusLogic_GlobalOptions.TraceProbe)
1258 BusLogic_Notice("BusLogic_Probe(0x%X): FlashPoint Found\n",
1259 HostAdapter, HostAdapter->IO_Address);
1260 /*
1261 Indicate the Host Adapter Probe completed successfully.
1262 */
1263 return true;
1264 }
1265 /*
1266 Read the Status, Interrupt, and Geometry Registers to test if there are I/O
1267 ports that respond, and to check the values to determine if they are from a
1268 BusLogic Host Adapter. A nonexistent I/O port will return 0xFF, in which
1269 case there is definitely no BusLogic Host Adapter at this base I/O Address.
1270 The test here is a subset of that used by the BusLogic Host Adapter BIOS.
1271 */
1272 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1273 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
1274 GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1275 if (BusLogic_GlobalOptions.TraceProbe)
1276 BusLogic_Notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, "
1277 "Geometry 0x%02X\n", HostAdapter,
1278 HostAdapter->IO_Address, StatusRegister.All,
1279 InterruptRegister.All, GeometryRegister.All);
1280 if (StatusRegister.All == 0 ||
1281 StatusRegister.Bits.DiagnosticActive ||
1282 StatusRegister.Bits.CommandParameterRegisterBusy ||
1283 StatusRegister.Bits.Reserved ||
1284 StatusRegister.Bits.CommandInvalid ||
1285 InterruptRegister.Bits.Reserved != 0)
1286 return false;
1287 /*
1288 Check the undocumented Geometry Register to test if there is an I/O port
1289 that responded. Adaptec Host Adapters do not implement the Geometry
1290 Register, so this test helps serve to avoid incorrectly recognizing an
1291 Adaptec 1542A or 1542B as a BusLogic. Unfortunately, the Adaptec 1542C
1292 series does respond to the Geometry Register I/O port, but it will be
1293 rejected later when the Inquire Extended Setup Information command is
1294 issued in BusLogic_CheckHostAdapter. The AMI FastDisk Host Adapter is a
1295 BusLogic clone that implements the same interface as earlier BusLogic
1296 Host Adapters, including the undocumented commands, and is therefore
1297 supported by this driver. However, the AMI FastDisk always returns 0x00
1298 upon reading the Geometry Register, so the extended translation option
1299 should always be left disabled on the AMI FastDisk.
1300 */
1301 if (GeometryRegister.All == 0xFF) return false;
1302 /*
1303 Indicate the Host Adapter Probe completed successfully.
1304 */
1305 return true;
1306 }
1307
1308
1309 /*
1310 BusLogic_HardwareResetHostAdapter issues a Hardware Reset to the Host Adapter
1311 and waits for Host Adapter Diagnostics to complete. If HardReset is true, a
1312 Hard Reset is performed which also initiates a SCSI Bus Reset. Otherwise, a
1313 Soft Reset is performed which only resets the Host Adapter without forcing a
1314 SCSI Bus Reset.
1315 */
1316
BusLogic_HardwareResetHostAdapter(BusLogic_HostAdapter_T * HostAdapter,boolean HardReset)1317 static boolean BusLogic_HardwareResetHostAdapter(BusLogic_HostAdapter_T
1318 *HostAdapter,
1319 boolean HardReset)
1320 {
1321 BusLogic_StatusRegister_T StatusRegister;
1322 int TimeoutCounter;
1323 /*
1324 FlashPoint Host Adapters are Hard Reset by the FlashPoint SCCB Manager.
1325 */
1326 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1327 {
1328 FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
1329 FlashPointInfo->HostSoftReset = !HardReset;
1330 FlashPointInfo->ReportDataUnderrun = true;
1331 HostAdapter->CardHandle =
1332 FlashPoint_HardwareResetHostAdapter(FlashPointInfo);
1333 if (HostAdapter->CardHandle == FlashPoint_BadCardHandle) return false;
1334 /*
1335 Indicate the Host Adapter Hard Reset completed successfully.
1336 */
1337 return true;
1338 }
1339 /*
1340 Issue a Hard Reset or Soft Reset Command to the Host Adapter. The Host
1341 Adapter should respond by setting Diagnostic Active in the Status Register.
1342 */
1343 if (HardReset)
1344 BusLogic_HardReset(HostAdapter);
1345 else BusLogic_SoftReset(HostAdapter);
1346 /*
1347 Wait until Diagnostic Active is set in the Status Register.
1348 */
1349 TimeoutCounter = 5*10000;
1350 while (--TimeoutCounter >= 0)
1351 {
1352 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1353 if (StatusRegister.Bits.DiagnosticActive) break;
1354 udelay(100);
1355 }
1356 if (BusLogic_GlobalOptions.TraceHardwareReset)
1357 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, "
1358 "Status 0x%02X\n", HostAdapter,
1359 HostAdapter->IO_Address, StatusRegister.All);
1360 if (TimeoutCounter < 0) return false;
1361 /*
1362 Wait 100 microseconds to allow completion of any initial diagnostic
1363 activity which might leave the contents of the Status Register
1364 unpredictable.
1365 */
1366 udelay(100);
1367 /*
1368 Wait until Diagnostic Active is reset in the Status Register.
1369 */
1370 TimeoutCounter = 10*10000;
1371 while (--TimeoutCounter >= 0)
1372 {
1373 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1374 if (!StatusRegister.Bits.DiagnosticActive) break;
1375 udelay(100);
1376 }
1377 if (BusLogic_GlobalOptions.TraceHardwareReset)
1378 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, "
1379 "Status 0x%02X\n", HostAdapter,
1380 HostAdapter->IO_Address, StatusRegister.All);
1381 if (TimeoutCounter < 0) return false;
1382 /*
1383 Wait until at least one of the Diagnostic Failure, Host Adapter Ready,
1384 or Data In Register Ready bits is set in the Status Register.
1385 */
1386 TimeoutCounter = 10000;
1387 while (--TimeoutCounter >= 0)
1388 {
1389 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1390 if (StatusRegister.Bits.DiagnosticFailure ||
1391 StatusRegister.Bits.HostAdapterReady ||
1392 StatusRegister.Bits.DataInRegisterReady)
1393 break;
1394 udelay(100);
1395 }
1396 if (BusLogic_GlobalOptions.TraceHardwareReset)
1397 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, "
1398 "Status 0x%02X\n", HostAdapter,
1399 HostAdapter->IO_Address, StatusRegister.All);
1400 if (TimeoutCounter < 0) return false;
1401 /*
1402 If Diagnostic Failure is set or Host Adapter Ready is reset, then an
1403 error occurred during the Host Adapter diagnostics. If Data In Register
1404 Ready is set, then there is an Error Code available.
1405 */
1406 if (StatusRegister.Bits.DiagnosticFailure ||
1407 !StatusRegister.Bits.HostAdapterReady)
1408 {
1409 BusLogic_CommandFailureReason = NULL;
1410 BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
1411 BusLogic_Error("HOST ADAPTER STATUS REGISTER = %02X\n",
1412 HostAdapter, StatusRegister.All);
1413 if (StatusRegister.Bits.DataInRegisterReady)
1414 {
1415 unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
1416 BusLogic_Error("HOST ADAPTER ERROR CODE = %d\n",
1417 HostAdapter, ErrorCode);
1418 }
1419 return false;
1420 }
1421 /*
1422 Indicate the Host Adapter Hard Reset completed successfully.
1423 */
1424 return true;
1425 }
1426
1427
1428 /*
1429 BusLogic_CheckHostAdapter checks to be sure this really is a BusLogic
1430 Host Adapter.
1431 */
1432
BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T * HostAdapter)1433 static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
1434 {
1435 BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
1436 BusLogic_RequestedReplyLength_T RequestedReplyLength;
1437 boolean Result = true;
1438 /*
1439 FlashPoint Host Adapters do not require this protection.
1440 */
1441 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
1442 /*
1443 Issue the Inquire Extended Setup Information command. Only genuine
1444 BusLogic Host Adapters and true clones support this command. Adaptec 1542C
1445 series Host Adapters that respond to the Geometry Register I/O port will
1446 fail this command.
1447 */
1448 RequestedReplyLength = sizeof(ExtendedSetupInformation);
1449 if (BusLogic_Command(HostAdapter,
1450 BusLogic_InquireExtendedSetupInformation,
1451 &RequestedReplyLength,
1452 sizeof(RequestedReplyLength),
1453 &ExtendedSetupInformation,
1454 sizeof(ExtendedSetupInformation))
1455 != sizeof(ExtendedSetupInformation))
1456 Result = false;
1457 /*
1458 Provide tracing information if requested and return.
1459 */
1460 if (BusLogic_GlobalOptions.TraceProbe)
1461 BusLogic_Notice("BusLogic_Check(0x%X): MultiMaster %s\n", HostAdapter,
1462 HostAdapter->IO_Address, (Result ? "Found" : "Not Found"));
1463 return Result;
1464 }
1465
1466
1467 /*
1468 BusLogic_ReadHostAdapterConfiguration reads the Configuration Information
1469 from Host Adapter and initializes the Host Adapter structure.
1470 */
1471
BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T * HostAdapter)1472 static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T
1473 *HostAdapter)
1474 {
1475 BusLogic_BoardID_T BoardID;
1476 BusLogic_Configuration_T Configuration;
1477 BusLogic_SetupInformation_T SetupInformation;
1478 BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
1479 BusLogic_HostAdapterModelNumber_T HostAdapterModelNumber;
1480 BusLogic_FirmwareVersion3rdDigit_T FirmwareVersion3rdDigit;
1481 BusLogic_FirmwareVersionLetter_T FirmwareVersionLetter;
1482 BusLogic_PCIHostAdapterInformation_T PCIHostAdapterInformation;
1483 BusLogic_FetchHostAdapterLocalRAMRequest_T FetchHostAdapterLocalRAMRequest;
1484 BusLogic_AutoSCSIData_T AutoSCSIData;
1485 BusLogic_GeometryRegister_T GeometryRegister;
1486 BusLogic_RequestedReplyLength_T RequestedReplyLength;
1487 unsigned char *TargetPointer, Character;
1488 int TargetID, i;
1489 /*
1490 Configuration Information for FlashPoint Host Adapters is provided in the
1491 FlashPoint_Info structure by the FlashPoint SCCB Manager's Probe Function.
1492 Initialize fields in the Host Adapter structure from the FlashPoint_Info
1493 structure.
1494 */
1495 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1496 {
1497 FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
1498 TargetPointer = HostAdapter->ModelName;
1499 *TargetPointer++ = 'B';
1500 *TargetPointer++ = 'T';
1501 *TargetPointer++ = '-';
1502 for (i = 0; i < sizeof(FlashPointInfo->ModelNumber); i++)
1503 *TargetPointer++ = FlashPointInfo->ModelNumber[i];
1504 *TargetPointer++ = '\0';
1505 strcpy(HostAdapter->FirmwareVersion, FlashPoint_FirmwareVersion);
1506 HostAdapter->SCSI_ID = FlashPointInfo->SCSI_ID;
1507 HostAdapter->ExtendedTranslationEnabled =
1508 FlashPointInfo->ExtendedTranslationEnabled;
1509 HostAdapter->ParityCheckingEnabled =
1510 FlashPointInfo->ParityCheckingEnabled;
1511 HostAdapter->BusResetEnabled = !FlashPointInfo->HostSoftReset;
1512 HostAdapter->LevelSensitiveInterrupt = true;
1513 HostAdapter->HostWideSCSI = FlashPointInfo->HostWideSCSI;
1514 HostAdapter->HostDifferentialSCSI = false;
1515 HostAdapter->HostSupportsSCAM = true;
1516 HostAdapter->HostUltraSCSI = true;
1517 HostAdapter->ExtendedLUNSupport = true;
1518 HostAdapter->TerminationInfoValid = true;
1519 HostAdapter->LowByteTerminated = FlashPointInfo->LowByteTerminated;
1520 HostAdapter->HighByteTerminated = FlashPointInfo->HighByteTerminated;
1521 HostAdapter->SCAM_Enabled = FlashPointInfo->SCAM_Enabled;
1522 HostAdapter->SCAM_Level2 = FlashPointInfo->SCAM_Level2;
1523 HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1524 HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1525 HostAdapter->MaxLogicalUnits = 32;
1526 HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1527 HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1528 HostAdapter->DriverQueueDepth = 255;
1529 HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth;
1530 HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted;
1531 HostAdapter->FastPermitted = FlashPointInfo->FastPermitted;
1532 HostAdapter->UltraPermitted = FlashPointInfo->UltraPermitted;
1533 HostAdapter->WidePermitted = FlashPointInfo->WidePermitted;
1534 HostAdapter->DisconnectPermitted = FlashPointInfo->DisconnectPermitted;
1535 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1536 goto Common;
1537 }
1538 /*
1539 Issue the Inquire Board ID command.
1540 */
1541 if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0,
1542 &BoardID, sizeof(BoardID)) != sizeof(BoardID))
1543 return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
1544 /*
1545 Issue the Inquire Configuration command.
1546 */
1547 if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0,
1548 &Configuration, sizeof(Configuration))
1549 != sizeof(Configuration))
1550 return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
1551 /*
1552 Issue the Inquire Setup Information command.
1553 */
1554 RequestedReplyLength = sizeof(SetupInformation);
1555 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
1556 &RequestedReplyLength, sizeof(RequestedReplyLength),
1557 &SetupInformation, sizeof(SetupInformation))
1558 != sizeof(SetupInformation))
1559 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
1560 /*
1561 Issue the Inquire Extended Setup Information command.
1562 */
1563 RequestedReplyLength = sizeof(ExtendedSetupInformation);
1564 if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation,
1565 &RequestedReplyLength, sizeof(RequestedReplyLength),
1566 &ExtendedSetupInformation,
1567 sizeof(ExtendedSetupInformation))
1568 != sizeof(ExtendedSetupInformation))
1569 return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
1570 /*
1571 Issue the Inquire Firmware Version 3rd Digit command.
1572 */
1573 FirmwareVersion3rdDigit = '\0';
1574 if (BoardID.FirmwareVersion1stDigit > '0')
1575 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit,
1576 NULL, 0, &FirmwareVersion3rdDigit,
1577 sizeof(FirmwareVersion3rdDigit))
1578 != sizeof(FirmwareVersion3rdDigit))
1579 return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
1580 /*
1581 Issue the Inquire Host Adapter Model Number command.
1582 */
1583 if (ExtendedSetupInformation.BusType == 'A' &&
1584 BoardID.FirmwareVersion1stDigit == '2')
1585 /* BusLogic BT-542B ISA 2.xx */
1586 strcpy(HostAdapterModelNumber, "542B");
1587 else if (ExtendedSetupInformation.BusType == 'E' &&
1588 BoardID.FirmwareVersion1stDigit == '2' &&
1589 (BoardID.FirmwareVersion2ndDigit <= '1' ||
1590 (BoardID.FirmwareVersion2ndDigit == '2' &&
1591 FirmwareVersion3rdDigit == '0')))
1592 /* BusLogic BT-742A EISA 2.1x or 2.20 */
1593 strcpy(HostAdapterModelNumber, "742A");
1594 else if (ExtendedSetupInformation.BusType == 'E' &&
1595 BoardID.FirmwareVersion1stDigit == '0')
1596 /* AMI FastDisk EISA Series 441 0.x */
1597 strcpy(HostAdapterModelNumber, "747A");
1598 else
1599 {
1600 RequestedReplyLength = sizeof(HostAdapterModelNumber);
1601 if (BusLogic_Command(HostAdapter, BusLogic_InquireHostAdapterModelNumber,
1602 &RequestedReplyLength, sizeof(RequestedReplyLength),
1603 &HostAdapterModelNumber,
1604 sizeof(HostAdapterModelNumber))
1605 != sizeof(HostAdapterModelNumber))
1606 return BusLogic_Failure(HostAdapter,
1607 "INQUIRE HOST ADAPTER MODEL NUMBER");
1608 }
1609 /*
1610 BusLogic MultiMaster Host Adapters can be identified by their model number
1611 and the major version number of their firmware as follows:
1612
1613 5.xx BusLogic "W" Series Host Adapters:
1614 BT-948/958/958D
1615 4.xx BusLogic "C" Series Host Adapters:
1616 BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
1617 3.xx BusLogic "S" Series Host Adapters:
1618 BT-747S/747D/757S/757D/445S/545S/542D
1619 BT-542B/742A (revision H)
1620 2.xx BusLogic "A" Series Host Adapters:
1621 BT-542B/742A (revision G and below)
1622 0.xx AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
1623 */
1624 /*
1625 Save the Model Name and Host Adapter Name in the Host Adapter structure.
1626 */
1627 TargetPointer = HostAdapter->ModelName;
1628 *TargetPointer++ = 'B';
1629 *TargetPointer++ = 'T';
1630 *TargetPointer++ = '-';
1631 for (i = 0; i < sizeof(HostAdapterModelNumber); i++)
1632 {
1633 Character = HostAdapterModelNumber[i];
1634 if (Character == ' ' || Character == '\0') break;
1635 *TargetPointer++ = Character;
1636 }
1637 *TargetPointer++ = '\0';
1638 /*
1639 Save the Firmware Version in the Host Adapter structure.
1640 */
1641 TargetPointer = HostAdapter->FirmwareVersion;
1642 *TargetPointer++ = BoardID.FirmwareVersion1stDigit;
1643 *TargetPointer++ = '.';
1644 *TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
1645 if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0')
1646 *TargetPointer++ = FirmwareVersion3rdDigit;
1647 *TargetPointer = '\0';
1648 /*
1649 Issue the Inquire Firmware Version Letter command.
1650 */
1651 if (strcmp(HostAdapter->FirmwareVersion, "3.3") >= 0)
1652 {
1653 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter,
1654 NULL, 0, &FirmwareVersionLetter,
1655 sizeof(FirmwareVersionLetter))
1656 != sizeof(FirmwareVersionLetter))
1657 return BusLogic_Failure(HostAdapter,
1658 "INQUIRE FIRMWARE VERSION LETTER");
1659 if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0')
1660 *TargetPointer++ = FirmwareVersionLetter;
1661 *TargetPointer = '\0';
1662 }
1663 /*
1664 Save the Host Adapter SCSI ID in the Host Adapter structure.
1665 */
1666 HostAdapter->SCSI_ID = Configuration.HostAdapterID;
1667 /*
1668 Determine the Bus Type and save it in the Host Adapter structure, determine
1669 and save the IRQ Channel if necessary, and determine and save the DMA
1670 Channel for ISA Host Adapters.
1671 */
1672 HostAdapter->HostAdapterBusType =
1673 BusLogic_HostAdapterBusTypes[HostAdapter->ModelName[3] - '4'];
1674 if (HostAdapter->IRQ_Channel == 0)
1675 {
1676 if (Configuration.IRQ_Channel9)
1677 HostAdapter->IRQ_Channel = 9;
1678 else if (Configuration.IRQ_Channel10)
1679 HostAdapter->IRQ_Channel = 10;
1680 else if (Configuration.IRQ_Channel11)
1681 HostAdapter->IRQ_Channel = 11;
1682 else if (Configuration.IRQ_Channel12)
1683 HostAdapter->IRQ_Channel = 12;
1684 else if (Configuration.IRQ_Channel14)
1685 HostAdapter->IRQ_Channel = 14;
1686 else if (Configuration.IRQ_Channel15)
1687 HostAdapter->IRQ_Channel = 15;
1688 }
1689 if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus)
1690 {
1691 if (Configuration.DMA_Channel5)
1692 HostAdapter->DMA_Channel = 5;
1693 else if (Configuration.DMA_Channel6)
1694 HostAdapter->DMA_Channel = 6;
1695 else if (Configuration.DMA_Channel7)
1696 HostAdapter->DMA_Channel = 7;
1697 }
1698 /*
1699 Determine whether Extended Translation is enabled and save it in
1700 the Host Adapter structure.
1701 */
1702 GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1703 HostAdapter->ExtendedTranslationEnabled =
1704 GeometryRegister.Bits.ExtendedTranslationEnabled;
1705 /*
1706 Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide
1707 SCSI flag, Differential SCSI flag, SCAM Supported flag, and
1708 Ultra SCSI flag in the Host Adapter structure.
1709 */
1710 HostAdapter->HostAdapterScatterGatherLimit =
1711 ExtendedSetupInformation.ScatterGatherLimit;
1712 HostAdapter->DriverScatterGatherLimit =
1713 HostAdapter->HostAdapterScatterGatherLimit;
1714 if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
1715 HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1716 if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupt)
1717 HostAdapter->LevelSensitiveInterrupt = true;
1718 HostAdapter->HostWideSCSI = ExtendedSetupInformation.HostWideSCSI;
1719 HostAdapter->HostDifferentialSCSI =
1720 ExtendedSetupInformation.HostDifferentialSCSI;
1721 HostAdapter->HostSupportsSCAM = ExtendedSetupInformation.HostSupportsSCAM;
1722 HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI;
1723 /*
1724 Determine whether Extended LUN Format CCBs are supported and save the
1725 information in the Host Adapter structure.
1726 */
1727 if (HostAdapter->FirmwareVersion[0] == '5' ||
1728 (HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI))
1729 HostAdapter->ExtendedLUNSupport = true;
1730 /*
1731 Issue the Inquire PCI Host Adapter Information command to read the
1732 Termination Information from "W" series MultiMaster Host Adapters.
1733 */
1734 if (HostAdapter->FirmwareVersion[0] == '5')
1735 {
1736 if (BusLogic_Command(HostAdapter,
1737 BusLogic_InquirePCIHostAdapterInformation,
1738 NULL, 0, &PCIHostAdapterInformation,
1739 sizeof(PCIHostAdapterInformation))
1740 != sizeof(PCIHostAdapterInformation))
1741 return BusLogic_Failure(HostAdapter,
1742 "INQUIRE PCI HOST ADAPTER INFORMATION");
1743 /*
1744 Save the Termination Information in the Host Adapter structure.
1745 */
1746 if (PCIHostAdapterInformation.GenericInfoValid)
1747 {
1748 HostAdapter->TerminationInfoValid = true;
1749 HostAdapter->LowByteTerminated =
1750 PCIHostAdapterInformation.LowByteTerminated;
1751 HostAdapter->HighByteTerminated =
1752 PCIHostAdapterInformation.HighByteTerminated;
1753 }
1754 }
1755 /*
1756 Issue the Fetch Host Adapter Local RAM command to read the AutoSCSI data
1757 from "W" and "C" series MultiMaster Host Adapters.
1758 */
1759 if (HostAdapter->FirmwareVersion[0] >= '4')
1760 {
1761 FetchHostAdapterLocalRAMRequest.ByteOffset =
1762 BusLogic_AutoSCSI_BaseOffset;
1763 FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIData);
1764 if (BusLogic_Command(HostAdapter,
1765 BusLogic_FetchHostAdapterLocalRAM,
1766 &FetchHostAdapterLocalRAMRequest,
1767 sizeof(FetchHostAdapterLocalRAMRequest),
1768 &AutoSCSIData, sizeof(AutoSCSIData))
1769 != sizeof(AutoSCSIData))
1770 return BusLogic_Failure(HostAdapter, "FETCH HOST ADAPTER LOCAL RAM");
1771 /*
1772 Save the Parity Checking Enabled, Bus Reset Enabled, and Termination
1773 Information in the Host Adapter structure.
1774 */
1775 HostAdapter->ParityCheckingEnabled = AutoSCSIData.ParityCheckingEnabled;
1776 HostAdapter->BusResetEnabled = AutoSCSIData.BusResetEnabled;
1777 if (HostAdapter->FirmwareVersion[0] == '4')
1778 {
1779 HostAdapter->TerminationInfoValid = true;
1780 HostAdapter->LowByteTerminated = AutoSCSIData.LowByteTerminated;
1781 HostAdapter->HighByteTerminated = AutoSCSIData.HighByteTerminated;
1782 }
1783 /*
1784 Save the Wide Permitted, Fast Permitted, Synchronous Permitted,
1785 Disconnect Permitted, Ultra Permitted, and SCAM Information in the
1786 Host Adapter structure.
1787 */
1788 HostAdapter->WidePermitted = AutoSCSIData.WidePermitted;
1789 HostAdapter->FastPermitted = AutoSCSIData.FastPermitted;
1790 HostAdapter->SynchronousPermitted =
1791 AutoSCSIData.SynchronousPermitted;
1792 HostAdapter->DisconnectPermitted =
1793 AutoSCSIData.DisconnectPermitted;
1794 if (HostAdapter->HostUltraSCSI)
1795 HostAdapter->UltraPermitted = AutoSCSIData.UltraPermitted;
1796 if (HostAdapter->HostSupportsSCAM)
1797 {
1798 HostAdapter->SCAM_Enabled = AutoSCSIData.SCAM_Enabled;
1799 HostAdapter->SCAM_Level2 = AutoSCSIData.SCAM_Level2;
1800 }
1801 }
1802 /*
1803 Initialize fields in the Host Adapter structure for "S" and "A" series
1804 MultiMaster Host Adapters.
1805 */
1806 if (HostAdapter->FirmwareVersion[0] < '4')
1807 {
1808 if (SetupInformation.SynchronousInitiationEnabled)
1809 {
1810 HostAdapter->SynchronousPermitted = 0xFF;
1811 if (HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)
1812 {
1813 if (ExtendedSetupInformation.Misc.FastOnEISA)
1814 HostAdapter->FastPermitted = 0xFF;
1815 if (strcmp(HostAdapter->ModelName, "BT-757") == 0)
1816 HostAdapter->WidePermitted = 0xFF;
1817 }
1818 }
1819 HostAdapter->DisconnectPermitted = 0xFF;
1820 HostAdapter->ParityCheckingEnabled =
1821 SetupInformation.ParityCheckingEnabled;
1822 HostAdapter->BusResetEnabled = true;
1823 }
1824 /*
1825 Determine the maximum number of Target IDs and Logical Units supported by
1826 this driver for Wide and Narrow Host Adapters.
1827 */
1828 HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1829 HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8);
1830 /*
1831 Select appropriate values for the Mailbox Count, Driver Queue Depth,
1832 Initial CCBs, and Incremental CCBs variables based on whether or not Strict
1833 Round Robin Mode is supported. If Strict Round Robin Mode is supported,
1834 then there is no performance degradation in using the maximum possible
1835 number of Outgoing and Incoming Mailboxes and allowing the Tagged and
1836 Untagged Queue Depths to determine the actual utilization. If Strict Round
1837 Robin Mode is not supported, then the Host Adapter must scan all the
1838 Outgoing Mailboxes whenever an Outgoing Mailbox entry is made, which can
1839 cause a substantial performance penalty. The host adapters actually have
1840 room to store the following number of CCBs internally; that is, they can
1841 internally queue and manage this many active commands on the SCSI bus
1842 simultaneously. Performance measurements demonstrate that the Driver Queue
1843 Depth should be set to the Mailbox Count, rather than the Host Adapter
1844 Queue Depth (internal CCB capacity), as it is more efficient to have the
1845 queued commands waiting in Outgoing Mailboxes if necessary than to block
1846 the process in the higher levels of the SCSI Subsystem.
1847
1848 192 BT-948/958/958D
1849 100 BT-946C/956C/956CD/747C/757C/757CD/445C
1850 50 BT-545C/540CF
1851 30 BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
1852 */
1853 if (HostAdapter->FirmwareVersion[0] == '5')
1854 HostAdapter->HostAdapterQueueDepth = 192;
1855 else if (HostAdapter->FirmwareVersion[0] == '4')
1856 HostAdapter->HostAdapterQueueDepth =
1857 (HostAdapter->HostAdapterBusType != BusLogic_ISA_Bus ? 100 : 50);
1858 else HostAdapter->HostAdapterQueueDepth = 30;
1859 if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0)
1860 {
1861 HostAdapter->StrictRoundRobinModeSupport = true;
1862 HostAdapter->MailboxCount = BusLogic_MaxMailboxes;
1863 }
1864 else
1865 {
1866 HostAdapter->StrictRoundRobinModeSupport = false;
1867 HostAdapter->MailboxCount = 32;
1868 }
1869 HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount;
1870 HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1871 HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1872 /*
1873 Tagged Queuing support is available and operates properly on all "W" series
1874 MultiMaster Host Adapters, on "C" series MultiMaster Host Adapters with
1875 firmware version 4.22 and above, and on "S" series MultiMaster Host
1876 Adapters with firmware version 3.35 and above.
1877 */
1878 HostAdapter->TaggedQueuingPermitted = 0;
1879 switch (HostAdapter->FirmwareVersion[0])
1880 {
1881 case '5':
1882 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1883 break;
1884 case '4':
1885 if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0)
1886 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1887 break;
1888 case '3':
1889 if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0)
1890 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1891 break;
1892 }
1893 /*
1894 Determine the Host Adapter BIOS Address if the BIOS is enabled and
1895 save it in the Host Adapter structure. The BIOS is disabled if the
1896 BIOS_Address is 0.
1897 */
1898 HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
1899 /*
1900 ISA Host Adapters require Bounce Buffers if there is more than 16MB memory.
1901 */
1902 if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus &&
1903 (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1904 HostAdapter->BounceBuffersRequired = true;
1905 /*
1906 BusLogic BT-445S Host Adapters prior to board revision E have a hardware
1907 bug whereby when the BIOS is enabled, transfers to/from the same address
1908 range the BIOS occupies modulo 16MB are handled incorrectly. Only properly
1909 functioning BT-445S Host Adapters have firmware version 3.37, so require
1910 that ISA Bounce Buffers be used for the buggy BT-445S models if there is
1911 more than 16MB memory.
1912 */
1913 if (HostAdapter->BIOS_Address > 0 &&
1914 strcmp(HostAdapter->ModelName, "BT-445S") == 0 &&
1915 strcmp(HostAdapter->FirmwareVersion, "3.37") < 0 &&
1916 (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1917 HostAdapter->BounceBuffersRequired = true;
1918 /*
1919 Initialize parameters common to MultiMaster and FlashPoint Host Adapters.
1920 */
1921 Common:
1922 /*
1923 Initialize the Host Adapter Full Model Name from the Model Name.
1924 */
1925 strcpy(HostAdapter->FullModelName, "BusLogic ");
1926 strcat(HostAdapter->FullModelName, HostAdapter->ModelName);
1927 /*
1928 Select an appropriate value for the Tagged Queue Depth either from a
1929 BusLogic Driver Options specification, or based on whether this Host
1930 Adapter requires that ISA Bounce Buffers be used. The Tagged Queue Depth
1931 is left at 0 for automatic determination in BusLogic_SelectQueueDepths.
1932 Initialize the Untagged Queue Depth.
1933 */
1934 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
1935 {
1936 unsigned char QueueDepth = 0;
1937 if (HostAdapter->DriverOptions != NULL &&
1938 HostAdapter->DriverOptions->QueueDepth[TargetID] > 0)
1939 QueueDepth = HostAdapter->DriverOptions->QueueDepth[TargetID];
1940 else if (HostAdapter->BounceBuffersRequired)
1941 QueueDepth = BusLogic_TaggedQueueDepthBB;
1942 HostAdapter->QueueDepth[TargetID] = QueueDepth;
1943 }
1944 if (HostAdapter->BounceBuffersRequired)
1945 HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepthBB;
1946 else HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth;
1947 if (HostAdapter->DriverOptions != NULL)
1948 HostAdapter->CommonQueueDepth =
1949 HostAdapter->DriverOptions->CommonQueueDepth;
1950 if (HostAdapter->CommonQueueDepth > 0 &&
1951 HostAdapter->CommonQueueDepth < HostAdapter->UntaggedQueueDepth)
1952 HostAdapter->UntaggedQueueDepth = HostAdapter->CommonQueueDepth;
1953 /*
1954 Tagged Queuing is only allowed if Disconnect/Reconnect is permitted.
1955 Therefore, mask the Tagged Queuing Permitted Default bits with the
1956 Disconnect/Reconnect Permitted bits.
1957 */
1958 HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted;
1959 /*
1960 Combine the default Tagged Queuing Permitted bits with any BusLogic Driver
1961 Options Tagged Queuing specification.
1962 */
1963 if (HostAdapter->DriverOptions != NULL)
1964 HostAdapter->TaggedQueuingPermitted =
1965 (HostAdapter->DriverOptions->TaggedQueuingPermitted &
1966 HostAdapter->DriverOptions->TaggedQueuingPermittedMask) |
1967 (HostAdapter->TaggedQueuingPermitted &
1968 ~HostAdapter->DriverOptions->TaggedQueuingPermittedMask);
1969 /*
1970 Select appropriate values for the Error Recovery Strategy array
1971 either from a BusLogic Driver Options specification, or using
1972 BusLogic_ErrorRecovery_Default.
1973 */
1974 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
1975 if (HostAdapter->DriverOptions != NULL)
1976 HostAdapter->ErrorRecoveryStrategy[TargetID] =
1977 HostAdapter->DriverOptions->ErrorRecoveryStrategy[TargetID];
1978 else HostAdapter->ErrorRecoveryStrategy[TargetID] =
1979 BusLogic_ErrorRecovery_Default;
1980 /*
1981 Select an appropriate value for Bus Settle Time either from a BusLogic
1982 Driver Options specification, or from BusLogic_DefaultBusSettleTime.
1983 */
1984 if (HostAdapter->DriverOptions != NULL &&
1985 HostAdapter->DriverOptions->BusSettleTime > 0)
1986 HostAdapter->BusSettleTime = HostAdapter->DriverOptions->BusSettleTime;
1987 else HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
1988 /*
1989 Indicate reading the Host Adapter Configuration completed successfully.
1990 */
1991 return true;
1992 }
1993
1994
1995 /*
1996 BusLogic_ReportHostAdapterConfiguration reports the configuration of
1997 Host Adapter.
1998 */
1999
BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T * HostAdapter)2000 static boolean BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T
2001 *HostAdapter)
2002 {
2003 unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1;
2004 unsigned short SynchronousPermitted, FastPermitted;
2005 unsigned short UltraPermitted, WidePermitted;
2006 unsigned short DisconnectPermitted, TaggedQueuingPermitted;
2007 boolean CommonSynchronousNegotiation, CommonTaggedQueueDepth;
2008 boolean CommonErrorRecovery;
2009 char SynchronousString[BusLogic_MaxTargetDevices+1];
2010 char WideString[BusLogic_MaxTargetDevices+1];
2011 char DisconnectString[BusLogic_MaxTargetDevices+1];
2012 char TaggedQueuingString[BusLogic_MaxTargetDevices+1];
2013 char ErrorRecoveryString[BusLogic_MaxTargetDevices+1];
2014 char *SynchronousMessage = SynchronousString;
2015 char *WideMessage = WideString;
2016 char *DisconnectMessage = DisconnectString;
2017 char *TaggedQueuingMessage = TaggedQueuingString;
2018 char *ErrorRecoveryMessage = ErrorRecoveryString;
2019 int TargetID;
2020 BusLogic_Info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n",
2021 HostAdapter, HostAdapter->ModelName,
2022 BusLogic_HostAdapterBusNames[HostAdapter->HostAdapterBusType],
2023 (HostAdapter->HostWideSCSI ? " Wide" : ""),
2024 (HostAdapter->HostDifferentialSCSI ? " Differential" : ""),
2025 (HostAdapter->HostUltraSCSI ? " Ultra" : ""));
2026 BusLogic_Info(" Firmware Version: %s, I/O Address: 0x%X, "
2027 "IRQ Channel: %d/%s\n", HostAdapter,
2028 HostAdapter->FirmwareVersion,
2029 HostAdapter->IO_Address, HostAdapter->IRQ_Channel,
2030 (HostAdapter->LevelSensitiveInterrupt ? "Level" : "Edge"));
2031 if (HostAdapter->HostAdapterBusType != BusLogic_PCI_Bus)
2032 {
2033 BusLogic_Info(" DMA Channel: ", HostAdapter);
2034 if (HostAdapter->DMA_Channel > 0)
2035 BusLogic_Info("%d, ", HostAdapter, HostAdapter->DMA_Channel);
2036 else BusLogic_Info("None, ", HostAdapter);
2037 if (HostAdapter->BIOS_Address > 0)
2038 BusLogic_Info("BIOS Address: 0x%X, ", HostAdapter,
2039 HostAdapter->BIOS_Address);
2040 else BusLogic_Info("BIOS Address: None, ", HostAdapter);
2041 }
2042 else
2043 {
2044 BusLogic_Info(" PCI Bus: %d, Device: %d, Address: ",
2045 HostAdapter, HostAdapter->Bus, HostAdapter->Device);
2046 if (HostAdapter->PCI_Address > 0)
2047 BusLogic_Info("0x%X, ", HostAdapter, HostAdapter->PCI_Address);
2048 else BusLogic_Info("Unassigned, ", HostAdapter);
2049 }
2050 BusLogic_Info("Host Adapter SCSI ID: %d\n", HostAdapter,
2051 HostAdapter->SCSI_ID);
2052 BusLogic_Info(" Parity Checking: %s, Extended Translation: %s\n",
2053 HostAdapter,
2054 (HostAdapter->ParityCheckingEnabled
2055 ? "Enabled" : "Disabled"),
2056 (HostAdapter->ExtendedTranslationEnabled
2057 ? "Enabled" : "Disabled"));
2058 AllTargetsMask &= ~(1 << HostAdapter->SCSI_ID);
2059 SynchronousPermitted = HostAdapter->SynchronousPermitted & AllTargetsMask;
2060 FastPermitted = HostAdapter->FastPermitted & AllTargetsMask;
2061 UltraPermitted = HostAdapter->UltraPermitted & AllTargetsMask;
2062 if ((BusLogic_MultiMasterHostAdapterP(HostAdapter) &&
2063 (HostAdapter->FirmwareVersion[0] >= '4' ||
2064 HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)) ||
2065 BusLogic_FlashPointHostAdapterP(HostAdapter))
2066 {
2067 CommonSynchronousNegotiation = false;
2068 if (SynchronousPermitted == 0)
2069 {
2070 SynchronousMessage = "Disabled";
2071 CommonSynchronousNegotiation = true;
2072 }
2073 else if (SynchronousPermitted == AllTargetsMask)
2074 {
2075 if (FastPermitted == 0)
2076 {
2077 SynchronousMessage = "Slow";
2078 CommonSynchronousNegotiation = true;
2079 }
2080 else if (FastPermitted == AllTargetsMask)
2081 {
2082 if (UltraPermitted == 0)
2083 {
2084 SynchronousMessage = "Fast";
2085 CommonSynchronousNegotiation = true;
2086 }
2087 else if (UltraPermitted == AllTargetsMask)
2088 {
2089 SynchronousMessage = "Ultra";
2090 CommonSynchronousNegotiation = true;
2091 }
2092 }
2093 }
2094 if (!CommonSynchronousNegotiation)
2095 {
2096 for (TargetID = 0;
2097 TargetID < HostAdapter->MaxTargetDevices;
2098 TargetID++)
2099 SynchronousString[TargetID] =
2100 ((!(SynchronousPermitted & (1 << TargetID))) ? 'N' :
2101 (!(FastPermitted & (1 << TargetID)) ? 'S' :
2102 (!(UltraPermitted & (1 << TargetID)) ? 'F' : 'U')));
2103 SynchronousString[HostAdapter->SCSI_ID] = '#';
2104 SynchronousString[HostAdapter->MaxTargetDevices] = '\0';
2105 }
2106 }
2107 else SynchronousMessage =
2108 (SynchronousPermitted == 0 ? "Disabled" : "Enabled");
2109 WidePermitted = HostAdapter->WidePermitted & AllTargetsMask;
2110 if (WidePermitted == 0)
2111 WideMessage = "Disabled";
2112 else if (WidePermitted == AllTargetsMask)
2113 WideMessage = "Enabled";
2114 else
2115 {
2116 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2117 WideString[TargetID] =
2118 ((WidePermitted & (1 << TargetID)) ? 'Y' : 'N');
2119 WideString[HostAdapter->SCSI_ID] = '#';
2120 WideString[HostAdapter->MaxTargetDevices] = '\0';
2121 }
2122 DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
2123 if (DisconnectPermitted == 0)
2124 DisconnectMessage = "Disabled";
2125 else if (DisconnectPermitted == AllTargetsMask)
2126 DisconnectMessage = "Enabled";
2127 else
2128 {
2129 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2130 DisconnectString[TargetID] =
2131 ((DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
2132 DisconnectString[HostAdapter->SCSI_ID] = '#';
2133 DisconnectString[HostAdapter->MaxTargetDevices] = '\0';
2134 }
2135 TaggedQueuingPermitted =
2136 HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
2137 if (TaggedQueuingPermitted == 0)
2138 TaggedQueuingMessage = "Disabled";
2139 else if (TaggedQueuingPermitted == AllTargetsMask)
2140 TaggedQueuingMessage = "Enabled";
2141 else
2142 {
2143 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2144 TaggedQueuingString[TargetID] =
2145 ((TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
2146 TaggedQueuingString[HostAdapter->SCSI_ID] = '#';
2147 TaggedQueuingString[HostAdapter->MaxTargetDevices] = '\0';
2148 }
2149 BusLogic_Info(" Synchronous Negotiation: %s, Wide Negotiation: %s\n",
2150 HostAdapter, SynchronousMessage, WideMessage);
2151 BusLogic_Info(" Disconnect/Reconnect: %s, Tagged Queuing: %s\n",
2152 HostAdapter, DisconnectMessage, TaggedQueuingMessage);
2153 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
2154 {
2155 BusLogic_Info(" Scatter/Gather Limit: %d of %d segments, "
2156 "Mailboxes: %d\n", HostAdapter,
2157 HostAdapter->DriverScatterGatherLimit,
2158 HostAdapter->HostAdapterScatterGatherLimit,
2159 HostAdapter->MailboxCount);
2160 BusLogic_Info(" Driver Queue Depth: %d, "
2161 "Host Adapter Queue Depth: %d\n",
2162 HostAdapter, HostAdapter->DriverQueueDepth,
2163 HostAdapter->HostAdapterQueueDepth);
2164 }
2165 else BusLogic_Info(" Driver Queue Depth: %d, "
2166 "Scatter/Gather Limit: %d segments\n",
2167 HostAdapter, HostAdapter->DriverQueueDepth,
2168 HostAdapter->DriverScatterGatherLimit);
2169 BusLogic_Info(" Tagged Queue Depth: ", HostAdapter);
2170 CommonTaggedQueueDepth = true;
2171 for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2172 if (HostAdapter->QueueDepth[TargetID] != HostAdapter->QueueDepth[0])
2173 {
2174 CommonTaggedQueueDepth = false;
2175 break;
2176 }
2177 if (CommonTaggedQueueDepth)
2178 {
2179 if (HostAdapter->QueueDepth[0] > 0)
2180 BusLogic_Info("%d", HostAdapter, HostAdapter->QueueDepth[0]);
2181 else BusLogic_Info("Automatic", HostAdapter);
2182 }
2183 else BusLogic_Info("Individual", HostAdapter);
2184 BusLogic_Info(", Untagged Queue Depth: %d\n", HostAdapter,
2185 HostAdapter->UntaggedQueueDepth);
2186 CommonErrorRecovery = true;
2187 for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2188 if (HostAdapter->ErrorRecoveryStrategy[TargetID] !=
2189 HostAdapter->ErrorRecoveryStrategy[0])
2190 {
2191 CommonErrorRecovery = false;
2192 break;
2193 }
2194 if (CommonErrorRecovery)
2195 ErrorRecoveryMessage =
2196 BusLogic_ErrorRecoveryStrategyNames[
2197 HostAdapter->ErrorRecoveryStrategy[0]];
2198 else
2199 {
2200 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2201 ErrorRecoveryString[TargetID] =
2202 BusLogic_ErrorRecoveryStrategyLetters[
2203 HostAdapter->ErrorRecoveryStrategy[TargetID]];
2204 ErrorRecoveryString[HostAdapter->SCSI_ID] = '#';
2205 ErrorRecoveryString[HostAdapter->MaxTargetDevices] = '\0';
2206 }
2207 BusLogic_Info(" Error Recovery Strategy: %s, SCSI Bus Reset: %s\n",
2208 HostAdapter, ErrorRecoveryMessage,
2209 (HostAdapter->BusResetEnabled ? "Enabled" : "Disabled"));
2210 if (HostAdapter->TerminationInfoValid)
2211 {
2212 if (HostAdapter->HostWideSCSI)
2213 BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter,
2214 (HostAdapter->LowByteTerminated
2215 ? (HostAdapter->HighByteTerminated
2216 ? "Both Enabled" : "Low Enabled")
2217 : (HostAdapter->HighByteTerminated
2218 ? "High Enabled" : "Both Disabled")));
2219 else BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter,
2220 (HostAdapter->LowByteTerminated ?
2221 "Enabled" : "Disabled"));
2222 if (HostAdapter->HostSupportsSCAM)
2223 BusLogic_Info(", SCAM: %s", HostAdapter,
2224 (HostAdapter->SCAM_Enabled
2225 ? (HostAdapter->SCAM_Level2
2226 ? "Enabled, Level 2" : "Enabled, Level 1")
2227 : "Disabled"));
2228 BusLogic_Info("\n", HostAdapter);
2229 }
2230 /*
2231 Indicate reporting the Host Adapter configuration completed successfully.
2232 */
2233 return true;
2234 }
2235
2236
2237 /*
2238 BusLogic_AcquireResources acquires the system resources necessary to use
2239 Host Adapter.
2240 */
2241
BusLogic_AcquireResources(BusLogic_HostAdapter_T * HostAdapter)2242 static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter)
2243 {
2244 if (HostAdapter->IRQ_Channel == 0)
2245 {
2246 BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n",
2247 HostAdapter);
2248 return false;
2249 }
2250 /*
2251 Acquire shared access to the IRQ Channel.
2252 */
2253 if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler,
2254 SA_SHIRQ, HostAdapter->FullModelName, HostAdapter) < 0)
2255 {
2256 BusLogic_Error("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
2257 HostAdapter, HostAdapter->IRQ_Channel);
2258 return false;
2259 }
2260 HostAdapter->IRQ_ChannelAcquired = true;
2261 /*
2262 Acquire exclusive access to the DMA Channel.
2263 */
2264 if (HostAdapter->DMA_Channel > 0)
2265 {
2266 if (request_dma(HostAdapter->DMA_Channel,
2267 HostAdapter->FullModelName) < 0)
2268 {
2269 BusLogic_Error("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n",
2270 HostAdapter, HostAdapter->DMA_Channel);
2271 return false;
2272 }
2273 set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
2274 enable_dma(HostAdapter->DMA_Channel);
2275 HostAdapter->DMA_ChannelAcquired = true;
2276 }
2277 /*
2278 Indicate the System Resource Acquisition completed successfully,
2279 */
2280 return true;
2281 }
2282
2283
2284 /*
2285 BusLogic_ReleaseResources releases any system resources previously acquired
2286 by BusLogic_AcquireResources.
2287 */
2288
BusLogic_ReleaseResources(BusLogic_HostAdapter_T * HostAdapter)2289 static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *HostAdapter)
2290 {
2291 /*
2292 Release shared access to the IRQ Channel.
2293 */
2294 if (HostAdapter->IRQ_ChannelAcquired)
2295 free_irq(HostAdapter->IRQ_Channel, HostAdapter);
2296 /*
2297 Release exclusive access to the DMA Channel.
2298 */
2299 if (HostAdapter->DMA_ChannelAcquired)
2300 free_dma(HostAdapter->DMA_Channel);
2301 }
2302
2303
2304 /*
2305 BusLogic_InitializeHostAdapter initializes Host Adapter. This is the only
2306 function called during SCSI Host Adapter detection which modifies the state
2307 of the Host Adapter from its initial power on or hard reset state.
2308 */
2309
BusLogic_InitializeHostAdapter(BusLogic_HostAdapter_T * HostAdapter)2310 static boolean BusLogic_InitializeHostAdapter(BusLogic_HostAdapter_T
2311 *HostAdapter)
2312 {
2313 BusLogic_ExtendedMailboxRequest_T ExtendedMailboxRequest;
2314 BusLogic_RoundRobinModeRequest_T RoundRobinModeRequest;
2315 BusLogic_SetCCBFormatRequest_T SetCCBFormatRequest;
2316 int TargetID;
2317 /*
2318 Initialize the pointers to the first and last CCBs that are queued for
2319 completion processing.
2320 */
2321 HostAdapter->FirstCompletedCCB = NULL;
2322 HostAdapter->LastCompletedCCB = NULL;
2323 /*
2324 Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active,
2325 Command Successful Flag, Active Commands, and Commands Since Reset
2326 for each Target Device.
2327 */
2328 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2329 {
2330 HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
2331 HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
2332 HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
2333 HostAdapter->ActiveCommands[TargetID] = 0;
2334 HostAdapter->CommandsSinceReset[TargetID] = 0;
2335 }
2336 /*
2337 FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes.
2338 */
2339 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) goto Done;
2340 /*
2341 Initialize the Outgoing and Incoming Mailbox pointers.
2342 */
2343 HostAdapter->FirstOutgoingMailbox =
2344 (BusLogic_OutgoingMailbox_T *) HostAdapter->MailboxSpace;
2345 HostAdapter->LastOutgoingMailbox =
2346 HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1;
2347 HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
2348 HostAdapter->FirstIncomingMailbox =
2349 (BusLogic_IncomingMailbox_T *) (HostAdapter->LastOutgoingMailbox + 1);
2350 HostAdapter->LastIncomingMailbox =
2351 HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1;
2352 HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
2353 /*
2354 Initialize the Outgoing and Incoming Mailbox structures.
2355 */
2356 memset(HostAdapter->FirstOutgoingMailbox, 0,
2357 HostAdapter->MailboxCount * sizeof(BusLogic_OutgoingMailbox_T));
2358 memset(HostAdapter->FirstIncomingMailbox, 0,
2359 HostAdapter->MailboxCount * sizeof(BusLogic_IncomingMailbox_T));
2360 /*
2361 Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes.
2362 */
2363 ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount;
2364 ExtendedMailboxRequest.BaseMailboxAddress =
2365 Virtual_to_Bus(HostAdapter->FirstOutgoingMailbox);
2366 if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox,
2367 &ExtendedMailboxRequest,
2368 sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
2369 return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION");
2370 /*
2371 Enable Strict Round Robin Mode if supported by the Host Adapter. In
2372 Strict Round Robin Mode, the Host Adapter only looks at the next Outgoing
2373 Mailbox for each new command, rather than scanning through all the
2374 Outgoing Mailboxes to find any that have new commands in them. Strict
2375 Round Robin Mode is significantly more efficient.
2376 */
2377 if (HostAdapter->StrictRoundRobinModeSupport)
2378 {
2379 RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
2380 if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode,
2381 &RoundRobinModeRequest,
2382 sizeof(RoundRobinModeRequest), NULL, 0) < 0)
2383 return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
2384 }
2385 /*
2386 For Host Adapters that support Extended LUN Format CCBs, issue the Set CCB
2387 Format command to allow 32 Logical Units per Target Device.
2388 */
2389 if (HostAdapter->ExtendedLUNSupport)
2390 {
2391 SetCCBFormatRequest = BusLogic_ExtendedLUNFormatCCB;
2392 if (BusLogic_Command(HostAdapter, BusLogic_SetCCBFormat,
2393 &SetCCBFormatRequest, sizeof(SetCCBFormatRequest),
2394 NULL, 0) < 0)
2395 return BusLogic_Failure(HostAdapter, "SET CCB FORMAT");
2396 }
2397 /*
2398 Announce Successful Initialization.
2399 */
2400 Done:
2401 if (!HostAdapter->HostAdapterInitialized)
2402 {
2403 BusLogic_Info("*** %s Initialized Successfully ***\n",
2404 HostAdapter, HostAdapter->FullModelName);
2405 BusLogic_Info("\n", HostAdapter);
2406 }
2407 else BusLogic_Warning("*** %s Initialized Successfully ***\n",
2408 HostAdapter, HostAdapter->FullModelName);
2409 HostAdapter->HostAdapterInitialized = true;
2410 /*
2411 Indicate the Host Adapter Initialization completed successfully.
2412 */
2413 return true;
2414 }
2415
2416
2417 /*
2418 BusLogic_TargetDeviceInquiry inquires about the Target Devices accessible
2419 through Host Adapter.
2420 */
2421
BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T * HostAdapter)2422 static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T
2423 *HostAdapter)
2424 {
2425 BusLogic_InstalledDevices_T InstalledDevices;
2426 BusLogic_InstalledDevices8_T InstalledDevicesID0to7;
2427 BusLogic_SetupInformation_T SetupInformation;
2428 BusLogic_SynchronousPeriod_T SynchronousPeriod;
2429 BusLogic_RequestedReplyLength_T RequestedReplyLength;
2430 int TargetID;
2431 /*
2432 Wait a few seconds between the Host Adapter Hard Reset which initiates
2433 a SCSI Bus Reset and issuing any SCSI Commands. Some SCSI devices get
2434 confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
2435 */
2436 BusLogic_Delay(HostAdapter->BusSettleTime);
2437 /*
2438 FlashPoint Host Adapters do not provide for Target Device Inquiry.
2439 */
2440 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
2441 /*
2442 Inhibit the Target Device Inquiry if requested.
2443 */
2444 if (HostAdapter->DriverOptions != NULL &&
2445 HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
2446 return true;
2447 /*
2448 Issue the Inquire Target Devices command for host adapters with firmware
2449 version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command
2450 for older host adapters. This is necessary to force Synchronous Transfer
2451 Negotiation so that the Inquire Setup Information and Inquire Synchronous
2452 Period commands will return valid data. The Inquire Target Devices command
2453 is preferable to Inquire Installed Devices ID 0 to 7 since it only probes
2454 Logical Unit 0 of each Target Device.
2455 */
2456 if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0)
2457 {
2458 if (BusLogic_Command(HostAdapter, BusLogic_InquireTargetDevices, NULL, 0,
2459 &InstalledDevices, sizeof(InstalledDevices))
2460 != sizeof(InstalledDevices))
2461 return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES");
2462 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2463 HostAdapter->TargetFlags[TargetID].TargetExists =
2464 (InstalledDevices & (1 << TargetID) ? true : false);
2465 }
2466 else
2467 {
2468 if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7,
2469 NULL, 0, &InstalledDevicesID0to7,
2470 sizeof(InstalledDevicesID0to7))
2471 != sizeof(InstalledDevicesID0to7))
2472 return BusLogic_Failure(HostAdapter,
2473 "INQUIRE INSTALLED DEVICES ID 0 TO 7");
2474 for (TargetID = 0; TargetID < 8; TargetID++)
2475 HostAdapter->TargetFlags[TargetID].TargetExists =
2476 (InstalledDevicesID0to7[TargetID] != 0 ? true : false);
2477 }
2478 /*
2479 Issue the Inquire Setup Information command.
2480 */
2481 RequestedReplyLength = sizeof(SetupInformation);
2482 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
2483 &RequestedReplyLength, sizeof(RequestedReplyLength),
2484 &SetupInformation, sizeof(SetupInformation))
2485 != sizeof(SetupInformation))
2486 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
2487 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2488 HostAdapter->SynchronousOffset[TargetID] =
2489 (TargetID < 8
2490 ? SetupInformation.SynchronousValuesID0to7[TargetID].Offset
2491 : SetupInformation.SynchronousValuesID8to15[TargetID-8].Offset);
2492 if (strcmp(HostAdapter->FirmwareVersion, "5.06L") >= 0)
2493 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2494 HostAdapter->TargetFlags[TargetID].WideTransfersActive =
2495 (TargetID < 8
2496 ? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID)
2497 ? true : false)
2498 : (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID-8))
2499 ? true : false));
2500 /*
2501 Issue the Inquire Synchronous Period command.
2502 */
2503 if (HostAdapter->FirmwareVersion[0] >= '3')
2504 {
2505 RequestedReplyLength = sizeof(SynchronousPeriod);
2506 if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod,
2507 &RequestedReplyLength, sizeof(RequestedReplyLength),
2508 &SynchronousPeriod, sizeof(SynchronousPeriod))
2509 != sizeof(SynchronousPeriod))
2510 return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
2511 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2512 HostAdapter->SynchronousPeriod[TargetID] = SynchronousPeriod[TargetID];
2513 }
2514 else
2515 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2516 if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
2517 HostAdapter->SynchronousPeriod[TargetID] =
2518 20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
2519 .TransferPeriod;
2520 /*
2521 Indicate the Target Device Inquiry completed successfully.
2522 */
2523 return true;
2524 }
2525
2526
2527 /*
2528 BusLogic_ReportTargetDeviceInfo reports about the Target Devices accessible
2529 through Host Adapter.
2530 */
2531
BusLogic_ReportTargetDeviceInfo(BusLogic_HostAdapter_T * HostAdapter)2532 static void BusLogic_ReportTargetDeviceInfo(BusLogic_HostAdapter_T
2533 *HostAdapter)
2534 {
2535 int TargetID;
2536 /*
2537 Inhibit the Target Device Inquiry and Reporting if requested.
2538 */
2539 if (BusLogic_MultiMasterHostAdapterP(HostAdapter) &&
2540 HostAdapter->DriverOptions != NULL &&
2541 HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
2542 return;
2543 /*
2544 Report on the Target Devices found.
2545 */
2546 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2547 {
2548 BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
2549 if (TargetFlags->TargetExists && !TargetFlags->TargetInfoReported)
2550 {
2551 int SynchronousTransferRate = 0;
2552 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
2553 {
2554 unsigned char WideTransfersActive;
2555 FlashPoint_InquireTargetInfo(
2556 HostAdapter->CardHandle, TargetID,
2557 &HostAdapter->SynchronousPeriod[TargetID],
2558 &HostAdapter->SynchronousOffset[TargetID],
2559 &WideTransfersActive);
2560 TargetFlags->WideTransfersActive = WideTransfersActive;
2561 }
2562 else if (TargetFlags->WideTransfersSupported &&
2563 (HostAdapter->WidePermitted & (1 << TargetID)) &&
2564 strcmp(HostAdapter->FirmwareVersion, "5.06L") < 0)
2565 TargetFlags->WideTransfersActive = true;
2566 if (HostAdapter->SynchronousPeriod[TargetID] > 0)
2567 SynchronousTransferRate =
2568 100000 / HostAdapter->SynchronousPeriod[TargetID];
2569 if (TargetFlags->WideTransfersActive)
2570 SynchronousTransferRate <<= 1;
2571 if (SynchronousTransferRate >= 9950)
2572 {
2573 SynchronousTransferRate = (SynchronousTransferRate + 50) / 100;
2574 BusLogic_Info("Target %d: Queue Depth %d, %sSynchronous at "
2575 "%d.%01d MB/sec, offset %d\n",
2576 HostAdapter, TargetID,
2577 HostAdapter->QueueDepth[TargetID],
2578 (TargetFlags->WideTransfersActive ? "Wide " : ""),
2579 SynchronousTransferRate / 10,
2580 SynchronousTransferRate % 10,
2581 HostAdapter->SynchronousOffset[TargetID]);
2582 }
2583 else if (SynchronousTransferRate > 0)
2584 {
2585 SynchronousTransferRate = (SynchronousTransferRate + 5) / 10;
2586 BusLogic_Info("Target %d: Queue Depth %d, %sSynchronous at "
2587 "%d.%02d MB/sec, offset %d\n",
2588 HostAdapter, TargetID,
2589 HostAdapter->QueueDepth[TargetID],
2590 (TargetFlags->WideTransfersActive ? "Wide " : ""),
2591 SynchronousTransferRate / 100,
2592 SynchronousTransferRate % 100,
2593 HostAdapter->SynchronousOffset[TargetID]);
2594 }
2595 else BusLogic_Info("Target %d: Queue Depth %d, Asynchronous\n",
2596 HostAdapter, TargetID,
2597 HostAdapter->QueueDepth[TargetID]);
2598 TargetFlags->TargetInfoReported = true;
2599 }
2600 }
2601 }
2602
2603
2604 /*
2605 BusLogic_InitializeHostStructure initializes the fields in the SCSI Host
2606 structure. The base, io_port, n_io_ports, irq, and dma_channel fields in the
2607 SCSI Host structure are intentionally left uninitialized, as this driver
2608 handles acquisition and release of these resources explicitly, as well as
2609 ensuring exclusive access to the Host Adapter hardware and data structures
2610 through explicit acquisition and release of the Host Adapter's Lock.
2611 */
2612
BusLogic_InitializeHostStructure(BusLogic_HostAdapter_T * HostAdapter,SCSI_Host_T * Host)2613 static void BusLogic_InitializeHostStructure(BusLogic_HostAdapter_T
2614 *HostAdapter,
2615 SCSI_Host_T *Host)
2616 {
2617 Host->max_id = HostAdapter->MaxTargetDevices;
2618 Host->max_lun = HostAdapter->MaxLogicalUnits;
2619 Host->max_channel = 0;
2620 Host->unique_id = HostAdapter->IO_Address;
2621 Host->this_id = HostAdapter->SCSI_ID;
2622 Host->can_queue = HostAdapter->DriverQueueDepth;
2623 Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
2624 Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
2625 Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth;
2626 }
2627
2628
2629 /*
2630 BusLogic_SelectQueueDepths selects Queue Depths for each Target Device based
2631 on the Host Adapter's Total Queue Depth and the number, type, speed, and
2632 capabilities of the Target Devices. When called for the last Host Adapter,
2633 it reports on the Target Device Information for all BusLogic Host Adapters
2634 since all the Target Devices have now been probed.
2635 */
2636
BusLogic_SelectQueueDepths(SCSI_Host_T * Host,SCSI_Device_T * DeviceList)2637 static void BusLogic_SelectQueueDepths(SCSI_Host_T *Host,
2638 SCSI_Device_T *DeviceList)
2639 {
2640 BusLogic_HostAdapter_T *HostAdapter =
2641 (BusLogic_HostAdapter_T *) Host->hostdata;
2642 int TaggedDeviceCount = 0, AutomaticTaggedDeviceCount = 0;
2643 int UntaggedDeviceCount = 0, AutomaticTaggedQueueDepth = 0;
2644 int AllocatedQueueDepth = 0;
2645 SCSI_Device_T *Device;
2646 int TargetID;
2647 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2648 if (HostAdapter->TargetFlags[TargetID].TargetExists)
2649 {
2650 int QueueDepth = HostAdapter->QueueDepth[TargetID];
2651 if (HostAdapter->TargetFlags[TargetID].TaggedQueuingSupported &&
2652 (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
2653 {
2654 TaggedDeviceCount++;
2655 if (QueueDepth == 0) AutomaticTaggedDeviceCount++;
2656 }
2657 else
2658 {
2659 UntaggedDeviceCount++;
2660 if (QueueDepth == 0 ||
2661 QueueDepth > HostAdapter->UntaggedQueueDepth)
2662 {
2663 QueueDepth = HostAdapter->UntaggedQueueDepth;
2664 HostAdapter->QueueDepth[TargetID] = QueueDepth;
2665 }
2666 }
2667 AllocatedQueueDepth += QueueDepth;
2668 if (QueueDepth == 1)
2669 HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
2670 }
2671 HostAdapter->TargetDeviceCount = TaggedDeviceCount + UntaggedDeviceCount;
2672 if (AutomaticTaggedDeviceCount > 0)
2673 {
2674 AutomaticTaggedQueueDepth =
2675 (HostAdapter->HostAdapterQueueDepth - AllocatedQueueDepth)
2676 / AutomaticTaggedDeviceCount;
2677 if (AutomaticTaggedQueueDepth > BusLogic_MaxAutomaticTaggedQueueDepth)
2678 AutomaticTaggedQueueDepth = BusLogic_MaxAutomaticTaggedQueueDepth;
2679 if (AutomaticTaggedQueueDepth < BusLogic_MinAutomaticTaggedQueueDepth)
2680 AutomaticTaggedQueueDepth = BusLogic_MinAutomaticTaggedQueueDepth;
2681 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2682 if (HostAdapter->TargetFlags[TargetID].TargetExists &&
2683 HostAdapter->QueueDepth[TargetID] == 0)
2684 {
2685 AllocatedQueueDepth += AutomaticTaggedQueueDepth;
2686 HostAdapter->QueueDepth[TargetID] = AutomaticTaggedQueueDepth;
2687 }
2688 }
2689 for (Device = DeviceList; Device != NULL; Device = Device->next)
2690 if (Device->host == Host)
2691 Device->queue_depth = HostAdapter->QueueDepth[Device->id];
2692 /* Allocate an extra CCB for each Target Device for a Bus Device Reset. */
2693 AllocatedQueueDepth += HostAdapter->TargetDeviceCount;
2694 if (AllocatedQueueDepth > HostAdapter->DriverQueueDepth)
2695 AllocatedQueueDepth = HostAdapter->DriverQueueDepth;
2696 BusLogic_CreateAdditionalCCBs(HostAdapter,
2697 AllocatedQueueDepth
2698 - HostAdapter->AllocatedCCBs,
2699 false);
2700 if (HostAdapter == BusLogic_LastRegisteredHostAdapter)
2701 for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
2702 HostAdapter != NULL;
2703 HostAdapter = HostAdapter->Next)
2704 BusLogic_ReportTargetDeviceInfo(HostAdapter);
2705 }
2706
2707
2708 /*
2709 BusLogic_DetectHostAdapter probes for BusLogic Host Adapters at the standard
2710 I/O Addresses where they may be located, initializing, registering, and
2711 reporting the configuration of each BusLogic Host Adapter it finds. It
2712 returns the number of BusLogic Host Adapters successfully initialized and
2713 registered.
2714 */
2715
BusLogic_DetectHostAdapter(SCSI_Host_Template_T * HostTemplate)2716 int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate)
2717 {
2718 int BusLogicHostAdapterCount = 0, DriverOptionsIndex = 0, ProbeIndex;
2719 BusLogic_HostAdapter_T *PrototypeHostAdapter;
2720 if (BusLogic_ProbeOptions.NoProbe) return 0;
2721 BusLogic_ProbeInfoList = (BusLogic_ProbeInfo_T *)
2722 kmalloc(BusLogic_MaxHostAdapters * sizeof(BusLogic_ProbeInfo_T),
2723 GFP_ATOMIC);
2724 if (BusLogic_ProbeInfoList == NULL)
2725 {
2726 BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL);
2727 return 0;
2728 }
2729 memset(BusLogic_ProbeInfoList, 0,
2730 BusLogic_MaxHostAdapters * sizeof(BusLogic_ProbeInfo_T));
2731 PrototypeHostAdapter = (BusLogic_HostAdapter_T *)
2732 kmalloc(sizeof(BusLogic_HostAdapter_T), GFP_ATOMIC);
2733 if (PrototypeHostAdapter == NULL)
2734 {
2735 kfree(BusLogic_ProbeInfoList);
2736 BusLogic_Error("BusLogic: Unable to allocate Prototype "
2737 "Host Adapter\n", NULL);
2738 return 0;
2739 }
2740 memset(PrototypeHostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
2741 #ifdef MODULE
2742 if (BusLogic != NULL)
2743 BusLogic_Setup(BusLogic);
2744 #endif
2745 BusLogic_InitializeProbeInfoList(PrototypeHostAdapter);
2746 for (ProbeIndex = 0; ProbeIndex < BusLogic_ProbeInfoCount; ProbeIndex++)
2747 {
2748 BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[ProbeIndex];
2749 BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
2750 SCSI_Host_T *Host;
2751 if (ProbeInfo->IO_Address == 0) continue;
2752 memset(HostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
2753 HostAdapter->HostAdapterType = ProbeInfo->HostAdapterType;
2754 HostAdapter->HostAdapterBusType = ProbeInfo->HostAdapterBusType;
2755 HostAdapter->IO_Address = ProbeInfo->IO_Address;
2756 HostAdapter->PCI_Address = ProbeInfo->PCI_Address;
2757 HostAdapter->Bus = ProbeInfo->Bus;
2758 HostAdapter->Device = ProbeInfo->Device;
2759 HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel;
2760 HostAdapter->AddressCount =
2761 BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType];
2762 /*
2763 Probe the Host Adapter. If unsuccessful, abort further initialization.
2764 */
2765 if (!BusLogic_ProbeHostAdapter(HostAdapter)) continue;
2766 /*
2767 Hard Reset the Host Adapter. If unsuccessful, abort further
2768 initialization.
2769 */
2770 if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) continue;
2771 /*
2772 Check the Host Adapter. If unsuccessful, abort further initialization.
2773 */
2774 if (!BusLogic_CheckHostAdapter(HostAdapter)) continue;
2775 /*
2776 Initialize the Driver Options field if provided.
2777 */
2778 if (DriverOptionsIndex < BusLogic_DriverOptionsCount)
2779 HostAdapter->DriverOptions =
2780 &BusLogic_DriverOptions[DriverOptionsIndex++];
2781 /*
2782 Announce the Driver Version and Date, Author's Name, Copyright Notice,
2783 and Electronic Mail Address.
2784 */
2785 BusLogic_AnnounceDriver(HostAdapter);
2786 /*
2787 Register usage of the I/O Address range. From this point onward, any
2788 failure will be assumed to be due to a problem with the Host Adapter,
2789 rather than due to having mistakenly identified this port as belonging
2790 to a BusLogic Host Adapter. The I/O Address range will not be
2791 released, thereby preventing it from being incorrectly identified as
2792 any other type of Host Adapter.
2793 */
2794 request_region(HostAdapter->IO_Address, HostAdapter->AddressCount,
2795 "BusLogic");
2796 /*
2797 Register the SCSI Host structure.
2798 */
2799 Host = scsi_register(HostTemplate, sizeof(BusLogic_HostAdapter_T));
2800 if(Host==NULL)
2801 {
2802 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2803 continue;
2804 }
2805 HostAdapter = (BusLogic_HostAdapter_T *) Host->hostdata;
2806 memcpy(HostAdapter, PrototypeHostAdapter, sizeof(BusLogic_HostAdapter_T));
2807 HostAdapter->SCSI_Host = Host;
2808 HostAdapter->HostNumber = Host->host_no;
2809 Host->select_queue_depths = BusLogic_SelectQueueDepths;
2810 /*
2811 Add Host Adapter to the end of the list of registered BusLogic
2812 Host Adapters.
2813 */
2814 BusLogic_RegisterHostAdapter(HostAdapter);
2815 /*
2816 Read the Host Adapter Configuration, Configure the Host Adapter,
2817 Acquire the System Resources necessary to use the Host Adapter, then
2818 Create the Initial CCBs, Initialize the Host Adapter, and finally
2819 perform Target Device Inquiry.
2820 */
2821 if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
2822 BusLogic_ReportHostAdapterConfiguration(HostAdapter) &&
2823 BusLogic_AcquireResources(HostAdapter) &&
2824 BusLogic_CreateInitialCCBs(HostAdapter) &&
2825 BusLogic_InitializeHostAdapter(HostAdapter) &&
2826 BusLogic_TargetDeviceInquiry(HostAdapter))
2827 {
2828 /*
2829 Initialization has been completed successfully. Release and
2830 re-register usage of the I/O Address range so that the Model
2831 Name of the Host Adapter will appear, and initialize the SCSI
2832 Host structure.
2833 */
2834 release_region(HostAdapter->IO_Address,
2835 HostAdapter->AddressCount);
2836 request_region(HostAdapter->IO_Address,
2837 HostAdapter->AddressCount,
2838 HostAdapter->FullModelName);
2839 BusLogic_InitializeHostStructure(HostAdapter, Host);
2840 BusLogicHostAdapterCount++;
2841 }
2842 else
2843 {
2844 /*
2845 An error occurred during Host Adapter Configuration Querying, Host
2846 Adapter Configuration, Resource Acquisition, CCB Creation, Host
2847 Adapter Initialization, or Target Device Inquiry, so remove Host
2848 Adapter from the list of registered BusLogic Host Adapters, destroy
2849 the CCBs, Release the System Resources, and Unregister the SCSI
2850 Host.
2851 */
2852 BusLogic_DestroyCCBs(HostAdapter);
2853 BusLogic_ReleaseResources(HostAdapter);
2854 BusLogic_UnregisterHostAdapter(HostAdapter);
2855 scsi_unregister(Host);
2856 }
2857 }
2858 kfree(PrototypeHostAdapter);
2859 kfree(BusLogic_ProbeInfoList);
2860 BusLogic_ProbeInfoList = NULL;
2861 return BusLogicHostAdapterCount;
2862 }
2863
2864
2865 /*
2866 BusLogic_ReleaseHostAdapter releases all resources previously acquired to
2867 support a specific Host Adapter, including the I/O Address range, and
2868 unregisters the BusLogic Host Adapter.
2869 */
2870
BusLogic_ReleaseHostAdapter(SCSI_Host_T * Host)2871 int BusLogic_ReleaseHostAdapter(SCSI_Host_T *Host)
2872 {
2873 BusLogic_HostAdapter_T *HostAdapter =
2874 (BusLogic_HostAdapter_T *) Host->hostdata;
2875 /*
2876 FlashPoint Host Adapters must first be released by the FlashPoint
2877 SCCB Manager.
2878 */
2879 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
2880 FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle);
2881 /*
2882 Destroy the CCBs and release any system resources acquired to
2883 support Host Adapter.
2884 */
2885 BusLogic_DestroyCCBs(HostAdapter);
2886 BusLogic_ReleaseResources(HostAdapter);
2887 /*
2888 Release usage of the I/O Address range.
2889 */
2890 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2891 /*
2892 Remove Host Adapter from the list of registered BusLogic Host Adapters.
2893 */
2894 BusLogic_UnregisterHostAdapter(HostAdapter);
2895 return 0;
2896 }
2897
2898
2899 /*
2900 BusLogic_QueueCompletedCCB queues CCB for completion processing.
2901 */
2902
BusLogic_QueueCompletedCCB(BusLogic_CCB_T * CCB)2903 static void BusLogic_QueueCompletedCCB(BusLogic_CCB_T *CCB)
2904 {
2905 BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
2906 CCB->Status = BusLogic_CCB_Completed;
2907 CCB->Next = NULL;
2908 if (HostAdapter->FirstCompletedCCB == NULL)
2909 {
2910 HostAdapter->FirstCompletedCCB = CCB;
2911 HostAdapter->LastCompletedCCB = CCB;
2912 }
2913 else
2914 {
2915 HostAdapter->LastCompletedCCB->Next = CCB;
2916 HostAdapter->LastCompletedCCB = CCB;
2917 }
2918 HostAdapter->ActiveCommands[CCB->TargetID]--;
2919 }
2920
2921
2922 /*
2923 BusLogic_ComputeResultCode computes a SCSI Subsystem Result Code from
2924 the Host Adapter Status and Target Device Status.
2925 */
2926
BusLogic_ComputeResultCode(BusLogic_HostAdapter_T * HostAdapter,BusLogic_HostAdapterStatus_T HostAdapterStatus,BusLogic_TargetDeviceStatus_T TargetDeviceStatus)2927 static int BusLogic_ComputeResultCode(BusLogic_HostAdapter_T *HostAdapter,
2928 BusLogic_HostAdapterStatus_T
2929 HostAdapterStatus,
2930 BusLogic_TargetDeviceStatus_T
2931 TargetDeviceStatus)
2932 {
2933 int HostStatus;
2934 switch (HostAdapterStatus)
2935 {
2936 case BusLogic_CommandCompletedNormally:
2937 case BusLogic_LinkedCommandCompleted:
2938 case BusLogic_LinkedCommandCompletedWithFlag:
2939 HostStatus = DID_OK;
2940 break;
2941 case BusLogic_SCSISelectionTimeout:
2942 HostStatus = DID_TIME_OUT;
2943 break;
2944 case BusLogic_InvalidOutgoingMailboxActionCode:
2945 case BusLogic_InvalidCommandOperationCode:
2946 case BusLogic_InvalidCommandParameter:
2947 BusLogic_Warning("BusLogic Driver Protocol Error 0x%02X\n",
2948 HostAdapter, HostAdapterStatus);
2949 case BusLogic_DataUnderRun:
2950 case BusLogic_DataOverRun:
2951 case BusLogic_UnexpectedBusFree:
2952 case BusLogic_LinkedCCBhasInvalidLUN:
2953 case BusLogic_AutoRequestSenseFailed:
2954 case BusLogic_TaggedQueuingMessageRejected:
2955 case BusLogic_UnsupportedMessageReceived:
2956 case BusLogic_HostAdapterHardwareFailed:
2957 case BusLogic_TargetDeviceReconnectedImproperly:
2958 case BusLogic_AbortQueueGenerated:
2959 case BusLogic_HostAdapterSoftwareError:
2960 case BusLogic_HostAdapterHardwareTimeoutError:
2961 case BusLogic_SCSIParityErrorDetected:
2962 HostStatus = DID_ERROR;
2963 break;
2964 case BusLogic_InvalidBusPhaseRequested:
2965 case BusLogic_TargetFailedResponseToATN:
2966 case BusLogic_HostAdapterAssertedRST:
2967 case BusLogic_OtherDeviceAssertedRST:
2968 case BusLogic_HostAdapterAssertedBusDeviceReset:
2969 HostStatus = DID_RESET;
2970 break;
2971 default:
2972 BusLogic_Warning("Unknown Host Adapter Status 0x%02X\n",
2973 HostAdapter, HostAdapterStatus);
2974 HostStatus = DID_ERROR;
2975 break;
2976 }
2977 return (HostStatus << 16) | TargetDeviceStatus;
2978 }
2979
2980
2981 /*
2982 BusLogic_ScanIncomingMailboxes scans the Incoming Mailboxes saving any
2983 Incoming Mailbox entries for completion processing.
2984 */
2985
BusLogic_ScanIncomingMailboxes(BusLogic_HostAdapter_T * HostAdapter)2986 static void BusLogic_ScanIncomingMailboxes(BusLogic_HostAdapter_T *HostAdapter)
2987 {
2988 /*
2989 Scan through the Incoming Mailboxes in Strict Round Robin fashion, saving
2990 any completed CCBs for further processing. It is essential that for each
2991 CCB and SCSI Command issued, command completion processing is performed
2992 exactly once. Therefore, only Incoming Mailboxes with completion code
2993 Command Completed Without Error, Command Completed With Error, or Command
2994 Aborted At Host Request are saved for completion processing. When an
2995 Incoming Mailbox has a completion code of Aborted Command Not Found, the
2996 CCB had already completed or been aborted before the current Abort request
2997 was processed, and so completion processing has already occurred and no
2998 further action should be taken.
2999 */
3000 BusLogic_IncomingMailbox_T *NextIncomingMailbox =
3001 HostAdapter->NextIncomingMailbox;
3002 BusLogic_CompletionCode_T CompletionCode;
3003 while ((CompletionCode = NextIncomingMailbox->CompletionCode) !=
3004 BusLogic_IncomingMailboxFree)
3005 {
3006 BusLogic_CCB_T *CCB = (BusLogic_CCB_T *)
3007 Bus_to_Virtual(NextIncomingMailbox->CCB);
3008 if (CompletionCode != BusLogic_AbortedCommandNotFound)
3009 {
3010 if (CCB->Status == BusLogic_CCB_Active ||
3011 CCB->Status == BusLogic_CCB_Reset)
3012 {
3013 /*
3014 Save the Completion Code for this CCB and queue the CCB
3015 for completion processing.
3016 */
3017 CCB->CompletionCode = CompletionCode;
3018 BusLogic_QueueCompletedCCB(CCB);
3019 }
3020 else
3021 {
3022 /*
3023 If a CCB ever appears in an Incoming Mailbox and is not marked
3024 as status Active or Reset, then there is most likely a bug in
3025 the Host Adapter firmware.
3026 */
3027 BusLogic_Warning("Illegal CCB #%ld status %d in "
3028 "Incoming Mailbox\n", HostAdapter,
3029 CCB->SerialNumber, CCB->Status);
3030 }
3031 }
3032 NextIncomingMailbox->CompletionCode = BusLogic_IncomingMailboxFree;
3033 if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
3034 NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
3035 }
3036 HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
3037 }
3038
3039
3040 /*
3041 BusLogic_ProcessCompletedCCBs iterates over the completed CCBs for Host
3042 Adapter setting the SCSI Command Result Codes, deallocating the CCBs, and
3043 calling the SCSI Subsystem Completion Routines. The Host Adapter's Lock
3044 should already have been acquired by the caller.
3045 */
3046
BusLogic_ProcessCompletedCCBs(BusLogic_HostAdapter_T * HostAdapter)3047 static void BusLogic_ProcessCompletedCCBs(BusLogic_HostAdapter_T *HostAdapter)
3048 {
3049 if (HostAdapter->ProcessCompletedCCBsActive) return;
3050 HostAdapter->ProcessCompletedCCBsActive = true;
3051 while (HostAdapter->FirstCompletedCCB != NULL)
3052 {
3053 BusLogic_CCB_T *CCB = HostAdapter->FirstCompletedCCB;
3054 SCSI_Command_T *Command = CCB->Command;
3055 HostAdapter->FirstCompletedCCB = CCB->Next;
3056 if (HostAdapter->FirstCompletedCCB == NULL)
3057 HostAdapter->LastCompletedCCB = NULL;
3058 /*
3059 Process the Completed CCB.
3060 */
3061 if (CCB->Opcode == BusLogic_BusDeviceReset)
3062 {
3063 int TargetID = CCB->TargetID;
3064 BusLogic_Warning("Bus Device Reset CCB #%ld to Target "
3065 "%d Completed\n", HostAdapter,
3066 CCB->SerialNumber, TargetID);
3067 BusLogic_IncrementErrorCounter(
3068 &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsCompleted);
3069 HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
3070 HostAdapter->CommandsSinceReset[TargetID] = 0;
3071 HostAdapter->LastResetCompleted[TargetID] = jiffies;
3072 /*
3073 Place CCB back on the Host Adapter's free list.
3074 */
3075 BusLogic_DeallocateCCB(CCB);
3076 /*
3077 Bus Device Reset CCBs have the Command field non-NULL only when a
3078 Bus Device Reset was requested for a Command that did not have a
3079 currently active CCB in the Host Adapter (i.e., a Synchronous
3080 Bus Device Reset), and hence would not have its Completion Routine
3081 called otherwise.
3082 */
3083 while (Command != NULL)
3084 {
3085 SCSI_Command_T *NextCommand = Command->reset_chain;
3086 Command->reset_chain = NULL;
3087 Command->result = DID_RESET << 16;
3088 Command->scsi_done(Command);
3089 Command = NextCommand;
3090 }
3091 /*
3092 Iterate over the CCBs for this Host Adapter performing completion
3093 processing for any CCBs marked as Reset for this Target.
3094 */
3095 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3096 if (CCB->Status == BusLogic_CCB_Reset && CCB->TargetID == TargetID)
3097 {
3098 Command = CCB->Command;
3099 BusLogic_DeallocateCCB(CCB);
3100 HostAdapter->ActiveCommands[TargetID]--;
3101 Command->result = DID_RESET << 16;
3102 Command->scsi_done(Command);
3103 }
3104 HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
3105 }
3106 else
3107 {
3108 /*
3109 Translate the Completion Code, Host Adapter Status, and Target
3110 Device Status into a SCSI Subsystem Result Code.
3111 */
3112 switch (CCB->CompletionCode)
3113 {
3114 case BusLogic_IncomingMailboxFree:
3115 case BusLogic_AbortedCommandNotFound:
3116 case BusLogic_InvalidCCB:
3117 BusLogic_Warning("CCB #%ld to Target %d Impossible State\n",
3118 HostAdapter, CCB->SerialNumber, CCB->TargetID);
3119 break;
3120 case BusLogic_CommandCompletedWithoutError:
3121 HostAdapter->TargetStatistics[CCB->TargetID]
3122 .CommandsCompleted++;
3123 HostAdapter->TargetFlags[CCB->TargetID]
3124 .CommandSuccessfulFlag = true;
3125 Command->result = DID_OK << 16;
3126 break;
3127 case BusLogic_CommandAbortedAtHostRequest:
3128 BusLogic_Warning("CCB #%ld to Target %d Aborted\n",
3129 HostAdapter, CCB->SerialNumber, CCB->TargetID);
3130 BusLogic_IncrementErrorCounter(
3131 &HostAdapter->TargetStatistics[CCB->TargetID]
3132 .CommandAbortsCompleted);
3133 Command->result = DID_ABORT << 16;
3134 break;
3135 case BusLogic_CommandCompletedWithError:
3136 Command->result =
3137 BusLogic_ComputeResultCode(HostAdapter,
3138 CCB->HostAdapterStatus,
3139 CCB->TargetDeviceStatus);
3140 if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout)
3141 {
3142 HostAdapter->TargetStatistics[CCB->TargetID]
3143 .CommandsCompleted++;
3144 if (BusLogic_GlobalOptions.TraceErrors)
3145 {
3146 int i;
3147 BusLogic_Notice("CCB #%ld Target %d: Result %X Host "
3148 "Adapter Status %02X "
3149 "Target Status %02X\n",
3150 HostAdapter, CCB->SerialNumber,
3151 CCB->TargetID, Command->result,
3152 CCB->HostAdapterStatus,
3153 CCB->TargetDeviceStatus);
3154 BusLogic_Notice("CDB ", HostAdapter);
3155 for (i = 0; i < CCB->CDB_Length; i++)
3156 BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]);
3157 BusLogic_Notice("\n", HostAdapter);
3158 BusLogic_Notice("Sense ", HostAdapter);
3159 for (i = 0; i < CCB->SenseDataLength; i++)
3160 BusLogic_Notice(" %02X", HostAdapter,
3161 Command->sense_buffer[i]);
3162 BusLogic_Notice("\n", HostAdapter);
3163 }
3164 }
3165 break;
3166 }
3167 /*
3168 When an INQUIRY command completes normally, save the
3169 CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit
3170 Wide Data Transfers Supported) bits.
3171 */
3172 if (CCB->CDB[0] == INQUIRY && CCB->CDB[1] == 0 &&
3173 CCB->HostAdapterStatus == BusLogic_CommandCompletedNormally)
3174 {
3175 BusLogic_TargetFlags_T *TargetFlags =
3176 &HostAdapter->TargetFlags[CCB->TargetID];
3177 SCSI_Inquiry_T *InquiryResult =
3178 (SCSI_Inquiry_T *) Command->request_buffer;
3179 TargetFlags->TargetExists = true;
3180 TargetFlags->TaggedQueuingSupported = InquiryResult->CmdQue;
3181 TargetFlags->WideTransfersSupported = InquiryResult->WBus16;
3182 }
3183 /*
3184 Place CCB back on the Host Adapter's free list.
3185 */
3186 BusLogic_DeallocateCCB(CCB);
3187 /*
3188 Call the SCSI Command Completion Routine.
3189 */
3190 Command->scsi_done(Command);
3191 }
3192 }
3193 HostAdapter->ProcessCompletedCCBsActive = false;
3194 }
3195
3196
3197 /*
3198 BusLogic_InterruptHandler handles hardware interrupts from BusLogic Host
3199 Adapters.
3200 */
3201
BusLogic_InterruptHandler(int IRQ_Channel,void * DeviceIdentifier,Registers_T * InterruptRegisters)3202 static void BusLogic_InterruptHandler(int IRQ_Channel,
3203 void *DeviceIdentifier,
3204 Registers_T *InterruptRegisters)
3205 {
3206 BusLogic_HostAdapter_T *HostAdapter =
3207 (BusLogic_HostAdapter_T *) DeviceIdentifier;
3208 ProcessorFlags_T ProcessorFlags;
3209 /*
3210 Acquire exclusive access to Host Adapter.
3211 */
3212 BusLogic_AcquireHostAdapterLockIH(HostAdapter, &ProcessorFlags);
3213 /*
3214 Handle Interrupts appropriately for each Host Adapter type.
3215 */
3216 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3217 {
3218 BusLogic_InterruptRegister_T InterruptRegister;
3219 /*
3220 Read the Host Adapter Interrupt Register.
3221 */
3222 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
3223 if (InterruptRegister.Bits.InterruptValid)
3224 {
3225 /*
3226 Acknowledge the interrupt and reset the Host Adapter
3227 Interrupt Register.
3228 */
3229 BusLogic_InterruptReset(HostAdapter);
3230 /*
3231 Process valid External SCSI Bus Reset and Incoming Mailbox
3232 Loaded Interrupts. Command Complete Interrupts are noted,
3233 and Outgoing Mailbox Available Interrupts are ignored, as
3234 they are never enabled.
3235 */
3236 if (InterruptRegister.Bits.ExternalBusReset)
3237 HostAdapter->HostAdapterExternalReset = true;
3238 else if (InterruptRegister.Bits.IncomingMailboxLoaded)
3239 BusLogic_ScanIncomingMailboxes(HostAdapter);
3240 else if (InterruptRegister.Bits.CommandComplete)
3241 HostAdapter->HostAdapterCommandCompleted = true;
3242 }
3243 }
3244 else
3245 {
3246 /*
3247 Check if there is a pending interrupt for this Host Adapter.
3248 */
3249 if (FlashPoint_InterruptPending(HostAdapter->CardHandle))
3250 switch (FlashPoint_HandleInterrupt(HostAdapter->CardHandle))
3251 {
3252 case FlashPoint_NormalInterrupt:
3253 break;
3254 case FlashPoint_ExternalBusReset:
3255 HostAdapter->HostAdapterExternalReset = true;
3256 break;
3257 case FlashPoint_InternalError:
3258 BusLogic_Warning("Internal FlashPoint Error detected"
3259 " - Resetting Host Adapter\n", HostAdapter);
3260 HostAdapter->HostAdapterInternalError = true;
3261 break;
3262 }
3263 }
3264 /*
3265 Process any completed CCBs.
3266 */
3267 if (HostAdapter->FirstCompletedCCB != NULL)
3268 BusLogic_ProcessCompletedCCBs(HostAdapter);
3269 /*
3270 Reset the Host Adapter if requested.
3271 */
3272 if (HostAdapter->HostAdapterExternalReset ||
3273 HostAdapter->HostAdapterInternalError)
3274 {
3275 BusLogic_ResetHostAdapter(HostAdapter, NULL, 0);
3276 HostAdapter->HostAdapterExternalReset = false;
3277 HostAdapter->HostAdapterInternalError = false;
3278 scsi_mark_host_reset(HostAdapter->SCSI_Host);
3279 }
3280 /*
3281 Release exclusive access to Host Adapter.
3282 */
3283 BusLogic_ReleaseHostAdapterLockIH(HostAdapter, &ProcessorFlags);
3284 }
3285
3286
3287 /*
3288 BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
3289 Mailbox for execution by Host Adapter. The Host Adapter's Lock should
3290 already have been acquired by the caller.
3291 */
3292
BusLogic_WriteOutgoingMailbox(BusLogic_HostAdapter_T * HostAdapter,BusLogic_ActionCode_T ActionCode,BusLogic_CCB_T * CCB)3293 static boolean BusLogic_WriteOutgoingMailbox(BusLogic_HostAdapter_T
3294 *HostAdapter,
3295 BusLogic_ActionCode_T ActionCode,
3296 BusLogic_CCB_T *CCB)
3297 {
3298 BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
3299 NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
3300 if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree)
3301 {
3302 CCB->Status = BusLogic_CCB_Active;
3303 /*
3304 The CCB field must be written before the Action Code field since
3305 the Host Adapter is operating asynchronously and the locking code
3306 does not protect against simultaneous access by the Host Adapter.
3307 */
3308 NextOutgoingMailbox->CCB = Virtual_to_Bus(CCB);
3309 NextOutgoingMailbox->ActionCode = ActionCode;
3310 BusLogic_StartMailboxCommand(HostAdapter);
3311 if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
3312 NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
3313 HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
3314 if (ActionCode == BusLogic_MailboxStartCommand)
3315 {
3316 HostAdapter->ActiveCommands[CCB->TargetID]++;
3317 if (CCB->Opcode != BusLogic_BusDeviceReset)
3318 HostAdapter->TargetStatistics[CCB->TargetID].CommandsAttempted++;
3319 }
3320 return true;
3321 }
3322 return false;
3323 }
3324
3325
3326 /*
3327 BusLogic_QueueCommand creates a CCB for Command and places it into an
3328 Outgoing Mailbox for execution by the associated Host Adapter.
3329 */
3330
BusLogic_QueueCommand(SCSI_Command_T * Command,void (* CompletionRoutine)(SCSI_Command_T *))3331 int BusLogic_QueueCommand(SCSI_Command_T *Command,
3332 void (*CompletionRoutine)(SCSI_Command_T *))
3333 {
3334 BusLogic_HostAdapter_T *HostAdapter =
3335 (BusLogic_HostAdapter_T *) Command->host->hostdata;
3336 BusLogic_TargetFlags_T *TargetFlags =
3337 &HostAdapter->TargetFlags[Command->target];
3338 BusLogic_TargetStatistics_T *TargetStatistics =
3339 HostAdapter->TargetStatistics;
3340 unsigned char *CDB = Command->cmnd;
3341 int CDB_Length = Command->cmd_len;
3342 int TargetID = Command->target;
3343 int LogicalUnit = Command->lun;
3344 void *BufferPointer = Command->request_buffer;
3345 int BufferLength = Command->request_bufflen;
3346 int SegmentCount = Command->use_sg;
3347 ProcessorFlags_T ProcessorFlags;
3348 BusLogic_CCB_T *CCB;
3349 /*
3350 SCSI REQUEST_SENSE commands will be executed automatically by the Host
3351 Adapter for any errors, so they should not be executed explicitly unless
3352 the Sense Data is zero indicating that no error occurred.
3353 */
3354 if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0)
3355 {
3356 Command->result = DID_OK << 16;
3357 CompletionRoutine(Command);
3358 return 0;
3359 }
3360 /*
3361 Acquire exclusive access to Host Adapter.
3362 */
3363 BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
3364 /*
3365 Allocate a CCB from the Host Adapter's free list. In the unlikely event
3366 that there are none available and memory allocation fails, wait 1 second
3367 and try again. If that fails, the Host Adapter is probably hung so signal
3368 an error as a Host Adapter Hard Reset should be initiated soon.
3369 */
3370 CCB = BusLogic_AllocateCCB(HostAdapter);
3371 if (CCB == NULL)
3372 {
3373 BusLogic_Delay(1);
3374 CCB = BusLogic_AllocateCCB(HostAdapter);
3375 if (CCB == NULL)
3376 {
3377 Command->result = DID_ERROR << 16;
3378 CompletionRoutine(Command);
3379 goto Done;
3380 }
3381 }
3382 /*
3383 Initialize the fields in the BusLogic Command Control Block (CCB).
3384 */
3385 if (SegmentCount == 0)
3386 {
3387 CCB->Opcode = BusLogic_InitiatorCCB;
3388 CCB->DataLength = BufferLength;
3389 CCB->DataPointer = Virtual_to_Bus(BufferPointer);
3390 }
3391 else
3392 {
3393 SCSI_ScatterList_T *ScatterList = (SCSI_ScatterList_T *) BufferPointer;
3394 int Segment;
3395 CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
3396 CCB->DataLength = SegmentCount * sizeof(BusLogic_ScatterGatherSegment_T);
3397 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3398 CCB->DataPointer = Virtual_to_Bus(CCB->ScatterGatherList);
3399 else CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList);
3400 for (Segment = 0; Segment < SegmentCount; Segment++)
3401 {
3402 CCB->ScatterGatherList[Segment].SegmentByteCount =
3403 ScatterList[Segment].length;
3404 CCB->ScatterGatherList[Segment].SegmentDataPointer =
3405 Virtual_to_Bus(ScatterList[Segment].address);
3406 }
3407 }
3408 switch (CDB[0])
3409 {
3410 case READ_6:
3411 case READ_10:
3412 CCB->DataDirection = BusLogic_DataInLengthChecked;
3413 TargetStatistics[TargetID].ReadCommands++;
3414 BusLogic_IncrementByteCounter(
3415 &TargetStatistics[TargetID].TotalBytesRead, BufferLength);
3416 BusLogic_IncrementSizeBucket(
3417 TargetStatistics[TargetID].ReadCommandSizeBuckets, BufferLength);
3418 break;
3419 case WRITE_6:
3420 case WRITE_10:
3421 CCB->DataDirection = BusLogic_DataOutLengthChecked;
3422 TargetStatistics[TargetID].WriteCommands++;
3423 BusLogic_IncrementByteCounter(
3424 &TargetStatistics[TargetID].TotalBytesWritten, BufferLength);
3425 BusLogic_IncrementSizeBucket(
3426 TargetStatistics[TargetID].WriteCommandSizeBuckets, BufferLength);
3427 break;
3428 default:
3429 CCB->DataDirection = BusLogic_UncheckedDataTransfer;
3430 break;
3431 }
3432 CCB->CDB_Length = CDB_Length;
3433 CCB->SenseDataLength = sizeof(Command->sense_buffer);
3434 CCB->HostAdapterStatus = 0;
3435 CCB->TargetDeviceStatus = 0;
3436 CCB->TargetID = TargetID;
3437 CCB->LogicalUnit = LogicalUnit;
3438 CCB->TagEnable = false;
3439 CCB->LegacyTagEnable = false;
3440 /*
3441 BusLogic recommends that after a Reset the first couple of commands that
3442 are sent to a Target Device be sent in a non Tagged Queue fashion so that
3443 the Host Adapter and Target Device can establish Synchronous and Wide
3444 Transfer before Queue Tag messages can interfere with the Synchronous and
3445 Wide Negotiation messages. By waiting to enable Tagged Queuing until after
3446 the first BusLogic_MaxTaggedQueueDepth commands have been queued, it is
3447 assured that after a Reset any pending commands are requeued before Tagged
3448 Queuing is enabled and that the Tagged Queuing message will not occur while
3449 the partition table is being printed. In addition, some devices do not
3450 properly handle the transition from non-tagged to tagged commands, so it is
3451 necessary to wait until there are no pending commands for a target device
3452 before queuing tagged commands.
3453 */
3454 if (HostAdapter->CommandsSinceReset[TargetID]++ >=
3455 BusLogic_MaxTaggedQueueDepth &&
3456 !TargetFlags->TaggedQueuingActive &&
3457 HostAdapter->ActiveCommands[TargetID] == 0 &&
3458 TargetFlags->TaggedQueuingSupported &&
3459 (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
3460 {
3461 TargetFlags->TaggedQueuingActive = true;
3462 BusLogic_Notice("Tagged Queuing now active for Target %d\n",
3463 HostAdapter, TargetID);
3464 }
3465 if (TargetFlags->TaggedQueuingActive)
3466 {
3467 BusLogic_QueueTag_T QueueTag = BusLogic_SimpleQueueTag;
3468 /*
3469 When using Tagged Queuing with Simple Queue Tags, it appears that disk
3470 drive controllers do not guarantee that a queued command will not
3471 remain in a disconnected state indefinitely if commands that read or
3472 write nearer the head position continue to arrive without interruption.
3473 Therefore, for each Target Device this driver keeps track of the last
3474 time either the queue was empty or an Ordered Queue Tag was issued. If
3475 more than 4 seconds (one fifth of the 20 second disk timeout) have
3476 elapsed since this last sequence point, this command will be issued
3477 with an Ordered Queue Tag rather than a Simple Queue Tag, which forces
3478 the Target Device to complete all previously queued commands before
3479 this command may be executed.
3480 */
3481 if (HostAdapter->ActiveCommands[TargetID] == 0)
3482 HostAdapter->LastSequencePoint[TargetID] = jiffies;
3483 else if (jiffies - HostAdapter->LastSequencePoint[TargetID] > 4*HZ)
3484 {
3485 HostAdapter->LastSequencePoint[TargetID] = jiffies;
3486 QueueTag = BusLogic_OrderedQueueTag;
3487 }
3488 if (HostAdapter->ExtendedLUNSupport)
3489 {
3490 CCB->TagEnable = true;
3491 CCB->QueueTag = QueueTag;
3492 }
3493 else
3494 {
3495 CCB->LegacyTagEnable = true;
3496 CCB->LegacyQueueTag = QueueTag;
3497 }
3498 }
3499 memcpy(CCB->CDB, CDB, CDB_Length);
3500 CCB->SenseDataPointer = Virtual_to_Bus(&Command->sense_buffer);
3501 CCB->Command = Command;
3502 Command->scsi_done = CompletionRoutine;
3503 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3504 {
3505 /*
3506 Place the CCB in an Outgoing Mailbox. The higher levels of the SCSI
3507 Subsystem should not attempt to queue more commands than can be placed
3508 in Outgoing Mailboxes, so there should always be one free. In the
3509 unlikely event that there are none available, wait 1 second and try
3510 again. If that fails, the Host Adapter is probably hung so signal an
3511 error as a Host Adapter Hard Reset should be initiated soon.
3512 */
3513 if (!BusLogic_WriteOutgoingMailbox(
3514 HostAdapter, BusLogic_MailboxStartCommand, CCB))
3515 {
3516 BusLogic_Warning("Unable to write Outgoing Mailbox - "
3517 "Pausing for 1 second\n", HostAdapter);
3518 BusLogic_Delay(1);
3519 if (!BusLogic_WriteOutgoingMailbox(
3520 HostAdapter, BusLogic_MailboxStartCommand, CCB))
3521 {
3522 BusLogic_Warning("Still unable to write Outgoing Mailbox - "
3523 "Host Adapter Dead?\n", HostAdapter);
3524 BusLogic_DeallocateCCB(CCB);
3525 Command->result = DID_ERROR << 16;
3526 Command->scsi_done(Command);
3527 }
3528 }
3529 }
3530 else
3531 {
3532 /*
3533 Call the FlashPoint SCCB Manager to start execution of the CCB.
3534 */
3535 CCB->Status = BusLogic_CCB_Active;
3536 HostAdapter->ActiveCommands[TargetID]++;
3537 TargetStatistics[TargetID].CommandsAttempted++;
3538 FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
3539 /*
3540 The Command may have already completed and BusLogic_QueueCompletedCCB
3541 been called, or it may still be pending.
3542 */
3543 if (CCB->Status == BusLogic_CCB_Completed)
3544 BusLogic_ProcessCompletedCCBs(HostAdapter);
3545 }
3546 /*
3547 Release exclusive access to Host Adapter.
3548 */
3549 Done:
3550 BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
3551 return 0;
3552 }
3553
3554
3555 /*
3556 BusLogic_AbortCommand aborts Command if possible.
3557 */
3558
BusLogic_AbortCommand(SCSI_Command_T * Command)3559 int BusLogic_AbortCommand(SCSI_Command_T *Command)
3560 {
3561 BusLogic_HostAdapter_T *HostAdapter =
3562 (BusLogic_HostAdapter_T *) Command->host->hostdata;
3563 int TargetID = Command->target;
3564 ProcessorFlags_T ProcessorFlags;
3565 BusLogic_CCB_T *CCB;
3566 int Result;
3567 BusLogic_IncrementErrorCounter(
3568 &HostAdapter->TargetStatistics[TargetID].CommandAbortsRequested);
3569 /*
3570 Acquire exclusive access to Host Adapter.
3571 */
3572 BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
3573 /*
3574 If this Command has already completed, then no Abort is necessary.
3575 */
3576 if (Command->serial_number != Command->serial_number_at_timeout)
3577 {
3578 BusLogic_Warning("Unable to Abort Command to Target %d - "
3579 "Already Completed\n", HostAdapter, TargetID);
3580 Result = SCSI_ABORT_NOT_RUNNING;
3581 goto Done;
3582 }
3583 /*
3584 Attempt to find an Active CCB for this Command. If no Active CCB for this
3585 Command is found, then no Abort is necessary.
3586 */
3587 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3588 if (CCB->Command == Command) break;
3589 if (CCB == NULL)
3590 {
3591 BusLogic_Warning("Unable to Abort Command to Target %d - "
3592 "No CCB Found\n", HostAdapter, TargetID);
3593 Result = SCSI_ABORT_NOT_RUNNING;
3594 goto Done;
3595 }
3596 else if (CCB->Status == BusLogic_CCB_Completed)
3597 {
3598 BusLogic_Warning("Unable to Abort Command to Target %d - "
3599 "CCB Completed\n", HostAdapter, TargetID);
3600 Result = SCSI_ABORT_NOT_RUNNING;
3601 goto Done;
3602 }
3603 else if (CCB->Status == BusLogic_CCB_Reset)
3604 {
3605 BusLogic_Warning("Unable to Abort Command to Target %d - "
3606 "CCB Reset\n", HostAdapter, TargetID);
3607 Result = SCSI_ABORT_PENDING;
3608 goto Done;
3609 }
3610 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3611 {
3612 /*
3613 Attempt to Abort this CCB. MultiMaster Firmware versions prior to 5.xx
3614 do not generate Abort Tag messages, but only generate the non-tagged
3615 Abort message. Since non-tagged commands are not sent by the Host
3616 Adapter until the queue of outstanding tagged commands has completed,
3617 and the Abort message is treated as a non-tagged command, it is
3618 effectively impossible to abort commands when Tagged Queuing is active.
3619 Firmware version 5.xx does generate Abort Tag messages, so it is
3620 possible to abort commands when Tagged Queuing is active.
3621 */
3622 if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
3623 HostAdapter->FirmwareVersion[0] < '5')
3624 {
3625 BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - "
3626 "Abort Tag Not Supported\n",
3627 HostAdapter, CCB->SerialNumber, TargetID);
3628 Result = SCSI_ABORT_SNOOZE;
3629 }
3630 else if (BusLogic_WriteOutgoingMailbox(
3631 HostAdapter, BusLogic_MailboxAbortCommand, CCB))
3632 {
3633 BusLogic_Warning("Aborting CCB #%ld to Target %d\n",
3634 HostAdapter, CCB->SerialNumber, TargetID);
3635 BusLogic_IncrementErrorCounter(
3636 &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
3637 Result = SCSI_ABORT_PENDING;
3638 }
3639 else
3640 {
3641 BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - "
3642 "No Outgoing Mailboxes\n",
3643 HostAdapter, CCB->SerialNumber, TargetID);
3644 Result = SCSI_ABORT_BUSY;
3645 }
3646 }
3647 else
3648 {
3649 /*
3650 Call the FlashPoint SCCB Manager to abort execution of the CCB.
3651 */
3652 BusLogic_Warning("Aborting CCB #%ld to Target %d\n",
3653 HostAdapter, CCB->SerialNumber, TargetID);
3654 BusLogic_IncrementErrorCounter(
3655 &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
3656 FlashPoint_AbortCCB(HostAdapter->CardHandle, CCB);
3657 /*
3658 The Abort may have already been completed and
3659 BusLogic_QueueCompletedCCB been called, or it
3660 may still be pending.
3661 */
3662 Result = SCSI_ABORT_PENDING;
3663 if (CCB->Status == BusLogic_CCB_Completed)
3664 {
3665 BusLogic_ProcessCompletedCCBs(HostAdapter);
3666 Result = SCSI_ABORT_SUCCESS;
3667 }
3668 }
3669 /*
3670 Release exclusive access to Host Adapter.
3671 */
3672 Done:
3673 BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
3674 return Result;
3675 }
3676
3677
3678 /*
3679 BusLogic_ResetHostAdapter resets Host Adapter if possible, marking all
3680 currently executing SCSI Commands as having been Reset.
3681 */
3682
BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T * HostAdapter,SCSI_Command_T * Command,unsigned int ResetFlags)3683 static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter,
3684 SCSI_Command_T *Command,
3685 unsigned int ResetFlags)
3686 {
3687 ProcessorFlags_T ProcessorFlags;
3688 BusLogic_CCB_T *CCB;
3689 int TargetID, Result;
3690 boolean HardReset;
3691 if (HostAdapter->HostAdapterExternalReset)
3692 {
3693 BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets);
3694 HardReset = false;
3695 }
3696 else if (HostAdapter->HostAdapterInternalError)
3697 {
3698 BusLogic_IncrementErrorCounter(&HostAdapter->HostAdapterInternalErrors);
3699 HardReset = true;
3700 }
3701 else
3702 {
3703 BusLogic_IncrementErrorCounter(
3704 &HostAdapter->TargetStatistics[Command->target]
3705 .HostAdapterResetsRequested);
3706 HardReset = true;
3707 }
3708 /*
3709 Acquire exclusive access to Host Adapter.
3710 */
3711 BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
3712 /*
3713 If this is an Asynchronous Reset and this Command has already completed,
3714 then no Reset is necessary.
3715 */
3716 if (ResetFlags & SCSI_RESET_ASYNCHRONOUS)
3717 {
3718 TargetID = Command->target;
3719 if (Command->serial_number != Command->serial_number_at_timeout)
3720 {
3721 BusLogic_Warning("Unable to Reset Command to Target %d - "
3722 "Already Completed or Reset\n",
3723 HostAdapter, TargetID);
3724 Result = SCSI_RESET_NOT_RUNNING;
3725 goto Done;
3726 }
3727 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3728 if (CCB->Command == Command) break;
3729 if (CCB == NULL)
3730 {
3731 BusLogic_Warning("Unable to Reset Command to Target %d - "
3732 "No CCB Found\n", HostAdapter, TargetID);
3733 Result = SCSI_RESET_NOT_RUNNING;
3734 goto Done;
3735 }
3736 else if (CCB->Status == BusLogic_CCB_Completed)
3737 {
3738 BusLogic_Warning("Unable to Reset Command to Target %d - "
3739 "CCB Completed\n", HostAdapter, TargetID);
3740 Result = SCSI_RESET_NOT_RUNNING;
3741 goto Done;
3742 }
3743 else if (CCB->Status == BusLogic_CCB_Reset &&
3744 HostAdapter->BusDeviceResetPendingCCB[TargetID] == NULL)
3745 {
3746 BusLogic_Warning("Unable to Reset Command to Target %d - "
3747 "Reset Pending\n", HostAdapter, TargetID);
3748 Result = SCSI_RESET_PENDING;
3749 goto Done;
3750 }
3751 }
3752 if (Command == NULL)
3753 {
3754 if (HostAdapter->HostAdapterInternalError)
3755 BusLogic_Warning("Resetting %s due to Host Adapter Internal Error\n",
3756 HostAdapter, HostAdapter->FullModelName);
3757 else BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n",
3758 HostAdapter, HostAdapter->FullModelName);
3759 }
3760 else
3761 {
3762 BusLogic_Warning("Resetting %s due to Target %d\n", HostAdapter,
3763 HostAdapter->FullModelName, Command->target);
3764 BusLogic_IncrementErrorCounter(
3765 &HostAdapter->TargetStatistics[Command->target]
3766 .HostAdapterResetsAttempted);
3767 }
3768 /*
3769 Attempt to Reset and Reinitialize the Host Adapter.
3770 */
3771 if (!(BusLogic_HardwareResetHostAdapter(HostAdapter, HardReset) &&
3772 BusLogic_InitializeHostAdapter(HostAdapter)))
3773 {
3774 BusLogic_Error("Resetting %s Failed\n", HostAdapter,
3775 HostAdapter->FullModelName);
3776 Result = SCSI_RESET_ERROR;
3777 goto Done;
3778 }
3779 if (Command != NULL)
3780 BusLogic_IncrementErrorCounter(
3781 &HostAdapter->TargetStatistics[Command->target]
3782 .HostAdapterResetsCompleted);
3783 /*
3784 Mark all currently executing CCBs as having been Reset.
3785 */
3786 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3787 if (CCB->Status == BusLogic_CCB_Active)
3788 CCB->Status = BusLogic_CCB_Reset;
3789 /*
3790 Wait a few seconds between the Host Adapter Hard Reset which initiates
3791 a SCSI Bus Reset and issuing any SCSI Commands. Some SCSI devices get
3792 confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
3793 Note that a timer interrupt may occur here, but all active CCBs have
3794 already been marked Reset and so a reentrant call will return Pending.
3795 */
3796 if (HardReset)
3797 BusLogic_Delay(HostAdapter->BusSettleTime);
3798 /*
3799 If this is a Synchronous Reset, perform completion processing for
3800 the Command being Reset.
3801 */
3802 if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
3803 {
3804 Command->result = DID_RESET << 16;
3805 Command->scsi_done(Command);
3806 }
3807 /*
3808 Perform completion processing for all CCBs marked as Reset.
3809 */
3810 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3811 if (CCB->Status == BusLogic_CCB_Reset)
3812 {
3813 Command = CCB->Command;
3814 BusLogic_DeallocateCCB(CCB);
3815 while (Command != NULL)
3816 {
3817 SCSI_Command_T *NextCommand = Command->reset_chain;
3818 Command->reset_chain = NULL;
3819 Command->result = DID_RESET << 16;
3820 Command->scsi_done(Command);
3821 Command = NextCommand;
3822 }
3823 }
3824 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
3825 {
3826 HostAdapter->LastResetAttempted[TargetID] = jiffies;
3827 HostAdapter->LastResetCompleted[TargetID] = jiffies;
3828 }
3829 Result = SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET;
3830 /*
3831 Release exclusive access to Host Adapter.
3832 */
3833 Done:
3834 BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
3835 return Result;
3836 }
3837
3838
3839 /*
3840 BusLogic_SendBusDeviceReset sends a Bus Device Reset to the Target
3841 Device associated with Command.
3842 */
3843
BusLogic_SendBusDeviceReset(BusLogic_HostAdapter_T * HostAdapter,SCSI_Command_T * Command,unsigned int ResetFlags)3844 static int BusLogic_SendBusDeviceReset(BusLogic_HostAdapter_T *HostAdapter,
3845 SCSI_Command_T *Command,
3846 unsigned int ResetFlags)
3847 {
3848 int TargetID = Command->target;
3849 BusLogic_CCB_T *CCB, *XCCB;
3850 ProcessorFlags_T ProcessorFlags;
3851 int Result = -1;
3852 BusLogic_IncrementErrorCounter(
3853 &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsRequested);
3854 /*
3855 Acquire exclusive access to Host Adapter.
3856 */
3857 BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
3858 /*
3859 If this is an Asynchronous Reset and this Command has already completed,
3860 then no Reset is necessary.
3861 */
3862 if (ResetFlags & SCSI_RESET_ASYNCHRONOUS)
3863 {
3864 if (Command->serial_number != Command->serial_number_at_timeout)
3865 {
3866 BusLogic_Warning("Unable to Reset Command to Target %d - "
3867 "Already Completed\n", HostAdapter, TargetID);
3868 Result = SCSI_RESET_NOT_RUNNING;
3869 goto Done;
3870 }
3871 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3872 if (CCB->Command == Command) break;
3873 if (CCB == NULL)
3874 {
3875 BusLogic_Warning("Unable to Reset Command to Target %d - "
3876 "No CCB Found\n", HostAdapter, TargetID);
3877 Result = SCSI_RESET_NOT_RUNNING;
3878 goto Done;
3879 }
3880 else if (CCB->Status == BusLogic_CCB_Completed)
3881 {
3882 BusLogic_Warning("Unable to Reset Command to Target %d - "
3883 "CCB Completed\n", HostAdapter, TargetID);
3884 Result = SCSI_RESET_NOT_RUNNING;
3885 goto Done;
3886 }
3887 else if (CCB->Status == BusLogic_CCB_Reset)
3888 {
3889 BusLogic_Warning("Unable to Reset Command to Target %d - "
3890 "Reset Pending\n", HostAdapter, TargetID);
3891 Result = SCSI_RESET_PENDING;
3892 goto Done;
3893 }
3894 else if (HostAdapter->BusDeviceResetPendingCCB[TargetID] != NULL)
3895 {
3896 BusLogic_Warning("Bus Device Reset already pending to Target %d\n",
3897 HostAdapter, TargetID);
3898 goto Done;
3899 }
3900 }
3901 /*
3902 If this is a Synchronous Reset and a Bus Device Reset is already pending
3903 for this Target Device, do not send a second one. Add this Command to
3904 the list of Commands for which completion processing must be performed
3905 when the Bus Device Reset CCB completes.
3906 */
3907 if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
3908 if ((CCB = HostAdapter->BusDeviceResetPendingCCB[TargetID]) != NULL)
3909 {
3910 Command->reset_chain = CCB->Command;
3911 CCB->Command = Command;
3912 BusLogic_Warning("Unable to Reset Command to Target %d - "
3913 "Reset Pending\n", HostAdapter, TargetID);
3914 Result = SCSI_RESET_PENDING;
3915 goto Done;
3916 }
3917 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3918 {
3919 /*
3920 MultiMaster Firmware versions prior to 5.xx treat a Bus Device Reset as
3921 a non-tagged command. Since non-tagged commands are not sent by the
3922 Host Adapter until the queue of outstanding tagged commands has
3923 completed, it is effectively impossible to send a Bus Device Reset
3924 while there are tagged commands outstanding. Therefore, in that case a
3925 full Host Adapter Hard Reset and SCSI Bus Reset must be done.
3926 */
3927 if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
3928 HostAdapter->ActiveCommands[TargetID] > 0 &&
3929 HostAdapter->FirmwareVersion[0] < '5')
3930 goto Done;
3931 }
3932 /*
3933 Allocate a CCB from the Host Adapter's free list. In the unlikely event
3934 that there are none available and memory allocation fails, attempt a full
3935 Host Adapter Hard Reset and SCSI Bus Reset.
3936 */
3937 CCB = BusLogic_AllocateCCB(HostAdapter);
3938 if (CCB == NULL) goto Done;
3939 BusLogic_Warning("Sending Bus Device Reset CCB #%ld to Target %d\n",
3940 HostAdapter, CCB->SerialNumber, TargetID);
3941 CCB->Opcode = BusLogic_BusDeviceReset;
3942 CCB->TargetID = TargetID;
3943 /*
3944 For Synchronous Resets, arrange for the interrupt handler to perform
3945 completion processing for the Command being Reset.
3946 */
3947 if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
3948 {
3949 Command->reset_chain = NULL;
3950 CCB->Command = Command;
3951 }
3952 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3953 {
3954 /*
3955 Attempt to write an Outgoing Mailbox with the Bus Device Reset CCB.
3956 If sending a Bus Device Reset is impossible, attempt a full Host
3957 Adapter Hard Reset and SCSI Bus Reset.
3958 */
3959 if (!(BusLogic_WriteOutgoingMailbox(
3960 HostAdapter, BusLogic_MailboxStartCommand, CCB)))
3961 {
3962 BusLogic_Warning("Unable to write Outgoing Mailbox for "
3963 "Bus Device Reset\n", HostAdapter);
3964 BusLogic_DeallocateCCB(CCB);
3965 goto Done;
3966 }
3967 }
3968 else
3969 {
3970 /*
3971 Call the FlashPoint SCCB Manager to start execution of the CCB.
3972 */
3973 CCB->Status = BusLogic_CCB_Active;
3974 HostAdapter->ActiveCommands[TargetID]++;
3975 FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
3976 }
3977 /*
3978 If there is a currently executing CCB in the Host Adapter for this Command
3979 (i.e. this is an Asynchronous Reset), then an Incoming Mailbox entry may be
3980 made with a completion code of BusLogic_HostAdapterAssertedBusDeviceReset.
3981 If there is no active CCB for this Command (i.e. this is a Synchronous
3982 Reset), then the Bus Device Reset CCB's Command field will have been set
3983 to the Command so that the interrupt for the completion of the Bus Device
3984 Reset can call the Completion Routine for the Command. On successful
3985 execution of a Bus Device Reset, older firmware versions did return the
3986 pending CCBs with the appropriate completion code, but more recent firmware
3987 versions only return the Bus Device Reset CCB itself. This driver handles
3988 both cases by marking all the currently executing CCBs to this Target
3989 Device as Reset. When the Bus Device Reset CCB is processed by the
3990 interrupt handler, any remaining CCBs marked as Reset will have completion
3991 processing performed.
3992 */
3993 BusLogic_IncrementErrorCounter(
3994 &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsAttempted);
3995 HostAdapter->BusDeviceResetPendingCCB[TargetID] = CCB;
3996 HostAdapter->LastResetAttempted[TargetID] = jiffies;
3997 for (XCCB = HostAdapter->All_CCBs; XCCB != NULL; XCCB = XCCB->NextAll)
3998 if (XCCB->Status == BusLogic_CCB_Active && XCCB->TargetID == TargetID)
3999 XCCB->Status = BusLogic_CCB_Reset;
4000 /*
4001 FlashPoint Host Adapters may have already completed the Bus Device
4002 Reset and BusLogic_QueueCompletedCCB been called, or it may still be
4003 pending.
4004 */
4005 Result = SCSI_RESET_PENDING;
4006 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
4007 if (CCB->Status == BusLogic_CCB_Completed)
4008 {
4009 BusLogic_ProcessCompletedCCBs(HostAdapter);
4010 Result = SCSI_RESET_SUCCESS;
4011 }
4012 /*
4013 If a Bus Device Reset was not possible for some reason, force a full
4014 Host Adapter Hard Reset and SCSI Bus Reset.
4015 */
4016 Done:
4017 if (Result < 0)
4018 Result = BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
4019 /*
4020 Release exclusive access to Host Adapter.
4021 */
4022 BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
4023 return Result;
4024 }
4025
4026
4027 /*
4028 BusLogic_ResetCommand takes appropriate action to reset Command.
4029 */
4030
BusLogic_ResetCommand(SCSI_Command_T * Command,unsigned int ResetFlags)4031 int BusLogic_ResetCommand(SCSI_Command_T *Command, unsigned int ResetFlags)
4032 {
4033 BusLogic_HostAdapter_T *HostAdapter =
4034 (BusLogic_HostAdapter_T *) Command->host->hostdata;
4035 int TargetID = Command->target;
4036 BusLogic_ErrorRecoveryStrategy_T
4037 ErrorRecoveryStrategy = HostAdapter->ErrorRecoveryStrategy[TargetID];
4038 /*
4039 Disable Tagged Queuing if it is active for this Target Device and if
4040 it has been less than 10 minutes since the last reset occurred, or since
4041 the system was initialized if no prior resets have occurred.
4042 */
4043 if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
4044 jiffies - HostAdapter->LastResetCompleted[TargetID] < 10*60*HZ)
4045 {
4046 HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
4047 HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
4048 BusLogic_Warning("Tagged Queuing now disabled for Target %d\n",
4049 HostAdapter, TargetID);
4050 }
4051 switch (ErrorRecoveryStrategy)
4052 {
4053 case BusLogic_ErrorRecovery_Default:
4054 if (ResetFlags & SCSI_RESET_SUGGEST_HOST_RESET)
4055 return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
4056 else if (ResetFlags & SCSI_RESET_SUGGEST_BUS_RESET)
4057 return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
4058 /* Fall through to Bus Device Reset case. */
4059 case BusLogic_ErrorRecovery_BusDeviceReset:
4060 /*
4061 The Bus Device Reset Error Recovery Strategy only graduates to a Hard
4062 Reset when no commands have completed successfully since the last Bus
4063 Device Reset and it has been at least 100 milliseconds. This prevents
4064 a sequence of commands that all timeout together from immediately
4065 forcing a Hard Reset before the Bus Device Reset has had a chance to
4066 clear the error condition.
4067 */
4068 if (HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag ||
4069 jiffies - HostAdapter->LastResetAttempted[TargetID] < HZ/10)
4070 {
4071 HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
4072 return BusLogic_SendBusDeviceReset(HostAdapter, Command, ResetFlags);
4073 }
4074 /* Fall through to Hard Reset case. */
4075 case BusLogic_ErrorRecovery_HardReset:
4076 return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
4077 case BusLogic_ErrorRecovery_None:
4078 BusLogic_Warning("Error Recovery for Target %d Suppressed\n",
4079 HostAdapter, TargetID);
4080 break;
4081 }
4082 return SCSI_RESET_PUNT;
4083 }
4084
4085
4086 /*
4087 BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk
4088 Parameters for Disk. The default disk geometry is 64 heads, 32 sectors, and
4089 the appropriate number of cylinders so as not to exceed drive capacity. In
4090 order for disks equal to or larger than 1 GB to be addressable by the BIOS
4091 without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
4092 may be enabled in AutoSCSI on FlashPoint Host Adapters and on "W" and "C"
4093 series MultiMaster Host Adapters, or by a dip switch setting on "S" and "A"
4094 series MultiMaster Host Adapters. With Extended Translation enabled, drives
4095 between 1 GB inclusive and 2 GB exclusive are given a disk geometry of 128
4096 heads and 32 sectors, and drives above 2 GB inclusive are given a disk
4097 geometry of 255 heads and 63 sectors. However, if the BIOS detects that the
4098 Extended Translation setting does not match the geometry in the partition
4099 table, then the translation inferred from the partition table will be used by
4100 the BIOS, and a warning may be displayed.
4101 */
4102
BusLogic_BIOSDiskParameters(SCSI_Disk_T * Disk,KernelDevice_T Device,int * Parameters)4103 int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device,
4104 int *Parameters)
4105 {
4106 BusLogic_HostAdapter_T *HostAdapter =
4107 (BusLogic_HostAdapter_T *) Disk->device->host->hostdata;
4108 BIOS_DiskParameters_T *DiskParameters = (BIOS_DiskParameters_T *) Parameters;
4109 struct buffer_head *BufferHead;
4110 if (HostAdapter->ExtendedTranslationEnabled &&
4111 Disk->capacity >= 2*1024*1024 /* 1 GB in 512 byte sectors */)
4112 {
4113 if (Disk->capacity >= 4*1024*1024 /* 2 GB in 512 byte sectors */)
4114 {
4115 DiskParameters->Heads = 255;
4116 DiskParameters->Sectors = 63;
4117 }
4118 else
4119 {
4120 DiskParameters->Heads = 128;
4121 DiskParameters->Sectors = 32;
4122 }
4123 }
4124 else
4125 {
4126 DiskParameters->Heads = 64;
4127 DiskParameters->Sectors = 32;
4128 }
4129 DiskParameters->Cylinders =
4130 Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
4131 /*
4132 Attempt to read the first 1024 bytes from the disk device.
4133 */
4134 BufferHead = bread(MKDEV(MAJOR(Device), MINOR(Device) & ~0x0F), 0, block_size(Device));
4135 if (BufferHead == NULL) return 0;
4136 /*
4137 If the boot sector partition table flag is valid, search for a partition
4138 table entry whose end_head matches one of the standard BusLogic geometry
4139 translations (64/32, 128/32, or 255/63).
4140 */
4141 if (*(unsigned short *) (BufferHead->b_data + 0x1FE) == 0xAA55)
4142 {
4143 PartitionTable_T *FirstPartitionEntry =
4144 (PartitionTable_T *) (BufferHead->b_data + 0x1BE);
4145 PartitionTable_T *PartitionEntry = FirstPartitionEntry;
4146 int SavedCylinders = DiskParameters->Cylinders, PartitionNumber;
4147 unsigned char PartitionEntryEndHead, PartitionEntryEndSector;
4148 for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++)
4149 {
4150 PartitionEntryEndHead = PartitionEntry->end_head;
4151 PartitionEntryEndSector = PartitionEntry->end_sector & 0x3F;
4152 if (PartitionEntryEndHead == 64-1)
4153 {
4154 DiskParameters->Heads = 64;
4155 DiskParameters->Sectors = 32;
4156 break;
4157 }
4158 else if (PartitionEntryEndHead == 128-1)
4159 {
4160 DiskParameters->Heads = 128;
4161 DiskParameters->Sectors = 32;
4162 break;
4163 }
4164 else if (PartitionEntryEndHead == 255-1)
4165 {
4166 DiskParameters->Heads = 255;
4167 DiskParameters->Sectors = 63;
4168 break;
4169 }
4170 PartitionEntry++;
4171 }
4172 if (PartitionNumber == 4)
4173 {
4174 PartitionEntryEndHead = FirstPartitionEntry->end_head;
4175 PartitionEntryEndSector = FirstPartitionEntry->end_sector & 0x3F;
4176 }
4177 DiskParameters->Cylinders =
4178 Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
4179 if (PartitionNumber < 4 &&
4180 PartitionEntryEndSector == DiskParameters->Sectors)
4181 {
4182 if (DiskParameters->Cylinders != SavedCylinders)
4183 BusLogic_Warning("Adopting Geometry %d/%d from Partition Table\n",
4184 HostAdapter,
4185 DiskParameters->Heads, DiskParameters->Sectors);
4186 }
4187 else if (PartitionEntryEndHead > 0 || PartitionEntryEndSector > 0)
4188 {
4189 BusLogic_Warning("Warning: Partition Table appears to "
4190 "have Geometry %d/%d which is\n", HostAdapter,
4191 PartitionEntryEndHead + 1,
4192 PartitionEntryEndSector);
4193 BusLogic_Warning("not compatible with current BusLogic "
4194 "Host Adapter Geometry %d/%d\n", HostAdapter,
4195 DiskParameters->Heads, DiskParameters->Sectors);
4196 }
4197 }
4198 brelse(BufferHead);
4199 return 0;
4200 }
4201
4202
4203 /*
4204 BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>.
4205 */
4206
BusLogic_ProcDirectoryInfo(char * ProcBuffer,char ** StartPointer,off_t Offset,int BytesAvailable,int HostNumber,int WriteFlag)4207 int BusLogic_ProcDirectoryInfo(char *ProcBuffer, char **StartPointer,
4208 off_t Offset, int BytesAvailable,
4209 int HostNumber, int WriteFlag)
4210 {
4211 BusLogic_HostAdapter_T *HostAdapter;
4212 BusLogic_TargetStatistics_T *TargetStatistics;
4213 int TargetID, Length;
4214 char *Buffer;
4215 for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
4216 HostAdapter != NULL;
4217 HostAdapter = HostAdapter->Next)
4218 if (HostAdapter->HostNumber == HostNumber) break;
4219 if (HostAdapter == NULL)
4220 {
4221 BusLogic_Error("Cannot find Host Adapter for SCSI Host %d\n",
4222 NULL, HostNumber);
4223 return 0;
4224 }
4225 TargetStatistics = HostAdapter->TargetStatistics;
4226 if (WriteFlag)
4227 {
4228 HostAdapter->ExternalHostAdapterResets = 0;
4229 HostAdapter->HostAdapterInternalErrors = 0;
4230 memset(TargetStatistics, 0,
4231 BusLogic_MaxTargetDevices * sizeof(BusLogic_TargetStatistics_T));
4232 return 0;
4233 }
4234 Buffer = HostAdapter->MessageBuffer;
4235 Length = HostAdapter->MessageBufferLength;
4236 Length += sprintf(&Buffer[Length], "\n\
4237 Current Driver Queue Depth: %d\n\
4238 Currently Allocated CCBs: %d\n",
4239 HostAdapter->DriverQueueDepth,
4240 HostAdapter->AllocatedCCBs);
4241 Length += sprintf(&Buffer[Length], "\n\n\
4242 DATA TRANSFER STATISTICS\n\
4243 \n\
4244 Target Tagged Queuing Queue Depth Active Attempted Completed\n\
4245 ====== ============== =========== ====== ========= =========\n");
4246 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4247 {
4248 BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4249 if (!TargetFlags->TargetExists) continue;
4250 Length +=
4251 sprintf(&Buffer[Length], " %2d %s", TargetID,
4252 (TargetFlags->TaggedQueuingSupported
4253 ? (TargetFlags->TaggedQueuingActive
4254 ? " Active"
4255 : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)
4256 ? " Permitted" : " Disabled"))
4257 : "Not Supported"));
4258 Length += sprintf(&Buffer[Length],
4259 " %3d %3u %9u %9u\n",
4260 HostAdapter->QueueDepth[TargetID],
4261 HostAdapter->ActiveCommands[TargetID],
4262 TargetStatistics[TargetID].CommandsAttempted,
4263 TargetStatistics[TargetID].CommandsCompleted);
4264 }
4265 Length += sprintf(&Buffer[Length], "\n\
4266 Target Read Commands Write Commands Total Bytes Read Total Bytes Written\n\
4267 ====== ============= ============== =================== ===================\n");
4268 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4269 {
4270 BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4271 if (!TargetFlags->TargetExists) continue;
4272 Length +=
4273 sprintf(&Buffer[Length], " %2d %9u %9u", TargetID,
4274 TargetStatistics[TargetID].ReadCommands,
4275 TargetStatistics[TargetID].WriteCommands);
4276 if (TargetStatistics[TargetID].TotalBytesRead.Billions > 0)
4277 Length +=
4278 sprintf(&Buffer[Length], " %9u%09u",
4279 TargetStatistics[TargetID].TotalBytesRead.Billions,
4280 TargetStatistics[TargetID].TotalBytesRead.Units);
4281 else
4282 Length +=
4283 sprintf(&Buffer[Length], " %9u",
4284 TargetStatistics[TargetID].TotalBytesRead.Units);
4285 if (TargetStatistics[TargetID].TotalBytesWritten.Billions > 0)
4286 Length +=
4287 sprintf(&Buffer[Length], " %9u%09u\n",
4288 TargetStatistics[TargetID].TotalBytesWritten.Billions,
4289 TargetStatistics[TargetID].TotalBytesWritten.Units);
4290 else
4291 Length +=
4292 sprintf(&Buffer[Length], " %9u\n",
4293 TargetStatistics[TargetID].TotalBytesWritten.Units);
4294 }
4295 Length += sprintf(&Buffer[Length], "\n\
4296 Target Command 0-1KB 1-2KB 2-4KB 4-8KB 8-16KB\n\
4297 ====== ======= ========= ========= ========= ========= =========\n");
4298 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4299 {
4300 BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4301 if (!TargetFlags->TargetExists) continue;
4302 Length +=
4303 sprintf(&Buffer[Length],
4304 " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
4305 TargetStatistics[TargetID].ReadCommandSizeBuckets[0],
4306 TargetStatistics[TargetID].ReadCommandSizeBuckets[1],
4307 TargetStatistics[TargetID].ReadCommandSizeBuckets[2],
4308 TargetStatistics[TargetID].ReadCommandSizeBuckets[3],
4309 TargetStatistics[TargetID].ReadCommandSizeBuckets[4]);
4310 Length +=
4311 sprintf(&Buffer[Length],
4312 " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
4313 TargetStatistics[TargetID].WriteCommandSizeBuckets[0],
4314 TargetStatistics[TargetID].WriteCommandSizeBuckets[1],
4315 TargetStatistics[TargetID].WriteCommandSizeBuckets[2],
4316 TargetStatistics[TargetID].WriteCommandSizeBuckets[3],
4317 TargetStatistics[TargetID].WriteCommandSizeBuckets[4]);
4318 }
4319 Length += sprintf(&Buffer[Length], "\n\
4320 Target Command 16-32KB 32-64KB 64-128KB 128-256KB 256KB+\n\
4321 ====== ======= ========= ========= ========= ========= =========\n");
4322 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4323 {
4324 BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4325 if (!TargetFlags->TargetExists) continue;
4326 Length +=
4327 sprintf(&Buffer[Length],
4328 " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
4329 TargetStatistics[TargetID].ReadCommandSizeBuckets[5],
4330 TargetStatistics[TargetID].ReadCommandSizeBuckets[6],
4331 TargetStatistics[TargetID].ReadCommandSizeBuckets[7],
4332 TargetStatistics[TargetID].ReadCommandSizeBuckets[8],
4333 TargetStatistics[TargetID].ReadCommandSizeBuckets[9]);
4334 Length +=
4335 sprintf(&Buffer[Length],
4336 " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
4337 TargetStatistics[TargetID].WriteCommandSizeBuckets[5],
4338 TargetStatistics[TargetID].WriteCommandSizeBuckets[6],
4339 TargetStatistics[TargetID].WriteCommandSizeBuckets[7],
4340 TargetStatistics[TargetID].WriteCommandSizeBuckets[8],
4341 TargetStatistics[TargetID].WriteCommandSizeBuckets[9]);
4342 }
4343 Length += sprintf(&Buffer[Length], "\n\n\
4344 ERROR RECOVERY STATISTICS\n\
4345 \n\
4346 Command Aborts Bus Device Resets Host Adapter Resets\n\
4347 Target Requested Completed Requested Completed Requested Completed\n\
4348 ID \\\\\\\\ Attempted //// \\\\\\\\ Attempted //// \\\\\\\\ Attempted ////\n\
4349 ====== ===== ===== ===== ===== ===== ===== ===== ===== =====\n");
4350 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4351 {
4352 BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4353 if (!TargetFlags->TargetExists) continue;
4354 Length +=
4355 sprintf(&Buffer[Length], "\
4356 %2d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n", TargetID,
4357 TargetStatistics[TargetID].CommandAbortsRequested,
4358 TargetStatistics[TargetID].CommandAbortsAttempted,
4359 TargetStatistics[TargetID].CommandAbortsCompleted,
4360 TargetStatistics[TargetID].BusDeviceResetsRequested,
4361 TargetStatistics[TargetID].BusDeviceResetsAttempted,
4362 TargetStatistics[TargetID].BusDeviceResetsCompleted,
4363 TargetStatistics[TargetID].HostAdapterResetsRequested,
4364 TargetStatistics[TargetID].HostAdapterResetsAttempted,
4365 TargetStatistics[TargetID].HostAdapterResetsCompleted);
4366 }
4367 Length += sprintf(&Buffer[Length], "\nExternal Host Adapter Resets: %d\n",
4368 HostAdapter->ExternalHostAdapterResets);
4369 Length += sprintf(&Buffer[Length], "Host Adapter Internal Errors: %d\n",
4370 HostAdapter->HostAdapterInternalErrors);
4371 if (Length >= BusLogic_MessageBufferSize)
4372 BusLogic_Error("Message Buffer length %d exceeds size %d\n",
4373 HostAdapter, Length, BusLogic_MessageBufferSize);
4374 if ((Length -= Offset) <= 0) return 0;
4375 if (Length >= BytesAvailable) Length = BytesAvailable;
4376 memcpy(ProcBuffer, HostAdapter->MessageBuffer + Offset, Length);
4377 *StartPointer = ProcBuffer;
4378 return Length;
4379 }
4380
4381
4382 /*
4383 BusLogic_Message prints Driver Messages.
4384 */
4385
BusLogic_Message(BusLogic_MessageLevel_T MessageLevel,char * Format,BusLogic_HostAdapter_T * HostAdapter,...)4386 static void BusLogic_Message(BusLogic_MessageLevel_T MessageLevel,
4387 char *Format,
4388 BusLogic_HostAdapter_T *HostAdapter,
4389 ...)
4390 {
4391 static char Buffer[BusLogic_LineBufferSize];
4392 static boolean BeginningOfLine = true;
4393 va_list Arguments;
4394 int Length = 0;
4395 va_start(Arguments, HostAdapter);
4396 Length = vsprintf(Buffer, Format, Arguments);
4397 va_end(Arguments);
4398 if (MessageLevel == BusLogic_AnnounceLevel)
4399 {
4400 static int AnnouncementLines = 0;
4401 strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength],
4402 Buffer);
4403 HostAdapter->MessageBufferLength += Length;
4404 if (++AnnouncementLines <= 2)
4405 printk("%sscsi: %s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
4406 }
4407 else if (MessageLevel == BusLogic_InfoLevel)
4408 {
4409 strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength],
4410 Buffer);
4411 HostAdapter->MessageBufferLength += Length;
4412 if (BeginningOfLine)
4413 {
4414 if (Buffer[0] != '\n' || Length > 1)
4415 printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
4416 HostAdapter->HostNumber, Buffer);
4417 }
4418 else printk("%s", Buffer);
4419 }
4420 else
4421 {
4422 if (BeginningOfLine)
4423 {
4424 if (HostAdapter != NULL && HostAdapter->HostAdapterInitialized)
4425 printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
4426 HostAdapter->HostNumber, Buffer);
4427 else printk("%s%s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
4428 }
4429 else printk("%s", Buffer);
4430 }
4431 BeginningOfLine = (Buffer[Length-1] == '\n');
4432 }
4433
4434
4435 /*
4436 BusLogic_ParseKeyword parses an individual option keyword. It returns true
4437 and updates the pointer if the keyword is recognized and false otherwise.
4438 */
4439
BusLogic_ParseKeyword(char ** StringPointer,char * Keyword)4440 static boolean BusLogic_ParseKeyword(char **StringPointer, char *Keyword)
4441 {
4442 char *Pointer = *StringPointer;
4443 while (*Keyword != '\0')
4444 {
4445 char StringChar = *Pointer++;
4446 char KeywordChar = *Keyword++;
4447 if (StringChar >= 'A' && StringChar <= 'Z')
4448 StringChar += 'a' - 'Z';
4449 if (KeywordChar >= 'A' && KeywordChar <= 'Z')
4450 KeywordChar += 'a' - 'Z';
4451 if (StringChar != KeywordChar) return false;
4452 }
4453 *StringPointer = Pointer;
4454 return true;
4455 }
4456
4457
4458 /*
4459 BusLogic_ParseDriverOptions handles processing of BusLogic Driver Options
4460 specifications.
4461
4462 BusLogic Driver Options may be specified either via the Linux Kernel Command
4463 Line or via the Loadable Kernel Module Installation Facility. Driver Options
4464 for multiple host adapters may be specified either by separating the option
4465 strings by a semicolon, or by specifying multiple "BusLogic=" strings on the
4466 command line. Individual option specifications for a single host adapter are
4467 separated by commas. The Probing and Debugging Options apply to all host
4468 adapters whereas the remaining options apply individually only to the
4469 selected host adapter.
4470
4471 The BusLogic Driver Probing Options comprise the following:
4472
4473 IO:<integer>
4474
4475 The "IO:" option specifies an ISA I/O Address to be probed for a non-PCI
4476 MultiMaster Host Adapter. If neither "IO:" nor "NoProbeISA" options are
4477 specified, then the standard list of BusLogic MultiMaster ISA I/O Addresses
4478 will be probed (0x330, 0x334, 0x230, 0x234, 0x130, and 0x134). Multiple
4479 "IO:" options may be specified to precisely determine the I/O Addresses to
4480 be probed, but the probe order will always follow the standard list.
4481
4482 NoProbe
4483
4484 The "NoProbe" option disables all probing and therefore no BusLogic Host
4485 Adapters will be detected.
4486
4487 NoProbeISA
4488
4489 The "NoProbeISA" option disables probing of the standard BusLogic ISA I/O
4490 Addresses and therefore only PCI MultiMaster and FlashPoint Host Adapters
4491 will be detected.
4492
4493 NoProbePCI
4494
4495 The "NoProbePCI" options disables the interrogation of PCI Configuration
4496 Space and therefore only ISA Multimaster Host Adapters will be detected, as
4497 well as PCI Multimaster Host Adapters that have their ISA Compatible I/O
4498 Port set to "Primary" or "Alternate".
4499
4500 NoSortPCI
4501
4502 The "NoSortPCI" option forces PCI MultiMaster Host Adapters to be
4503 enumerated in the order provided by the PCI BIOS, ignoring any setting of
4504 the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option.
4505
4506 MultiMasterFirst
4507
4508 The "MultiMasterFirst" option forces MultiMaster Host Adapters to be probed
4509 before FlashPoint Host Adapters. By default, if both FlashPoint and PCI
4510 MultiMaster Host Adapters are present, this driver will probe for
4511 FlashPoint Host Adapters first unless the BIOS primary disk is controlled
4512 by the first PCI MultiMaster Host Adapter, in which case MultiMaster Host
4513 Adapters will be probed first.
4514
4515 FlashPointFirst
4516
4517 The "FlashPointFirst" option forces FlashPoint Host Adapters to be probed
4518 before MultiMaster Host Adapters.
4519
4520 The BusLogic Driver Tagged Queuing Options allow for explicitly specifying
4521 the Queue Depth and whether Tagged Queuing is permitted for each Target
4522 Device (assuming that the Target Device supports Tagged Queuing). The Queue
4523 Depth is the number of SCSI Commands that are allowed to be concurrently
4524 presented for execution (either to the Host Adapter or Target Device). Note
4525 that explicitly enabling Tagged Queuing may lead to problems; the option to
4526 enable or disable Tagged Queuing is provided primarily to allow disabling
4527 Tagged Queuing on Target Devices that do not implement it correctly. The
4528 following options are available:
4529
4530 QueueDepth:<integer>
4531
4532 The "QueueDepth:" or QD:" option specifies the Queue Depth to use for all
4533 Target Devices that support Tagged Queuing, as well as the maximum Queue
4534 Depth for devices that do not support Tagged Queuing. If no Queue Depth
4535 option is provided, the Queue Depth will be determined automatically based
4536 on the Host Adapter's Total Queue Depth and the number, type, speed, and
4537 capabilities of the detected Target Devices. For Host Adapters that
4538 require ISA Bounce Buffers, the Queue Depth is automatically set by default
4539 to BusLogic_TaggedQueueDepthBB or BusLogic_UntaggedQueueDepthBB to avoid
4540 excessive preallocation of DMA Bounce Buffer memory. Target Devices that
4541 do not support Tagged Queuing always have their Queue Depth set to
4542 BusLogic_UntaggedQueueDepth or BusLogic_UntaggedQueueDepthBB, unless a
4543 lower Queue Depth option is provided. A Queue Depth of 1 automatically
4544 disables Tagged Queuing.
4545
4546 QueueDepth:[<integer>,<integer>...]
4547
4548 The "QueueDepth:[...]" or "QD:[...]" option specifies the Queue Depth
4549 individually for each Target Device. If an <integer> is omitted, the
4550 associated Target Device will have its Queue Depth selected automatically.
4551
4552 TaggedQueuing:Default
4553
4554 The "TaggedQueuing:Default" or "TQ:Default" option permits Tagged Queuing
4555 based on the firmware version of the BusLogic Host Adapter and based on
4556 whether the Queue Depth allows queuing multiple commands.
4557
4558 TaggedQueuing:Enable
4559
4560 The "TaggedQueuing:Enable" or "TQ:Enable" option enables Tagged Queuing for
4561 all Target Devices on this Host Adapter, overriding any limitation that
4562 would otherwise be imposed based on the Host Adapter firmware version.
4563
4564 TaggedQueuing:Disable
4565
4566 The "TaggedQueuing:Disable" or "TQ:Disable" option disables Tagged Queuing
4567 for all Target Devices on this Host Adapter.
4568
4569 TaggedQueuing:<Target-Spec>
4570
4571 The "TaggedQueuing:<Target-Spec>" or "TQ:<Target-Spec>" option controls
4572 Tagged Queuing individually for each Target Device. <Target-Spec> is a
4573 sequence of "Y", "N", and "X" characters. "Y" enables Tagged Queuing, "N"
4574 disables Tagged Queuing, and "X" accepts the default based on the firmware
4575 version. The first character refers to Target Device 0, the second to
4576 Target Device 1, and so on; if the sequence of "Y", "N", and "X" characters
4577 does not cover all the Target Devices, unspecified characters are assumed
4578 to be "X".
4579
4580 The BusLogic Driver Error Recovery Option allows for explicitly specifying
4581 the Error Recovery action to be performed when BusLogic_ResetCommand is
4582 called due to a SCSI Command failing to complete successfully. The following
4583 options are available:
4584
4585 ErrorRecovery:Default
4586
4587 The "ErrorRecovery:Default" or "ER:Default" option selects between the Hard
4588 Reset and Bus Device Reset options based on the recommendation of the SCSI
4589 Subsystem.
4590
4591 ErrorRecovery:HardReset
4592
4593 The "ErrorRecovery:HardReset" or "ER:HardReset" option will initiate a Host
4594 Adapter Hard Reset which also causes a SCSI Bus Reset.
4595
4596 ErrorRecovery:BusDeviceReset
4597
4598 The "ErrorRecovery:BusDeviceReset" or "ER:BusDeviceReset" option will send
4599 a Bus Device Reset message to the individual Target Device causing the
4600 error. If Error Recovery is again initiated for this Target Device and no
4601 SCSI Command to this Target Device has completed successfully since the Bus
4602 Device Reset message was sent, then a Hard Reset will be attempted.
4603
4604 ErrorRecovery:None
4605
4606 The "ErrorRecovery:None" or "ER:None" option suppresses Error Recovery.
4607 This option should only be selected if a SCSI Bus Reset or Bus Device Reset
4608 will cause the Target Device or a critical operation to suffer a complete
4609 and unrecoverable failure.
4610
4611 ErrorRecovery:<Target-Spec>
4612
4613 The "ErrorRecovery:<Target-Spec>" or "ER:<Target-Spec>" option controls
4614 Error Recovery individually for each Target Device. <Target-Spec> is a
4615 sequence of "D", "H", "B", and "N" characters. "D" selects Default, "H"
4616 selects Hard Reset, "B" selects Bus Device Reset, and "N" selects None.
4617 The first character refers to Target Device 0, the second to Target Device
4618 1, and so on; if the sequence of "D", "H", "B", and "N" characters does not
4619 cover all the possible Target Devices, unspecified characters are assumed
4620 to be "D".
4621
4622 The BusLogic Driver Miscellaneous Options comprise the following:
4623
4624 BusSettleTime:<seconds>
4625
4626 The "BusSettleTime:" or "BST:" option specifies the Bus Settle Time in
4627 seconds. The Bus Settle Time is the amount of time to wait between a Host
4628 Adapter Hard Reset which initiates a SCSI Bus Reset and issuing any SCSI
4629 Commands. If unspecified, it defaults to BusLogic_DefaultBusSettleTime.
4630
4631 InhibitTargetInquiry
4632
4633 The "InhibitTargetInquiry" option inhibits the execution of an Inquire
4634 Target Devices or Inquire Installed Devices command on MultiMaster Host
4635 Adapters. This may be necessary with some older Target Devices that do not
4636 respond correctly when Logical Units above 0 are addressed.
4637
4638 The BusLogic Driver Debugging Options comprise the following:
4639
4640 TraceProbe
4641
4642 The "TraceProbe" option enables tracing of Host Adapter Probing.
4643
4644 TraceHardwareReset
4645
4646 The "TraceHardwareReset" option enables tracing of Host Adapter Hardware
4647 Reset.
4648
4649 TraceConfiguration
4650
4651 The "TraceConfiguration" option enables tracing of Host Adapter
4652 Configuration.
4653
4654 TraceErrors
4655
4656 The "TraceErrors" option enables tracing of SCSI Commands that return an
4657 error from the Target Device. The CDB and Sense Data will be printed for
4658 each SCSI Command that fails.
4659
4660 Debug
4661
4662 The "Debug" option enables all debugging options.
4663
4664 The following examples demonstrate setting the Queue Depth for Target Devices
4665 1 and 2 on the first host adapter to 7 and 15, the Queue Depth for all Target
4666 Devices on the second host adapter to 31, and the Bus Settle Time on the
4667 second host adapter to 30 seconds.
4668
4669 Linux Kernel Command Line:
4670
4671 linux BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30
4672
4673 LILO Linux Boot Loader (in /etc/lilo.conf):
4674
4675 append = "BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"
4676
4677 INSMOD Loadable Kernel Module Installation Facility:
4678
4679 insmod BusLogic.o \
4680 'BusLogic="QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"'
4681
4682 NOTE: Module Utilities 2.1.71 or later is required for correct parsing
4683 of driver options containing commas.
4684
4685 */
4686
BusLogic_ParseDriverOptions(char * OptionsString)4687 static int __init BusLogic_ParseDriverOptions(char *OptionsString)
4688 {
4689 while (true)
4690 {
4691 BusLogic_DriverOptions_T *DriverOptions =
4692 &BusLogic_DriverOptions[BusLogic_DriverOptionsCount++];
4693 int TargetID;
4694 memset(DriverOptions, 0, sizeof(BusLogic_DriverOptions_T));
4695 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
4696 DriverOptions->ErrorRecoveryStrategy[TargetID] =
4697 BusLogic_ErrorRecovery_Default;
4698 while (*OptionsString != '\0' && *OptionsString != ';')
4699 {
4700 /* Probing Options. */
4701 if (BusLogic_ParseKeyword(&OptionsString, "IO:"))
4702 {
4703 BusLogic_IO_Address_T IO_Address =
4704 simple_strtoul(OptionsString, &OptionsString, 0);
4705 BusLogic_ProbeOptions.LimitedProbeISA = true;
4706 switch (IO_Address)
4707 {
4708 case 0x330:
4709 BusLogic_ProbeOptions.Probe330 = true;
4710 break;
4711 case 0x334:
4712 BusLogic_ProbeOptions.Probe334 = true;
4713 break;
4714 case 0x230:
4715 BusLogic_ProbeOptions.Probe230 = true;
4716 break;
4717 case 0x234:
4718 BusLogic_ProbeOptions.Probe234 = true;
4719 break;
4720 case 0x130:
4721 BusLogic_ProbeOptions.Probe130 = true;
4722 break;
4723 case 0x134:
4724 BusLogic_ProbeOptions.Probe134 = true;
4725 break;
4726 default:
4727 BusLogic_Error("BusLogic: Invalid Driver Options "
4728 "(illegal I/O Address 0x%X)\n",
4729 NULL, IO_Address);
4730 return 0;
4731 }
4732 }
4733 else if (BusLogic_ParseKeyword(&OptionsString, "NoProbeISA"))
4734 BusLogic_ProbeOptions.NoProbeISA = true;
4735 else if (BusLogic_ParseKeyword(&OptionsString, "NoProbePCI"))
4736 BusLogic_ProbeOptions.NoProbePCI = true;
4737 else if (BusLogic_ParseKeyword(&OptionsString, "NoProbe"))
4738 BusLogic_ProbeOptions.NoProbe = true;
4739 else if (BusLogic_ParseKeyword(&OptionsString, "NoSortPCI"))
4740 BusLogic_ProbeOptions.NoSortPCI = true;
4741 else if (BusLogic_ParseKeyword(&OptionsString, "MultiMasterFirst"))
4742 BusLogic_ProbeOptions.MultiMasterFirst = true;
4743 else if (BusLogic_ParseKeyword(&OptionsString, "FlashPointFirst"))
4744 BusLogic_ProbeOptions.FlashPointFirst = true;
4745 /* Tagged Queuing Options. */
4746 else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:[") ||
4747 BusLogic_ParseKeyword(&OptionsString, "QD:["))
4748 {
4749 for (TargetID = 0;
4750 TargetID < BusLogic_MaxTargetDevices;
4751 TargetID++)
4752 {
4753 unsigned short QueueDepth =
4754 simple_strtoul(OptionsString, &OptionsString, 0);
4755 if (QueueDepth > BusLogic_MaxTaggedQueueDepth)
4756 {
4757 BusLogic_Error("BusLogic: Invalid Driver Options "
4758 "(illegal Queue Depth %d)\n",
4759 NULL, QueueDepth);
4760 return 0;
4761 }
4762 DriverOptions->QueueDepth[TargetID] = QueueDepth;
4763 if (*OptionsString == ',')
4764 OptionsString++;
4765 else if (*OptionsString == ']')
4766 break;
4767 else
4768 {
4769 BusLogic_Error("BusLogic: Invalid Driver Options "
4770 "(',' or ']' expected at '%s')\n",
4771 NULL, OptionsString);
4772 return 0;
4773 }
4774 }
4775 if (*OptionsString != ']')
4776 {
4777 BusLogic_Error("BusLogic: Invalid Driver Options "
4778 "(']' expected at '%s')\n",
4779 NULL, OptionsString);
4780 return 0;
4781 }
4782 else OptionsString++;
4783 }
4784 else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:") ||
4785 BusLogic_ParseKeyword(&OptionsString, "QD:"))
4786 {
4787 unsigned short QueueDepth =
4788 simple_strtoul(OptionsString, &OptionsString, 0);
4789 if (QueueDepth == 0 || QueueDepth > BusLogic_MaxTaggedQueueDepth)
4790 {
4791 BusLogic_Error("BusLogic: Invalid Driver Options "
4792 "(illegal Queue Depth %d)\n",
4793 NULL, QueueDepth);
4794 return 0;
4795 }
4796 DriverOptions->CommonQueueDepth = QueueDepth;
4797 for (TargetID = 0;
4798 TargetID < BusLogic_MaxTargetDevices;
4799 TargetID++)
4800 DriverOptions->QueueDepth[TargetID] = QueueDepth;
4801 }
4802 else if (BusLogic_ParseKeyword(&OptionsString, "TaggedQueuing:") ||
4803 BusLogic_ParseKeyword(&OptionsString, "TQ:"))
4804 {
4805 if (BusLogic_ParseKeyword(&OptionsString, "Default"))
4806 {
4807 DriverOptions->TaggedQueuingPermitted = 0x0000;
4808 DriverOptions->TaggedQueuingPermittedMask = 0x0000;
4809 }
4810 else if (BusLogic_ParseKeyword(&OptionsString, "Enable"))
4811 {
4812 DriverOptions->TaggedQueuingPermitted = 0xFFFF;
4813 DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
4814 }
4815 else if (BusLogic_ParseKeyword(&OptionsString, "Disable"))
4816 {
4817 DriverOptions->TaggedQueuingPermitted = 0x0000;
4818 DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
4819 }
4820 else
4821 {
4822 unsigned short TargetBit;
4823 for (TargetID = 0, TargetBit = 1;
4824 TargetID < BusLogic_MaxTargetDevices;
4825 TargetID++, TargetBit <<= 1)
4826 switch (*OptionsString++)
4827 {
4828 case 'Y':
4829 DriverOptions->TaggedQueuingPermitted |= TargetBit;
4830 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
4831 break;
4832 case 'N':
4833 DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
4834 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
4835 break;
4836 case 'X':
4837 break;
4838 default:
4839 OptionsString--;
4840 TargetID = BusLogic_MaxTargetDevices;
4841 break;
4842 }
4843 }
4844 }
4845 /* Error Recovery Option. */
4846 else if (BusLogic_ParseKeyword(&OptionsString, "ErrorRecovery:") ||
4847 BusLogic_ParseKeyword(&OptionsString, "ER:"))
4848 {
4849 if (BusLogic_ParseKeyword(&OptionsString, "Default"))
4850 for (TargetID = 0;
4851 TargetID < BusLogic_MaxTargetDevices;
4852 TargetID++)
4853 DriverOptions->ErrorRecoveryStrategy[TargetID] =
4854 BusLogic_ErrorRecovery_Default;
4855 else if (BusLogic_ParseKeyword(&OptionsString, "HardReset"))
4856 for (TargetID = 0;
4857 TargetID < BusLogic_MaxTargetDevices;
4858 TargetID++)
4859 DriverOptions->ErrorRecoveryStrategy[TargetID] =
4860 BusLogic_ErrorRecovery_HardReset;
4861 else if (BusLogic_ParseKeyword(&OptionsString, "BusDeviceReset"))
4862 for (TargetID = 0;
4863 TargetID < BusLogic_MaxTargetDevices;
4864 TargetID++)
4865 DriverOptions->ErrorRecoveryStrategy[TargetID] =
4866 BusLogic_ErrorRecovery_BusDeviceReset;
4867 else if (BusLogic_ParseKeyword(&OptionsString, "None"))
4868 for (TargetID = 0;
4869 TargetID < BusLogic_MaxTargetDevices;
4870 TargetID++)
4871 DriverOptions->ErrorRecoveryStrategy[TargetID] =
4872 BusLogic_ErrorRecovery_None;
4873 else
4874 for (TargetID = 0;
4875 TargetID < BusLogic_MaxTargetDevices;
4876 TargetID++)
4877 switch (*OptionsString++)
4878 {
4879 case 'D':
4880 DriverOptions->ErrorRecoveryStrategy[TargetID] =
4881 BusLogic_ErrorRecovery_Default;
4882 break;
4883 case 'H':
4884 DriverOptions->ErrorRecoveryStrategy[TargetID] =
4885 BusLogic_ErrorRecovery_HardReset;
4886 break;
4887 case 'B':
4888 DriverOptions->ErrorRecoveryStrategy[TargetID] =
4889 BusLogic_ErrorRecovery_BusDeviceReset;
4890 break;
4891 case 'N':
4892 DriverOptions->ErrorRecoveryStrategy[TargetID] =
4893 BusLogic_ErrorRecovery_None;
4894 break;
4895 default:
4896 OptionsString--;
4897 TargetID = BusLogic_MaxTargetDevices;
4898 break;
4899 }
4900 }
4901 /* Miscellaneous Options. */
4902 else if (BusLogic_ParseKeyword(&OptionsString, "BusSettleTime:") ||
4903 BusLogic_ParseKeyword(&OptionsString, "BST:"))
4904 {
4905 unsigned short BusSettleTime =
4906 simple_strtoul(OptionsString, &OptionsString, 0);
4907 if (BusSettleTime > 5 * 60)
4908 {
4909 BusLogic_Error("BusLogic: Invalid Driver Options "
4910 "(illegal Bus Settle Time %d)\n",
4911 NULL, BusSettleTime);
4912 return 0;
4913 }
4914 DriverOptions->BusSettleTime = BusSettleTime;
4915 }
4916 else if (BusLogic_ParseKeyword(&OptionsString,
4917 "InhibitTargetInquiry"))
4918 DriverOptions->LocalOptions.InhibitTargetInquiry = true;
4919 /* Debugging Options. */
4920 else if (BusLogic_ParseKeyword(&OptionsString, "TraceProbe"))
4921 BusLogic_GlobalOptions.TraceProbe = true;
4922 else if (BusLogic_ParseKeyword(&OptionsString, "TraceHardwareReset"))
4923 BusLogic_GlobalOptions.TraceHardwareReset = true;
4924 else if (BusLogic_ParseKeyword(&OptionsString, "TraceConfiguration"))
4925 BusLogic_GlobalOptions.TraceConfiguration = true;
4926 else if (BusLogic_ParseKeyword(&OptionsString, "TraceErrors"))
4927 BusLogic_GlobalOptions.TraceErrors = true;
4928 else if (BusLogic_ParseKeyword(&OptionsString, "Debug"))
4929 {
4930 BusLogic_GlobalOptions.TraceProbe = true;
4931 BusLogic_GlobalOptions.TraceHardwareReset = true;
4932 BusLogic_GlobalOptions.TraceConfiguration = true;
4933 BusLogic_GlobalOptions.TraceErrors = true;
4934 }
4935 if (*OptionsString == ',')
4936 OptionsString++;
4937 else if (*OptionsString != ';' && *OptionsString != '\0')
4938 {
4939 BusLogic_Error("BusLogic: Unexpected Driver Option '%s' "
4940 "ignored\n", NULL, OptionsString);
4941 *OptionsString = '\0';
4942 }
4943 }
4944 if (!(BusLogic_DriverOptionsCount == 0 ||
4945 BusLogic_ProbeInfoCount == 0 ||
4946 BusLogic_DriverOptionsCount == BusLogic_ProbeInfoCount))
4947 {
4948 BusLogic_Error("BusLogic: Invalid Driver Options "
4949 "(all or no I/O Addresses must be specified)\n", NULL);
4950 return 0;
4951 }
4952 /*
4953 Tagged Queuing is disabled when the Queue Depth is 1 since queuing
4954 multiple commands is not possible.
4955 */
4956 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
4957 if (DriverOptions->QueueDepth[TargetID] == 1)
4958 {
4959 unsigned short TargetBit = 1 << TargetID;
4960 DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
4961 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
4962 }
4963 if (*OptionsString == ';') OptionsString++;
4964 if (*OptionsString == '\0') return 0;
4965 }
4966 return 1;
4967 }
4968
4969
4970 /*
4971 BusLogic_Setup handles processing of Kernel Command Line Arguments.
4972 */
4973
4974 static int __init
BusLogic_Setup(char * str)4975 BusLogic_Setup(char *str)
4976 {
4977 int ints[3];
4978
4979 (void)get_options(str, ARRAY_SIZE(ints), ints);
4980
4981 if (ints[0] != 0) {
4982 BusLogic_Error("BusLogic: Obsolete Command Line Entry "
4983 "Format Ignored\n", NULL);
4984 return 0;
4985 }
4986 if (str == NULL || *str == '\0')
4987 return 0;
4988 return BusLogic_ParseDriverOptions(str);
4989 }
4990
4991 __setup("BusLogic=", BusLogic_Setup);
4992
4993 /*
4994 Get it all started
4995 */
4996 MODULE_LICENSE("GPL");
4997
4998 static SCSI_Host_Template_T driver_template = BUSLOGIC;
4999
5000 #include "scsi_module.c"
5001