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
28
29#define BusLogic_DriverVersion "2.1.16"
30#define BusLogic_DriverDate "18 July 2002"
31
32#include <linux/module.h>
33#include <linux/init.h>
34#include <linux/interrupt.h>
35#include <linux/types.h>
36#include <linux/blkdev.h>
37#include <linux/delay.h>
38#include <linux/ioport.h>
39#include <linux/mm.h>
40#include <linux/stat.h>
41#include <linux/pci.h>
42#include <linux/spinlock.h>
43#include <linux/jiffies.h>
44#include <linux/dma-mapping.h>
45#include <scsi/scsicam.h>
46
47#include <asm/dma.h>
48#include <asm/io.h>
49#include <asm/system.h>
50
51#include <scsi/scsi.h>
52#include <scsi/scsi_cmnd.h>
53#include <scsi/scsi_device.h>
54#include <scsi/scsi_host.h>
55#include <scsi/scsi_tcq.h>
56#include "BusLogic.h"
57#include "FlashPoint.c"
58
59#ifndef FAILURE
60#define FAILURE (-1)
61#endif
62
63static struct scsi_host_template Bus_Logic_template;
64
65
66
67
68
69
70
71static int BusLogic_DriverOptionsCount;
72
73
74
75
76
77
78
79
80static struct BusLogic_DriverOptions BusLogic_DriverOptions[BusLogic_MaxHostAdapters];
81
82
83
84
85
86
87MODULE_LICENSE("GPL");
88#ifdef MODULE
89static char *BusLogic;
90module_param(BusLogic, charp, 0);
91#endif
92
93
94
95
96
97
98
99static struct BusLogic_ProbeOptions BusLogic_ProbeOptions;
100
101
102
103
104
105
106
107static struct BusLogic_GlobalOptions BusLogic_GlobalOptions;
108
109static LIST_HEAD(BusLogic_host_list);
110
111
112
113
114
115static int BusLogic_ProbeInfoCount;
116
117
118
119
120
121
122
123
124
125static struct BusLogic_ProbeInfo *BusLogic_ProbeInfoList;
126
127
128
129
130
131
132
133
134static char *BusLogic_CommandFailureReason;
135
136
137
138
139
140
141static void BusLogic_AnnounceDriver(struct BusLogic_HostAdapter *HostAdapter)
142{
143 BusLogic_Announce("***** BusLogic SCSI Driver Version " BusLogic_DriverVersion " of " BusLogic_DriverDate " *****\n", HostAdapter);
144 BusLogic_Announce("Copyright 1995-1998 by Leonard N. Zubkoff " "<lnz@dandelion.com>\n", HostAdapter);
145}
146
147
148
149
150
151
152
153static const char *BusLogic_DriverInfo(struct Scsi_Host *Host)
154{
155 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata;
156 return HostAdapter->FullModelName;
157}
158
159
160
161
162
163
164
165static void BusLogic_InitializeCCBs(struct BusLogic_HostAdapter *HostAdapter, void *BlockPointer, int BlockSize, dma_addr_t BlockPointerHandle)
166{
167 struct BusLogic_CCB *CCB = (struct BusLogic_CCB *) BlockPointer;
168 unsigned int offset = 0;
169 memset(BlockPointer, 0, BlockSize);
170 CCB->AllocationGroupHead = BlockPointerHandle;
171 CCB->AllocationGroupSize = BlockSize;
172 while ((BlockSize -= sizeof(struct BusLogic_CCB)) >= 0) {
173 CCB->Status = BusLogic_CCB_Free;
174 CCB->HostAdapter = HostAdapter;
175 CCB->DMA_Handle = (u32) BlockPointerHandle + offset;
176 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
177 CCB->CallbackFunction = BusLogic_QueueCompletedCCB;
178 CCB->BaseAddress = HostAdapter->FlashPointInfo.BaseAddress;
179 }
180 CCB->Next = HostAdapter->Free_CCBs;
181 CCB->NextAll = HostAdapter->All_CCBs;
182 HostAdapter->Free_CCBs = CCB;
183 HostAdapter->All_CCBs = CCB;
184 HostAdapter->AllocatedCCBs++;
185 CCB++;
186 offset += sizeof(struct BusLogic_CCB);
187 }
188}
189
190
191
192
193
194
195static bool __init BusLogic_CreateInitialCCBs(struct BusLogic_HostAdapter *HostAdapter)
196{
197 int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB);
198 void *BlockPointer;
199 dma_addr_t BlockPointerHandle;
200 while (HostAdapter->AllocatedCCBs < HostAdapter->InitialCCBs) {
201 BlockPointer = pci_alloc_consistent(HostAdapter->PCI_Device, BlockSize, &BlockPointerHandle);
202 if (BlockPointer == NULL) {
203 BusLogic_Error("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n", HostAdapter);
204 return false;
205 }
206 BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize, BlockPointerHandle);
207 }
208 return true;
209}
210
211
212
213
214
215
216static void BusLogic_DestroyCCBs(struct BusLogic_HostAdapter *HostAdapter)
217{
218 struct BusLogic_CCB *NextCCB = HostAdapter->All_CCBs, *CCB, *Last_CCB = NULL;
219 HostAdapter->All_CCBs = NULL;
220 HostAdapter->Free_CCBs = NULL;
221 while ((CCB = NextCCB) != NULL) {
222 NextCCB = CCB->NextAll;
223 if (CCB->AllocationGroupHead) {
224 if (Last_CCB)
225 pci_free_consistent(HostAdapter->PCI_Device, Last_CCB->AllocationGroupSize, Last_CCB, Last_CCB->AllocationGroupHead);
226 Last_CCB = CCB;
227 }
228 }
229 if (Last_CCB)
230 pci_free_consistent(HostAdapter->PCI_Device, Last_CCB->AllocationGroupSize, Last_CCB, Last_CCB->AllocationGroupHead);
231}
232
233
234
235
236
237
238
239
240
241static void BusLogic_CreateAdditionalCCBs(struct BusLogic_HostAdapter *HostAdapter, int AdditionalCCBs, bool SuccessMessageP)
242{
243 int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB);
244 int PreviouslyAllocated = HostAdapter->AllocatedCCBs;
245 void *BlockPointer;
246 dma_addr_t BlockPointerHandle;
247 if (AdditionalCCBs <= 0)
248 return;
249 while (HostAdapter->AllocatedCCBs - PreviouslyAllocated < AdditionalCCBs) {
250 BlockPointer = pci_alloc_consistent(HostAdapter->PCI_Device, BlockSize, &BlockPointerHandle);
251 if (BlockPointer == NULL)
252 break;
253 BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize, BlockPointerHandle);
254 }
255 if (HostAdapter->AllocatedCCBs > PreviouslyAllocated) {
256 if (SuccessMessageP)
257 BusLogic_Notice("Allocated %d additional CCBs (total now %d)\n", HostAdapter, HostAdapter->AllocatedCCBs - PreviouslyAllocated, HostAdapter->AllocatedCCBs);
258 return;
259 }
260 BusLogic_Notice("Failed to allocate additional CCBs\n", HostAdapter);
261 if (HostAdapter->DriverQueueDepth > HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount) {
262 HostAdapter->DriverQueueDepth = HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount;
263 HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth;
264 }
265}
266
267
268
269
270
271
272
273static struct BusLogic_CCB *BusLogic_AllocateCCB(struct BusLogic_HostAdapter
274 *HostAdapter)
275{
276 static unsigned long SerialNumber = 0;
277 struct BusLogic_CCB *CCB;
278 CCB = HostAdapter->Free_CCBs;
279 if (CCB != NULL) {
280 CCB->SerialNumber = ++SerialNumber;
281 HostAdapter->Free_CCBs = CCB->Next;
282 CCB->Next = NULL;
283 if (HostAdapter->Free_CCBs == NULL)
284 BusLogic_CreateAdditionalCCBs(HostAdapter, HostAdapter->IncrementalCCBs, true);
285 return CCB;
286 }
287 BusLogic_CreateAdditionalCCBs(HostAdapter, HostAdapter->IncrementalCCBs, true);
288 CCB = HostAdapter->Free_CCBs;
289 if (CCB == NULL)
290 return NULL;
291 CCB->SerialNumber = ++SerialNumber;
292 HostAdapter->Free_CCBs = CCB->Next;
293 CCB->Next = NULL;
294 return CCB;
295}
296
297
298
299
300
301
302
303
304static void BusLogic_DeallocateCCB(struct BusLogic_CCB *CCB)
305{
306 struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter;
307
308 scsi_dma_unmap(CCB->Command);
309 pci_unmap_single(HostAdapter->PCI_Device, CCB->SenseDataPointer,
310 CCB->SenseDataLength, PCI_DMA_FROMDEVICE);
311
312 CCB->Command = NULL;
313 CCB->Status = BusLogic_CCB_Free;
314 CCB->Next = HostAdapter->Free_CCBs;
315 HostAdapter->Free_CCBs = CCB;
316}
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337static int BusLogic_Command(struct BusLogic_HostAdapter *HostAdapter, enum BusLogic_OperationCode OperationCode, void *ParameterData, int ParameterLength, void *ReplyData, int ReplyLength)
338{
339 unsigned char *ParameterPointer = (unsigned char *) ParameterData;
340 unsigned char *ReplyPointer = (unsigned char *) ReplyData;
341 union BusLogic_StatusRegister StatusRegister;
342 union BusLogic_InterruptRegister InterruptRegister;
343 unsigned long ProcessorFlags = 0;
344 int ReplyBytes = 0, Result;
345 long TimeoutCounter;
346
347
348
349 if (ReplyLength > 0)
350 memset(ReplyData, 0, ReplyLength);
351
352
353
354
355
356
357 if (!HostAdapter->IRQ_ChannelAcquired)
358 local_irq_save(ProcessorFlags);
359
360
361
362
363 TimeoutCounter = 10000;
364 while (--TimeoutCounter >= 0) {
365 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
366 if (StatusRegister.sr.HostAdapterReady && !StatusRegister.sr.CommandParameterRegisterBusy)
367 break;
368 udelay(100);
369 }
370 if (TimeoutCounter < 0) {
371 BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";
372 Result = -2;
373 goto Done;
374 }
375
376
377
378 HostAdapter->HostAdapterCommandCompleted = false;
379 BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);
380
381
382
383 TimeoutCounter = 10000;
384 while (ParameterLength > 0 && --TimeoutCounter >= 0) {
385
386
387
388
389
390
391
392
393
394
395
396
397 udelay(100);
398 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
399 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
400 if (InterruptRegister.ir.CommandComplete)
401 break;
402 if (HostAdapter->HostAdapterCommandCompleted)
403 break;
404 if (StatusRegister.sr.DataInRegisterReady)
405 break;
406 if (StatusRegister.sr.CommandParameterRegisterBusy)
407 continue;
408 BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++);
409 ParameterLength--;
410 }
411 if (TimeoutCounter < 0) {
412 BusLogic_CommandFailureReason = "Timeout waiting for Parameter Acceptance";
413 Result = -2;
414 goto Done;
415 }
416
417
418
419 if (OperationCode == BusLogic_ModifyIOAddress) {
420 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
421 if (StatusRegister.sr.CommandInvalid) {
422 BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
423 Result = -1;
424 goto Done;
425 }
426 if (BusLogic_GlobalOptions.TraceConfiguration)
427 BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: " "(Modify I/O Address)\n", HostAdapter, OperationCode, StatusRegister.All);
428 Result = 0;
429 goto Done;
430 }
431
432
433
434 switch (OperationCode) {
435 case BusLogic_InquireInstalledDevicesID0to7:
436 case BusLogic_InquireInstalledDevicesID8to15:
437 case BusLogic_InquireTargetDevices:
438
439 TimeoutCounter = 60 * 10000;
440 break;
441 default:
442
443 TimeoutCounter = 10000;
444 break;
445 }
446
447
448
449
450
451 while (--TimeoutCounter >= 0) {
452 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
453 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
454 if (InterruptRegister.ir.CommandComplete)
455 break;
456 if (HostAdapter->HostAdapterCommandCompleted)
457 break;
458 if (StatusRegister.sr.DataInRegisterReady) {
459 if (++ReplyBytes <= ReplyLength)
460 *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
461 else
462 BusLogic_ReadDataInRegister(HostAdapter);
463 }
464 if (OperationCode == BusLogic_FetchHostAdapterLocalRAM && StatusRegister.sr.HostAdapterReady)
465 break;
466 udelay(100);
467 }
468 if (TimeoutCounter < 0) {
469 BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";
470 Result = -2;
471 goto Done;
472 }
473
474
475
476 BusLogic_InterruptReset(HostAdapter);
477
478
479
480 if (BusLogic_GlobalOptions.TraceConfiguration) {
481 int i;
482 BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:", HostAdapter, OperationCode, StatusRegister.All, ReplyLength, ReplyBytes);
483 if (ReplyLength > ReplyBytes)
484 ReplyLength = ReplyBytes;
485 for (i = 0; i < ReplyLength; i++)
486 BusLogic_Notice(" %02X", HostAdapter, ((unsigned char *) ReplyData)[i]);
487 BusLogic_Notice("\n", HostAdapter);
488 }
489
490
491
492 if (StatusRegister.sr.CommandInvalid) {
493
494
495
496
497
498
499
500
501 udelay(1000);
502 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
503 if (StatusRegister.sr.CommandInvalid ||
504 StatusRegister.sr.Reserved ||
505 StatusRegister.sr.DataInRegisterReady ||
506 StatusRegister.sr.CommandParameterRegisterBusy || !StatusRegister.sr.HostAdapterReady || !StatusRegister.sr.InitializationRequired || StatusRegister.sr.DiagnosticActive || StatusRegister.sr.DiagnosticFailure) {
507 BusLogic_SoftReset(HostAdapter);
508 udelay(1000);
509 }
510 BusLogic_CommandFailureReason = "Command Invalid";
511 Result = -1;
512 goto Done;
513 }
514
515
516
517 if (ParameterLength > 0) {
518 BusLogic_CommandFailureReason = "Excess Parameters Supplied";
519 Result = -1;
520 goto Done;
521 }
522
523
524
525 BusLogic_CommandFailureReason = NULL;
526 Result = ReplyBytes;
527
528
529
530 Done:
531 if (!HostAdapter->IRQ_ChannelAcquired)
532 local_irq_restore(ProcessorFlags);
533 return Result;
534}
535
536
537
538
539
540
541
542
543static void __init BusLogic_AppendProbeAddressISA(unsigned long IO_Address)
544{
545 struct BusLogic_ProbeInfo *ProbeInfo;
546 if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters)
547 return;
548 ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
549 ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
550 ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
551 ProbeInfo->IO_Address = IO_Address;
552 ProbeInfo->PCI_Device = NULL;
553}
554
555
556
557
558
559
560
561
562static void __init BusLogic_InitializeProbeInfoListISA(struct BusLogic_HostAdapter
563 *PrototypeHostAdapter)
564{
565
566
567
568
569 if (BusLogic_ProbeOptions.NoProbeISA)
570 return;
571
572
573
574 if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe330)
575 BusLogic_AppendProbeAddressISA(0x330);
576 if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe334)
577 BusLogic_AppendProbeAddressISA(0x334);
578 if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe230)
579 BusLogic_AppendProbeAddressISA(0x230);
580 if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe234)
581 BusLogic_AppendProbeAddressISA(0x234);
582 if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe130)
583 BusLogic_AppendProbeAddressISA(0x130);
584 if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe134)
585 BusLogic_AppendProbeAddressISA(0x134);
586}
587
588
589#ifdef CONFIG_PCI
590
591
592
593
594
595
596
597static void __init BusLogic_SortProbeInfo(struct BusLogic_ProbeInfo *ProbeInfoList, int ProbeInfoCount)
598{
599 int LastInterchange = ProbeInfoCount - 1, Bound, j;
600 while (LastInterchange > 0) {
601 Bound = LastInterchange;
602 LastInterchange = 0;
603 for (j = 0; j < Bound; j++) {
604 struct BusLogic_ProbeInfo *ProbeInfo1 = &ProbeInfoList[j];
605 struct BusLogic_ProbeInfo *ProbeInfo2 = &ProbeInfoList[j + 1];
606 if (ProbeInfo1->Bus > ProbeInfo2->Bus || (ProbeInfo1->Bus == ProbeInfo2->Bus && (ProbeInfo1->Device > ProbeInfo2->Device))) {
607 struct BusLogic_ProbeInfo TempProbeInfo;
608 memcpy(&TempProbeInfo, ProbeInfo1, sizeof(struct BusLogic_ProbeInfo));
609 memcpy(ProbeInfo1, ProbeInfo2, sizeof(struct BusLogic_ProbeInfo));
610 memcpy(ProbeInfo2, &TempProbeInfo, sizeof(struct BusLogic_ProbeInfo));
611 LastInterchange = j;
612 }
613 }
614 }
615}
616
617
618
619
620
621
622
623
624
625
626static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAdapter
627 *PrototypeHostAdapter)
628{
629 struct BusLogic_ProbeInfo *PrimaryProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount];
630 int NonPrimaryPCIMultiMasterIndex = BusLogic_ProbeInfoCount + 1;
631 int NonPrimaryPCIMultiMasterCount = 0, PCIMultiMasterCount = 0;
632 bool ForceBusDeviceScanningOrder = false;
633 bool ForceBusDeviceScanningOrderChecked = false;
634 bool StandardAddressSeen[6];
635 struct pci_dev *PCI_Device = NULL;
636 int i;
637 if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters)
638 return 0;
639 BusLogic_ProbeInfoCount++;
640 for (i = 0; i < 6; i++)
641 StandardAddressSeen[i] = false;
642
643
644
645
646
647
648
649
650
651
652
653
654 PrimaryProbeInfo->IO_Address = 0;
655 while ((PCI_Device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER, PCI_Device)) != NULL) {
656 struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter;
657 struct BusLogic_PCIHostAdapterInformation PCIHostAdapterInformation;
658 enum BusLogic_ISACompatibleIOPort ModifyIOAddressRequest;
659 unsigned char Bus;
660 unsigned char Device;
661 unsigned int IRQ_Channel;
662 unsigned long BaseAddress0;
663 unsigned long BaseAddress1;
664 unsigned long IO_Address;
665 unsigned long PCI_Address;
666
667 if (pci_enable_device(PCI_Device))
668 continue;
669
670 if (pci_set_dma_mask(PCI_Device, DMA_32BIT_MASK ))
671 continue;
672
673 Bus = PCI_Device->bus->number;
674 Device = PCI_Device->devfn >> 3;
675 IRQ_Channel = PCI_Device->irq;
676 IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0);
677 PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1);
678
679 if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) {
680 BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "MultiMaster Host Adapter\n", NULL, BaseAddress0);
681 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
682 continue;
683 }
684 if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO) {
685 BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for " "MultiMaster Host Adapter\n", NULL, BaseAddress1);
686 BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, Bus, Device, PCI_Address);
687 continue;
688 }
689 if (IRQ_Channel == 0) {
690 BusLogic_Error("BusLogic: IRQ Channel %d invalid for " "MultiMaster Host Adapter\n", NULL, IRQ_Channel);
691 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
692 continue;
693 }
694 if (BusLogic_GlobalOptions.TraceProbe) {
695 BusLogic_Notice("BusLogic: PCI MultiMaster Host Adapter " "detected at\n", NULL);
696 BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address " "0x%X PCI Address 0x%X\n", NULL, Bus, Device, IO_Address, PCI_Address);
697 }
698
699
700
701
702
703
704 HostAdapter->IO_Address = IO_Address;
705 BusLogic_InterruptReset(HostAdapter);
706 if (BusLogic_Command(HostAdapter, BusLogic_InquirePCIHostAdapterInformation, NULL, 0, &PCIHostAdapterInformation, sizeof(PCIHostAdapterInformation))
707 == sizeof(PCIHostAdapterInformation)) {
708 if (PCIHostAdapterInformation.ISACompatibleIOPort < 6)
709 StandardAddressSeen[PCIHostAdapterInformation.ISACompatibleIOPort] = true;
710 } else
711 PCIHostAdapterInformation.ISACompatibleIOPort = BusLogic_IO_Disable;
712
713
714
715
716
717
718
719 ModifyIOAddressRequest = BusLogic_IO_Disable;
720 BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress, &ModifyIOAddressRequest, sizeof(ModifyIOAddressRequest), NULL, 0);
721
722
723
724
725
726
727
728 if (!ForceBusDeviceScanningOrderChecked) {
729 struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest;
730 struct BusLogic_AutoSCSIByte45 AutoSCSIByte45;
731 struct BusLogic_BoardID BoardID;
732 FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_AutoSCSI_BaseOffset + 45;
733 FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIByte45);
734 BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &AutoSCSIByte45, sizeof(AutoSCSIByte45));
735 BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0, &BoardID, sizeof(BoardID));
736 if (BoardID.FirmwareVersion1stDigit == '5')
737 ForceBusDeviceScanningOrder = AutoSCSIByte45.ForceBusDeviceScanningOrder;
738 ForceBusDeviceScanningOrderChecked = true;
739 }
740
741
742
743
744
745
746
747 if (PCIHostAdapterInformation.ISACompatibleIOPort == BusLogic_IO_330) {
748 PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
749 PrimaryProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
750 PrimaryProbeInfo->IO_Address = IO_Address;
751 PrimaryProbeInfo->PCI_Address = PCI_Address;
752 PrimaryProbeInfo->Bus = Bus;
753 PrimaryProbeInfo->Device = Device;
754 PrimaryProbeInfo->IRQ_Channel = IRQ_Channel;
755 PrimaryProbeInfo->PCI_Device = pci_dev_get(PCI_Device);
756 PCIMultiMasterCount++;
757 } else if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters) {
758 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
759 ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
760 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
761 ProbeInfo->IO_Address = IO_Address;
762 ProbeInfo->PCI_Address = PCI_Address;
763 ProbeInfo->Bus = Bus;
764 ProbeInfo->Device = Device;
765 ProbeInfo->IRQ_Channel = IRQ_Channel;
766 ProbeInfo->PCI_Device = pci_dev_get(PCI_Device);
767 NonPrimaryPCIMultiMasterCount++;
768 PCIMultiMasterCount++;
769 } else
770 BusLogic_Warning("BusLogic: Too many Host Adapters " "detected\n", NULL);
771 }
772
773
774
775
776
777
778
779
780
781
782 if (ForceBusDeviceScanningOrder)
783 BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[NonPrimaryPCIMultiMasterIndex], NonPrimaryPCIMultiMasterCount);
784
785
786
787
788
789 if (!BusLogic_ProbeOptions.NoProbeISA)
790 if (PrimaryProbeInfo->IO_Address == 0 &&
791 (!BusLogic_ProbeOptions.LimitedProbeISA ||
792 BusLogic_ProbeOptions.Probe330)) {
793 PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
794 PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
795 PrimaryProbeInfo->IO_Address = 0x330;
796 }
797
798
799
800
801 if (!BusLogic_ProbeOptions.NoProbeISA) {
802 if (!StandardAddressSeen[1] &&
803 (!BusLogic_ProbeOptions.LimitedProbeISA ||
804 BusLogic_ProbeOptions.Probe334))
805 BusLogic_AppendProbeAddressISA(0x334);
806 if (!StandardAddressSeen[2] &&
807 (!BusLogic_ProbeOptions.LimitedProbeISA ||
808 BusLogic_ProbeOptions.Probe230))
809 BusLogic_AppendProbeAddressISA(0x230);
810 if (!StandardAddressSeen[3] &&
811 (!BusLogic_ProbeOptions.LimitedProbeISA ||
812 BusLogic_ProbeOptions.Probe234))
813 BusLogic_AppendProbeAddressISA(0x234);
814 if (!StandardAddressSeen[4] &&
815 (!BusLogic_ProbeOptions.LimitedProbeISA ||
816 BusLogic_ProbeOptions.Probe130))
817 BusLogic_AppendProbeAddressISA(0x130);
818 if (!StandardAddressSeen[5] &&
819 (!BusLogic_ProbeOptions.LimitedProbeISA ||
820 BusLogic_ProbeOptions.Probe134))
821 BusLogic_AppendProbeAddressISA(0x134);
822 }
823
824
825
826
827 PCI_Device = NULL;
828 while ((PCI_Device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC, PCI_Device)) != NULL) {
829 unsigned char Bus;
830 unsigned char Device;
831 unsigned int IRQ_Channel;
832 unsigned long IO_Address;
833
834 if (pci_enable_device(PCI_Device))
835 continue;
836
837 if (pci_set_dma_mask(PCI_Device, DMA_32BIT_MASK))
838 continue;
839
840 Bus = PCI_Device->bus->number;
841 Device = PCI_Device->devfn >> 3;
842 IRQ_Channel = PCI_Device->irq;
843 IO_Address = pci_resource_start(PCI_Device, 0);
844
845 if (IO_Address == 0 || IRQ_Channel == 0)
846 continue;
847 for (i = 0; i < BusLogic_ProbeInfoCount; i++) {
848 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[i];
849 if (ProbeInfo->IO_Address == IO_Address && ProbeInfo->HostAdapterType == BusLogic_MultiMaster) {
850 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
851 ProbeInfo->PCI_Address = 0;
852 ProbeInfo->Bus = Bus;
853 ProbeInfo->Device = Device;
854 ProbeInfo->IRQ_Channel = IRQ_Channel;
855 ProbeInfo->PCI_Device = pci_dev_get(PCI_Device);
856 break;
857 }
858 }
859 }
860 return PCIMultiMasterCount;
861}
862
863
864
865
866
867
868
869
870
871static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAdapter
872 *PrototypeHostAdapter)
873{
874 int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0;
875 struct pci_dev *PCI_Device = NULL;
876
877
878
879 while ((PCI_Device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT, PCI_Device)) != NULL) {
880 unsigned char Bus;
881 unsigned char Device;
882 unsigned int IRQ_Channel;
883 unsigned long BaseAddress0;
884 unsigned long BaseAddress1;
885 unsigned long IO_Address;
886 unsigned long PCI_Address;
887
888 if (pci_enable_device(PCI_Device))
889 continue;
890
891 if (pci_set_dma_mask(PCI_Device, DMA_32BIT_MASK))
892 continue;
893
894 Bus = PCI_Device->bus->number;
895 Device = PCI_Device->devfn >> 3;
896 IRQ_Channel = PCI_Device->irq;
897 IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0);
898 PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1);
899#ifdef CONFIG_SCSI_FLASHPOINT
900 if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) {
901 BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, BaseAddress0);
902 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
903 continue;
904 }
905 if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO) {
906 BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for " "FlashPoint Host Adapter\n", NULL, BaseAddress1);
907 BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, Bus, Device, PCI_Address);
908 continue;
909 }
910 if (IRQ_Channel == 0) {
911 BusLogic_Error("BusLogic: IRQ Channel %d invalid for " "FlashPoint Host Adapter\n", NULL, IRQ_Channel);
912 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
913 continue;
914 }
915 if (BusLogic_GlobalOptions.TraceProbe) {
916 BusLogic_Notice("BusLogic: FlashPoint Host Adapter " "detected at\n", NULL);
917 BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address " "0x%X PCI Address 0x%X\n", NULL, Bus, Device, IO_Address, PCI_Address);
918 }
919 if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters) {
920 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
921 ProbeInfo->HostAdapterType = BusLogic_FlashPoint;
922 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
923 ProbeInfo->IO_Address = IO_Address;
924 ProbeInfo->PCI_Address = PCI_Address;
925 ProbeInfo->Bus = Bus;
926 ProbeInfo->Device = Device;
927 ProbeInfo->IRQ_Channel = IRQ_Channel;
928 ProbeInfo->PCI_Device = pci_dev_get(PCI_Device);
929 FlashPointCount++;
930 } else
931 BusLogic_Warning("BusLogic: Too many Host Adapters " "detected\n", NULL);
932#else
933 BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", NULL, Bus, Device);
934 BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, irq %d, " "but FlashPoint\n", NULL, IO_Address, PCI_Address, IRQ_Channel);
935 BusLogic_Error("BusLogic: support was omitted in this kernel " "configuration.\n", NULL);
936#endif
937 }
938
939
940
941
942
943 BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[FlashPointIndex], FlashPointCount);
944 return FlashPointCount;
945}
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961static void __init BusLogic_InitializeProbeInfoList(struct BusLogic_HostAdapter
962 *PrototypeHostAdapter)
963{
964
965
966
967
968 if (!BusLogic_ProbeOptions.NoProbePCI) {
969 if (BusLogic_ProbeOptions.MultiMasterFirst) {
970 BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
971 BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
972 } else if (BusLogic_ProbeOptions.FlashPointFirst) {
973 BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
974 BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
975 } else {
976 int FlashPointCount = BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
977 int PCIMultiMasterCount = BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
978 if (FlashPointCount > 0 && PCIMultiMasterCount > 0) {
979 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[FlashPointCount];
980 struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter;
981 struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest;
982 struct BusLogic_BIOSDriveMapByte Drive0MapByte;
983 while (ProbeInfo->HostAdapterBusType != BusLogic_PCI_Bus)
984 ProbeInfo++;
985 HostAdapter->IO_Address = ProbeInfo->IO_Address;
986 FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_BIOS_BaseOffset + BusLogic_BIOS_DriveMapOffset + 0;
987 FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(Drive0MapByte);
988 BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &Drive0MapByte, sizeof(Drive0MapByte));
989
990
991
992
993
994
995 if (Drive0MapByte.DiskGeometry != BusLogic_BIOS_Disk_Not_Installed) {
996 struct BusLogic_ProbeInfo SavedProbeInfo[BusLogic_MaxHostAdapters];
997 int MultiMasterCount = BusLogic_ProbeInfoCount - FlashPointCount;
998 memcpy(SavedProbeInfo, BusLogic_ProbeInfoList, BusLogic_ProbeInfoCount * sizeof(struct BusLogic_ProbeInfo));
999 memcpy(&BusLogic_ProbeInfoList[0], &SavedProbeInfo[FlashPointCount], MultiMasterCount * sizeof(struct BusLogic_ProbeInfo));
1000 memcpy(&BusLogic_ProbeInfoList[MultiMasterCount], &SavedProbeInfo[0], FlashPointCount * sizeof(struct BusLogic_ProbeInfo));
1001 }
1002 }
1003 }
1004 } else
1005 BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter);
1006}
1007
1008
1009#else
1010#define BusLogic_InitializeProbeInfoList(adapter) \
1011 BusLogic_InitializeProbeInfoListISA(adapter)
1012#endif
1013
1014
1015
1016
1017
1018
1019static bool BusLogic_Failure(struct BusLogic_HostAdapter *HostAdapter, char *ErrorMessage)
1020{
1021 BusLogic_AnnounceDriver(HostAdapter);
1022 if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus) {
1023 BusLogic_Error("While configuring BusLogic PCI Host Adapter at\n", HostAdapter);
1024 BusLogic_Error("Bus %d Device %d I/O Address 0x%X PCI Address 0x%X:\n", HostAdapter, HostAdapter->Bus, HostAdapter->Device, HostAdapter->IO_Address, HostAdapter->PCI_Address);
1025 } else
1026 BusLogic_Error("While configuring BusLogic Host Adapter at " "I/O Address 0x%X:\n", HostAdapter, HostAdapter->IO_Address);
1027 BusLogic_Error("%s FAILED - DETACHING\n", HostAdapter, ErrorMessage);
1028 if (BusLogic_CommandFailureReason != NULL)
1029 BusLogic_Error("ADDITIONAL FAILURE INFO - %s\n", HostAdapter, BusLogic_CommandFailureReason);
1030 return false;
1031}
1032
1033
1034
1035
1036
1037
1038static bool __init BusLogic_ProbeHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
1039{
1040 union BusLogic_StatusRegister StatusRegister;
1041 union BusLogic_InterruptRegister InterruptRegister;
1042 union BusLogic_GeometryRegister GeometryRegister;
1043
1044
1045
1046 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1047 struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
1048 FlashPointInfo->BaseAddress = (u32) HostAdapter->IO_Address;
1049 FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel;
1050 FlashPointInfo->Present = false;
1051 if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 && FlashPointInfo->Present)) {
1052 BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", HostAdapter, HostAdapter->Bus, HostAdapter->Device);
1053 BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, " "but FlashPoint\n", HostAdapter, HostAdapter->IO_Address, HostAdapter->PCI_Address);
1054 BusLogic_Error("BusLogic: Probe Function failed to validate it.\n", HostAdapter);
1055 return false;
1056 }
1057 if (BusLogic_GlobalOptions.TraceProbe)
1058 BusLogic_Notice("BusLogic_Probe(0x%X): FlashPoint Found\n", HostAdapter, HostAdapter->IO_Address);
1059
1060
1061
1062 return true;
1063 }
1064
1065
1066
1067
1068
1069
1070
1071 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1072 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
1073 GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1074 if (BusLogic_GlobalOptions.TraceProbe)
1075 BusLogic_Notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, " "Geometry 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All, InterruptRegister.All, GeometryRegister.All);
1076 if (StatusRegister.All == 0 || StatusRegister.sr.DiagnosticActive || StatusRegister.sr.CommandParameterRegisterBusy || StatusRegister.sr.Reserved || StatusRegister.sr.CommandInvalid || InterruptRegister.ir.Reserved != 0)
1077 return false;
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092 if (GeometryRegister.All == 0xFF)
1093 return false;
1094
1095
1096
1097 return true;
1098}
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109static bool BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter
1110 *HostAdapter, bool HardReset)
1111{
1112 union BusLogic_StatusRegister StatusRegister;
1113 int TimeoutCounter;
1114
1115
1116
1117 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1118 struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
1119 FlashPointInfo->HostSoftReset = !HardReset;
1120 FlashPointInfo->ReportDataUnderrun = true;
1121 HostAdapter->CardHandle = FlashPoint_HardwareResetHostAdapter(FlashPointInfo);
1122 if (HostAdapter->CardHandle == FlashPoint_BadCardHandle)
1123 return false;
1124
1125
1126
1127 return true;
1128 }
1129
1130
1131
1132
1133 if (HardReset)
1134 BusLogic_HardReset(HostAdapter);
1135 else
1136 BusLogic_SoftReset(HostAdapter);
1137
1138
1139
1140 TimeoutCounter = 5 * 10000;
1141 while (--TimeoutCounter >= 0) {
1142 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1143 if (StatusRegister.sr.DiagnosticActive)
1144 break;
1145 udelay(100);
1146 }
1147 if (BusLogic_GlobalOptions.TraceHardwareReset)
1148 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All);
1149 if (TimeoutCounter < 0)
1150 return false;
1151
1152
1153
1154
1155
1156 udelay(100);
1157
1158
1159
1160 TimeoutCounter = 10 * 10000;
1161 while (--TimeoutCounter >= 0) {
1162 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1163 if (!StatusRegister.sr.DiagnosticActive)
1164 break;
1165 udelay(100);
1166 }
1167 if (BusLogic_GlobalOptions.TraceHardwareReset)
1168 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All);
1169 if (TimeoutCounter < 0)
1170 return false;
1171
1172
1173
1174
1175 TimeoutCounter = 10000;
1176 while (--TimeoutCounter >= 0) {
1177 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1178 if (StatusRegister.sr.DiagnosticFailure || StatusRegister.sr.HostAdapterReady || StatusRegister.sr.DataInRegisterReady)
1179 break;
1180 udelay(100);
1181 }
1182 if (BusLogic_GlobalOptions.TraceHardwareReset)
1183 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All);
1184 if (TimeoutCounter < 0)
1185 return false;
1186
1187
1188
1189
1190
1191 if (StatusRegister.sr.DiagnosticFailure || !StatusRegister.sr.HostAdapterReady) {
1192 BusLogic_CommandFailureReason = NULL;
1193 BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
1194 BusLogic_Error("HOST ADAPTER STATUS REGISTER = %02X\n", HostAdapter, StatusRegister.All);
1195 if (StatusRegister.sr.DataInRegisterReady) {
1196 unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
1197 BusLogic_Error("HOST ADAPTER ERROR CODE = %d\n", HostAdapter, ErrorCode);
1198 }
1199 return false;
1200 }
1201
1202
1203
1204 return true;
1205}
1206
1207
1208
1209
1210
1211
1212
1213static bool __init BusLogic_CheckHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
1214{
1215 struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation;
1216 unsigned char RequestedReplyLength;
1217 bool Result = true;
1218
1219
1220
1221 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1222 return true;
1223
1224
1225
1226
1227
1228
1229 RequestedReplyLength = sizeof(ExtendedSetupInformation);
1230 if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &ExtendedSetupInformation, sizeof(ExtendedSetupInformation))
1231 != sizeof(ExtendedSetupInformation))
1232 Result = false;
1233
1234
1235
1236 if (BusLogic_GlobalOptions.TraceProbe)
1237 BusLogic_Notice("BusLogic_Check(0x%X): MultiMaster %s\n", HostAdapter, HostAdapter->IO_Address, (Result ? "Found" : "Not Found"));
1238 return Result;
1239}
1240
1241
1242
1243
1244
1245
1246
1247static bool __init BusLogic_ReadHostAdapterConfiguration(struct BusLogic_HostAdapter
1248 *HostAdapter)
1249{
1250 struct BusLogic_BoardID BoardID;
1251 struct BusLogic_Configuration Configuration;
1252 struct BusLogic_SetupInformation SetupInformation;
1253 struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation;
1254 unsigned char HostAdapterModelNumber[5];
1255 unsigned char FirmwareVersion3rdDigit;
1256 unsigned char FirmwareVersionLetter;
1257 struct BusLogic_PCIHostAdapterInformation PCIHostAdapterInformation;
1258 struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest;
1259 struct BusLogic_AutoSCSIData AutoSCSIData;
1260 union BusLogic_GeometryRegister GeometryRegister;
1261 unsigned char RequestedReplyLength;
1262 unsigned char *TargetPointer, Character;
1263 int TargetID, i;
1264
1265
1266
1267
1268
1269
1270 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1271 struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
1272 TargetPointer = HostAdapter->ModelName;
1273 *TargetPointer++ = 'B';
1274 *TargetPointer++ = 'T';
1275 *TargetPointer++ = '-';
1276 for (i = 0; i < sizeof(FlashPointInfo->ModelNumber); i++)
1277 *TargetPointer++ = FlashPointInfo->ModelNumber[i];
1278 *TargetPointer++ = '\0';
1279 strcpy(HostAdapter->FirmwareVersion, FlashPoint_FirmwareVersion);
1280 HostAdapter->SCSI_ID = FlashPointInfo->SCSI_ID;
1281 HostAdapter->ExtendedTranslationEnabled = FlashPointInfo->ExtendedTranslationEnabled;
1282 HostAdapter->ParityCheckingEnabled = FlashPointInfo->ParityCheckingEnabled;
1283 HostAdapter->BusResetEnabled = !FlashPointInfo->HostSoftReset;
1284 HostAdapter->LevelSensitiveInterrupt = true;
1285 HostAdapter->HostWideSCSI = FlashPointInfo->HostWideSCSI;
1286 HostAdapter->HostDifferentialSCSI = false;
1287 HostAdapter->HostSupportsSCAM = true;
1288 HostAdapter->HostUltraSCSI = true;
1289 HostAdapter->ExtendedLUNSupport = true;
1290 HostAdapter->TerminationInfoValid = true;
1291 HostAdapter->LowByteTerminated = FlashPointInfo->LowByteTerminated;
1292 HostAdapter->HighByteTerminated = FlashPointInfo->HighByteTerminated;
1293 HostAdapter->SCAM_Enabled = FlashPointInfo->SCAM_Enabled;
1294 HostAdapter->SCAM_Level2 = FlashPointInfo->SCAM_Level2;
1295 HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1296 HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1297 HostAdapter->MaxLogicalUnits = 32;
1298 HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1299 HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1300 HostAdapter->DriverQueueDepth = 255;
1301 HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth;
1302 HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted;
1303 HostAdapter->FastPermitted = FlashPointInfo->FastPermitted;
1304 HostAdapter->UltraPermitted = FlashPointInfo->UltraPermitted;
1305 HostAdapter->WidePermitted = FlashPointInfo->WidePermitted;
1306 HostAdapter->DisconnectPermitted = FlashPointInfo->DisconnectPermitted;
1307 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1308 goto Common;
1309 }
1310
1311
1312
1313 if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0, &BoardID, sizeof(BoardID)) != sizeof(BoardID))
1314 return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
1315
1316
1317
1318 if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0, &Configuration, sizeof(Configuration))
1319 != sizeof(Configuration))
1320 return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
1321
1322
1323
1324 RequestedReplyLength = sizeof(SetupInformation);
1325 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &SetupInformation, sizeof(SetupInformation))
1326 != sizeof(SetupInformation))
1327 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
1328
1329
1330
1331 RequestedReplyLength = sizeof(ExtendedSetupInformation);
1332 if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &ExtendedSetupInformation, sizeof(ExtendedSetupInformation))
1333 != sizeof(ExtendedSetupInformation))
1334 return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
1335
1336
1337
1338 FirmwareVersion3rdDigit = '\0';
1339 if (BoardID.FirmwareVersion1stDigit > '0')
1340 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit, NULL, 0, &FirmwareVersion3rdDigit, sizeof(FirmwareVersion3rdDigit))
1341 != sizeof(FirmwareVersion3rdDigit))
1342 return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
1343
1344
1345
1346 if (ExtendedSetupInformation.BusType == 'A' && BoardID.FirmwareVersion1stDigit == '2')
1347
1348 strcpy(HostAdapterModelNumber, "542B");
1349 else if (ExtendedSetupInformation.BusType == 'E' && BoardID.FirmwareVersion1stDigit == '2' && (BoardID.FirmwareVersion2ndDigit <= '1' || (BoardID.FirmwareVersion2ndDigit == '2' && FirmwareVersion3rdDigit == '0')))
1350
1351 strcpy(HostAdapterModelNumber, "742A");
1352 else if (ExtendedSetupInformation.BusType == 'E' && BoardID.FirmwareVersion1stDigit == '0')
1353
1354 strcpy(HostAdapterModelNumber, "747A");
1355 else {
1356 RequestedReplyLength = sizeof(HostAdapterModelNumber);
1357 if (BusLogic_Command(HostAdapter, BusLogic_InquireHostAdapterModelNumber, &RequestedReplyLength, sizeof(RequestedReplyLength), &HostAdapterModelNumber, sizeof(HostAdapterModelNumber))
1358 != sizeof(HostAdapterModelNumber))
1359 return BusLogic_Failure(HostAdapter, "INQUIRE HOST ADAPTER MODEL NUMBER");
1360 }
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379 TargetPointer = HostAdapter->ModelName;
1380 *TargetPointer++ = 'B';
1381 *TargetPointer++ = 'T';
1382 *TargetPointer++ = '-';
1383 for (i = 0; i < sizeof(HostAdapterModelNumber); i++) {
1384 Character = HostAdapterModelNumber[i];
1385 if (Character == ' ' || Character == '\0')
1386 break;
1387 *TargetPointer++ = Character;
1388 }
1389 *TargetPointer++ = '\0';
1390
1391
1392
1393 TargetPointer = HostAdapter->FirmwareVersion;
1394 *TargetPointer++ = BoardID.FirmwareVersion1stDigit;
1395 *TargetPointer++ = '.';
1396 *TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
1397 if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0')
1398 *TargetPointer++ = FirmwareVersion3rdDigit;
1399 *TargetPointer = '\0';
1400
1401
1402
1403 if (strcmp(HostAdapter->FirmwareVersion, "3.3") >= 0) {
1404 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter, NULL, 0, &FirmwareVersionLetter, sizeof(FirmwareVersionLetter))
1405 != sizeof(FirmwareVersionLetter))
1406 return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE VERSION LETTER");
1407 if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0')
1408 *TargetPointer++ = FirmwareVersionLetter;
1409 *TargetPointer = '\0';
1410 }
1411
1412
1413
1414 HostAdapter->SCSI_ID = Configuration.HostAdapterID;
1415
1416
1417
1418
1419
1420 HostAdapter->HostAdapterBusType = BusLogic_HostAdapterBusTypes[HostAdapter->ModelName[3] - '4'];
1421 if (HostAdapter->IRQ_Channel == 0) {
1422 if (Configuration.IRQ_Channel9)
1423 HostAdapter->IRQ_Channel = 9;
1424 else if (Configuration.IRQ_Channel10)
1425 HostAdapter->IRQ_Channel = 10;
1426 else if (Configuration.IRQ_Channel11)
1427 HostAdapter->IRQ_Channel = 11;
1428 else if (Configuration.IRQ_Channel12)
1429 HostAdapter->IRQ_Channel = 12;
1430 else if (Configuration.IRQ_Channel14)
1431 HostAdapter->IRQ_Channel = 14;
1432 else if (Configuration.IRQ_Channel15)
1433 HostAdapter->IRQ_Channel = 15;
1434 }
1435 if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus) {
1436 if (Configuration.DMA_Channel5)
1437 HostAdapter->DMA_Channel = 5;
1438 else if (Configuration.DMA_Channel6)
1439 HostAdapter->DMA_Channel = 6;
1440 else if (Configuration.DMA_Channel7)
1441 HostAdapter->DMA_Channel = 7;
1442 }
1443
1444
1445
1446
1447 GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1448 HostAdapter->ExtendedTranslationEnabled = GeometryRegister.gr.ExtendedTranslationEnabled;
1449
1450
1451
1452
1453
1454 HostAdapter->HostAdapterScatterGatherLimit = ExtendedSetupInformation.ScatterGatherLimit;
1455 HostAdapter->DriverScatterGatherLimit = HostAdapter->HostAdapterScatterGatherLimit;
1456 if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
1457 HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1458 if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupt)
1459 HostAdapter->LevelSensitiveInterrupt = true;
1460 HostAdapter->HostWideSCSI = ExtendedSetupInformation.HostWideSCSI;
1461 HostAdapter->HostDifferentialSCSI = ExtendedSetupInformation.HostDifferentialSCSI;
1462 HostAdapter->HostSupportsSCAM = ExtendedSetupInformation.HostSupportsSCAM;
1463 HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI;
1464
1465
1466
1467
1468 if (HostAdapter->FirmwareVersion[0] == '5' || (HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI))
1469 HostAdapter->ExtendedLUNSupport = true;
1470
1471
1472
1473
1474 if (HostAdapter->FirmwareVersion[0] == '5') {
1475 if (BusLogic_Command(HostAdapter, BusLogic_InquirePCIHostAdapterInformation, NULL, 0, &PCIHostAdapterInformation, sizeof(PCIHostAdapterInformation))
1476 != sizeof(PCIHostAdapterInformation))
1477 return BusLogic_Failure(HostAdapter, "INQUIRE PCI HOST ADAPTER INFORMATION");
1478
1479
1480
1481 if (PCIHostAdapterInformation.GenericInfoValid) {
1482 HostAdapter->TerminationInfoValid = true;
1483 HostAdapter->LowByteTerminated = PCIHostAdapterInformation.LowByteTerminated;
1484 HostAdapter->HighByteTerminated = PCIHostAdapterInformation.HighByteTerminated;
1485 }
1486 }
1487
1488
1489
1490
1491 if (HostAdapter->FirmwareVersion[0] >= '4') {
1492 FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_AutoSCSI_BaseOffset;
1493 FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIData);
1494 if (BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &AutoSCSIData, sizeof(AutoSCSIData))
1495 != sizeof(AutoSCSIData))
1496 return BusLogic_Failure(HostAdapter, "FETCH HOST ADAPTER LOCAL RAM");
1497
1498
1499
1500
1501 HostAdapter->ParityCheckingEnabled = AutoSCSIData.ParityCheckingEnabled;
1502 HostAdapter->BusResetEnabled = AutoSCSIData.BusResetEnabled;
1503 if (HostAdapter->FirmwareVersion[0] == '4') {
1504 HostAdapter->TerminationInfoValid = true;
1505 HostAdapter->LowByteTerminated = AutoSCSIData.LowByteTerminated;
1506 HostAdapter->HighByteTerminated = AutoSCSIData.HighByteTerminated;
1507 }
1508
1509
1510
1511
1512
1513 HostAdapter->WidePermitted = AutoSCSIData.WidePermitted;
1514 HostAdapter->FastPermitted = AutoSCSIData.FastPermitted;
1515 HostAdapter->SynchronousPermitted = AutoSCSIData.SynchronousPermitted;
1516 HostAdapter->DisconnectPermitted = AutoSCSIData.DisconnectPermitted;
1517 if (HostAdapter->HostUltraSCSI)
1518 HostAdapter->UltraPermitted = AutoSCSIData.UltraPermitted;
1519 if (HostAdapter->HostSupportsSCAM) {
1520 HostAdapter->SCAM_Enabled = AutoSCSIData.SCAM_Enabled;
1521 HostAdapter->SCAM_Level2 = AutoSCSIData.SCAM_Level2;
1522 }
1523 }
1524
1525
1526
1527
1528 if (HostAdapter->FirmwareVersion[0] < '4') {
1529 if (SetupInformation.SynchronousInitiationEnabled) {
1530 HostAdapter->SynchronousPermitted = 0xFF;
1531 if (HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus) {
1532 if (ExtendedSetupInformation.Misc.FastOnEISA)
1533 HostAdapter->FastPermitted = 0xFF;
1534 if (strcmp(HostAdapter->ModelName, "BT-757") == 0)
1535 HostAdapter->WidePermitted = 0xFF;
1536 }
1537 }
1538 HostAdapter->DisconnectPermitted = 0xFF;
1539 HostAdapter->ParityCheckingEnabled = SetupInformation.ParityCheckingEnabled;
1540 HostAdapter->BusResetEnabled = true;
1541 }
1542
1543
1544
1545
1546 HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1547 HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8);
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571 if (HostAdapter->FirmwareVersion[0] == '5')
1572 HostAdapter->HostAdapterQueueDepth = 192;
1573 else if (HostAdapter->FirmwareVersion[0] == '4')
1574 HostAdapter->HostAdapterQueueDepth = (HostAdapter->HostAdapterBusType != BusLogic_ISA_Bus ? 100 : 50);
1575 else
1576 HostAdapter->HostAdapterQueueDepth = 30;
1577 if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0) {
1578 HostAdapter->StrictRoundRobinModeSupport = true;
1579 HostAdapter->MailboxCount = BusLogic_MaxMailboxes;
1580 } else {
1581 HostAdapter->StrictRoundRobinModeSupport = false;
1582 HostAdapter->MailboxCount = 32;
1583 }
1584 HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount;
1585 HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1586 HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1587
1588
1589
1590
1591
1592
1593 HostAdapter->TaggedQueuingPermitted = 0;
1594 switch (HostAdapter->FirmwareVersion[0]) {
1595 case '5':
1596 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1597 break;
1598 case '4':
1599 if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0)
1600 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1601 break;
1602 case '3':
1603 if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0)
1604 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1605 break;
1606 }
1607
1608
1609
1610
1611
1612 HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
1613
1614
1615
1616 if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus && (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1617 HostAdapter->BounceBuffersRequired = true;
1618
1619
1620
1621
1622
1623
1624
1625
1626 if (HostAdapter->BIOS_Address > 0 && strcmp(HostAdapter->ModelName, "BT-445S") == 0 && strcmp(HostAdapter->FirmwareVersion, "3.37") < 0 && (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1627 HostAdapter->BounceBuffersRequired = true;
1628
1629
1630
1631 Common:
1632
1633
1634
1635 strcpy(HostAdapter->FullModelName, "BusLogic ");
1636 strcat(HostAdapter->FullModelName, HostAdapter->ModelName);
1637
1638
1639
1640
1641
1642
1643
1644 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) {
1645 unsigned char QueueDepth = 0;
1646 if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->QueueDepth[TargetID] > 0)
1647 QueueDepth = HostAdapter->DriverOptions->QueueDepth[TargetID];
1648 else if (HostAdapter->BounceBuffersRequired)
1649 QueueDepth = BusLogic_TaggedQueueDepthBB;
1650 HostAdapter->QueueDepth[TargetID] = QueueDepth;
1651 }
1652 if (HostAdapter->BounceBuffersRequired)
1653 HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepthBB;
1654 else
1655 HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth;
1656 if (HostAdapter->DriverOptions != NULL)
1657 HostAdapter->CommonQueueDepth = HostAdapter->DriverOptions->CommonQueueDepth;
1658 if (HostAdapter->CommonQueueDepth > 0 && HostAdapter->CommonQueueDepth < HostAdapter->UntaggedQueueDepth)
1659 HostAdapter->UntaggedQueueDepth = HostAdapter->CommonQueueDepth;
1660
1661
1662
1663
1664
1665 HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted;
1666
1667
1668
1669
1670 if (HostAdapter->DriverOptions != NULL)
1671 HostAdapter->TaggedQueuingPermitted =
1672 (HostAdapter->DriverOptions->TaggedQueuingPermitted & HostAdapter->DriverOptions->TaggedQueuingPermittedMask) | (HostAdapter->TaggedQueuingPermitted & ~HostAdapter->DriverOptions->TaggedQueuingPermittedMask);
1673
1674
1675
1676
1677
1678 if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->BusSettleTime > 0)
1679 HostAdapter->BusSettleTime = HostAdapter->DriverOptions->BusSettleTime;
1680 else
1681 HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
1682
1683
1684
1685 return true;
1686}
1687
1688
1689
1690
1691
1692
1693
1694static bool __init BusLogic_ReportHostAdapterConfiguration(struct BusLogic_HostAdapter
1695 *HostAdapter)
1696{
1697 unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1;
1698 unsigned short SynchronousPermitted, FastPermitted;
1699 unsigned short UltraPermitted, WidePermitted;
1700 unsigned short DisconnectPermitted, TaggedQueuingPermitted;
1701 bool CommonSynchronousNegotiation, CommonTaggedQueueDepth;
1702 char SynchronousString[BusLogic_MaxTargetDevices + 1];
1703 char WideString[BusLogic_MaxTargetDevices + 1];
1704 char DisconnectString[BusLogic_MaxTargetDevices + 1];
1705 char TaggedQueuingString[BusLogic_MaxTargetDevices + 1];
1706 char *SynchronousMessage = SynchronousString;
1707 char *WideMessage = WideString;
1708 char *DisconnectMessage = DisconnectString;
1709 char *TaggedQueuingMessage = TaggedQueuingString;
1710 int TargetID;
1711 BusLogic_Info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n",
1712 HostAdapter, HostAdapter->ModelName,
1713 BusLogic_HostAdapterBusNames[HostAdapter->HostAdapterBusType], (HostAdapter->HostWideSCSI ? " Wide" : ""), (HostAdapter->HostDifferentialSCSI ? " Differential" : ""), (HostAdapter->HostUltraSCSI ? " Ultra" : ""));
1714 BusLogic_Info(" Firmware Version: %s, I/O Address: 0x%X, " "IRQ Channel: %d/%s\n", HostAdapter, HostAdapter->FirmwareVersion, HostAdapter->IO_Address, HostAdapter->IRQ_Channel, (HostAdapter->LevelSensitiveInterrupt ? "Level" : "Edge"));
1715 if (HostAdapter->HostAdapterBusType != BusLogic_PCI_Bus) {
1716 BusLogic_Info(" DMA Channel: ", HostAdapter);
1717 if (HostAdapter->DMA_Channel > 0)
1718 BusLogic_Info("%d, ", HostAdapter, HostAdapter->DMA_Channel);
1719 else
1720 BusLogic_Info("None, ", HostAdapter);
1721 if (HostAdapter->BIOS_Address > 0)
1722 BusLogic_Info("BIOS Address: 0x%X, ", HostAdapter, HostAdapter->BIOS_Address);
1723 else
1724 BusLogic_Info("BIOS Address: None, ", HostAdapter);
1725 } else {
1726 BusLogic_Info(" PCI Bus: %d, Device: %d, Address: ", HostAdapter, HostAdapter->Bus, HostAdapter->Device);
1727 if (HostAdapter->PCI_Address > 0)
1728 BusLogic_Info("0x%X, ", HostAdapter, HostAdapter->PCI_Address);
1729 else
1730 BusLogic_Info("Unassigned, ", HostAdapter);
1731 }
1732 BusLogic_Info("Host Adapter SCSI ID: %d\n", HostAdapter, HostAdapter->SCSI_ID);
1733 BusLogic_Info(" Parity Checking: %s, Extended Translation: %s\n", HostAdapter, (HostAdapter->ParityCheckingEnabled ? "Enabled" : "Disabled"), (HostAdapter->ExtendedTranslationEnabled ? "Enabled" : "Disabled"));
1734 AllTargetsMask &= ~(1 << HostAdapter->SCSI_ID);
1735 SynchronousPermitted = HostAdapter->SynchronousPermitted & AllTargetsMask;
1736 FastPermitted = HostAdapter->FastPermitted & AllTargetsMask;
1737 UltraPermitted = HostAdapter->UltraPermitted & AllTargetsMask;
1738 if ((BusLogic_MultiMasterHostAdapterP(HostAdapter) && (HostAdapter->FirmwareVersion[0] >= '4' || HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)) || BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1739 CommonSynchronousNegotiation = false;
1740 if (SynchronousPermitted == 0) {
1741 SynchronousMessage = "Disabled";
1742 CommonSynchronousNegotiation = true;
1743 } else if (SynchronousPermitted == AllTargetsMask) {
1744 if (FastPermitted == 0) {
1745 SynchronousMessage = "Slow";
1746 CommonSynchronousNegotiation = true;
1747 } else if (FastPermitted == AllTargetsMask) {
1748 if (UltraPermitted == 0) {
1749 SynchronousMessage = "Fast";
1750 CommonSynchronousNegotiation = true;
1751 } else if (UltraPermitted == AllTargetsMask) {
1752 SynchronousMessage = "Ultra";
1753 CommonSynchronousNegotiation = true;
1754 }
1755 }
1756 }
1757 if (!CommonSynchronousNegotiation) {
1758 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1759 SynchronousString[TargetID] = ((!(SynchronousPermitted & (1 << TargetID))) ? 'N' : (!(FastPermitted & (1 << TargetID)) ? 'S' : (!(UltraPermitted & (1 << TargetID)) ? 'F' : 'U')));
1760 SynchronousString[HostAdapter->SCSI_ID] = '#';
1761 SynchronousString[HostAdapter->MaxTargetDevices] = '\0';
1762 }
1763 } else
1764 SynchronousMessage = (SynchronousPermitted == 0 ? "Disabled" : "Enabled");
1765 WidePermitted = HostAdapter->WidePermitted & AllTargetsMask;
1766 if (WidePermitted == 0)
1767 WideMessage = "Disabled";
1768 else if (WidePermitted == AllTargetsMask)
1769 WideMessage = "Enabled";
1770 else {
1771 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1772 WideString[TargetID] = ((WidePermitted & (1 << TargetID)) ? 'Y' : 'N');
1773 WideString[HostAdapter->SCSI_ID] = '#';
1774 WideString[HostAdapter->MaxTargetDevices] = '\0';
1775 }
1776 DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
1777 if (DisconnectPermitted == 0)
1778 DisconnectMessage = "Disabled";
1779 else if (DisconnectPermitted == AllTargetsMask)
1780 DisconnectMessage = "Enabled";
1781 else {
1782 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1783 DisconnectString[TargetID] = ((DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
1784 DisconnectString[HostAdapter->SCSI_ID] = '#';
1785 DisconnectString[HostAdapter->MaxTargetDevices] = '\0';
1786 }
1787 TaggedQueuingPermitted = HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
1788 if (TaggedQueuingPermitted == 0)
1789 TaggedQueuingMessage = "Disabled";
1790 else if (TaggedQueuingPermitted == AllTargetsMask)
1791 TaggedQueuingMessage = "Enabled";
1792 else {
1793 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1794 TaggedQueuingString[TargetID] = ((TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
1795 TaggedQueuingString[HostAdapter->SCSI_ID] = '#';
1796 TaggedQueuingString[HostAdapter->MaxTargetDevices] = '\0';
1797 }
1798 BusLogic_Info(" Synchronous Negotiation: %s, Wide Negotiation: %s\n", HostAdapter, SynchronousMessage, WideMessage);
1799 BusLogic_Info(" Disconnect/Reconnect: %s, Tagged Queuing: %s\n", HostAdapter, DisconnectMessage, TaggedQueuingMessage);
1800 if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
1801 BusLogic_Info(" Scatter/Gather Limit: %d of %d segments, " "Mailboxes: %d\n", HostAdapter, HostAdapter->DriverScatterGatherLimit, HostAdapter->HostAdapterScatterGatherLimit, HostAdapter->MailboxCount);
1802 BusLogic_Info(" Driver Queue Depth: %d, " "Host Adapter Queue Depth: %d\n", HostAdapter, HostAdapter->DriverQueueDepth, HostAdapter->HostAdapterQueueDepth);
1803 } else
1804 BusLogic_Info(" Driver Queue Depth: %d, " "Scatter/Gather Limit: %d segments\n", HostAdapter, HostAdapter->DriverQueueDepth, HostAdapter->DriverScatterGatherLimit);
1805 BusLogic_Info(" Tagged Queue Depth: ", HostAdapter);
1806 CommonTaggedQueueDepth = true;
1807 for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1808 if (HostAdapter->QueueDepth[TargetID] != HostAdapter->QueueDepth[0]) {
1809 CommonTaggedQueueDepth = false;
1810 break;
1811 }
1812 if (CommonTaggedQueueDepth) {
1813 if (HostAdapter->QueueDepth[0] > 0)
1814 BusLogic_Info("%d", HostAdapter, HostAdapter->QueueDepth[0]);
1815 else
1816 BusLogic_Info("Automatic", HostAdapter);
1817 } else
1818 BusLogic_Info("Individual", HostAdapter);
1819 BusLogic_Info(", Untagged Queue Depth: %d\n", HostAdapter, HostAdapter->UntaggedQueueDepth);
1820 if (HostAdapter->TerminationInfoValid) {
1821 if (HostAdapter->HostWideSCSI)
1822 BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter, (HostAdapter->LowByteTerminated ? (HostAdapter->HighByteTerminated ? "Both Enabled" : "Low Enabled")
1823 : (HostAdapter->HighByteTerminated ? "High Enabled" : "Both Disabled")));
1824 else
1825 BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter, (HostAdapter->LowByteTerminated ? "Enabled" : "Disabled"));
1826 if (HostAdapter->HostSupportsSCAM)
1827 BusLogic_Info(", SCAM: %s", HostAdapter, (HostAdapter->SCAM_Enabled ? (HostAdapter->SCAM_Level2 ? "Enabled, Level 2" : "Enabled, Level 1")
1828 : "Disabled"));
1829 BusLogic_Info("\n", HostAdapter);
1830 }
1831
1832
1833
1834 return true;
1835}
1836
1837
1838
1839
1840
1841
1842
1843static bool __init BusLogic_AcquireResources(struct BusLogic_HostAdapter *HostAdapter)
1844{
1845 if (HostAdapter->IRQ_Channel == 0) {
1846 BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n", HostAdapter);
1847 return false;
1848 }
1849
1850
1851
1852 if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler, IRQF_SHARED, HostAdapter->FullModelName, HostAdapter) < 0) {
1853 BusLogic_Error("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n", HostAdapter, HostAdapter->IRQ_Channel);
1854 return false;
1855 }
1856 HostAdapter->IRQ_ChannelAcquired = true;
1857
1858
1859
1860 if (HostAdapter->DMA_Channel > 0) {
1861 if (request_dma(HostAdapter->DMA_Channel, HostAdapter->FullModelName) < 0) {
1862 BusLogic_Error("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n", HostAdapter, HostAdapter->DMA_Channel);
1863 return false;
1864 }
1865 set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
1866 enable_dma(HostAdapter->DMA_Channel);
1867 HostAdapter->DMA_ChannelAcquired = true;
1868 }
1869
1870
1871
1872 return true;
1873}
1874
1875
1876
1877
1878
1879
1880
1881static void BusLogic_ReleaseResources(struct BusLogic_HostAdapter *HostAdapter)
1882{
1883
1884
1885
1886 if (HostAdapter->IRQ_ChannelAcquired)
1887 free_irq(HostAdapter->IRQ_Channel, HostAdapter);
1888
1889
1890
1891 if (HostAdapter->DMA_ChannelAcquired)
1892 free_dma(HostAdapter->DMA_Channel);
1893
1894
1895
1896 if (HostAdapter->MailboxSpace)
1897 pci_free_consistent(HostAdapter->PCI_Device, HostAdapter->MailboxSize, HostAdapter->MailboxSpace, HostAdapter->MailboxSpaceHandle);
1898 pci_dev_put(HostAdapter->PCI_Device);
1899 HostAdapter->MailboxSpace = NULL;
1900 HostAdapter->MailboxSpaceHandle = 0;
1901 HostAdapter->MailboxSize = 0;
1902}
1903
1904
1905
1906
1907
1908
1909
1910
1911static bool BusLogic_InitializeHostAdapter(struct BusLogic_HostAdapter
1912 *HostAdapter)
1913{
1914 struct BusLogic_ExtendedMailboxRequest ExtendedMailboxRequest;
1915 enum BusLogic_RoundRobinModeRequest RoundRobinModeRequest;
1916 enum BusLogic_SetCCBFormatRequest SetCCBFormatRequest;
1917 int TargetID;
1918
1919
1920
1921
1922 HostAdapter->FirstCompletedCCB = NULL;
1923 HostAdapter->LastCompletedCCB = NULL;
1924
1925
1926
1927
1928
1929 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
1930 HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
1931 HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
1932 HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
1933 HostAdapter->ActiveCommands[TargetID] = 0;
1934 HostAdapter->CommandsSinceReset[TargetID] = 0;
1935 }
1936
1937
1938
1939 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1940 goto Done;
1941
1942
1943
1944 HostAdapter->MailboxSize = HostAdapter->MailboxCount * (sizeof(struct BusLogic_OutgoingMailbox) + sizeof(struct BusLogic_IncomingMailbox));
1945 HostAdapter->MailboxSpace = pci_alloc_consistent(HostAdapter->PCI_Device, HostAdapter->MailboxSize, &HostAdapter->MailboxSpaceHandle);
1946 if (HostAdapter->MailboxSpace == NULL)
1947 return BusLogic_Failure(HostAdapter, "MAILBOX ALLOCATION");
1948 HostAdapter->FirstOutgoingMailbox = (struct BusLogic_OutgoingMailbox *) HostAdapter->MailboxSpace;
1949 HostAdapter->LastOutgoingMailbox = HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1;
1950 HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
1951 HostAdapter->FirstIncomingMailbox = (struct BusLogic_IncomingMailbox *) (HostAdapter->LastOutgoingMailbox + 1);
1952 HostAdapter->LastIncomingMailbox = HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1;
1953 HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
1954
1955
1956
1957
1958 memset(HostAdapter->FirstOutgoingMailbox, 0, HostAdapter->MailboxCount * sizeof(struct BusLogic_OutgoingMailbox));
1959 memset(HostAdapter->FirstIncomingMailbox, 0, HostAdapter->MailboxCount * sizeof(struct BusLogic_IncomingMailbox));
1960
1961
1962
1963 ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount;
1964 ExtendedMailboxRequest.BaseMailboxAddress = (u32) HostAdapter->MailboxSpaceHandle;
1965 if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox, &ExtendedMailboxRequest, sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
1966 return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION");
1967
1968
1969
1970
1971
1972
1973
1974 if (HostAdapter->StrictRoundRobinModeSupport) {
1975 RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
1976 if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode, &RoundRobinModeRequest, sizeof(RoundRobinModeRequest), NULL, 0) < 0)
1977 return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
1978 }
1979
1980
1981
1982
1983 if (HostAdapter->ExtendedLUNSupport) {
1984 SetCCBFormatRequest = BusLogic_ExtendedLUNFormatCCB;
1985 if (BusLogic_Command(HostAdapter, BusLogic_SetCCBFormat, &SetCCBFormatRequest, sizeof(SetCCBFormatRequest), NULL, 0) < 0)
1986 return BusLogic_Failure(HostAdapter, "SET CCB FORMAT");
1987 }
1988
1989
1990
1991 Done:
1992 if (!HostAdapter->HostAdapterInitialized) {
1993 BusLogic_Info("*** %s Initialized Successfully ***\n", HostAdapter, HostAdapter->FullModelName);
1994 BusLogic_Info("\n", HostAdapter);
1995 } else
1996 BusLogic_Warning("*** %s Initialized Successfully ***\n", HostAdapter, HostAdapter->FullModelName);
1997 HostAdapter->HostAdapterInitialized = true;
1998
1999
2000
2001 return true;
2002}
2003
2004
2005
2006
2007
2008
2009
2010static bool __init BusLogic_TargetDeviceInquiry(struct BusLogic_HostAdapter
2011 *HostAdapter)
2012{
2013 u16 InstalledDevices;
2014 u8 InstalledDevicesID0to7[8];
2015 struct BusLogic_SetupInformation SetupInformation;
2016 u8 SynchronousPeriod[BusLogic_MaxTargetDevices];
2017 unsigned char RequestedReplyLength;
2018 int TargetID;
2019
2020
2021
2022
2023
2024 BusLogic_Delay(HostAdapter->BusSettleTime);
2025
2026
2027
2028 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
2029 return true;
2030
2031
2032
2033 if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
2034 return true;
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044 if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0) {
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054 if (BusLogic_Command(HostAdapter, BusLogic_InquireTargetDevices, NULL, 0, &InstalledDevices, sizeof(InstalledDevices))
2055 != sizeof(InstalledDevices))
2056 return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES");
2057 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2058 HostAdapter->TargetFlags[TargetID].TargetExists = (InstalledDevices & (1 << TargetID) ? true : false);
2059 } else {
2060
2061
2062
2063
2064
2065
2066
2067 if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7, NULL, 0, &InstalledDevicesID0to7, sizeof(InstalledDevicesID0to7))
2068 != sizeof(InstalledDevicesID0to7))
2069 return BusLogic_Failure(HostAdapter, "INQUIRE INSTALLED DEVICES ID 0 TO 7");
2070 for (TargetID = 0; TargetID < 8; TargetID++)
2071 HostAdapter->TargetFlags[TargetID].TargetExists = (InstalledDevicesID0to7[TargetID] != 0 ? true : false);
2072 }
2073
2074
2075
2076 RequestedReplyLength = sizeof(SetupInformation);
2077 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &SetupInformation, sizeof(SetupInformation))
2078 != sizeof(SetupInformation))
2079 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
2080 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2081 HostAdapter->SynchronousOffset[TargetID] = (TargetID < 8 ? SetupInformation.SynchronousValuesID0to7[TargetID].Offset : SetupInformation.SynchronousValuesID8to15[TargetID - 8].Offset);
2082 if (strcmp(HostAdapter->FirmwareVersion, "5.06L") >= 0)
2083 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2084 HostAdapter->TargetFlags[TargetID].WideTransfersActive = (TargetID < 8 ? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID)
2085 ? true : false)
2086 : (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID - 8))
2087 ? true : false));
2088
2089
2090
2091 if (HostAdapter->FirmwareVersion[0] >= '3') {
2092
2093
2094
2095
2096
2097
2098 RequestedReplyLength = sizeof(SynchronousPeriod);
2099 if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod, &RequestedReplyLength, sizeof(RequestedReplyLength), &SynchronousPeriod, sizeof(SynchronousPeriod))
2100 != sizeof(SynchronousPeriod))
2101 return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
2102 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2103 HostAdapter->SynchronousPeriod[TargetID] = SynchronousPeriod[TargetID];
2104 } else
2105 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2106 if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
2107 HostAdapter->SynchronousPeriod[TargetID] = 20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
2108 .TransferPeriod;
2109
2110
2111
2112 return true;
2113}
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124static void __init BusLogic_InitializeHostStructure(struct BusLogic_HostAdapter
2125 *HostAdapter, struct Scsi_Host *Host)
2126{
2127 Host->max_id = HostAdapter->MaxTargetDevices;
2128 Host->max_lun = HostAdapter->MaxLogicalUnits;
2129 Host->max_channel = 0;
2130 Host->unique_id = HostAdapter->IO_Address;
2131 Host->this_id = HostAdapter->SCSI_ID;
2132 Host->can_queue = HostAdapter->DriverQueueDepth;
2133 Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
2134 Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
2135 Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth;
2136}
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146static int BusLogic_SlaveConfigure(struct scsi_device *Device)
2147{
2148 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Device->host->hostdata;
2149 int TargetID = Device->id;
2150 int QueueDepth = HostAdapter->QueueDepth[TargetID];
2151
2152 if (HostAdapter->TargetFlags[TargetID].TaggedQueuingSupported && (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) {
2153 if (QueueDepth == 0)
2154 QueueDepth = BusLogic_MaxAutomaticTaggedQueueDepth;
2155 HostAdapter->QueueDepth[TargetID] = QueueDepth;
2156 scsi_adjust_queue_depth(Device, MSG_SIMPLE_TAG, QueueDepth);
2157 } else {
2158 HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
2159 QueueDepth = HostAdapter->UntaggedQueueDepth;
2160 HostAdapter->QueueDepth[TargetID] = QueueDepth;
2161 scsi_adjust_queue_depth(Device, 0, QueueDepth);
2162 }
2163 QueueDepth = 0;
2164 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2165 if (HostAdapter->TargetFlags[TargetID].TargetExists) {
2166 QueueDepth += HostAdapter->QueueDepth[TargetID];
2167 }
2168 if (QueueDepth > HostAdapter->AllocatedCCBs)
2169 BusLogic_CreateAdditionalCCBs(HostAdapter, QueueDepth - HostAdapter->AllocatedCCBs, false);
2170 return 0;
2171}
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181static int __init BusLogic_init(void)
2182{
2183 int BusLogicHostAdapterCount = 0, DriverOptionsIndex = 0, ProbeIndex;
2184 struct BusLogic_HostAdapter *PrototypeHostAdapter;
2185 int ret = 0;
2186
2187#ifdef MODULE
2188 if (BusLogic)
2189 BusLogic_Setup(BusLogic);
2190#endif
2191
2192 if (BusLogic_ProbeOptions.NoProbe)
2193 return -ENODEV;
2194 BusLogic_ProbeInfoList =
2195 kzalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo), GFP_KERNEL);
2196 if (BusLogic_ProbeInfoList == NULL) {
2197 BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL);
2198 return -ENOMEM;
2199 }
2200
2201 PrototypeHostAdapter =
2202 kzalloc(sizeof(struct BusLogic_HostAdapter), GFP_KERNEL);
2203 if (PrototypeHostAdapter == NULL) {
2204 kfree(BusLogic_ProbeInfoList);
2205 BusLogic_Error("BusLogic: Unable to allocate Prototype " "Host Adapter\n", NULL);
2206 return -ENOMEM;
2207 }
2208
2209#ifdef MODULE
2210 if (BusLogic != NULL)
2211 BusLogic_Setup(BusLogic);
2212#endif
2213 BusLogic_InitializeProbeInfoList(PrototypeHostAdapter);
2214 for (ProbeIndex = 0; ProbeIndex < BusLogic_ProbeInfoCount; ProbeIndex++) {
2215 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[ProbeIndex];
2216 struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter;
2217 struct Scsi_Host *Host;
2218 if (ProbeInfo->IO_Address == 0)
2219 continue;
2220 memset(HostAdapter, 0, sizeof(struct BusLogic_HostAdapter));
2221 HostAdapter->HostAdapterType = ProbeInfo->HostAdapterType;
2222 HostAdapter->HostAdapterBusType = ProbeInfo->HostAdapterBusType;
2223 HostAdapter->IO_Address = ProbeInfo->IO_Address;
2224 HostAdapter->PCI_Address = ProbeInfo->PCI_Address;
2225 HostAdapter->Bus = ProbeInfo->Bus;
2226 HostAdapter->Device = ProbeInfo->Device;
2227 HostAdapter->PCI_Device = ProbeInfo->PCI_Device;
2228 HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel;
2229 HostAdapter->AddressCount = BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType];
2230
2231
2232
2233
2234 if (!request_region(HostAdapter->IO_Address, HostAdapter->AddressCount,
2235 "BusLogic"))
2236 continue;
2237
2238
2239
2240 if (!BusLogic_ProbeHostAdapter(HostAdapter)) {
2241 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2242 continue;
2243 }
2244
2245
2246
2247
2248 if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) {
2249 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2250 continue;
2251 }
2252
2253
2254
2255 if (!BusLogic_CheckHostAdapter(HostAdapter)) {
2256 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2257 continue;
2258 }
2259
2260
2261
2262 if (DriverOptionsIndex < BusLogic_DriverOptionsCount)
2263 HostAdapter->DriverOptions = &BusLogic_DriverOptions[DriverOptionsIndex++];
2264
2265
2266
2267
2268 BusLogic_AnnounceDriver(HostAdapter);
2269
2270
2271
2272
2273 Host = scsi_host_alloc(&Bus_Logic_template, sizeof(struct BusLogic_HostAdapter));
2274 if (Host == NULL) {
2275 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2276 continue;
2277 }
2278 HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata;
2279 memcpy(HostAdapter, PrototypeHostAdapter, sizeof(struct BusLogic_HostAdapter));
2280 HostAdapter->SCSI_Host = Host;
2281 HostAdapter->HostNumber = Host->host_no;
2282
2283
2284
2285
2286 list_add_tail(&HostAdapter->host_list, &BusLogic_host_list);
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300 if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
2301 BusLogic_ReportHostAdapterConfiguration(HostAdapter) &&
2302 BusLogic_AcquireResources(HostAdapter) &&
2303 BusLogic_CreateInitialCCBs(HostAdapter) &&
2304 BusLogic_InitializeHostAdapter(HostAdapter) &&
2305 BusLogic_TargetDeviceInquiry(HostAdapter)) {
2306
2307
2308
2309
2310
2311
2312 release_region(HostAdapter->IO_Address,
2313 HostAdapter->AddressCount);
2314 if (!request_region(HostAdapter->IO_Address,
2315 HostAdapter->AddressCount,
2316 HostAdapter->FullModelName)) {
2317 printk(KERN_WARNING
2318 "BusLogic: Release and re-register of "
2319 "port 0x%04lx failed \n",
2320 (unsigned long)HostAdapter->IO_Address);
2321 BusLogic_DestroyCCBs(HostAdapter);
2322 BusLogic_ReleaseResources(HostAdapter);
2323 list_del(&HostAdapter->host_list);
2324 scsi_host_put(Host);
2325 ret = -ENOMEM;
2326 } else {
2327 BusLogic_InitializeHostStructure(HostAdapter,
2328 Host);
2329 if (scsi_add_host(Host, HostAdapter->PCI_Device
2330 ? &HostAdapter->PCI_Device->dev
2331 : NULL)) {
2332 printk(KERN_WARNING
2333 "BusLogic: scsi_add_host()"
2334 "failed!\n");
2335 BusLogic_DestroyCCBs(HostAdapter);
2336 BusLogic_ReleaseResources(HostAdapter);
2337 list_del(&HostAdapter->host_list);
2338 scsi_host_put(Host);
2339 ret = -ENODEV;
2340 } else {
2341 scsi_scan_host(Host);
2342 BusLogicHostAdapterCount++;
2343 }
2344 }
2345 } else {
2346
2347
2348
2349
2350
2351
2352
2353
2354 BusLogic_DestroyCCBs(HostAdapter);
2355 BusLogic_ReleaseResources(HostAdapter);
2356 list_del(&HostAdapter->host_list);
2357 scsi_host_put(Host);
2358 ret = -ENODEV;
2359 }
2360 }
2361 kfree(PrototypeHostAdapter);
2362 kfree(BusLogic_ProbeInfoList);
2363 BusLogic_ProbeInfoList = NULL;
2364 return ret;
2365}
2366
2367
2368
2369
2370
2371
2372
2373
2374static int __exit BusLogic_ReleaseHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
2375{
2376 struct Scsi_Host *Host = HostAdapter->SCSI_Host;
2377
2378 scsi_remove_host(Host);
2379
2380
2381
2382
2383
2384 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
2385 FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle);
2386
2387
2388
2389
2390 BusLogic_DestroyCCBs(HostAdapter);
2391 BusLogic_ReleaseResources(HostAdapter);
2392
2393
2394
2395 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2396
2397
2398
2399 list_del(&HostAdapter->host_list);
2400
2401 scsi_host_put(Host);
2402 return 0;
2403}
2404
2405
2406
2407
2408
2409
2410static void BusLogic_QueueCompletedCCB(struct BusLogic_CCB *CCB)
2411{
2412 struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter;
2413 CCB->Status = BusLogic_CCB_Completed;
2414 CCB->Next = NULL;
2415 if (HostAdapter->FirstCompletedCCB == NULL) {
2416 HostAdapter->FirstCompletedCCB = CCB;
2417 HostAdapter->LastCompletedCCB = CCB;
2418 } else {
2419 HostAdapter->LastCompletedCCB->Next = CCB;
2420 HostAdapter->LastCompletedCCB = CCB;
2421 }
2422 HostAdapter->ActiveCommands[CCB->TargetID]--;
2423}
2424
2425
2426
2427
2428
2429
2430
2431static int BusLogic_ComputeResultCode(struct BusLogic_HostAdapter *HostAdapter, enum BusLogic_HostAdapterStatus HostAdapterStatus, enum BusLogic_TargetDeviceStatus TargetDeviceStatus)
2432{
2433 int HostStatus;
2434 switch (HostAdapterStatus) {
2435 case BusLogic_CommandCompletedNormally:
2436 case BusLogic_LinkedCommandCompleted:
2437 case BusLogic_LinkedCommandCompletedWithFlag:
2438 HostStatus = DID_OK;
2439 break;
2440 case BusLogic_SCSISelectionTimeout:
2441 HostStatus = DID_TIME_OUT;
2442 break;
2443 case BusLogic_InvalidOutgoingMailboxActionCode:
2444 case BusLogic_InvalidCommandOperationCode:
2445 case BusLogic_InvalidCommandParameter:
2446 BusLogic_Warning("BusLogic Driver Protocol Error 0x%02X\n", HostAdapter, HostAdapterStatus);
2447 case BusLogic_DataUnderRun:
2448 case BusLogic_DataOverRun:
2449 case BusLogic_UnexpectedBusFree:
2450 case BusLogic_LinkedCCBhasInvalidLUN:
2451 case BusLogic_AutoRequestSenseFailed:
2452 case BusLogic_TaggedQueuingMessageRejected:
2453 case BusLogic_UnsupportedMessageReceived:
2454 case BusLogic_HostAdapterHardwareFailed:
2455 case BusLogic_TargetDeviceReconnectedImproperly:
2456 case BusLogic_AbortQueueGenerated:
2457 case BusLogic_HostAdapterSoftwareError:
2458 case BusLogic_HostAdapterHardwareTimeoutError:
2459 case BusLogic_SCSIParityErrorDetected:
2460 HostStatus = DID_ERROR;
2461 break;
2462 case BusLogic_InvalidBusPhaseRequested:
2463 case BusLogic_TargetFailedResponseToATN:
2464 case BusLogic_HostAdapterAssertedRST:
2465 case BusLogic_OtherDeviceAssertedRST:
2466 case BusLogic_HostAdapterAssertedBusDeviceReset:
2467 HostStatus = DID_RESET;
2468 break;
2469 default:
2470 BusLogic_Warning("Unknown Host Adapter Status 0x%02X\n", HostAdapter, HostAdapterStatus);
2471 HostStatus = DID_ERROR;
2472 break;
2473 }
2474 return (HostStatus << 16) | TargetDeviceStatus;
2475}
2476
2477
2478
2479
2480
2481
2482
2483static void BusLogic_ScanIncomingMailboxes(struct BusLogic_HostAdapter *HostAdapter)
2484{
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497 struct BusLogic_IncomingMailbox *NextIncomingMailbox = HostAdapter->NextIncomingMailbox;
2498 enum BusLogic_CompletionCode CompletionCode;
2499 while ((CompletionCode = NextIncomingMailbox->CompletionCode) != BusLogic_IncomingMailboxFree) {
2500
2501
2502
2503
2504
2505
2506
2507 struct BusLogic_CCB *CCB = (struct BusLogic_CCB *) Bus_to_Virtual(NextIncomingMailbox->CCB);
2508 if (CompletionCode != BusLogic_AbortedCommandNotFound) {
2509 if (CCB->Status == BusLogic_CCB_Active || CCB->Status == BusLogic_CCB_Reset) {
2510
2511
2512
2513
2514 CCB->CompletionCode = CompletionCode;
2515 BusLogic_QueueCompletedCCB(CCB);
2516 } else {
2517
2518
2519
2520
2521
2522 BusLogic_Warning("Illegal CCB #%ld status %d in " "Incoming Mailbox\n", HostAdapter, CCB->SerialNumber, CCB->Status);
2523 }
2524 }
2525 NextIncomingMailbox->CompletionCode = BusLogic_IncomingMailboxFree;
2526 if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
2527 NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
2528 }
2529 HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
2530}
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540static void BusLogic_ProcessCompletedCCBs(struct BusLogic_HostAdapter *HostAdapter)
2541{
2542 if (HostAdapter->ProcessCompletedCCBsActive)
2543 return;
2544 HostAdapter->ProcessCompletedCCBsActive = true;
2545 while (HostAdapter->FirstCompletedCCB != NULL) {
2546 struct BusLogic_CCB *CCB = HostAdapter->FirstCompletedCCB;
2547 struct scsi_cmnd *Command = CCB->Command;
2548 HostAdapter->FirstCompletedCCB = CCB->Next;
2549 if (HostAdapter->FirstCompletedCCB == NULL)
2550 HostAdapter->LastCompletedCCB = NULL;
2551
2552
2553
2554 if (CCB->Opcode == BusLogic_BusDeviceReset) {
2555 int TargetID = CCB->TargetID;
2556 BusLogic_Warning("Bus Device Reset CCB #%ld to Target " "%d Completed\n", HostAdapter, CCB->SerialNumber, TargetID);
2557 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].BusDeviceResetsCompleted);
2558 HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
2559 HostAdapter->CommandsSinceReset[TargetID] = 0;
2560 HostAdapter->LastResetCompleted[TargetID] = jiffies;
2561
2562
2563
2564 BusLogic_DeallocateCCB(CCB);
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2586 if (CCB->Status == BusLogic_CCB_Reset && CCB->TargetID == TargetID) {
2587 Command = CCB->Command;
2588 BusLogic_DeallocateCCB(CCB);
2589 HostAdapter->ActiveCommands[TargetID]--;
2590 Command->result = DID_RESET << 16;
2591 Command->scsi_done(Command);
2592 }
2593 HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
2594 } else {
2595
2596
2597
2598
2599 switch (CCB->CompletionCode) {
2600 case BusLogic_IncomingMailboxFree:
2601 case BusLogic_AbortedCommandNotFound:
2602 case BusLogic_InvalidCCB:
2603 BusLogic_Warning("CCB #%ld to Target %d Impossible State\n", HostAdapter, CCB->SerialNumber, CCB->TargetID);
2604 break;
2605 case BusLogic_CommandCompletedWithoutError:
2606 HostAdapter->TargetStatistics[CCB->TargetID]
2607 .CommandsCompleted++;
2608 HostAdapter->TargetFlags[CCB->TargetID]
2609 .CommandSuccessfulFlag = true;
2610 Command->result = DID_OK << 16;
2611 break;
2612 case BusLogic_CommandAbortedAtHostRequest:
2613 BusLogic_Warning("CCB #%ld to Target %d Aborted\n", HostAdapter, CCB->SerialNumber, CCB->TargetID);
2614 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[CCB->TargetID]
2615 .CommandAbortsCompleted);
2616 Command->result = DID_ABORT << 16;
2617 break;
2618 case BusLogic_CommandCompletedWithError:
2619 Command->result = BusLogic_ComputeResultCode(HostAdapter, CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
2620 if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout) {
2621 HostAdapter->TargetStatistics[CCB->TargetID]
2622 .CommandsCompleted++;
2623 if (BusLogic_GlobalOptions.TraceErrors) {
2624 int i;
2625 BusLogic_Notice("CCB #%ld Target %d: Result %X Host "
2626 "Adapter Status %02X " "Target Status %02X\n", HostAdapter, CCB->SerialNumber, CCB->TargetID, Command->result, CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
2627 BusLogic_Notice("CDB ", HostAdapter);
2628 for (i = 0; i < CCB->CDB_Length; i++)
2629 BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]);
2630 BusLogic_Notice("\n", HostAdapter);
2631 BusLogic_Notice("Sense ", HostAdapter);
2632 for (i = 0; i < CCB->SenseDataLength; i++)
2633 BusLogic_Notice(" %02X", HostAdapter, Command->sense_buffer[i]);
2634 BusLogic_Notice("\n", HostAdapter);
2635 }
2636 }
2637 break;
2638 }
2639
2640
2641
2642
2643
2644 if (CCB->CDB[0] == INQUIRY && CCB->CDB[1] == 0 && CCB->HostAdapterStatus == BusLogic_CommandCompletedNormally) {
2645 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[CCB->TargetID];
2646 struct SCSI_Inquiry *InquiryResult =
2647 (struct SCSI_Inquiry *) scsi_sglist(Command);
2648 TargetFlags->TargetExists = true;
2649 TargetFlags->TaggedQueuingSupported = InquiryResult->CmdQue;
2650 TargetFlags->WideTransfersSupported = InquiryResult->WBus16;
2651 }
2652
2653
2654
2655 BusLogic_DeallocateCCB(CCB);
2656
2657
2658
2659 Command->scsi_done(Command);
2660 }
2661 }
2662 HostAdapter->ProcessCompletedCCBsActive = false;
2663}
2664
2665
2666
2667
2668
2669
2670
2671static irqreturn_t BusLogic_InterruptHandler(int IRQ_Channel, void *DeviceIdentifier)
2672{
2673 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) DeviceIdentifier;
2674 unsigned long ProcessorFlags;
2675
2676
2677
2678 spin_lock_irqsave(HostAdapter->SCSI_Host->host_lock, ProcessorFlags);
2679
2680
2681
2682 if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
2683 union BusLogic_InterruptRegister InterruptRegister;
2684
2685
2686
2687 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
2688 if (InterruptRegister.ir.InterruptValid) {
2689
2690
2691
2692
2693 BusLogic_InterruptReset(HostAdapter);
2694
2695
2696
2697
2698
2699
2700 if (InterruptRegister.ir.ExternalBusReset)
2701 HostAdapter->HostAdapterExternalReset = true;
2702 else if (InterruptRegister.ir.IncomingMailboxLoaded)
2703 BusLogic_ScanIncomingMailboxes(HostAdapter);
2704 else if (InterruptRegister.ir.CommandComplete)
2705 HostAdapter->HostAdapterCommandCompleted = true;
2706 }
2707 } else {
2708
2709
2710
2711 if (FlashPoint_InterruptPending(HostAdapter->CardHandle))
2712 switch (FlashPoint_HandleInterrupt(HostAdapter->CardHandle)) {
2713 case FlashPoint_NormalInterrupt:
2714 break;
2715 case FlashPoint_ExternalBusReset:
2716 HostAdapter->HostAdapterExternalReset = true;
2717 break;
2718 case FlashPoint_InternalError:
2719 BusLogic_Warning("Internal FlashPoint Error detected" " - Resetting Host Adapter\n", HostAdapter);
2720 HostAdapter->HostAdapterInternalError = true;
2721 break;
2722 }
2723 }
2724
2725
2726
2727 if (HostAdapter->FirstCompletedCCB != NULL)
2728 BusLogic_ProcessCompletedCCBs(HostAdapter);
2729
2730
2731
2732 if (HostAdapter->HostAdapterExternalReset) {
2733 BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n", HostAdapter, HostAdapter->FullModelName);
2734 BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets);
2735 BusLogic_ResetHostAdapter(HostAdapter, false);
2736 HostAdapter->HostAdapterExternalReset = false;
2737 } else if (HostAdapter->HostAdapterInternalError) {
2738 BusLogic_Warning("Resetting %s due to Host Adapter Internal Error\n", HostAdapter, HostAdapter->FullModelName);
2739 BusLogic_IncrementErrorCounter(&HostAdapter->HostAdapterInternalErrors);
2740 BusLogic_ResetHostAdapter(HostAdapter, true);
2741 HostAdapter->HostAdapterInternalError = false;
2742 }
2743
2744
2745
2746 spin_unlock_irqrestore(HostAdapter->SCSI_Host->host_lock, ProcessorFlags);
2747 return IRQ_HANDLED;
2748}
2749
2750
2751
2752
2753
2754
2755
2756
2757static bool BusLogic_WriteOutgoingMailbox(struct BusLogic_HostAdapter
2758 *HostAdapter, enum BusLogic_ActionCode ActionCode, struct BusLogic_CCB *CCB)
2759{
2760 struct BusLogic_OutgoingMailbox *NextOutgoingMailbox;
2761 NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
2762 if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree) {
2763 CCB->Status = BusLogic_CCB_Active;
2764
2765
2766
2767
2768
2769 NextOutgoingMailbox->CCB = CCB->DMA_Handle;
2770 NextOutgoingMailbox->ActionCode = ActionCode;
2771 BusLogic_StartMailboxCommand(HostAdapter);
2772 if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
2773 NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
2774 HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
2775 if (ActionCode == BusLogic_MailboxStartCommand) {
2776 HostAdapter->ActiveCommands[CCB->TargetID]++;
2777 if (CCB->Opcode != BusLogic_BusDeviceReset)
2778 HostAdapter->TargetStatistics[CCB->TargetID].CommandsAttempted++;
2779 }
2780 return true;
2781 }
2782 return false;
2783}
2784
2785
2786
2787static int BusLogic_host_reset(struct scsi_cmnd * SCpnt)
2788{
2789 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) SCpnt->device->host->hostdata;
2790
2791 unsigned int id = SCpnt->device->id;
2792 struct BusLogic_TargetStatistics *stats = &HostAdapter->TargetStatistics[id];
2793 int rc;
2794
2795 spin_lock_irq(SCpnt->device->host->host_lock);
2796
2797 BusLogic_IncrementErrorCounter(&stats->HostAdapterResetsRequested);
2798
2799 rc = BusLogic_ResetHostAdapter(HostAdapter, false);
2800 spin_unlock_irq(SCpnt->device->host->host_lock);
2801 return rc;
2802}
2803
2804
2805
2806
2807
2808
2809static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRoutine) (struct scsi_cmnd *))
2810{
2811 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata;
2812 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[Command->device->id];
2813 struct BusLogic_TargetStatistics *TargetStatistics = HostAdapter->TargetStatistics;
2814 unsigned char *CDB = Command->cmnd;
2815 int CDB_Length = Command->cmd_len;
2816 int TargetID = Command->device->id;
2817 int LogicalUnit = Command->device->lun;
2818 int BufferLength = scsi_bufflen(Command);
2819 int Count;
2820 struct BusLogic_CCB *CCB;
2821
2822
2823
2824
2825
2826 if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0) {
2827 Command->result = DID_OK << 16;
2828 CompletionRoutine(Command);
2829 return 0;
2830 }
2831
2832
2833
2834
2835
2836
2837 CCB = BusLogic_AllocateCCB(HostAdapter);
2838 if (CCB == NULL) {
2839 spin_unlock_irq(HostAdapter->SCSI_Host->host_lock);
2840 BusLogic_Delay(1);
2841 spin_lock_irq(HostAdapter->SCSI_Host->host_lock);
2842 CCB = BusLogic_AllocateCCB(HostAdapter);
2843 if (CCB == NULL) {
2844 Command->result = DID_ERROR << 16;
2845 CompletionRoutine(Command);
2846 return 0;
2847 }
2848 }
2849
2850
2851
2852
2853 Count = scsi_dma_map(Command);
2854 BUG_ON(Count < 0);
2855 if (Count) {
2856 struct scatterlist *sg;
2857 int i;
2858
2859 CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
2860 CCB->DataLength = Count * sizeof(struct BusLogic_ScatterGatherSegment);
2861 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
2862 CCB->DataPointer = (unsigned int) CCB->DMA_Handle + ((unsigned long) &CCB->ScatterGatherList - (unsigned long) CCB);
2863 else
2864 CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList);
2865
2866 scsi_for_each_sg(Command, sg, Count, i) {
2867 CCB->ScatterGatherList[i].SegmentByteCount =
2868 sg_dma_len(sg);
2869 CCB->ScatterGatherList[i].SegmentDataPointer =
2870 sg_dma_address(sg);
2871 }
2872 } else if (!Count) {
2873 CCB->Opcode = BusLogic_InitiatorCCB;
2874 CCB->DataLength = BufferLength;
2875 CCB->DataPointer = 0;
2876 }
2877
2878 switch (CDB[0]) {
2879 case READ_6:
2880 case READ_10:
2881 CCB->DataDirection = BusLogic_DataInLengthChecked;
2882 TargetStatistics[TargetID].ReadCommands++;
2883 BusLogic_IncrementByteCounter(&TargetStatistics[TargetID].TotalBytesRead, BufferLength);
2884 BusLogic_IncrementSizeBucket(TargetStatistics[TargetID].ReadCommandSizeBuckets, BufferLength);
2885 break;
2886 case WRITE_6:
2887 case WRITE_10:
2888 CCB->DataDirection = BusLogic_DataOutLengthChecked;
2889 TargetStatistics[TargetID].WriteCommands++;
2890 BusLogic_IncrementByteCounter(&TargetStatistics[TargetID].TotalBytesWritten, BufferLength);
2891 BusLogic_IncrementSizeBucket(TargetStatistics[TargetID].WriteCommandSizeBuckets, BufferLength);
2892 break;
2893 default:
2894 CCB->DataDirection = BusLogic_UncheckedDataTransfer;
2895 break;
2896 }
2897 CCB->CDB_Length = CDB_Length;
2898 CCB->HostAdapterStatus = 0;
2899 CCB->TargetDeviceStatus = 0;
2900 CCB->TargetID = TargetID;
2901 CCB->LogicalUnit = LogicalUnit;
2902 CCB->TagEnable = false;
2903 CCB->LegacyTagEnable = false;
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918 if (HostAdapter->CommandsSinceReset[TargetID]++ >=
2919 BusLogic_MaxTaggedQueueDepth && !TargetFlags->TaggedQueuingActive && HostAdapter->ActiveCommands[TargetID] == 0 && TargetFlags->TaggedQueuingSupported && (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) {
2920 TargetFlags->TaggedQueuingActive = true;
2921 BusLogic_Notice("Tagged Queuing now active for Target %d\n", HostAdapter, TargetID);
2922 }
2923 if (TargetFlags->TaggedQueuingActive) {
2924 enum BusLogic_QueueTag QueueTag = BusLogic_SimpleQueueTag;
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938 if (HostAdapter->ActiveCommands[TargetID] == 0)
2939 HostAdapter->LastSequencePoint[TargetID] = jiffies;
2940 else if (time_after(jiffies, HostAdapter->LastSequencePoint[TargetID] + 4 * HZ)) {
2941 HostAdapter->LastSequencePoint[TargetID] = jiffies;
2942 QueueTag = BusLogic_OrderedQueueTag;
2943 }
2944 if (HostAdapter->ExtendedLUNSupport) {
2945 CCB->TagEnable = true;
2946 CCB->QueueTag = QueueTag;
2947 } else {
2948 CCB->LegacyTagEnable = true;
2949 CCB->LegacyQueueTag = QueueTag;
2950 }
2951 }
2952 memcpy(CCB->CDB, CDB, CDB_Length);
2953 CCB->SenseDataLength = SCSI_SENSE_BUFFERSIZE;
2954 CCB->SenseDataPointer = pci_map_single(HostAdapter->PCI_Device, Command->sense_buffer, CCB->SenseDataLength, PCI_DMA_FROMDEVICE);
2955 CCB->Command = Command;
2956 Command->scsi_done = CompletionRoutine;
2957 if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
2958
2959
2960
2961
2962
2963
2964
2965
2966 if (!BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxStartCommand, CCB)) {
2967 spin_unlock_irq(HostAdapter->SCSI_Host->host_lock);
2968 BusLogic_Warning("Unable to write Outgoing Mailbox - " "Pausing for 1 second\n", HostAdapter);
2969 BusLogic_Delay(1);
2970 spin_lock_irq(HostAdapter->SCSI_Host->host_lock);
2971 if (!BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxStartCommand, CCB)) {
2972 BusLogic_Warning("Still unable to write Outgoing Mailbox - " "Host Adapter Dead?\n", HostAdapter);
2973 BusLogic_DeallocateCCB(CCB);
2974 Command->result = DID_ERROR << 16;
2975 Command->scsi_done(Command);
2976 }
2977 }
2978 } else {
2979
2980
2981
2982 CCB->Status = BusLogic_CCB_Active;
2983 HostAdapter->ActiveCommands[TargetID]++;
2984 TargetStatistics[TargetID].CommandsAttempted++;
2985 FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
2986
2987
2988
2989
2990 if (CCB->Status == BusLogic_CCB_Completed)
2991 BusLogic_ProcessCompletedCCBs(HostAdapter);
2992 }
2993 return 0;
2994}
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter, bool HardReset)
3075{
3076 struct BusLogic_CCB *CCB;
3077 int TargetID;
3078
3079
3080
3081
3082
3083 if (!(BusLogic_HardwareResetHostAdapter(HostAdapter, HardReset) && BusLogic_InitializeHostAdapter(HostAdapter))) {
3084 BusLogic_Error("Resetting %s Failed\n", HostAdapter, HostAdapter->FullModelName);
3085 return FAILURE;
3086 }
3087
3088
3089
3090
3091
3092 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3093 if (CCB->Status == BusLogic_CCB_Active)
3094 BusLogic_DeallocateCCB(CCB);
3095
3096
3097
3098
3099
3100
3101
3102 if (HardReset) {
3103 spin_unlock_irq(HostAdapter->SCSI_Host->host_lock);
3104 BusLogic_Delay(HostAdapter->BusSettleTime);
3105 spin_lock_irq(HostAdapter->SCSI_Host->host_lock);
3106 }
3107
3108 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3109 HostAdapter->LastResetAttempted[TargetID] = jiffies;
3110 HostAdapter->LastResetCompleted[TargetID] = jiffies;
3111 }
3112 return SUCCESS;
3113}
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132static int BusLogic_BIOSDiskParameters(struct scsi_device *sdev, struct block_device *Device, sector_t capacity, int *Parameters)
3133{
3134 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) sdev->host->hostdata;
3135 struct BIOS_DiskParameters *DiskParameters = (struct BIOS_DiskParameters *) Parameters;
3136 unsigned char *buf;
3137 if (HostAdapter->ExtendedTranslationEnabled && capacity >= 2 * 1024 * 1024 ) {
3138 if (capacity >= 4 * 1024 * 1024 ) {
3139 DiskParameters->Heads = 255;
3140 DiskParameters->Sectors = 63;
3141 } else {
3142 DiskParameters->Heads = 128;
3143 DiskParameters->Sectors = 32;
3144 }
3145 } else {
3146 DiskParameters->Heads = 64;
3147 DiskParameters->Sectors = 32;
3148 }
3149 DiskParameters->Cylinders = (unsigned long) capacity / (DiskParameters->Heads * DiskParameters->Sectors);
3150 buf = scsi_bios_ptable(Device);
3151 if (buf == NULL)
3152 return 0;
3153
3154
3155
3156
3157
3158 if (*(unsigned short *) (buf + 64) == 0xAA55) {
3159 struct partition *FirstPartitionEntry = (struct partition *) buf;
3160 struct partition *PartitionEntry = FirstPartitionEntry;
3161 int SavedCylinders = DiskParameters->Cylinders, PartitionNumber;
3162 unsigned char PartitionEntryEndHead = 0, PartitionEntryEndSector = 0;
3163 for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++) {
3164 PartitionEntryEndHead = PartitionEntry->end_head;
3165 PartitionEntryEndSector = PartitionEntry->end_sector & 0x3F;
3166 if (PartitionEntryEndHead == 64 - 1) {
3167 DiskParameters->Heads = 64;
3168 DiskParameters->Sectors = 32;
3169 break;
3170 } else if (PartitionEntryEndHead == 128 - 1) {
3171 DiskParameters->Heads = 128;
3172 DiskParameters->Sectors = 32;
3173 break;
3174 } else if (PartitionEntryEndHead == 255 - 1) {
3175 DiskParameters->Heads = 255;
3176 DiskParameters->Sectors = 63;
3177 break;
3178 }
3179 PartitionEntry++;
3180 }
3181 if (PartitionNumber == 4) {
3182 PartitionEntryEndHead = FirstPartitionEntry->end_head;
3183 PartitionEntryEndSector = FirstPartitionEntry->end_sector & 0x3F;
3184 }
3185 DiskParameters->Cylinders = (unsigned long) capacity / (DiskParameters->Heads * DiskParameters->Sectors);
3186 if (PartitionNumber < 4 && PartitionEntryEndSector == DiskParameters->Sectors) {
3187 if (DiskParameters->Cylinders != SavedCylinders)
3188 BusLogic_Warning("Adopting Geometry %d/%d from Partition Table\n", HostAdapter, DiskParameters->Heads, DiskParameters->Sectors);
3189 } else if (PartitionEntryEndHead > 0 || PartitionEntryEndSector > 0) {
3190 BusLogic_Warning("Warning: Partition Table appears to " "have Geometry %d/%d which is\n", HostAdapter, PartitionEntryEndHead + 1, PartitionEntryEndSector);
3191 BusLogic_Warning("not compatible with current BusLogic " "Host Adapter Geometry %d/%d\n", HostAdapter, DiskParameters->Heads, DiskParameters->Sectors);
3192 }
3193 }
3194 kfree(buf);
3195 return 0;
3196}
3197
3198
3199
3200
3201
3202
3203static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *shost, char *ProcBuffer, char **StartPointer, off_t Offset, int BytesAvailable, int WriteFlag)
3204{
3205 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) shost->hostdata;
3206 struct BusLogic_TargetStatistics *TargetStatistics;
3207 int TargetID, Length;
3208 char *Buffer;
3209
3210 TargetStatistics = HostAdapter->TargetStatistics;
3211 if (WriteFlag) {
3212 HostAdapter->ExternalHostAdapterResets = 0;
3213 HostAdapter->HostAdapterInternalErrors = 0;
3214 memset(TargetStatistics, 0, BusLogic_MaxTargetDevices * sizeof(struct BusLogic_TargetStatistics));
3215 return 0;
3216 }
3217 Buffer = HostAdapter->MessageBuffer;
3218 Length = HostAdapter->MessageBufferLength;
3219 Length += sprintf(&Buffer[Length], "\n\
3220Current Driver Queue Depth: %d\n\
3221Currently Allocated CCBs: %d\n", HostAdapter->DriverQueueDepth, HostAdapter->AllocatedCCBs);
3222 Length += sprintf(&Buffer[Length], "\n\n\
3223 DATA TRANSFER STATISTICS\n\
3224\n\
3225Target Tagged Queuing Queue Depth Active Attempted Completed\n\
3226====== ============== =========== ====== ========= =========\n");
3227 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3228 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3229 if (!TargetFlags->TargetExists)
3230 continue;
3231 Length += sprintf(&Buffer[Length], " %2d %s", TargetID, (TargetFlags->TaggedQueuingSupported ? (TargetFlags->TaggedQueuingActive ? " Active" : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)
3232 ? " Permitted" : " Disabled"))
3233 : "Not Supported"));
3234 Length += sprintf(&Buffer[Length],
3235 " %3d %3u %9u %9u\n", HostAdapter->QueueDepth[TargetID], HostAdapter->ActiveCommands[TargetID], TargetStatistics[TargetID].CommandsAttempted, TargetStatistics[TargetID].CommandsCompleted);
3236 }
3237 Length += sprintf(&Buffer[Length], "\n\
3238Target Read Commands Write Commands Total Bytes Read Total Bytes Written\n\
3239====== ============= ============== =================== ===================\n");
3240 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3241 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3242 if (!TargetFlags->TargetExists)
3243 continue;
3244 Length += sprintf(&Buffer[Length], " %2d %9u %9u", TargetID, TargetStatistics[TargetID].ReadCommands, TargetStatistics[TargetID].WriteCommands);
3245 if (TargetStatistics[TargetID].TotalBytesRead.Billions > 0)
3246 Length += sprintf(&Buffer[Length], " %9u%09u", TargetStatistics[TargetID].TotalBytesRead.Billions, TargetStatistics[TargetID].TotalBytesRead.Units);
3247 else
3248 Length += sprintf(&Buffer[Length], " %9u", TargetStatistics[TargetID].TotalBytesRead.Units);
3249 if (TargetStatistics[TargetID].TotalBytesWritten.Billions > 0)
3250 Length += sprintf(&Buffer[Length], " %9u%09u\n", TargetStatistics[TargetID].TotalBytesWritten.Billions, TargetStatistics[TargetID].TotalBytesWritten.Units);
3251 else
3252 Length += sprintf(&Buffer[Length], " %9u\n", TargetStatistics[TargetID].TotalBytesWritten.Units);
3253 }
3254 Length += sprintf(&Buffer[Length], "\n\
3255Target Command 0-1KB 1-2KB 2-4KB 4-8KB 8-16KB\n\
3256====== ======= ========= ========= ========= ========= =========\n");
3257 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3258 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3259 if (!TargetFlags->TargetExists)
3260 continue;
3261 Length +=
3262 sprintf(&Buffer[Length],
3263 " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
3264 TargetStatistics[TargetID].ReadCommandSizeBuckets[0],
3265 TargetStatistics[TargetID].ReadCommandSizeBuckets[1], TargetStatistics[TargetID].ReadCommandSizeBuckets[2], TargetStatistics[TargetID].ReadCommandSizeBuckets[3], TargetStatistics[TargetID].ReadCommandSizeBuckets[4]);
3266 Length +=
3267 sprintf(&Buffer[Length],
3268 " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
3269 TargetStatistics[TargetID].WriteCommandSizeBuckets[0],
3270 TargetStatistics[TargetID].WriteCommandSizeBuckets[1], TargetStatistics[TargetID].WriteCommandSizeBuckets[2], TargetStatistics[TargetID].WriteCommandSizeBuckets[3], TargetStatistics[TargetID].WriteCommandSizeBuckets[4]);
3271 }
3272 Length += sprintf(&Buffer[Length], "\n\
3273Target Command 16-32KB 32-64KB 64-128KB 128-256KB 256KB+\n\
3274====== ======= ========= ========= ========= ========= =========\n");
3275 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3276 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3277 if (!TargetFlags->TargetExists)
3278 continue;
3279 Length +=
3280 sprintf(&Buffer[Length],
3281 " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
3282 TargetStatistics[TargetID].ReadCommandSizeBuckets[5],
3283 TargetStatistics[TargetID].ReadCommandSizeBuckets[6], TargetStatistics[TargetID].ReadCommandSizeBuckets[7], TargetStatistics[TargetID].ReadCommandSizeBuckets[8], TargetStatistics[TargetID].ReadCommandSizeBuckets[9]);
3284 Length +=
3285 sprintf(&Buffer[Length],
3286 " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
3287 TargetStatistics[TargetID].WriteCommandSizeBuckets[5],
3288 TargetStatistics[TargetID].WriteCommandSizeBuckets[6], TargetStatistics[TargetID].WriteCommandSizeBuckets[7], TargetStatistics[TargetID].WriteCommandSizeBuckets[8], TargetStatistics[TargetID].WriteCommandSizeBuckets[9]);
3289 }
3290 Length += sprintf(&Buffer[Length], "\n\n\
3291 ERROR RECOVERY STATISTICS\n\
3292\n\
3293 Command Aborts Bus Device Resets Host Adapter Resets\n\
3294Target Requested Completed Requested Completed Requested Completed\n\
3295 ID \\\\\\\\ Attempted //// \\\\\\\\ Attempted //// \\\\\\\\ Attempted ////\n\
3296====== ===== ===== ===== ===== ===== ===== ===== ===== =====\n");
3297 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3298 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3299 if (!TargetFlags->TargetExists)
3300 continue;
3301 Length += sprintf(&Buffer[Length], "\
3302 %2d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n", TargetID, TargetStatistics[TargetID].CommandAbortsRequested, TargetStatistics[TargetID].CommandAbortsAttempted, TargetStatistics[TargetID].CommandAbortsCompleted, TargetStatistics[TargetID].BusDeviceResetsRequested, TargetStatistics[TargetID].BusDeviceResetsAttempted, TargetStatistics[TargetID].BusDeviceResetsCompleted, TargetStatistics[TargetID].HostAdapterResetsRequested, TargetStatistics[TargetID].HostAdapterResetsAttempted, TargetStatistics[TargetID].HostAdapterResetsCompleted);
3303 }
3304 Length += sprintf(&Buffer[Length], "\nExternal Host Adapter Resets: %d\n", HostAdapter->ExternalHostAdapterResets);
3305 Length += sprintf(&Buffer[Length], "Host Adapter Internal Errors: %d\n", HostAdapter->HostAdapterInternalErrors);
3306 if (Length >= BusLogic_MessageBufferSize)
3307 BusLogic_Error("Message Buffer length %d exceeds size %d\n", HostAdapter, Length, BusLogic_MessageBufferSize);
3308 if ((Length -= Offset) <= 0)
3309 return 0;
3310 if (Length >= BytesAvailable)
3311 Length = BytesAvailable;
3312 memcpy(ProcBuffer, HostAdapter->MessageBuffer + Offset, Length);
3313 *StartPointer = ProcBuffer;
3314 return Length;
3315}
3316
3317
3318
3319
3320
3321
3322static void BusLogic_Message(enum BusLogic_MessageLevel MessageLevel, char *Format, struct BusLogic_HostAdapter *HostAdapter, ...)
3323{
3324 static char Buffer[BusLogic_LineBufferSize];
3325 static bool BeginningOfLine = true;
3326 va_list Arguments;
3327 int Length = 0;
3328 va_start(Arguments, HostAdapter);
3329 Length = vsprintf(Buffer, Format, Arguments);
3330 va_end(Arguments);
3331 if (MessageLevel == BusLogic_AnnounceLevel) {
3332 static int AnnouncementLines = 0;
3333 strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength], Buffer);
3334 HostAdapter->MessageBufferLength += Length;
3335 if (++AnnouncementLines <= 2)
3336 printk("%sscsi: %s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
3337 } else if (MessageLevel == BusLogic_InfoLevel) {
3338 strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength], Buffer);
3339 HostAdapter->MessageBufferLength += Length;
3340 if (BeginningOfLine) {
3341 if (Buffer[0] != '\n' || Length > 1)
3342 printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel], HostAdapter->HostNumber, Buffer);
3343 } else
3344 printk("%s", Buffer);
3345 } else {
3346 if (BeginningOfLine) {
3347 if (HostAdapter != NULL && HostAdapter->HostAdapterInitialized)
3348 printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel], HostAdapter->HostNumber, Buffer);
3349 else
3350 printk("%s%s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
3351 } else
3352 printk("%s", Buffer);
3353 }
3354 BeginningOfLine = (Buffer[Length - 1] == '\n');
3355}
3356
3357
3358
3359
3360
3361
3362
3363static bool __init BusLogic_ParseKeyword(char **StringPointer, char *Keyword)
3364{
3365 char *Pointer = *StringPointer;
3366 while (*Keyword != '\0') {
3367 char StringChar = *Pointer++;
3368 char KeywordChar = *Keyword++;
3369 if (StringChar >= 'A' && StringChar <= 'Z')
3370 StringChar += 'a' - 'Z';
3371 if (KeywordChar >= 'A' && KeywordChar <= 'Z')
3372 KeywordChar += 'a' - 'Z';
3373 if (StringChar != KeywordChar)
3374 return false;
3375 }
3376 *StringPointer = Pointer;
3377 return true;
3378}
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398static int __init BusLogic_ParseDriverOptions(char *OptionsString)
3399{
3400 while (true) {
3401 struct BusLogic_DriverOptions *DriverOptions = &BusLogic_DriverOptions[BusLogic_DriverOptionsCount++];
3402 int TargetID;
3403 memset(DriverOptions, 0, sizeof(struct BusLogic_DriverOptions));
3404 while (*OptionsString != '\0' && *OptionsString != ';') {
3405
3406 if (BusLogic_ParseKeyword(&OptionsString, "IO:")) {
3407 unsigned long IO_Address = simple_strtoul(OptionsString, &OptionsString, 0);
3408 BusLogic_ProbeOptions.LimitedProbeISA = true;
3409 switch (IO_Address) {
3410 case 0x330:
3411 BusLogic_ProbeOptions.Probe330 = true;
3412 break;
3413 case 0x334:
3414 BusLogic_ProbeOptions.Probe334 = true;
3415 break;
3416 case 0x230:
3417 BusLogic_ProbeOptions.Probe230 = true;
3418 break;
3419 case 0x234:
3420 BusLogic_ProbeOptions.Probe234 = true;
3421 break;
3422 case 0x130:
3423 BusLogic_ProbeOptions.Probe130 = true;
3424 break;
3425 case 0x134:
3426 BusLogic_ProbeOptions.Probe134 = true;
3427 break;
3428 default:
3429 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid I/O Address 0x%X)\n", NULL, IO_Address);
3430 return 0;
3431 }
3432 } else if (BusLogic_ParseKeyword(&OptionsString, "NoProbeISA"))
3433 BusLogic_ProbeOptions.NoProbeISA = true;
3434 else if (BusLogic_ParseKeyword(&OptionsString, "NoProbePCI"))
3435 BusLogic_ProbeOptions.NoProbePCI = true;
3436 else if (BusLogic_ParseKeyword(&OptionsString, "NoProbe"))
3437 BusLogic_ProbeOptions.NoProbe = true;
3438 else if (BusLogic_ParseKeyword(&OptionsString, "NoSortPCI"))
3439 BusLogic_ProbeOptions.NoSortPCI = true;
3440 else if (BusLogic_ParseKeyword(&OptionsString, "MultiMasterFirst"))
3441 BusLogic_ProbeOptions.MultiMasterFirst = true;
3442 else if (BusLogic_ParseKeyword(&OptionsString, "FlashPointFirst"))
3443 BusLogic_ProbeOptions.FlashPointFirst = true;
3444
3445 else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:[") || BusLogic_ParseKeyword(&OptionsString, "QD:[")) {
3446 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) {
3447 unsigned short QueueDepth = simple_strtoul(OptionsString, &OptionsString, 0);
3448 if (QueueDepth > BusLogic_MaxTaggedQueueDepth) {
3449 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, QueueDepth);
3450 return 0;
3451 }
3452 DriverOptions->QueueDepth[TargetID] = QueueDepth;
3453 if (*OptionsString == ',')
3454 OptionsString++;
3455 else if (*OptionsString == ']')
3456 break;
3457 else {
3458 BusLogic_Error("BusLogic: Invalid Driver Options " "(',' or ']' expected at '%s')\n", NULL, OptionsString);
3459 return 0;
3460 }
3461 }
3462 if (*OptionsString != ']') {
3463 BusLogic_Error("BusLogic: Invalid Driver Options " "(']' expected at '%s')\n", NULL, OptionsString);
3464 return 0;
3465 } else
3466 OptionsString++;
3467 } else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:") || BusLogic_ParseKeyword(&OptionsString, "QD:")) {
3468 unsigned short QueueDepth = simple_strtoul(OptionsString, &OptionsString, 0);
3469 if (QueueDepth == 0 || QueueDepth > BusLogic_MaxTaggedQueueDepth) {
3470 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, QueueDepth);
3471 return 0;
3472 }
3473 DriverOptions->CommonQueueDepth = QueueDepth;
3474 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
3475 DriverOptions->QueueDepth[TargetID] = QueueDepth;
3476 } else if (BusLogic_ParseKeyword(&OptionsString, "TaggedQueuing:") || BusLogic_ParseKeyword(&OptionsString, "TQ:")) {
3477 if (BusLogic_ParseKeyword(&OptionsString, "Default")) {
3478 DriverOptions->TaggedQueuingPermitted = 0x0000;
3479 DriverOptions->TaggedQueuingPermittedMask = 0x0000;
3480 } else if (BusLogic_ParseKeyword(&OptionsString, "Enable")) {
3481 DriverOptions->TaggedQueuingPermitted = 0xFFFF;
3482 DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
3483 } else if (BusLogic_ParseKeyword(&OptionsString, "Disable")) {
3484 DriverOptions->TaggedQueuingPermitted = 0x0000;
3485 DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
3486 } else {
3487 unsigned short TargetBit;
3488 for (TargetID = 0, TargetBit = 1; TargetID < BusLogic_MaxTargetDevices; TargetID++, TargetBit <<= 1)
3489 switch (*OptionsString++) {
3490 case 'Y':
3491 DriverOptions->TaggedQueuingPermitted |= TargetBit;
3492 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
3493 break;
3494 case 'N':
3495 DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
3496 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
3497 break;
3498 case 'X':
3499 break;
3500 default:
3501 OptionsString--;
3502 TargetID = BusLogic_MaxTargetDevices;
3503 break;
3504 }
3505 }
3506 }
3507
3508 else if (BusLogic_ParseKeyword(&OptionsString, "BusSettleTime:") || BusLogic_ParseKeyword(&OptionsString, "BST:")) {
3509 unsigned short BusSettleTime = simple_strtoul(OptionsString, &OptionsString, 0);
3510 if (BusSettleTime > 5 * 60) {
3511 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Bus Settle Time %d)\n", NULL, BusSettleTime);
3512 return 0;
3513 }
3514 DriverOptions->BusSettleTime = BusSettleTime;
3515 } else if (BusLogic_ParseKeyword(&OptionsString, "InhibitTargetInquiry"))
3516 DriverOptions->LocalOptions.InhibitTargetInquiry = true;
3517
3518 else if (BusLogic_ParseKeyword(&OptionsString, "TraceProbe"))
3519 BusLogic_GlobalOptions.TraceProbe = true;
3520 else if (BusLogic_ParseKeyword(&OptionsString, "TraceHardwareReset"))
3521 BusLogic_GlobalOptions.TraceHardwareReset = true;
3522 else if (BusLogic_ParseKeyword(&OptionsString, "TraceConfiguration"))
3523 BusLogic_GlobalOptions.TraceConfiguration = true;
3524 else if (BusLogic_ParseKeyword(&OptionsString, "TraceErrors"))
3525 BusLogic_GlobalOptions.TraceErrors = true;
3526 else if (BusLogic_ParseKeyword(&OptionsString, "Debug")) {
3527 BusLogic_GlobalOptions.TraceProbe = true;
3528 BusLogic_GlobalOptions.TraceHardwareReset = true;
3529 BusLogic_GlobalOptions.TraceConfiguration = true;
3530 BusLogic_GlobalOptions.TraceErrors = true;
3531 }
3532 if (*OptionsString == ',')
3533 OptionsString++;
3534 else if (*OptionsString != ';' && *OptionsString != '\0') {
3535 BusLogic_Error("BusLogic: Unexpected Driver Option '%s' " "ignored\n", NULL, OptionsString);
3536 *OptionsString = '\0';
3537 }
3538 }
3539 if (!(BusLogic_DriverOptionsCount == 0 || BusLogic_ProbeInfoCount == 0 || BusLogic_DriverOptionsCount == BusLogic_ProbeInfoCount)) {
3540 BusLogic_Error("BusLogic: Invalid Driver Options " "(all or no I/O Addresses must be specified)\n", NULL);
3541 return 0;
3542 }
3543
3544
3545
3546
3547 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
3548 if (DriverOptions->QueueDepth[TargetID] == 1) {
3549 unsigned short TargetBit = 1 << TargetID;
3550 DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
3551 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
3552 }
3553 if (*OptionsString == ';')
3554 OptionsString++;
3555 if (*OptionsString == '\0')
3556 return 0;
3557 }
3558 return 1;
3559}
3560
3561
3562
3563
3564
3565static struct scsi_host_template Bus_Logic_template = {
3566 .module = THIS_MODULE,
3567 .proc_name = "BusLogic",
3568 .proc_info = BusLogic_ProcDirectoryInfo,
3569 .name = "BusLogic",
3570 .info = BusLogic_DriverInfo,
3571 .queuecommand = BusLogic_QueueCommand,
3572 .slave_configure = BusLogic_SlaveConfigure,
3573 .bios_param = BusLogic_BIOSDiskParameters,
3574 .eh_host_reset_handler = BusLogic_host_reset,
3575
3576
3577
3578 .unchecked_isa_dma = 1,
3579 .max_sectors = 128,
3580 .use_clustering = ENABLE_CLUSTERING,
3581};
3582
3583
3584
3585
3586
3587static int __init BusLogic_Setup(char *str)
3588{
3589 int ints[3];
3590
3591 (void) get_options(str, ARRAY_SIZE(ints), ints);
3592
3593 if (ints[0] != 0) {
3594 BusLogic_Error("BusLogic: Obsolete Command Line Entry " "Format Ignored\n", NULL);
3595 return 0;
3596 }
3597 if (str == NULL || *str == '\0')
3598 return 0;
3599 return BusLogic_ParseDriverOptions(str);
3600}
3601
3602
3603
3604
3605
3606static void __exit BusLogic_exit(void)
3607{
3608 struct BusLogic_HostAdapter *ha, *next;
3609
3610 list_for_each_entry_safe(ha, next, &BusLogic_host_list, host_list)
3611 BusLogic_ReleaseHostAdapter(ha);
3612}
3613
3614__setup("BusLogic=", BusLogic_Setup);
3615
3616#ifdef MODULE
3617static struct pci_device_id BusLogic_pci_tbl[] __devinitdata = {
3618 { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
3619 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
3620 { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
3621 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
3622 { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
3623 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
3624 { }
3625};
3626#endif
3627MODULE_DEVICE_TABLE(pci, BusLogic_pci_tbl);
3628
3629module_init(BusLogic_init);
3630module_exit(BusLogic_exit);