This source file includes following definitions.
- BusLogic_AnnounceDriver
- BusLogic_DriverInfo
- BusLogic_RegisterHostAdapter
- BusLogic_UnregisterHostAdapter
- BusLogic_CreateMailboxes
- BusLogic_DestroyMailboxes
- BusLogic_CreateCCBs
- BusLogic_DestroyCCBs
- BusLogic_AllocateCCB
- BusLogic_DeallocateCCB
- BusLogic_Command
- BusLogic_InitializeAddressProbeList
- BusLogic_Failure
- BusLogic_ProbeHostAdapter
- BusLogic_HardResetHostAdapter
- BusLogic_CheckHostAdapter
- BusLogic_ReadHostAdapterConfiguration
- BusLogic_AcquireResources
- BusLogic_ReleaseResources
- BusLogic_TestInterrupts
- BusLogic_InitializeHostAdapter
- BusLogic_InquireTargetDevices
- BusLogic_InitializeHostStructure
- BusLogic_SelectQueueDepths
- BusLogic_DetectHostAdapter
- BusLogic_ReleaseHostAdapter
- BusLogic_ComputeResultCode
- BusLogic_InterruptHandler
- BusLogic_WriteOutgoingMailbox
- BusLogic_QueueCommand
- BusLogic_AbortCommand
- BusLogic_ResetHostAdapter
- BusLogic_SendBusDeviceReset
- 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.2"
28 #define BusLogic_DriverDate "16 April 1996"
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 static void BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
175 {
176 HostAdapter->Next = NULL;
177 if (BusLogic_RegisteredHostAdapters != NULL)
178 {
179 BusLogic_HostAdapter_T *LastHostAdapter = BusLogic_RegisteredHostAdapters;
180 BusLogic_HostAdapter_T *NextHostAdapter;
181 while ((NextHostAdapter = LastHostAdapter->Next) != NULL)
182 LastHostAdapter = NextHostAdapter;
183 LastHostAdapter->Next = HostAdapter;
184 }
185 else BusLogic_RegisteredHostAdapters = HostAdapter;
186 }
187
188
189
190
191
192
193
194 static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
195 {
196 if (BusLogic_RegisteredHostAdapters != HostAdapter)
197 {
198 BusLogic_HostAdapter_T *LastHostAdapter = BusLogic_RegisteredHostAdapters;
199 while (LastHostAdapter != NULL && LastHostAdapter->Next != HostAdapter)
200 LastHostAdapter = LastHostAdapter->Next;
201 if (LastHostAdapter != NULL)
202 LastHostAdapter->Next = HostAdapter->Next;
203 }
204 else BusLogic_RegisteredHostAdapters = HostAdapter->Next;
205 HostAdapter->Next = NULL;
206 }
207
208
209
210
211
212
213
214 static boolean BusLogic_CreateMailboxes(BusLogic_HostAdapter_T *HostAdapter)
215 {
216 HostAdapter->FirstOutgoingMailbox =
217 (BusLogic_OutgoingMailbox_T *)
218 scsi_init_malloc(HostAdapter->MailboxCount
219 * (sizeof(BusLogic_OutgoingMailbox_T)
220 + sizeof(BusLogic_IncomingMailbox_T)),
221 (HostAdapter->BounceBuffersRequired
222 ? GFP_ATOMIC | GFP_DMA
223 : GFP_ATOMIC));
224 if (HostAdapter->FirstOutgoingMailbox == NULL)
225 {
226 printk("scsi%d: UNABLE TO ALLOCATE MAILBOXES - DETACHING\n",
227 HostAdapter->HostNumber);
228 return false;
229 }
230 HostAdapter->LastOutgoingMailbox =
231 HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1;
232 HostAdapter->FirstIncomingMailbox =
233 (BusLogic_IncomingMailbox_T *) (HostAdapter->LastOutgoingMailbox + 1);
234 HostAdapter->LastIncomingMailbox =
235 HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1;
236 return true;
237 }
238
239
240
241
242
243
244
245 static void BusLogic_DestroyMailboxes(BusLogic_HostAdapter_T *HostAdapter)
246 {
247 if (HostAdapter->FirstOutgoingMailbox == NULL) return;
248 scsi_init_free((char *) HostAdapter->FirstOutgoingMailbox,
249 HostAdapter->MailboxCount
250 * (sizeof(BusLogic_OutgoingMailbox_T)
251 + sizeof(BusLogic_IncomingMailbox_T)));
252 }
253
254
255
256
257
258
259
260 static boolean BusLogic_CreateCCBs(BusLogic_HostAdapter_T *HostAdapter)
261 {
262 int i;
263 for (i = 0; i < HostAdapter->InitialCCBs; i++)
264 {
265 BusLogic_CCB_T *CCB = (BusLogic_CCB_T *)
266 scsi_init_malloc(sizeof(BusLogic_CCB_T),
267 (HostAdapter->BounceBuffersRequired
268 ? GFP_ATOMIC | GFP_DMA
269 : GFP_ATOMIC));
270 if (CCB == NULL)
271 {
272 printk("scsi%d: UNABLE TO ALLOCATE CCB %d - DETACHING\n",
273 HostAdapter->HostNumber, i);
274 return false;
275 }
276 memset(CCB, 0, sizeof(BusLogic_CCB_T));
277 CCB->HostAdapter = HostAdapter;
278 CCB->Status = BusLogic_CCB_Free;
279 CCB->Next = HostAdapter->Free_CCBs;
280 CCB->NextAll = HostAdapter->All_CCBs;
281 HostAdapter->Free_CCBs = CCB;
282 HostAdapter->All_CCBs = CCB;
283 }
284 return true;
285 }
286
287
288
289
290
291
292 static void BusLogic_DestroyCCBs(BusLogic_HostAdapter_T *HostAdapter)
293 {
294 BusLogic_CCB_T *NextCCB = HostAdapter->All_CCBs, *CCB;
295 HostAdapter->All_CCBs = NULL;
296 HostAdapter->Free_CCBs = NULL;
297 while ((CCB = NextCCB) != NULL)
298 {
299 NextCCB = CCB->NextAll;
300 scsi_init_free((char *) CCB, sizeof(BusLogic_CCB_T));
301 }
302 }
303
304
305
306
307
308
309
310
311 static BusLogic_CCB_T *BusLogic_AllocateCCB(BusLogic_HostAdapter_T *HostAdapter)
312 {
313 static unsigned int SerialNumber = 0;
314 BusLogic_CCB_T *CCB;
315 int Allocated;
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 return CCB;
323 }
324 for (Allocated = 0; Allocated < HostAdapter->IncrementalCCBs; Allocated++)
325 {
326 CCB = (BusLogic_CCB_T *)
327 scsi_init_malloc(sizeof(BusLogic_CCB_T),
328 (HostAdapter->BounceBuffersRequired
329 ? GFP_ATOMIC | GFP_DMA
330 : GFP_ATOMIC));
331 if (CCB == NULL) break;
332 memset(CCB, 0, sizeof(BusLogic_CCB_T));
333 CCB->HostAdapter = HostAdapter;
334 CCB->Status = BusLogic_CCB_Free;
335 CCB->Next = HostAdapter->Free_CCBs;
336 CCB->NextAll = HostAdapter->All_CCBs;
337 HostAdapter->Free_CCBs = CCB;
338 HostAdapter->All_CCBs = CCB;
339 }
340 CCB = HostAdapter->Free_CCBs;
341 if (CCB == NULL)
342 {
343 printk("scsi%d: Failed to allocate additional CCBs\n",
344 HostAdapter->HostNumber);
345 return NULL;
346 }
347 printk("scsi%d: Allocated %d additional CCBs\n",
348 HostAdapter->HostNumber, Allocated);
349 CCB->SerialNumber = ++SerialNumber;
350 HostAdapter->Free_CCBs = CCB->Next;
351 CCB->Next = NULL;
352 return CCB;
353 }
354
355
356
357
358
359
360
361
362 static void BusLogic_DeallocateCCB(BusLogic_CCB_T *CCB)
363 {
364 BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
365 CCB->Command = NULL;
366 CCB->Status = BusLogic_CCB_Free;
367 CCB->Next = HostAdapter->Free_CCBs;
368 HostAdapter->Free_CCBs = CCB;
369 }
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390 static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter,
391 BusLogic_OperationCode_T OperationCode,
392 void *ParameterData,
393 int ParameterLength,
394 void *ReplyData,
395 int ReplyLength)
396 {
397 unsigned char *ParameterPointer = (unsigned char *) ParameterData;
398 unsigned char *ReplyPointer = (unsigned char *) ReplyData;
399 unsigned char StatusRegister = 0, InterruptRegister;
400 long TimeoutCounter;
401 int ReplyBytes = 0;
402
403
404
405 if (ReplyLength > 0)
406 memset(ReplyData, 0, ReplyLength);
407
408
409
410
411 TimeoutCounter = loops_per_sec >> 3;
412 while (--TimeoutCounter >= 0)
413 {
414 StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
415 if ((StatusRegister & BusLogic_HostAdapterReady) &&
416 !(StatusRegister & BusLogic_CommandParameterRegisterBusy))
417 break;
418 }
419 BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";
420 if (TimeoutCounter < 0) return -2;
421
422
423
424 HostAdapter->HostAdapterCommandCompleted = false;
425 BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);
426
427
428
429 TimeoutCounter = 10000;
430 while (ParameterLength > 0 && --TimeoutCounter >= 0)
431 {
432
433
434
435
436
437
438
439
440
441
442
443
444 udelay(100);
445 InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
446 StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
447 if (InterruptRegister & BusLogic_CommandComplete) break;
448 if (HostAdapter->HostAdapterCommandCompleted) break;
449 if (StatusRegister & BusLogic_DataInRegisterReady) break;
450 if (StatusRegister & BusLogic_CommandParameterRegisterBusy) continue;
451 BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++);
452 ParameterLength--;
453 }
454 BusLogic_CommandFailureReason = "Timeout waiting for Parameter Acceptance";
455 if (TimeoutCounter < 0) return -2;
456
457
458
459 if (OperationCode == BusLogic_ModifyIOAddress)
460 {
461 StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
462 BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
463 if (StatusRegister & BusLogic_CommandInvalid) return -1;
464 BusLogic_CommandFailureReason = NULL;
465 return 0;
466 }
467
468
469
470 switch (OperationCode)
471 {
472 case BusLogic_InquireInstalledDevicesID0to7:
473 case BusLogic_InquireInstalledDevicesID8to15:
474 case BusLogic_InquireDevices:
475
476 TimeoutCounter = loops_per_sec << 2;
477 break;
478 default:
479
480 TimeoutCounter = loops_per_sec >> 4;
481 break;
482 }
483
484
485
486
487
488 while (--TimeoutCounter >= 0)
489 {
490 InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
491 StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
492 if (InterruptRegister & BusLogic_CommandComplete) break;
493 if (HostAdapter->HostAdapterCommandCompleted) break;
494 if (StatusRegister & BusLogic_DataInRegisterReady)
495 if (++ReplyBytes <= ReplyLength)
496 *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
497 else BusLogic_ReadDataInRegister(HostAdapter);
498 if (OperationCode == BusLogic_FetchHostAdapterLocalRAM &&
499 (StatusRegister & BusLogic_HostAdapterReady)) break;
500 }
501 BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";
502 if (TimeoutCounter < 0) return -2;
503
504
505
506
507
508
509
510 if (OperationCode == BusLogic_TestCommandCompleteInterrupt)
511 udelay(10000);
512
513
514
515 BusLogic_WriteControlRegister(HostAdapter, BusLogic_InterruptReset);
516 if (BusLogic_GlobalOptions & BusLogic_TraceConfiguration)
517 if (OperationCode != BusLogic_TestCommandCompleteInterrupt)
518 {
519 int i;
520 printk("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:",
521 OperationCode, StatusRegister, ReplyLength, ReplyBytes);
522 if (ReplyLength > ReplyBytes) ReplyLength = ReplyBytes;
523 for (i = 0; i < ReplyLength; i++)
524 printk(" %02X", ((unsigned char *) ReplyData)[i]);
525 printk("\n");
526 }
527
528
529
530 if (StatusRegister & BusLogic_CommandInvalid)
531 {
532
533
534
535
536
537
538
539
540 udelay(1000);
541 StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
542 if (StatusRegister != (BusLogic_HostAdapterReady |
543 BusLogic_InitializationRequired))
544 {
545 BusLogic_WriteControlRegister(HostAdapter, BusLogic_SoftReset);
546 udelay(1000);
547 }
548 BusLogic_CommandFailureReason = "Command Invalid";
549 return -1;
550 }
551
552
553
554 BusLogic_CommandFailureReason = "Excess Parameters Supplied";
555 if (ParameterLength > 0) return -1;
556
557
558
559 BusLogic_CommandFailureReason = NULL;
560 return ReplyBytes;
561 }
562
563
564
565
566
567
568
569
570
571 static void BusLogic_InitializeAddressProbeList(void)
572 {
573 int DestinationIndex = 0, SourceIndex = 0;
574
575
576
577
578 if (BusLogic_IO_AddressProbeList[0] != 0) return;
579 #ifdef CONFIG_PCI
580
581
582
583 if (pcibios_present())
584 {
585 unsigned short BusDeviceFunction[BusLogic_IO_MaxProbeAddresses];
586 unsigned short Index = 0, VendorID, DeviceID;
587 boolean NonIncreasingScanningOrder = false;
588 unsigned char Bus, DeviceFunction;
589 unsigned int BaseAddress0;
590 while (pcibios_find_class(PCI_CLASS_STORAGE_SCSI<<8, Index++,
591 &Bus, &DeviceFunction) == 0)
592 if (pcibios_read_config_word(Bus, DeviceFunction,
593 PCI_VENDOR_ID, &VendorID) == 0 &&
594 VendorID == PCI_VENDOR_ID_BUSLOGIC &&
595 pcibios_read_config_word(Bus, DeviceFunction,
596 PCI_DEVICE_ID, &DeviceID) == 0 &&
597 (DeviceID == PCI_DEVICE_ID_BUSLOGIC_946C ||
598 DeviceID == PCI_DEVICE_ID_BUSLOGIC_946C_2) &&
599 pcibios_read_config_dword(Bus, DeviceFunction,
600 PCI_BASE_ADDRESS_0, &BaseAddress0) == 0 &&
601 (BaseAddress0 & PCI_BASE_ADDRESS_SPACE) ==
602 PCI_BASE_ADDRESS_SPACE_IO)
603 {
604 BusLogic_IO_AddressProbeList[DestinationIndex] =
605 BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK;
606 BusDeviceFunction[DestinationIndex] = (Bus << 8) | DeviceFunction;
607 if (DestinationIndex > 0 &&
608 BusDeviceFunction[DestinationIndex] <
609 BusDeviceFunction[DestinationIndex-1])
610 NonIncreasingScanningOrder = true;
611 DestinationIndex++;
612 }
613
614
615
616
617
618
619
620
621
622 if (DestinationIndex > 1 && NonIncreasingScanningOrder)
623 {
624 BusLogic_FetchHostAdapterLocalRAMRequest_T
625 FetchHostAdapterLocalRAMRequest;
626 BusLogic_AutoSCSIByte45_T AutoSCSIByte45;
627 BusLogic_HostAdapter_T HostAdapterPrototype;
628 BusLogic_HostAdapter_T *HostAdapter = &HostAdapterPrototype;
629 HostAdapter->IO_Address = BusLogic_IO_AddressProbeList[0];
630 FetchHostAdapterLocalRAMRequest.ByteOffset =
631 BusLogic_AutoSCSI_BaseOffset + 45;
632 FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIByte45);
633 AutoSCSIByte45.ForceBusDeviceScanningOrder = false;
634 BusLogic_Command(HostAdapter,
635 BusLogic_FetchHostAdapterLocalRAM,
636 &FetchHostAdapterLocalRAMRequest,
637 sizeof(FetchHostAdapterLocalRAMRequest),
638 &AutoSCSIByte45, sizeof(AutoSCSIByte45));
639 if (AutoSCSIByte45.ForceBusDeviceScanningOrder)
640 {
641
642
643
644
645 int LastInterchange = DestinationIndex-1, Bound, j;
646 while (LastInterchange > 0)
647 {
648 Bound = LastInterchange;
649 LastInterchange = 0;
650 for (j = 0; j < Bound; j++)
651 if (BusDeviceFunction[j] > BusDeviceFunction[j+1])
652 {
653 unsigned short Temp;
654 Temp = BusDeviceFunction[j];
655 BusDeviceFunction[j] = BusDeviceFunction[j+1];
656 BusDeviceFunction[j+1] = Temp;
657 Temp = BusLogic_IO_AddressProbeList[j];
658 BusLogic_IO_AddressProbeList[j] =
659 BusLogic_IO_AddressProbeList[j+1];
660 BusLogic_IO_AddressProbeList[j+1] = Temp;
661 LastInterchange = j;
662 }
663 }
664 }
665 }
666 }
667 #endif
668
669
670
671 while (DestinationIndex < BusLogic_IO_MaxProbeAddresses &&
672 BusLogic_IO_StandardAddresses[SourceIndex] > 0)
673 BusLogic_IO_AddressProbeList[DestinationIndex++] =
674 BusLogic_IO_StandardAddresses[SourceIndex++];
675 BusLogic_IO_AddressProbeList[DestinationIndex] = 0;
676 }
677
678
679
680
681
682
683 static boolean BusLogic_Failure(BusLogic_HostAdapter_T *HostAdapter,
684 char *ErrorMessage)
685 {
686 BusLogic_AnnounceDriver();
687 printk("While configuring BusLogic Host Adapter at I/O Address 0x%X:\n",
688 HostAdapter->IO_Address);
689 printk("%s FAILED - DETACHING\n", ErrorMessage);
690 if (BusLogic_CommandFailureReason != NULL)
691 printk("ADDITIONAL FAILURE INFO - %s\n", BusLogic_CommandFailureReason);
692 return false;
693 }
694
695
696
697
698
699
700 static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
701 {
702 boolean TraceProbe = (BusLogic_GlobalOptions & BusLogic_TraceProbe);
703 unsigned char StatusRegister, GeometryRegister;
704
705
706
707
708
709 StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
710 if (TraceProbe)
711 printk("BusLogic_Probe(0x%X): Status 0x%02X\n",
712 HostAdapter->IO_Address, StatusRegister);
713 if (StatusRegister == 0xFF) return false;
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728 GeometryRegister = BusLogic_ReadGeometryRegister(HostAdapter);
729 if (TraceProbe)
730 printk("BusLogic_Probe(0x%X): Geometry 0x%02X\n",
731 HostAdapter->IO_Address, GeometryRegister);
732 if (GeometryRegister == 0xFF) return false;
733
734
735
736 return true;
737 }
738
739
740
741
742
743
744
745 static boolean BusLogic_HardResetHostAdapter(BusLogic_HostAdapter_T
746 *HostAdapter)
747 {
748 boolean TraceHardReset = (BusLogic_GlobalOptions & BusLogic_TraceHardReset);
749 long TimeoutCounter = loops_per_sec >> 2;
750 unsigned char StatusRegister = 0;
751
752
753
754
755 BusLogic_WriteControlRegister(HostAdapter, BusLogic_HardReset);
756
757
758
759 while (--TimeoutCounter >= 0)
760 {
761 StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
762 if ((StatusRegister & BusLogic_DiagnosticActive)) break;
763 }
764 if (TraceHardReset)
765 printk("BusLogic_HardReset(0x%X): Diagnostic Active, Status 0x%02X\n",
766 HostAdapter->IO_Address, StatusRegister);
767 if (TimeoutCounter < 0) return false;
768
769
770
771
772
773 udelay(100);
774
775
776
777 while (--TimeoutCounter >= 0)
778 {
779 StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
780 if (!(StatusRegister & BusLogic_DiagnosticActive)) break;
781 }
782 if (TraceHardReset)
783 printk("BusLogic_HardReset(0x%X): Diagnostic Completed, Status 0x%02X\n",
784 HostAdapter->IO_Address, StatusRegister);
785 if (TimeoutCounter < 0) return false;
786
787
788
789
790 while (--TimeoutCounter >= 0)
791 {
792 StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
793 if (StatusRegister & (BusLogic_DiagnosticFailure |
794 BusLogic_HostAdapterReady |
795 BusLogic_DataInRegisterReady))
796 break;
797 }
798 if (TraceHardReset)
799 printk("BusLogic_HardReset(0x%X): Host Adapter Ready, Status 0x%02X\n",
800 HostAdapter->IO_Address, StatusRegister);
801 if (TimeoutCounter < 0) return false;
802
803
804
805
806
807 if ((StatusRegister & BusLogic_DiagnosticFailure) ||
808 !(StatusRegister & BusLogic_HostAdapterReady))
809 {
810 BusLogic_CommandFailureReason = NULL;
811 BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
812 printk("HOST ADAPTER STATUS REGISTER = %02X\n", StatusRegister);
813 if (StatusRegister & BusLogic_DataInRegisterReady)
814 {
815 unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
816 printk("HOST ADAPTER ERROR CODE = %d\n", ErrorCode);
817 }
818 return false;
819 }
820
821
822
823 return true;
824 }
825
826
827
828
829
830
831
832 static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
833 {
834 BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
835 BusLogic_RequestedReplyLength_T RequestedReplyLength;
836 unsigned long ProcessorFlags;
837 int Result;
838
839
840
841
842
843
844
845
846
847 save_flags(ProcessorFlags);
848 cli();
849 RequestedReplyLength = sizeof(ExtendedSetupInformation);
850 Result = BusLogic_Command(HostAdapter,
851 BusLogic_InquireExtendedSetupInformation,
852 &RequestedReplyLength, sizeof(RequestedReplyLength),
853 &ExtendedSetupInformation,
854 sizeof(ExtendedSetupInformation));
855 restore_flags(ProcessorFlags);
856 if (BusLogic_GlobalOptions & BusLogic_TraceProbe)
857 printk("BusLogic_Check(0x%X): Result %d\n",
858 HostAdapter->IO_Address, Result);
859 return (Result == sizeof(ExtendedSetupInformation));
860 }
861
862
863
864
865
866
867
868 static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T
869 *HostAdapter)
870 {
871 BusLogic_BoardID_T BoardID;
872 BusLogic_Configuration_T Configuration;
873 BusLogic_SetupInformation_T SetupInformation;
874 BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
875 BusLogic_BoardModelNumber_T BoardModelNumber;
876 BusLogic_FirmwareVersion3rdDigit_T FirmwareVersion3rdDigit;
877 BusLogic_FirmwareVersionLetter_T FirmwareVersionLetter;
878 BusLogic_GenericIOPortInformation_T GenericIOPortInformation;
879 BusLogic_FetchHostAdapterLocalRAMRequest_T FetchHostAdapterLocalRAMRequest;
880 BusLogic_AutoSCSIByte15_T AutoSCSIByte15;
881 BusLogic_RequestedReplyLength_T RequestedReplyLength;
882 unsigned char GeometryRegister, *TargetPointer, Character;
883 unsigned short AllTargetsMask, DisconnectPermitted;
884 unsigned short TaggedQueuingPermitted, TaggedQueuingPermittedDefault;
885 boolean CommonErrorRecovery;
886 int TargetID, i;
887
888
889
890 if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0,
891 &BoardID, sizeof(BoardID)) != sizeof(BoardID))
892 return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
893
894
895
896 if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0,
897 &Configuration, sizeof(Configuration))
898 != sizeof(Configuration))
899 return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
900
901
902
903 RequestedReplyLength = sizeof(SetupInformation);
904 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
905 &RequestedReplyLength, sizeof(RequestedReplyLength),
906 &SetupInformation, sizeof(SetupInformation))
907 != sizeof(SetupInformation))
908 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
909
910
911
912 RequestedReplyLength = sizeof(ExtendedSetupInformation);
913 if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation,
914 &RequestedReplyLength, sizeof(RequestedReplyLength),
915 &ExtendedSetupInformation,
916 sizeof(ExtendedSetupInformation))
917 != sizeof(ExtendedSetupInformation))
918 return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
919
920
921
922 if (!(BoardID.FirmwareVersion1stDigit == '2' &&
923 ExtendedSetupInformation.BusType == 'A'))
924 {
925 RequestedReplyLength = sizeof(BoardModelNumber);
926 if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardModelNumber,
927 &RequestedReplyLength, sizeof(RequestedReplyLength),
928 &BoardModelNumber, sizeof(BoardModelNumber))
929 != sizeof(BoardModelNumber))
930 return BusLogic_Failure(HostAdapter, "INQUIRE BOARD MODEL NUMBER");
931 }
932 else strcpy(BoardModelNumber, "542B");
933
934
935
936 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit,
937 NULL, 0, &FirmwareVersion3rdDigit,
938 sizeof(FirmwareVersion3rdDigit))
939 != sizeof(FirmwareVersion3rdDigit))
940 return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
941
942
943
944 FirmwareVersionLetter = '\0';
945 if (BoardID.FirmwareVersion1stDigit > '3' ||
946 (BoardID.FirmwareVersion1stDigit == '3' &&
947 BoardID.FirmwareVersion2ndDigit >= '3'))
948 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter,
949 NULL, 0, &FirmwareVersionLetter,
950 sizeof(FirmwareVersionLetter))
951 != sizeof(FirmwareVersionLetter))
952 return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE VERSION LETTER");
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972 if (BoardID.FirmwareVersion1stDigit == '5')
973 {
974 if (BusLogic_Command(HostAdapter,
975 BusLogic_InquireGenericIOPortInformation,
976 NULL, 0, &GenericIOPortInformation,
977 sizeof(GenericIOPortInformation))
978 != sizeof(GenericIOPortInformation))
979 return BusLogic_Failure(HostAdapter,
980 "INQUIRE GENERIC I/O PORT INFORMATION");
981
982
983
984 if (GenericIOPortInformation.Valid)
985 {
986 HostAdapter->TerminationInfoValid = true;
987 HostAdapter->LowByteTerminated =
988 GenericIOPortInformation.LowByteTerminated;
989 HostAdapter->HighByteTerminated =
990 GenericIOPortInformation.HighByteTerminated;
991 }
992 }
993
994
995
996
997 if (BoardID.FirmwareVersion1stDigit == '4')
998 {
999 FetchHostAdapterLocalRAMRequest.ByteOffset =
1000 BusLogic_AutoSCSI_BaseOffset + 15;
1001 FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIByte15);
1002 if (BusLogic_Command(HostAdapter,
1003 BusLogic_FetchHostAdapterLocalRAM,
1004 &FetchHostAdapterLocalRAMRequest,
1005 sizeof(FetchHostAdapterLocalRAMRequest),
1006 &AutoSCSIByte15, sizeof(AutoSCSIByte15))
1007 != sizeof(AutoSCSIByte15))
1008 return BusLogic_Failure(HostAdapter, "FETCH HOST ADAPTER LOCAL RAM");
1009
1010
1011
1012 HostAdapter->TerminationInfoValid = true;
1013 HostAdapter->LowByteTerminated = AutoSCSIByte15.LowByteTerminated;
1014 HostAdapter->HighByteTerminated = AutoSCSIByte15.HighByteTerminated;
1015 }
1016
1017
1018
1019 TargetPointer = HostAdapter->ModelName;
1020 *TargetPointer++ = 'B';
1021 *TargetPointer++ = 'T';
1022 *TargetPointer++ = '-';
1023 for (i = 0; i < sizeof(BoardModelNumber); i++)
1024 {
1025 Character = BoardModelNumber[i];
1026 if (Character == ' ' || Character == '\0') break;
1027 *TargetPointer++ = Character;
1028 }
1029 *TargetPointer++ = '\0';
1030 strcpy(HostAdapter->BoardName, "BusLogic ");
1031 strcat(HostAdapter->BoardName, HostAdapter->ModelName);
1032 strcpy(HostAdapter->InterruptLabel, HostAdapter->BoardName);
1033
1034
1035
1036 TargetPointer = HostAdapter->FirmwareVersion;
1037 *TargetPointer++ = BoardID.FirmwareVersion1stDigit;
1038 *TargetPointer++ = '.';
1039 *TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
1040 if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0')
1041 *TargetPointer++ = FirmwareVersion3rdDigit;
1042 if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0')
1043 *TargetPointer++ = FirmwareVersionLetter;
1044 *TargetPointer++ = '\0';
1045
1046
1047
1048 if (Configuration.IRQ_Channel9)
1049 HostAdapter->IRQ_Channel = 9;
1050 else if (Configuration.IRQ_Channel10)
1051 HostAdapter->IRQ_Channel = 10;
1052 else if (Configuration.IRQ_Channel11)
1053 HostAdapter->IRQ_Channel = 11;
1054 else if (Configuration.IRQ_Channel12)
1055 HostAdapter->IRQ_Channel = 12;
1056 else if (Configuration.IRQ_Channel14)
1057 HostAdapter->IRQ_Channel = 14;
1058 else if (Configuration.IRQ_Channel15)
1059 HostAdapter->IRQ_Channel = 15;
1060
1061
1062
1063 if (Configuration.DMA_Channel5)
1064 HostAdapter->DMA_Channel = 5;
1065 else if (Configuration.DMA_Channel6)
1066 HostAdapter->DMA_Channel = 6;
1067 else if (Configuration.DMA_Channel7)
1068 HostAdapter->DMA_Channel = 7;
1069
1070
1071
1072 HostAdapter->SCSI_ID = Configuration.HostAdapterID;
1073
1074
1075
1076
1077 HostAdapter->SynchronousInitiation =
1078 SetupInformation.SynchronousInitiationEnabled;
1079 HostAdapter->ParityChecking = SetupInformation.ParityCheckEnabled;
1080
1081
1082
1083
1084 switch (HostAdapter->ModelName[3])
1085 {
1086 case '4':
1087 HostAdapter->BusType = BusLogic_VESA_Bus;
1088 HostAdapter->DMA_Channel = 0;
1089 break;
1090 case '5':
1091 HostAdapter->BusType = BusLogic_ISA_Bus;
1092 break;
1093 case '6':
1094 HostAdapter->BusType = BusLogic_MCA_Bus;
1095 HostAdapter->DMA_Channel = 0;
1096 break;
1097 case '7':
1098 HostAdapter->BusType = BusLogic_EISA_Bus;
1099 HostAdapter->DMA_Channel = 0;
1100 break;
1101 case '9':
1102 HostAdapter->BusType = BusLogic_PCI_Bus;
1103 HostAdapter->DMA_Channel = 0;
1104 break;
1105 }
1106
1107
1108
1109
1110 GeometryRegister = BusLogic_ReadGeometryRegister(HostAdapter);
1111 if (GeometryRegister & BusLogic_ExtendedTranslationEnabled)
1112 HostAdapter->ExtendedTranslation = true;
1113
1114
1115
1116
1117
1118
1119 if (HostAdapter->FirmwareVersion[0] >= '4')
1120 HostAdapter->DisconnectPermitted =
1121 (SetupInformation.DisconnectPermittedID8to15 << 8)
1122 | SetupInformation.DisconnectPermittedID0to7;
1123 else HostAdapter->DisconnectPermitted = 0xFF;
1124
1125
1126
1127
1128
1129 HostAdapter->HostAdapterScatterGatherLimit =
1130 ExtendedSetupInformation.ScatterGatherLimit;
1131 HostAdapter->DriverScatterGatherLimit =
1132 HostAdapter->HostAdapterScatterGatherLimit;
1133 if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
1134 HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1135 if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupts)
1136 HostAdapter->LevelSensitiveInterrupts = true;
1137 HostAdapter->HostWideSCSI = ExtendedSetupInformation.HostWideSCSI;
1138 HostAdapter->HostDifferentialSCSI =
1139 ExtendedSetupInformation.HostDifferentialSCSI;
1140 HostAdapter->HostAutomaticConfiguration =
1141 ExtendedSetupInformation.HostAutomaticConfiguration;
1142 HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI;
1143
1144
1145
1146
1147
1148 HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
1149
1150
1151
1152 if (HostAdapter->BusType == BusLogic_ISA_Bus && high_memory > MAX_DMA_ADDRESS)
1153 HostAdapter->BounceBuffersRequired = true;
1154
1155
1156
1157
1158
1159
1160
1161
1162 if (HostAdapter->BIOS_Address > 0 &&
1163 strcmp(HostAdapter->ModelName, "BT-445S") == 0 &&
1164 strcmp(HostAdapter->FirmwareVersion, "3.37") < 0 &&
1165 high_memory > MAX_DMA_ADDRESS)
1166 HostAdapter->BounceBuffersRequired = true;
1167
1168
1169
1170
1171 if (HostAdapter->HostWideSCSI)
1172 {
1173 HostAdapter->MaxTargetDevices = 16;
1174 HostAdapter->MaxLogicalUnits = 64;
1175 }
1176 else
1177 {
1178 HostAdapter->MaxTargetDevices = 8;
1179 HostAdapter->MaxLogicalUnits = 8;
1180 }
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204 if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0)
1205 {
1206 HostAdapter->StrictRoundRobinModeSupported = true;
1207 HostAdapter->MailboxCount = 255;
1208 HostAdapter->InitialCCBs = 64;
1209 HostAdapter->IncrementalCCBs = 32;
1210 }
1211 else
1212 {
1213 HostAdapter->StrictRoundRobinModeSupported = false;
1214 HostAdapter->MailboxCount = 32;
1215 HostAdapter->InitialCCBs = 32;
1216 HostAdapter->IncrementalCCBs = 4;
1217 }
1218 if (HostAdapter->FirmwareVersion[0] == '5')
1219 HostAdapter->TotalQueueDepth = 192;
1220 else if (HostAdapter->FirmwareVersion[0] == '4')
1221 HostAdapter->TotalQueueDepth =
1222 (HostAdapter->BusType != BusLogic_ISA_Bus ? 100 : 50);
1223 else HostAdapter->TotalQueueDepth = 30;
1224
1225
1226
1227
1228
1229
1230
1231 if (HostAdapter->CommandLineEntry != NULL &&
1232 HostAdapter->CommandLineEntry->TaggedQueueDepth > 0)
1233 HostAdapter->TaggedQueueDepth =
1234 HostAdapter->CommandLineEntry->TaggedQueueDepth;
1235 else if (HostAdapter->BounceBuffersRequired)
1236 HostAdapter->TaggedQueueDepth = BusLogic_TaggedQueueDepth_BB;
1237 else HostAdapter->TaggedQueueDepth = 0;
1238 HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth;
1239 if (HostAdapter->UntaggedQueueDepth > HostAdapter->TaggedQueueDepth &&
1240 HostAdapter->TaggedQueueDepth > 0)
1241 HostAdapter->UntaggedQueueDepth = HostAdapter->TaggedQueueDepth;
1242
1243
1244
1245
1246 if (HostAdapter->CommandLineEntry != NULL &&
1247 HostAdapter->CommandLineEntry->BusSettleTime > 0)
1248 HostAdapter->BusSettleTime = HostAdapter->CommandLineEntry->BusSettleTime;
1249 else HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
1250
1251
1252
1253 if (HostAdapter->CommandLineEntry != NULL)
1254 HostAdapter->LocalOptions = HostAdapter->CommandLineEntry->LocalOptions;
1255
1256
1257
1258
1259 if (HostAdapter->CommandLineEntry != NULL)
1260 memcpy(HostAdapter->ErrorRecoveryStrategy,
1261 HostAdapter->CommandLineEntry->ErrorRecoveryStrategy,
1262 sizeof(HostAdapter->ErrorRecoveryStrategy));
1263 else memset(HostAdapter->ErrorRecoveryStrategy,
1264 BusLogic_ErrorRecovery_Default,
1265 sizeof(HostAdapter->ErrorRecoveryStrategy));
1266
1267
1268
1269
1270
1271
1272
1273 TaggedQueuingPermittedDefault = 0;
1274 if (HostAdapter->TaggedQueueDepth != 1)
1275 switch (HostAdapter->FirmwareVersion[0])
1276 {
1277 case '5':
1278 TaggedQueuingPermittedDefault = 0xFFFF;
1279 break;
1280 case '4':
1281 if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0)
1282 TaggedQueuingPermittedDefault = 0xFFFF;
1283 break;
1284 case '3':
1285 if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0)
1286 TaggedQueuingPermittedDefault = 0xFFFF;
1287 break;
1288 }
1289
1290
1291
1292
1293
1294 TaggedQueuingPermittedDefault &= HostAdapter->DisconnectPermitted;
1295
1296
1297
1298
1299 if (HostAdapter->CommandLineEntry != NULL)
1300 HostAdapter->TaggedQueuingPermitted =
1301 (HostAdapter->CommandLineEntry->TaggedQueuingPermitted &
1302 HostAdapter->CommandLineEntry->TaggedQueuingPermittedMask) |
1303 (TaggedQueuingPermittedDefault &
1304 ~HostAdapter->CommandLineEntry->TaggedQueuingPermittedMask);
1305 else HostAdapter->TaggedQueuingPermitted = TaggedQueuingPermittedDefault;
1306
1307
1308
1309 printk("scsi%d: Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n",
1310 HostAdapter->HostNumber, HostAdapter->ModelName,
1311 BusLogic_BusNames[HostAdapter->BusType],
1312 (HostAdapter->HostWideSCSI ? " Wide" : ""),
1313 (HostAdapter->HostDifferentialSCSI ? " Differential" : ""),
1314 (HostAdapter->HostUltraSCSI ? " Ultra" : ""));
1315 printk("scsi%d: Firmware Version: %s, I/O Address: 0x%X, "
1316 "IRQ Channel: %d/%s\n",
1317 HostAdapter->HostNumber, HostAdapter->FirmwareVersion,
1318 HostAdapter->IO_Address, HostAdapter->IRQ_Channel,
1319 (HostAdapter->LevelSensitiveInterrupts ? "Level" : "Edge"));
1320 printk("scsi%d: DMA Channel: ", HostAdapter->HostNumber);
1321 if (HostAdapter->DMA_Channel > 0)
1322 printk("%d, ", HostAdapter->DMA_Channel);
1323 else printk("None, ");
1324 if (HostAdapter->BIOS_Address > 0)
1325 printk("BIOS Address: 0x%lX, ", HostAdapter->BIOS_Address);
1326 else printk("BIOS Address: None, ");
1327 printk("Host Adapter SCSI ID: %d\n", HostAdapter->SCSI_ID);
1328 printk("scsi%d: Scatter/Gather Limit: %d of %d segments, "
1329 "Parity Checking: %s\n", HostAdapter->HostNumber,
1330 HostAdapter->DriverScatterGatherLimit,
1331 HostAdapter->HostAdapterScatterGatherLimit,
1332 (HostAdapter->ParityChecking ? "Enabled" : "Disabled"));
1333 printk("scsi%d: Synchronous Initiation: %s, "
1334 "Extended Disk Translation: %s\n", HostAdapter->HostNumber,
1335 (HostAdapter->SynchronousInitiation ? "Enabled" : "Disabled"),
1336 (HostAdapter->ExtendedTranslation ? "Enabled" : "Disabled"));
1337 AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1;
1338 DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
1339 printk("scsi%d: Disconnect/Reconnect: ", HostAdapter->HostNumber);
1340 if (DisconnectPermitted == 0)
1341 printk("Disabled");
1342 else if (DisconnectPermitted == AllTargetsMask)
1343 printk("Enabled");
1344 else
1345 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1346 printk("%c", (DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
1347 printk(", Tagged Queuing: ");
1348 TaggedQueuingPermitted =
1349 HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
1350 if (TaggedQueuingPermitted == 0)
1351 printk("Disabled");
1352 else if (TaggedQueuingPermitted == AllTargetsMask)
1353 printk("Enabled");
1354 else
1355 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1356 printk("%c", (TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
1357 printk("\n");
1358 printk("scsi%d: Total Queue Depth: %d, Mailboxes: %d, Initial CCBs: %d\n",
1359 HostAdapter->HostNumber, HostAdapter->TotalQueueDepth,
1360 HostAdapter->MailboxCount, HostAdapter->InitialCCBs);
1361 printk("scsi%d: Tagged Queue Depth: ", HostAdapter->HostNumber);
1362 if (HostAdapter->TaggedQueueDepth > 0)
1363 printk("%d", HostAdapter->TaggedQueueDepth);
1364 else printk("Automatic");
1365 printk(", Untagged Queue Depth: %d\n", HostAdapter->UntaggedQueueDepth);
1366 if (HostAdapter->TerminationInfoValid)
1367 if (HostAdapter->HostWideSCSI)
1368 printk("scsi%d: Host Adapter SCSI Bus Termination (Low/High): %s/%s\n",
1369 HostAdapter->HostNumber,
1370 (HostAdapter->LowByteTerminated ? "Enabled" : "Disabled"),
1371 (HostAdapter->HighByteTerminated ? "Enabled" : "Disabled"));
1372 else printk("scsi%d: Host Adapter SCSI Bus Termination: %s\n",
1373 HostAdapter->HostNumber,
1374 (HostAdapter->LowByteTerminated ? "Enabled" : "Disabled"));
1375 CommonErrorRecovery = true;
1376 for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1377 if (HostAdapter->ErrorRecoveryStrategy[TargetID] !=
1378 HostAdapter->ErrorRecoveryStrategy[0])
1379 {
1380 CommonErrorRecovery = false;
1381 break;
1382 }
1383 printk("scsi%d: Error Recovery Strategy: ", HostAdapter->HostNumber);
1384 if (CommonErrorRecovery)
1385 printk("%s", BusLogic_ErrorRecoveryStrategyNames[
1386 HostAdapter->ErrorRecoveryStrategy[0]]);
1387 else
1388 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1389 printk("%s", BusLogic_ErrorRecoveryStrategyLetters[
1390 HostAdapter->ErrorRecoveryStrategy[TargetID]]);
1391 printk("\n");
1392
1393
1394
1395 return true;
1396 }
1397
1398
1399
1400
1401
1402
1403
1404 static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter)
1405 {
1406 if (HostAdapter->IRQ_Channel == 0)
1407 {
1408 printk("scsi%d: NO INTERRUPT CHANNEL ASSIGNED - DETACHING\n",
1409 HostAdapter->HostNumber);
1410 return false;
1411 }
1412
1413
1414
1415
1416 if (BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9]++ == 0)
1417 {
1418 if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler,
1419 SA_INTERRUPT | SA_SHIRQ,
1420 HostAdapter->InterruptLabel, NULL) < 0)
1421 {
1422 BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9]--;
1423 printk("scsi%d: UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
1424 HostAdapter->HostNumber, HostAdapter->IRQ_Channel);
1425 return false;
1426 }
1427 }
1428 else
1429 {
1430 BusLogic_HostAdapter_T *FirstHostAdapter =
1431 BusLogic_RegisteredHostAdapters;
1432 while (FirstHostAdapter != NULL)
1433 {
1434 if (FirstHostAdapter->IRQ_Channel == HostAdapter->IRQ_Channel)
1435 {
1436 if (strlen(FirstHostAdapter->InterruptLabel) + 11
1437 < sizeof(FirstHostAdapter->InterruptLabel))
1438 {
1439 strcat(FirstHostAdapter->InterruptLabel, " + ");
1440 strcat(FirstHostAdapter->InterruptLabel,
1441 HostAdapter->ModelName);
1442 }
1443 break;
1444 }
1445 FirstHostAdapter = FirstHostAdapter->Next;
1446 }
1447 }
1448 HostAdapter->IRQ_ChannelAcquired = true;
1449
1450
1451
1452 if (HostAdapter->DMA_Channel > 0)
1453 {
1454 if (request_dma(HostAdapter->DMA_Channel, HostAdapter->BoardName) < 0)
1455 {
1456 printk("scsi%d: UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n",
1457 HostAdapter->HostNumber, HostAdapter->DMA_Channel);
1458 return false;
1459 }
1460 set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
1461 enable_dma(HostAdapter->DMA_Channel);
1462 HostAdapter->DMA_ChannelAcquired = true;
1463 }
1464
1465
1466
1467 return true;
1468 }
1469
1470
1471
1472
1473
1474
1475
1476 static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *HostAdapter)
1477 {
1478
1479
1480
1481 if (HostAdapter->IRQ_ChannelAcquired)
1482 if (--BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9] == 0)
1483 free_irq(HostAdapter->IRQ_Channel, NULL);
1484
1485
1486
1487 if (HostAdapter->DMA_ChannelAcquired)
1488 free_dma(HostAdapter->DMA_Channel);
1489 }
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501 static boolean BusLogic_TestInterrupts(BusLogic_HostAdapter_T *HostAdapter)
1502 {
1503 unsigned int InitialInterruptCount, FinalInterruptCount;
1504 int TestCount = 5, i;
1505 InitialInterruptCount = kstat.interrupts[HostAdapter->IRQ_Channel];
1506
1507
1508
1509 for (i = 0; i < TestCount; i++)
1510 BusLogic_Command(HostAdapter, BusLogic_TestCommandCompleteInterrupt,
1511 NULL, 0, NULL, 0);
1512
1513
1514
1515
1516
1517 FinalInterruptCount = kstat.interrupts[HostAdapter->IRQ_Channel];
1518 if (FinalInterruptCount < InitialInterruptCount + TestCount)
1519 {
1520 BusLogic_Failure(HostAdapter, "HOST ADAPTER INTERRUPT TEST");
1521 printk("\n\
1522 Interrupts are not getting through from the Host Adapter to the BusLogic\n\
1523 Driver Interrupt Handler. The most likely cause is that either the Host\n\
1524 Adapter or Motherboard is configured incorrectly. Please check the Host\n\
1525 Adapter configuration with AutoSCSI or by examining any dip switch and\n\
1526 jumper settings on the Host Adapter, and verify that no other device is\n\
1527 attempting to use the same IRQ Channel. For PCI Host Adapters, it may also\n\
1528 be necessary to investigate and manually set the PCI interrupt assignments\n\
1529 and edge/level interrupt type selection in the BIOS Setup Program or with\n\
1530 Motherboard jumpers.\n\n");
1531 return false;
1532 }
1533
1534
1535
1536 return true;
1537 }
1538
1539
1540
1541
1542
1543
1544
1545
1546 static boolean BusLogic_InitializeHostAdapter(BusLogic_HostAdapter_T
1547 *HostAdapter)
1548 {
1549 BusLogic_ExtendedMailboxRequest_T ExtendedMailboxRequest;
1550 BusLogic_RoundRobinModeRequest_T RoundRobinModeRequest;
1551 BusLogic_WideModeCCBRequest_T WideModeCCBRequest;
1552 BusLogic_ModifyIOAddressRequest_T ModifyIOAddressRequest;
1553 int TargetID;
1554
1555
1556
1557
1558
1559 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1560 HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
1561 memset(HostAdapter->TaggedQueuingActive, false,
1562 sizeof(HostAdapter->TaggedQueuingActive));
1563 memset(HostAdapter->CommandSuccessfulFlag, false,
1564 sizeof(HostAdapter->CommandSuccessfulFlag));
1565 memset(HostAdapter->ActiveCommandCount, 0,
1566 sizeof(HostAdapter->ActiveCommandCount));
1567 memset(HostAdapter->TotalCommandCount, 0,
1568 sizeof(HostAdapter->TotalCommandCount));
1569
1570
1571
1572 memset(HostAdapter->FirstOutgoingMailbox, 0,
1573 HostAdapter->MailboxCount * sizeof(BusLogic_OutgoingMailbox_T));
1574 memset(HostAdapter->FirstIncomingMailbox, 0,
1575 HostAdapter->MailboxCount * sizeof(BusLogic_IncomingMailbox_T));
1576
1577
1578
1579 HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
1580 HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
1581
1582
1583
1584 ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount;
1585 ExtendedMailboxRequest.BaseMailboxAddress = HostAdapter->FirstOutgoingMailbox;
1586 if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox,
1587 &ExtendedMailboxRequest,
1588 sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
1589 return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION");
1590
1591
1592
1593
1594
1595
1596
1597 if (HostAdapter->StrictRoundRobinModeSupported)
1598 {
1599 RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
1600 if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode,
1601 &RoundRobinModeRequest,
1602 sizeof(RoundRobinModeRequest), NULL, 0) < 0)
1603 return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
1604 }
1605
1606
1607
1608
1609 if (HostAdapter->HostWideSCSI)
1610 {
1611 WideModeCCBRequest = BusLogic_WideModeCCB;
1612 if (BusLogic_Command(HostAdapter, BusLogic_EnableWideModeCCB,
1613 &WideModeCCBRequest,
1614 sizeof(WideModeCCBRequest), NULL, 0) < 0)
1615 return BusLogic_Failure(HostAdapter, "ENABLE WIDE MODE CCB");
1616 }
1617
1618
1619
1620
1621
1622 if (HostAdapter->BusType == BusLogic_PCI_Bus)
1623 {
1624 int Index;
1625 for (Index = 0; BusLogic_IO_StandardAddresses[Index] > 0; Index++)
1626 if (HostAdapter->IO_Address == BusLogic_IO_StandardAddresses[Index])
1627 break;
1628 if (BusLogic_IO_StandardAddresses[Index] == 0)
1629 {
1630 ModifyIOAddressRequest = BusLogic_ModifyIO_Disable;
1631 if (BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress,
1632 &ModifyIOAddressRequest,
1633 sizeof(ModifyIOAddressRequest), NULL, 0) < 0)
1634 return BusLogic_Failure(HostAdapter, "MODIFY I/O ADDRESS");
1635 }
1636 }
1637
1638
1639
1640 printk("scsi%d: *** %s Initialized Successfully ***\n",
1641 HostAdapter->HostNumber, HostAdapter->BoardName);
1642
1643
1644
1645 return true;
1646 }
1647
1648
1649
1650
1651
1652
1653
1654 static boolean BusLogic_InquireTargetDevices(BusLogic_HostAdapter_T
1655 *HostAdapter)
1656 {
1657 BusLogic_InstalledDevices_T InstalledDevices;
1658 BusLogic_InstalledDevices8_T InstalledDevicesID0to7;
1659 BusLogic_SetupInformation_T SetupInformation;
1660 BusLogic_SynchronousPeriod_T SynchronousPeriod;
1661 BusLogic_RequestedReplyLength_T RequestedReplyLength;
1662 int TargetDevicesFound = 0, TargetID;
1663
1664
1665
1666
1667
1668 BusLogic_Delay(HostAdapter->BusSettleTime);
1669
1670
1671
1672 if (HostAdapter->LocalOptions & BusLogic_InhibitTargetInquiry)
1673 {
1674 printk("scsi%d: Target Device Inquiry Inhibited\n",
1675 HostAdapter->HostNumber);
1676 return true;
1677 }
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687 if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0)
1688 {
1689 if (BusLogic_Command(HostAdapter, BusLogic_InquireDevices, NULL, 0,
1690 &InstalledDevices, sizeof(InstalledDevices))
1691 != sizeof(InstalledDevices))
1692 return BusLogic_Failure(HostAdapter, "INQUIRE DEVICES");
1693 }
1694 else
1695 {
1696 if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7,
1697 NULL, 0, &InstalledDevicesID0to7,
1698 sizeof(InstalledDevicesID0to7))
1699 != sizeof(InstalledDevicesID0to7))
1700 return BusLogic_Failure(HostAdapter,
1701 "INQUIRE INSTALLED DEVICES ID 0 TO 7");
1702 InstalledDevices = 0;
1703 for (TargetID = 0; TargetID < 8; TargetID++)
1704 if (InstalledDevicesID0to7[TargetID] != 0)
1705 InstalledDevices |= (1 << TargetID);
1706 }
1707
1708
1709
1710 RequestedReplyLength = sizeof(SetupInformation);
1711 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
1712 &RequestedReplyLength, sizeof(RequestedReplyLength),
1713 &SetupInformation, sizeof(SetupInformation))
1714 != sizeof(SetupInformation))
1715 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
1716
1717
1718
1719 if (HostAdapter->FirmwareVersion[0] >= '3')
1720 {
1721 RequestedReplyLength = sizeof(SynchronousPeriod);
1722 if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod,
1723 &RequestedReplyLength, sizeof(RequestedReplyLength),
1724 &SynchronousPeriod, sizeof(SynchronousPeriod))
1725 != sizeof(SynchronousPeriod))
1726 return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
1727 }
1728 else
1729 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1730 if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
1731 SynchronousPeriod[TargetID] =
1732 20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
1733 .TransferPeriod;
1734 else SynchronousPeriod[TargetID] = 0;
1735
1736
1737
1738
1739 HostAdapter->InstalledDevices = InstalledDevices;
1740 memcpy(HostAdapter->SynchronousValues,
1741 SetupInformation.SynchronousValuesID0to7,
1742 sizeof(BusLogic_SynchronousValues8_T));
1743 if (HostAdapter->HostWideSCSI)
1744 memcpy(&HostAdapter->SynchronousValues[8],
1745 SetupInformation.SynchronousValuesID8to15,
1746 sizeof(BusLogic_SynchronousValues8_T));
1747 memcpy(HostAdapter->SynchronousPeriod, SynchronousPeriod,
1748 sizeof(BusLogic_SynchronousPeriod_T));
1749
1750
1751
1752 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1753 if (HostAdapter->InstalledDevices & (1 << TargetID))
1754 {
1755 int SynchronousPeriod = HostAdapter->SynchronousPeriod[TargetID];
1756 if (SynchronousPeriod > 10)
1757 {
1758 int SynchronousTransferRate = 100000000 / SynchronousPeriod;
1759 int RoundedSynchronousTransferRate =
1760 (SynchronousTransferRate + 5000) / 10000;
1761 printk("scsi%d: Target %d: Synchronous at "
1762 "%d.%02d mega-transfers/second, offset %d\n",
1763 HostAdapter->HostNumber, TargetID,
1764 RoundedSynchronousTransferRate / 100,
1765 RoundedSynchronousTransferRate % 100,
1766 HostAdapter->SynchronousValues[TargetID].Offset);
1767 }
1768 else if (SynchronousPeriod > 0)
1769 {
1770 int SynchronousTransferRate = 100000000 / SynchronousPeriod;
1771 int RoundedSynchronousTransferRate =
1772 (SynchronousTransferRate + 50000) / 100000;
1773 printk("scsi%d: Target %d: Synchronous at "
1774 "%d.%01d mega-transfers/second, offset %d\n",
1775 HostAdapter->HostNumber, TargetID,
1776 RoundedSynchronousTransferRate / 10,
1777 RoundedSynchronousTransferRate % 10,
1778 HostAdapter->SynchronousValues[TargetID].Offset);
1779 }
1780 else printk("scsi%d: Target %d: Asynchronous\n",
1781 HostAdapter->HostNumber, TargetID);
1782 TargetDevicesFound++;
1783 }
1784 if (TargetDevicesFound == 0)
1785 printk("scsi%d: No Target Devices Found\n", HostAdapter->HostNumber);
1786
1787
1788
1789 return true;
1790 }
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802 static void BusLogic_InitializeHostStructure(BusLogic_HostAdapter_T
1803 *HostAdapter,
1804 SCSI_Host_T *Host)
1805 {
1806 Host->max_id = HostAdapter->MaxTargetDevices;
1807 Host->max_lun = HostAdapter->MaxLogicalUnits;
1808 Host->max_channel = 0;
1809 Host->unique_id = HostAdapter->IO_Address;
1810 Host->this_id = HostAdapter->SCSI_ID;
1811 Host->can_queue = HostAdapter->MailboxCount;
1812 Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
1813 Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
1814 Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth;
1815 }
1816
1817
1818
1819
1820
1821
1822
1823
1824 static void BusLogic_SelectQueueDepths(SCSI_Host_T *Host,
1825 SCSI_Device_T *DeviceList)
1826 {
1827 BusLogic_HostAdapter_T *HostAdapter =
1828 (BusLogic_HostAdapter_T *) Host->hostdata;
1829 int TaggedQueueDepth = HostAdapter->TaggedQueueDepth;
1830 int UntaggedQueueDepth = HostAdapter->UntaggedQueueDepth;
1831 int TaggedDeviceCount = 0, UntaggedDeviceCount = 0;
1832 SCSI_Device_T *Device;
1833 for (Device = DeviceList; Device != NULL; Device = Device->next)
1834 if (Device->host == Host)
1835 {
1836 if (Device->tagged_supported &&
1837 (HostAdapter->TaggedQueuingPermitted & (1 << Device->id)))
1838 TaggedDeviceCount++;
1839 else UntaggedDeviceCount++;
1840 }
1841 if (TaggedQueueDepth == 0 && TaggedDeviceCount > 0)
1842 TaggedQueueDepth =
1843 1 + ((HostAdapter->TotalQueueDepth
1844 - UntaggedDeviceCount * UntaggedQueueDepth)
1845 / TaggedDeviceCount);
1846 if (TaggedQueueDepth > BusLogic_MaxTaggedQueueDepth)
1847 TaggedQueueDepth = BusLogic_MaxTaggedQueueDepth;
1848 for (Device = DeviceList; Device != NULL; Device = Device->next)
1849 if (Device->host == Host)
1850 {
1851 if (Device->tagged_supported &&
1852 (HostAdapter->TaggedQueuingPermitted & (1 << Device->id)))
1853 Device->queue_depth = TaggedQueueDepth;
1854 else Device->queue_depth = UntaggedQueueDepth;
1855 if (BusLogic_GlobalOptions & BusLogic_TraceQueueDepths)
1856 printk("scsi%d: Setting Queue Depth for Target %d to %d\n",
1857 HostAdapter->HostNumber, Device->id, Device->queue_depth);
1858 }
1859 }
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870 int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate)
1871 {
1872 int BusLogicHostAdapterCount = 0, CommandLineEntryIndex = 0;
1873 int AddressProbeIndex = 0;
1874 BusLogic_InitializeAddressProbeList();
1875 while (BusLogic_IO_AddressProbeList[AddressProbeIndex] > 0)
1876 {
1877 BusLogic_HostAdapter_T HostAdapterPrototype;
1878 BusLogic_HostAdapter_T *HostAdapter = &HostAdapterPrototype;
1879 SCSI_Host_T *Host;
1880 memset(HostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
1881 HostAdapter->IO_Address =
1882 BusLogic_IO_AddressProbeList[AddressProbeIndex++];
1883
1884
1885
1886
1887 if (CommandLineEntryIndex < BusLogic_CommandLineEntryCount &&
1888 BusLogic_CommandLineEntries[CommandLineEntryIndex].IO_Address ==
1889 HostAdapter->IO_Address)
1890 HostAdapter->CommandLineEntry =
1891 &BusLogic_CommandLineEntries[CommandLineEntryIndex++];
1892
1893
1894
1895 if (check_region(HostAdapter->IO_Address, BusLogic_IO_PortCount) < 0)
1896 continue;
1897
1898
1899
1900 if (!BusLogic_ProbeHostAdapter(HostAdapter)) continue;
1901
1902
1903
1904
1905 if (!BusLogic_HardResetHostAdapter(HostAdapter)) continue;
1906
1907
1908
1909 if (!BusLogic_CheckHostAdapter(HostAdapter)) continue;
1910
1911
1912
1913
1914 if (CommandLineEntryIndex < BusLogic_CommandLineEntryCount &&
1915 BusLogic_CommandLineEntries[CommandLineEntryIndex].IO_Address == 0)
1916 HostAdapter->CommandLineEntry =
1917 &BusLogic_CommandLineEntries[CommandLineEntryIndex++];
1918
1919
1920
1921
1922 BusLogic_AnnounceDriver();
1923
1924
1925
1926
1927
1928
1929
1930
1931 request_region(HostAdapter->IO_Address, BusLogic_IO_PortCount,
1932 "BusLogic");
1933
1934
1935
1936 HostTemplate->proc_dir = &BusLogic_ProcDirectoryEntry;
1937 Host = scsi_register(HostTemplate, sizeof(BusLogic_HostAdapter_T));
1938 HostAdapter = (BusLogic_HostAdapter_T *) Host->hostdata;
1939 memcpy(HostAdapter, &HostAdapterPrototype,
1940 sizeof(BusLogic_HostAdapter_T));
1941 HostAdapter->SCSI_Host = Host;
1942 HostAdapter->HostNumber = Host->host_no;
1943 Host->select_queue_depths = BusLogic_SelectQueueDepths;
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953 BusLogic_RegisterHostAdapter(HostAdapter);
1954
1955
1956
1957
1958
1959
1960
1961 if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
1962 BusLogic_AcquireResources(HostAdapter) &&
1963 BusLogic_TestInterrupts(HostAdapter) &&
1964 BusLogic_CreateMailboxes(HostAdapter) &&
1965 BusLogic_CreateCCBs(HostAdapter) &&
1966 BusLogic_InitializeHostAdapter(HostAdapter) &&
1967 BusLogic_InquireTargetDevices(HostAdapter))
1968 {
1969
1970
1971
1972
1973
1974
1975 release_region(HostAdapter->IO_Address, BusLogic_IO_PortCount);
1976 request_region(HostAdapter->IO_Address, BusLogic_IO_PortCount,
1977 HostAdapter->BoardName);
1978 BusLogic_InitializeHostStructure(HostAdapter, Host);
1979 BusLogicHostAdapterCount++;
1980 }
1981 else
1982 {
1983
1984
1985
1986
1987
1988
1989
1990
1991 BusLogic_DestroyCCBs(HostAdapter);
1992 BusLogic_DestroyMailboxes(HostAdapter);
1993 BusLogic_ReleaseResources(HostAdapter);
1994 BusLogic_UnregisterHostAdapter(HostAdapter);
1995 scsi_unregister(Host);
1996 }
1997 }
1998 return BusLogicHostAdapterCount;
1999 }
2000
2001
2002
2003
2004
2005
2006
2007
2008 int BusLogic_ReleaseHostAdapter(SCSI_Host_T *Host)
2009 {
2010 BusLogic_HostAdapter_T *HostAdapter =
2011 (BusLogic_HostAdapter_T *) Host->hostdata;
2012
2013
2014
2015
2016 BusLogic_DestroyCCBs(HostAdapter);
2017 BusLogic_DestroyMailboxes(HostAdapter);
2018 BusLogic_ReleaseResources(HostAdapter);
2019
2020
2021
2022 release_region(HostAdapter->IO_Address, BusLogic_IO_PortCount);
2023
2024
2025
2026 BusLogic_UnregisterHostAdapter(HostAdapter);
2027 return 0;
2028 }
2029
2030
2031
2032
2033
2034
2035
2036 static int BusLogic_ComputeResultCode(BusLogic_HostAdapterStatus_T
2037 HostAdapterStatus,
2038 BusLogic_TargetDeviceStatus_T
2039 TargetDeviceStatus)
2040 {
2041 int HostStatus;
2042 switch (HostAdapterStatus)
2043 {
2044 case BusLogic_CommandCompletedNormally:
2045 case BusLogic_LinkedCommandCompleted:
2046 case BusLogic_LinkedCommandCompletedWithFlag:
2047 HostStatus = DID_OK;
2048 break;
2049 case BusLogic_SCSISelectionTimeout:
2050 HostStatus = DID_TIME_OUT;
2051 break;
2052 case BusLogic_InvalidOutgoingMailboxActionCode:
2053 case BusLogic_InvalidCommandOperationCode:
2054 case BusLogic_InvalidCommandParameter:
2055 printk("BusLogic: BusLogic Driver Protocol Error 0x%02X\n",
2056 HostAdapterStatus);
2057 case BusLogic_DataOverUnderRun:
2058 case BusLogic_UnexpectedBusFree:
2059 case BusLogic_LinkedCCBhasInvalidLUN:
2060 case BusLogic_AutoRequestSenseFailed:
2061 case BusLogic_TaggedQueuingMessageRejected:
2062 case BusLogic_UnsupportedMessageReceived:
2063 case BusLogic_HostAdapterHardwareFailed:
2064 case BusLogic_TargetDeviceReconnectedImproperly:
2065 case BusLogic_AbortQueueGenerated:
2066 case BusLogic_HostAdapterSoftwareError:
2067 case BusLogic_HostAdapterHardwareTimeoutError:
2068 case BusLogic_SCSIParityErrorDetected:
2069 HostStatus = DID_ERROR;
2070 break;
2071 case BusLogic_InvalidBusPhaseRequested:
2072 case BusLogic_TargetFailedResponseToATN:
2073 case BusLogic_HostAdapterAssertedRST:
2074 case BusLogic_OtherDeviceAssertedRST:
2075 case BusLogic_HostAdapterAssertedBusDeviceReset:
2076 HostStatus = DID_RESET;
2077 break;
2078 default:
2079 printk("BusLogic: unknown Host Adapter Status 0x%02X\n",
2080 HostAdapterStatus);
2081 HostStatus = DID_ERROR;
2082 break;
2083 }
2084 return (HostStatus << 16) | TargetDeviceStatus;
2085 }
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095 static void BusLogic_InterruptHandler(int IRQ_Channel,
2096 void *DeviceIdentifier,
2097 Registers_T *InterruptRegisters)
2098 {
2099 BusLogic_CCB_T *FirstCompletedCCB = NULL, *LastCompletedCCB = NULL;
2100 BusLogic_HostAdapter_T *HostAdapter;
2101 int HostAdapterResetRequestedCount = 0;
2102 BusLogic_Lock_T Lock;
2103
2104
2105
2106
2107
2108
2109 for (HostAdapter = BusLogic_RegisteredHostAdapters;
2110 HostAdapter != NULL;
2111 HostAdapter = HostAdapter->Next)
2112 {
2113 unsigned char InterruptRegister;
2114
2115
2116
2117 BusLogic_AcquireHostAdapterLockID(HostAdapter, &Lock);
2118
2119
2120
2121 InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
2122 if (InterruptRegister & BusLogic_InterruptValid)
2123 {
2124
2125
2126
2127
2128 BusLogic_WriteControlRegister(HostAdapter, BusLogic_InterruptReset);
2129
2130
2131
2132
2133
2134
2135 if (InterruptRegister & BusLogic_SCSIResetState)
2136 {
2137 HostAdapter->HostAdapterResetRequested = true;
2138 HostAdapterResetRequestedCount++;
2139 }
2140 else if (InterruptRegister & BusLogic_IncomingMailboxLoaded)
2141 {
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156 BusLogic_IncomingMailbox_T *NextIncomingMailbox =
2157 HostAdapter->NextIncomingMailbox;
2158 BusLogic_CompletionCode_T MailboxCompletionCode;
2159 while ((MailboxCompletionCode =
2160 NextIncomingMailbox->CompletionCode) !=
2161 BusLogic_IncomingMailboxFree)
2162 {
2163 BusLogic_CCB_T *CCB = NextIncomingMailbox->CCB;
2164 if (MailboxCompletionCode != BusLogic_AbortedCommandNotFound)
2165 if (CCB->Status == BusLogic_CCB_Active ||
2166 CCB->Status == BusLogic_CCB_Reset)
2167 {
2168
2169
2170
2171
2172 CCB->Status = BusLogic_CCB_Completed;
2173 CCB->MailboxCompletionCode = MailboxCompletionCode;
2174 CCB->Next = NULL;
2175 if (FirstCompletedCCB == NULL)
2176 {
2177 FirstCompletedCCB = CCB;
2178 LastCompletedCCB = CCB;
2179 }
2180 else
2181 {
2182 LastCompletedCCB->Next = CCB;
2183 LastCompletedCCB = CCB;
2184 }
2185 HostAdapter->ActiveCommandCount[CCB->TargetID]--;
2186 }
2187 else
2188 {
2189
2190
2191
2192
2193
2194 printk("scsi%d: Illegal CCB #%d status %d in "
2195 "Incoming Mailbox\n", HostAdapter->HostNumber,
2196 CCB->SerialNumber, CCB->Status);
2197 }
2198 else printk("scsi%d: Aborted CCB #%d to Target %d "
2199 "Not Found\n", HostAdapter->HostNumber,
2200 CCB->SerialNumber, CCB->TargetID);
2201 NextIncomingMailbox->CompletionCode =
2202 BusLogic_IncomingMailboxFree;
2203 if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
2204 NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
2205 }
2206 HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
2207 }
2208 else if (InterruptRegister & BusLogic_CommandComplete)
2209 HostAdapter->HostAdapterCommandCompleted = true;
2210 }
2211
2212
2213
2214 BusLogic_ReleaseHostAdapterLockID(HostAdapter, &Lock);
2215 }
2216
2217
2218
2219
2220 while (FirstCompletedCCB != NULL)
2221 {
2222 BusLogic_CCB_T *CCB = FirstCompletedCCB;
2223 SCSI_Command_T *Command = CCB->Command;
2224 FirstCompletedCCB = FirstCompletedCCB->Next;
2225 HostAdapter = CCB->HostAdapter;
2226
2227
2228
2229 BusLogic_AcquireHostAdapterLockID(HostAdapter, &Lock);
2230
2231
2232
2233 if (CCB->Opcode == BusLogic_BusDeviceReset)
2234 {
2235 unsigned char TargetID = CCB->TargetID;
2236 printk("scsi%d: Bus Device Reset CCB #%d to Target %d Completed\n",
2237 HostAdapter->HostNumber, CCB->SerialNumber, TargetID);
2238 HostAdapter->TotalCommandCount[TargetID] = 0;
2239 HostAdapter->TaggedQueuingActive[TargetID] = false;
2240
2241
2242
2243 BusLogic_DeallocateCCB(CCB);
2244
2245
2246
2247
2248
2249
2250
2251 while (Command != NULL)
2252 {
2253 SCSI_Command_T *NextCommand = Command->reset_chain;
2254 Command->reset_chain = NULL;
2255 Command->result = DID_RESET << 16;
2256 Command->scsi_done(Command);
2257 Command = NextCommand;
2258 }
2259
2260
2261
2262
2263 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2264 if (CCB->Status == BusLogic_CCB_Reset && CCB->TargetID == TargetID)
2265 {
2266 Command = CCB->Command;
2267 BusLogic_DeallocateCCB(CCB);
2268 HostAdapter->ActiveCommandCount[TargetID]--;
2269 Command->result = DID_RESET << 16;
2270 Command->scsi_done(Command);
2271 }
2272 HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
2273 }
2274 else
2275 {
2276
2277
2278
2279
2280 switch (CCB->MailboxCompletionCode)
2281 {
2282 case BusLogic_IncomingMailboxFree:
2283 case BusLogic_AbortedCommandNotFound:
2284 printk("scsi%d: CCB #%d to Target %d Impossible State\n",
2285 HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
2286 break;
2287 case BusLogic_CommandCompletedWithoutError:
2288 HostAdapter->CommandSuccessfulFlag[CCB->TargetID] = true;
2289 Command->result = DID_OK << 16;
2290 break;
2291 case BusLogic_CommandAbortedAtHostRequest:
2292 printk("scsi%d: CCB #%d to Target %d Aborted\n",
2293 HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
2294 Command->result = DID_ABORT << 16;
2295 break;
2296 case BusLogic_CommandCompletedWithError:
2297 Command->result =
2298 BusLogic_ComputeResultCode(CCB->HostAdapterStatus,
2299 CCB->TargetDeviceStatus);
2300 if (BusLogic_GlobalOptions & BusLogic_TraceErrors)
2301 if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout)
2302 {
2303 int i;
2304 printk("scsi%d: CCB #%d Target %d: Result %X "
2305 "Host Adapter Status %02X Target Status %02X\n",
2306 HostAdapter->HostNumber, CCB->SerialNumber,
2307 CCB->TargetID, Command->result,
2308 CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
2309 printk("scsi%d: CDB ", HostAdapter->HostNumber);
2310 for (i = 0; i < CCB->CDB_Length; i++)
2311 printk(" %02X", CCB->CDB[i]);
2312 printk("\n");
2313 printk("scsi%d: Sense ", HostAdapter->HostNumber);
2314 for (i = 0; i < CCB->SenseDataLength; i++)
2315 printk(" %02X", (*CCB->SenseDataPointer)[i]);
2316 printk("\n");
2317 }
2318 break;
2319 }
2320
2321
2322
2323 BusLogic_DeallocateCCB(CCB);
2324
2325
2326
2327 Command->scsi_done(Command);
2328 }
2329
2330
2331
2332 BusLogic_ReleaseHostAdapterLockID(HostAdapter, &Lock);
2333 }
2334
2335
2336
2337 if (HostAdapterResetRequestedCount == 0) return;
2338 for (HostAdapter = BusLogic_RegisteredHostAdapters;
2339 HostAdapter != NULL;
2340 HostAdapter = HostAdapter->Next)
2341 if (HostAdapter->HostAdapterResetRequested)
2342 {
2343 BusLogic_ResetHostAdapter(HostAdapter, NULL, 0);
2344 HostAdapter->HostAdapterResetRequested = false;
2345 scsi_mark_host_reset(HostAdapter->SCSI_Host);
2346 }
2347 }
2348
2349
2350
2351
2352
2353
2354
2355
2356 static boolean BusLogic_WriteOutgoingMailbox(BusLogic_HostAdapter_T
2357 *HostAdapter,
2358 BusLogic_ActionCode_T ActionCode,
2359 BusLogic_CCB_T *CCB)
2360 {
2361 BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
2362 NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
2363 if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree)
2364 {
2365 CCB->Status = BusLogic_CCB_Active;
2366
2367
2368
2369
2370
2371 NextOutgoingMailbox->CCB = CCB;
2372 NextOutgoingMailbox->ActionCode = ActionCode;
2373 BusLogic_StartMailboxCommand(HostAdapter);
2374 if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
2375 NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
2376 HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
2377 if (ActionCode == BusLogic_MailboxStartCommand)
2378 HostAdapter->ActiveCommandCount[CCB->TargetID]++;
2379 return true;
2380 }
2381 return false;
2382 }
2383
2384
2385
2386
2387
2388
2389
2390 int BusLogic_QueueCommand(SCSI_Command_T *Command,
2391 void (*CompletionRoutine)(SCSI_Command_T *))
2392 {
2393 BusLogic_HostAdapter_T *HostAdapter =
2394 (BusLogic_HostAdapter_T *) Command->host->hostdata;
2395 unsigned char *CDB = Command->cmnd;
2396 unsigned char CDB_Length = Command->cmd_len;
2397 unsigned char TargetID = Command->target;
2398 unsigned char LogicalUnit = Command->lun;
2399 void *BufferPointer = Command->request_buffer;
2400 int BufferLength = Command->request_bufflen;
2401 int SegmentCount = Command->use_sg;
2402 BusLogic_Lock_T Lock;
2403 BusLogic_CCB_T *CCB;
2404
2405
2406
2407
2408
2409 if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0)
2410 {
2411 Command->result = DID_OK << 16;
2412 CompletionRoutine(Command);
2413 return 0;
2414 }
2415
2416
2417
2418 BusLogic_AcquireHostAdapterLock(HostAdapter, &Lock);
2419
2420
2421
2422
2423
2424
2425 CCB = BusLogic_AllocateCCB(HostAdapter);
2426 if (CCB == NULL)
2427 {
2428 BusLogic_Delay(1);
2429 CCB = BusLogic_AllocateCCB(HostAdapter);
2430 if (CCB == NULL)
2431 {
2432 Command->result = DID_ERROR << 16;
2433 CompletionRoutine(Command);
2434 goto Done;
2435 }
2436 }
2437
2438
2439
2440 if (SegmentCount == 0)
2441 {
2442 CCB->Opcode = BusLogic_InitiatorCCB;
2443 CCB->DataLength = BufferLength;
2444 CCB->DataPointer = BufferPointer;
2445 }
2446 else
2447 {
2448 SCSI_ScatterList_T *ScatterList = (SCSI_ScatterList_T *) BufferPointer;
2449 int Segment;
2450 CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
2451 CCB->DataLength = SegmentCount * sizeof(BusLogic_ScatterGatherSegment_T);
2452 CCB->DataPointer = CCB->ScatterGatherList;
2453 for (Segment = 0; Segment < SegmentCount; Segment++)
2454 {
2455 CCB->ScatterGatherList[Segment].SegmentByteCount =
2456 ScatterList[Segment].length;
2457 CCB->ScatterGatherList[Segment].SegmentDataPointer =
2458 ScatterList[Segment].address;
2459 }
2460 }
2461 switch (CDB[0])
2462 {
2463 case READ_6:
2464 case READ_10:
2465 CCB->DataDirection = BusLogic_DataInLengthChecked;
2466 break;
2467 case WRITE_6:
2468 case WRITE_10:
2469 CCB->DataDirection = BusLogic_DataOutLengthChecked;
2470 break;
2471 default:
2472 CCB->DataDirection = BusLogic_UncheckedDataTransfer;
2473 break;
2474 }
2475 CCB->CDB_Length = CDB_Length;
2476 CCB->SenseDataLength = sizeof(Command->sense_buffer);
2477 CCB->HostAdapterStatus = 0;
2478 CCB->TargetDeviceStatus = 0;
2479 CCB->TargetID = TargetID;
2480 CCB->LogicalUnit = LogicalUnit;
2481
2482
2483
2484
2485
2486 if (HostAdapter->HostWideSCSI)
2487 {
2488 CCB->TagEnable = LogicalUnit >> 5;
2489 CCB->WideModeTagEnable = false;
2490 }
2491 else CCB->TagEnable = false;
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503 if (HostAdapter->TotalCommandCount[TargetID]++ ==
2504 BusLogic_MaxTaggedQueueDepth &&
2505 (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)) &&
2506 Command->device->tagged_supported)
2507 {
2508 HostAdapter->TaggedQueuingActive[TargetID] = true;
2509 printk("scsi%d: Tagged Queuing now active for Target %d\n",
2510 HostAdapter->HostNumber, TargetID);
2511 }
2512 if (HostAdapter->TaggedQueuingActive[TargetID])
2513 {
2514 BusLogic_QueueTag_T QueueTag = BusLogic_SimpleQueueTag;
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528 if (HostAdapter->ActiveCommandCount[TargetID] == 0)
2529 HostAdapter->LastSequencePoint[TargetID] = jiffies;
2530 else if (jiffies - HostAdapter->LastSequencePoint[TargetID] > 5*HZ)
2531 {
2532 HostAdapter->LastSequencePoint[TargetID] = jiffies;
2533 QueueTag = BusLogic_OrderedQueueTag;
2534 }
2535 if (HostAdapter->HostWideSCSI)
2536 {
2537 CCB->WideModeTagEnable = true;
2538 CCB->WideModeQueueTag = QueueTag;
2539 }
2540 else
2541 {
2542 CCB->TagEnable = true;
2543 CCB->QueueTag = QueueTag;
2544 }
2545 }
2546 memcpy(CCB->CDB, CDB, CDB_Length);
2547 CCB->SenseDataPointer = (SCSI_SenseData_T *) &Command->sense_buffer;
2548 CCB->Command = Command;
2549 Command->scsi_done = CompletionRoutine;
2550
2551
2552
2553
2554
2555
2556
2557
2558 if (!BusLogic_WriteOutgoingMailbox(HostAdapter,
2559 BusLogic_MailboxStartCommand, CCB))
2560 {
2561 printk("scsi%d: cannot write Outgoing Mailbox - Pausing for 1 second\n",
2562 HostAdapter->HostNumber);
2563 BusLogic_Delay(1);
2564 if (!BusLogic_WriteOutgoingMailbox(HostAdapter,
2565 BusLogic_MailboxStartCommand, CCB))
2566 {
2567 printk("scsi%d: still cannot write Outgoing Mailbox - "
2568 "Host Adapter Dead?\n", HostAdapter->HostNumber);
2569 BusLogic_DeallocateCCB(CCB);
2570 Command->result = DID_ERROR << 16;
2571 Command->scsi_done(Command);
2572 }
2573 }
2574
2575
2576
2577 Done:
2578 BusLogic_ReleaseHostAdapterLock(HostAdapter, &Lock);
2579 return 0;
2580 }
2581
2582
2583
2584
2585
2586
2587 int BusLogic_AbortCommand(SCSI_Command_T *Command)
2588 {
2589 BusLogic_HostAdapter_T *HostAdapter =
2590 (BusLogic_HostAdapter_T *) Command->host->hostdata;
2591 unsigned char TargetID = Command->target;
2592 BusLogic_Lock_T Lock;
2593 BusLogic_CCB_T *CCB;
2594 int Result;
2595
2596
2597
2598 BusLogic_AcquireHostAdapterLock(HostAdapter, &Lock);
2599
2600
2601
2602 if (Command->serial_number != Command->serial_number_at_timeout)
2603 {
2604 printk("scsi%d: Unable to Abort Command to Target %d - "
2605 "Already Completed\n", HostAdapter->HostNumber, TargetID);
2606 Result = SCSI_ABORT_NOT_RUNNING;
2607 goto Done;
2608 }
2609
2610
2611
2612
2613 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2614 if (CCB->Command == Command) break;
2615 if (CCB == NULL)
2616 {
2617 printk("scsi%d: Unable to Abort Command to Target %d - No CCB Found\n",
2618 HostAdapter->HostNumber, TargetID);
2619 Result = SCSI_ABORT_NOT_RUNNING;
2620 goto Done;
2621 }
2622 else if (CCB->Status == BusLogic_CCB_Completed)
2623 {
2624 printk("scsi%d: Unable to Abort Command to Target %d - CCB Completed\n",
2625 HostAdapter->HostNumber, TargetID);
2626 Result = SCSI_ABORT_NOT_RUNNING;
2627 goto Done;
2628 }
2629 else if (CCB->Status == BusLogic_CCB_Reset)
2630 {
2631 printk("scsi%d: Unable to Abort Command to Target %d - CCB Reset\n",
2632 HostAdapter->HostNumber, TargetID);
2633 Result = SCSI_ABORT_NOT_RUNNING;
2634 goto Done;
2635 }
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646 if (HostAdapter->TaggedQueuingActive[TargetID] &&
2647 HostAdapter->FirmwareVersion[0] < '5')
2648 {
2649 printk("scsi%d: Unable to Abort CCB #%d to Target %d - "
2650 "Abort Tag Not Supported\n", HostAdapter->HostNumber,
2651 CCB->SerialNumber, TargetID);
2652 Result = SCSI_ABORT_SNOOZE;
2653 }
2654 else if (BusLogic_WriteOutgoingMailbox(HostAdapter,
2655 BusLogic_MailboxAbortCommand, CCB))
2656 {
2657 printk("scsi%d: Aborting CCB #%d to Target %d\n",
2658 HostAdapter->HostNumber, CCB->SerialNumber, TargetID);
2659 Result = SCSI_ABORT_PENDING;
2660 }
2661 else
2662 {
2663 printk("scsi%d: Unable to Abort CCB #%d to Target %d - "
2664 "No Outgoing Mailboxes\n", HostAdapter->HostNumber,
2665 CCB->SerialNumber, TargetID);
2666 Result = SCSI_ABORT_BUSY;
2667 }
2668
2669
2670
2671 Done:
2672 BusLogic_ReleaseHostAdapterLock(HostAdapter, &Lock);
2673 return Result;
2674 }
2675
2676
2677
2678
2679
2680
2681
2682 static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter,
2683 SCSI_Command_T *Command,
2684 unsigned int ResetFlags)
2685 {
2686 BusLogic_Lock_T Lock;
2687 BusLogic_CCB_T *CCB;
2688 int TargetID, Result;
2689
2690
2691
2692 BusLogic_AcquireHostAdapterLock(HostAdapter, &Lock);
2693
2694
2695
2696
2697 if (ResetFlags & SCSI_RESET_ASYNCHRONOUS)
2698 {
2699 TargetID = Command->target;
2700 if (Command->serial_number != Command->serial_number_at_timeout)
2701 {
2702 printk("scsi%d: Unable to Reset Command to Target %d - "
2703 "Already Completed or Reset\n",
2704 HostAdapter->HostNumber, TargetID);
2705 Result = SCSI_RESET_NOT_RUNNING;
2706 goto Done;
2707 }
2708 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2709 if (CCB->Command == Command) break;
2710 if (CCB == NULL)
2711 {
2712 printk("scsi%d: Unable to Reset Command to Target %d - "
2713 "No CCB Found\n", HostAdapter->HostNumber, TargetID);
2714 Result = SCSI_RESET_NOT_RUNNING;
2715 goto Done;
2716 }
2717 else if (CCB->Status == BusLogic_CCB_Completed)
2718 {
2719 printk("scsi%d: Unable to Reset Command to Target %d - "
2720 "CCB Completed\n", HostAdapter->HostNumber, TargetID);
2721 Result = SCSI_RESET_NOT_RUNNING;
2722 goto Done;
2723 }
2724 else if (CCB->Status == BusLogic_CCB_Reset &&
2725 HostAdapter->BusDeviceResetPendingCCB[TargetID] == NULL)
2726 {
2727 printk("scsi%d: Unable to Reset Command to Target %d - "
2728 "Reset Pending\n", HostAdapter->HostNumber, TargetID);
2729 Result = SCSI_RESET_PENDING;
2730 goto Done;
2731 }
2732 }
2733 if (Command == NULL)
2734 printk("scsi%d: Resetting %s due to SCSI Reset State Interrupt\n",
2735 HostAdapter->HostNumber, HostAdapter->BoardName);
2736 else printk("scsi%d: Resetting %s due to Target %d\n",
2737 HostAdapter->HostNumber, HostAdapter->BoardName, Command->target);
2738
2739
2740
2741 if (!(BusLogic_HardResetHostAdapter(HostAdapter) &&
2742 BusLogic_InitializeHostAdapter(HostAdapter)))
2743 {
2744 printk("scsi%d: Resetting %s Failed\n",
2745 HostAdapter->HostNumber, HostAdapter->BoardName);
2746 Result = SCSI_RESET_ERROR;
2747 goto Done;
2748 }
2749
2750
2751
2752 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2753 if (CCB->Status == BusLogic_CCB_Active)
2754 CCB->Status = BusLogic_CCB_Reset;
2755
2756
2757
2758
2759
2760
2761
2762 BusLogic_Delay(HostAdapter->BusSettleTime);
2763
2764
2765
2766
2767 if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
2768 {
2769 Command->result = DID_RESET << 16;
2770 Command->scsi_done(Command);
2771 }
2772
2773
2774
2775 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2776 if (CCB->Status == BusLogic_CCB_Reset)
2777 {
2778 Command = CCB->Command;
2779 BusLogic_DeallocateCCB(CCB);
2780 while (Command != NULL)
2781 {
2782 SCSI_Command_T *NextCommand = Command->reset_chain;
2783 Command->reset_chain = NULL;
2784 Command->result = DID_RESET << 16;
2785 Command->scsi_done(Command);
2786 Command = NextCommand;
2787 }
2788 }
2789 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2790 HostAdapter->LastResetTime[TargetID] = jiffies;
2791 Result = SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET;
2792
2793
2794
2795 Done:
2796 BusLogic_ReleaseHostAdapterLock(HostAdapter, &Lock);
2797 return Result;
2798 }
2799
2800
2801
2802
2803
2804
2805
2806 static int BusLogic_SendBusDeviceReset(BusLogic_HostAdapter_T *HostAdapter,
2807 SCSI_Command_T *Command,
2808 unsigned int ResetFlags)
2809 {
2810 unsigned char TargetID = Command->target;
2811 BusLogic_Lock_T Lock;
2812 BusLogic_CCB_T *CCB;
2813 int Result = -1;
2814
2815
2816
2817 BusLogic_AcquireHostAdapterLock(HostAdapter, &Lock);
2818
2819
2820
2821
2822 if (ResetFlags & SCSI_RESET_ASYNCHRONOUS)
2823 {
2824 if (Command->serial_number != Command->serial_number_at_timeout)
2825 {
2826 printk("scsi%d: Unable to Reset Command to Target %d - "
2827 "Already Completed\n", HostAdapter->HostNumber, TargetID);
2828 Result = SCSI_RESET_NOT_RUNNING;
2829 goto Done;
2830 }
2831 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2832 if (CCB->Command == Command) break;
2833 if (CCB == NULL)
2834 {
2835 printk("scsi%d: Unable to Reset Command to Target %d - "
2836 "No CCB Found\n", HostAdapter->HostNumber, TargetID);
2837 Result = SCSI_RESET_NOT_RUNNING;
2838 goto Done;
2839 }
2840 else if (CCB->Status == BusLogic_CCB_Completed)
2841 {
2842 printk("scsi%d: Unable to Reset Command to Target %d - "
2843 "CCB Completed\n", HostAdapter->HostNumber, TargetID);
2844 Result = SCSI_RESET_NOT_RUNNING;
2845 goto Done;
2846 }
2847 else if (CCB->Status == BusLogic_CCB_Reset)
2848 {
2849 printk("scsi%d: Unable to Reset Command to Target %d - "
2850 "Reset Pending\n", HostAdapter->HostNumber, TargetID);
2851 Result = SCSI_RESET_PENDING;
2852 goto Done;
2853 }
2854 }
2855
2856
2857
2858
2859
2860
2861 if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
2862 if ((CCB = HostAdapter->BusDeviceResetPendingCCB[TargetID]) != NULL)
2863 {
2864 Command->reset_chain = CCB->Command;
2865 CCB->Command = Command;
2866 Result = SCSI_RESET_PENDING;
2867 goto Done;
2868 }
2869
2870
2871
2872
2873
2874
2875
2876
2877 if (HostAdapter->TaggedQueuingActive[TargetID] &&
2878 HostAdapter->ActiveCommandCount[TargetID] > 0 &&
2879 HostAdapter->FirmwareVersion[0] < '5')
2880 goto Done;
2881
2882
2883
2884
2885
2886 CCB = BusLogic_AllocateCCB(HostAdapter);
2887 if (CCB == NULL) goto Done;
2888 printk("scsi%d: Sending Bus Device Reset CCB #%d to Target %d\n",
2889 HostAdapter->HostNumber, CCB->SerialNumber, TargetID);
2890 CCB->Opcode = BusLogic_BusDeviceReset;
2891 CCB->TargetID = TargetID;
2892
2893
2894
2895
2896 if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
2897 {
2898 Command->reset_chain = NULL;
2899 CCB->Command = Command;
2900 }
2901
2902
2903
2904
2905
2906 if (!(BusLogic_WriteOutgoingMailbox(HostAdapter,
2907 BusLogic_MailboxStartCommand, CCB)))
2908 {
2909 printk("scsi%d: cannot write Outgoing Mailbox for Bus Device Reset\n",
2910 HostAdapter->HostNumber);
2911 BusLogic_DeallocateCCB(CCB);
2912 goto Done;
2913 }
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930 HostAdapter->BusDeviceResetPendingCCB[TargetID] = CCB;
2931 HostAdapter->LastResetTime[TargetID] = jiffies;
2932 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2933 if (CCB->Status == BusLogic_CCB_Active && CCB->TargetID == TargetID)
2934 CCB->Status = BusLogic_CCB_Reset;
2935 Result = SCSI_RESET_PENDING;
2936
2937
2938
2939
2940 Done:
2941 if (Result < 0)
2942 Result = BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
2943
2944
2945
2946 BusLogic_ReleaseHostAdapterLock(HostAdapter, &Lock);
2947 return Result;
2948 }
2949
2950
2951
2952
2953
2954
2955 int BusLogic_ResetCommand(SCSI_Command_T *Command, unsigned int ResetFlags)
2956 {
2957 BusLogic_HostAdapter_T *HostAdapter =
2958 (BusLogic_HostAdapter_T *) Command->host->hostdata;
2959 unsigned char TargetID = Command->target;
2960 unsigned char ErrorRecoveryStrategy =
2961 HostAdapter->ErrorRecoveryStrategy[TargetID];
2962
2963
2964
2965
2966
2967 if (HostAdapter->TaggedQueuingActive[TargetID] &&
2968 jiffies - HostAdapter->LastResetTime[TargetID] < 10*60*HZ)
2969 {
2970 HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
2971 HostAdapter->TaggedQueuingActive[TargetID] = false;
2972 printk("scsi%d: Tagged Queuing now disabled for Target %d\n",
2973 HostAdapter->HostNumber, TargetID);
2974 }
2975 if (ErrorRecoveryStrategy == BusLogic_ErrorRecovery_Default)
2976 if (ResetFlags & SCSI_RESET_SUGGEST_HOST_RESET)
2977 ErrorRecoveryStrategy = BusLogic_ErrorRecovery_HardReset;
2978 else if (ResetFlags & SCSI_RESET_SUGGEST_BUS_RESET)
2979 ErrorRecoveryStrategy = BusLogic_ErrorRecovery_HardReset;
2980 else ErrorRecoveryStrategy = BusLogic_ErrorRecovery_BusDeviceReset;
2981 switch (ErrorRecoveryStrategy)
2982 {
2983 case BusLogic_ErrorRecovery_HardReset:
2984 return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
2985 case BusLogic_ErrorRecovery_BusDeviceReset:
2986
2987
2988
2989
2990
2991
2992
2993
2994 if (HostAdapter->CommandSuccessfulFlag[TargetID] ||
2995 jiffies - HostAdapter->LastResetTime[TargetID] < HZ/10)
2996 {
2997 HostAdapter->CommandSuccessfulFlag[TargetID] = false;
2998 return BusLogic_SendBusDeviceReset(HostAdapter, Command, ResetFlags);
2999 }
3000 else return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
3001 }
3002 printk("scsi%d: Error Recovery for Target %d Suppressed\n",
3003 HostAdapter->HostNumber, TargetID);
3004 return SCSI_RESET_PUNT;
3005 }
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024 int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device,
3025 int *Parameters)
3026 {
3027 BusLogic_HostAdapter_T *HostAdapter =
3028 (BusLogic_HostAdapter_T *) Disk->device->host->hostdata;
3029 BIOS_DiskParameters_T *DiskParameters = (BIOS_DiskParameters_T *) Parameters;
3030 struct buffer_head *BufferHead;
3031 if (HostAdapter->ExtendedTranslation &&
3032 Disk->capacity >= 2*1024*1024 )
3033 if (Disk->capacity >= 4*1024*1024 )
3034 {
3035 DiskParameters->Heads = 255;
3036 DiskParameters->Sectors = 63;
3037 }
3038 else
3039 {
3040 DiskParameters->Heads = 128;
3041 DiskParameters->Sectors = 32;
3042 }
3043 else
3044 {
3045 DiskParameters->Heads = 64;
3046 DiskParameters->Sectors = 32;
3047 }
3048 DiskParameters->Cylinders =
3049 Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
3050
3051
3052
3053 BufferHead = bread(MKDEV(MAJOR(Device), MINOR(Device) & ~0x0F), 0, 1024);
3054 if (BufferHead == NULL) return 0;
3055
3056
3057
3058
3059
3060 if (*(unsigned short *) (BufferHead->b_data + 0x1FE) == 0xAA55)
3061 {
3062 struct partition *PartitionEntry =
3063 (struct partition *) (BufferHead->b_data + 0x1BE);
3064 int SavedCylinders = DiskParameters->Cylinders, PartitionNumber;
3065 for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++)
3066 {
3067 if (PartitionEntry->end_head == 64-1)
3068 {
3069 DiskParameters->Heads = 64;
3070 DiskParameters->Sectors = 32;
3071 break;
3072 }
3073 else if (PartitionEntry->end_head == 128-1)
3074 {
3075 DiskParameters->Heads = 128;
3076 DiskParameters->Sectors = 32;
3077 break;
3078 }
3079 else if (PartitionEntry->end_head == 255-1)
3080 {
3081 DiskParameters->Heads = 255;
3082 DiskParameters->Sectors = 63;
3083 break;
3084 }
3085 PartitionEntry++;
3086 }
3087 DiskParameters->Cylinders =
3088 Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
3089 if (SavedCylinders != DiskParameters->Cylinders)
3090 printk("scsi%d: Warning: Extended Translation Setting "
3091 "(> 1GB Switch) does not match\n"
3092 "scsi%d: Partition Table - Adopting %d/%d Geometry "
3093 "from Partition Table\n",
3094 HostAdapter->HostNumber, HostAdapter->HostNumber,
3095 DiskParameters->Heads, DiskParameters->Sectors);
3096 }
3097 brelse(BufferHead);
3098 return 0;
3099 }
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212 void BusLogic_Setup(char *Strings, int *Integers)
3213 {
3214 BusLogic_CommandLineEntry_T *CommandLineEntry =
3215 &BusLogic_CommandLineEntries[BusLogic_CommandLineEntryCount++];
3216 static int ProbeListIndex = 0;
3217 int IntegerCount = Integers[0], TargetID, i;
3218 CommandLineEntry->IO_Address = 0;
3219 CommandLineEntry->TaggedQueueDepth = 0;
3220 CommandLineEntry->BusSettleTime = 0;
3221 CommandLineEntry->LocalOptions = 0;
3222 CommandLineEntry->TaggedQueuingPermitted = 0;
3223 CommandLineEntry->TaggedQueuingPermittedMask = 0;
3224 memset(CommandLineEntry->ErrorRecoveryStrategy,
3225 BusLogic_ErrorRecovery_Default,
3226 sizeof(CommandLineEntry->ErrorRecoveryStrategy));
3227 if (IntegerCount > 5)
3228 printk("BusLogic: Unexpected Command Line Integers ignored\n");
3229 if (IntegerCount >= 1)
3230 {
3231 unsigned short IO_Address = Integers[1];
3232 if (IO_Address > 0)
3233 {
3234 for (i = 0; ; i++)
3235 if (BusLogic_IO_StandardAddresses[i] == 0)
3236 {
3237 printk("BusLogic: Invalid Command Line Entry "
3238 "(illegal I/O Address 0x%X)\n", IO_Address);
3239 return;
3240 }
3241 else if (i < ProbeListIndex &&
3242 IO_Address == BusLogic_IO_AddressProbeList[i])
3243 {
3244 printk("BusLogic: Invalid Command Line Entry "
3245 "(duplicate I/O Address 0x%X)\n", IO_Address);
3246 return;
3247 }
3248 else if (IO_Address >= 0x400 ||
3249 IO_Address == BusLogic_IO_StandardAddresses[i]) break;
3250 BusLogic_IO_AddressProbeList[ProbeListIndex++] = IO_Address;
3251 BusLogic_IO_AddressProbeList[ProbeListIndex] = 0;
3252 }
3253 CommandLineEntry->IO_Address = IO_Address;
3254 }
3255 if (IntegerCount >= 2)
3256 {
3257 unsigned short TaggedQueueDepth = Integers[2];
3258 if (TaggedQueueDepth > BusLogic_MaxTaggedQueueDepth)
3259 {
3260 printk("BusLogic: Invalid Command Line Entry "
3261 "(illegal Tagged Queue Depth %d)\n", TaggedQueueDepth);
3262 return;
3263 }
3264 CommandLineEntry->TaggedQueueDepth = TaggedQueueDepth;
3265 }
3266 if (IntegerCount >= 3)
3267 CommandLineEntry->BusSettleTime = Integers[3];
3268 if (IntegerCount >= 4)
3269 CommandLineEntry->LocalOptions = Integers[4];
3270 if (IntegerCount >= 5)
3271 BusLogic_GlobalOptions |= Integers[5];
3272 if (!(BusLogic_CommandLineEntryCount == 0 || ProbeListIndex == 0 ||
3273 BusLogic_CommandLineEntryCount == ProbeListIndex))
3274 {
3275 printk("BusLogic: Invalid Command Line Entry "
3276 "(all or no I/O Addresses must be specified)\n");
3277 return;
3278 }
3279 if (Strings == NULL) return;
3280 if (strncmp(Strings, "TQ:", 3) == 0)
3281 {
3282 Strings += 3;
3283 if (strncmp(Strings, "Default", 7) == 0)
3284 Strings += 7;
3285 else if (strncmp(Strings, "Enable", 6) == 0)
3286 {
3287 Strings += 6;
3288 CommandLineEntry->TaggedQueuingPermitted = 0xFFFF;
3289 CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF;
3290 }
3291 else if (strncmp(Strings, "Disable", 7) == 0)
3292 {
3293 Strings += 7;
3294 CommandLineEntry->TaggedQueuingPermitted = 0x0000;
3295 CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF;
3296 }
3297 else
3298 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
3299 switch (*Strings++)
3300 {
3301 case 'Y':
3302 CommandLineEntry->TaggedQueuingPermitted |= 1 << TargetID;
3303 CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID;
3304 break;
3305 case 'N':
3306 CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID;
3307 break;
3308 case 'X':
3309 break;
3310 default:
3311 Strings--;
3312 TargetID = BusLogic_MaxTargetDevices;
3313 break;
3314 }
3315 }
3316 if (*Strings == ',') Strings++;
3317 if (strncmp(Strings, "ER:", 3) == 0)
3318 {
3319 Strings += 3;
3320 if (strncmp(Strings, "Default", 7) == 0)
3321 Strings += 7;
3322 else if (strncmp(Strings, "HardReset", 9) == 0)
3323 {
3324 Strings += 9;
3325 memset(CommandLineEntry->ErrorRecoveryStrategy,
3326 BusLogic_ErrorRecovery_HardReset,
3327 sizeof(CommandLineEntry->ErrorRecoveryStrategy));
3328 }
3329 else if (strncmp(Strings, "BusDeviceReset", 14) == 0)
3330 {
3331 Strings += 14;
3332 memset(CommandLineEntry->ErrorRecoveryStrategy,
3333 BusLogic_ErrorRecovery_BusDeviceReset,
3334 sizeof(CommandLineEntry->ErrorRecoveryStrategy));
3335 }
3336 else if (strncmp(Strings, "None", 4) == 0)
3337 {
3338 Strings += 4;
3339 memset(CommandLineEntry->ErrorRecoveryStrategy,
3340 BusLogic_ErrorRecovery_None,
3341 sizeof(CommandLineEntry->ErrorRecoveryStrategy));
3342 }
3343 else
3344 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
3345 switch (*Strings++)
3346 {
3347 case 'D':
3348 CommandLineEntry->ErrorRecoveryStrategy[TargetID] =
3349 BusLogic_ErrorRecovery_Default;
3350 break;
3351 case 'H':
3352 CommandLineEntry->ErrorRecoveryStrategy[TargetID] =
3353 BusLogic_ErrorRecovery_HardReset;
3354 break;
3355 case 'B':
3356 CommandLineEntry->ErrorRecoveryStrategy[TargetID] =
3357 BusLogic_ErrorRecovery_BusDeviceReset;
3358 break;
3359 case 'N':
3360 CommandLineEntry->ErrorRecoveryStrategy[TargetID] =
3361 BusLogic_ErrorRecovery_None;
3362 break;
3363 default:
3364 Strings--;
3365 TargetID = BusLogic_MaxTargetDevices;
3366 break;
3367 }
3368 }
3369 if (*Strings != '\0')
3370 printk("BusLogic: Unexpected Command Line String '%s' ignored\n", Strings);
3371 }
3372
3373
3374
3375
3376
3377
3378 #ifdef MODULE
3379
3380 SCSI_Host_Template_T driver_template = BUSLOGIC;
3381
3382 #include "scsi_module.c"
3383
3384 #endif