|
|
1.1 root 1: /*
2:
3: Linux Driver for BusLogic MultiMaster SCSI Host Adapters
4:
5: Copyright 1995 by Leonard N. Zubkoff <[email protected]>
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, provided that none of the source code or runtime
10: copyright notices are removed or modified.
11:
12: This program is distributed in the hope that it will be useful, but
13: WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
14: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15: for complete details.
16:
17: The author respectfully requests that all modifications to this software be
18: sent directly to him for evaluation and testing.
19:
20: Special thanks to Alex T. Win of BusLogic, whose advice has been invaluable,
21: to David B. Gentzel, for writing the original Linux BusLogic driver, and to
22: Paul Gortmaker, for being such a dedicated test site.
23:
24: */
25:
26:
27: #define BusLogic_DriverVersion "1.3.1"
28: #define BusLogic_DriverDate "31 December 1995"
29:
30:
31: #include <linux/module.h>
32: #include <linux/config.h>
33: #include <linux/types.h>
34: #include <linux/blkdev.h>
35: #include <linux/delay.h>
36: #include <linux/ioport.h>
37: #include <linux/kernel_stat.h>
38: #include <linux/mm.h>
39: #include <linux/sched.h>
40: #include <linux/stat.h>
41: #include <linux/pci.h>
42: #include <linux/bios32.h>
43: #include <asm/dma.h>
44: #include <asm/io.h>
45: #include <asm/system.h>
46: #include "scsi.h"
47: #include "hosts.h"
48: #include "sd.h"
49: #include "BusLogic.h"
50:
51:
52: /*
53: BusLogic_CommandLineEntryCount is a count of the number of "BusLogic="
54: entries provided on the Linux Kernel Command Line.
55: */
56:
57: static int
58: BusLogic_CommandLineEntryCount = 0;
59:
60:
61: /*
62: BusLogic_CommandLineEntries is an array of Command Line Entry structures
63: representing the "BusLogic=" entries provided on the Linux Kernel Command
64: Line.
65: */
66:
67: static BusLogic_CommandLineEntry_T
68: BusLogic_CommandLineEntries[BusLogic_MaxHostAdapters];
69:
70:
71: /*
72: BusLogic_GlobalOptions is a bit mask of Global Options to be applied
73: across all Host Adapters.
74: */
75:
76: static int
77: BusLogic_GlobalOptions = 0;
78:
79:
80: /*
81: BusLogic_RegisteredHostAdapters is a linked list of all the registered
82: BusLogic Host Adapters.
83: */
84:
85: static BusLogic_HostAdapter_T
86: *BusLogic_RegisteredHostAdapters = NULL;
87:
88:
89: /*
90: BusLogic_Standard_IO_Addresses is the list of standard I/O Addresses at which
91: BusLogic Host Adapters may potentially be found.
92: */
93:
94: static unsigned short
95: BusLogic_IO_StandardAddresses[] =
96: { 0x330, 0x334, 0x230, 0x234, 0x130, 0x134, 0 };
97:
98:
99: /*
100: BusLogic_IO_AddressProbeList is the list of I/O Addresses to be probed for
101: potential BusLogic Host Adapters. It is initialized by interrogating the
102: PCI Configuration Space on PCI machines as well as from the list of
103: standard BusLogic I/O Addresses.
104: */
105:
106: static unsigned short
107: BusLogic_IO_AddressProbeList[BusLogic_IO_MaxProbeAddresses+1] = { 0 };
108:
109:
110: /*
111: BusLogic_IRQ_UsageCount stores a count of the number of Host Adapters using
112: a given IRQ Channel, which is necessary to support PCI, EISA, or MCA shared
113: interrupts. Only IRQ Channels 9, 10, 11, 12, 14, and 15 are supported by
114: BusLogic Host Adapters.
115: */
116:
117: static short
118: BusLogic_IRQ_UsageCount[7] = { 0 };
119:
120:
121: /*
122: BusLogic_CommandFailureReason holds a string identifying the reason why a
123: call to BusLogic_Command failed. It is only valid when BusLogic_Command
124: returns a failure code.
125: */
126:
127: static char
128: *BusLogic_CommandFailureReason;
129:
130:
131: /*
132: BusLogic_ProcDirectoryEntry is the BusLogic /proc/scsi directory entry.
133: */
134:
135: static struct proc_dir_entry
136: BusLogic_ProcDirectoryEntry =
137: { PROC_SCSI_BUSLOGIC, 8, "BusLogic", S_IFDIR | S_IRUGO | S_IXUGO, 2 };
138:
139:
140: /*
141: BusLogic_AnnounceDriver announces the Driver Version and Date, Author's
142: Name, Copyright Notice, and Contact Address.
143: */
144:
145: static void BusLogic_AnnounceDriver(void)
146: {
147: static boolean DriverAnnouncementPrinted = false;
148: if (DriverAnnouncementPrinted) return;
149: printk("scsi: ***** BusLogic SCSI Driver Version "
150: BusLogic_DriverVersion " of " BusLogic_DriverDate " *****\n");
151: printk("scsi: Copyright 1995 by Leonard N. Zubkoff <[email protected]>\n");
152: DriverAnnouncementPrinted = true;
153: }
154:
155:
156: /*
157: BusLogic_DriverInfo returns the Board Name to identify this SCSI Driver
158: and Host Adapter.
159: */
160:
161: const char *BusLogic_DriverInfo(SCSI_Host_T *Host)
162: {
163: BusLogic_HostAdapter_T *HostAdapter =
164: (BusLogic_HostAdapter_T *) Host->hostdata;
165: return HostAdapter->BoardName;
166: }
167:
168:
169: /*
170: BusLogic_InitializeAddressProbeList initializes the list of I/O Addresses
171: to be probed for potential BusLogic SCSI Host Adapters by interrogating the
172: PCI Configuration Space on PCI machines as well as from the list of standard
173: BusLogic I/O Addresses.
174: */
175:
176: static void BusLogic_InitializeAddressProbeList(void)
177: {
178: int DestinationIndex = 0, SourceIndex = 0;
179: /*
180: If BusLogic_Setup has been called, do not override the Kernel Command
181: Line specifications.
182: */
183: if (BusLogic_IO_AddressProbeList[0] != 0) return;
184: #ifdef CONFIG_PCI
185: /*
186: Interrogate PCI Configuration Space for any BusLogic SCSI Host Adapters.
187: */
188: if (pcibios_present())
189: {
190: unsigned short Index = 0, VendorID;
191: unsigned char Bus, DeviceAndFunction;
192: unsigned int BaseAddress0;
193: while (pcibios_find_class(PCI_CLASS_STORAGE_SCSI<<8, Index++,
194: &Bus, &DeviceAndFunction) == 0)
195: if (pcibios_read_config_word(Bus, DeviceAndFunction,
196: PCI_VENDOR_ID, &VendorID) == 0 &&
197: VendorID == PCI_VENDOR_ID_BUSLOGIC &&
198: pcibios_read_config_dword(Bus, DeviceAndFunction,
199: PCI_BASE_ADDRESS_0, &BaseAddress0) == 0 &&
200: (BaseAddress0 & PCI_BASE_ADDRESS_SPACE) ==
201: PCI_BASE_ADDRESS_SPACE_IO)
202: {
203: BusLogic_IO_AddressProbeList[DestinationIndex++] =
204: BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK;
205: }
206: }
207: #endif
208: /*
209: Append the list of standard BusLogic I/O Addresses.
210: */
211: while (DestinationIndex < BusLogic_IO_MaxProbeAddresses &&
212: BusLogic_IO_StandardAddresses[SourceIndex] > 0)
213: BusLogic_IO_AddressProbeList[DestinationIndex++] =
214: BusLogic_IO_StandardAddresses[SourceIndex++];
215: BusLogic_IO_AddressProbeList[DestinationIndex] = 0;
216: }
217:
218:
219: /*
220: BusLogic_RegisterHostAdapter adds Host Adapter to the list of registered
221: BusLogic Host Adapters.
222: */
223:
224: static void BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
225: {
226: HostAdapter->Next = NULL;
227: if (BusLogic_RegisteredHostAdapters != NULL)
228: {
229: BusLogic_HostAdapter_T *LastHostAdapter = BusLogic_RegisteredHostAdapters;
230: BusLogic_HostAdapter_T *NextHostAdapter;
231: while ((NextHostAdapter = LastHostAdapter->Next) != NULL)
232: LastHostAdapter = NextHostAdapter;
233: LastHostAdapter->Next = HostAdapter;
234: }
235: else BusLogic_RegisteredHostAdapters = HostAdapter;
236: }
237:
238:
239: /*
240: BusLogic_UnregisterHostAdapter removes Host Adapter from the list of
241: registered BusLogic Host Adapters.
242: */
243:
244: static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
245: {
246: if (BusLogic_RegisteredHostAdapters != HostAdapter)
247: {
248: BusLogic_HostAdapter_T *LastHostAdapter = BusLogic_RegisteredHostAdapters;
249: while (LastHostAdapter != NULL && LastHostAdapter->Next != HostAdapter)
250: LastHostAdapter = LastHostAdapter->Next;
251: if (LastHostAdapter != NULL)
252: LastHostAdapter->Next = HostAdapter->Next;
253: }
254: else BusLogic_RegisteredHostAdapters = HostAdapter->Next;
255: HostAdapter->Next = NULL;
256: }
257:
258:
259: /*
260: BusLogic_CreateCCBs allocates the initial Command Control Blocks (CCBs)
261: for Host Adapter.
262: */
263:
264: static boolean BusLogic_CreateCCBs(BusLogic_HostAdapter_T *HostAdapter)
265: {
266: int i;
267: for (i = 0; i < BusLogic_InitialCCBs; i++)
268: {
269: BusLogic_CCB_T *CCB = (BusLogic_CCB_T *)
270: scsi_init_malloc(sizeof(BusLogic_CCB_T), GFP_ATOMIC | GFP_DMA);
271: if (CCB == NULL)
272: {
273: printk("scsi%d: UNABLE TO ALLOCATE CCB %d - DETACHING\n",
274: HostAdapter->HostNumber, i);
275: return false;
276: }
277: memset(CCB, 0, sizeof(BusLogic_CCB_T));
278: CCB->HostAdapter = HostAdapter;
279: CCB->Status = BusLogic_CCB_Free;
280: CCB->Next = HostAdapter->Free_CCBs;
281: CCB->NextAll = HostAdapter->All_CCBs;
282: HostAdapter->Free_CCBs = CCB;
283: HostAdapter->All_CCBs = CCB;
284: }
285: return true;
286: }
287:
288:
289: /*
290: BusLogic_DestroyCCBs deallocates the CCBs for Host Adapter.
291: */
292:
293: static void BusLogic_DestroyCCBs(BusLogic_HostAdapter_T *HostAdapter)
294: {
295: BusLogic_CCB_T *NextCCB = HostAdapter->All_CCBs, *CCB;
296: HostAdapter->All_CCBs = NULL;
297: HostAdapter->Free_CCBs = NULL;
298: while ((CCB = NextCCB) != NULL)
299: {
300: NextCCB = CCB->NextAll;
301: scsi_init_free((char *) CCB, sizeof(BusLogic_CCB_T));
302: }
303: }
304:
305:
306: /*
307: BusLogic_AllocateCCB allocates a CCB from the Host Adapter's free list,
308: allocating more memory from the Kernel if necessary.
309: */
310:
311: static BusLogic_CCB_T *BusLogic_AllocateCCB(BusLogic_HostAdapter_T *HostAdapter)
312: {
313: static unsigned int SerialNumber = 0;
314: BusLogic_CCB_T *CCB;
315: BusLogic_LockHostAdapter(HostAdapter);
316: CCB = HostAdapter->Free_CCBs;
317: if (CCB != NULL)
318: {
319: CCB->SerialNumber = ++SerialNumber;
320: HostAdapter->Free_CCBs = CCB->Next;
321: CCB->Next = NULL;
322: BusLogic_UnlockHostAdapter(HostAdapter);
323: return CCB;
324: }
325: BusLogic_UnlockHostAdapter(HostAdapter);
326: CCB = (BusLogic_CCB_T *) scsi_init_malloc(sizeof(BusLogic_CCB_T),
327: GFP_ATOMIC | GFP_DMA);
328: if (CCB == NULL)
329: {
330: printk("scsi%d: Failed to allocate an additional CCB\n",
331: HostAdapter->HostNumber);
332: return NULL;
333: }
334: printk("scsi%d: Allocated an additional CCB\n", HostAdapter->HostNumber);
335: memset(CCB, 0, sizeof(BusLogic_CCB_T));
336: CCB->HostAdapter = HostAdapter;
337: CCB->Status = BusLogic_CCB_Free;
338: BusLogic_LockHostAdapter(HostAdapter);
339: CCB->SerialNumber = ++SerialNumber;
340: CCB->NextAll = HostAdapter->All_CCBs;
341: HostAdapter->All_CCBs = CCB;
342: BusLogic_UnlockHostAdapter(HostAdapter);
343: return CCB;
344: }
345:
346:
347: /*
348: BusLogic_DeallocateCCB deallocates a CCB, returning it to the Host Adapter's
349: free list.
350: */
351:
352: static void BusLogic_DeallocateCCB(BusLogic_CCB_T *CCB)
353: {
354: BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
355: BusLogic_LockHostAdapter(HostAdapter);
356: CCB->Command = NULL;
357: CCB->Status = BusLogic_CCB_Free;
358: CCB->Next = HostAdapter->Free_CCBs;
359: HostAdapter->Free_CCBs = CCB;
360: BusLogic_UnlockHostAdapter(HostAdapter);
361: }
362:
363:
364: /*
365: BusLogic_Command sends the command OperationCode to HostAdapter, optionally
366: providing ParameterLength bytes of ParameterData and receiving at most
367: ReplyLength bytes of ReplyData; any excess reply data is received but
368: discarded.
369:
370: On success, this function returns the number of reply bytes read from
371: the Host Adapter (including any discarded data); on failure, it returns
372: -1 if the command was invalid, or -2 if a timeout occurred.
373:
374: This function is only called during board detection and initialization, so
375: performance and latency are not critical, and exclusive access to the Host
376: Adapter hardware is assumed. Once the board and driver are initialized, the
377: only Host Adapter command that is issued is the single byte Start Mailbox
378: Scan command, which does not require waiting for the Host Adapter Ready bit
379: to be set in the Status Register.
380: */
381:
382: static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter,
383: BusLogic_OperationCode_T OperationCode,
384: void *ParameterData,
385: int ParameterLength,
386: void *ReplyData,
387: int ReplyLength)
388: {
389: unsigned char *ParameterPointer = (unsigned char *) ParameterData;
390: unsigned char *ReplyPointer = (unsigned char *) ReplyData;
391: unsigned char StatusRegister = 0, InterruptRegister;
392: long TimeoutCounter;
393: int ReplyBytes = 0;
394: /*
395: Clear out the Reply Data if provided.
396: */
397: if (ReplyLength > 0)
398: memset(ReplyData, 0, ReplyLength);
399: /*
400: Wait for the Host Adapter Ready bit to be set and the Command/Parameter
401: Register Busy bit to be reset in the Status Register.
402: */
403: TimeoutCounter = loops_per_sec >> 3;
404: while (--TimeoutCounter >= 0)
405: {
406: StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
407: if ((StatusRegister & BusLogic_HostAdapterReady) &&
408: !(StatusRegister & BusLogic_CommandParameterRegisterBusy))
409: break;
410: }
411: BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";
412: if (TimeoutCounter < 0) return -2;
413: /*
414: Write the OperationCode to the Command/Parameter Register.
415: */
416: HostAdapter->HostAdapterCommandCompleted = false;
417: BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);
418: /*
419: Write any additional Parameter Bytes.
420: */
421: TimeoutCounter = 10000;
422: while (ParameterLength > 0 && --TimeoutCounter >= 0)
423: {
424: /*
425: Wait 100 microseconds to give the Host Adapter enough time to determine
426: whether the last value written to the Command/Parameter Register was
427: valid or not. If the Command Complete bit is set in the Interrupt
428: Register, then the Command Invalid bit in the Status Register will be
429: reset if the Operation Code or Parameter was valid and the command
430: has completed, or set if the Operation Code or Parameter was invalid.
431: If the Data In Register Ready bit is set in the Status Register, then
432: the Operation Code was valid, and data is waiting to be read back
433: from the Host Adapter. Otherwise, wait for the Command/Parameter
434: Register Busy bit in the Status Register to be reset.
435: */
436: udelay(100);
437: InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
438: StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
439: if (InterruptRegister & BusLogic_CommandComplete) break;
440: if (HostAdapter->HostAdapterCommandCompleted) break;
441: if (StatusRegister & BusLogic_DataInRegisterReady) break;
442: if (StatusRegister & BusLogic_CommandParameterRegisterBusy) continue;
443: BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++);
444: ParameterLength--;
445: }
446: BusLogic_CommandFailureReason = "Timeout waiting for Parameter Acceptance";
447: if (TimeoutCounter < 0) return -2;
448: /*
449: The Modify I/O Address command does not cause a Command Complete Interrupt.
450: */
451: if (OperationCode == BusLogic_ModifyIOAddress)
452: {
453: StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
454: BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
455: if (StatusRegister & BusLogic_CommandInvalid) return -1;
456: BusLogic_CommandFailureReason = NULL;
457: return 0;
458: }
459: /*
460: Select an appropriate timeout value for awaiting command completion.
461: */
462: switch (OperationCode)
463: {
464: case BusLogic_InquireInstalledDevicesID0to7:
465: case BusLogic_InquireInstalledDevicesID8to15:
466: /* Approximately 60 seconds. */
467: TimeoutCounter = loops_per_sec << 2;
468: break;
469: default:
470: /* Approximately 1 second. */
471: TimeoutCounter = loops_per_sec >> 4;
472: break;
473: }
474: /*
475: Receive any Reply Bytes, waiting for either the Command Complete bit to
476: be set in the Interrupt Register, or for the Interrupt Handler to set the
477: Host Adapter Command Completed bit in the Host Adapter structure.
478: */
479: while (--TimeoutCounter >= 0)
480: {
481: InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
482: StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
483: if (InterruptRegister & BusLogic_CommandComplete) break;
484: if (HostAdapter->HostAdapterCommandCompleted) break;
485: if (StatusRegister & BusLogic_DataInRegisterReady)
486: if (++ReplyBytes <= ReplyLength)
487: *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
488: else BusLogic_ReadDataInRegister(HostAdapter);
489: }
490: BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";
491: if (TimeoutCounter < 0) return -2;
492: /*
493: If testing Command Complete Interrupts, wait a short while in case the
494: loop immediately above terminated due to the Command Complete bit being
495: set in the Interrupt Register, but the interrupt hasn't actually been
496: processed yet. Otherwise, acknowledging the interrupt here could prevent
497: the interrupt test from succeeding.
498: */
499: if (OperationCode == BusLogic_TestCommandCompleteInterrupt)
500: udelay(10000);
501: /*
502: Clear any pending Command Complete Interrupt.
503: */
504: BusLogic_WriteControlRegister(HostAdapter, BusLogic_InterruptReset);
505: if (BusLogic_GlobalOptions & BusLogic_TraceConfiguration)
506: if (OperationCode != BusLogic_TestCommandCompleteInterrupt)
507: {
508: int i;
509: printk("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:",
510: OperationCode, StatusRegister, ReplyLength, ReplyBytes);
511: if (ReplyLength > ReplyBytes) ReplyLength = ReplyBytes;
512: for (i = 0; i < ReplyLength; i++)
513: printk(" %02X", ((unsigned char *) ReplyData)[i]);
514: printk("\n");
515: }
516: /*
517: Process Command Invalid conditions.
518: */
519: if (StatusRegister & BusLogic_CommandInvalid)
520: {
521: /*
522: Some early BusLogic Host Adapters may not recover properly from
523: a Command Invalid condition, so if this appears to be the case,
524: a Soft Reset is issued to the Host Adapter. Potentially invalid
525: commands are never attempted after Mailbox Initialization is
526: performed, so there should be no Host Adapter state lost by a
527: Soft Reset in response to a Command Invalid condition.
528: */
529: udelay(1000);
530: StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
531: if (StatusRegister != (BusLogic_HostAdapterReady |
532: BusLogic_InitializationRequired))
533: {
534: BusLogic_WriteControlRegister(HostAdapter, BusLogic_SoftReset);
535: udelay(1000);
536: }
537: BusLogic_CommandFailureReason = "Command Invalid";
538: return -1;
539: }
540: /*
541: Handle Excess Parameters Supplied conditions.
542: */
543: BusLogic_CommandFailureReason = "Excess Parameters Supplied";
544: if (ParameterLength > 0) return -1;
545: /*
546: Indicate the command completed successfully.
547: */
548: BusLogic_CommandFailureReason = NULL;
549: return ReplyBytes;
550: }
551:
552:
553: /*
554: BusLogic_Failure prints a standardized error message, and then returns false.
555: */
556:
557: static boolean BusLogic_Failure(BusLogic_HostAdapter_T *HostAdapter,
558: char *ErrorMessage)
559: {
560: BusLogic_AnnounceDriver();
561: printk("While configuring BusLogic Host Adapter at I/O Address 0x%X:\n",
562: HostAdapter->IO_Address);
563: printk("%s FAILED - DETACHING\n", ErrorMessage);
564: if (BusLogic_CommandFailureReason != NULL)
565: printk("ADDITIONAL FAILURE INFO - %s\n", BusLogic_CommandFailureReason);
566: return false;
567: }
568:
569:
570: /*
571: BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter.
572: */
573:
574: static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
575: {
576: boolean TraceProbe = (BusLogic_GlobalOptions & BusLogic_TraceProbe);
577: unsigned char StatusRegister, GeometryRegister;
578: /*
579: Read the Status Register to test if there is an I/O port that responds. A
580: nonexistent I/O port will return 0xFF, in which case there is definitely no
581: BusLogic Host Adapter at this base I/O Address.
582: */
583: StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
584: if (TraceProbe)
585: printk("BusLogic_Probe(0x%X): Status 0x%02X\n",
586: HostAdapter->IO_Address, StatusRegister);
587: if (StatusRegister == 0xFF) return false;
588: /*
589: Read the undocumented BusLogic Geometry Register to test if there is an I/O
590: port that responds. Adaptec Host Adapters do not implement the Geometry
591: Register, so this test helps serve to avoid incorrectly recognizing an
592: Adaptec 1542A or 1542B as a BusLogic. Unfortunately, the Adaptec 1542C
593: series does respond to the Geometry Register I/O port, but it will be
594: rejected later when the Inquire Extended Setup Information command is
595: issued in BusLogic_CheckHostAdapter. The AMI FastDisk Host Adapter is a
596: BusLogic clone that implements the same interface as earlier BusLogic
597: boards, including the undocumented commands, and is therefore supported by
598: this driver. However, the AMI FastDisk always returns 0x00 upon reading
599: the Geometry Register, so the extended translation option should always be
600: left disabled on the AMI FastDisk.
601: */
602: GeometryRegister = BusLogic_ReadGeometryRegister(HostAdapter);
603: if (TraceProbe)
604: printk("BusLogic_Probe(0x%X): Geometry 0x%02X\n",
605: HostAdapter->IO_Address, GeometryRegister);
606: if (GeometryRegister == 0xFF) return false;
607: /*
608: Indicate the Host Adapter Probe completed successfully.
609: */
610: return true;
611: }
612:
613:
614: /*
615: BusLogic_HardResetHostAdapter issues a Hard Reset to the Host Adapter,
616: and waits for Host Adapter Diagnostics to complete.
617: */
618:
619: static boolean BusLogic_HardResetHostAdapter(BusLogic_HostAdapter_T
620: *HostAdapter)
621: {
622: boolean TraceHardReset = (BusLogic_GlobalOptions & BusLogic_TraceHardReset);
623: long TimeoutCounter = loops_per_sec >> 2;
624: unsigned char StatusRegister = 0;
625: /*
626: Issue a Hard Reset Command to the Host Adapter. The Host Adapter should
627: respond by setting Diagnostic Active in the Status Register.
628: */
629: BusLogic_WriteControlRegister(HostAdapter, BusLogic_HardReset);
630: /*
631: Wait until Diagnostic Active is set in the Status Register.
632: */
633: while (--TimeoutCounter >= 0)
634: {
635: StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
636: if ((StatusRegister & BusLogic_DiagnosticActive)) break;
637: }
638: if (TraceHardReset)
639: printk("BusLogic_HardReset(0x%X): Diagnostic Active, Status 0x%02X\n",
640: HostAdapter->IO_Address, StatusRegister);
641: if (TimeoutCounter < 0) return false;
642: /*
643: Wait 100 microseconds to allow completion of any initial diagnostic
644: activity which might leave the contents of the Status Register
645: unpredictable.
646: */
647: udelay(100);
648: /*
649: Wait until Diagnostic Active is reset in the Status Register.
650: */
651: while (--TimeoutCounter >= 0)
652: {
653: StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
654: if (!(StatusRegister & BusLogic_DiagnosticActive)) break;
655: }
656: if (TraceHardReset)
657: printk("BusLogic_HardReset(0x%X): Diagnostic Completed, Status 0x%02X\n",
658: HostAdapter->IO_Address, StatusRegister);
659: if (TimeoutCounter < 0) return false;
660: /*
661: Wait until at least one of the Diagnostic Failure, Host Adapter Ready,
662: or Data In Register Ready bits is set in the Status Register.
663: */
664: while (--TimeoutCounter >= 0)
665: {
666: StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
667: if (StatusRegister & (BusLogic_DiagnosticFailure |
668: BusLogic_HostAdapterReady |
669: BusLogic_DataInRegisterReady))
670: break;
671: }
672: if (TraceHardReset)
673: printk("BusLogic_HardReset(0x%X): Host Adapter Ready, Status 0x%02X\n",
674: HostAdapter->IO_Address, StatusRegister);
675: if (TimeoutCounter < 0) return false;
676: /*
677: If Diagnostic Failure is set or Host Adapter Ready is reset, then an
678: error occurred during the Host Adapter diagnostics. If Data In Register
679: Ready is set, then there is an Error Code available.
680: */
681: if ((StatusRegister & BusLogic_DiagnosticFailure) ||
682: !(StatusRegister & BusLogic_HostAdapterReady))
683: {
684: BusLogic_CommandFailureReason = NULL;
685: BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
686: printk("HOST ADAPTER STATUS REGISTER = %02X\n", StatusRegister);
687: if (StatusRegister & BusLogic_DataInRegisterReady)
688: {
689: unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
690: printk("HOST ADAPTER ERROR CODE = %d\n", ErrorCode);
691: }
692: return false;
693: }
694: /*
695: Indicate the Host Adapter Hard Reset completed successfully.
696: */
697: return true;
698: }
699:
700:
701: /*
702: BusLogic_CheckHostAdapter checks to be sure this really is a BusLogic
703: Host Adapter.
704: */
705:
706: static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
707: {
708: BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
709: BusLogic_RequestedReplyLength_T RequestedReplyLength;
710: unsigned long ProcessorFlags;
711: int Result;
712: /*
713: Issue the Inquire Extended Setup Information command. Only genuine
714: BusLogic Host Adapters and true clones support this command. Adaptec 1542C
715: series Host Adapters that respond to the Geometry Register I/O port will
716: fail this command. Interrupts must be disabled around the call to
717: BusLogic_Command since a Command Complete interrupt could occur if the IRQ
718: Channel was previously enabled for another BusLogic Host Adapter sharing
719: the same IRQ Channel.
720: */
721: save_flags(ProcessorFlags);
722: cli();
723: RequestedReplyLength = sizeof(ExtendedSetupInformation);
724: Result = BusLogic_Command(HostAdapter,
725: BusLogic_InquireExtendedSetupInformation,
726: &RequestedReplyLength, sizeof(RequestedReplyLength),
727: &ExtendedSetupInformation,
728: sizeof(ExtendedSetupInformation));
729: restore_flags(ProcessorFlags);
730: if (BusLogic_GlobalOptions & BusLogic_TraceProbe)
731: printk("BusLogic_Check(0x%X): Result %d\n",
732: HostAdapter->IO_Address, Result);
733: return (Result == sizeof(ExtendedSetupInformation));
734: }
735:
736:
737: /*
738: BusLogic_ReadHostAdapterConfiguration reads the Configuration Information
739: from Host Adapter.
740: */
741:
742: static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T
743: *HostAdapter)
744: {
745: BusLogic_BoardID_T BoardID;
746: BusLogic_Configuration_T Configuration;
747: BusLogic_SetupInformation_T SetupInformation;
748: BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
749: BusLogic_BoardModelNumber_T BoardModelNumber;
750: BusLogic_FirmwareVersion3rdDigit_T FirmwareVersion3rdDigit;
751: BusLogic_FirmwareVersionLetter_T FirmwareVersionLetter;
752: BusLogic_RequestedReplyLength_T RequestedReplyLength;
753: unsigned char GeometryRegister, *TargetPointer, Character;
754: unsigned short AllTargetsMask, DisconnectPermitted;
755: unsigned short TaggedQueuingPermitted, TaggedQueuingPermittedDefault;
756: boolean CommonErrorRecovery;
757: int TargetID, i;
758: /*
759: Issue the Inquire Board ID command.
760: */
761: if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0,
762: &BoardID, sizeof(BoardID)) != sizeof(BoardID))
763: return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
764: /*
765: Issue the Inquire Configuration command.
766: */
767: if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0,
768: &Configuration, sizeof(Configuration))
769: != sizeof(Configuration))
770: return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
771: /*
772: Issue the Inquire Setup Information command.
773: */
774: RequestedReplyLength = sizeof(SetupInformation);
775: if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
776: &RequestedReplyLength, sizeof(RequestedReplyLength),
777: &SetupInformation, sizeof(SetupInformation))
778: != sizeof(SetupInformation))
779: return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
780: /*
781: Issue the Inquire Extended Setup Information command.
782: */
783: RequestedReplyLength = sizeof(ExtendedSetupInformation);
784: if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation,
785: &RequestedReplyLength, sizeof(RequestedReplyLength),
786: &ExtendedSetupInformation,
787: sizeof(ExtendedSetupInformation))
788: != sizeof(ExtendedSetupInformation))
789: return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
790: /*
791: Issue the Inquire Board Model Number command.
792: */
793: if (!(BoardID.FirmwareVersion1stDigit == '2' &&
794: ExtendedSetupInformation.BusType == 'A'))
795: {
796: RequestedReplyLength = sizeof(BoardModelNumber);
797: if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardModelNumber,
798: &RequestedReplyLength, sizeof(RequestedReplyLength),
799: &BoardModelNumber, sizeof(BoardModelNumber))
800: != sizeof(BoardModelNumber))
801: return BusLogic_Failure(HostAdapter, "INQUIRE BOARD MODEL NUMBER");
802: }
803: else strcpy(BoardModelNumber, "542B");
804: /*
805: Issue the Inquire Firmware Version 3rd Digit command.
806: */
807: if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit,
808: NULL, 0, &FirmwareVersion3rdDigit,
809: sizeof(FirmwareVersion3rdDigit))
810: != sizeof(FirmwareVersion3rdDigit))
811: return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
812: /*
813: Issue the Inquire Firmware Version Letter command.
814: */
815: FirmwareVersionLetter = '\0';
816: if (BoardID.FirmwareVersion1stDigit > '3' ||
817: (BoardID.FirmwareVersion1stDigit == '3' &&
818: BoardID.FirmwareVersion2ndDigit >= '3'))
819: if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter,
820: NULL, 0, &FirmwareVersionLetter,
821: sizeof(FirmwareVersionLetter))
822: != sizeof(FirmwareVersionLetter))
823: return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE VERSION LETTER");
824: /*
825: BusLogic Host Adapters can be identified by their model number and
826: the major version number of their firmware as follows:
827:
828: 4.xx BusLogic "C" Series Host Adapters:
829: BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
830: 3.xx BusLogic "S" Series Host Adapters:
831: BT-747S/747D/757S/757D/445S/545S/542D
832: BT-542B/742A (revision H)
833: 2.xx BusLogic "A" Series Host Adapters:
834: BT-542B/742A (revision G and below)
835: 0.xx AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
836: */
837: /*
838: Save the Model Name and Board Name in the Host Adapter structure.
839: */
840: TargetPointer = HostAdapter->ModelName;
841: *TargetPointer++ = 'B';
842: *TargetPointer++ = 'T';
843: *TargetPointer++ = '-';
844: for (i = 0; i < sizeof(BoardModelNumber); i++)
845: {
846: Character = BoardModelNumber[i];
847: if (Character == ' ' || Character == '\0') break;
848: *TargetPointer++ = Character;
849: }
850: *TargetPointer++ = '\0';
851: strcpy(HostAdapter->BoardName, "BusLogic ");
852: strcat(HostAdapter->BoardName, HostAdapter->ModelName);
853: strcpy(HostAdapter->InterruptLabel, HostAdapter->BoardName);
854: /*
855: Save the Firmware Version in the Host Adapter structure.
856: */
857: TargetPointer = HostAdapter->FirmwareVersion;
858: *TargetPointer++ = BoardID.FirmwareVersion1stDigit;
859: *TargetPointer++ = '.';
860: *TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
861: if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0')
862: *TargetPointer++ = FirmwareVersion3rdDigit;
863: if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0')
864: *TargetPointer++ = FirmwareVersionLetter;
865: *TargetPointer++ = '\0';
866: /*
867: Determine the IRQ Channel and save it in the Host Adapter structure.
868: */
869: if (Configuration.IRQ_Channel9)
870: HostAdapter->IRQ_Channel = 9;
871: else if (Configuration.IRQ_Channel10)
872: HostAdapter->IRQ_Channel = 10;
873: else if (Configuration.IRQ_Channel11)
874: HostAdapter->IRQ_Channel = 11;
875: else if (Configuration.IRQ_Channel12)
876: HostAdapter->IRQ_Channel = 12;
877: else if (Configuration.IRQ_Channel14)
878: HostAdapter->IRQ_Channel = 14;
879: else if (Configuration.IRQ_Channel15)
880: HostAdapter->IRQ_Channel = 15;
881: /*
882: Determine the DMA Channel and save it in the Host Adapter structure.
883: */
884: if (Configuration.DMA_Channel5)
885: HostAdapter->DMA_Channel = 5;
886: else if (Configuration.DMA_Channel6)
887: HostAdapter->DMA_Channel = 6;
888: else if (Configuration.DMA_Channel7)
889: HostAdapter->DMA_Channel = 7;
890: /*
891: Save the Host Adapter SCSI ID in the Host Adapter structure.
892: */
893: HostAdapter->SCSI_ID = Configuration.HostAdapterID;
894: /*
895: Save the Synchronous Initiation flag and SCSI Parity Checking flag
896: in the Host Adapter structure.
897: */
898: HostAdapter->SynchronousInitiation =
899: SetupInformation.SynchronousInitiationEnabled;
900: HostAdapter->ParityChecking = SetupInformation.ParityCheckEnabled;
901: /*
902: Determine the Bus Type and save it in the Host Adapter structure,
903: overriding the DMA Channel if it is inappropriate for the bus type.
904: */
905: if (ExtendedSetupInformation.BusType == 'A')
906: HostAdapter->BusType = BusLogic_ISA_Bus;
907: else
908: switch (HostAdapter->ModelName[3])
909: {
910: case '4':
911: HostAdapter->BusType = BusLogic_VESA_Bus;
912: HostAdapter->DMA_Channel = 0;
913: break;
914: case '5':
915: HostAdapter->BusType = BusLogic_ISA_Bus;
916: break;
917: case '6':
918: HostAdapter->BusType = BusLogic_MCA_Bus;
919: HostAdapter->DMA_Channel = 0;
920: break;
921: case '7':
922: HostAdapter->BusType = BusLogic_EISA_Bus;
923: HostAdapter->DMA_Channel = 0;
924: break;
925: case '9':
926: HostAdapter->BusType = BusLogic_PCI_Bus;
927: HostAdapter->DMA_Channel = 0;
928: break;
929: }
930: /*
931: Determine whether Extended Translation is enabled and save it in
932: the Host Adapter structure.
933: */
934: GeometryRegister = BusLogic_ReadGeometryRegister(HostAdapter);
935: if (GeometryRegister & BusLogic_ExtendedTranslationEnabled)
936: HostAdapter->ExtendedTranslation = true;
937: /*
938: Save the Disconnect/Reconnect Permitted flag bits in the Host Adapter
939: structure. The Disconnect Permitted information is only valid on "C"
940: Series boards, but Disconnect/Reconnect is always permitted on "S" and
941: "A" Series boards.
942: */
943: if (HostAdapter->FirmwareVersion[0] >= '4')
944: HostAdapter->DisconnectPermitted =
945: (SetupInformation.DisconnectPermittedID8to15 << 8)
946: | SetupInformation.DisconnectPermittedID0to7;
947: else HostAdapter->DisconnectPermitted = 0xFF;
948: /*
949: Save the Scatter Gather Limits, Level Sensitive Interrupts flag,
950: Wide SCSI flag, and Differential SCSI flag in the Host Adapter structure.
951: */
952: HostAdapter->HostAdapterScatterGatherLimit =
953: ExtendedSetupInformation.ScatterGatherLimit;
954: HostAdapter->DriverScatterGatherLimit =
955: HostAdapter->HostAdapterScatterGatherLimit;
956: if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
957: HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
958: if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupts)
959: HostAdapter->LevelSensitiveInterrupts = true;
960: if (ExtendedSetupInformation.HostWideSCSI)
961: {
962: HostAdapter->HostWideSCSI = true;
963: HostAdapter->MaxTargetIDs = 16;
964: HostAdapter->MaxLogicalUnits = 64;
965: }
966: else
967: {
968: HostAdapter->HostWideSCSI = false;
969: HostAdapter->MaxTargetIDs = 8;
970: HostAdapter->MaxLogicalUnits = 8;
971: }
972: HostAdapter->HostDifferentialSCSI =
973: ExtendedSetupInformation.HostDifferentialSCSI;
974: /*
975: Determine the Host Adapter BIOS Address if the BIOS is enabled and
976: save it in the Host Adapter structure. The BIOS is disabled if the
977: BIOS_Address is 0.
978: */
979: HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
980: /*
981: BusLogic BT-445S Host Adapters prior to board revision D have a hardware
982: bug whereby when the BIOS is enabled, transfers to/from the same address
983: range the BIOS occupies modulo 16MB are handled incorrectly. Only properly
984: functioning BT-445S boards have firmware version 3.37, so we require that
985: ISA bounce buffers be used for the buggy BT-445S models as well as for all
986: ISA models.
987: */
988: if (HostAdapter->BusType == BusLogic_ISA_Bus ||
989: (HostAdapter->BIOS_Address > 0 &&
990: strcmp(HostAdapter->ModelName, "BT-445S") == 0 &&
991: strcmp(HostAdapter->FirmwareVersion, "3.37") < 0))
992: HostAdapter->BounceBuffersRequired = true;
993: /*
994: Select an appropriate value for Concurrency (Commands per Logical Unit)
995: either from a Command Line Entry, or based on whether this Host Adapter
996: requires that ISA bounce buffers be used.
997: */
998: if (HostAdapter->CommandLineEntry != NULL &&
999: HostAdapter->CommandLineEntry->Concurrency > 0)
1000: HostAdapter->Concurrency = HostAdapter->CommandLineEntry->Concurrency;
1001: else if (HostAdapter->BounceBuffersRequired)
1002: HostAdapter->Concurrency = BusLogic_Concurrency_BB;
1003: else HostAdapter->Concurrency = BusLogic_Concurrency;
1004: /*
1005: Select an appropriate value for Bus Settle Time either from a Command
1006: Line Entry, or from BusLogic_DefaultBusSettleTime.
1007: */
1008: if (HostAdapter->CommandLineEntry != NULL &&
1009: HostAdapter->CommandLineEntry->BusSettleTime > 0)
1010: HostAdapter->BusSettleTime = HostAdapter->CommandLineEntry->BusSettleTime;
1011: else HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
1012: /*
1013: Select an appropriate value for Local Options from a Command Line Entry.
1014: */
1015: if (HostAdapter->CommandLineEntry != NULL)
1016: HostAdapter->LocalOptions = HostAdapter->CommandLineEntry->LocalOptions;
1017: /*
1018: Select appropriate values for the Error Recovery Option array either from
1019: a Command Line Entry, or using BusLogic_ErrorRecoveryDefault.
1020: */
1021: if (HostAdapter->CommandLineEntry != NULL)
1022: memcpy(HostAdapter->ErrorRecoveryOption,
1023: HostAdapter->CommandLineEntry->ErrorRecoveryOption,
1024: sizeof(HostAdapter->ErrorRecoveryOption));
1025: else memset(HostAdapter->ErrorRecoveryOption,
1026: BusLogic_ErrorRecoveryDefault,
1027: sizeof(HostAdapter->ErrorRecoveryOption));
1028: /*
1029: Tagged Queuing support is available and operates properly only on "C"
1030: Series boards with firmware version 4.22 and above and on "S" Series
1031: boards with firmware version 3.35 and above. Tagged Queuing is disabled
1032: by default when the Concurrency value is 1 since queuing multiple commands
1033: is not possible.
1034: */
1035: TaggedQueuingPermittedDefault = 0;
1036: if (HostAdapter->Concurrency > 1)
1037: switch (HostAdapter->FirmwareVersion[0])
1038: {
1039: case '5':
1040: TaggedQueuingPermittedDefault = 0xFFFF;
1041: break;
1042: case '4':
1043: if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0)
1044: TaggedQueuingPermittedDefault = 0xFFFF;
1045: break;
1046: case '3':
1047: if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0)
1048: TaggedQueuingPermittedDefault = 0xFFFF;
1049: break;
1050: }
1051: /*
1052: Tagged Queuing is only useful if Disconnect/Reconnect is permitted.
1053: Therefore, mask the Tagged Queuing Permitted Default bits with the
1054: Disconnect/Reconnect Permitted bits.
1055: */
1056: TaggedQueuingPermittedDefault &= HostAdapter->DisconnectPermitted;
1057: /*
1058: Combine the default Tagged Queuing Permitted Default bits with any
1059: Command Line Entry Tagged Queuing specification.
1060: */
1061: if (HostAdapter->CommandLineEntry != NULL)
1062: HostAdapter->TaggedQueuingPermitted =
1063: (HostAdapter->CommandLineEntry->TaggedQueuingPermitted &
1064: HostAdapter->CommandLineEntry->TaggedQueuingPermittedMask) |
1065: (TaggedQueuingPermittedDefault &
1066: ~HostAdapter->CommandLineEntry->TaggedQueuingPermittedMask);
1067: else HostAdapter->TaggedQueuingPermitted = TaggedQueuingPermittedDefault;
1068: /*
1069: Announce the Host Adapter Configuration.
1070: */
1071: printk("scsi%d: Configuring BusLogic Model %s %s%s%s SCSI Host Adapter\n",
1072: HostAdapter->HostNumber, HostAdapter->ModelName,
1073: BusLogic_BusNames[HostAdapter->BusType],
1074: (HostAdapter->HostWideSCSI ? " Wide" : ""),
1075: (HostAdapter->HostDifferentialSCSI ? " Differential" : ""));
1076: printk("scsi%d: Firmware Version: %s, I/O Address: 0x%X, "
1077: "IRQ Channel: %d/%s\n",
1078: HostAdapter->HostNumber, HostAdapter->FirmwareVersion,
1079: HostAdapter->IO_Address, HostAdapter->IRQ_Channel,
1080: (HostAdapter->LevelSensitiveInterrupts ? "Level" : "Edge"));
1081: printk("scsi%d: DMA Channel: ", HostAdapter->HostNumber);
1082: if (HostAdapter->DMA_Channel > 0)
1083: printk("%d, ", HostAdapter->DMA_Channel);
1084: else printk("None, ");
1085: if (HostAdapter->BIOS_Address > 0)
1086: printk("BIOS Address: 0x%lX, ", HostAdapter->BIOS_Address);
1087: else printk("BIOS Address: None, ");
1088: printk("Host Adapter SCSI ID: %d\n", HostAdapter->SCSI_ID);
1089: printk("scsi%d: Scatter/Gather Limit: %d segments, "
1090: "Synchronous Initiation: %s\n", HostAdapter->HostNumber,
1091: HostAdapter->HostAdapterScatterGatherLimit,
1092: (HostAdapter->SynchronousInitiation ? "Enabled" : "Disabled"));
1093: printk("scsi%d: SCSI Parity Checking: %s, "
1094: "Extended Disk Translation: %s\n", HostAdapter->HostNumber,
1095: (HostAdapter->ParityChecking ? "Enabled" : "Disabled"),
1096: (HostAdapter->ExtendedTranslation ? "Enabled" : "Disabled"));
1097: AllTargetsMask = (1 << HostAdapter->MaxTargetIDs) - 1;
1098: DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
1099: printk("scsi%d: Disconnect/Reconnect: ", HostAdapter->HostNumber);
1100: if (DisconnectPermitted == 0)
1101: printk("Disabled");
1102: else if (DisconnectPermitted == AllTargetsMask)
1103: printk("Enabled");
1104: else
1105: for (TargetID = 0; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
1106: printk("%c", (DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
1107: printk(", Tagged Queuing: ");
1108: TaggedQueuingPermitted =
1109: HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
1110: if (TaggedQueuingPermitted == 0)
1111: printk("Disabled");
1112: else if (TaggedQueuingPermitted == AllTargetsMask)
1113: printk("Enabled");
1114: else
1115: for (TargetID = 0; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
1116: printk("%c", (TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
1117: printk("\n");
1118: CommonErrorRecovery = true;
1119: for (TargetID = 1; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
1120: if (HostAdapter->ErrorRecoveryOption[TargetID] !=
1121: HostAdapter->ErrorRecoveryOption[0])
1122: {
1123: CommonErrorRecovery = false;
1124: break;
1125: }
1126: printk("scsi%d: Error Recovery: ", HostAdapter->HostNumber);
1127: if (CommonErrorRecovery)
1128: printk("%s", BusLogic_ErrorRecoveryOptions[
1129: HostAdapter->ErrorRecoveryOption[0]]);
1130: else
1131: for (TargetID = 0; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
1132: printk("%s", BusLogic_ErrorRecoveryOptions2[
1133: HostAdapter->ErrorRecoveryOption[TargetID]]);
1134: printk(", Mailboxes: %d, Initial CCBs: %d\n",
1135: BusLogic_MailboxCount, BusLogic_InitialCCBs);
1136: printk("scsi%d: Driver Scatter/Gather Limit: %d segments, "
1137: "Concurrency: %d\n", HostAdapter->HostNumber,
1138: HostAdapter->DriverScatterGatherLimit, HostAdapter->Concurrency);
1139: /*
1140: Indicate reading the Host Adapter Configuration completed successfully.
1141: */
1142: return true;
1143: }
1144:
1145:
1146: /*
1147: BusLogic_AcquireResources acquires the system resources necessary to use Host
1148: Adapter, and initializes the fields in the SCSI Host structure. The base,
1149: io_port, n_io_ports, irq, and dma_channel fields in the SCSI Host structure
1150: are intentionally left uninitialized, as this driver handles acquisition and
1151: release of these resources explicitly, as well as ensuring exclusive access
1152: to the Host Adapter hardware and data structures through explicit locking.
1153: */
1154:
1155: static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter,
1156: SCSI_Host_T *Host)
1157: {
1158: /*
1159: Acquire exclusive or shared access to the IRQ Channel. A usage count is
1160: maintained so that PCI, EISA, or MCA shared Interrupts can be supported.
1161: */
1162: if (BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9]++ == 0)
1163: {
1164: if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler,
1165: SA_INTERRUPT, HostAdapter->InterruptLabel) < 0)
1166: {
1167: BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9]--;
1168: printk("scsi%d: UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
1169: HostAdapter->HostNumber, HostAdapter->IRQ_Channel);
1170: return false;
1171: }
1172: }
1173: else
1174: {
1175: BusLogic_HostAdapter_T *FirstHostAdapter =
1176: BusLogic_RegisteredHostAdapters;
1177: while (FirstHostAdapter != NULL)
1178: {
1179: if (FirstHostAdapter->IRQ_Channel == HostAdapter->IRQ_Channel)
1180: {
1181: if (strlen(FirstHostAdapter->InterruptLabel) + 11
1182: < sizeof(FirstHostAdapter->InterruptLabel))
1183: {
1184: strcat(FirstHostAdapter->InterruptLabel, " + ");
1185: strcat(FirstHostAdapter->InterruptLabel,
1186: HostAdapter->ModelName);
1187: }
1188: break;
1189: }
1190: FirstHostAdapter = FirstHostAdapter->Next;
1191: }
1192: }
1193: HostAdapter->IRQ_ChannelAcquired = true;
1194: /*
1195: Acquire exclusive access to the DMA Channel.
1196: */
1197: if (HostAdapter->DMA_Channel > 0)
1198: {
1199: if (request_dma(HostAdapter->DMA_Channel, HostAdapter->BoardName) < 0)
1200: {
1201: printk("scsi%d: UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n",
1202: HostAdapter->HostNumber, HostAdapter->DMA_Channel);
1203: return false;
1204: }
1205: set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
1206: enable_dma(HostAdapter->DMA_Channel);
1207: HostAdapter->DMA_ChannelAcquired = true;
1208: }
1209: /*
1210: Initialize necessary fields in the SCSI Host structure.
1211: */
1212: Host->max_id = HostAdapter->MaxTargetIDs;
1213: Host->max_lun = HostAdapter->MaxLogicalUnits;
1214: Host->max_channel = 0;
1215: Host->this_id = HostAdapter->SCSI_ID;
1216: Host->can_queue = BusLogic_MailboxCount;
1217: Host->cmd_per_lun = HostAdapter->Concurrency;
1218: Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
1219: Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
1220: /*
1221: Indicate the System Resource Acquisition completed successfully,
1222: */
1223: return true;
1224: }
1225:
1226:
1227: /*
1228: BusLogic_ReleaseResources releases any system resources previously acquired
1229: by BusLogic_AcquireResources.
1230: */
1231:
1232: static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *HostAdapter)
1233: {
1234: /*
1235: Release exclusive or shared access to the IRQ Channel.
1236: */
1237: if (HostAdapter->IRQ_ChannelAcquired)
1238: if (--BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9] == 0)
1239: free_irq(HostAdapter->IRQ_Channel);
1240: /*
1241: Release exclusive access to the DMA Channel.
1242: */
1243: if (HostAdapter->DMA_ChannelAcquired)
1244: free_dma(HostAdapter->DMA_Channel);
1245: }
1246:
1247:
1248: /*
1249: BusLogic_TestInterrupts tests for proper functioning of the Host Adapter
1250: Interrupt Register and that interrupts generated by the Host Adapter are
1251: getting through to the Interrupt Handler. A large proportion of initial
1252: problems with installing PCI Host Adapters are due to configuration problems
1253: where either the Host Adapter or Motherboard is configured incorrectly, and
1254: interrupts do not get through as a result.
1255: */
1256:
1257: static boolean BusLogic_TestInterrupts(BusLogic_HostAdapter_T *HostAdapter)
1258: {
1259: unsigned int InitialInterruptCount, FinalInterruptCount;
1260: int TestCount = 5, i;
1261: InitialInterruptCount = kstat.interrupts[HostAdapter->IRQ_Channel];
1262: /*
1263: Issue the Test Command Complete Interrupt commands.
1264: */
1265: for (i = 0; i < TestCount; i++)
1266: BusLogic_Command(HostAdapter, BusLogic_TestCommandCompleteInterrupt,
1267: NULL, 0, NULL, 0);
1268: /*
1269: Verify that BusLogic_InterruptHandler was called at least TestCount times.
1270: Shared IRQ Channels could cause more than TestCount interrupts to occur,
1271: but there should never be fewer than TestCount.
1272: */
1273: FinalInterruptCount = kstat.interrupts[HostAdapter->IRQ_Channel];
1274: if (FinalInterruptCount < InitialInterruptCount + TestCount)
1275: {
1276: BusLogic_Failure(HostAdapter, "HOST ADAPTER INTERRUPT TEST");
1277: printk("\n\
1278: Interrupts are not getting through from the Host Adapter to the BusLogic\n\
1279: Driver Interrupt Handler. The most likely cause is that either the Host\n\
1280: Adapter or Motherboard is configured incorrectly. Please check the Host\n\
1281: Adapter configuration with AutoSCSI or by examining any dip switch and\n\
1282: jumper settings on the Host Adapter, and verify that no other device is\n\
1283: attempting to use the same IRQ Channel. For PCI Host Adapters, it may also\n\
1284: be necessary to investigate and manually set the PCI interrupt assignments\n\
1285: and edge/level interrupt type selection in the BIOS Setup Program or with\n\
1286: Motherboard jumpers.\n\n");
1287: return false;
1288: }
1289: /*
1290: Indicate the Host Adapter Interrupt Test completed successfully.
1291: */
1292: return true;
1293: }
1294:
1295:
1296: /*
1297: BusLogic_InitializeHostAdapter initializes Host Adapter. This is the only
1298: function called during SCSI Host Adapter detection which modifies the state
1299: of the Host Adapter from its initial power on or hard reset state.
1300: */
1301:
1302: static boolean BusLogic_InitializeHostAdapter(BusLogic_HostAdapter_T
1303: *HostAdapter)
1304: {
1305: BusLogic_ExtendedMailboxRequest_T ExtendedMailboxRequest;
1306: BusLogic_RoundRobinModeRequest_T RoundRobinModeRequest;
1307: BusLogic_WideModeCCBRequest_T WideModeCCBRequest;
1308: BusLogic_ModifyIOAddressRequest_T ModifyIOAddressRequest;
1309: /*
1310: Initialize the Command Successful Flag, Read/Write Operation Count,
1311: and Queued Operation Count for each Target.
1312: */
1313: memset(HostAdapter->CommandSuccessfulFlag, false,
1314: sizeof(HostAdapter->CommandSuccessfulFlag));
1315: memset(HostAdapter->ReadWriteOperationCount, 0,
1316: sizeof(HostAdapter->ReadWriteOperationCount));
1317: memset(HostAdapter->QueuedOperationCount, 0,
1318: sizeof(HostAdapter->QueuedOperationCount));
1319: /*
1320: Initialize the Outgoing and Incoming Mailbox structures.
1321: */
1322: memset(HostAdapter->OutgoingMailboxes, 0,
1323: sizeof(HostAdapter->OutgoingMailboxes));
1324: memset(HostAdapter->IncomingMailboxes, 0,
1325: sizeof(HostAdapter->IncomingMailboxes));
1326: /*
1327: Initialize the pointers to the First, Last, and Next Mailboxes.
1328: */
1329: HostAdapter->FirstOutgoingMailbox = &HostAdapter->OutgoingMailboxes[0];
1330: HostAdapter->LastOutgoingMailbox =
1331: &HostAdapter->OutgoingMailboxes[BusLogic_MailboxCount-1];
1332: HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
1333: HostAdapter->FirstIncomingMailbox = &HostAdapter->IncomingMailboxes[0];
1334: HostAdapter->LastIncomingMailbox =
1335: &HostAdapter->IncomingMailboxes[BusLogic_MailboxCount-1];
1336: HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
1337: /*
1338: Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes.
1339: */
1340: ExtendedMailboxRequest.MailboxCount = BusLogic_MailboxCount;
1341: ExtendedMailboxRequest.BaseMailboxAddress = HostAdapter->OutgoingMailboxes;
1342: if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox,
1343: &ExtendedMailboxRequest,
1344: sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
1345: return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION");
1346: /*
1347: Enable Strict Round Robin Mode if supported by the Host Adapter. In Strict
1348: Round Robin Mode, the Host Adapter only looks at the next Outgoing Mailbox
1349: for each new command, rather than scanning through all the Outgoing
1350: Mailboxes to find any that have new commands in them. BusLogic indicates
1351: that Strict Round Robin Mode is significantly more efficient.
1352: */
1353: if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0)
1354: {
1355: RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
1356: if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode,
1357: &RoundRobinModeRequest,
1358: sizeof(RoundRobinModeRequest), NULL, 0) < 0)
1359: return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
1360: }
1361: /*
1362: For Wide SCSI Host Adapters, issue the Enable Wide Mode CCB command to
1363: allow more than 8 Logical Units per Target to be supported.
1364: */
1365: if (HostAdapter->HostWideSCSI)
1366: {
1367: WideModeCCBRequest = BusLogic_WideModeCCB;
1368: if (BusLogic_Command(HostAdapter, BusLogic_EnableWideModeCCB,
1369: &WideModeCCBRequest,
1370: sizeof(WideModeCCBRequest), NULL, 0) < 0)
1371: return BusLogic_Failure(HostAdapter, "ENABLE WIDE MODE CCB");
1372: }
1373: /*
1374: For PCI Host Adapters being accessed through the PCI compliant I/O
1375: Address, disable the ISA compatible I/O Address to avoid detecting the
1376: same Host Adapter at both I/O Addresses.
1377: */
1378: if (HostAdapter->BusType == BusLogic_PCI_Bus)
1379: {
1380: int Index;
1381: for (Index = 0; BusLogic_IO_StandardAddresses[Index] > 0; Index++)
1382: if (HostAdapter->IO_Address == BusLogic_IO_StandardAddresses[Index])
1383: break;
1384: if (BusLogic_IO_StandardAddresses[Index] == 0)
1385: {
1386: ModifyIOAddressRequest = BusLogic_ModifyIO_Disable;
1387: if (BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress,
1388: &ModifyIOAddressRequest,
1389: sizeof(ModifyIOAddressRequest), NULL, 0) < 0)
1390: return BusLogic_Failure(HostAdapter, "MODIFY I/O ADDRESS");
1391: }
1392: }
1393: /*
1394: Announce Successful Initialization.
1395: */
1396: printk("scsi%d: *** %s Initialized Successfully ***\n",
1397: HostAdapter->HostNumber, HostAdapter->BoardName);
1398: /*
1399: Indicate the Host Adapter Initialization completed successfully.
1400: */
1401: return true;
1402: }
1403:
1404:
1405: /*
1406: BusLogic_InquireTargetDevices inquires about the Target Devices accessible
1407: through Host Adapter and reports on the results.
1408: */
1409:
1410: static boolean BusLogic_InquireTargetDevices(BusLogic_HostAdapter_T
1411: *HostAdapter)
1412: {
1413: BusLogic_InstalledDevices8_T InstalledDevicesID0to7;
1414: BusLogic_InstalledDevices8_T InstalledDevicesID8to15;
1415: BusLogic_SetupInformation_T SetupInformation;
1416: BusLogic_SynchronousPeriod_T SynchronousPeriod;
1417: BusLogic_RequestedReplyLength_T RequestedReplyLength;
1418: int TargetDevicesFound = 0, TargetID;
1419: /*
1420: Wait a few seconds between the Host Adapter Hard Reset which initiates
1421: a SCSI Bus Reset and issuing any SCSI commands. Some SCSI devices get
1422: confused if they receive SCSI commands too soon after a SCSI Bus Reset.
1423: */
1424: BusLogic_Delay(HostAdapter->BusSettleTime);
1425: /*
1426: Inhibit the Target Devices Inquiry if requested.
1427: */
1428: if (HostAdapter->LocalOptions & BusLogic_InhibitTargetInquiry)
1429: {
1430: printk("scsi%d: Target Device Inquiry Inhibited\n",
1431: HostAdapter->HostNumber);
1432: return true;
1433: }
1434: /*
1435: Issue the Inquire Installed Devices ID 0 to 7 command, and for Wide SCSI
1436: Host Adapters the Inquire Installed Devices ID 8 to 15 command. This is
1437: necessary to force Synchronous Transfer Negotiation so that the Inquire
1438: Setup Information and Inquire Synchronous Period commands will return
1439: valid data.
1440: */
1441: if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7,
1442: NULL, 0, &InstalledDevicesID0to7,
1443: sizeof(InstalledDevicesID0to7))
1444: != sizeof(InstalledDevicesID0to7))
1445: return BusLogic_Failure(HostAdapter, "INQUIRE INSTALLED DEVICES ID 0 TO 7");
1446: if (HostAdapter->HostWideSCSI)
1447: if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID8to15,
1448: NULL, 0, &InstalledDevicesID8to15,
1449: sizeof(InstalledDevicesID8to15))
1450: != sizeof(InstalledDevicesID8to15))
1451: return BusLogic_Failure(HostAdapter,
1452: "INQUIRE INSTALLED DEVICES ID 8 TO 15");
1453: /*
1454: Issue the Inquire Setup Information command.
1455: */
1456: RequestedReplyLength = sizeof(SetupInformation);
1457: if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
1458: &RequestedReplyLength, sizeof(RequestedReplyLength),
1459: &SetupInformation, sizeof(SetupInformation))
1460: != sizeof(SetupInformation))
1461: return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
1462: /*
1463: Issue the Inquire Synchronous Period command.
1464: */
1465: if (HostAdapter->FirmwareVersion[0] >= '3')
1466: {
1467: RequestedReplyLength = sizeof(SynchronousPeriod);
1468: if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod,
1469: &RequestedReplyLength, sizeof(RequestedReplyLength),
1470: &SynchronousPeriod, sizeof(SynchronousPeriod))
1471: != sizeof(SynchronousPeriod))
1472: return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
1473: }
1474: else
1475: for (TargetID = 0; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
1476: if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
1477: SynchronousPeriod[TargetID] =
1478: 20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
1479: .TransferPeriod;
1480: else SynchronousPeriod[TargetID] = 0;
1481: /*
1482: Save the Installed Devices, Synchronous Values, and Synchronous Period
1483: information in the Host Adapter structure.
1484: */
1485: memcpy(HostAdapter->InstalledDevices, InstalledDevicesID0to7,
1486: sizeof(BusLogic_InstalledDevices8_T));
1487: memcpy(HostAdapter->SynchronousValues,
1488: SetupInformation.SynchronousValuesID0to7,
1489: sizeof(BusLogic_SynchronousValues8_T));
1490: if (HostAdapter->HostWideSCSI)
1491: {
1492: memcpy(&HostAdapter->InstalledDevices[8], InstalledDevicesID8to15,
1493: sizeof(BusLogic_InstalledDevices8_T));
1494: memcpy(&HostAdapter->SynchronousValues[8],
1495: SetupInformation.SynchronousValuesID8to15,
1496: sizeof(BusLogic_SynchronousValues8_T));
1497: }
1498: memcpy(HostAdapter->SynchronousPeriod, SynchronousPeriod,
1499: sizeof(BusLogic_SynchronousPeriod_T));
1500: for (TargetID = 0; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
1501: if (HostAdapter->InstalledDevices[TargetID] != 0)
1502: {
1503: int SynchronousPeriod = HostAdapter->SynchronousPeriod[TargetID];
1504: if (SynchronousPeriod > 10)
1505: {
1506: int SynchronousTransferRate = 100000000 / SynchronousPeriod;
1507: int RoundedSynchronousTransferRate =
1508: (SynchronousTransferRate + 5000) / 10000;
1509: printk("scsi%d: Target %d: Synchronous at "
1510: "%d.%02d mega-transfers/second, offset %d\n",
1511: HostAdapter->HostNumber, TargetID,
1512: RoundedSynchronousTransferRate / 100,
1513: RoundedSynchronousTransferRate % 100,
1514: HostAdapter->SynchronousValues[TargetID].Offset);
1515: }
1516: else if (SynchronousPeriod > 0)
1517: {
1518: int SynchronousTransferRate = 100000000 / SynchronousPeriod;
1519: int RoundedSynchronousTransferRate =
1520: (SynchronousTransferRate + 50000) / 100000;
1521: printk("scsi%d: Target %d: Synchronous at "
1522: "%d.%01d mega-transfers/second, offset %d\n",
1523: HostAdapter->HostNumber, TargetID,
1524: RoundedSynchronousTransferRate / 10,
1525: RoundedSynchronousTransferRate % 10,
1526: HostAdapter->SynchronousValues[TargetID].Offset);
1527: }
1528: else printk("scsi%d: Target %d: Asynchronous\n",
1529: HostAdapter->HostNumber, TargetID);
1530: TargetDevicesFound++;
1531: }
1532: if (TargetDevicesFound == 0)
1533: printk("scsi%d: No Target Devices Found\n", HostAdapter->HostNumber);
1534: /*
1535: Indicate the Target Device Inquiry completed successfully.
1536: */
1537: return true;
1538: }
1539:
1540:
1541: /*
1542: BusLogic_DetectHostAdapter probes for BusLogic Host Adapters at the standard
1543: I/O Addresses where they may be located, initializing, registering, and
1544: reporting the configuration of each BusLogic Host Adapter it finds. It
1545: returns the number of BusLogic Host Adapters successfully initialized and
1546: registered.
1547: */
1548:
1549: int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate)
1550: {
1551: int BusLogicHostAdapterCount = 0, CommandLineEntryIndex = 0;
1552: int AddressProbeIndex = 0;
1553: BusLogic_InitializeAddressProbeList();
1554: while (BusLogic_IO_AddressProbeList[AddressProbeIndex] > 0)
1555: {
1556: BusLogic_HostAdapter_T HostAdapterPrototype;
1557: BusLogic_HostAdapter_T *HostAdapter = &HostAdapterPrototype;
1558: SCSI_Host_T *Host;
1559: memset(HostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
1560: HostAdapter->IO_Address =
1561: BusLogic_IO_AddressProbeList[AddressProbeIndex++];
1562: /*
1563: Initialize the Command Line Entry field if an explicit I/O Address
1564: was specified.
1565: */
1566: if (CommandLineEntryIndex < BusLogic_CommandLineEntryCount &&
1567: BusLogic_CommandLineEntries[CommandLineEntryIndex].IO_Address ==
1568: HostAdapter->IO_Address)
1569: HostAdapter->CommandLineEntry =
1570: &BusLogic_CommandLineEntries[CommandLineEntryIndex++];
1571: /*
1572: Check whether the I/O Address range is already in use.
1573: */
1574: if (check_region(HostAdapter->IO_Address, BusLogic_IO_PortCount) < 0)
1575: continue;
1576: /*
1577: Probe the Host Adapter. If unsuccessful, abort further initialization.
1578: */
1579: if (!BusLogic_ProbeHostAdapter(HostAdapter)) continue;
1580: /*
1581: Hard Reset the Host Adapter. If unsuccessful, abort further
1582: initialization.
1583: */
1584: if (!BusLogic_HardResetHostAdapter(HostAdapter)) continue;
1585: /*
1586: Check the Host Adapter. If unsuccessful, abort further initialization.
1587: */
1588: if (!BusLogic_CheckHostAdapter(HostAdapter)) continue;
1589: /*
1590: Initialize the Command Line Entry field if an explicit I/O Address
1591: was not specified.
1592: */
1593: if (CommandLineEntryIndex < BusLogic_CommandLineEntryCount &&
1594: BusLogic_CommandLineEntries[CommandLineEntryIndex].IO_Address == 0)
1595: HostAdapter->CommandLineEntry =
1596: &BusLogic_CommandLineEntries[CommandLineEntryIndex++];
1597: /*
1598: Announce the Driver Version and Date, Author's Name, Copyright Notice,
1599: and Contact Address.
1600: */
1601: BusLogic_AnnounceDriver();
1602: /*
1603: Register usage of the I/O Address range. From this point onward, any
1604: failure will be assumed to be due to a problem with the Host Adapter,
1605: rather than due to having mistakenly identified this port as belonging
1606: to a BusLogic Host Adapter. The I/O Address range will not be
1607: released, thereby preventing it from being incorrectly identified as
1608: any other type of Host Adapter.
1609: */
1610: request_region(HostAdapter->IO_Address, BusLogic_IO_PortCount,
1611: "BusLogic");
1612: /*
1613: Register the SCSI Host structure.
1614: */
1615: HostTemplate->proc_dir = &BusLogic_ProcDirectoryEntry;
1616: Host = scsi_register(HostTemplate, sizeof(BusLogic_HostAdapter_T));
1617: HostAdapter = (BusLogic_HostAdapter_T *) Host->hostdata;
1618: memcpy(HostAdapter, &HostAdapterPrototype,
1619: sizeof(BusLogic_HostAdapter_T));
1620: HostAdapter->SCSI_Host = Host;
1621: HostAdapter->HostNumber = Host->host_no;
1622: /*
1623: Add Host Adapter to the end of the list of registered BusLogic
1624: Host Adapters. In order for Command Complete Interrupts to be
1625: properly dismissed by BusLogic_InterruptHandler, the Host Adapter
1626: must be registered. This must be done before the IRQ Channel is
1627: acquired, and in a shared IRQ Channel environment, must be done
1628: before any Command Complete Interrupts occur, since the IRQ Channel
1629: may have already been acquired by a previous BusLogic Host Adapter.
1630: */
1631: BusLogic_RegisterHostAdapter(HostAdapter);
1632: /*
1633: Read the Host Adapter Configuration, Acquire the System Resources
1634: necessary to use Host Adapter and initialize the fields in the SCSI
1635: Host structure, then Test Interrupts, Create the CCBs, Initialize
1636: the Host Adapter, and finally Inquire about the Target Devices.
1637: */
1638: if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
1639: BusLogic_AcquireResources(HostAdapter, Host) &&
1640: BusLogic_TestInterrupts(HostAdapter) &&
1641: BusLogic_CreateCCBs(HostAdapter) &&
1642: BusLogic_InitializeHostAdapter(HostAdapter) &&
1643: BusLogic_InquireTargetDevices(HostAdapter))
1644: {
1645: /*
1646: Initialization has been completed successfully. Release and
1647: re-register usage of the I/O Address range so that the Model
1648: Name of the Host Adapter will appear.
1649: */
1650: release_region(HostAdapter->IO_Address, BusLogic_IO_PortCount);
1651: request_region(HostAdapter->IO_Address, BusLogic_IO_PortCount,
1652: HostAdapter->BoardName);
1653: BusLogicHostAdapterCount++;
1654: }
1655: else
1656: {
1657: /*
1658: An error occurred during Host Adapter Configuration Querying,
1659: Resource Acquisition, Interrupt Testing, CCB Creation, Host
1660: Adapter Initialization, or Target Device Inquiry, so remove
1661: Host Adapter from the list of registered BusLogic Host Adapters,
1662: destroy the CCBs, Release the System Resources, and Unregister
1663: the SCSI Host.
1664: */
1665: BusLogic_DestroyCCBs(HostAdapter);
1666: BusLogic_ReleaseResources(HostAdapter);
1667: BusLogic_UnregisterHostAdapter(HostAdapter);
1668: scsi_unregister(Host);
1669: }
1670: }
1671: return BusLogicHostAdapterCount;
1672: }
1673:
1674:
1675: /*
1676: BusLogic_ReleaseHostAdapter releases all resources previously acquired to
1677: support a specific Host Adapter, including the I/O Address range, and
1678: unregisters the BusLogic Host Adapter.
1679: */
1680:
1681: int BusLogic_ReleaseHostAdapter(SCSI_Host_T *Host)
1682: {
1683: BusLogic_HostAdapter_T *HostAdapter =
1684: (BusLogic_HostAdapter_T *) Host->hostdata;
1685: /*
1686: Destroy the CCBs and release any system resources acquired to use
1687: Host Adapter.
1688: */
1689: BusLogic_DestroyCCBs(HostAdapter);
1690: BusLogic_ReleaseResources(HostAdapter);
1691: /*
1692: Release usage of the I/O Address range.
1693: */
1694: release_region(HostAdapter->IO_Address, BusLogic_IO_PortCount);
1695: /*
1696: Remove Host Adapter from the list of registered BusLogic Host Adapters.
1697: */
1698: BusLogic_UnregisterHostAdapter(HostAdapter);
1699: return 0;
1700: }
1701:
1702:
1703: /*
1704: BusLogic_ComputeResultCode computes a SCSI Subsystem Result Code from
1705: the Host Adapter Status and Target Device Status.
1706: */
1707:
1708: static int BusLogic_ComputeResultCode(BusLogic_HostAdapterStatus_T
1709: HostAdapterStatus,
1710: BusLogic_TargetDeviceStatus_T
1711: TargetDeviceStatus)
1712: {
1713: int HostStatus;
1714: switch (HostAdapterStatus)
1715: {
1716: case BusLogic_CommandCompletedNormally:
1717: case BusLogic_LinkedCommandCompleted:
1718: case BusLogic_LinkedCommandCompletedWithFlag:
1719: HostStatus = DID_OK;
1720: break;
1721: case BusLogic_SCSISelectionTimeout:
1722: HostStatus = DID_TIME_OUT;
1723: break;
1724: case BusLogic_InvalidOutgoingMailboxActionCode:
1725: case BusLogic_InvalidCommandOperationCode:
1726: case BusLogic_InvalidCommandParameter:
1727: printk("BusLogic: BusLogic Driver Protocol Error 0x%02X\n",
1728: HostAdapterStatus);
1729: case BusLogic_DataOverUnderRun:
1730: case BusLogic_UnexpectedBusFree:
1731: case BusLogic_LinkedCCBhasInvalidLUN:
1732: case BusLogic_AutoRequestSenseFailed:
1733: case BusLogic_TaggedQueuingMessageRejected:
1734: case BusLogic_UnsupportedMessageReceived:
1735: case BusLogic_HostAdapterHardwareFailed:
1736: case BusLogic_TargetDeviceReconnectedImproperly:
1737: case BusLogic_AbortQueueGenerated:
1738: case BusLogic_HostAdapterSoftwareError:
1739: case BusLogic_HostAdapterHardwareTimeoutError:
1740: case BusLogic_SCSIParityErrorDetected:
1741: HostStatus = DID_ERROR;
1742: break;
1743: case BusLogic_InvalidBusPhaseRequested:
1744: case BusLogic_TargetFailedResponseToATN:
1745: case BusLogic_HostAdapterAssertedRST:
1746: case BusLogic_OtherDeviceAssertedRST:
1747: case BusLogic_HostAdapterAssertedBusDeviceReset:
1748: HostStatus = DID_RESET;
1749: break;
1750: default:
1751: printk("BusLogic: unknown Host Adapter Status 0x%02X\n",
1752: HostAdapterStatus);
1753: HostStatus = DID_ERROR;
1754: break;
1755: }
1756: return (HostStatus << 16) | TargetDeviceStatus;
1757: }
1758:
1759:
1760: /*
1761: BusLogic_InterruptHandler handles hardware interrupts from BusLogic Host
1762: Adapters. To simplify handling shared IRQ Channels, all installed BusLogic
1763: Host Adapters are scanned whenever any one of them signals a hardware
1764: interrupt.
1765: */
1766:
1767: static void BusLogic_InterruptHandler(int IRQ_Channel,
1768: Registers_T *InterruptRegisters)
1769: {
1770: BusLogic_CCB_T *FirstCompletedCCB = NULL, *LastCompletedCCB = NULL;
1771: BusLogic_HostAdapter_T *HostAdapter;
1772: int HostAdapterResetPendingCount = 0;
1773: /*
1774: Iterate over the installed BusLogic Host Adapters accepting any Incoming
1775: Mailbox entries and saving the completed CCBs for processing. This
1776: interrupt handler is installed with SA_INTERRUPT, so interrupts are
1777: disabled when the interrupt handler is entered.
1778: */
1779: for (HostAdapter = BusLogic_RegisteredHostAdapters;
1780: HostAdapter != NULL;
1781: HostAdapter = HostAdapter->Next)
1782: {
1783: unsigned char InterruptRegister;
1784: /*
1785: Acquire exclusive access to Host Adapter.
1786: */
1787: BusLogic_LockHostAdapterID(HostAdapter);
1788: /*
1789: Read the Host Adapter Interrupt Register.
1790: */
1791: InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
1792: if (InterruptRegister & BusLogic_InterruptValid)
1793: {
1794: /*
1795: Acknowledge the interrupt and reset the Host Adapter
1796: Interrupt Register.
1797: */
1798: BusLogic_WriteControlRegister(HostAdapter, BusLogic_InterruptReset);
1799: /*
1800: Process valid SCSI Reset State and Incoming Mailbox Loaded
1801: interrupts. Command Complete interrupts are noted, and
1802: Outgoing Mailbox Available interrupts are ignored, as they
1803: are never enabled.
1804: */
1805: if (InterruptRegister & BusLogic_SCSIResetState)
1806: {
1807: HostAdapter->HostAdapterResetPending = true;
1808: HostAdapterResetPendingCount++;
1809: }
1810: else if (InterruptRegister & BusLogic_IncomingMailboxLoaded)
1811: {
1812: /*
1813: Scan through the Incoming Mailboxes in Strict Round Robin
1814: fashion, saving any completed CCBs for further processing.
1815: It is essential that for each CCB and SCSI Command issued,
1816: command completion processing is performed exactly once.
1817: Therefore, only Incoming Mailboxes with completion code
1818: Command Completed Without Error, Command Completed With
1819: Error, or Command Aborted At Host Request are saved for
1820: completion processing. When an Incoming Mailbox has a
1821: completion code of Aborted Command Not Found, the CCB had
1822: already completed or been aborted before the current Abort
1823: request was processed, and so completion processing has
1824: already occurred and no further action should be taken.
1825: */
1826: BusLogic_IncomingMailbox_T *NextIncomingMailbox =
1827: HostAdapter->NextIncomingMailbox;
1828: BusLogic_CompletionCode_T MailboxCompletionCode;
1829: while ((MailboxCompletionCode =
1830: NextIncomingMailbox->CompletionCode) !=
1831: BusLogic_IncomingMailboxFree)
1832: {
1833: BusLogic_CCB_T *CCB = NextIncomingMailbox->CCB;
1834: if (MailboxCompletionCode != BusLogic_AbortedCommandNotFound)
1835: if (CCB->Status == BusLogic_CCB_Active)
1836: {
1837: /*
1838: Mark this CCB as completed and add it to the end
1839: of the list of completed CCBs.
1840: */
1841: CCB->Status = BusLogic_CCB_Completed;
1842: CCB->MailboxCompletionCode = MailboxCompletionCode;
1843: CCB->Next = NULL;
1844: if (FirstCompletedCCB == NULL)
1845: {
1846: FirstCompletedCCB = CCB;
1847: LastCompletedCCB = CCB;
1848: }
1849: else
1850: {
1851: LastCompletedCCB->Next = CCB;
1852: LastCompletedCCB = CCB;
1853: }
1854: HostAdapter->QueuedOperationCount[CCB->TargetID]--;
1855: }
1856: else
1857: {
1858: /*
1859: If a CCB ever appears in an Incoming Mailbox and
1860: is not marked as status Active, then there is
1861: most likely a bug in the Host Adapter firmware.
1862: */
1863: printk("scsi%d: Illegal CCB #%d status %d in "
1864: "Incoming Mailbox\n", HostAdapter->HostNumber,
1865: CCB->SerialNumber, CCB->Status);
1866: }
1867: else printk("scsi%d: Aborted CCB #%d to Target %d "
1868: "Not Found\n", HostAdapter->HostNumber,
1869: CCB->SerialNumber, CCB->TargetID);
1870: NextIncomingMailbox->CompletionCode =
1871: BusLogic_IncomingMailboxFree;
1872: if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
1873: NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
1874: }
1875: HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
1876: }
1877: else if (InterruptRegister & BusLogic_CommandComplete)
1878: HostAdapter->HostAdapterCommandCompleted = true;
1879: }
1880: /*
1881: Release exclusive access to Host Adapter.
1882: */
1883: BusLogic_UnlockHostAdapterID(HostAdapter);
1884: }
1885: /*
1886: Enable interrupts while the completed CCBs are processed.
1887: */
1888: sti();
1889: /*
1890: Iterate over the Host Adapters performing any pending Host Adapter Resets.
1891: */
1892: if (HostAdapterResetPendingCount > 0)
1893: for (HostAdapter = BusLogic_RegisteredHostAdapters;
1894: HostAdapter != NULL;
1895: HostAdapter = HostAdapter->Next)
1896: if (HostAdapter->HostAdapterResetPending)
1897: {
1898: BusLogic_ResetHostAdapter(HostAdapter, NULL);
1899: HostAdapter->HostAdapterResetPending = false;
1900: scsi_mark_host_bus_reset(HostAdapter->SCSI_Host);
1901: }
1902: /*
1903: Iterate over the completed CCBs setting the SCSI Command Result Codes,
1904: deallocating the CCBs, and calling the Completion Routines.
1905: */
1906: while (FirstCompletedCCB != NULL)
1907: {
1908: BusLogic_CCB_T *CCB = FirstCompletedCCB;
1909: SCSI_Command_T *Command = CCB->Command;
1910: FirstCompletedCCB = FirstCompletedCCB->Next;
1911: HostAdapter = CCB->HostAdapter;
1912: /*
1913: Bus Device Reset CCBs have the Command field non-NULL only when a Bus
1914: Device Reset was requested for a command that was not currently active
1915: in the Host Adapter, and hence would not have its Completion Routine
1916: called otherwise.
1917: */
1918: if (CCB->Opcode == BusLogic_SCSIBusDeviceReset)
1919: {
1920: printk("scsi%d: Bus Device Reset CCB #%d to Target %d Completed\n",
1921: HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
1922: if (Command != NULL) Command->result = DID_RESET << 16;
1923: }
1924: else
1925: /*
1926: Translate the Mailbox Completion Code, Host Adapter Status, and
1927: Target Device Status into a SCSI Subsystem Result Code.
1928: */
1929: switch (CCB->MailboxCompletionCode)
1930: {
1931: case BusLogic_IncomingMailboxFree:
1932: case BusLogic_AbortedCommandNotFound:
1933: printk("scsi%d: CCB #%d to Target %d Impossible State\n",
1934: HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
1935: break;
1936: case BusLogic_CommandCompletedWithoutError:
1937: HostAdapter->CommandSuccessfulFlag[CCB->TargetID] = true;
1938: Command->result = DID_OK << 16;
1939: break;
1940: case BusLogic_CommandAbortedAtHostRequest:
1941: printk("scsi%d: CCB #%d to Target %d Aborted\n",
1942: HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
1943: Command->result = DID_ABORT << 16;
1944: break;
1945: case BusLogic_CommandCompletedWithError:
1946: Command->result =
1947: BusLogic_ComputeResultCode(CCB->HostAdapterStatus,
1948: CCB->TargetDeviceStatus);
1949: if (BusLogic_GlobalOptions & BusLogic_TraceErrors)
1950: if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout)
1951: {
1952: int i;
1953: printk("scsi%d: CCB #%d Target %d: Result %X "
1954: "Host Adapter Status %02X Target Status %02X\n",
1955: HostAdapter->HostNumber, CCB->SerialNumber,
1956: CCB->TargetID, Command->result,
1957: CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
1958: printk("scsi%d: CDB ", HostAdapter->HostNumber);
1959: for (i = 0; i < CCB->CDB_Length; i++)
1960: printk(" %02X", CCB->CDB[i]);
1961: printk("\n");
1962: printk("scsi%d: Sense ", HostAdapter->HostNumber);
1963: for (i = 0; i < CCB->SenseDataLength; i++)
1964: printk(" %02X", (*CCB->SenseDataPointer)[i]);
1965: printk("\n");
1966: }
1967: break;
1968: }
1969: /*
1970: Place CCB back on the Host Adapter's free list.
1971: */
1972: BusLogic_DeallocateCCB(CCB);
1973: /*
1974: Call the SCSI Command Completion Routine if appropriate.
1975: */
1976: if (Command != NULL) Command->scsi_done(Command);
1977: }
1978: }
1979:
1980:
1981: /*
1982: BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
1983: Mailbox for execution by Host Adapter.
1984: */
1985:
1986: static boolean BusLogic_WriteOutgoingMailbox(BusLogic_HostAdapter_T
1987: *HostAdapter,
1988: BusLogic_ActionCode_T ActionCode,
1989: BusLogic_CCB_T *CCB)
1990: {
1991: BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
1992: boolean Result = false;
1993: BusLogic_LockHostAdapter(HostAdapter);
1994: NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
1995: if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree)
1996: {
1997: CCB->Status = BusLogic_CCB_Active;
1998: /*
1999: The CCB field must be written before the Action Code field since
2000: the Host Adapter is operating asynchronously and the locking code
2001: does not protect against simultaneous access by the Host Adapter.
2002: */
2003: NextOutgoingMailbox->CCB = CCB;
2004: NextOutgoingMailbox->ActionCode = ActionCode;
2005: BusLogic_StartMailboxScan(HostAdapter);
2006: if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
2007: NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
2008: HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
2009: if (ActionCode == BusLogic_MailboxStartCommand)
2010: HostAdapter->QueuedOperationCount[CCB->TargetID]++;
2011: Result = true;
2012: }
2013: BusLogic_UnlockHostAdapter(HostAdapter);
2014: return Result;
2015: }
2016:
2017:
2018: /*
2019: BusLogic_QueueCommand creates a CCB for Command and places it into an
2020: Outgoing Mailbox for execution by the associated Host Adapter.
2021: */
2022:
2023: int BusLogic_QueueCommand(SCSI_Command_T *Command,
2024: void (*CompletionRoutine)(SCSI_Command_T *))
2025: {
2026: BusLogic_HostAdapter_T *HostAdapter =
2027: (BusLogic_HostAdapter_T *) Command->host->hostdata;
2028: unsigned char *CDB = Command->cmnd;
2029: unsigned char CDB_Length = Command->cmd_len;
2030: unsigned char TargetID = Command->target;
2031: unsigned char LogicalUnit = Command->lun;
2032: void *BufferPointer = Command->request_buffer;
2033: int BufferLength = Command->request_bufflen;
2034: int SegmentCount = Command->use_sg;
2035: BusLogic_CCB_T *CCB;
2036: long EnableTQ;
2037: /*
2038: SCSI REQUEST_SENSE commands will be executed automatically by the Host
2039: Adapter for any errors, so they should not be executed explicitly unless
2040: the Sense Data is zero indicating that no error occurred.
2041: */
2042: if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0)
2043: {
2044: Command->result = DID_OK << 16;
2045: CompletionRoutine(Command);
2046: return 0;
2047: }
2048: /*
2049: Allocate a CCB from the Host Adapter's free list. If there are none
2050: available and memory allocation fails, return a result code of Bus Busy
2051: so that this Command will be retried.
2052: */
2053: CCB = BusLogic_AllocateCCB(HostAdapter);
2054: if (CCB == NULL)
2055: {
2056: Command->result = DID_BUS_BUSY << 16;
2057: CompletionRoutine(Command);
2058: return 0;
2059: }
2060: /*
2061: Initialize the fields in the BusLogic Command Control Block (CCB).
2062: */
2063: if (SegmentCount == 0)
2064: {
2065: CCB->Opcode = BusLogic_InitiatorCCB;
2066: CCB->DataLength = BufferLength;
2067: CCB->DataPointer = BufferPointer;
2068: }
2069: else
2070: {
2071: SCSI_ScatterList_T *ScatterList = (SCSI_ScatterList_T *) BufferPointer;
2072: int Segment;
2073: CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
2074: CCB->DataLength = SegmentCount * sizeof(BusLogic_ScatterGatherSegment_T);
2075: CCB->DataPointer = CCB->ScatterGatherList;
2076: for (Segment = 0; Segment < SegmentCount; Segment++)
2077: {
2078: CCB->ScatterGatherList[Segment].SegmentByteCount =
2079: ScatterList[Segment].length;
2080: CCB->ScatterGatherList[Segment].SegmentDataPointer =
2081: ScatterList[Segment].address;
2082: }
2083: }
2084: switch (CDB[0])
2085: {
2086: case READ_6:
2087: case READ_10:
2088: CCB->DataDirection = BusLogic_DataInLengthChecked;
2089: HostAdapter->ReadWriteOperationCount[TargetID]++;
2090: break;
2091: case WRITE_6:
2092: case WRITE_10:
2093: CCB->DataDirection = BusLogic_DataOutLengthChecked;
2094: HostAdapter->ReadWriteOperationCount[TargetID]++;
2095: break;
2096: default:
2097: CCB->DataDirection = BusLogic_UncheckedDataTransfer;
2098: break;
2099: }
2100: CCB->CDB_Length = CDB_Length;
2101: CCB->SenseDataLength = sizeof(Command->sense_buffer);
2102: CCB->HostAdapterStatus = 0;
2103: CCB->TargetDeviceStatus = 0;
2104: CCB->TargetID = TargetID;
2105: CCB->LogicalUnit = LogicalUnit;
2106: /*
2107: For Wide SCSI Host Adapters, Wide Mode CCBs are used to support more than
2108: 8 Logical Units per Target, and this requires setting the overloaded
2109: TagEnable field to Logical Unit bit 5.
2110: */
2111: if (HostAdapter->HostWideSCSI)
2112: {
2113: CCB->TagEnable = LogicalUnit >> 5;
2114: CCB->WideModeTagEnable = false;
2115: }
2116: else CCB->TagEnable = false;
2117: /*
2118: BusLogic recommends that after a Reset the first couple of commands that
2119: are sent to a Target be sent in a non Tagged Queue fashion so that the Host
2120: Adapter and Target can establish Synchronous Transfer before Queue Tag
2121: messages can interfere with the Synchronous Negotiation message. By
2122: waiting to enable tagged Queuing until after the first 16 read/write
2123: commands have been sent, it is assured that the Tagged Queuing message
2124: will not occur while the partition table is printed.
2125: */
2126: if ((HostAdapter->TaggedQueuingPermitted & (1 << TargetID)) &&
2127: Command->device->tagged_supported &&
2128: (EnableTQ = HostAdapter->ReadWriteOperationCount[TargetID] - 16) >= 0)
2129: {
2130: BusLogic_QueueTag_T QueueTag = BusLogic_SimpleQueueTag;
2131: unsigned long CurrentTime = jiffies;
2132: if (EnableTQ == 0)
2133: printk("scsi%d: Tagged Queuing now active for Target %d\n",
2134: HostAdapter->HostNumber, TargetID);
2135: /*
2136: When using Tagged Queuing with Simple Queue Tags, it appears that disk
2137: drive controllers do not guarantee that a queued command will not
2138: remain in a disconnected state indefinitely if commands that read or
2139: write nearer the head position continue to arrive without interruption.
2140: Therefore, for each Target Device this driver keeps track of the last
2141: time either the queue was empty or an Ordered Queue Tag was issued. If
2142: more than 2 seconds have elapsed since this last sequence point, this
2143: command will be issued with an Ordered Queue Tag rather than a Simple
2144: Queue Tag, which forces the Target Device to complete all previously
2145: queued commands before this command may be executed.
2146: */
2147: if (HostAdapter->QueuedOperationCount[TargetID] == 0)
2148: HostAdapter->LastSequencePoint[TargetID] = CurrentTime;
2149: else if (CurrentTime - HostAdapter->LastSequencePoint[TargetID] > 2*HZ)
2150: {
2151: HostAdapter->LastSequencePoint[TargetID] = CurrentTime;
2152: QueueTag = BusLogic_OrderedQueueTag;
2153: }
2154: if (HostAdapter->HostWideSCSI)
2155: {
2156: CCB->WideModeTagEnable = true;
2157: CCB->WideModeQueueTag = QueueTag;
2158: }
2159: else
2160: {
2161: CCB->TagEnable = true;
2162: CCB->QueueTag = QueueTag;
2163: }
2164: }
2165: memcpy(CCB->CDB, CDB, CDB_Length);
2166: CCB->SenseDataPointer = (SCSI_SenseData_T *) &Command->sense_buffer;
2167: CCB->Command = Command;
2168: Command->scsi_done = CompletionRoutine;
2169: /*
2170: Place the CCB in an Outgoing Mailbox. If there are no Outgoing
2171: Mailboxes available, return a result code of Bus Busy so that this
2172: Command will be retried.
2173: */
2174: if (!(BusLogic_WriteOutgoingMailbox(HostAdapter,
2175: BusLogic_MailboxStartCommand, CCB)))
2176: {
2177: printk("scsi%d: cannot write Outgoing Mailbox\n",
2178: HostAdapter->HostNumber);
2179: BusLogic_DeallocateCCB(CCB);
2180: Command->result = DID_BUS_BUSY << 16;
2181: CompletionRoutine(Command);
2182: }
2183: return 0;
2184: }
2185:
2186:
2187: /*
2188: BusLogic_AbortCommand aborts Command if possible.
2189: */
2190:
2191: int BusLogic_AbortCommand(SCSI_Command_T *Command)
2192: {
2193: BusLogic_HostAdapter_T *HostAdapter =
2194: (BusLogic_HostAdapter_T *) Command->host->hostdata;
2195: unsigned long CommandPID = Command->pid;
2196: unsigned char InterruptRegister;
2197: BusLogic_CCB_T *CCB;
2198: int Result;
2199: /*
2200: If the Host Adapter has posted an interrupt but the Interrupt Handler
2201: has not been called for some reason (i.e. the interrupt was lost), try
2202: calling the Interrupt Handler directly to process the commands that
2203: have been completed.
2204: */
2205: InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
2206: if (InterruptRegister & BusLogic_InterruptValid)
2207: {
2208: unsigned long ProcessorFlags;
2209: printk("scsi%d: Recovering Lost/Delayed Interrupt for IRQ Channel %d\n",
2210: HostAdapter->HostNumber, HostAdapter->IRQ_Channel);
2211: save_flags(ProcessorFlags);
2212: cli();
2213: BusLogic_InterruptHandler(HostAdapter->IRQ_Channel, NULL);
2214: restore_flags(ProcessorFlags);
2215: return SCSI_ABORT_SNOOZE;
2216: }
2217: /*
2218: Find the CCB to be aborted if possible.
2219: */
2220: BusLogic_LockHostAdapter(HostAdapter);
2221: for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2222: if (CCB->Command == Command) break;
2223: BusLogic_UnlockHostAdapter(HostAdapter);
2224: if (CCB == NULL)
2225: {
2226: printk("scsi%d: Unable to Abort Command to Target %d - No CCB Found\n",
2227: HostAdapter->HostNumber, Command->target);
2228: return SCSI_ABORT_NOT_RUNNING;
2229: }
2230: /*
2231: Briefly pause to see if this command will complete.
2232: */
2233: printk("scsi%d: Pausing briefly to see if CCB #%d "
2234: "to Target %d will complete\n",
2235: HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
2236: BusLogic_Delay(2);
2237: /*
2238: If this CCB is still Active and still refers to the same Command, then
2239: actually aborting this Command is necessary.
2240: */
2241: BusLogic_LockHostAdapter(HostAdapter);
2242: Result = SCSI_ABORT_NOT_RUNNING;
2243: if (CCB->Status == BusLogic_CCB_Active &&
2244: CCB->Command == Command && Command->pid == CommandPID)
2245: {
2246: /*
2247: Attempt to abort this CCB.
2248: */
2249: if (BusLogic_WriteOutgoingMailbox(HostAdapter,
2250: BusLogic_MailboxAbortCommand, CCB))
2251: {
2252: printk("scsi%d: Aborting CCB #%d to Target %d\n",
2253: HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
2254: Result = SCSI_ABORT_PENDING;
2255: }
2256: else
2257: {
2258: printk("scsi%d: Unable to Abort CCB #%d to Target %d - "
2259: "No Outgoing Mailboxes\n", HostAdapter->HostNumber,
2260: CCB->SerialNumber, CCB->TargetID);
2261: Result = SCSI_ABORT_BUSY;
2262: }
2263: }
2264: else printk("scsi%d: CCB #%d to Target %d completed\n",
2265: HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
2266: BusLogic_UnlockHostAdapter(HostAdapter);
2267: return Result;
2268: }
2269:
2270:
2271: /*
2272: BusLogic_ResetHostAdapter resets Host Adapter if possible, marking all
2273: currently executing SCSI commands as having been reset, as well as
2274: the specified Command if non-NULL.
2275: */
2276:
2277: static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter,
2278: SCSI_Command_T *Command)
2279: {
2280: BusLogic_CCB_T *CCB;
2281: if (Command == NULL)
2282: printk("scsi%d: Resetting %s due to SCSI Reset State Interrupt\n",
2283: HostAdapter->HostNumber, HostAdapter->BoardName);
2284: else printk("scsi%d: Resetting %s due to Target %d\n",
2285: HostAdapter->HostNumber, HostAdapter->BoardName, Command->target);
2286: /*
2287: Attempt to Reset and Reinitialize the Host Adapter.
2288: */
2289: BusLogic_LockHostAdapter(HostAdapter);
2290: if (!(BusLogic_HardResetHostAdapter(HostAdapter) &&
2291: BusLogic_InitializeHostAdapter(HostAdapter)))
2292: {
2293: printk("scsi%d: Resetting %s Failed\n",
2294: HostAdapter->HostNumber, HostAdapter->BoardName);
2295: BusLogic_UnlockHostAdapter(HostAdapter);
2296: return SCSI_RESET_ERROR;
2297: }
2298: BusLogic_UnlockHostAdapter(HostAdapter);
2299: /*
2300: Wait a few seconds between the Host Adapter Hard Reset which initiates
2301: a SCSI Bus Reset and issuing any SCSI commands. Some SCSI devices get
2302: confused if they receive SCSI commands too soon after a SCSI Bus Reset.
2303: */
2304: BusLogic_Delay(HostAdapter->BusSettleTime);
2305: /*
2306: Mark all currently executing CCBs as having been reset.
2307: */
2308: BusLogic_LockHostAdapter(HostAdapter);
2309: for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2310: if (CCB->Status == BusLogic_CCB_Active)
2311: {
2312: CCB->Status = BusLogic_CCB_Reset;
2313: if (CCB->Command == Command)
2314: {
2315: CCB->Command = NULL;
2316: /*
2317: Disable Tagged Queuing if it was active for this Target Device.
2318: */
2319: if (((HostAdapter->HostWideSCSI && CCB->WideModeTagEnable) ||
2320: (!HostAdapter->HostWideSCSI && CCB->TagEnable)) &&
2321: (HostAdapter->TaggedQueuingPermitted & (1 << CCB->TargetID)))
2322: {
2323: HostAdapter->TaggedQueuingPermitted &= ~(1 << CCB->TargetID);
2324: printk("scsi%d: Tagged Queuing now disabled for Target %d\n",
2325: HostAdapter->HostNumber, CCB->TargetID);
2326: }
2327: }
2328: }
2329: BusLogic_UnlockHostAdapter(HostAdapter);
2330: /*
2331: Perform completion processing for the Command being Reset.
2332: */
2333: if (Command != NULL)
2334: {
2335: Command->result = DID_RESET << 16;
2336: Command->scsi_done(Command);
2337: }
2338: /*
2339: Perform completion processing for any other active CCBs.
2340: */
2341: for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2342: if (CCB->Status == BusLogic_CCB_Reset)
2343: {
2344: Command = CCB->Command;
2345: BusLogic_DeallocateCCB(CCB);
2346: if (Command != NULL)
2347: {
2348: Command->result = DID_RESET << 16;
2349: Command->scsi_done(Command);
2350: }
2351: }
2352: return SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
2353: }
2354:
2355:
2356: /*
2357: BusLogic_BusDeviceReset sends a Bus Device Reset to the Target
2358: associated with Command.
2359: */
2360:
2361: static int BusLogic_BusDeviceReset(BusLogic_HostAdapter_T *HostAdapter,
2362: SCSI_Command_T *Command)
2363: {
2364: BusLogic_CCB_T *CCB = BusLogic_AllocateCCB(HostAdapter), *XCCB;
2365: unsigned char TargetID = Command->target;
2366: /*
2367: If sending a Bus Device Reset is impossible, attempt a full Host
2368: Adapter Hard Reset and SCSI Bus Reset.
2369: */
2370: if (CCB == NULL)
2371: return BusLogic_ResetHostAdapter(HostAdapter, Command);
2372: printk("scsi%d: Sending Bus Device Reset CCB #%d to Target %d\n",
2373: HostAdapter->HostNumber, CCB->SerialNumber, TargetID);
2374: CCB->Opcode = BusLogic_SCSIBusDeviceReset;
2375: CCB->TargetID = TargetID;
2376: CCB->Command = Command;
2377: /*
2378: If there is a currently executing CCB in the Host Adapter for this Command,
2379: then an Incoming Mailbox entry will be made with a completion code of
2380: BusLogic_HostAdapterAssertedBusDeviceReset. Otherwise, the CCB's Command
2381: field will be left pointing to the Command so that the interrupt for the
2382: completion of the Bus Device Reset can call the Completion Routine for the
2383: Command.
2384: */
2385: BusLogic_LockHostAdapter(HostAdapter);
2386: for (XCCB = HostAdapter->All_CCBs; XCCB != NULL; XCCB = XCCB->NextAll)
2387: if (XCCB->Command == Command && XCCB->Status == BusLogic_CCB_Active)
2388: {
2389: CCB->Command = NULL;
2390: /*
2391: Disable Tagged Queuing if it was active for this Target Device.
2392: */
2393: if (((HostAdapter->HostWideSCSI && XCCB->WideModeTagEnable) ||
2394: (!HostAdapter->HostWideSCSI && XCCB->TagEnable)) &&
2395: (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
2396: {
2397: HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
2398: printk("scsi%d: Tagged Queuing now disabled for Target %d\n",
2399: HostAdapter->HostNumber, TargetID);
2400: }
2401: break;
2402: }
2403: BusLogic_UnlockHostAdapter(HostAdapter);
2404: /*
2405: Attempt to write an Outgoing Mailbox with the Bus Device Reset CCB.
2406: If sending a Bus Device Reset is impossible, attempt a full Host
2407: Adapter Hard Reset and SCSI Bus Reset.
2408: */
2409: if (!(BusLogic_WriteOutgoingMailbox(HostAdapter,
2410: BusLogic_MailboxStartCommand, CCB)))
2411: {
2412: printk("scsi%d: cannot write Outgoing Mailbox for Bus Device Reset\n",
2413: HostAdapter->HostNumber);
2414: BusLogic_DeallocateCCB(CCB);
2415: return BusLogic_ResetHostAdapter(HostAdapter, Command);
2416: }
2417: HostAdapter->ReadWriteOperationCount[TargetID] = 0;
2418: HostAdapter->QueuedOperationCount[TargetID] = 0;
2419: return SCSI_RESET_PENDING;
2420: }
2421:
2422:
2423: /*
2424: BusLogic_ResetCommand takes appropriate action to reset Command.
2425: */
2426:
2427: int BusLogic_ResetCommand(SCSI_Command_T *Command)
2428: {
2429: BusLogic_HostAdapter_T *HostAdapter =
2430: (BusLogic_HostAdapter_T *) Command->host->hostdata;
2431: unsigned char TargetID = Command->target;
2432: unsigned char ErrorRecoveryOption =
2433: HostAdapter->ErrorRecoveryOption[TargetID];
2434: if (ErrorRecoveryOption == BusLogic_ErrorRecoveryDefault)
2435: if (Command->host->suggest_bus_reset)
2436: ErrorRecoveryOption = BusLogic_ErrorRecoveryHardReset;
2437: else ErrorRecoveryOption = BusLogic_ErrorRecoveryBusDeviceReset;
2438: switch (ErrorRecoveryOption)
2439: {
2440: case BusLogic_ErrorRecoveryHardReset:
2441: return BusLogic_ResetHostAdapter(HostAdapter, Command);
2442: case BusLogic_ErrorRecoveryBusDeviceReset:
2443: if (HostAdapter->CommandSuccessfulFlag[TargetID])
2444: {
2445: HostAdapter->CommandSuccessfulFlag[TargetID] = false;
2446: return BusLogic_BusDeviceReset(HostAdapter, Command);
2447: }
2448: else return BusLogic_ResetHostAdapter(HostAdapter, Command);
2449: }
2450: printk("scsi%d: Error Recovery for Target %d Suppressed\n",
2451: HostAdapter->HostNumber, TargetID);
2452: return SCSI_RESET_PUNT;
2453: }
2454:
2455:
2456: /*
2457: BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk
2458: Parameters for Disk. The default disk geometry is 64 heads, 32 sectors, and
2459: the appropriate number of cylinders so as not to exceed drive capacity. In
2460: order for disks equal to or larger than 1 GB to be addressable by the BIOS
2461: without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
2462: may be enabled in AutoSCSI on "C" Series boards or by a dip switch setting
2463: on older boards. With Extended Translation enabled, drives between 1 GB
2464: inclusive and 2 GB exclusive are given a disk geometry of 128 heads and 32
2465: sectors, and drives between 2 GB inclusive and 8 GB exclusive are given a
2466: disk geometry of 255 heads and 63 sectors. On "C" Series boards the firmware
2467: can be queried for the precise translation in effect for each drive
2468: individually, but there is really no need to do so since we know the total
2469: capacity of the drive and whether Extended Translation is enabled, hence we
2470: can deduce the BIOS disk geometry that must be in effect.
2471: */
2472:
2473: int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device,
2474: int *Parameters)
2475: {
2476: BusLogic_HostAdapter_T *HostAdapter =
2477: (BusLogic_HostAdapter_T *) Disk->device->host->hostdata;
2478: BIOS_DiskParameters_T *DiskParameters = (BIOS_DiskParameters_T *) Parameters;
2479: if (HostAdapter->ExtendedTranslation &&
2480: Disk->capacity >= 2*1024*1024 /* 1 GB in 512 byte sectors */)
2481: if (Disk->capacity >= 4*1024*1024 /* 2 GB in 512 byte sectors */)
2482: {
2483: DiskParameters->Heads = 255;
2484: DiskParameters->Sectors = 63;
2485: }
2486: else
2487: {
2488: DiskParameters->Heads = 128;
2489: DiskParameters->Sectors = 32;
2490: }
2491: else
2492: {
2493: DiskParameters->Heads = 64;
2494: DiskParameters->Sectors = 32;
2495: }
2496: DiskParameters->Cylinders =
2497: Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
2498: return 0;
2499: }
2500:
2501:
2502: /*
2503: BusLogic_Setup handles processing of Kernel Command Line Arguments.
2504:
2505: For the BusLogic driver, a kernel command line entry comprises the driver
2506: identifier "BusLogic=" optionally followed by a comma-separated sequence of
2507: integers and then optionally followed by a comma-separated sequence of
2508: strings. Each command line entry applies to one BusLogic Host Adapter.
2509: Multiple command line entries may be used in systems which contain multiple
2510: BusLogic Host Adapters.
2511:
2512: The first integer specified is the I/O Address at which the Host Adapter is
2513: located. If unspecified, it defaults to 0 which means to apply this entry to
2514: the first BusLogic Host Adapter found during the default probe sequence. If
2515: any I/O Address parameters are provided on the command line, then the default
2516: probe sequence is omitted.
2517:
2518: The second integer specified is the number of Concurrent Commands per Logical
2519: Unit to allow for Target Devices on the Host Adapter. If unspecified, it
2520: defaults to 0 which means to use the value of BusLogic_Concurrency for
2521: non-ISA Host Adapters, or BusLogic_Concurrency_ISA for ISA Host Adapters.
2522:
2523: The third integer specified is the Bus Settle Time in seconds. This is
2524: the amount of time to wait between a Host Adapter Hard Reset which initiates
2525: a SCSI Bus Reset and issuing any SCSI commands. If unspecified, it defaults
2526: to 0 which means to use the value of BusLogic_DefaultBusSettleTime.
2527:
2528: The fourth integer specified is the Local Options. If unspecified, it
2529: defaults to 0. Note that Local Options are only applied to a specific Host
2530: Adapter.
2531:
2532: The fifth integer specified is the Global Options. If unspecified, it
2533: defaults to 0. Note that Global Options are applied across all Host
2534: Adapters.
2535:
2536: The string options are used to provide control over Tagged Queuing and Error
2537: Recovery. If both Tagged Queuing and Error Recovery strings are provided, the
2538: Tagged Queuing specification string must come first.
2539:
2540: The Tagged Queuing specification begins with "TQ:" and allows for explicitly
2541: specifying whether Tagged Queuing is permitted on Target Devices that support
2542: it. The following specification options are available:
2543:
2544: TQ:Default Tagged Queuing will be permitted based on the firmware
2545: version of the BusLogic Host Adapter and based on
2546: whether the Concurrency value allows queuing multiple
2547: commands.
2548:
2549: TQ:Enable Tagged Queuing will be enabled for all Target Devices
2550: on this Host Adapter overriding any limitation that
2551: would otherwise be imposed based on the Host Adapter
2552: firmware version.
2553:
2554: TQ:Disable Tagged Queuing will be disabled for all Target Devices
2555: on this Host Adapter.
2556:
2557: TQ:<Per-Target-Spec> Tagged Queuing will be controlled individually for each
2558: Target Device. <Per-Target-Spec> is a sequence of "Y",
2559: "N", and "X" characters. "Y" enabled Tagged Queuing,
2560: "N" disables Tagged Queuing, and "X" accepts the
2561: default based on the firmware version. The first
2562: character refers to Target 0, the second to Target 1,
2563: and so on; if the sequence of "Y", "N", and "X"
2564: characters does not cover all the Target Devices,
2565: unspecified characters are assumed to be "X".
2566:
2567: Note that explicitly requesting Tagged Queuing may lead to problems; this
2568: facility is provided primarily to allow disabling Tagged Queuing on Target
2569: Devices that do not implement it correctly.
2570:
2571: The Error Recovery specification begins with "ER:" and allows for explicitly
2572: specifying the Error Recovery action to be performed when ResetCommand is
2573: called due to a SCSI Command failing to complete successfully. The following
2574: specification options are available:
2575:
2576: ER:Default Error Recovery will select between the Hard Reset and
2577: Bus Device Reset options based on the recommendation
2578: of the SCSI Subsystem.
2579:
2580: ER:HardReset Error Recovery will initiate a Host Adapter Hard Reset
2581: which also causes a SCSI Bus Reset.
2582:
2583: ER:BusDeviceReset Error Recovery will send a Bus Device Reset message to
2584: the individual Target Device causing the error. If
2585: Error Recovery is again initiated for this Target
2586: Device and no SCSI Command to this Target Device has
2587: completed successfully since the Bus Device Reset
2588: message was sent, then a Hard Reset will be attempted.
2589:
2590: ER:None Error Recovery will be suppressed. This option should
2591: only be selected if a SCSI Bus Reset or Bus Device
2592: Reset will cause the Target Device to fail completely
2593: and unrecoverably.
2594:
2595: ER:<Per-Target-Spec> Error Recovery will be controlled individually for each
2596: Target Device. <Per-Target-Spec> is a sequence of "D",
2597: "H", "B", and "N" characters. "D" selects Default, "H"
2598: selects Hard Reset, "B" selects Bus Device Reset, and
2599: "N" selects None. The first character refers to Target
2600: 0, the second to Target 1, and so on; if the sequence
2601: of "D", "H", "B", and "N" characters does not cover all
2602: the Target Devices, unspecified characters are assumed
2603: to be "D".
2604: */
2605:
2606: void BusLogic_Setup(char *Strings, int *Integers)
2607: {
2608: BusLogic_CommandLineEntry_T *CommandLineEntry =
2609: &BusLogic_CommandLineEntries[BusLogic_CommandLineEntryCount++];
2610: static int ProbeListIndex = 0;
2611: int IntegerCount = Integers[0], TargetID, i;
2612: CommandLineEntry->IO_Address = 0;
2613: CommandLineEntry->Concurrency = 0;
2614: CommandLineEntry->BusSettleTime = 0;
2615: CommandLineEntry->LocalOptions = 0;
2616: CommandLineEntry->TaggedQueuingPermitted = 0;
2617: CommandLineEntry->TaggedQueuingPermittedMask = 0;
2618: memset(CommandLineEntry->ErrorRecoveryOption,
2619: BusLogic_ErrorRecoveryDefault,
2620: sizeof(CommandLineEntry->ErrorRecoveryOption));
2621: if (IntegerCount > 5)
2622: printk("BusLogic: Unexpected Command Line Integers ignored\n");
2623: if (IntegerCount >= 1)
2624: {
2625: unsigned short IO_Address = Integers[1];
2626: if (IO_Address > 0)
2627: {
2628: for (i = 0; ; i++)
2629: if (BusLogic_IO_StandardAddresses[i] == 0)
2630: {
2631: printk("BusLogic: Invalid Command Line Entry "
2632: "(illegal I/O Address 0x%X)\n", IO_Address);
2633: return;
2634: }
2635: else if (i < ProbeListIndex &&
2636: IO_Address == BusLogic_IO_AddressProbeList[i])
2637: {
2638: printk("BusLogic: Invalid Command Line Entry "
2639: "(duplicate I/O Address 0x%X)\n", IO_Address);
2640: return;
2641: }
2642: else if (IO_Address >= 0x1000 ||
2643: IO_Address == BusLogic_IO_StandardAddresses[i]) break;
2644: BusLogic_IO_AddressProbeList[ProbeListIndex++] = IO_Address;
2645: BusLogic_IO_AddressProbeList[ProbeListIndex] = 0;
2646: }
2647: CommandLineEntry->IO_Address = IO_Address;
2648: }
2649: if (IntegerCount >= 2)
2650: {
2651: unsigned short Concurrency = Integers[2];
2652: if (Concurrency > BusLogic_MailboxCount)
2653: {
2654: printk("BusLogic: Invalid Command Line Entry "
2655: "(illegal Concurrency %d)\n", Concurrency);
2656: return;
2657: }
2658: CommandLineEntry->Concurrency = Concurrency;
2659: }
2660: if (IntegerCount >= 3)
2661: CommandLineEntry->BusSettleTime = Integers[3];
2662: if (IntegerCount >= 4)
2663: CommandLineEntry->LocalOptions = Integers[4];
2664: if (IntegerCount >= 5)
2665: BusLogic_GlobalOptions |= Integers[5];
2666: if (!(BusLogic_CommandLineEntryCount == 0 || ProbeListIndex == 0 ||
2667: BusLogic_CommandLineEntryCount == ProbeListIndex))
2668: {
2669: printk("BusLogic: Invalid Command Line Entry "
2670: "(all or no I/O Addresses must be specified)\n");
2671: return;
2672: }
2673: if (Strings == NULL) return;
2674: if (strncmp(Strings, "TQ:", 3) == 0)
2675: {
2676: Strings += 3;
2677: if (strncmp(Strings, "Default", 7) == 0)
2678: Strings += 7;
2679: else if (strncmp(Strings, "Enable", 6) == 0)
2680: {
2681: Strings += 6;
2682: CommandLineEntry->TaggedQueuingPermitted = 0xFFFF;
2683: CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF;
2684: }
2685: else if (strncmp(Strings, "Disable", 7) == 0)
2686: {
2687: Strings += 7;
2688: CommandLineEntry->TaggedQueuingPermitted = 0x0000;
2689: CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF;
2690: }
2691: else
2692: for (TargetID = 0; TargetID < BusLogic_MaxTargetIDs; TargetID++)
2693: switch (*Strings++)
2694: {
2695: case 'Y':
2696: CommandLineEntry->TaggedQueuingPermitted |= 1 << TargetID;
2697: CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID;
2698: break;
2699: case 'N':
2700: CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID;
2701: break;
2702: case 'X':
2703: break;
2704: default:
2705: Strings--;
2706: TargetID = BusLogic_MaxTargetIDs;
2707: break;
2708: }
2709: }
2710: if (*Strings == ',') Strings++;
2711: if (strncmp(Strings, "ER:", 3) == 0)
2712: {
2713: Strings += 3;
2714: if (strncmp(Strings, "Default", 7) == 0)
2715: Strings += 7;
2716: else if (strncmp(Strings, "HardReset", 9) == 0)
2717: {
2718: Strings += 9;
2719: memset(CommandLineEntry->ErrorRecoveryOption,
2720: BusLogic_ErrorRecoveryHardReset,
2721: sizeof(CommandLineEntry->ErrorRecoveryOption));
2722: }
2723: else if (strncmp(Strings, "BusDeviceReset", 14) == 0)
2724: {
2725: Strings += 14;
2726: memset(CommandLineEntry->ErrorRecoveryOption,
2727: BusLogic_ErrorRecoveryBusDeviceReset,
2728: sizeof(CommandLineEntry->ErrorRecoveryOption));
2729: }
2730: else if (strncmp(Strings, "None", 4) == 0)
2731: {
2732: Strings += 4;
2733: memset(CommandLineEntry->ErrorRecoveryOption,
2734: BusLogic_ErrorRecoveryNone,
2735: sizeof(CommandLineEntry->ErrorRecoveryOption));
2736: }
2737: else
2738: for (TargetID = 0; TargetID < BusLogic_MaxTargetIDs; TargetID++)
2739: switch (*Strings++)
2740: {
2741: case 'D':
2742: CommandLineEntry->ErrorRecoveryOption[TargetID] =
2743: BusLogic_ErrorRecoveryDefault;
2744: break;
2745: case 'H':
2746: CommandLineEntry->ErrorRecoveryOption[TargetID] =
2747: BusLogic_ErrorRecoveryHardReset;
2748: break;
2749: case 'B':
2750: CommandLineEntry->ErrorRecoveryOption[TargetID] =
2751: BusLogic_ErrorRecoveryBusDeviceReset;
2752: break;
2753: case 'N':
2754: CommandLineEntry->ErrorRecoveryOption[TargetID] =
2755: BusLogic_ErrorRecoveryNone;
2756: break;
2757: default:
2758: Strings--;
2759: TargetID = BusLogic_MaxTargetIDs;
2760: break;
2761: }
2762: }
2763: if (*Strings != '\0')
2764: printk("BusLogic: Unexpected Command Line String '%s' ignored\n", Strings);
2765: }
2766:
2767:
2768: /*
2769: Include Module support if requested.
2770: */
2771:
2772:
2773: #ifdef MODULE
2774:
2775: SCSI_Host_Template_T driver_template = BUSLOGIC;
2776:
2777: #include "scsi_module.c"
2778:
2779: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.