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 void *DeviceIdentifier,
1769 Registers_T *InterruptRegisters)
1770 {
1771 BusLogic_CCB_T *FirstCompletedCCB = NULL, *LastCompletedCCB = NULL;
1772 BusLogic_HostAdapter_T *HostAdapter;
1773 int HostAdapterResetPendingCount = 0;
1774
1775
1776
1777
1778
1779
1780 for (HostAdapter = BusLogic_RegisteredHostAdapters;
1781 HostAdapter != NULL;
1782 HostAdapter = HostAdapter->Next)
1783 {
1784 unsigned char InterruptRegister;
1785
1786
1787
1788 BusLogic_LockHostAdapterID(HostAdapter);
1789
1790
1791
1792 InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
1793 if (InterruptRegister & BusLogic_InterruptValid)
1794 {
1795
1796
1797
1798
1799 BusLogic_WriteControlRegister(HostAdapter, BusLogic_InterruptReset);
1800
1801
1802
1803
1804
1805
1806 if (InterruptRegister & BusLogic_SCSIResetState)
1807 {
1808 HostAdapter->HostAdapterResetPending = true;
1809 HostAdapterResetPendingCount++;
1810 }
1811 else if (InterruptRegister & BusLogic_IncomingMailboxLoaded)
1812 {
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827 BusLogic_IncomingMailbox_T *NextIncomingMailbox =
1828 HostAdapter->NextIncomingMailbox;
1829 BusLogic_CompletionCode_T MailboxCompletionCode;
1830 while ((MailboxCompletionCode =
1831 NextIncomingMailbox->CompletionCode) !=
1832 BusLogic_IncomingMailboxFree)
1833 {
1834 BusLogic_CCB_T *CCB = NextIncomingMailbox->CCB;
1835 if (MailboxCompletionCode != BusLogic_AbortedCommandNotFound)
1836 if (CCB->Status == BusLogic_CCB_Active)
1837 {
1838
1839
1840
1841
1842 CCB->Status = BusLogic_CCB_Completed;
1843 CCB->MailboxCompletionCode = MailboxCompletionCode;
1844 CCB->Next = NULL;
1845 if (FirstCompletedCCB == NULL)
1846 {
1847 FirstCompletedCCB = CCB;
1848 LastCompletedCCB = CCB;
1849 }
1850 else
1851 {
1852 LastCompletedCCB->Next = CCB;
1853 LastCompletedCCB = CCB;
1854 }
1855 HostAdapter->QueuedOperationCount[CCB->TargetID]--;
1856 }
1857 else
1858 {
1859
1860
1861
1862
1863
1864 printk("scsi%d: Illegal CCB #%d status %d in "
1865 "Incoming Mailbox\n", HostAdapter->HostNumber,
1866 CCB->SerialNumber, CCB->Status);
1867 }
1868 else printk("scsi%d: Aborted CCB #%d to Target %d "
1869 "Not Found\n", HostAdapter->HostNumber,
1870 CCB->SerialNumber, CCB->TargetID);
1871 NextIncomingMailbox->CompletionCode =
1872 BusLogic_IncomingMailboxFree;
1873 if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
1874 NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
1875 }
1876 HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
1877 }
1878 else if (InterruptRegister & BusLogic_CommandComplete)
1879 HostAdapter->HostAdapterCommandCompleted = true;
1880 }
1881
1882
1883
1884 BusLogic_UnlockHostAdapterID(HostAdapter);
1885 }
1886
1887
1888
1889 sti();
1890
1891
1892
1893 if (HostAdapterResetPendingCount > 0)
1894 for (HostAdapter = BusLogic_RegisteredHostAdapters;
1895 HostAdapter != NULL;
1896 HostAdapter = HostAdapter->Next)
1897 if (HostAdapter->HostAdapterResetPending)
1898 {
1899 BusLogic_ResetHostAdapter(HostAdapter, NULL);
1900 HostAdapter->HostAdapterResetPending = false;
1901 scsi_mark_host_bus_reset(HostAdapter->SCSI_Host);
1902 }
1903
1904
1905
1906
1907 while (FirstCompletedCCB != NULL)
1908 {
1909 BusLogic_CCB_T *CCB = FirstCompletedCCB;
1910 SCSI_Command_T *Command = CCB->Command;
1911 FirstCompletedCCB = FirstCompletedCCB->Next;
1912 HostAdapter = CCB->HostAdapter;
1913
1914
1915
1916
1917
1918
1919 if (CCB->Opcode == BusLogic_SCSIBusDeviceReset)
1920 {
1921 printk("scsi%d: Bus Device Reset CCB #%d to Target %d Completed\n",
1922 HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
1923 if (Command != NULL) Command->result = DID_RESET << 16;
1924 }
1925 else
1926
1927
1928
1929
1930 switch (CCB->MailboxCompletionCode)
1931 {
1932 case BusLogic_IncomingMailboxFree:
1933 case BusLogic_AbortedCommandNotFound:
1934 printk("scsi%d: CCB #%d to Target %d Impossible State\n",
1935 HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
1936 break;
1937 case BusLogic_CommandCompletedWithoutError:
1938 HostAdapter->CommandSuccessfulFlag[CCB->TargetID] = true;
1939 Command->result = DID_OK << 16;
1940 break;
1941 case BusLogic_CommandAbortedAtHostRequest:
1942 printk("scsi%d: CCB #%d to Target %d Aborted\n",
1943 HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
1944 Command->result = DID_ABORT << 16;
1945 break;
1946 case BusLogic_CommandCompletedWithError:
1947 Command->result =
1948 BusLogic_ComputeResultCode(CCB->HostAdapterStatus,
1949 CCB->TargetDeviceStatus);
1950 if (BusLogic_GlobalOptions & BusLogic_TraceErrors)
1951 if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout)
1952 {
1953 int i;
1954 printk("scsi%d: CCB #%d Target %d: Result %X "
1955 "Host Adapter Status %02X Target Status %02X\n",
1956 HostAdapter->HostNumber, CCB->SerialNumber,
1957 CCB->TargetID, Command->result,
1958 CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
1959 printk("scsi%d: CDB ", HostAdapter->HostNumber);
1960 for (i = 0; i < CCB->CDB_Length; i++)
1961 printk(" %02X", CCB->CDB[i]);
1962 printk("\n");
1963 printk("scsi%d: Sense ", HostAdapter->HostNumber);
1964 for (i = 0; i < CCB->SenseDataLength; i++)
1965 printk(" %02X", (*CCB->SenseDataPointer)[i]);
1966 printk("\n");
1967 }
1968 break;
1969 }
1970
1971
1972
1973 BusLogic_DeallocateCCB(CCB);
1974
1975
1976
1977 if (Command != NULL) Command->scsi_done(Command);
1978 }
1979 }
1980
1981
1982
1983
1984
1985
1986
1987 static boolean BusLogic_WriteOutgoingMailbox(BusLogic_HostAdapter_T
1988 *HostAdapter,
1989 BusLogic_ActionCode_T ActionCode,
1990 BusLogic_CCB_T *CCB)
1991 {
1992 BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
1993 boolean Result = false;
1994 BusLogic_LockHostAdapter(HostAdapter);
1995 NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
1996 if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree)
1997 {
1998 CCB->Status = BusLogic_CCB_Active;
1999
2000
2001
2002
2003
2004 NextOutgoingMailbox->CCB = CCB;
2005 NextOutgoingMailbox->ActionCode = ActionCode;
2006 BusLogic_StartMailboxScan(HostAdapter);
2007 if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
2008 NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
2009 HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
2010 if (ActionCode == BusLogic_MailboxStartCommand)
2011 HostAdapter->QueuedOperationCount[CCB->TargetID]++;
2012 Result = true;
2013 }
2014 BusLogic_UnlockHostAdapter(HostAdapter);
2015 return Result;
2016 }
2017
2018
2019
2020
2021
2022
2023
2024 int BusLogic_QueueCommand(SCSI_Command_T *Command,
2025 void (*CompletionRoutine)(SCSI_Command_T *))
2026 {
2027 BusLogic_HostAdapter_T *HostAdapter =
2028 (BusLogic_HostAdapter_T *) Command->host->hostdata;
2029 unsigned char *CDB = Command->cmnd;
2030 unsigned char CDB_Length = Command->cmd_len;
2031 unsigned char TargetID = Command->target;
2032 unsigned char LogicalUnit = Command->lun;
2033 void *BufferPointer = Command->request_buffer;
2034 int BufferLength = Command->request_bufflen;
2035 int SegmentCount = Command->use_sg;
2036 BusLogic_CCB_T *CCB;
2037 long EnableTQ;
2038
2039
2040
2041
2042
2043 if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0)
2044 {
2045 Command->result = DID_OK << 16;
2046 CompletionRoutine(Command);
2047 return 0;
2048 }
2049
2050
2051
2052
2053
2054 CCB = BusLogic_AllocateCCB(HostAdapter);
2055 if (CCB == NULL)
2056 {
2057 Command->result = DID_BUS_BUSY << 16;
2058 CompletionRoutine(Command);
2059 return 0;
2060 }
2061
2062
2063
2064 if (SegmentCount == 0)
2065 {
2066 CCB->Opcode = BusLogic_InitiatorCCB;
2067 CCB->DataLength = BufferLength;
2068 CCB->DataPointer = BufferPointer;
2069 }
2070 else
2071 {
2072 SCSI_ScatterList_T *ScatterList = (SCSI_ScatterList_T *) BufferPointer;
2073 int Segment;
2074 CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
2075 CCB->DataLength = SegmentCount * sizeof(BusLogic_ScatterGatherSegment_T);
2076 CCB->DataPointer = CCB->ScatterGatherList;
2077 for (Segment = 0; Segment < SegmentCount; Segment++)
2078 {
2079 CCB->ScatterGatherList[Segment].SegmentByteCount =
2080 ScatterList[Segment].length;
2081 CCB->ScatterGatherList[Segment].SegmentDataPointer =
2082 ScatterList[Segment].address;
2083 }
2084 }
2085 switch (CDB[0])
2086 {
2087 case READ_6:
2088 case READ_10:
2089 CCB->DataDirection = BusLogic_DataInLengthChecked;
2090 HostAdapter->ReadWriteOperationCount[TargetID]++;
2091 break;
2092 case WRITE_6:
2093 case WRITE_10:
2094 CCB->DataDirection = BusLogic_DataOutLengthChecked;
2095 HostAdapter->ReadWriteOperationCount[TargetID]++;
2096 break;
2097 default:
2098 CCB->DataDirection = BusLogic_UncheckedDataTransfer;
2099 break;
2100 }
2101 CCB->CDB_Length = CDB_Length;
2102 CCB->SenseDataLength = sizeof(Command->sense_buffer);
2103 CCB->HostAdapterStatus = 0;
2104 CCB->TargetDeviceStatus = 0;
2105 CCB->TargetID = TargetID;
2106 CCB->LogicalUnit = LogicalUnit;
2107
2108
2109
2110
2111
2112 if (HostAdapter->HostWideSCSI)
2113 {
2114 CCB->TagEnable = LogicalUnit >> 5;
2115 CCB->WideModeTagEnable = false;
2116 }
2117 else CCB->TagEnable = false;
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127 if ((HostAdapter->TaggedQueuingPermitted & (1 << TargetID)) &&
2128 Command->device->tagged_supported &&
2129 (EnableTQ = HostAdapter->ReadWriteOperationCount[TargetID] - 16) >= 0)
2130 {
2131 BusLogic_QueueTag_T QueueTag = BusLogic_SimpleQueueTag;
2132 unsigned long CurrentTime = jiffies;
2133 if (EnableTQ == 0)
2134 printk("scsi%d: Tagged Queuing now active for Target %d\n",
2135 HostAdapter->HostNumber, TargetID);
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148 if (HostAdapter->QueuedOperationCount[TargetID] == 0)
2149 HostAdapter->LastSequencePoint[TargetID] = CurrentTime;
2150 else if (CurrentTime - HostAdapter->LastSequencePoint[TargetID] > 2*HZ)
2151 {
2152 HostAdapter->LastSequencePoint[TargetID] = CurrentTime;
2153 QueueTag = BusLogic_OrderedQueueTag;
2154 }
2155 if (HostAdapter->HostWideSCSI)
2156 {
2157 CCB->WideModeTagEnable = true;
2158 CCB->WideModeQueueTag = QueueTag;
2159 }
2160 else
2161 {
2162 CCB->TagEnable = true;
2163 CCB->QueueTag = QueueTag;
2164 }
2165 }
2166 memcpy(CCB->CDB, CDB, CDB_Length);
2167 CCB->SenseDataPointer = (SCSI_SenseData_T *) &Command->sense_buffer;
2168 CCB->Command = Command;
2169 Command->scsi_done = CompletionRoutine;
2170
2171
2172
2173
2174
2175 if (!(BusLogic_WriteOutgoingMailbox(HostAdapter,
2176 BusLogic_MailboxStartCommand, CCB)))
2177 {
2178 printk("scsi%d: cannot write Outgoing Mailbox\n",
2179 HostAdapter->HostNumber);
2180 BusLogic_DeallocateCCB(CCB);
2181 Command->result = DID_BUS_BUSY << 16;
2182 CompletionRoutine(Command);
2183 }
2184 return 0;
2185 }
2186
2187
2188
2189
2190
2191
2192 int BusLogic_AbortCommand(SCSI_Command_T *Command)
2193 {
2194 BusLogic_HostAdapter_T *HostAdapter =
2195 (BusLogic_HostAdapter_T *) Command->host->hostdata;
2196 unsigned long CommandPID = Command->pid;
2197 unsigned char InterruptRegister;
2198 BusLogic_CCB_T *CCB;
2199 int Result;
2200
2201
2202
2203
2204
2205
2206 InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
2207 if (InterruptRegister & BusLogic_InterruptValid)
2208 {
2209 unsigned long ProcessorFlags;
2210 printk("scsi%d: Recovering Lost/Delayed Interrupt for IRQ Channel %d\n",
2211 HostAdapter->HostNumber, HostAdapter->IRQ_Channel);
2212 save_flags(ProcessorFlags);
2213 cli();
2214 BusLogic_InterruptHandler(HostAdapter->IRQ_Channel, NULL, NULL);
2215 restore_flags(ProcessorFlags);
2216 return SCSI_ABORT_SNOOZE;
2217 }
2218
2219
2220
2221 BusLogic_LockHostAdapter(HostAdapter);
2222 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2223 if (CCB->Command == Command) break;
2224 BusLogic_UnlockHostAdapter(HostAdapter);
2225 if (CCB == NULL)
2226 {
2227 printk("scsi%d: Unable to Abort Command to Target %d - No CCB Found\n",
2228 HostAdapter->HostNumber, Command->target);
2229 return SCSI_ABORT_NOT_RUNNING;
2230 }
2231
2232
2233
2234 printk("scsi%d: Pausing briefly to see if CCB #%d "
2235 "to Target %d will complete\n",
2236 HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
2237 BusLogic_Delay(2);
2238
2239
2240
2241
2242 BusLogic_LockHostAdapter(HostAdapter);
2243 Result = SCSI_ABORT_NOT_RUNNING;
2244 if (CCB->Status == BusLogic_CCB_Active &&
2245 CCB->Command == Command && Command->pid == CommandPID)
2246 {
2247
2248
2249
2250 if (BusLogic_WriteOutgoingMailbox(HostAdapter,
2251 BusLogic_MailboxAbortCommand, CCB))
2252 {
2253 printk("scsi%d: Aborting CCB #%d to Target %d\n",
2254 HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
2255 Result = SCSI_ABORT_PENDING;
2256 }
2257 else
2258 {
2259 printk("scsi%d: Unable to Abort CCB #%d to Target %d - "
2260 "No Outgoing Mailboxes\n", HostAdapter->HostNumber,
2261 CCB->SerialNumber, CCB->TargetID);
2262 Result = SCSI_ABORT_BUSY;
2263 }
2264 }
2265 else printk("scsi%d: CCB #%d to Target %d completed\n",
2266 HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
2267 BusLogic_UnlockHostAdapter(HostAdapter);
2268 return Result;
2269 }
2270
2271
2272
2273
2274
2275
2276
2277
2278 static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter,
2279 SCSI_Command_T *Command)
2280 {
2281 BusLogic_CCB_T *CCB;
2282 if (Command == NULL)
2283 printk("scsi%d: Resetting %s due to SCSI Reset State Interrupt\n",
2284 HostAdapter->HostNumber, HostAdapter->BoardName);
2285 else printk("scsi%d: Resetting %s due to Target %d\n",
2286 HostAdapter->HostNumber, HostAdapter->BoardName, Command->target);
2287
2288
2289
2290 BusLogic_LockHostAdapter(HostAdapter);
2291 if (!(BusLogic_HardResetHostAdapter(HostAdapter) &&
2292 BusLogic_InitializeHostAdapter(HostAdapter)))
2293 {
2294 printk("scsi%d: Resetting %s Failed\n",
2295 HostAdapter->HostNumber, HostAdapter->BoardName);
2296 BusLogic_UnlockHostAdapter(HostAdapter);
2297 return SCSI_RESET_ERROR;
2298 }
2299 BusLogic_UnlockHostAdapter(HostAdapter);
2300
2301
2302
2303
2304
2305 BusLogic_Delay(HostAdapter->BusSettleTime);
2306
2307
2308
2309 BusLogic_LockHostAdapter(HostAdapter);
2310 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2311 if (CCB->Status == BusLogic_CCB_Active)
2312 {
2313 CCB->Status = BusLogic_CCB_Reset;
2314 if (CCB->Command == Command)
2315 {
2316 CCB->Command = NULL;
2317
2318
2319
2320 if (((HostAdapter->HostWideSCSI && CCB->WideModeTagEnable) ||
2321 (!HostAdapter->HostWideSCSI && CCB->TagEnable)) &&
2322 (HostAdapter->TaggedQueuingPermitted & (1 << CCB->TargetID)))
2323 {
2324 HostAdapter->TaggedQueuingPermitted &= ~(1 << CCB->TargetID);
2325 printk("scsi%d: Tagged Queuing now disabled for Target %d\n",
2326 HostAdapter->HostNumber, CCB->TargetID);
2327 }
2328 }
2329 }
2330 BusLogic_UnlockHostAdapter(HostAdapter);
2331
2332
2333
2334 if (Command != NULL)
2335 {
2336 Command->result = DID_RESET << 16;
2337 Command->scsi_done(Command);
2338 }
2339
2340
2341
2342 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2343 if (CCB->Status == BusLogic_CCB_Reset)
2344 {
2345 Command = CCB->Command;
2346 BusLogic_DeallocateCCB(CCB);
2347 if (Command != NULL)
2348 {
2349 Command->result = DID_RESET << 16;
2350 Command->scsi_done(Command);
2351 }
2352 }
2353 return SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
2354 }
2355
2356
2357
2358
2359
2360
2361
2362 static int BusLogic_BusDeviceReset(BusLogic_HostAdapter_T *HostAdapter,
2363 SCSI_Command_T *Command)
2364 {
2365 BusLogic_CCB_T *CCB = BusLogic_AllocateCCB(HostAdapter), *XCCB;
2366 unsigned char TargetID = Command->target;
2367
2368
2369
2370
2371 if (CCB == NULL)
2372 return BusLogic_ResetHostAdapter(HostAdapter, Command);
2373 printk("scsi%d: Sending Bus Device Reset CCB #%d to Target %d\n",
2374 HostAdapter->HostNumber, CCB->SerialNumber, TargetID);
2375 CCB->Opcode = BusLogic_SCSIBusDeviceReset;
2376 CCB->TargetID = TargetID;
2377 CCB->Command = Command;
2378
2379
2380
2381
2382
2383
2384
2385
2386 BusLogic_LockHostAdapter(HostAdapter);
2387 for (XCCB = HostAdapter->All_CCBs; XCCB != NULL; XCCB = XCCB->NextAll)
2388 if (XCCB->Command == Command && XCCB->Status == BusLogic_CCB_Active)
2389 {
2390 CCB->Command = NULL;
2391
2392
2393
2394 if (((HostAdapter->HostWideSCSI && XCCB->WideModeTagEnable) ||
2395 (!HostAdapter->HostWideSCSI && XCCB->TagEnable)) &&
2396 (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
2397 {
2398 HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
2399 printk("scsi%d: Tagged Queuing now disabled for Target %d\n",
2400 HostAdapter->HostNumber, TargetID);
2401 }
2402 break;
2403 }
2404 BusLogic_UnlockHostAdapter(HostAdapter);
2405
2406
2407
2408
2409
2410 if (!(BusLogic_WriteOutgoingMailbox(HostAdapter,
2411 BusLogic_MailboxStartCommand, CCB)))
2412 {
2413 printk("scsi%d: cannot write Outgoing Mailbox for Bus Device Reset\n",
2414 HostAdapter->HostNumber);
2415 BusLogic_DeallocateCCB(CCB);
2416 return BusLogic_ResetHostAdapter(HostAdapter, Command);
2417 }
2418 HostAdapter->ReadWriteOperationCount[TargetID] = 0;
2419 HostAdapter->QueuedOperationCount[TargetID] = 0;
2420 return SCSI_RESET_PENDING;
2421 }
2422
2423
2424
2425
2426
2427
2428 int BusLogic_ResetCommand(SCSI_Command_T *Command)
2429 {
2430 BusLogic_HostAdapter_T *HostAdapter =
2431 (BusLogic_HostAdapter_T *) Command->host->hostdata;
2432 unsigned char TargetID = Command->target;
2433 unsigned char ErrorRecoveryOption =
2434 HostAdapter->ErrorRecoveryOption[TargetID];
2435 if (ErrorRecoveryOption == BusLogic_ErrorRecoveryDefault)
2436 if (Command->host->suggest_bus_reset)
2437 ErrorRecoveryOption = BusLogic_ErrorRecoveryHardReset;
2438 else ErrorRecoveryOption = BusLogic_ErrorRecoveryBusDeviceReset;
2439 switch (ErrorRecoveryOption)
2440 {
2441 case BusLogic_ErrorRecoveryHardReset:
2442 return BusLogic_ResetHostAdapter(HostAdapter, Command);
2443 case BusLogic_ErrorRecoveryBusDeviceReset:
2444 if (HostAdapter->CommandSuccessfulFlag[TargetID])
2445 {
2446 HostAdapter->CommandSuccessfulFlag[TargetID] = false;
2447 return BusLogic_BusDeviceReset(HostAdapter, Command);
2448 }
2449 else return BusLogic_ResetHostAdapter(HostAdapter, Command);
2450 }
2451 printk("scsi%d: Error Recovery for Target %d Suppressed\n",
2452 HostAdapter->HostNumber, TargetID);
2453 return SCSI_RESET_PUNT;
2454 }
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474 int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device,
2475 int *Parameters)
2476 {
2477 BusLogic_HostAdapter_T *HostAdapter =
2478 (BusLogic_HostAdapter_T *) Disk->device->host->hostdata;
2479 BIOS_DiskParameters_T *DiskParameters = (BIOS_DiskParameters_T *) Parameters;
2480 if (HostAdapter->ExtendedTranslation &&
2481 Disk->capacity >= 2*1024*1024 )
2482 if (Disk->capacity >= 4*1024*1024 )
2483 {
2484 DiskParameters->Heads = 255;
2485 DiskParameters->Sectors = 63;
2486 }
2487 else
2488 {
2489 DiskParameters->Heads = 128;
2490 DiskParameters->Sectors = 32;
2491 }
2492 else
2493 {
2494 DiskParameters->Heads = 64;
2495 DiskParameters->Sectors = 32;
2496 }
2497 DiskParameters->Cylinders =
2498 Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
2499 return 0;
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
2607 void BusLogic_Setup(char *Strings, int *Integers)
2608 {
2609 BusLogic_CommandLineEntry_T *CommandLineEntry =
2610 &BusLogic_CommandLineEntries[BusLogic_CommandLineEntryCount++];
2611 static int ProbeListIndex = 0;
2612 int IntegerCount = Integers[0], TargetID, i;
2613 CommandLineEntry->IO_Address = 0;
2614 CommandLineEntry->Concurrency = 0;
2615 CommandLineEntry->BusSettleTime = 0;
2616 CommandLineEntry->LocalOptions = 0;
2617 CommandLineEntry->TaggedQueuingPermitted = 0;
2618 CommandLineEntry->TaggedQueuingPermittedMask = 0;
2619 memset(CommandLineEntry->ErrorRecoveryOption,
2620 BusLogic_ErrorRecoveryDefault,
2621 sizeof(CommandLineEntry->ErrorRecoveryOption));
2622 if (IntegerCount > 5)
2623 printk("BusLogic: Unexpected Command Line Integers ignored\n");
2624 if (IntegerCount >= 1)
2625 {
2626 unsigned short IO_Address = Integers[1];
2627 if (IO_Address > 0)
2628 {
2629 for (i = 0; ; i++)
2630 if (BusLogic_IO_StandardAddresses[i] == 0)
2631 {
2632 printk("BusLogic: Invalid Command Line Entry "
2633 "(illegal I/O Address 0x%X)\n", IO_Address);
2634 return;
2635 }
2636 else if (i < ProbeListIndex &&
2637 IO_Address == BusLogic_IO_AddressProbeList[i])
2638 {
2639 printk("BusLogic: Invalid Command Line Entry "
2640 "(duplicate I/O Address 0x%X)\n", IO_Address);
2641 return;
2642 }
2643 else if (IO_Address >= 0x1000 ||
2644 IO_Address == BusLogic_IO_StandardAddresses[i]) break;
2645 BusLogic_IO_AddressProbeList[ProbeListIndex++] = IO_Address;
2646 BusLogic_IO_AddressProbeList[ProbeListIndex] = 0;
2647 }
2648 CommandLineEntry->IO_Address = IO_Address;
2649 }
2650 if (IntegerCount >= 2)
2651 {
2652 unsigned short Concurrency = Integers[2];
2653 if (Concurrency > BusLogic_MailboxCount)
2654 {
2655 printk("BusLogic: Invalid Command Line Entry "
2656 "(illegal Concurrency %d)\n", Concurrency);
2657 return;
2658 }
2659 CommandLineEntry->Concurrency = Concurrency;
2660 }
2661 if (IntegerCount >= 3)
2662 CommandLineEntry->BusSettleTime = Integers[3];
2663 if (IntegerCount >= 4)
2664 CommandLineEntry->LocalOptions = Integers[4];
2665 if (IntegerCount >= 5)
2666 BusLogic_GlobalOptions |= Integers[5];
2667 if (!(BusLogic_CommandLineEntryCount == 0 || ProbeListIndex == 0 ||
2668 BusLogic_CommandLineEntryCount == ProbeListIndex))
2669 {
2670 printk("BusLogic: Invalid Command Line Entry "
2671 "(all or no I/O Addresses must be specified)\n");
2672 return;
2673 }
2674 if (Strings == NULL) return;
2675 if (strncmp(Strings, "TQ:", 3) == 0)
2676 {
2677 Strings += 3;
2678 if (strncmp(Strings, "Default", 7) == 0)
2679 Strings += 7;
2680 else if (strncmp(Strings, "Enable", 6) == 0)
2681 {
2682 Strings += 6;
2683 CommandLineEntry->TaggedQueuingPermitted = 0xFFFF;
2684 CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF;
2685 }
2686 else if (strncmp(Strings, "Disable", 7) == 0)
2687 {
2688 Strings += 7;
2689 CommandLineEntry->TaggedQueuingPermitted = 0x0000;
2690 CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF;
2691 }
2692 else
2693 for (TargetID = 0; TargetID < BusLogic_MaxTargetIDs; TargetID++)
2694 switch (*Strings++)
2695 {
2696 case 'Y':
2697 CommandLineEntry->TaggedQueuingPermitted |= 1 << TargetID;
2698 CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID;
2699 break;
2700 case 'N':
2701 CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID;
2702 break;
2703 case 'X':
2704 break;
2705 default:
2706 Strings--;
2707 TargetID = BusLogic_MaxTargetIDs;
2708 break;
2709 }
2710 }
2711 if (*Strings == ',') Strings++;
2712 if (strncmp(Strings, "ER:", 3) == 0)
2713 {
2714 Strings += 3;
2715 if (strncmp(Strings, "Default", 7) == 0)
2716 Strings += 7;
2717 else if (strncmp(Strings, "HardReset", 9) == 0)
2718 {
2719 Strings += 9;
2720 memset(CommandLineEntry->ErrorRecoveryOption,
2721 BusLogic_ErrorRecoveryHardReset,
2722 sizeof(CommandLineEntry->ErrorRecoveryOption));
2723 }
2724 else if (strncmp(Strings, "BusDeviceReset", 14) == 0)
2725 {
2726 Strings += 14;
2727 memset(CommandLineEntry->ErrorRecoveryOption,
2728 BusLogic_ErrorRecoveryBusDeviceReset,
2729 sizeof(CommandLineEntry->ErrorRecoveryOption));
2730 }
2731 else if (strncmp(Strings, "None", 4) == 0)
2732 {
2733 Strings += 4;
2734 memset(CommandLineEntry->ErrorRecoveryOption,
2735 BusLogic_ErrorRecoveryNone,
2736 sizeof(CommandLineEntry->ErrorRecoveryOption));
2737 }
2738 else
2739 for (TargetID = 0; TargetID < BusLogic_MaxTargetIDs; TargetID++)
2740 switch (*Strings++)
2741 {
2742 case 'D':
2743 CommandLineEntry->ErrorRecoveryOption[TargetID] =
2744 BusLogic_ErrorRecoveryDefault;
2745 break;
2746 case 'H':
2747 CommandLineEntry->ErrorRecoveryOption[TargetID] =
2748 BusLogic_ErrorRecoveryHardReset;
2749 break;
2750 case 'B':
2751 CommandLineEntry->ErrorRecoveryOption[TargetID] =
2752 BusLogic_ErrorRecoveryBusDeviceReset;
2753 break;
2754 case 'N':
2755 CommandLineEntry->ErrorRecoveryOption[TargetID] =
2756 BusLogic_ErrorRecoveryNone;
2757 break;
2758 default:
2759 Strings--;
2760 TargetID = BusLogic_MaxTargetIDs;
2761 break;
2762 }
2763 }
2764 if (*Strings != '\0')
2765 printk("BusLogic: Unexpected Command Line String '%s' ignored\n", Strings);
2766 }
2767
2768
2769
2770
2771
2772
2773
2774 #ifdef MODULE
2775
2776 SCSI_Host_Template_T driver_template = BUSLOGIC;
2777
2778 #include "scsi_module.c"
2779
2780 #endif