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_WriteOutgoingMailbox
- 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
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
54
55
56
57 static int
58 BusLogic_CommandLineEntryCount = 0;
59
60
61
62
63
64
65
66
67 static BusLogic_CommandLineEntry_T
68 BusLogic_CommandLineEntries[BusLogic_MaxHostAdapters];
69
70
71
72
73
74
75
76 static int
77 BusLogic_GlobalOptions = 0;
78
79
80
81
82
83
84
85 static BusLogic_HostAdapter_T
86 *BusLogic_RegisteredHostAdapters = NULL;
87
88
89
90
91
92
93
94 static unsigned short
95 BusLogic_IO_StandardAddresses[] =
96 { 0x330, 0x334, 0x230, 0x234, 0x130, 0x134, 0 };
97
98
99
100
101
102
103
104
105
106 static unsigned short
107 BusLogic_IO_AddressProbeList[BusLogic_IO_MaxProbeAddresses+1] = { 0 };
108
109
110
111
112
113
114
115
116
117 static short
118 BusLogic_IRQ_UsageCount[7] = { 0 };
119
120
121
122
123
124
125
126
127 static char
128 *BusLogic_CommandFailureReason;
129
130
131
132
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
142
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 <lnz@dandelion.com>\n");
152 DriverAnnouncementPrinted = true;
153 }
154
155
156
157
158
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
171
172
173
174
175
176 static void BusLogic_InitializeAddressProbeList(void)
177 {
178 int DestinationIndex = 0, SourceIndex = 0;
179
180
181
182
183 if (BusLogic_IO_AddressProbeList[0] != 0) return;
184 #ifdef CONFIG_PCI
185
186
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
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
221
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
241
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
261
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
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
308
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
349
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
366
367
368
369
370
371
372
373
374
375
376
377
378
379
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
396
397 if (ReplyLength > 0)
398 memset(ReplyData, 0, ReplyLength);
399
400
401
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
415
416 HostAdapter->HostAdapterCommandCompleted = false;
417 BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);
418
419
420
421 TimeoutCounter = 10000;
422 while (ParameterLength > 0 && --TimeoutCounter >= 0)
423 {
424
425
426
427
428
429
430
431
432
433
434
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
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
461
462 switch (OperationCode)
463 {
464 case BusLogic_InquireInstalledDevicesID0to7:
465 case BusLogic_InquireInstalledDevicesID8to15:
466
467 TimeoutCounter = loops_per_sec << 2;
468 break;
469 default:
470
471 TimeoutCounter = loops_per_sec >> 4;
472 break;
473 }
474
475
476
477
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
494
495
496
497
498
499 if (OperationCode == BusLogic_TestCommandCompleteInterrupt)
500 udelay(10000);
501
502
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
518
519 if (StatusRegister & BusLogic_CommandInvalid)
520 {
521
522
523
524
525
526
527
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
542
543 BusLogic_CommandFailureReason = "Excess Parameters Supplied";
544 if (ParameterLength > 0) return -1;
545
546
547
548 BusLogic_CommandFailureReason = NULL;
549 return ReplyBytes;
550 }
551
552
553
554
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
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
580
581
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
590
591
592
593
594
595
596
597
598
599
600
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
609
610 return true;
611 }
612
613
614
615
616
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
627
628
629 BusLogic_WriteControlRegister(HostAdapter, BusLogic_HardReset);
630
631
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
644
645
646
647 udelay(100);
648
649
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
662
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
678
679
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
696
697 return true;
698 }
699
700
701
702
703
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
714
715
716
717
718
719
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
739
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
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
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
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
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
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
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
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
826
827
828
829
830
831
832
833
834
835
836
837
838
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
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
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
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
892
893 HostAdapter->SCSI_ID = Configuration.HostAdapterID;
894
895
896
897
898 HostAdapter->SynchronousInitiation =
899 SetupInformation.SynchronousInitiationEnabled;
900 HostAdapter->ParityChecking = SetupInformation.ParityCheckEnabled;
901
902
903
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
932
933
934 GeometryRegister = BusLogic_ReadGeometryRegister(HostAdapter);
935 if (GeometryRegister & BusLogic_ExtendedTranslationEnabled)
936 HostAdapter->ExtendedTranslation = true;
937
938
939
940
941
942
943 if (HostAdapter->FirmwareVersion[0] >= '4')
944 HostAdapter->DisconnectPermitted =
945 (SetupInformation.DisconnectPermittedID8to15 << 8)
946 | SetupInformation.DisconnectPermittedID0to7;
947 else HostAdapter->DisconnectPermitted = 0xFF;
948
949
950
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
976
977
978
979 HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
980
981
982
983
984
985
986
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
995
996
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
1006
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
1014
1015 if (HostAdapter->CommandLineEntry != NULL)
1016 HostAdapter->LocalOptions = HostAdapter->CommandLineEntry->LocalOptions;
1017
1018
1019
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
1030
1031
1032
1033
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
1053
1054
1055
1056 TaggedQueuingPermittedDefault &= HostAdapter->DisconnectPermitted;
1057
1058
1059
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
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
1141
1142 return true;
1143 }
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155 static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter,
1156 SCSI_Host_T *Host)
1157 {
1158
1159
1160
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, NULL) < 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
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
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
1222
1223 return true;
1224 }
1225
1226
1227
1228
1229
1230
1231
1232 static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *HostAdapter)
1233 {
1234
1235
1236
1237 if (HostAdapter->IRQ_ChannelAcquired)
1238 if (--BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9] == 0)
1239 free_irq(HostAdapter->IRQ_Channel, NULL);
1240
1241
1242
1243 if (HostAdapter->DMA_ChannelAcquired)
1244 free_dma(HostAdapter->DMA_Channel);
1245 }
1246
1247
1248
1249
1250
1251
1252
1253
1254
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
1264
1265 for (i = 0; i < TestCount; i++)
1266 BusLogic_Command(HostAdapter, BusLogic_TestCommandCompleteInterrupt,
1267 NULL, 0, NULL, 0);
1268
1269
1270
1271
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
1291
1292 return true;
1293 }
1294
1295
1296
1297
1298
1299
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
1311
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
1321
1322 memset(HostAdapter->OutgoingMailboxes, 0,
1323 sizeof(HostAdapter->OutgoingMailboxes));
1324 memset(HostAdapter->IncomingMailboxes, 0,
1325 sizeof(HostAdapter->IncomingMailboxes));
1326
1327
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
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
1348
1349
1350
1351
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
1363
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
1375
1376
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
1395
1396 printk("scsi%d: *** %s Initialized Successfully ***\n",
1397 HostAdapter->HostNumber, HostAdapter->BoardName);
1398
1399
1400
1401 return true;
1402 }
1403
1404
1405
1406
1407
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
1421
1422
1423
1424 BusLogic_Delay(HostAdapter->BusSettleTime);
1425
1426
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
1436
1437
1438
1439
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
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
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
1483
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
1536
1537 return true;
1538 }
1539
1540
1541
1542
1543
1544
1545
1546
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
1564
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
1573
1574 if (check_region(HostAdapter->IO_Address, BusLogic_IO_PortCount) < 0)
1575 continue;
1576
1577
1578
1579 if (!BusLogic_ProbeHostAdapter(HostAdapter)) continue;
1580
1581
1582
1583
1584 if (!BusLogic_HardResetHostAdapter(HostAdapter)) continue;
1585
1586
1587
1588 if (!BusLogic_CheckHostAdapter(HostAdapter)) continue;
1589
1590
1591
1592
1593 if (CommandLineEntryIndex < BusLogic_CommandLineEntryCount &&
1594 BusLogic_CommandLineEntries[CommandLineEntryIndex].IO_Address == 0)
1595 HostAdapter->CommandLineEntry =
1596 &BusLogic_CommandLineEntries[CommandLineEntryIndex++];
1597
1598
1599
1600
1601 BusLogic_AnnounceDriver();
1602
1603
1604
1605
1606
1607
1608
1609
1610 request_region(HostAdapter->IO_Address, BusLogic_IO_PortCount,
1611 "BusLogic");
1612
1613
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
1624
1625
1626
1627
1628
1629
1630
1631 BusLogic_RegisterHostAdapter(HostAdapter);
1632
1633
1634
1635
1636
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
1647
1648
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
1659
1660
1661
1662
1663
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
1677
1678
1679
1680
1681 int BusLogic_ReleaseHostAdapter(SCSI_Host_T *Host)
1682 {
1683 BusLogic_HostAdapter_T *HostAdapter =
1684 (BusLogic_HostAdapter_T *) Host->hostdata;
1685
1686
1687
1688
1689 BusLogic_DestroyCCBs(HostAdapter);
1690 BusLogic_ReleaseResources(HostAdapter);
1691
1692
1693
1694 release_region(HostAdapter->IO_Address, BusLogic_IO_PortCount);
1695
1696
1697
1698 BusLogic_UnregisterHostAdapter(HostAdapter);
1699 return 0;
1700 }
1701
1702
1703
1704
1705
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
1762
1763
1764
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
1775
1776
1777
1778
1779 for (HostAdapter = BusLogic_RegisteredHostAdapters;
1780 HostAdapter != NULL;
1781 HostAdapter = HostAdapter->Next)
1782 {
1783 unsigned char InterruptRegister;
1784
1785
1786
1787 BusLogic_LockHostAdapterID(HostAdapter);
1788
1789
1790
1791 InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
1792 if (InterruptRegister & BusLogic_InterruptValid)
1793 {
1794
1795
1796
1797
1798 BusLogic_WriteControlRegister(HostAdapter, BusLogic_InterruptReset);
1799
1800
1801
1802
1803
1804
1805 if (InterruptRegister & BusLogic_SCSIResetState)
1806 {
1807 HostAdapter->HostAdapterResetPending = true;
1808 HostAdapterResetPendingCount++;
1809 }
1810 else if (InterruptRegister & BusLogic_IncomingMailboxLoaded)
1811 {
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
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
1839
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
1860
1861
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
1882
1883 BusLogic_UnlockHostAdapterID(HostAdapter);
1884 }
1885
1886
1887
1888 sti();
1889
1890
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
1904
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
1914
1915
1916
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
1927
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
1971
1972 BusLogic_DeallocateCCB(CCB);
1973
1974
1975
1976 if (Command != NULL) Command->scsi_done(Command);
1977 }
1978 }
1979
1980
1981
1982
1983
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
2000
2001
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
2020
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
2039
2040
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
2050
2051
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
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
2108
2109
2110
2111 if (HostAdapter->HostWideSCSI)
2112 {
2113 CCB->TagEnable = LogicalUnit >> 5;
2114 CCB->WideModeTagEnable = false;
2115 }
2116 else CCB->TagEnable = false;
2117
2118
2119
2120
2121
2122
2123
2124
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
2137
2138
2139
2140
2141
2142
2143
2144
2145
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
2171
2172
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
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
2201
2202
2203
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
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
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
2239
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
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
2273
2274
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
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
2301
2302
2303
2304 BusLogic_Delay(HostAdapter->BusSettleTime);
2305
2306
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
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
2332
2333 if (Command != NULL)
2334 {
2335 Command->result = DID_RESET << 16;
2336 Command->scsi_done(Command);
2337 }
2338
2339
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
2358
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
2368
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
2379
2380
2381
2382
2383
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
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
2406
2407
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
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
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
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 )
2481 if (Disk->capacity >= 4*1024*1024 )
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
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
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
2770
2771
2772
2773 #ifdef MODULE
2774
2775 SCSI_Host_Template_T driver_template = BUSLOGIC;
2776
2777 #include "scsi_module.c"
2778
2779 #endif