This source file includes following definitions.
- BusLogic_AnnounceDriver
- BusLogic_DriverInfo
- BusLogic_InitializeAddressProbeList
- BusLogic_RegisterHostAdapter
- BusLogic_UnregisterHostAdapter
- BusLogic_CreateCCBs
- BusLogic_DestroyCCBs
- BusLogic_AllocateCCB
- BusLogic_DeallocateCCB
- BusLogic_Command
- BusLogic_Failure
- BusLogic_ProbeHostAdapter
- BusLogic_HardResetHostAdapter
- BusLogic_CheckHostAdapter
- BusLogic_ReadHostAdapterConfiguration
- BusLogic_AcquireResources
- BusLogic_ReleaseResources
- BusLogic_TestInterrupts
- BusLogic_InitializeHostAdapter
- BusLogic_InquireTargetDevices
- BusLogic_DetectHostAdapter
- BusLogic_ReleaseHostAdapter
- BusLogic_ComputeResultCode
- BusLogic_InterruptHandler
- BusLogic_WriteOutgoingMailboxEntry
- BusLogic_QueueCommand
- BusLogic_AbortCommand
- BusLogic_ResetHostAdapter
- BusLogic_BusDeviceReset
- BusLogic_ResetCommand
- BusLogic_BIOSDiskParameters
- BusLogic_Setup
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #define BusLogic_DriverVersion "1.3.0"
27 #define BusLogic_DriverDate "13 November 1995"
28
29
30 #include <linux/config.h>
31 #include <linux/types.h>
32 #include <linux/blkdev.h>
33 #include <linux/delay.h>
34 #include <linux/ioport.h>
35 #include <linux/kernel_stat.h>
36 #include <linux/mm.h>
37 #include <linux/sched.h>
38 #include <linux/stat.h>
39 #include <linux/pci.h>
40 #include <linux/bios32.h>
41 #include <asm/dma.h>
42 #include <asm/io.h>
43 #include <asm/system.h>
44 #include "scsi.h"
45 #include "hosts.h"
46 #include "sd.h"
47 #include "BusLogic.h"
48
49
50
51
52
53
54
55 static int
56 BusLogic_CommandLineEntryCount = 0;
57
58
59
60
61
62
63
64
65 static BusLogic_CommandLineEntry_T
66 BusLogic_CommandLineEntries[BusLogic_MaxHostAdapters];
67
68
69
70
71
72
73
74 static int
75 BusLogic_TracingOptions = 0;
76
77
78
79
80
81
82
83 static BusLogic_HostAdapter_T
84 *BusLogic_RegisteredHostAdapters = NULL;
85
86
87
88
89
90
91
92 static unsigned short
93 BusLogic_IO_StandardAddresses[] =
94 { 0x330, 0x334, 0x230, 0x234, 0x130, 0x134, 0 };
95
96
97
98
99
100
101
102
103
104 static unsigned short
105 BusLogic_IO_AddressProbeList[BusLogic_IO_MaxProbeAddresses+1] = { 0 };
106
107
108
109
110
111
112
113
114
115 static short
116 BusLogic_IRQ_UsageCount[7] = { 0 };
117
118
119
120
121
122
123
124
125 static char
126 *BusLogic_CommandFailureReason;
127
128
129
130
131
132
133 static struct proc_dir_entry
134 BusLogic_ProcDirectoryEntry =
135 { PROC_SCSI_BUSLOGIC, 8, "BusLogic", S_IFDIR | S_IRUGO | S_IXUGO, 2 };
136
137
138
139
140
141
142
143 static void BusLogic_AnnounceDriver(void)
144 {
145 static boolean DriverAnnouncementPrinted = false;
146 if (DriverAnnouncementPrinted) return;
147 printk("scsi: ***** BusLogic SCSI Driver Version "
148 BusLogic_DriverVersion " of " BusLogic_DriverDate " *****\n");
149 printk("scsi: Copyright 1995 by Leonard N. Zubkoff "
150 "<lnz@dandelion.com>\n");
151 DriverAnnouncementPrinted = true;
152 }
153
154
155
156
157
158
159
160 const char *BusLogic_DriverInfo(SCSI_Host_T *Host)
161 {
162 BusLogic_HostAdapter_T *HostAdapter =
163 (BusLogic_HostAdapter_T *) Host->hostdata;
164 return HostAdapter->BoardName;
165 }
166
167
168
169
170
171
172
173
174
175 static void BusLogic_InitializeAddressProbeList(void)
176 {
177 int DestinationIndex = 0, SourceIndex = 0;
178
179
180
181
182 if (BusLogic_IO_AddressProbeList[0] != 0) return;
183 #ifdef CONFIG_PCI
184
185
186
187 if (pcibios_present())
188 {
189 unsigned short Index = 0, VendorID;
190 unsigned char Bus, DeviceAndFunction;
191 unsigned int BaseAddress0;
192 while (pcibios_find_class(PCI_CLASS_STORAGE_SCSI<<8, Index++,
193 &Bus, &DeviceAndFunction) == 0)
194 if (pcibios_read_config_word(Bus, DeviceAndFunction,
195 PCI_VENDOR_ID, &VendorID) == 0 &&
196 VendorID == PCI_VENDOR_ID_BUSLOGIC &&
197 pcibios_read_config_dword(Bus, DeviceAndFunction,
198 PCI_BASE_ADDRESS_0, &BaseAddress0) == 0 &&
199 (BaseAddress0 & PCI_BASE_ADDRESS_SPACE) ==
200 PCI_BASE_ADDRESS_SPACE_IO)
201 {
202 BusLogic_IO_AddressProbeList[DestinationIndex++] =
203 BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK;
204 }
205 }
206 #endif
207
208
209
210 while (DestinationIndex < BusLogic_IO_MaxProbeAddresses &&
211 BusLogic_IO_StandardAddresses[SourceIndex] > 0)
212 BusLogic_IO_AddressProbeList[DestinationIndex++] =
213 BusLogic_IO_StandardAddresses[SourceIndex++];
214 BusLogic_IO_AddressProbeList[DestinationIndex] = 0;
215 }
216
217
218
219
220
221
222
223 static void BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
224 {
225 HostAdapter->Next = NULL;
226 if (BusLogic_RegisteredHostAdapters != NULL)
227 {
228 BusLogic_HostAdapter_T *LastHostAdapter = BusLogic_RegisteredHostAdapters;
229 BusLogic_HostAdapter_T *NextHostAdapter;
230 while ((NextHostAdapter = LastHostAdapter->Next) != NULL)
231 LastHostAdapter = NextHostAdapter;
232 LastHostAdapter->Next = HostAdapter;
233 }
234 else BusLogic_RegisteredHostAdapters = HostAdapter;
235 }
236
237
238
239
240
241
242
243 static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
244 {
245 if (BusLogic_RegisteredHostAdapters != HostAdapter)
246 {
247 BusLogic_HostAdapter_T *LastHostAdapter = BusLogic_RegisteredHostAdapters;
248 while (LastHostAdapter != NULL && LastHostAdapter->Next != HostAdapter)
249 LastHostAdapter = LastHostAdapter->Next;
250 if (LastHostAdapter != NULL)
251 LastHostAdapter->Next = HostAdapter->Next;
252 }
253 else BusLogic_RegisteredHostAdapters = HostAdapter->Next;
254 HostAdapter->Next = NULL;
255 }
256
257
258
259
260
261
262
263 static boolean BusLogic_CreateCCBs(BusLogic_HostAdapter_T *HostAdapter)
264 {
265 int i;
266 for (i = 0; i < BusLogic_InitialCCBs; i++)
267 {
268 BusLogic_CCB_T *CCB = (BusLogic_CCB_T *)
269 scsi_init_malloc(sizeof(BusLogic_CCB_T), GFP_ATOMIC | GFP_DMA);
270 if (CCB == NULL)
271 {
272 printk("scsi%d: UNABLE TO ALLOCATE CCB %d - DETACHING\n",
273 HostAdapter->HostNumber, i);
274 return false;
275 }
276 memset(CCB, 0, sizeof(BusLogic_CCB_T));
277 CCB->HostAdapter = HostAdapter;
278 CCB->Status = BusLogic_CCB_Free;
279 CCB->Next = HostAdapter->Free_CCBs;
280 CCB->NextAll = HostAdapter->All_CCBs;
281 HostAdapter->Free_CCBs = CCB;
282 HostAdapter->All_CCBs = CCB;
283 }
284 return true;
285 }
286
287
288
289
290
291
292 static void BusLogic_DestroyCCBs(BusLogic_HostAdapter_T *HostAdapter)
293 {
294 BusLogic_CCB_T *NextCCB = HostAdapter->All_CCBs, *CCB;
295 HostAdapter->All_CCBs = NULL;
296 HostAdapter->Free_CCBs = NULL;
297 while ((CCB = NextCCB) != NULL)
298 {
299 NextCCB = CCB->NextAll;
300 scsi_init_free((char *) CCB, sizeof(BusLogic_CCB_T));
301 }
302 }
303
304
305
306
307
308
309
310 static BusLogic_CCB_T *BusLogic_AllocateCCB(BusLogic_HostAdapter_T *HostAdapter)
311 {
312 static unsigned int SerialNumber = 0;
313 BusLogic_CCB_T *CCB;
314 BusLogic_LockHostAdapter(HostAdapter);
315 CCB = HostAdapter->Free_CCBs;
316 if (CCB != NULL)
317 {
318 CCB->SerialNumber = SerialNumber++;
319 HostAdapter->Free_CCBs = CCB->Next;
320 BusLogic_UnlockHostAdapter(HostAdapter);
321 return CCB;
322 }
323 BusLogic_UnlockHostAdapter(HostAdapter);
324 CCB = (BusLogic_CCB_T *) scsi_init_malloc(sizeof(BusLogic_CCB_T),
325 GFP_ATOMIC | GFP_DMA);
326 if (CCB == NULL)
327 {
328 printk("scsi%d: Failed to allocate an additional CCB\n",
329 HostAdapter->HostNumber);
330 return NULL;
331 }
332 printk("scsi%d: Allocated an additional CCB\n", HostAdapter->HostNumber);
333 memset(CCB, 0, sizeof(BusLogic_CCB_T));
334 CCB->HostAdapter = HostAdapter;
335 CCB->Status = BusLogic_CCB_Free;
336 BusLogic_LockHostAdapter(HostAdapter);
337 CCB->SerialNumber = SerialNumber++;
338 CCB->NextAll = HostAdapter->All_CCBs;
339 HostAdapter->All_CCBs = CCB;
340 BusLogic_UnlockHostAdapter(HostAdapter);
341 return CCB;
342 }
343
344
345
346
347
348
349
350 static void BusLogic_DeallocateCCB(BusLogic_CCB_T *CCB)
351 {
352 BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
353 BusLogic_LockHostAdapter(HostAdapter);
354 CCB->Command = NULL;
355 CCB->Status = BusLogic_CCB_Free;
356 CCB->SerialNumber = 0;
357 CCB->Next = HostAdapter->Free_CCBs;
358 HostAdapter->Free_CCBs = CCB;
359 BusLogic_UnlockHostAdapter(HostAdapter);
360 }
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381 static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter,
382 BusLogic_OperationCode_T OperationCode,
383 void *ParameterData,
384 int ParameterLength,
385 void *ReplyData,
386 int ReplyLength)
387 {
388 unsigned char *ParameterPointer = (unsigned char *) ParameterData;
389 unsigned char *ReplyPointer = (unsigned char *) ReplyData;
390 unsigned char StatusRegister = 0, InterruptRegister;
391 long TimeoutCounter;
392 int ReplyBytes = 0;
393
394
395
396 if (ReplyLength > 0)
397 memset(ReplyData, 0, ReplyLength);
398
399
400
401 switch (OperationCode)
402 {
403 case BusLogic_InquireInstalledDevicesID0to7:
404 case BusLogic_InquireInstalledDevicesID8to15:
405
406 TimeoutCounter = loops_per_sec << 2;
407 break;
408 default:
409
410 TimeoutCounter = loops_per_sec >> 4;
411 break;
412 }
413
414
415
416
417 while (--TimeoutCounter >= 0)
418 {
419 StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
420 if ((StatusRegister & BusLogic_HostAdapterReady) &&
421 !(StatusRegister & BusLogic_CommandParameterRegisterBusy))
422 break;
423 }
424 BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";
425 if (TimeoutCounter < 0) return -2;
426
427
428
429 BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);
430
431
432
433 HostAdapter->HostAdapterCommandCompleted = false;
434 while (--ParameterLength >= 0)
435 {
436 InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
437 if (InterruptRegister & BusLogic_CommandComplete) break;
438 if (HostAdapter->HostAdapterCommandCompleted) break;
439 while (--TimeoutCounter >= 0)
440 {
441 StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
442 if (!(StatusRegister & BusLogic_CommandParameterRegisterBusy)) break;
443 }
444 BusLogic_CommandFailureReason =
445 "Timeout waiting for Parameter Acceptance";
446 if (TimeoutCounter < 0) return -2;
447 BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++);
448 }
449 BusLogic_CommandFailureReason = "Excess Parameters Supplied";
450 if (ParameterLength >= 0) return -1;
451
452
453
454 if (OperationCode == BusLogic_ModifyIOAddress)
455 {
456 StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
457 BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
458 return ((StatusRegister & BusLogic_CommandInvalid) ? -1 : 0);
459 }
460
461
462
463
464
465 HostAdapter->HostAdapterCommandCompleted = false;
466 while (--TimeoutCounter >= 0)
467 {
468 InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
469 StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
470 if (InterruptRegister & BusLogic_CommandComplete) break;
471 if (HostAdapter->HostAdapterCommandCompleted) break;
472 if (StatusRegister & BusLogic_DataInRegisterReady)
473 if (++ReplyBytes <= ReplyLength)
474 *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
475 else BusLogic_ReadDataInRegister(HostAdapter);
476 }
477 BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";
478 if (TimeoutCounter < 0) return -2;
479
480
481
482
483 if (OperationCode != BusLogic_TestCommandCompleteInterrupt)
484 BusLogic_WriteControlRegister(HostAdapter, BusLogic_InterruptReset);
485 if (BusLogic_TracingOptions & BusLogic_TraceConfiguration)
486 if (OperationCode != BusLogic_TestCommandCompleteInterrupt)
487 {
488 int i;
489 printk("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:",
490 OperationCode, StatusRegister, ReplyLength, ReplyBytes);
491 for (i = 0; i < ReplyBytes; i++)
492 printk(" %02X", ((unsigned char *) ReplyData)[i]);
493 printk("\n");
494 }
495
496
497
498 BusLogic_CommandFailureReason = "Command Invalid";
499 return ((StatusRegister & BusLogic_CommandInvalid) ? -1 : ReplyBytes);
500 }
501
502
503
504
505
506
507
508 static boolean BusLogic_Failure(BusLogic_HostAdapter_T *HostAdapter,
509 char *ErrorMessage)
510 {
511 BusLogic_AnnounceDriver();
512 printk("While configuring BusLogic Host Adapter at I/O Address 0x%X:\n",
513 HostAdapter->IO_Address);
514 printk("%s FAILED - DETACHING\n", ErrorMessage);
515 if (BusLogic_CommandFailureReason != NULL)
516 printk("ADDITIONAL FAILURE INFO - %s\n", BusLogic_CommandFailureReason);
517 return false;
518 }
519
520
521
522
523
524
525 static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
526 {
527 boolean TraceProbe = (BusLogic_TracingOptions & BusLogic_TraceProbe);
528 unsigned char StatusRegister, GeometryRegister;
529
530
531
532
533
534 StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
535 if (TraceProbe)
536 printk("BusLogic_Probe(0x%X): Status 0x%02X\n",
537 HostAdapter->IO_Address, StatusRegister);
538 if (StatusRegister == 0xFF) return false;
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553 GeometryRegister = BusLogic_ReadGeometryRegister(HostAdapter);
554 if (TraceProbe)
555 printk("BusLogic_Probe(0x%X): Geometry 0x%02X\n",
556 HostAdapter->IO_Address, GeometryRegister);
557 if (GeometryRegister == 0xFF) return false;
558
559
560
561 return true;
562 }
563
564
565
566
567
568
569
570 static boolean BusLogic_HardResetHostAdapter(BusLogic_HostAdapter_T
571 *HostAdapter)
572 {
573 boolean TraceHardReset = (BusLogic_TracingOptions & BusLogic_TraceHardReset);
574 long TimeoutCounter = loops_per_sec >> 2;
575 unsigned char StatusRegister = 0;
576
577
578
579
580 BusLogic_WriteControlRegister(HostAdapter, BusLogic_HardReset);
581
582
583
584 while (--TimeoutCounter >= 0)
585 {
586 StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
587 if ((StatusRegister & BusLogic_DiagnosticActive)) break;
588 }
589 if (TraceHardReset)
590 printk("BusLogic_HardReset(0x%X): Diagnostic Active, Status 0x%02X\n",
591 HostAdapter->IO_Address, StatusRegister);
592 if (TimeoutCounter < 0) return false;
593
594
595
596 while (--TimeoutCounter >= 0)
597 {
598 StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
599 if (!(StatusRegister & BusLogic_DiagnosticActive)) break;
600 }
601 if (TraceHardReset)
602 printk("BusLogic_HardReset(0x%X): Diagnostic Completed, Status 0x%02X\n",
603 HostAdapter->IO_Address, StatusRegister);
604 if (TimeoutCounter < 0) return false;
605
606
607
608
609 while (--TimeoutCounter >= 0)
610 {
611 StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
612 if (StatusRegister & (BusLogic_DiagnosticFailure |
613 BusLogic_HostAdapterReady |
614 BusLogic_DataInRegisterReady))
615 break;
616 }
617 if (TraceHardReset)
618 printk("BusLogic_HardReset(0x%X): Host Adapter Ready, Status 0x%02X\n",
619 HostAdapter->IO_Address, StatusRegister);
620 if (TimeoutCounter < 0) return false;
621
622
623
624
625
626 if ((StatusRegister & BusLogic_DiagnosticFailure) ||
627 !(StatusRegister & BusLogic_HostAdapterReady))
628 {
629 BusLogic_CommandFailureReason = NULL;
630 BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
631 printk("HOST ADAPTER STATUS REGISTER = %02X\n", StatusRegister);
632 if (StatusRegister & BusLogic_DataInRegisterReady)
633 {
634 unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
635 printk("HOST ADAPTER ERROR CODE = %d\n", ErrorCode);
636 }
637 return false;
638 }
639
640
641
642 return true;
643 }
644
645
646
647
648
649
650
651 static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
652 {
653 BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
654 BusLogic_RequestedReplyLength_T RequestedReplyLength;
655 unsigned long ProcessorFlags;
656 int Result;
657
658
659
660
661
662
663
664
665
666 save_flags(ProcessorFlags);
667 cli();
668 RequestedReplyLength = sizeof(ExtendedSetupInformation);
669 Result = BusLogic_Command(HostAdapter,
670 BusLogic_InquireExtendedSetupInformation,
671 &RequestedReplyLength, sizeof(RequestedReplyLength),
672 &ExtendedSetupInformation,
673 sizeof(ExtendedSetupInformation));
674 restore_flags(ProcessorFlags);
675 if (BusLogic_TracingOptions & BusLogic_TraceProbe)
676 printk("BusLogic_Check(0x%X): Result %d\n",
677 HostAdapter->IO_Address, Result);
678 return (Result == sizeof(ExtendedSetupInformation));
679 }
680
681
682
683
684
685
686
687 static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T
688 *HostAdapter)
689 {
690 BusLogic_BoardID_T BoardID;
691 BusLogic_Configuration_T Configuration;
692 BusLogic_SetupInformation_T SetupInformation;
693 BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
694 BusLogic_ModelAndRevision_T ModelAndRevision;
695 BusLogic_FirmwareVersion3rdDigit_T FirmwareVersion3rdDigit;
696 BusLogic_FirmwareVersionLetter_T FirmwareVersionLetter;
697 BusLogic_RequestedReplyLength_T RequestedReplyLength;
698 unsigned char GeometryRegister, *TargetPointer, Character;
699 unsigned short AllTargetsMask, DisconnectPermitted;
700 unsigned short TaggedQueuingPermitted, TaggedQueuingPermittedDefault;
701 boolean CommonErrorRecovery;
702 int TargetID, i;
703
704
705
706 if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0,
707 &BoardID, sizeof(BoardID)) != sizeof(BoardID))
708 return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
709
710
711
712 if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0,
713 &Configuration, sizeof(Configuration))
714 != sizeof(Configuration))
715 return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
716
717
718
719 RequestedReplyLength = sizeof(SetupInformation);
720 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
721 &RequestedReplyLength, sizeof(RequestedReplyLength),
722 &SetupInformation, sizeof(SetupInformation))
723 != sizeof(SetupInformation))
724 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
725
726
727
728 RequestedReplyLength = sizeof(ExtendedSetupInformation);
729 if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation,
730 &RequestedReplyLength, sizeof(RequestedReplyLength),
731 &ExtendedSetupInformation,
732 sizeof(ExtendedSetupInformation))
733 != sizeof(ExtendedSetupInformation))
734 return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
735
736
737
738 RequestedReplyLength = sizeof(ModelAndRevision);
739 if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardModelAndRevision,
740 &RequestedReplyLength, sizeof(RequestedReplyLength),
741 &ModelAndRevision, sizeof(ModelAndRevision))
742 != sizeof(ModelAndRevision))
743 return BusLogic_Failure(HostAdapter, "INQUIRE BOARD MODEL AND REVISION");
744
745
746
747 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit,
748 NULL, 0, &FirmwareVersion3rdDigit,
749 sizeof(FirmwareVersion3rdDigit))
750 != sizeof(FirmwareVersion3rdDigit))
751 return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
752
753
754
755 FirmwareVersionLetter = '\0';
756 if (BoardID.FirmwareVersion1stDigit >= '3')
757 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter,
758 NULL, 0, &FirmwareVersionLetter,
759 sizeof(FirmwareVersionLetter))
760 != sizeof(FirmwareVersionLetter))
761 return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE VERSION LETTER");
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778 TargetPointer = HostAdapter->ModelName;
779 for (i = 0; i < sizeof(ModelAndRevision.Model); i++)
780 {
781 Character = ModelAndRevision.Model[i];
782 if (Character == ' ' || Character == '\0') break;
783 *TargetPointer++ = Character;
784 }
785 *TargetPointer++ = '\0';
786 strcpy(HostAdapter->BoardName, "BusLogic ");
787 strcat(HostAdapter->BoardName, HostAdapter->ModelName);
788 strcpy(HostAdapter->InterruptLabel, HostAdapter->BoardName);
789
790
791
792 TargetPointer = HostAdapter->FirmwareVersion;
793 *TargetPointer++ = BoardID.FirmwareVersion1stDigit;
794 *TargetPointer++ = '.';
795 *TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
796 if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0')
797 *TargetPointer++ = FirmwareVersion3rdDigit;
798 if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0')
799 *TargetPointer++ = FirmwareVersionLetter;
800 *TargetPointer++ = '\0';
801
802
803
804 if (Configuration.IRQ_Channel9)
805 HostAdapter->IRQ_Channel = 9;
806 else if (Configuration.IRQ_Channel10)
807 HostAdapter->IRQ_Channel = 10;
808 else if (Configuration.IRQ_Channel11)
809 HostAdapter->IRQ_Channel = 11;
810 else if (Configuration.IRQ_Channel12)
811 HostAdapter->IRQ_Channel = 12;
812 else if (Configuration.IRQ_Channel14)
813 HostAdapter->IRQ_Channel = 14;
814 else if (Configuration.IRQ_Channel15)
815 HostAdapter->IRQ_Channel = 15;
816
817
818
819 if (Configuration.DMA_Channel5)
820 HostAdapter->DMA_Channel = 5;
821 else if (Configuration.DMA_Channel6)
822 HostAdapter->DMA_Channel = 6;
823 else if (Configuration.DMA_Channel7)
824 HostAdapter->DMA_Channel = 7;
825
826
827
828 HostAdapter->SCSI_ID = Configuration.HostAdapterID;
829
830
831
832
833 HostAdapter->SynchronousInitiation =
834 SetupInformation.SynchronousInitiationEnabled;
835 HostAdapter->ParityChecking = SetupInformation.ParityCheckEnabled;
836
837
838
839
840 if (ExtendedSetupInformation.BusType == 'A')
841 HostAdapter->BusType = BusLogic_ISA_Bus;
842 else
843 switch (HostAdapter->ModelName[0])
844 {
845 case '4':
846 HostAdapter->BusType = BusLogic_VESA_Bus;
847 HostAdapter->DMA_Channel = 0;
848 break;
849 case '5':
850 HostAdapter->BusType = BusLogic_ISA_Bus;
851 break;
852 case '6':
853 HostAdapter->BusType = BusLogic_MCA_Bus;
854 HostAdapter->DMA_Channel = 0;
855 break;
856 case '7':
857 HostAdapter->BusType = BusLogic_EISA_Bus;
858 HostAdapter->DMA_Channel = 0;
859 break;
860 case '9':
861 HostAdapter->BusType = BusLogic_PCI_Bus;
862 HostAdapter->DMA_Channel = 0;
863 break;
864 }
865
866
867
868
869 GeometryRegister = BusLogic_ReadGeometryRegister(HostAdapter);
870 if (GeometryRegister & BusLogic_ExtendedTranslationEnabled)
871 HostAdapter->ExtendedTranslation = true;
872
873
874
875
876
877
878 if (HostAdapter->FirmwareVersion[0] >= '4')
879 HostAdapter->DisconnectPermitted =
880 (SetupInformation.DisconnectPermittedID8to15 << 8)
881 | SetupInformation.DisconnectPermittedID0to7;
882 else HostAdapter->DisconnectPermitted = 0xFF;
883
884
885
886
887 HostAdapter->HostAdapterScatterGatherLimit =
888 ExtendedSetupInformation.ScatterGatherLimit;
889 HostAdapter->DriverScatterGatherLimit =
890 HostAdapter->HostAdapterScatterGatherLimit;
891 if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
892 HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
893 if (ExtendedSetupInformation.Misc.LevelTriggeredInterrupts)
894 HostAdapter->LevelTriggeredInterrupts = true;
895 if (ExtendedSetupInformation.HostWideSCSI)
896 {
897 HostAdapter->HostWideSCSI = true;
898 HostAdapter->MaxTargetIDs = 16;
899 HostAdapter->MaxLogicalUnits = 64;
900 }
901 else
902 {
903 HostAdapter->HostWideSCSI = false;
904 HostAdapter->MaxTargetIDs = 8;
905 HostAdapter->MaxLogicalUnits = 8;
906 }
907 HostAdapter->HostDifferentialSCSI =
908 ExtendedSetupInformation.HostDifferentialSCSI;
909
910
911
912
913
914 HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
915
916
917
918
919
920 if (HostAdapter->CommandLineEntry != NULL &&
921 HostAdapter->CommandLineEntry->Concurrency > 0)
922 HostAdapter->Concurrency = HostAdapter->CommandLineEntry->Concurrency;
923 else if (HostAdapter->BusType == BusLogic_ISA_Bus)
924 HostAdapter->Concurrency = BusLogic_Concurrency_ISA;
925 else HostAdapter->Concurrency = BusLogic_Concurrency;
926
927
928
929
930 if (HostAdapter->CommandLineEntry != NULL &&
931 HostAdapter->CommandLineEntry->BusSettleTime > 0)
932 HostAdapter->BusSettleTime = HostAdapter->CommandLineEntry->BusSettleTime;
933 else HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
934
935
936
937
938 if (HostAdapter->CommandLineEntry != NULL)
939 memcpy(HostAdapter->ErrorRecoveryOption,
940 HostAdapter->CommandLineEntry->ErrorRecoveryOption,
941 sizeof(HostAdapter->ErrorRecoveryOption));
942 else memset(HostAdapter->ErrorRecoveryOption,
943 BusLogic_ErrorRecoveryDefault,
944 sizeof(HostAdapter->ErrorRecoveryOption));
945
946
947
948
949
950
951
952 TaggedQueuingPermittedDefault = 0;
953 if (HostAdapter->Concurrency > 1)
954 switch (HostAdapter->FirmwareVersion[0])
955 {
956 case '4':
957 if (HostAdapter->FirmwareVersion[2] > '2' ||
958 (HostAdapter->FirmwareVersion[2] == '2' &&
959 HostAdapter->FirmwareVersion[3] >= '2'))
960 TaggedQueuingPermittedDefault = 0xFFFF;
961 break;
962 case '3':
963 if (HostAdapter->FirmwareVersion[2] > '3' ||
964 (HostAdapter->FirmwareVersion[2] == '3' &&
965 HostAdapter->FirmwareVersion[3] >= '5'))
966 TaggedQueuingPermittedDefault = 0xFFFF;
967 break;
968 }
969
970
971
972
973
974 if (HostAdapter->CommandLineEntry != NULL)
975 HostAdapter->TaggedQueuingPermitted =
976 (HostAdapter->CommandLineEntry->TaggedQueuingPermitted &
977 HostAdapter->CommandLineEntry->TaggedQueuingPermittedMask) |
978 (TaggedQueuingPermittedDefault &
979 ~HostAdapter->CommandLineEntry->TaggedQueuingPermittedMask);
980 else HostAdapter->TaggedQueuingPermitted = TaggedQueuingPermittedDefault;
981
982
983
984 printk("scsi%d: Configuring BusLogic Model %s %s%s%s SCSI Host Adapter\n",
985 HostAdapter->HostNumber, HostAdapter->ModelName,
986 BusLogic_BusNames[HostAdapter->BusType],
987 (HostAdapter->HostWideSCSI ? " Wide" : ""),
988 (HostAdapter->HostDifferentialSCSI ? " Differential" : ""));
989 printk("scsi%d: Firmware Version: %s, I/O Address: 0x%X, "
990 "IRQ Channel: %d/%s\n",
991 HostAdapter->HostNumber, HostAdapter->FirmwareVersion,
992 HostAdapter->IO_Address, HostAdapter->IRQ_Channel,
993 (HostAdapter->LevelTriggeredInterrupts ? "Level" : "Edge"));
994 printk("scsi%d: DMA Channel: ", HostAdapter->HostNumber);
995 if (HostAdapter->DMA_Channel > 0)
996 printk("%d, ", HostAdapter->DMA_Channel);
997 else printk("None, ");
998 if (HostAdapter->BIOS_Address > 0)
999 printk("BIOS Address: 0x%lX, ", HostAdapter->BIOS_Address);
1000 else printk("BIOS Address: None, ");
1001 printk("Host Adapter SCSI ID: %d\n", HostAdapter->SCSI_ID);
1002 printk("scsi%d: Scatter/Gather Limit: %d segments, "
1003 "Synchronous Initiation: %s\n", HostAdapter->HostNumber,
1004 HostAdapter->HostAdapterScatterGatherLimit,
1005 (HostAdapter->SynchronousInitiation ? "Enabled" : "Disabled"));
1006 printk("scsi%d: SCSI Parity Checking: %s, "
1007 "Extended Disk Translation: %s\n", HostAdapter->HostNumber,
1008 (HostAdapter->ParityChecking ? "Enabled" : "Disabled"),
1009 (HostAdapter->ExtendedTranslation ? "Enabled" : "Disabled"));
1010 AllTargetsMask = (1 << HostAdapter->MaxTargetIDs) - 1;
1011 DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
1012 printk("scsi%d: Disconnect/Reconnect: ", HostAdapter->HostNumber);
1013 if (DisconnectPermitted == 0)
1014 printk("Disabled");
1015 else if (DisconnectPermitted == AllTargetsMask)
1016 printk("Enabled");
1017 else
1018 for (TargetID = 0; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
1019 printk("%c", (DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
1020 printk(", Tagged Queuing: ");
1021 TaggedQueuingPermitted =
1022 HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
1023 if (TaggedQueuingPermitted == 0)
1024 printk("Disabled");
1025 else if (TaggedQueuingPermitted == AllTargetsMask)
1026 printk("Enabled");
1027 else
1028 for (TargetID = 0; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
1029 printk("%c", (TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
1030 printk("\n");
1031 CommonErrorRecovery = true;
1032 for (TargetID = 1; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
1033 if (HostAdapter->ErrorRecoveryOption[TargetID] !=
1034 HostAdapter->ErrorRecoveryOption[0])
1035 {
1036 CommonErrorRecovery = false;
1037 break;
1038 }
1039 printk("scsi%d: Error Recovery: ", HostAdapter->HostNumber);
1040 if (CommonErrorRecovery)
1041 printk("%s", BusLogic_ErrorRecoveryOptions[
1042 HostAdapter->ErrorRecoveryOption[0]]);
1043 else
1044 for (TargetID = 0; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
1045 printk("%s", BusLogic_ErrorRecoveryOptions2[
1046 HostAdapter->ErrorRecoveryOption[TargetID]]);
1047 printk(", Mailboxes: %d, Initial CCBs: %d\n",
1048 BusLogic_MailboxCount, BusLogic_InitialCCBs);
1049 printk("scsi%d: Driver Scatter/Gather Limit: %d segments, "
1050 "Concurrency: %d\n", HostAdapter->HostNumber,
1051 HostAdapter->DriverScatterGatherLimit, HostAdapter->Concurrency);
1052
1053
1054
1055 return true;
1056 }
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068 static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter,
1069 SCSI_Host_T *Host)
1070 {
1071
1072
1073
1074
1075 if (BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9]++ == 0)
1076 {
1077 if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler,
1078 SA_INTERRUPT, HostAdapter->InterruptLabel) < 0)
1079 {
1080 BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9]--;
1081 printk("scsi%d: UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
1082 HostAdapter->HostNumber, HostAdapter->IRQ_Channel);
1083 return false;
1084 }
1085 }
1086 else
1087 {
1088 BusLogic_HostAdapter_T *FirstHostAdapter =
1089 BusLogic_RegisteredHostAdapters;
1090 while (FirstHostAdapter != NULL)
1091 {
1092 if (FirstHostAdapter->IRQ_Channel == HostAdapter->IRQ_Channel)
1093 {
1094 if (strlen(FirstHostAdapter->InterruptLabel) + 8
1095 < sizeof(FirstHostAdapter->InterruptLabel))
1096 {
1097 strcat(FirstHostAdapter->InterruptLabel, " + ");
1098 strcat(FirstHostAdapter->InterruptLabel,
1099 HostAdapter->ModelName);
1100 }
1101 break;
1102 }
1103 FirstHostAdapter = FirstHostAdapter->Next;
1104 }
1105 }
1106 HostAdapter->IRQ_ChannelAcquired = true;
1107
1108
1109
1110 if (HostAdapter->DMA_Channel > 0)
1111 {
1112 if (request_dma(HostAdapter->DMA_Channel, HostAdapter->BoardName) < 0)
1113 {
1114 printk("scsi%d: UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n",
1115 HostAdapter->HostNumber, HostAdapter->DMA_Channel);
1116 return false;
1117 }
1118 set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
1119 enable_dma(HostAdapter->DMA_Channel);
1120 HostAdapter->DMA_ChannelAcquired = true;
1121 }
1122
1123
1124
1125 Host->max_id = HostAdapter->MaxTargetIDs;
1126 Host->max_lun = HostAdapter->MaxLogicalUnits;
1127 Host->max_channel = 0;
1128 Host->this_id = HostAdapter->SCSI_ID;
1129 Host->can_queue = BusLogic_MailboxCount;
1130 Host->cmd_per_lun = HostAdapter->Concurrency;
1131 Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
1132 Host->unchecked_isa_dma = (HostAdapter->BusType == BusLogic_ISA_Bus);
1133
1134
1135
1136
1137
1138
1139
1140
1141 if (HostAdapter->BIOS_Address > 0 &&
1142 strcmp(HostAdapter->ModelName, "445S") == 0)
1143 {
1144 Host->forbidden_addr = HostAdapter->BIOS_Address;
1145 Host->forbidden_size = 16*1024;
1146 }
1147
1148
1149
1150 return true;
1151 }
1152
1153
1154
1155
1156
1157
1158
1159 static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *HostAdapter)
1160 {
1161
1162
1163
1164 if (HostAdapter->IRQ_ChannelAcquired)
1165 if (--BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9] == 0)
1166 free_irq(HostAdapter->IRQ_Channel);
1167
1168
1169
1170 if (HostAdapter->DMA_ChannelAcquired)
1171 free_dma(HostAdapter->DMA_Channel);
1172 }
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184 static boolean BusLogic_TestInterrupts(BusLogic_HostAdapter_T *HostAdapter)
1185 {
1186 unsigned int InitialInterruptCount, FinalInterruptCount;
1187 int TestCount = 5, i;
1188 InitialInterruptCount = kstat.interrupts[HostAdapter->IRQ_Channel];
1189
1190
1191
1192 for (i = 0; i < TestCount; i++)
1193 BusLogic_Command(HostAdapter, BusLogic_TestCommandCompleteInterrupt,
1194 NULL, 0, NULL, 0);
1195
1196
1197
1198
1199
1200 FinalInterruptCount = kstat.interrupts[HostAdapter->IRQ_Channel];
1201 if (FinalInterruptCount < InitialInterruptCount + TestCount)
1202 {
1203 printk("scsi%d: HOST ADAPTER INTERRUPT TEST FAILED - DETACHING\n",
1204 HostAdapter->HostNumber);
1205 printk("scsi%d: Interrupts are not getting through "
1206 "from the Host Adapter to the\n", HostAdapter->HostNumber);
1207 printk("scsi%d: BusLogic Driver Interrupt Handler. "
1208 "The most likely cause is that\n", HostAdapter->HostNumber);
1209 printk("scsi%d: either the Host Adapter or Motherboard "
1210 "is configured incorrectly.\n", HostAdapter->HostNumber);
1211 printk("scsi%d: Please check the Host Adapter configuration "
1212 "with AutoSCSI or by\n", HostAdapter->HostNumber);
1213 printk("scsi%d: examining any dip switch and jumper settings "
1214 "on the Host Adapter, and\n", HostAdapter->HostNumber);
1215 printk("scsi%d: verify that no other device is attempting to "
1216 "use the same IRQ Channel.\n", HostAdapter->HostNumber);
1217 printk("scsi%d: For PCI Host Adapters, it may also be necessary "
1218 "to investigate and\n", HostAdapter->HostNumber);
1219 printk("scsi%d: manually set the PCI interrupt assignments "
1220 "and edge/level interrupt\n", HostAdapter->HostNumber);
1221 printk("scsi%d: type selection in the BIOS Setup Program or "
1222 "with Motherboard jumpers.\n", HostAdapter->HostNumber);
1223 return false;
1224 }
1225
1226
1227
1228 return true;
1229 }
1230
1231
1232
1233
1234
1235
1236
1237
1238 static boolean BusLogic_InitializeHostAdapter(BusLogic_HostAdapter_T
1239 *HostAdapter)
1240 {
1241 BusLogic_ExtendedMailboxRequest_T ExtendedMailboxRequest;
1242 BusLogic_RoundRobinModeRequest_T RoundRobinModeRequest;
1243 BusLogic_WideModeCCBRequest_T WideModeCCBRequest;
1244 BusLogic_ModifyIOAddressRequest_T ModifyIOAddressRequest;
1245
1246
1247
1248
1249 memset(HostAdapter->ReadWriteOperationCount, 0,
1250 sizeof(HostAdapter->ReadWriteOperationCount));
1251 memset(HostAdapter->CommandSuccessfulFlag, false,
1252 sizeof(HostAdapter->CommandSuccessfulFlag));
1253
1254
1255
1256 memset(HostAdapter->OutgoingMailboxes, 0,
1257 sizeof(HostAdapter->OutgoingMailboxes));
1258 memset(HostAdapter->IncomingMailboxes, 0,
1259 sizeof(HostAdapter->IncomingMailboxes));
1260
1261
1262
1263 HostAdapter->FirstOutgoingMailbox = &HostAdapter->OutgoingMailboxes[0];
1264 HostAdapter->LastOutgoingMailbox =
1265 &HostAdapter->OutgoingMailboxes[BusLogic_MailboxCount-1];
1266 HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
1267 HostAdapter->FirstIncomingMailbox = &HostAdapter->IncomingMailboxes[0];
1268 HostAdapter->LastIncomingMailbox =
1269 &HostAdapter->IncomingMailboxes[BusLogic_MailboxCount-1];
1270 HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
1271
1272
1273
1274 ExtendedMailboxRequest.MailboxCount = BusLogic_MailboxCount;
1275 ExtendedMailboxRequest.BaseMailboxAddress = HostAdapter->OutgoingMailboxes;
1276 if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox,
1277 &ExtendedMailboxRequest,
1278 sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
1279 {
1280 printk("scsi%d: MAILBOX INITIALIZATION FAILED - DETACHING\n",
1281 HostAdapter->HostNumber);
1282 return false;
1283 }
1284
1285
1286
1287
1288
1289
1290
1291 RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
1292 BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode,
1293 &RoundRobinModeRequest,
1294 sizeof(RoundRobinModeRequest), NULL, 0);
1295
1296
1297
1298
1299 if (HostAdapter->HostWideSCSI)
1300 {
1301 WideModeCCBRequest = BusLogic_WideModeCCB;
1302 if (BusLogic_Command(HostAdapter, BusLogic_EnableWideModeCCB,
1303 &WideModeCCBRequest,
1304 sizeof(WideModeCCBRequest), NULL, 0) < 0)
1305 {
1306 printk("scsi%d: ENABLE WIDE MODE CCB FAILED - DETACHING\n",
1307 HostAdapter->HostNumber);
1308 return false;
1309 }
1310 }
1311
1312
1313
1314
1315
1316 if (HostAdapter->BusType == BusLogic_PCI_Bus)
1317 {
1318 int Index;
1319 for (Index = 0; BusLogic_IO_StandardAddresses[Index] > 0; Index++)
1320 if (HostAdapter->IO_Address == BusLogic_IO_StandardAddresses[Index])
1321 break;
1322 if (BusLogic_IO_StandardAddresses[Index] == 0)
1323 {
1324 ModifyIOAddressRequest = BusLogic_ModifyIO_Disable;
1325 if (BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress,
1326 &ModifyIOAddressRequest,
1327 sizeof(ModifyIOAddressRequest), NULL, 0) < 0)
1328 {
1329 printk("scsi%d: MODIFY I/O ADDRESS FAILED - DETACHING\n",
1330 HostAdapter->HostNumber);
1331 return false;
1332 }
1333 }
1334 }
1335
1336
1337
1338 printk("scsi%d: *** %s Initialized Successfully ***\n",
1339 HostAdapter->HostNumber, HostAdapter->BoardName);
1340
1341
1342
1343 return true;
1344 }
1345
1346
1347
1348
1349
1350
1351
1352 static boolean BusLogic_InquireTargetDevices(BusLogic_HostAdapter_T
1353 *HostAdapter)
1354 {
1355 BusLogic_InstalledDevices8_T InstalledDevicesID0to7;
1356 BusLogic_InstalledDevices8_T InstalledDevicesID8to15;
1357 BusLogic_SetupInformation_T SetupInformation;
1358 BusLogic_SynchronousPeriod_T SynchronousPeriod;
1359 BusLogic_RequestedReplyLength_T RequestedReplyLength;
1360 int TargetDevicesFound = 0, TargetID;
1361
1362
1363
1364
1365
1366 BusLogic_Delay(HostAdapter->BusSettleTime);
1367
1368
1369
1370
1371
1372
1373
1374 if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7,
1375 NULL, 0, &InstalledDevicesID0to7,
1376 sizeof(InstalledDevicesID0to7))
1377 != sizeof(InstalledDevicesID0to7))
1378 return BusLogic_Failure(HostAdapter, "INQUIRE INSTALLED DEVICES ID 0 TO 7");
1379 if (HostAdapter->HostWideSCSI)
1380 if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID8to15,
1381 NULL, 0, &InstalledDevicesID8to15,
1382 sizeof(InstalledDevicesID8to15))
1383 != sizeof(InstalledDevicesID8to15))
1384 return BusLogic_Failure(HostAdapter,
1385 "INQUIRE INSTALLED DEVICES ID 8 TO 15");
1386
1387
1388
1389 RequestedReplyLength = sizeof(SetupInformation);
1390 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
1391 &RequestedReplyLength, sizeof(RequestedReplyLength),
1392 &SetupInformation, sizeof(SetupInformation))
1393 != sizeof(SetupInformation))
1394 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
1395
1396
1397
1398 RequestedReplyLength = sizeof(SynchronousPeriod);
1399 if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod,
1400 &RequestedReplyLength, 1,
1401 &SynchronousPeriod, sizeof(SynchronousPeriod))
1402 != sizeof(SynchronousPeriod))
1403 return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
1404
1405
1406
1407
1408 memcpy(HostAdapter->InstalledDevices, InstalledDevicesID0to7,
1409 sizeof(BusLogic_InstalledDevices8_T));
1410 memcpy(HostAdapter->SynchronousValues,
1411 SetupInformation.SynchronousValuesID0to7,
1412 sizeof(BusLogic_SynchronousValues8_T));
1413 if (HostAdapter->HostWideSCSI)
1414 {
1415 memcpy(&HostAdapter->InstalledDevices[8], InstalledDevicesID8to15,
1416 sizeof(BusLogic_InstalledDevices8_T));
1417 memcpy(&HostAdapter->SynchronousValues[8],
1418 SetupInformation.SynchronousValuesID8to15,
1419 sizeof(BusLogic_SynchronousValues8_T));
1420 }
1421 memcpy(HostAdapter->SynchronousPeriod, SynchronousPeriod,
1422 sizeof(BusLogic_SynchronousPeriod_T));
1423 for (TargetID = 0; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
1424 if (HostAdapter->InstalledDevices[TargetID] != 0)
1425 {
1426 int SynchronousPeriod = HostAdapter->SynchronousPeriod[TargetID];
1427 if (SynchronousPeriod > 10)
1428 {
1429 int SynchronousTransferRate = 100000000 / SynchronousPeriod;
1430 int RoundedSynchronousTransferRate =
1431 (SynchronousTransferRate + 5000) / 10000;
1432 printk("scsi%d: Target %d: Synchronous at "
1433 "%d.%02d mega-transfers/sec, offset %d\n",
1434 HostAdapter->HostNumber, TargetID,
1435 RoundedSynchronousTransferRate / 100,
1436 RoundedSynchronousTransferRate % 100,
1437 HostAdapter->SynchronousValues[TargetID].Offset);
1438 }
1439 else if (SynchronousPeriod > 0)
1440 {
1441 int SynchronousTransferRate = 100000000 / SynchronousPeriod;
1442 int RoundedSynchronousTransferRate =
1443 (SynchronousTransferRate + 50000) / 100000;
1444 printk("scsi%d: Target %d: Synchronous at "
1445 "%d.%01d mega-transfers/sec, offset %d\n",
1446 HostAdapter->HostNumber, TargetID,
1447 RoundedSynchronousTransferRate / 10,
1448 RoundedSynchronousTransferRate % 10,
1449 HostAdapter->SynchronousValues[TargetID].Offset);
1450 }
1451 else printk("scsi%d: Target %d: Asynchronous\n",
1452 HostAdapter->HostNumber, TargetID);
1453 TargetDevicesFound++;
1454 }
1455 if (TargetDevicesFound == 0)
1456 printk("scsi%d: No Target Devices Found\n", HostAdapter->HostNumber);
1457
1458
1459
1460 return true;
1461 }
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472 int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate)
1473 {
1474 int BusLogicHostAdapterCount = 0, CommandLineEntryIndex = 0;
1475 int AddressProbeIndex = 0;
1476 BusLogic_InitializeAddressProbeList();
1477 while (BusLogic_IO_AddressProbeList[AddressProbeIndex] > 0)
1478 {
1479 BusLogic_HostAdapter_T HostAdapterPrototype;
1480 BusLogic_HostAdapter_T *HostAdapter = &HostAdapterPrototype;
1481 SCSI_Host_T *Host;
1482 memset(HostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
1483 HostAdapter->IO_Address =
1484 BusLogic_IO_AddressProbeList[AddressProbeIndex++];
1485
1486
1487
1488
1489 if (CommandLineEntryIndex < BusLogic_CommandLineEntryCount &&
1490 BusLogic_CommandLineEntries[CommandLineEntryIndex].IO_Address ==
1491 HostAdapter->IO_Address)
1492 HostAdapter->CommandLineEntry =
1493 &BusLogic_CommandLineEntries[CommandLineEntryIndex++];
1494
1495
1496
1497 if (check_region(HostAdapter->IO_Address, BusLogic_IO_PortCount) < 0)
1498 continue;
1499
1500
1501
1502 if (!BusLogic_ProbeHostAdapter(HostAdapter)) continue;
1503
1504
1505
1506
1507 if (!BusLogic_HardResetHostAdapter(HostAdapter)) continue;
1508
1509
1510
1511 if (!BusLogic_CheckHostAdapter(HostAdapter)) continue;
1512
1513
1514
1515
1516 if (CommandLineEntryIndex < BusLogic_CommandLineEntryCount &&
1517 BusLogic_CommandLineEntries[CommandLineEntryIndex].IO_Address == 0)
1518 HostAdapter->CommandLineEntry =
1519 &BusLogic_CommandLineEntries[CommandLineEntryIndex++];
1520
1521
1522
1523
1524 BusLogic_AnnounceDriver();
1525
1526
1527
1528
1529
1530
1531
1532
1533 request_region(HostAdapter->IO_Address, BusLogic_IO_PortCount,
1534 "BusLogic");
1535
1536
1537
1538 HostTemplate->proc_dir = &BusLogic_ProcDirectoryEntry;
1539 Host = scsi_register(HostTemplate, sizeof(BusLogic_HostAdapter_T));
1540 HostAdapter = (BusLogic_HostAdapter_T *) Host->hostdata;
1541 memcpy(HostAdapter, &HostAdapterPrototype,
1542 sizeof(BusLogic_HostAdapter_T));
1543 HostAdapter->SCSI_Host = Host;
1544 HostAdapter->HostNumber = Host->host_no;
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554 BusLogic_RegisterHostAdapter(HostAdapter);
1555
1556
1557
1558
1559
1560
1561 if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
1562 BusLogic_AcquireResources(HostAdapter, Host) &&
1563 BusLogic_TestInterrupts(HostAdapter) &&
1564 BusLogic_CreateCCBs(HostAdapter) &&
1565 BusLogic_InitializeHostAdapter(HostAdapter) &&
1566 BusLogic_InquireTargetDevices(HostAdapter))
1567 {
1568
1569
1570
1571
1572
1573 release_region(HostAdapter->IO_Address, BusLogic_IO_PortCount);
1574 request_region(HostAdapter->IO_Address, BusLogic_IO_PortCount,
1575 HostAdapter->BoardName);
1576 BusLogicHostAdapterCount++;
1577 }
1578 else
1579 {
1580
1581
1582
1583
1584
1585
1586
1587 BusLogic_DestroyCCBs(HostAdapter);
1588 BusLogic_ReleaseResources(HostAdapter);
1589 BusLogic_UnregisterHostAdapter(HostAdapter);
1590 scsi_unregister(Host);
1591 }
1592 }
1593 return BusLogicHostAdapterCount;
1594 }
1595
1596
1597
1598
1599
1600
1601
1602
1603 int BusLogic_ReleaseHostAdapter(SCSI_Host_T *Host)
1604 {
1605 BusLogic_HostAdapter_T *HostAdapter =
1606 (BusLogic_HostAdapter_T *) Host->hostdata;
1607
1608
1609
1610
1611 BusLogic_DestroyCCBs(HostAdapter);
1612 BusLogic_ReleaseResources(HostAdapter);
1613
1614
1615
1616 release_region(HostAdapter->IO_Address, BusLogic_IO_PortCount);
1617
1618
1619
1620 BusLogic_UnregisterHostAdapter(HostAdapter);
1621 return 0;
1622 }
1623
1624
1625
1626
1627
1628
1629
1630 static int BusLogic_ComputeResultCode(BusLogic_HostAdapterStatus_T
1631 HostAdapterStatus,
1632 BusLogic_TargetDeviceStatus_T
1633 TargetDeviceStatus)
1634 {
1635 int HostStatus;
1636 switch (HostAdapterStatus)
1637 {
1638 case BusLogic_CommandCompletedNormally:
1639 case BusLogic_LinkedCommandCompleted:
1640 case BusLogic_LinkedCommandCompletedWithFlag:
1641 HostStatus = DID_OK;
1642 break;
1643 case BusLogic_SCSISelectionTimeout:
1644 HostStatus = DID_TIME_OUT;
1645 break;
1646 case BusLogic_InvalidOutgoingMailboxActionCode:
1647 case BusLogic_InvalidCommandOperationCode:
1648 case BusLogic_InvalidCommandParameter:
1649 printk("BusLogic: BusLogic Driver Protocol Error 0x%02X\n",
1650 HostAdapterStatus);
1651 case BusLogic_DataOverUnderRun:
1652 case BusLogic_UnexpectedBusFree:
1653 case BusLogic_LinkedCCBhasInvalidLUN:
1654 case BusLogic_AutoRequestSenseFailed:
1655 case BusLogic_TaggedQueuingMessageRejected:
1656 case BusLogic_UnsupportedMessageReceived:
1657 case BusLogic_HostAdapterHardwareFailed:
1658 case BusLogic_TargetDeviceReconnectedImproperly:
1659 case BusLogic_AbortQueueGenerated:
1660 case BusLogic_HostAdapterSoftwareError:
1661 case BusLogic_HostAdapterHardwareTimeoutError:
1662 case BusLogic_SCSIParityErrorDetected:
1663 HostStatus = DID_ERROR;
1664 break;
1665 case BusLogic_InvalidBusPhaseRequested:
1666 case BusLogic_TargetFailedResponseToATN:
1667 case BusLogic_HostAdapterAssertedRST:
1668 case BusLogic_OtherDeviceAssertedRST:
1669 case BusLogic_HostAdapterAssertedBusDeviceReset:
1670 HostStatus = DID_RESET;
1671 break;
1672 default:
1673 printk("BusLogic: unknown Host Adapter Status 0x%02X\n",
1674 HostAdapterStatus);
1675 HostStatus = DID_ERROR;
1676 break;
1677 }
1678 return (HostStatus << 16) | TargetDeviceStatus;
1679 }
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689 static void BusLogic_InterruptHandler(int IRQ_Channel,
1690 Registers_T *InterruptRegisters)
1691 {
1692 BusLogic_CCB_T *FirstCompletedCCB = NULL, *LastCompletedCCB = NULL;
1693 BusLogic_HostAdapter_T *HostAdapter;
1694 int HostAdapterResetPendingCount = 0;
1695
1696
1697
1698
1699
1700
1701 for (HostAdapter = BusLogic_RegisteredHostAdapters;
1702 HostAdapter != NULL;
1703 HostAdapter = HostAdapter->Next)
1704 {
1705 unsigned char InterruptRegister;
1706
1707
1708
1709 BusLogic_LockHostAdapterID(HostAdapter);
1710
1711
1712
1713 InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
1714 if (InterruptRegister & BusLogic_InterruptValid)
1715 {
1716
1717
1718
1719
1720 BusLogic_WriteControlRegister(HostAdapter, BusLogic_InterruptReset);
1721
1722
1723
1724
1725
1726
1727 if (InterruptRegister & BusLogic_SCSIResetState)
1728 {
1729 HostAdapter->HostAdapterResetPending = true;
1730 HostAdapterResetPendingCount++;
1731 }
1732 else if (InterruptRegister & BusLogic_IncomingMailboxLoaded)
1733 {
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748 BusLogic_IncomingMailbox_T *NextIncomingMailbox =
1749 HostAdapter->NextIncomingMailbox;
1750 while (NextIncomingMailbox->CompletionCode !=
1751 BusLogic_IncomingMailboxFree)
1752 {
1753 BusLogic_CCB_T *CCB = NextIncomingMailbox->CCB;
1754 BusLogic_CompletionCode_T MailboxCompletionCode =
1755 NextIncomingMailbox->CompletionCode;
1756 if (MailboxCompletionCode != BusLogic_AbortedCommandNotFound)
1757 {
1758
1759
1760
1761
1762 CCB->Status = BusLogic_CCB_Completed;
1763 CCB->MailboxCompletionCode = MailboxCompletionCode;
1764 CCB->Next = NULL;
1765 if (FirstCompletedCCB == NULL)
1766 {
1767 FirstCompletedCCB = CCB;
1768 LastCompletedCCB = CCB;
1769 }
1770 else
1771 {
1772 LastCompletedCCB->Next = CCB;
1773 LastCompletedCCB = CCB;
1774 }
1775 }
1776 else printk("scsi%d: Aborted CCB #%d Not Found\n",
1777 HostAdapter->HostNumber, CCB->SerialNumber);
1778 NextIncomingMailbox->CompletionCode =
1779 BusLogic_IncomingMailboxFree;
1780 if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
1781 NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
1782 }
1783 HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
1784 }
1785 else if (InterruptRegister & BusLogic_CommandComplete)
1786 HostAdapter->HostAdapterCommandCompleted = true;
1787 }
1788
1789
1790
1791 BusLogic_UnlockHostAdapterID(HostAdapter);
1792 }
1793
1794
1795
1796 sti();
1797
1798
1799
1800 if (HostAdapterResetPendingCount > 0)
1801 for (HostAdapter = BusLogic_RegisteredHostAdapters;
1802 HostAdapter != NULL;
1803 HostAdapter = HostAdapter->Next)
1804 if (HostAdapter->HostAdapterResetPending)
1805 {
1806 BusLogic_ResetHostAdapter(HostAdapter, NULL);
1807 HostAdapter->HostAdapterResetPending = false;
1808 scsi_mark_host_bus_reset(HostAdapter->SCSI_Host);
1809 }
1810
1811
1812
1813
1814 while (FirstCompletedCCB != NULL)
1815 {
1816 BusLogic_CCB_T *CCB = FirstCompletedCCB;
1817 SCSI_Command_T *Command = CCB->Command;
1818 FirstCompletedCCB = FirstCompletedCCB->Next;
1819 HostAdapter = CCB->HostAdapter;
1820
1821
1822
1823
1824
1825
1826 if (CCB->Opcode == BusLogic_SCSIBusDeviceReset)
1827 {
1828 printk("scsi%d: Bus Device Reset CCB #%d to Target %d Completed\n",
1829 HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
1830 if (Command != NULL) Command->result = DID_RESET << 16;
1831 }
1832 else
1833
1834
1835
1836
1837 switch (CCB->MailboxCompletionCode)
1838 {
1839 case BusLogic_IncomingMailboxFree:
1840 case BusLogic_AbortedCommandNotFound:
1841 printk("scsi%d: CCB #%d Impossible State\n",
1842 HostAdapter->HostNumber, CCB->SerialNumber);
1843 break;
1844 case BusLogic_CommandCompletedWithoutError:
1845 HostAdapter->CommandSuccessfulFlag[CCB->TargetID] = true;
1846 Command->result = DID_OK << 16;
1847 break;
1848 case BusLogic_CommandAbortedAtHostRequest:
1849 printk("scsi%d: CCB #%d Aborted\n",
1850 HostAdapter->HostNumber, CCB->SerialNumber);
1851 Command->result = DID_ABORT << 16;
1852 break;
1853 case BusLogic_CommandCompletedWithError:
1854 Command->result =
1855 BusLogic_ComputeResultCode(CCB->HostAdapterStatus,
1856 CCB->TargetDeviceStatus);
1857 if (BusLogic_TracingOptions & BusLogic_TraceErrors)
1858 if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout)
1859 {
1860 int i;
1861 printk("scsi%d: CCB #%d Target %d: Result %X "
1862 "Host Adapter Status %02X Target Status %02X\n",
1863 HostAdapter->HostNumber, CCB->SerialNumber,
1864 CCB->TargetID, Command->result,
1865 CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
1866 printk("scsi%d: CDB ", HostAdapter->HostNumber);
1867 for (i = 0; i < CCB->CDB_Length; i++)
1868 printk(" %02X", CCB->CDB[i]);
1869 printk("\n");
1870 printk("scsi%d: Sense ", HostAdapter->HostNumber);
1871 for (i = 0; i < CCB->SenseDataLength; i++)
1872 printk(" %02X", (*CCB->SenseDataPointer)[i]);
1873 printk("\n");
1874 }
1875 break;
1876 }
1877
1878
1879
1880 BusLogic_DeallocateCCB(CCB);
1881
1882
1883
1884 if (Command != NULL) Command->scsi_done(Command);
1885 }
1886 }
1887
1888
1889
1890
1891
1892
1893
1894 static boolean BusLogic_WriteOutgoingMailboxEntry(BusLogic_HostAdapter_T
1895 *HostAdapter,
1896 BusLogic_ActionCode_T
1897 ActionCode,
1898 BusLogic_CCB_T *CCB)
1899 {
1900 BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
1901 boolean Result = false;
1902 BusLogic_LockHostAdapter(HostAdapter);
1903 NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
1904 if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree)
1905 {
1906 NextOutgoingMailbox->ActionCode = ActionCode;
1907 NextOutgoingMailbox->CCB = CCB;
1908 CCB->Status = BusLogic_CCB_Active;
1909 BusLogic_StartMailboxScan(HostAdapter);
1910 if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
1911 NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
1912 HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
1913 Result = true;
1914 }
1915 BusLogic_UnlockHostAdapter(HostAdapter);
1916 return Result;
1917 }
1918
1919
1920
1921
1922
1923
1924
1925 int BusLogic_QueueCommand(SCSI_Command_T *Command,
1926 void (*CompletionRoutine)(SCSI_Command_T *))
1927 {
1928 BusLogic_HostAdapter_T *HostAdapter =
1929 (BusLogic_HostAdapter_T *) Command->host->hostdata;
1930 unsigned char *CDB = Command->cmnd;
1931 unsigned char CDB_Length = Command->cmd_len;
1932 unsigned char TargetID = Command->target;
1933 unsigned char LogicalUnit = Command->lun;
1934 void *BufferPointer = Command->request_buffer;
1935 int BufferLength = Command->request_bufflen;
1936 int SegmentCount = Command->use_sg;
1937 BusLogic_CCB_T *CCB;
1938 long EnableTQ;
1939
1940
1941
1942
1943
1944 if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0)
1945 {
1946 Command->result = DID_OK << 16;
1947 CompletionRoutine(Command);
1948 return 0;
1949 }
1950
1951
1952
1953
1954 CCB = BusLogic_AllocateCCB(HostAdapter);
1955 if (CCB == NULL)
1956 {
1957 Command->result = DID_ERROR << 16;
1958 CompletionRoutine(Command);
1959 return 0;
1960 }
1961
1962
1963
1964 if (SegmentCount == 0)
1965 {
1966 CCB->Opcode = BusLogic_InitiatorCCB;
1967 CCB->DataLength = BufferLength;
1968 CCB->DataPointer = BufferPointer;
1969 }
1970 else
1971 {
1972 SCSI_ScatterList_T *ScatterList = (SCSI_ScatterList_T *) BufferPointer;
1973 int Segment;
1974 CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
1975 CCB->DataLength = SegmentCount * sizeof(BusLogic_ScatterGatherSegment_T);
1976 CCB->DataPointer = CCB->ScatterGatherList;
1977 for (Segment = 0; Segment < SegmentCount; Segment++)
1978 {
1979 CCB->ScatterGatherList[Segment].SegmentByteCount =
1980 ScatterList[Segment].length;
1981 CCB->ScatterGatherList[Segment].SegmentDataPointer =
1982 ScatterList[Segment].address;
1983 }
1984 }
1985 switch (CDB[0])
1986 {
1987 case READ_6:
1988 case READ_10:
1989 CCB->DataDirection = BusLogic_DataInLengthChecked;
1990 HostAdapter->ReadWriteOperationCount[TargetID]++;
1991 break;
1992 case WRITE_6:
1993 case WRITE_10:
1994 CCB->DataDirection = BusLogic_DataOutLengthChecked;
1995 HostAdapter->ReadWriteOperationCount[TargetID]++;
1996 break;
1997 default:
1998 CCB->DataDirection = BusLogic_UncheckedDataTransfer;
1999 break;
2000 }
2001 CCB->CDB_Length = CDB_Length;
2002 CCB->SenseDataLength = sizeof(Command->sense_buffer);
2003 CCB->TargetID = TargetID;
2004 CCB->LogicalUnit = LogicalUnit;
2005
2006
2007
2008
2009
2010 if (HostAdapter->HostWideSCSI)
2011 {
2012 CCB->TagEnable = LogicalUnit >> 5;
2013 CCB->WideModeTagEnable = false;
2014 }
2015 else CCB->TagEnable = false;
2016
2017
2018
2019
2020
2021
2022 if ((HostAdapter->TaggedQueuingPermitted & (1 << TargetID)) &&
2023 Command->device->tagged_supported &&
2024 (EnableTQ = HostAdapter->ReadWriteOperationCount[TargetID] - 5) >= 0)
2025 {
2026 if (EnableTQ == 0)
2027 printk("scsi%d: Tagged Queuing now active for Target %d\n",
2028 HostAdapter->HostNumber, TargetID);
2029 if (HostAdapter->HostWideSCSI)
2030 {
2031 CCB->WideModeTagEnable = true;
2032 CCB->WideModeQueueTag = BusLogic_SimpleQueueTag;
2033 }
2034 else
2035 {
2036 CCB->TagEnable = true;
2037 CCB->QueueTag = BusLogic_SimpleQueueTag;
2038 }
2039 }
2040 memcpy(CCB->CDB, CDB, CDB_Length);
2041 CCB->SenseDataPointer = (SCSI_SenseData_T *) &Command->sense_buffer;
2042 CCB->Command = Command;
2043 Command->scsi_done = CompletionRoutine;
2044
2045
2046
2047
2048 if (!(BusLogic_WriteOutgoingMailboxEntry(
2049 HostAdapter, BusLogic_MailboxStartCommand, CCB)))
2050 {
2051 printk("scsi%d: cannot write Outgoing Mailbox Entry\n",
2052 HostAdapter->HostNumber);
2053 BusLogic_DeallocateCCB(CCB);
2054 Command->result = DID_ERROR << 16;
2055 CompletionRoutine(Command);
2056 }
2057 return 0;
2058 }
2059
2060
2061
2062
2063
2064
2065 int BusLogic_AbortCommand(SCSI_Command_T *Command)
2066 {
2067 BusLogic_HostAdapter_T *HostAdapter =
2068 (BusLogic_HostAdapter_T *) Command->host->hostdata;
2069 unsigned char InterruptRegister;
2070 BusLogic_CCB_T *CCB;
2071 int Result;
2072
2073
2074
2075
2076
2077
2078 InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
2079 if (InterruptRegister & BusLogic_InterruptValid)
2080 {
2081 unsigned long ProcessorFlags;
2082 printk("scsi%d: Recovering Lost Interrupt for IRQ Channel %d\n",
2083 HostAdapter->HostNumber, HostAdapter->IRQ_Channel);
2084 save_flags(ProcessorFlags);
2085 cli();
2086 BusLogic_InterruptHandler(HostAdapter->IRQ_Channel, NULL);
2087 restore_flags(ProcessorFlags);
2088 return SCSI_ABORT_SNOOZE;
2089 }
2090
2091
2092
2093 BusLogic_LockHostAdapter(HostAdapter);
2094 Result = SCSI_ABORT_NOT_RUNNING;
2095 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2096 if (CCB->Command == Command)
2097 {
2098 if (CCB->Status == BusLogic_CCB_Active)
2099 if ((HostAdapter->HostWideSCSI && CCB->WideModeTagEnable &&
2100 CCB->WideModeQueueTag != BusLogic_SimpleQueueTag) ||
2101 (!HostAdapter->HostWideSCSI && CCB->TagEnable &&
2102 CCB->QueueTag != BusLogic_SimpleQueueTag))
2103 {
2104
2105
2106
2107
2108 Result = SCSI_ABORT_BUSY;
2109 }
2110 else
2111 {
2112
2113
2114
2115 if (BusLogic_WriteOutgoingMailboxEntry(
2116 HostAdapter, BusLogic_MailboxAbortCommand, CCB))
2117 {
2118 printk("scsi%d: Aborting CCB #%d\n",
2119 HostAdapter->HostNumber, CCB->SerialNumber);
2120 Result = SCSI_ABORT_PENDING;
2121 }
2122 else Result = SCSI_ABORT_BUSY;
2123 }
2124 break;
2125 }
2126 BusLogic_UnlockHostAdapter(HostAdapter);
2127 return Result;
2128 }
2129
2130
2131
2132
2133
2134
2135
2136
2137 static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter,
2138 SCSI_Command_T *Command)
2139 {
2140 BusLogic_CCB_T *CCB;
2141 if (Command == NULL)
2142 printk("scsi%d: Resetting %s due to SCSI Reset State Interrupt\n",
2143 HostAdapter->HostNumber, HostAdapter->BoardName);
2144 else printk("scsi%d: Resetting %s due to Target %d\n",
2145 HostAdapter->HostNumber, HostAdapter->BoardName, Command->target);
2146
2147
2148
2149 BusLogic_LockHostAdapter(HostAdapter);
2150 if (!(BusLogic_HardResetHostAdapter(HostAdapter) &&
2151 BusLogic_InitializeHostAdapter(HostAdapter)))
2152 {
2153 printk("scsi%d: Resetting %s Failed\n",
2154 HostAdapter->HostNumber, HostAdapter->BoardName);
2155 BusLogic_UnlockHostAdapter(HostAdapter);
2156 return SCSI_RESET_ERROR;
2157 }
2158 BusLogic_UnlockHostAdapter(HostAdapter);
2159
2160
2161
2162
2163
2164 BusLogic_Delay(HostAdapter->BusSettleTime);
2165
2166
2167
2168 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2169 if (CCB->Status == BusLogic_CCB_Active)
2170 {
2171 SCSI_Command_T *ActiveCommand = CCB->Command;
2172 if (ActiveCommand == Command) Command = NULL;
2173 BusLogic_DeallocateCCB(CCB);
2174 if (ActiveCommand != NULL)
2175 {
2176 ActiveCommand->result = DID_RESET << 16;
2177 ActiveCommand->scsi_done(ActiveCommand);
2178 }
2179 }
2180 if (Command != NULL)
2181 {
2182 Command->result = DID_RESET << 16;
2183 Command->scsi_done(Command);
2184 }
2185 return SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
2186 }
2187
2188
2189
2190
2191
2192
2193
2194 static int BusLogic_BusDeviceReset(BusLogic_HostAdapter_T *HostAdapter,
2195 SCSI_Command_T *Command)
2196 {
2197 BusLogic_CCB_T *CCB = BusLogic_AllocateCCB(HostAdapter), *XCCB;
2198 unsigned char TargetID = Command->target;
2199
2200
2201
2202
2203 if (CCB == NULL)
2204 return BusLogic_ResetHostAdapter(HostAdapter, Command);
2205 printk("scsi%d: Sending Bus Device Reset CCB #%d to Target %d\n",
2206 HostAdapter->HostNumber, CCB->SerialNumber, TargetID);
2207 CCB->Opcode = BusLogic_SCSIBusDeviceReset;
2208 CCB->TargetID = TargetID;
2209 CCB->Command = Command;
2210
2211
2212
2213
2214
2215
2216
2217
2218 BusLogic_LockHostAdapter(HostAdapter);
2219 for (XCCB = HostAdapter->All_CCBs; XCCB != NULL; XCCB = XCCB->NextAll)
2220 if (XCCB->Status == BusLogic_CCB_Active && XCCB->Command == Command)
2221 {
2222 CCB->Command = NULL;
2223 break;
2224 }
2225 BusLogic_UnlockHostAdapter(HostAdapter);
2226
2227
2228
2229
2230
2231 if (!(BusLogic_WriteOutgoingMailboxEntry(
2232 HostAdapter, BusLogic_MailboxStartCommand, CCB)))
2233 {
2234 printk("scsi%d: cannot write Outgoing Mailbox Entry for "
2235 "Bus Device Reset\n", HostAdapter->HostNumber);
2236 BusLogic_DeallocateCCB(CCB);
2237 return BusLogic_ResetHostAdapter(HostAdapter, Command);
2238 }
2239 HostAdapter->ReadWriteOperationCount[TargetID] = 0;
2240 return SCSI_RESET_PENDING;
2241 }
2242
2243
2244
2245
2246
2247
2248 int BusLogic_ResetCommand(SCSI_Command_T *Command)
2249 {
2250 BusLogic_HostAdapter_T *HostAdapter =
2251 (BusLogic_HostAdapter_T *) Command->host->hostdata;
2252 unsigned char TargetID = Command->target;
2253 unsigned char ErrorRecoveryOption =
2254 HostAdapter->ErrorRecoveryOption[TargetID];
2255 if (ErrorRecoveryOption == BusLogic_ErrorRecoveryDefault)
2256 if (Command->host->suggest_bus_reset)
2257 ErrorRecoveryOption = BusLogic_ErrorRecoveryHardReset;
2258 else ErrorRecoveryOption = BusLogic_ErrorRecoveryBusDeviceReset;
2259 switch (ErrorRecoveryOption)
2260 {
2261 case BusLogic_ErrorRecoveryHardReset:
2262 return BusLogic_ResetHostAdapter(HostAdapter, Command);
2263 case BusLogic_ErrorRecoveryBusDeviceReset:
2264 if (HostAdapter->CommandSuccessfulFlag[TargetID])
2265 {
2266 HostAdapter->CommandSuccessfulFlag[TargetID] = false;
2267 return BusLogic_BusDeviceReset(HostAdapter, Command);
2268 }
2269 else return BusLogic_ResetHostAdapter(HostAdapter, Command);
2270 }
2271 printk("scsi%d: Error Recovery Suppressed\n", HostAdapter->HostNumber);
2272 return SCSI_RESET_PUNT;
2273 }
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293 int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device,
2294 int *Parameters)
2295 {
2296 BusLogic_HostAdapter_T *HostAdapter =
2297 (BusLogic_HostAdapter_T *) Disk->device->host->hostdata;
2298 BIOS_DiskParameters_T *DiskParameters = (BIOS_DiskParameters_T *) Parameters;
2299 if (HostAdapter->ExtendedTranslation &&
2300 Disk->capacity >= 2*1024*1024 )
2301 if (Disk->capacity >= 4*1024*1024 )
2302 {
2303 DiskParameters->Heads = 255;
2304 DiskParameters->Sectors = 63;
2305 }
2306 else
2307 {
2308 DiskParameters->Heads = 128;
2309 DiskParameters->Sectors = 32;
2310 }
2311 else
2312 {
2313 DiskParameters->Heads = 64;
2314 DiskParameters->Sectors = 32;
2315 }
2316 DiskParameters->Cylinders =
2317 Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
2318 return 0;
2319 }
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422 void BusLogic_Setup(char *Strings, int *Integers)
2423 {
2424 BusLogic_CommandLineEntry_T *CommandLineEntry =
2425 &BusLogic_CommandLineEntries[BusLogic_CommandLineEntryCount++];
2426 static int ProbeListIndex = 0;
2427 int IntegerCount = Integers[0], TargetID, i;
2428 CommandLineEntry->IO_Address = 0;
2429 CommandLineEntry->Concurrency = 0;
2430 CommandLineEntry->BusSettleTime = 0;
2431 CommandLineEntry->TaggedQueuingPermitted = 0;
2432 CommandLineEntry->TaggedQueuingPermittedMask = 0;
2433 memset(CommandLineEntry->ErrorRecoveryOption,
2434 BusLogic_ErrorRecoveryDefault,
2435 sizeof(CommandLineEntry->ErrorRecoveryOption));
2436 if (IntegerCount > 4)
2437 printk("BusLogic: Unexpected Command Line Integers ignored\n");
2438 if (IntegerCount >= 1)
2439 {
2440 unsigned short IO_Address = Integers[1];
2441 if (IO_Address > 0)
2442 {
2443 for (i = 0; ; i++)
2444 if (BusLogic_IO_StandardAddresses[i] == 0)
2445 {
2446 printk("BusLogic: Invalid Command Line Entry "
2447 "(illegal I/O Address 0x%X)\n", IO_Address);
2448 return;
2449 }
2450 else if (i < ProbeListIndex &&
2451 IO_Address == BusLogic_IO_AddressProbeList[i])
2452 {
2453 printk("BusLogic: Invalid Command Line Entry "
2454 "(duplicate I/O Address 0x%X)\n", IO_Address);
2455 return;
2456 }
2457 else if (IO_Address == BusLogic_IO_StandardAddresses[i]) break;
2458 BusLogic_IO_AddressProbeList[ProbeListIndex++] = IO_Address;
2459 BusLogic_IO_AddressProbeList[ProbeListIndex] = 0;
2460 }
2461 CommandLineEntry->IO_Address = IO_Address;
2462 }
2463 if (IntegerCount >= 2)
2464 {
2465 unsigned short Concurrency = Integers[2];
2466 if (Concurrency > BusLogic_MailboxCount)
2467 {
2468 printk("BusLogic: Invalid Command Line Entry "
2469 "(illegal Concurrency %d)\n", Concurrency);
2470 return;
2471 }
2472 CommandLineEntry->Concurrency = Concurrency;
2473 }
2474 if (IntegerCount >= 3)
2475 CommandLineEntry->BusSettleTime = Integers[3];
2476 if (IntegerCount >= 4)
2477 BusLogic_TracingOptions |= Integers[4];
2478 if (!(BusLogic_CommandLineEntryCount == 0 || ProbeListIndex == 0 ||
2479 BusLogic_CommandLineEntryCount == ProbeListIndex))
2480 {
2481 printk("BusLogic: Invalid Command Line Entry "
2482 "(all or no I/O Addresses must be specified)\n");
2483 return;
2484 }
2485 if (Strings == NULL) return;
2486 if (strncmp(Strings, "TQ:", 3) == 0)
2487 {
2488 Strings += 3;
2489 if (strncmp(Strings, "Default", 7) == 0)
2490 Strings += 7;
2491 else if (strncmp(Strings, "Enable", 6) == 0)
2492 {
2493 Strings += 6;
2494 CommandLineEntry->TaggedQueuingPermitted = 0xFFFF;
2495 CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF;
2496 }
2497 else if (strncmp(Strings, "Disable", 7) == 0)
2498 {
2499 Strings += 7;
2500 CommandLineEntry->TaggedQueuingPermitted = 0x0000;
2501 CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF;
2502 }
2503 else
2504 for (TargetID = 0; TargetID < BusLogic_MaxTargetIDs; TargetID++)
2505 switch (*Strings++)
2506 {
2507 case 'Y':
2508 CommandLineEntry->TaggedQueuingPermitted |= 1 << TargetID;
2509 CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID;
2510 break;
2511 case 'N':
2512 CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID;
2513 break;
2514 case 'X':
2515 break;
2516 default:
2517 Strings--;
2518 TargetID = BusLogic_MaxTargetIDs;
2519 break;
2520 }
2521 }
2522 if (*Strings == ',') Strings++;
2523 if (strncmp(Strings, "ER:", 3) == 0)
2524 {
2525 Strings += 3;
2526 if (strncmp(Strings, "Default", 7) == 0)
2527 Strings += 7;
2528 else if (strncmp(Strings, "HardReset", 9) == 0)
2529 {
2530 Strings += 9;
2531 memset(CommandLineEntry->ErrorRecoveryOption,
2532 BusLogic_ErrorRecoveryHardReset,
2533 sizeof(CommandLineEntry->ErrorRecoveryOption));
2534 }
2535 else if (strncmp(Strings, "BusDeviceReset", 14) == 0)
2536 {
2537 Strings += 14;
2538 memset(CommandLineEntry->ErrorRecoveryOption,
2539 BusLogic_ErrorRecoveryBusDeviceReset,
2540 sizeof(CommandLineEntry->ErrorRecoveryOption));
2541 }
2542 else if (strncmp(Strings, "None", 4) == 0)
2543 {
2544 Strings += 4;
2545 memset(CommandLineEntry->ErrorRecoveryOption,
2546 BusLogic_ErrorRecoveryNone,
2547 sizeof(CommandLineEntry->ErrorRecoveryOption));
2548 }
2549 else
2550 for (TargetID = 0; TargetID < BusLogic_MaxTargetIDs; TargetID++)
2551 switch (*Strings++)
2552 {
2553 case 'D':
2554 CommandLineEntry->ErrorRecoveryOption[TargetID] =
2555 BusLogic_ErrorRecoveryDefault;
2556 break;
2557 case 'H':
2558 CommandLineEntry->ErrorRecoveryOption[TargetID] =
2559 BusLogic_ErrorRecoveryHardReset;
2560 break;
2561 case 'B':
2562 CommandLineEntry->ErrorRecoveryOption[TargetID] =
2563 BusLogic_ErrorRecoveryBusDeviceReset;
2564 break;
2565 case 'N':
2566 CommandLineEntry->ErrorRecoveryOption[TargetID] =
2567 BusLogic_ErrorRecoveryNone;
2568 break;
2569 default:
2570 Strings--;
2571 TargetID = BusLogic_MaxTargetIDs;
2572 break;
2573 }
2574 }
2575 if (*Strings != '\0')
2576 printk("BusLogic: Unexpected Command Line String '%s' ignored\n", Strings);
2577 }