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#ifndef CONFIG_SCSI_OMIT_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#endif
1010
1011
1012
1013
1014
1015
1016static bool BusLogic_Failure(struct BusLogic_HostAdapter *HostAdapter, char *ErrorMessage)
1017{
1018 BusLogic_AnnounceDriver(HostAdapter);
1019 if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus) {
1020 BusLogic_Error("While configuring BusLogic PCI Host Adapter at\n", HostAdapter);
1021 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);
1022 } else
1023 BusLogic_Error("While configuring BusLogic Host Adapter at " "I/O Address 0x%X:\n", HostAdapter, HostAdapter->IO_Address);
1024 BusLogic_Error("%s FAILED - DETACHING\n", HostAdapter, ErrorMessage);
1025 if (BusLogic_CommandFailureReason != NULL)
1026 BusLogic_Error("ADDITIONAL FAILURE INFO - %s\n", HostAdapter, BusLogic_CommandFailureReason);
1027 return false;
1028}
1029
1030
1031
1032
1033
1034
1035static bool __init BusLogic_ProbeHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
1036{
1037 union BusLogic_StatusRegister StatusRegister;
1038 union BusLogic_InterruptRegister InterruptRegister;
1039 union BusLogic_GeometryRegister GeometryRegister;
1040
1041
1042
1043 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1044 struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
1045 FlashPointInfo->BaseAddress = (u32) HostAdapter->IO_Address;
1046 FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel;
1047 FlashPointInfo->Present = false;
1048 if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 && FlashPointInfo->Present)) {
1049 BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", HostAdapter, HostAdapter->Bus, HostAdapter->Device);
1050 BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, " "but FlashPoint\n", HostAdapter, HostAdapter->IO_Address, HostAdapter->PCI_Address);
1051 BusLogic_Error("BusLogic: Probe Function failed to validate it.\n", HostAdapter);
1052 return false;
1053 }
1054 if (BusLogic_GlobalOptions.TraceProbe)
1055 BusLogic_Notice("BusLogic_Probe(0x%X): FlashPoint Found\n", HostAdapter, HostAdapter->IO_Address);
1056
1057
1058
1059 return true;
1060 }
1061
1062
1063
1064
1065
1066
1067
1068 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1069 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
1070 GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1071 if (BusLogic_GlobalOptions.TraceProbe)
1072 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);
1073 if (StatusRegister.All == 0 || StatusRegister.sr.DiagnosticActive || StatusRegister.sr.CommandParameterRegisterBusy || StatusRegister.sr.Reserved || StatusRegister.sr.CommandInvalid || InterruptRegister.ir.Reserved != 0)
1074 return false;
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089 if (GeometryRegister.All == 0xFF)
1090 return false;
1091
1092
1093
1094 return true;
1095}
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106static bool BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter
1107 *HostAdapter, bool HardReset)
1108{
1109 union BusLogic_StatusRegister StatusRegister;
1110 int TimeoutCounter;
1111
1112
1113
1114 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1115 struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
1116 FlashPointInfo->HostSoftReset = !HardReset;
1117 FlashPointInfo->ReportDataUnderrun = true;
1118 HostAdapter->CardHandle = FlashPoint_HardwareResetHostAdapter(FlashPointInfo);
1119 if (HostAdapter->CardHandle == FlashPoint_BadCardHandle)
1120 return false;
1121
1122
1123
1124 return true;
1125 }
1126
1127
1128
1129
1130 if (HardReset)
1131 BusLogic_HardReset(HostAdapter);
1132 else
1133 BusLogic_SoftReset(HostAdapter);
1134
1135
1136
1137 TimeoutCounter = 5 * 10000;
1138 while (--TimeoutCounter >= 0) {
1139 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1140 if (StatusRegister.sr.DiagnosticActive)
1141 break;
1142 udelay(100);
1143 }
1144 if (BusLogic_GlobalOptions.TraceHardwareReset)
1145 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All);
1146 if (TimeoutCounter < 0)
1147 return false;
1148
1149
1150
1151
1152
1153 udelay(100);
1154
1155
1156
1157 TimeoutCounter = 10 * 10000;
1158 while (--TimeoutCounter >= 0) {
1159 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1160 if (!StatusRegister.sr.DiagnosticActive)
1161 break;
1162 udelay(100);
1163 }
1164 if (BusLogic_GlobalOptions.TraceHardwareReset)
1165 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All);
1166 if (TimeoutCounter < 0)
1167 return false;
1168
1169
1170
1171
1172 TimeoutCounter = 10000;
1173 while (--TimeoutCounter >= 0) {
1174 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1175 if (StatusRegister.sr.DiagnosticFailure || StatusRegister.sr.HostAdapterReady || StatusRegister.sr.DataInRegisterReady)
1176 break;
1177 udelay(100);
1178 }
1179 if (BusLogic_GlobalOptions.TraceHardwareReset)
1180 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All);
1181 if (TimeoutCounter < 0)
1182 return false;
1183
1184
1185
1186
1187
1188 if (StatusRegister.sr.DiagnosticFailure || !StatusRegister.sr.HostAdapterReady) {
1189 BusLogic_CommandFailureReason = NULL;
1190 BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
1191 BusLogic_Error("HOST ADAPTER STATUS REGISTER = %02X\n", HostAdapter, StatusRegister.All);
1192 if (StatusRegister.sr.DataInRegisterReady) {
1193 unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
1194 BusLogic_Error("HOST ADAPTER ERROR CODE = %d\n", HostAdapter, ErrorCode);
1195 }
1196 return false;
1197 }
1198
1199
1200
1201 return true;
1202}
1203
1204
1205
1206
1207
1208
1209
1210static bool __init BusLogic_CheckHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
1211{
1212 struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation;
1213 unsigned char RequestedReplyLength;
1214 bool Result = true;
1215
1216
1217
1218 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1219 return true;
1220
1221
1222
1223
1224
1225
1226 RequestedReplyLength = sizeof(ExtendedSetupInformation);
1227 if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &ExtendedSetupInformation, sizeof(ExtendedSetupInformation))
1228 != sizeof(ExtendedSetupInformation))
1229 Result = false;
1230
1231
1232
1233 if (BusLogic_GlobalOptions.TraceProbe)
1234 BusLogic_Notice("BusLogic_Check(0x%X): MultiMaster %s\n", HostAdapter, HostAdapter->IO_Address, (Result ? "Found" : "Not Found"));
1235 return Result;
1236}
1237
1238
1239
1240
1241
1242
1243
1244static bool __init BusLogic_ReadHostAdapterConfiguration(struct BusLogic_HostAdapter
1245 *HostAdapter)
1246{
1247 struct BusLogic_BoardID BoardID;
1248 struct BusLogic_Configuration Configuration;
1249 struct BusLogic_SetupInformation SetupInformation;
1250 struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation;
1251 unsigned char HostAdapterModelNumber[5];
1252 unsigned char FirmwareVersion3rdDigit;
1253 unsigned char FirmwareVersionLetter;
1254 struct BusLogic_PCIHostAdapterInformation PCIHostAdapterInformation;
1255 struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest;
1256 struct BusLogic_AutoSCSIData AutoSCSIData;
1257 union BusLogic_GeometryRegister GeometryRegister;
1258 unsigned char RequestedReplyLength;
1259 unsigned char *TargetPointer, Character;
1260 int TargetID, i;
1261
1262
1263
1264
1265
1266
1267 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1268 struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
1269 TargetPointer = HostAdapter->ModelName;
1270 *TargetPointer++ = 'B';
1271 *TargetPointer++ = 'T';
1272 *TargetPointer++ = '-';
1273 for (i = 0; i < sizeof(FlashPointInfo->ModelNumber); i++)
1274 *TargetPointer++ = FlashPointInfo->ModelNumber[i];
1275 *TargetPointer++ = '\0';
1276 strcpy(HostAdapter->FirmwareVersion, FlashPoint_FirmwareVersion);
1277 HostAdapter->SCSI_ID = FlashPointInfo->SCSI_ID;
1278 HostAdapter->ExtendedTranslationEnabled = FlashPointInfo->ExtendedTranslationEnabled;
1279 HostAdapter->ParityCheckingEnabled = FlashPointInfo->ParityCheckingEnabled;
1280 HostAdapter->BusResetEnabled = !FlashPointInfo->HostSoftReset;
1281 HostAdapter->LevelSensitiveInterrupt = true;
1282 HostAdapter->HostWideSCSI = FlashPointInfo->HostWideSCSI;
1283 HostAdapter->HostDifferentialSCSI = false;
1284 HostAdapter->HostSupportsSCAM = true;
1285 HostAdapter->HostUltraSCSI = true;
1286 HostAdapter->ExtendedLUNSupport = true;
1287 HostAdapter->TerminationInfoValid = true;
1288 HostAdapter->LowByteTerminated = FlashPointInfo->LowByteTerminated;
1289 HostAdapter->HighByteTerminated = FlashPointInfo->HighByteTerminated;
1290 HostAdapter->SCAM_Enabled = FlashPointInfo->SCAM_Enabled;
1291 HostAdapter->SCAM_Level2 = FlashPointInfo->SCAM_Level2;
1292 HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1293 HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1294 HostAdapter->MaxLogicalUnits = 32;
1295 HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1296 HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1297 HostAdapter->DriverQueueDepth = 255;
1298 HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth;
1299 HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted;
1300 HostAdapter->FastPermitted = FlashPointInfo->FastPermitted;
1301 HostAdapter->UltraPermitted = FlashPointInfo->UltraPermitted;
1302 HostAdapter->WidePermitted = FlashPointInfo->WidePermitted;
1303 HostAdapter->DisconnectPermitted = FlashPointInfo->DisconnectPermitted;
1304 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1305 goto Common;
1306 }
1307
1308
1309
1310 if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0, &BoardID, sizeof(BoardID)) != sizeof(BoardID))
1311 return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
1312
1313
1314
1315 if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0, &Configuration, sizeof(Configuration))
1316 != sizeof(Configuration))
1317 return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
1318
1319
1320
1321 RequestedReplyLength = sizeof(SetupInformation);
1322 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &SetupInformation, sizeof(SetupInformation))
1323 != sizeof(SetupInformation))
1324 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
1325
1326
1327
1328 RequestedReplyLength = sizeof(ExtendedSetupInformation);
1329 if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &ExtendedSetupInformation, sizeof(ExtendedSetupInformation))
1330 != sizeof(ExtendedSetupInformation))
1331 return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
1332
1333
1334
1335 FirmwareVersion3rdDigit = '\0';
1336 if (BoardID.FirmwareVersion1stDigit > '0')
1337 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit, NULL, 0, &FirmwareVersion3rdDigit, sizeof(FirmwareVersion3rdDigit))
1338 != sizeof(FirmwareVersion3rdDigit))
1339 return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
1340
1341
1342
1343 if (ExtendedSetupInformation.BusType == 'A' && BoardID.FirmwareVersion1stDigit == '2')
1344
1345 strcpy(HostAdapterModelNumber, "542B");
1346 else if (ExtendedSetupInformation.BusType == 'E' && BoardID.FirmwareVersion1stDigit == '2' && (BoardID.FirmwareVersion2ndDigit <= '1' || (BoardID.FirmwareVersion2ndDigit == '2' && FirmwareVersion3rdDigit == '0')))
1347
1348 strcpy(HostAdapterModelNumber, "742A");
1349 else if (ExtendedSetupInformation.BusType == 'E' && BoardID.FirmwareVersion1stDigit == '0')
1350
1351 strcpy(HostAdapterModelNumber, "747A");
1352 else {
1353 RequestedReplyLength = sizeof(HostAdapterModelNumber);
1354 if (BusLogic_Command(HostAdapter, BusLogic_InquireHostAdapterModelNumber, &RequestedReplyLength, sizeof(RequestedReplyLength), &HostAdapterModelNumber, sizeof(HostAdapterModelNumber))
1355 != sizeof(HostAdapterModelNumber))
1356 return BusLogic_Failure(HostAdapter, "INQUIRE HOST ADAPTER MODEL NUMBER");
1357 }
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376 TargetPointer = HostAdapter->ModelName;
1377 *TargetPointer++ = 'B';
1378 *TargetPointer++ = 'T';
1379 *TargetPointer++ = '-';
1380 for (i = 0; i < sizeof(HostAdapterModelNumber); i++) {
1381 Character = HostAdapterModelNumber[i];
1382 if (Character == ' ' || Character == '\0')
1383 break;
1384 *TargetPointer++ = Character;
1385 }
1386 *TargetPointer++ = '\0';
1387
1388
1389
1390 TargetPointer = HostAdapter->FirmwareVersion;
1391 *TargetPointer++ = BoardID.FirmwareVersion1stDigit;
1392 *TargetPointer++ = '.';
1393 *TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
1394 if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0')
1395 *TargetPointer++ = FirmwareVersion3rdDigit;
1396 *TargetPointer = '\0';
1397
1398
1399
1400 if (strcmp(HostAdapter->FirmwareVersion, "3.3") >= 0) {
1401 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter, NULL, 0, &FirmwareVersionLetter, sizeof(FirmwareVersionLetter))
1402 != sizeof(FirmwareVersionLetter))
1403 return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE VERSION LETTER");
1404 if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0')
1405 *TargetPointer++ = FirmwareVersionLetter;
1406 *TargetPointer = '\0';
1407 }
1408
1409
1410
1411 HostAdapter->SCSI_ID = Configuration.HostAdapterID;
1412
1413
1414
1415
1416
1417 HostAdapter->HostAdapterBusType = BusLogic_HostAdapterBusTypes[HostAdapter->ModelName[3] - '4'];
1418 if (HostAdapter->IRQ_Channel == 0) {
1419 if (Configuration.IRQ_Channel9)
1420 HostAdapter->IRQ_Channel = 9;
1421 else if (Configuration.IRQ_Channel10)
1422 HostAdapter->IRQ_Channel = 10;
1423 else if (Configuration.IRQ_Channel11)
1424 HostAdapter->IRQ_Channel = 11;
1425 else if (Configuration.IRQ_Channel12)
1426 HostAdapter->IRQ_Channel = 12;
1427 else if (Configuration.IRQ_Channel14)
1428 HostAdapter->IRQ_Channel = 14;
1429 else if (Configuration.IRQ_Channel15)
1430 HostAdapter->IRQ_Channel = 15;
1431 }
1432 if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus) {
1433 if (Configuration.DMA_Channel5)
1434 HostAdapter->DMA_Channel = 5;
1435 else if (Configuration.DMA_Channel6)
1436 HostAdapter->DMA_Channel = 6;
1437 else if (Configuration.DMA_Channel7)
1438 HostAdapter->DMA_Channel = 7;
1439 }
1440
1441
1442
1443
1444 GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1445 HostAdapter->ExtendedTranslationEnabled = GeometryRegister.gr.ExtendedTranslationEnabled;
1446
1447
1448
1449
1450
1451 HostAdapter->HostAdapterScatterGatherLimit = ExtendedSetupInformation.ScatterGatherLimit;
1452 HostAdapter->DriverScatterGatherLimit = HostAdapter->HostAdapterScatterGatherLimit;
1453 if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
1454 HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1455 if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupt)
1456 HostAdapter->LevelSensitiveInterrupt = true;
1457 HostAdapter->HostWideSCSI = ExtendedSetupInformation.HostWideSCSI;
1458 HostAdapter->HostDifferentialSCSI = ExtendedSetupInformation.HostDifferentialSCSI;
1459 HostAdapter->HostSupportsSCAM = ExtendedSetupInformation.HostSupportsSCAM;
1460 HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI;
1461
1462
1463
1464
1465 if (HostAdapter->FirmwareVersion[0] == '5' || (HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI))
1466 HostAdapter->ExtendedLUNSupport = true;
1467
1468
1469
1470
1471 if (HostAdapter->FirmwareVersion[0] == '5') {
1472 if (BusLogic_Command(HostAdapter, BusLogic_InquirePCIHostAdapterInformation, NULL, 0, &PCIHostAdapterInformation, sizeof(PCIHostAdapterInformation))
1473 != sizeof(PCIHostAdapterInformation))
1474 return BusLogic_Failure(HostAdapter, "INQUIRE PCI HOST ADAPTER INFORMATION");
1475
1476
1477
1478 if (PCIHostAdapterInformation.GenericInfoValid) {
1479 HostAdapter->TerminationInfoValid = true;
1480 HostAdapter->LowByteTerminated = PCIHostAdapterInformation.LowByteTerminated;
1481 HostAdapter->HighByteTerminated = PCIHostAdapterInformation.HighByteTerminated;
1482 }
1483 }
1484
1485
1486
1487
1488 if (HostAdapter->FirmwareVersion[0] >= '4') {
1489 FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_AutoSCSI_BaseOffset;
1490 FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIData);
1491 if (BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &AutoSCSIData, sizeof(AutoSCSIData))
1492 != sizeof(AutoSCSIData))
1493 return BusLogic_Failure(HostAdapter, "FETCH HOST ADAPTER LOCAL RAM");
1494
1495
1496
1497
1498 HostAdapter->ParityCheckingEnabled = AutoSCSIData.ParityCheckingEnabled;
1499 HostAdapter->BusResetEnabled = AutoSCSIData.BusResetEnabled;
1500 if (HostAdapter->FirmwareVersion[0] == '4') {
1501 HostAdapter->TerminationInfoValid = true;
1502 HostAdapter->LowByteTerminated = AutoSCSIData.LowByteTerminated;
1503 HostAdapter->HighByteTerminated = AutoSCSIData.HighByteTerminated;
1504 }
1505
1506
1507
1508
1509
1510 HostAdapter->WidePermitted = AutoSCSIData.WidePermitted;
1511 HostAdapter->FastPermitted = AutoSCSIData.FastPermitted;
1512 HostAdapter->SynchronousPermitted = AutoSCSIData.SynchronousPermitted;
1513 HostAdapter->DisconnectPermitted = AutoSCSIData.DisconnectPermitted;
1514 if (HostAdapter->HostUltraSCSI)
1515 HostAdapter->UltraPermitted = AutoSCSIData.UltraPermitted;
1516 if (HostAdapter->HostSupportsSCAM) {
1517 HostAdapter->SCAM_Enabled = AutoSCSIData.SCAM_Enabled;
1518 HostAdapter->SCAM_Level2 = AutoSCSIData.SCAM_Level2;
1519 }
1520 }
1521
1522
1523
1524
1525 if (HostAdapter->FirmwareVersion[0] < '4') {
1526 if (SetupInformation.SynchronousInitiationEnabled) {
1527 HostAdapter->SynchronousPermitted = 0xFF;
1528 if (HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus) {
1529 if (ExtendedSetupInformation.Misc.FastOnEISA)
1530 HostAdapter->FastPermitted = 0xFF;
1531 if (strcmp(HostAdapter->ModelName, "BT-757") == 0)
1532 HostAdapter->WidePermitted = 0xFF;
1533 }
1534 }
1535 HostAdapter->DisconnectPermitted = 0xFF;
1536 HostAdapter->ParityCheckingEnabled = SetupInformation.ParityCheckingEnabled;
1537 HostAdapter->BusResetEnabled = true;
1538 }
1539
1540
1541
1542
1543 HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1544 HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8);
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568 if (HostAdapter->FirmwareVersion[0] == '5')
1569 HostAdapter->HostAdapterQueueDepth = 192;
1570 else if (HostAdapter->FirmwareVersion[0] == '4')
1571 HostAdapter->HostAdapterQueueDepth = (HostAdapter->HostAdapterBusType != BusLogic_ISA_Bus ? 100 : 50);
1572 else
1573 HostAdapter->HostAdapterQueueDepth = 30;
1574 if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0) {
1575 HostAdapter->StrictRoundRobinModeSupport = true;
1576 HostAdapter->MailboxCount = BusLogic_MaxMailboxes;
1577 } else {
1578 HostAdapter->StrictRoundRobinModeSupport = false;
1579 HostAdapter->MailboxCount = 32;
1580 }
1581 HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount;
1582 HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1583 HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1584
1585
1586
1587
1588
1589
1590 HostAdapter->TaggedQueuingPermitted = 0;
1591 switch (HostAdapter->FirmwareVersion[0]) {
1592 case '5':
1593 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1594 break;
1595 case '4':
1596 if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0)
1597 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1598 break;
1599 case '3':
1600 if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0)
1601 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1602 break;
1603 }
1604
1605
1606
1607
1608
1609 HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
1610
1611
1612
1613 if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus && (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1614 HostAdapter->BounceBuffersRequired = true;
1615
1616
1617
1618
1619
1620
1621
1622
1623 if (HostAdapter->BIOS_Address > 0 && strcmp(HostAdapter->ModelName, "BT-445S") == 0 && strcmp(HostAdapter->FirmwareVersion, "3.37") < 0 && (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1624 HostAdapter->BounceBuffersRequired = true;
1625
1626
1627
1628 Common:
1629
1630
1631
1632 strcpy(HostAdapter->FullModelName, "BusLogic ");
1633 strcat(HostAdapter->FullModelName, HostAdapter->ModelName);
1634
1635
1636
1637
1638
1639
1640
1641 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) {
1642 unsigned char QueueDepth = 0;
1643 if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->QueueDepth[TargetID] > 0)
1644 QueueDepth = HostAdapter->DriverOptions->QueueDepth[TargetID];
1645 else if (HostAdapter->BounceBuffersRequired)
1646 QueueDepth = BusLogic_TaggedQueueDepthBB;
1647 HostAdapter->QueueDepth[TargetID] = QueueDepth;
1648 }
1649 if (HostAdapter->BounceBuffersRequired)
1650 HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepthBB;
1651 else
1652 HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth;
1653 if (HostAdapter->DriverOptions != NULL)
1654 HostAdapter->CommonQueueDepth = HostAdapter->DriverOptions->CommonQueueDepth;
1655 if (HostAdapter->CommonQueueDepth > 0 && HostAdapter->CommonQueueDepth < HostAdapter->UntaggedQueueDepth)
1656 HostAdapter->UntaggedQueueDepth = HostAdapter->CommonQueueDepth;
1657
1658
1659
1660
1661
1662 HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted;
1663
1664
1665
1666
1667 if (HostAdapter->DriverOptions != NULL)
1668 HostAdapter->TaggedQueuingPermitted =
1669 (HostAdapter->DriverOptions->TaggedQueuingPermitted & HostAdapter->DriverOptions->TaggedQueuingPermittedMask) | (HostAdapter->TaggedQueuingPermitted & ~HostAdapter->DriverOptions->TaggedQueuingPermittedMask);
1670
1671
1672
1673
1674
1675 if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->BusSettleTime > 0)
1676 HostAdapter->BusSettleTime = HostAdapter->DriverOptions->BusSettleTime;
1677 else
1678 HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
1679
1680
1681
1682 return true;
1683}
1684
1685
1686
1687
1688
1689
1690
1691static bool __init BusLogic_ReportHostAdapterConfiguration(struct BusLogic_HostAdapter
1692 *HostAdapter)
1693{
1694 unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1;
1695 unsigned short SynchronousPermitted, FastPermitted;
1696 unsigned short UltraPermitted, WidePermitted;
1697 unsigned short DisconnectPermitted, TaggedQueuingPermitted;
1698 bool CommonSynchronousNegotiation, CommonTaggedQueueDepth;
1699 char SynchronousString[BusLogic_MaxTargetDevices + 1];
1700 char WideString[BusLogic_MaxTargetDevices + 1];
1701 char DisconnectString[BusLogic_MaxTargetDevices + 1];
1702 char TaggedQueuingString[BusLogic_MaxTargetDevices + 1];
1703 char *SynchronousMessage = SynchronousString;
1704 char *WideMessage = WideString;
1705 char *DisconnectMessage = DisconnectString;
1706 char *TaggedQueuingMessage = TaggedQueuingString;
1707 int TargetID;
1708 BusLogic_Info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n",
1709 HostAdapter, HostAdapter->ModelName,
1710 BusLogic_HostAdapterBusNames[HostAdapter->HostAdapterBusType], (HostAdapter->HostWideSCSI ? " Wide" : ""), (HostAdapter->HostDifferentialSCSI ? " Differential" : ""), (HostAdapter->HostUltraSCSI ? " Ultra" : ""));
1711 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"));
1712 if (HostAdapter->HostAdapterBusType != BusLogic_PCI_Bus) {
1713 BusLogic_Info(" DMA Channel: ", HostAdapter);
1714 if (HostAdapter->DMA_Channel > 0)
1715 BusLogic_Info("%d, ", HostAdapter, HostAdapter->DMA_Channel);
1716 else
1717 BusLogic_Info("None, ", HostAdapter);
1718 if (HostAdapter->BIOS_Address > 0)
1719 BusLogic_Info("BIOS Address: 0x%X, ", HostAdapter, HostAdapter->BIOS_Address);
1720 else
1721 BusLogic_Info("BIOS Address: None, ", HostAdapter);
1722 } else {
1723 BusLogic_Info(" PCI Bus: %d, Device: %d, Address: ", HostAdapter, HostAdapter->Bus, HostAdapter->Device);
1724 if (HostAdapter->PCI_Address > 0)
1725 BusLogic_Info("0x%X, ", HostAdapter, HostAdapter->PCI_Address);
1726 else
1727 BusLogic_Info("Unassigned, ", HostAdapter);
1728 }
1729 BusLogic_Info("Host Adapter SCSI ID: %d\n", HostAdapter, HostAdapter->SCSI_ID);
1730 BusLogic_Info(" Parity Checking: %s, Extended Translation: %s\n", HostAdapter, (HostAdapter->ParityCheckingEnabled ? "Enabled" : "Disabled"), (HostAdapter->ExtendedTranslationEnabled ? "Enabled" : "Disabled"));
1731 AllTargetsMask &= ~(1 << HostAdapter->SCSI_ID);
1732 SynchronousPermitted = HostAdapter->SynchronousPermitted & AllTargetsMask;
1733 FastPermitted = HostAdapter->FastPermitted & AllTargetsMask;
1734 UltraPermitted = HostAdapter->UltraPermitted & AllTargetsMask;
1735 if ((BusLogic_MultiMasterHostAdapterP(HostAdapter) && (HostAdapter->FirmwareVersion[0] >= '4' || HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)) || BusLogic_FlashPointHostAdapterP(HostAdapter)) {
1736 CommonSynchronousNegotiation = false;
1737 if (SynchronousPermitted == 0) {
1738 SynchronousMessage = "Disabled";
1739 CommonSynchronousNegotiation = true;
1740 } else if (SynchronousPermitted == AllTargetsMask) {
1741 if (FastPermitted == 0) {
1742 SynchronousMessage = "Slow";
1743 CommonSynchronousNegotiation = true;
1744 } else if (FastPermitted == AllTargetsMask) {
1745 if (UltraPermitted == 0) {
1746 SynchronousMessage = "Fast";
1747 CommonSynchronousNegotiation = true;
1748 } else if (UltraPermitted == AllTargetsMask) {
1749 SynchronousMessage = "Ultra";
1750 CommonSynchronousNegotiation = true;
1751 }
1752 }
1753 }
1754 if (!CommonSynchronousNegotiation) {
1755 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1756 SynchronousString[TargetID] = ((!(SynchronousPermitted & (1 << TargetID))) ? 'N' : (!(FastPermitted & (1 << TargetID)) ? 'S' : (!(UltraPermitted & (1 << TargetID)) ? 'F' : 'U')));
1757 SynchronousString[HostAdapter->SCSI_ID] = '#';
1758 SynchronousString[HostAdapter->MaxTargetDevices] = '\0';
1759 }
1760 } else
1761 SynchronousMessage = (SynchronousPermitted == 0 ? "Disabled" : "Enabled");
1762 WidePermitted = HostAdapter->WidePermitted & AllTargetsMask;
1763 if (WidePermitted == 0)
1764 WideMessage = "Disabled";
1765 else if (WidePermitted == AllTargetsMask)
1766 WideMessage = "Enabled";
1767 else {
1768 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1769 WideString[TargetID] = ((WidePermitted & (1 << TargetID)) ? 'Y' : 'N');
1770 WideString[HostAdapter->SCSI_ID] = '#';
1771 WideString[HostAdapter->MaxTargetDevices] = '\0';
1772 }
1773 DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
1774 if (DisconnectPermitted == 0)
1775 DisconnectMessage = "Disabled";
1776 else if (DisconnectPermitted == AllTargetsMask)
1777 DisconnectMessage = "Enabled";
1778 else {
1779 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1780 DisconnectString[TargetID] = ((DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
1781 DisconnectString[HostAdapter->SCSI_ID] = '#';
1782 DisconnectString[HostAdapter->MaxTargetDevices] = '\0';
1783 }
1784 TaggedQueuingPermitted = HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
1785 if (TaggedQueuingPermitted == 0)
1786 TaggedQueuingMessage = "Disabled";
1787 else if (TaggedQueuingPermitted == AllTargetsMask)
1788 TaggedQueuingMessage = "Enabled";
1789 else {
1790 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1791 TaggedQueuingString[TargetID] = ((TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
1792 TaggedQueuingString[HostAdapter->SCSI_ID] = '#';
1793 TaggedQueuingString[HostAdapter->MaxTargetDevices] = '\0';
1794 }
1795 BusLogic_Info(" Synchronous Negotiation: %s, Wide Negotiation: %s\n", HostAdapter, SynchronousMessage, WideMessage);
1796 BusLogic_Info(" Disconnect/Reconnect: %s, Tagged Queuing: %s\n", HostAdapter, DisconnectMessage, TaggedQueuingMessage);
1797 if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
1798 BusLogic_Info(" Scatter/Gather Limit: %d of %d segments, " "Mailboxes: %d\n", HostAdapter, HostAdapter->DriverScatterGatherLimit, HostAdapter->HostAdapterScatterGatherLimit, HostAdapter->MailboxCount);
1799 BusLogic_Info(" Driver Queue Depth: %d, " "Host Adapter Queue Depth: %d\n", HostAdapter, HostAdapter->DriverQueueDepth, HostAdapter->HostAdapterQueueDepth);
1800 } else
1801 BusLogic_Info(" Driver Queue Depth: %d, " "Scatter/Gather Limit: %d segments\n", HostAdapter, HostAdapter->DriverQueueDepth, HostAdapter->DriverScatterGatherLimit);
1802 BusLogic_Info(" Tagged Queue Depth: ", HostAdapter);
1803 CommonTaggedQueueDepth = true;
1804 for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1805 if (HostAdapter->QueueDepth[TargetID] != HostAdapter->QueueDepth[0]) {
1806 CommonTaggedQueueDepth = false;
1807 break;
1808 }
1809 if (CommonTaggedQueueDepth) {
1810 if (HostAdapter->QueueDepth[0] > 0)
1811 BusLogic_Info("%d", HostAdapter, HostAdapter->QueueDepth[0]);
1812 else
1813 BusLogic_Info("Automatic", HostAdapter);
1814 } else
1815 BusLogic_Info("Individual", HostAdapter);
1816 BusLogic_Info(", Untagged Queue Depth: %d\n", HostAdapter, HostAdapter->UntaggedQueueDepth);
1817 if (HostAdapter->TerminationInfoValid) {
1818 if (HostAdapter->HostWideSCSI)
1819 BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter, (HostAdapter->LowByteTerminated ? (HostAdapter->HighByteTerminated ? "Both Enabled" : "Low Enabled")
1820 : (HostAdapter->HighByteTerminated ? "High Enabled" : "Both Disabled")));
1821 else
1822 BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter, (HostAdapter->LowByteTerminated ? "Enabled" : "Disabled"));
1823 if (HostAdapter->HostSupportsSCAM)
1824 BusLogic_Info(", SCAM: %s", HostAdapter, (HostAdapter->SCAM_Enabled ? (HostAdapter->SCAM_Level2 ? "Enabled, Level 2" : "Enabled, Level 1")
1825 : "Disabled"));
1826 BusLogic_Info("\n", HostAdapter);
1827 }
1828
1829
1830
1831 return true;
1832}
1833
1834
1835
1836
1837
1838
1839
1840static bool __init BusLogic_AcquireResources(struct BusLogic_HostAdapter *HostAdapter)
1841{
1842 if (HostAdapter->IRQ_Channel == 0) {
1843 BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n", HostAdapter);
1844 return false;
1845 }
1846
1847
1848
1849 if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler, IRQF_SHARED, HostAdapter->FullModelName, HostAdapter) < 0) {
1850 BusLogic_Error("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n", HostAdapter, HostAdapter->IRQ_Channel);
1851 return false;
1852 }
1853 HostAdapter->IRQ_ChannelAcquired = true;
1854
1855
1856
1857 if (HostAdapter->DMA_Channel > 0) {
1858 if (request_dma(HostAdapter->DMA_Channel, HostAdapter->FullModelName) < 0) {
1859 BusLogic_Error("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n", HostAdapter, HostAdapter->DMA_Channel);
1860 return false;
1861 }
1862 set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
1863 enable_dma(HostAdapter->DMA_Channel);
1864 HostAdapter->DMA_ChannelAcquired = true;
1865 }
1866
1867
1868
1869 return true;
1870}
1871
1872
1873
1874
1875
1876
1877
1878static void BusLogic_ReleaseResources(struct BusLogic_HostAdapter *HostAdapter)
1879{
1880
1881
1882
1883 if (HostAdapter->IRQ_ChannelAcquired)
1884 free_irq(HostAdapter->IRQ_Channel, HostAdapter);
1885
1886
1887
1888 if (HostAdapter->DMA_ChannelAcquired)
1889 free_dma(HostAdapter->DMA_Channel);
1890
1891
1892
1893 if (HostAdapter->MailboxSpace)
1894 pci_free_consistent(HostAdapter->PCI_Device, HostAdapter->MailboxSize, HostAdapter->MailboxSpace, HostAdapter->MailboxSpaceHandle);
1895 pci_dev_put(HostAdapter->PCI_Device);
1896 HostAdapter->MailboxSpace = NULL;
1897 HostAdapter->MailboxSpaceHandle = 0;
1898 HostAdapter->MailboxSize = 0;
1899}
1900
1901
1902
1903
1904
1905
1906
1907
1908static bool BusLogic_InitializeHostAdapter(struct BusLogic_HostAdapter
1909 *HostAdapter)
1910{
1911 struct BusLogic_ExtendedMailboxRequest ExtendedMailboxRequest;
1912 enum BusLogic_RoundRobinModeRequest RoundRobinModeRequest;
1913 enum BusLogic_SetCCBFormatRequest SetCCBFormatRequest;
1914 int TargetID;
1915
1916
1917
1918
1919 HostAdapter->FirstCompletedCCB = NULL;
1920 HostAdapter->LastCompletedCCB = NULL;
1921
1922
1923
1924
1925
1926 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
1927 HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
1928 HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
1929 HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
1930 HostAdapter->ActiveCommands[TargetID] = 0;
1931 HostAdapter->CommandsSinceReset[TargetID] = 0;
1932 }
1933
1934
1935
1936 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1937 goto Done;
1938
1939
1940
1941 HostAdapter->MailboxSize = HostAdapter->MailboxCount * (sizeof(struct BusLogic_OutgoingMailbox) + sizeof(struct BusLogic_IncomingMailbox));
1942 HostAdapter->MailboxSpace = pci_alloc_consistent(HostAdapter->PCI_Device, HostAdapter->MailboxSize, &HostAdapter->MailboxSpaceHandle);
1943 if (HostAdapter->MailboxSpace == NULL)
1944 return BusLogic_Failure(HostAdapter, "MAILBOX ALLOCATION");
1945 HostAdapter->FirstOutgoingMailbox = (struct BusLogic_OutgoingMailbox *) HostAdapter->MailboxSpace;
1946 HostAdapter->LastOutgoingMailbox = HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1;
1947 HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
1948 HostAdapter->FirstIncomingMailbox = (struct BusLogic_IncomingMailbox *) (HostAdapter->LastOutgoingMailbox + 1);
1949 HostAdapter->LastIncomingMailbox = HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1;
1950 HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
1951
1952
1953
1954
1955 memset(HostAdapter->FirstOutgoingMailbox, 0, HostAdapter->MailboxCount * sizeof(struct BusLogic_OutgoingMailbox));
1956 memset(HostAdapter->FirstIncomingMailbox, 0, HostAdapter->MailboxCount * sizeof(struct BusLogic_IncomingMailbox));
1957
1958
1959
1960 ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount;
1961 ExtendedMailboxRequest.BaseMailboxAddress = (u32) HostAdapter->MailboxSpaceHandle;
1962 if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox, &ExtendedMailboxRequest, sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
1963 return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION");
1964
1965
1966
1967
1968
1969
1970
1971 if (HostAdapter->StrictRoundRobinModeSupport) {
1972 RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
1973 if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode, &RoundRobinModeRequest, sizeof(RoundRobinModeRequest), NULL, 0) < 0)
1974 return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
1975 }
1976
1977
1978
1979
1980 if (HostAdapter->ExtendedLUNSupport) {
1981 SetCCBFormatRequest = BusLogic_ExtendedLUNFormatCCB;
1982 if (BusLogic_Command(HostAdapter, BusLogic_SetCCBFormat, &SetCCBFormatRequest, sizeof(SetCCBFormatRequest), NULL, 0) < 0)
1983 return BusLogic_Failure(HostAdapter, "SET CCB FORMAT");
1984 }
1985
1986
1987
1988 Done:
1989 if (!HostAdapter->HostAdapterInitialized) {
1990 BusLogic_Info("*** %s Initialized Successfully ***\n", HostAdapter, HostAdapter->FullModelName);
1991 BusLogic_Info("\n", HostAdapter);
1992 } else
1993 BusLogic_Warning("*** %s Initialized Successfully ***\n", HostAdapter, HostAdapter->FullModelName);
1994 HostAdapter->HostAdapterInitialized = true;
1995
1996
1997
1998 return true;
1999}
2000
2001
2002
2003
2004
2005
2006
2007static bool __init BusLogic_TargetDeviceInquiry(struct BusLogic_HostAdapter
2008 *HostAdapter)
2009{
2010 u16 InstalledDevices;
2011 u8 InstalledDevicesID0to7[8];
2012 struct BusLogic_SetupInformation SetupInformation;
2013 u8 SynchronousPeriod[BusLogic_MaxTargetDevices];
2014 unsigned char RequestedReplyLength;
2015 int TargetID;
2016
2017
2018
2019
2020
2021 BusLogic_Delay(HostAdapter->BusSettleTime);
2022
2023
2024
2025 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
2026 return true;
2027
2028
2029
2030 if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
2031 return true;
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041 if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0) {
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051 if (BusLogic_Command(HostAdapter, BusLogic_InquireTargetDevices, NULL, 0, &InstalledDevices, sizeof(InstalledDevices))
2052 != sizeof(InstalledDevices))
2053 return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES");
2054 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2055 HostAdapter->TargetFlags[TargetID].TargetExists = (InstalledDevices & (1 << TargetID) ? true : false);
2056 } else {
2057
2058
2059
2060
2061
2062
2063
2064 if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7, NULL, 0, &InstalledDevicesID0to7, sizeof(InstalledDevicesID0to7))
2065 != sizeof(InstalledDevicesID0to7))
2066 return BusLogic_Failure(HostAdapter, "INQUIRE INSTALLED DEVICES ID 0 TO 7");
2067 for (TargetID = 0; TargetID < 8; TargetID++)
2068 HostAdapter->TargetFlags[TargetID].TargetExists = (InstalledDevicesID0to7[TargetID] != 0 ? true : false);
2069 }
2070
2071
2072
2073 RequestedReplyLength = sizeof(SetupInformation);
2074 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &SetupInformation, sizeof(SetupInformation))
2075 != sizeof(SetupInformation))
2076 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
2077 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2078 HostAdapter->SynchronousOffset[TargetID] = (TargetID < 8 ? SetupInformation.SynchronousValuesID0to7[TargetID].Offset : SetupInformation.SynchronousValuesID8to15[TargetID - 8].Offset);
2079 if (strcmp(HostAdapter->FirmwareVersion, "5.06L") >= 0)
2080 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2081 HostAdapter->TargetFlags[TargetID].WideTransfersActive = (TargetID < 8 ? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID)
2082 ? true : false)
2083 : (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID - 8))
2084 ? true : false));
2085
2086
2087
2088 if (HostAdapter->FirmwareVersion[0] >= '3') {
2089
2090
2091
2092
2093
2094
2095 RequestedReplyLength = sizeof(SynchronousPeriod);
2096 if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod, &RequestedReplyLength, sizeof(RequestedReplyLength), &SynchronousPeriod, sizeof(SynchronousPeriod))
2097 != sizeof(SynchronousPeriod))
2098 return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
2099 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2100 HostAdapter->SynchronousPeriod[TargetID] = SynchronousPeriod[TargetID];
2101 } else
2102 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2103 if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
2104 HostAdapter->SynchronousPeriod[TargetID] = 20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
2105 .TransferPeriod;
2106
2107
2108
2109 return true;
2110}
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121static void __init BusLogic_InitializeHostStructure(struct BusLogic_HostAdapter
2122 *HostAdapter, struct Scsi_Host *Host)
2123{
2124 Host->max_id = HostAdapter->MaxTargetDevices;
2125 Host->max_lun = HostAdapter->MaxLogicalUnits;
2126 Host->max_channel = 0;
2127 Host->unique_id = HostAdapter->IO_Address;
2128 Host->this_id = HostAdapter->SCSI_ID;
2129 Host->can_queue = HostAdapter->DriverQueueDepth;
2130 Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
2131 Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
2132 Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth;
2133}
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143static int BusLogic_SlaveConfigure(struct scsi_device *Device)
2144{
2145 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Device->host->hostdata;
2146 int TargetID = Device->id;
2147 int QueueDepth = HostAdapter->QueueDepth[TargetID];
2148
2149 if (HostAdapter->TargetFlags[TargetID].TaggedQueuingSupported && (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) {
2150 if (QueueDepth == 0)
2151 QueueDepth = BusLogic_MaxAutomaticTaggedQueueDepth;
2152 HostAdapter->QueueDepth[TargetID] = QueueDepth;
2153 scsi_adjust_queue_depth(Device, MSG_SIMPLE_TAG, QueueDepth);
2154 } else {
2155 HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
2156 QueueDepth = HostAdapter->UntaggedQueueDepth;
2157 HostAdapter->QueueDepth[TargetID] = QueueDepth;
2158 scsi_adjust_queue_depth(Device, 0, QueueDepth);
2159 }
2160 QueueDepth = 0;
2161 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2162 if (HostAdapter->TargetFlags[TargetID].TargetExists) {
2163 QueueDepth += HostAdapter->QueueDepth[TargetID];
2164 }
2165 if (QueueDepth > HostAdapter->AllocatedCCBs)
2166 BusLogic_CreateAdditionalCCBs(HostAdapter, QueueDepth - HostAdapter->AllocatedCCBs, false);
2167 return 0;
2168}
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178static int __init BusLogic_init(void)
2179{
2180 int BusLogicHostAdapterCount = 0, DriverOptionsIndex = 0, ProbeIndex;
2181 struct BusLogic_HostAdapter *PrototypeHostAdapter;
2182 int ret = 0;
2183
2184#ifdef MODULE
2185 if (BusLogic)
2186 BusLogic_Setup(BusLogic);
2187#endif
2188
2189 if (BusLogic_ProbeOptions.NoProbe)
2190 return -ENODEV;
2191 BusLogic_ProbeInfoList =
2192 kzalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo), GFP_KERNEL);
2193 if (BusLogic_ProbeInfoList == NULL) {
2194 BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL);
2195 return -ENOMEM;
2196 }
2197
2198 PrototypeHostAdapter =
2199 kzalloc(sizeof(struct BusLogic_HostAdapter), GFP_KERNEL);
2200 if (PrototypeHostAdapter == NULL) {
2201 kfree(BusLogic_ProbeInfoList);
2202 BusLogic_Error("BusLogic: Unable to allocate Prototype " "Host Adapter\n", NULL);
2203 return -ENOMEM;
2204 }
2205
2206#ifdef MODULE
2207 if (BusLogic != NULL)
2208 BusLogic_Setup(BusLogic);
2209#endif
2210 BusLogic_InitializeProbeInfoList(PrototypeHostAdapter);
2211 for (ProbeIndex = 0; ProbeIndex < BusLogic_ProbeInfoCount; ProbeIndex++) {
2212 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[ProbeIndex];
2213 struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter;
2214 struct Scsi_Host *Host;
2215 if (ProbeInfo->IO_Address == 0)
2216 continue;
2217 memset(HostAdapter, 0, sizeof(struct BusLogic_HostAdapter));
2218 HostAdapter->HostAdapterType = ProbeInfo->HostAdapterType;
2219 HostAdapter->HostAdapterBusType = ProbeInfo->HostAdapterBusType;
2220 HostAdapter->IO_Address = ProbeInfo->IO_Address;
2221 HostAdapter->PCI_Address = ProbeInfo->PCI_Address;
2222 HostAdapter->Bus = ProbeInfo->Bus;
2223 HostAdapter->Device = ProbeInfo->Device;
2224 HostAdapter->PCI_Device = ProbeInfo->PCI_Device;
2225 HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel;
2226 HostAdapter->AddressCount = BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType];
2227
2228
2229
2230
2231 if (!request_region(HostAdapter->IO_Address, HostAdapter->AddressCount,
2232 "BusLogic"))
2233 continue;
2234
2235
2236
2237 if (!BusLogic_ProbeHostAdapter(HostAdapter)) {
2238 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2239 continue;
2240 }
2241
2242
2243
2244
2245 if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) {
2246 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2247 continue;
2248 }
2249
2250
2251
2252 if (!BusLogic_CheckHostAdapter(HostAdapter)) {
2253 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2254 continue;
2255 }
2256
2257
2258
2259 if (DriverOptionsIndex < BusLogic_DriverOptionsCount)
2260 HostAdapter->DriverOptions = &BusLogic_DriverOptions[DriverOptionsIndex++];
2261
2262
2263
2264
2265 BusLogic_AnnounceDriver(HostAdapter);
2266
2267
2268
2269
2270 Host = scsi_host_alloc(&Bus_Logic_template, sizeof(struct BusLogic_HostAdapter));
2271 if (Host == NULL) {
2272 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2273 continue;
2274 }
2275 HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata;
2276 memcpy(HostAdapter, PrototypeHostAdapter, sizeof(struct BusLogic_HostAdapter));
2277 HostAdapter->SCSI_Host = Host;
2278 HostAdapter->HostNumber = Host->host_no;
2279
2280
2281
2282
2283 list_add_tail(&HostAdapter->host_list, &BusLogic_host_list);
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297 if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
2298 BusLogic_ReportHostAdapterConfiguration(HostAdapter) &&
2299 BusLogic_AcquireResources(HostAdapter) &&
2300 BusLogic_CreateInitialCCBs(HostAdapter) &&
2301 BusLogic_InitializeHostAdapter(HostAdapter) &&
2302 BusLogic_TargetDeviceInquiry(HostAdapter)) {
2303
2304
2305
2306
2307
2308
2309 release_region(HostAdapter->IO_Address,
2310 HostAdapter->AddressCount);
2311 if (!request_region(HostAdapter->IO_Address,
2312 HostAdapter->AddressCount,
2313 HostAdapter->FullModelName)) {
2314 printk(KERN_WARNING
2315 "BusLogic: Release and re-register of "
2316 "port 0x%04lx failed \n",
2317 (unsigned long)HostAdapter->IO_Address);
2318 BusLogic_DestroyCCBs(HostAdapter);
2319 BusLogic_ReleaseResources(HostAdapter);
2320 list_del(&HostAdapter->host_list);
2321 scsi_host_put(Host);
2322 ret = -ENOMEM;
2323 } else {
2324 BusLogic_InitializeHostStructure(HostAdapter,
2325 Host);
2326 if (scsi_add_host(Host, HostAdapter->PCI_Device
2327 ? &HostAdapter->PCI_Device->dev
2328 : NULL)) {
2329 printk(KERN_WARNING
2330 "BusLogic: scsi_add_host()"
2331 "failed!\n");
2332 BusLogic_DestroyCCBs(HostAdapter);
2333 BusLogic_ReleaseResources(HostAdapter);
2334 list_del(&HostAdapter->host_list);
2335 scsi_host_put(Host);
2336 ret = -ENODEV;
2337 } else {
2338 scsi_scan_host(Host);
2339 BusLogicHostAdapterCount++;
2340 }
2341 }
2342 } else {
2343
2344
2345
2346
2347
2348
2349
2350
2351 BusLogic_DestroyCCBs(HostAdapter);
2352 BusLogic_ReleaseResources(HostAdapter);
2353 list_del(&HostAdapter->host_list);
2354 scsi_host_put(Host);
2355 ret = -ENODEV;
2356 }
2357 }
2358 kfree(PrototypeHostAdapter);
2359 kfree(BusLogic_ProbeInfoList);
2360 BusLogic_ProbeInfoList = NULL;
2361 return ret;
2362}
2363
2364
2365
2366
2367
2368
2369
2370
2371static int __exit BusLogic_ReleaseHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
2372{
2373 struct Scsi_Host *Host = HostAdapter->SCSI_Host;
2374
2375 scsi_remove_host(Host);
2376
2377
2378
2379
2380
2381 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
2382 FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle);
2383
2384
2385
2386
2387 BusLogic_DestroyCCBs(HostAdapter);
2388 BusLogic_ReleaseResources(HostAdapter);
2389
2390
2391
2392 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2393
2394
2395
2396 list_del(&HostAdapter->host_list);
2397
2398 scsi_host_put(Host);
2399 return 0;
2400}
2401
2402
2403
2404
2405
2406
2407static void BusLogic_QueueCompletedCCB(struct BusLogic_CCB *CCB)
2408{
2409 struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter;
2410 CCB->Status = BusLogic_CCB_Completed;
2411 CCB->Next = NULL;
2412 if (HostAdapter->FirstCompletedCCB == NULL) {
2413 HostAdapter->FirstCompletedCCB = CCB;
2414 HostAdapter->LastCompletedCCB = CCB;
2415 } else {
2416 HostAdapter->LastCompletedCCB->Next = CCB;
2417 HostAdapter->LastCompletedCCB = CCB;
2418 }
2419 HostAdapter->ActiveCommands[CCB->TargetID]--;
2420}
2421
2422
2423
2424
2425
2426
2427
2428static int BusLogic_ComputeResultCode(struct BusLogic_HostAdapter *HostAdapter, enum BusLogic_HostAdapterStatus HostAdapterStatus, enum BusLogic_TargetDeviceStatus TargetDeviceStatus)
2429{
2430 int HostStatus;
2431 switch (HostAdapterStatus) {
2432 case BusLogic_CommandCompletedNormally:
2433 case BusLogic_LinkedCommandCompleted:
2434 case BusLogic_LinkedCommandCompletedWithFlag:
2435 HostStatus = DID_OK;
2436 break;
2437 case BusLogic_SCSISelectionTimeout:
2438 HostStatus = DID_TIME_OUT;
2439 break;
2440 case BusLogic_InvalidOutgoingMailboxActionCode:
2441 case BusLogic_InvalidCommandOperationCode:
2442 case BusLogic_InvalidCommandParameter:
2443 BusLogic_Warning("BusLogic Driver Protocol Error 0x%02X\n", HostAdapter, HostAdapterStatus);
2444 case BusLogic_DataUnderRun:
2445 case BusLogic_DataOverRun:
2446 case BusLogic_UnexpectedBusFree:
2447 case BusLogic_LinkedCCBhasInvalidLUN:
2448 case BusLogic_AutoRequestSenseFailed:
2449 case BusLogic_TaggedQueuingMessageRejected:
2450 case BusLogic_UnsupportedMessageReceived:
2451 case BusLogic_HostAdapterHardwareFailed:
2452 case BusLogic_TargetDeviceReconnectedImproperly:
2453 case BusLogic_AbortQueueGenerated:
2454 case BusLogic_HostAdapterSoftwareError:
2455 case BusLogic_HostAdapterHardwareTimeoutError:
2456 case BusLogic_SCSIParityErrorDetected:
2457 HostStatus = DID_ERROR;
2458 break;
2459 case BusLogic_InvalidBusPhaseRequested:
2460 case BusLogic_TargetFailedResponseToATN:
2461 case BusLogic_HostAdapterAssertedRST:
2462 case BusLogic_OtherDeviceAssertedRST:
2463 case BusLogic_HostAdapterAssertedBusDeviceReset:
2464 HostStatus = DID_RESET;
2465 break;
2466 default:
2467 BusLogic_Warning("Unknown Host Adapter Status 0x%02X\n", HostAdapter, HostAdapterStatus);
2468 HostStatus = DID_ERROR;
2469 break;
2470 }
2471 return (HostStatus << 16) | TargetDeviceStatus;
2472}
2473
2474
2475
2476
2477
2478
2479
2480static void BusLogic_ScanIncomingMailboxes(struct BusLogic_HostAdapter *HostAdapter)
2481{
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494 struct BusLogic_IncomingMailbox *NextIncomingMailbox = HostAdapter->NextIncomingMailbox;
2495 enum BusLogic_CompletionCode CompletionCode;
2496 while ((CompletionCode = NextIncomingMailbox->CompletionCode) != BusLogic_IncomingMailboxFree) {
2497
2498
2499
2500
2501
2502
2503
2504 struct BusLogic_CCB *CCB = (struct BusLogic_CCB *) Bus_to_Virtual(NextIncomingMailbox->CCB);
2505 if (CompletionCode != BusLogic_AbortedCommandNotFound) {
2506 if (CCB->Status == BusLogic_CCB_Active || CCB->Status == BusLogic_CCB_Reset) {
2507
2508
2509
2510
2511 CCB->CompletionCode = CompletionCode;
2512 BusLogic_QueueCompletedCCB(CCB);
2513 } else {
2514
2515
2516
2517
2518
2519 BusLogic_Warning("Illegal CCB #%ld status %d in " "Incoming Mailbox\n", HostAdapter, CCB->SerialNumber, CCB->Status);
2520 }
2521 }
2522 NextIncomingMailbox->CompletionCode = BusLogic_IncomingMailboxFree;
2523 if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
2524 NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
2525 }
2526 HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
2527}
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537static void BusLogic_ProcessCompletedCCBs(struct BusLogic_HostAdapter *HostAdapter)
2538{
2539 if (HostAdapter->ProcessCompletedCCBsActive)
2540 return;
2541 HostAdapter->ProcessCompletedCCBsActive = true;
2542 while (HostAdapter->FirstCompletedCCB != NULL) {
2543 struct BusLogic_CCB *CCB = HostAdapter->FirstCompletedCCB;
2544 struct scsi_cmnd *Command = CCB->Command;
2545 HostAdapter->FirstCompletedCCB = CCB->Next;
2546 if (HostAdapter->FirstCompletedCCB == NULL)
2547 HostAdapter->LastCompletedCCB = NULL;
2548
2549
2550
2551 if (CCB->Opcode == BusLogic_BusDeviceReset) {
2552 int TargetID = CCB->TargetID;
2553 BusLogic_Warning("Bus Device Reset CCB #%ld to Target " "%d Completed\n", HostAdapter, CCB->SerialNumber, TargetID);
2554 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].BusDeviceResetsCompleted);
2555 HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
2556 HostAdapter->CommandsSinceReset[TargetID] = 0;
2557 HostAdapter->LastResetCompleted[TargetID] = jiffies;
2558
2559
2560
2561 BusLogic_DeallocateCCB(CCB);
2562#if 0
2563
2564
2565
2566
2567
2568
2569
2570 while (Command != NULL) {
2571 struct scsi_cmnd *NextCommand = Command->reset_chain;
2572 Command->reset_chain = NULL;
2573 Command->result = DID_RESET << 16;
2574 Command->scsi_done(Command);
2575 Command = NextCommand;
2576 }
2577#endif
2578
2579
2580
2581
2582 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2583 if (CCB->Status == BusLogic_CCB_Reset && CCB->TargetID == TargetID) {
2584 Command = CCB->Command;
2585 BusLogic_DeallocateCCB(CCB);
2586 HostAdapter->ActiveCommands[TargetID]--;
2587 Command->result = DID_RESET << 16;
2588 Command->scsi_done(Command);
2589 }
2590 HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
2591 } else {
2592
2593
2594
2595
2596 switch (CCB->CompletionCode) {
2597 case BusLogic_IncomingMailboxFree:
2598 case BusLogic_AbortedCommandNotFound:
2599 case BusLogic_InvalidCCB:
2600 BusLogic_Warning("CCB #%ld to Target %d Impossible State\n", HostAdapter, CCB->SerialNumber, CCB->TargetID);
2601 break;
2602 case BusLogic_CommandCompletedWithoutError:
2603 HostAdapter->TargetStatistics[CCB->TargetID]
2604 .CommandsCompleted++;
2605 HostAdapter->TargetFlags[CCB->TargetID]
2606 .CommandSuccessfulFlag = true;
2607 Command->result = DID_OK << 16;
2608 break;
2609 case BusLogic_CommandAbortedAtHostRequest:
2610 BusLogic_Warning("CCB #%ld to Target %d Aborted\n", HostAdapter, CCB->SerialNumber, CCB->TargetID);
2611 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[CCB->TargetID]
2612 .CommandAbortsCompleted);
2613 Command->result = DID_ABORT << 16;
2614 break;
2615 case BusLogic_CommandCompletedWithError:
2616 Command->result = BusLogic_ComputeResultCode(HostAdapter, CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
2617 if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout) {
2618 HostAdapter->TargetStatistics[CCB->TargetID]
2619 .CommandsCompleted++;
2620 if (BusLogic_GlobalOptions.TraceErrors) {
2621 int i;
2622 BusLogic_Notice("CCB #%ld Target %d: Result %X Host "
2623 "Adapter Status %02X " "Target Status %02X\n", HostAdapter, CCB->SerialNumber, CCB->TargetID, Command->result, CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
2624 BusLogic_Notice("CDB ", HostAdapter);
2625 for (i = 0; i < CCB->CDB_Length; i++)
2626 BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]);
2627 BusLogic_Notice("\n", HostAdapter);
2628 BusLogic_Notice("Sense ", HostAdapter);
2629 for (i = 0; i < CCB->SenseDataLength; i++)
2630 BusLogic_Notice(" %02X", HostAdapter, Command->sense_buffer[i]);
2631 BusLogic_Notice("\n", HostAdapter);
2632 }
2633 }
2634 break;
2635 }
2636
2637
2638
2639
2640
2641 if (CCB->CDB[0] == INQUIRY && CCB->CDB[1] == 0 && CCB->HostAdapterStatus == BusLogic_CommandCompletedNormally) {
2642 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[CCB->TargetID];
2643 struct SCSI_Inquiry *InquiryResult =
2644 (struct SCSI_Inquiry *) scsi_sglist(Command);
2645 TargetFlags->TargetExists = true;
2646 TargetFlags->TaggedQueuingSupported = InquiryResult->CmdQue;
2647 TargetFlags->WideTransfersSupported = InquiryResult->WBus16;
2648 }
2649
2650
2651
2652 BusLogic_DeallocateCCB(CCB);
2653
2654
2655
2656 Command->scsi_done(Command);
2657 }
2658 }
2659 HostAdapter->ProcessCompletedCCBsActive = false;
2660}
2661
2662
2663
2664
2665
2666
2667
2668static irqreturn_t BusLogic_InterruptHandler(int IRQ_Channel, void *DeviceIdentifier)
2669{
2670 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) DeviceIdentifier;
2671 unsigned long ProcessorFlags;
2672
2673
2674
2675 spin_lock_irqsave(HostAdapter->SCSI_Host->host_lock, ProcessorFlags);
2676
2677
2678
2679 if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
2680 union BusLogic_InterruptRegister InterruptRegister;
2681
2682
2683
2684 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
2685 if (InterruptRegister.ir.InterruptValid) {
2686
2687
2688
2689
2690 BusLogic_InterruptReset(HostAdapter);
2691
2692
2693
2694
2695
2696
2697 if (InterruptRegister.ir.ExternalBusReset)
2698 HostAdapter->HostAdapterExternalReset = true;
2699 else if (InterruptRegister.ir.IncomingMailboxLoaded)
2700 BusLogic_ScanIncomingMailboxes(HostAdapter);
2701 else if (InterruptRegister.ir.CommandComplete)
2702 HostAdapter->HostAdapterCommandCompleted = true;
2703 }
2704 } else {
2705
2706
2707
2708 if (FlashPoint_InterruptPending(HostAdapter->CardHandle))
2709 switch (FlashPoint_HandleInterrupt(HostAdapter->CardHandle)) {
2710 case FlashPoint_NormalInterrupt:
2711 break;
2712 case FlashPoint_ExternalBusReset:
2713 HostAdapter->HostAdapterExternalReset = true;
2714 break;
2715 case FlashPoint_InternalError:
2716 BusLogic_Warning("Internal FlashPoint Error detected" " - Resetting Host Adapter\n", HostAdapter);
2717 HostAdapter->HostAdapterInternalError = true;
2718 break;
2719 }
2720 }
2721
2722
2723
2724 if (HostAdapter->FirstCompletedCCB != NULL)
2725 BusLogic_ProcessCompletedCCBs(HostAdapter);
2726
2727
2728
2729 if (HostAdapter->HostAdapterExternalReset) {
2730 BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n", HostAdapter, HostAdapter->FullModelName);
2731 BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets);
2732 BusLogic_ResetHostAdapter(HostAdapter, false);
2733 HostAdapter->HostAdapterExternalReset = false;
2734 } else if (HostAdapter->HostAdapterInternalError) {
2735 BusLogic_Warning("Resetting %s due to Host Adapter Internal Error\n", HostAdapter, HostAdapter->FullModelName);
2736 BusLogic_IncrementErrorCounter(&HostAdapter->HostAdapterInternalErrors);
2737 BusLogic_ResetHostAdapter(HostAdapter, true);
2738 HostAdapter->HostAdapterInternalError = false;
2739 }
2740
2741
2742
2743 spin_unlock_irqrestore(HostAdapter->SCSI_Host->host_lock, ProcessorFlags);
2744 return IRQ_HANDLED;
2745}
2746
2747
2748
2749
2750
2751
2752
2753
2754static bool BusLogic_WriteOutgoingMailbox(struct BusLogic_HostAdapter
2755 *HostAdapter, enum BusLogic_ActionCode ActionCode, struct BusLogic_CCB *CCB)
2756{
2757 struct BusLogic_OutgoingMailbox *NextOutgoingMailbox;
2758 NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
2759 if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree) {
2760 CCB->Status = BusLogic_CCB_Active;
2761
2762
2763
2764
2765
2766 NextOutgoingMailbox->CCB = CCB->DMA_Handle;
2767 NextOutgoingMailbox->ActionCode = ActionCode;
2768 BusLogic_StartMailboxCommand(HostAdapter);
2769 if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
2770 NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
2771 HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
2772 if (ActionCode == BusLogic_MailboxStartCommand) {
2773 HostAdapter->ActiveCommands[CCB->TargetID]++;
2774 if (CCB->Opcode != BusLogic_BusDeviceReset)
2775 HostAdapter->TargetStatistics[CCB->TargetID].CommandsAttempted++;
2776 }
2777 return true;
2778 }
2779 return false;
2780}
2781
2782
2783
2784static int BusLogic_host_reset(struct scsi_cmnd * SCpnt)
2785{
2786 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) SCpnt->device->host->hostdata;
2787
2788 unsigned int id = SCpnt->device->id;
2789 struct BusLogic_TargetStatistics *stats = &HostAdapter->TargetStatistics[id];
2790 int rc;
2791
2792 spin_lock_irq(SCpnt->device->host->host_lock);
2793
2794 BusLogic_IncrementErrorCounter(&stats->HostAdapterResetsRequested);
2795
2796 rc = BusLogic_ResetHostAdapter(HostAdapter, false);
2797 spin_unlock_irq(SCpnt->device->host->host_lock);
2798 return rc;
2799}
2800
2801
2802
2803
2804
2805
2806static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRoutine) (struct scsi_cmnd *))
2807{
2808 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata;
2809 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[Command->device->id];
2810 struct BusLogic_TargetStatistics *TargetStatistics = HostAdapter->TargetStatistics;
2811 unsigned char *CDB = Command->cmnd;
2812 int CDB_Length = Command->cmd_len;
2813 int TargetID = Command->device->id;
2814 int LogicalUnit = Command->device->lun;
2815 int BufferLength = scsi_bufflen(Command);
2816 int Count;
2817 struct BusLogic_CCB *CCB;
2818
2819
2820
2821
2822
2823 if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0) {
2824 Command->result = DID_OK << 16;
2825 CompletionRoutine(Command);
2826 return 0;
2827 }
2828
2829
2830
2831
2832
2833
2834 CCB = BusLogic_AllocateCCB(HostAdapter);
2835 if (CCB == NULL) {
2836 spin_unlock_irq(HostAdapter->SCSI_Host->host_lock);
2837 BusLogic_Delay(1);
2838 spin_lock_irq(HostAdapter->SCSI_Host->host_lock);
2839 CCB = BusLogic_AllocateCCB(HostAdapter);
2840 if (CCB == NULL) {
2841 Command->result = DID_ERROR << 16;
2842 CompletionRoutine(Command);
2843 return 0;
2844 }
2845 }
2846
2847
2848
2849
2850 Count = scsi_dma_map(Command);
2851 BUG_ON(Count < 0);
2852 if (Count) {
2853 struct scatterlist *sg;
2854 int i;
2855
2856 CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
2857 CCB->DataLength = Count * sizeof(struct BusLogic_ScatterGatherSegment);
2858 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
2859 CCB->DataPointer = (unsigned int) CCB->DMA_Handle + ((unsigned long) &CCB->ScatterGatherList - (unsigned long) CCB);
2860 else
2861 CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList);
2862
2863 scsi_for_each_sg(Command, sg, Count, i) {
2864 CCB->ScatterGatherList[i].SegmentByteCount =
2865 sg_dma_len(sg);
2866 CCB->ScatterGatherList[i].SegmentDataPointer =
2867 sg_dma_address(sg);
2868 }
2869 } else if (!Count) {
2870 CCB->Opcode = BusLogic_InitiatorCCB;
2871 CCB->DataLength = BufferLength;
2872 CCB->DataPointer = 0;
2873 }
2874
2875 switch (CDB[0]) {
2876 case READ_6:
2877 case READ_10:
2878 CCB->DataDirection = BusLogic_DataInLengthChecked;
2879 TargetStatistics[TargetID].ReadCommands++;
2880 BusLogic_IncrementByteCounter(&TargetStatistics[TargetID].TotalBytesRead, BufferLength);
2881 BusLogic_IncrementSizeBucket(TargetStatistics[TargetID].ReadCommandSizeBuckets, BufferLength);
2882 break;
2883 case WRITE_6:
2884 case WRITE_10:
2885 CCB->DataDirection = BusLogic_DataOutLengthChecked;
2886 TargetStatistics[TargetID].WriteCommands++;
2887 BusLogic_IncrementByteCounter(&TargetStatistics[TargetID].TotalBytesWritten, BufferLength);
2888 BusLogic_IncrementSizeBucket(TargetStatistics[TargetID].WriteCommandSizeBuckets, BufferLength);
2889 break;
2890 default:
2891 CCB->DataDirection = BusLogic_UncheckedDataTransfer;
2892 break;
2893 }
2894 CCB->CDB_Length = CDB_Length;
2895 CCB->HostAdapterStatus = 0;
2896 CCB->TargetDeviceStatus = 0;
2897 CCB->TargetID = TargetID;
2898 CCB->LogicalUnit = LogicalUnit;
2899 CCB->TagEnable = false;
2900 CCB->LegacyTagEnable = false;
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915 if (HostAdapter->CommandsSinceReset[TargetID]++ >=
2916 BusLogic_MaxTaggedQueueDepth && !TargetFlags->TaggedQueuingActive && HostAdapter->ActiveCommands[TargetID] == 0 && TargetFlags->TaggedQueuingSupported && (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) {
2917 TargetFlags->TaggedQueuingActive = true;
2918 BusLogic_Notice("Tagged Queuing now active for Target %d\n", HostAdapter, TargetID);
2919 }
2920 if (TargetFlags->TaggedQueuingActive) {
2921 enum BusLogic_QueueTag QueueTag = BusLogic_SimpleQueueTag;
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935 if (HostAdapter->ActiveCommands[TargetID] == 0)
2936 HostAdapter->LastSequencePoint[TargetID] = jiffies;
2937 else if (time_after(jiffies, HostAdapter->LastSequencePoint[TargetID] + 4 * HZ)) {
2938 HostAdapter->LastSequencePoint[TargetID] = jiffies;
2939 QueueTag = BusLogic_OrderedQueueTag;
2940 }
2941 if (HostAdapter->ExtendedLUNSupport) {
2942 CCB->TagEnable = true;
2943 CCB->QueueTag = QueueTag;
2944 } else {
2945 CCB->LegacyTagEnable = true;
2946 CCB->LegacyQueueTag = QueueTag;
2947 }
2948 }
2949 memcpy(CCB->CDB, CDB, CDB_Length);
2950 CCB->SenseDataLength = sizeof(Command->sense_buffer);
2951 CCB->SenseDataPointer = pci_map_single(HostAdapter->PCI_Device, Command->sense_buffer, CCB->SenseDataLength, PCI_DMA_FROMDEVICE);
2952 CCB->Command = Command;
2953 Command->scsi_done = CompletionRoutine;
2954 if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
2955
2956
2957
2958
2959
2960
2961
2962
2963 if (!BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxStartCommand, CCB)) {
2964 spin_unlock_irq(HostAdapter->SCSI_Host->host_lock);
2965 BusLogic_Warning("Unable to write Outgoing Mailbox - " "Pausing for 1 second\n", HostAdapter);
2966 BusLogic_Delay(1);
2967 spin_lock_irq(HostAdapter->SCSI_Host->host_lock);
2968 if (!BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxStartCommand, CCB)) {
2969 BusLogic_Warning("Still unable to write Outgoing Mailbox - " "Host Adapter Dead?\n", HostAdapter);
2970 BusLogic_DeallocateCCB(CCB);
2971 Command->result = DID_ERROR << 16;
2972 Command->scsi_done(Command);
2973 }
2974 }
2975 } else {
2976
2977
2978
2979 CCB->Status = BusLogic_CCB_Active;
2980 HostAdapter->ActiveCommands[TargetID]++;
2981 TargetStatistics[TargetID].CommandsAttempted++;
2982 FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
2983
2984
2985
2986
2987 if (CCB->Status == BusLogic_CCB_Completed)
2988 BusLogic_ProcessCompletedCCBs(HostAdapter);
2989 }
2990 return 0;
2991}
2992
2993
2994#if 0
2995
2996
2997
2998
2999static int BusLogic_AbortCommand(struct scsi_cmnd *Command)
3000{
3001 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata;
3002
3003 int TargetID = Command->device->id;
3004 struct BusLogic_CCB *CCB;
3005 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsRequested);
3006
3007
3008
3009
3010 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3011 if (CCB->Command == Command)
3012 break;
3013 if (CCB == NULL) {
3014 BusLogic_Warning("Unable to Abort Command to Target %d - " "No CCB Found\n", HostAdapter, TargetID);
3015 return SUCCESS;
3016 } else if (CCB->Status == BusLogic_CCB_Completed) {
3017 BusLogic_Warning("Unable to Abort Command to Target %d - " "CCB Completed\n", HostAdapter, TargetID);
3018 return SUCCESS;
3019 } else if (CCB->Status == BusLogic_CCB_Reset) {
3020 BusLogic_Warning("Unable to Abort Command to Target %d - " "CCB Reset\n", HostAdapter, TargetID);
3021 return SUCCESS;
3022 }
3023 if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034 if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive && HostAdapter->FirmwareVersion[0] < '5') {
3035 BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - " "Abort Tag Not Supported\n", HostAdapter, CCB->SerialNumber, TargetID);
3036 return FAILURE;
3037 } else if (BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxAbortCommand, CCB)) {
3038 BusLogic_Warning("Aborting CCB #%ld to Target %d\n", HostAdapter, CCB->SerialNumber, TargetID);
3039 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
3040 return SUCCESS;
3041 } else {
3042 BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - " "No Outgoing Mailboxes\n", HostAdapter, CCB->SerialNumber, TargetID);
3043 return FAILURE;
3044 }
3045 } else {
3046
3047
3048
3049 BusLogic_Warning("Aborting CCB #%ld to Target %d\n", HostAdapter, CCB->SerialNumber, TargetID);
3050 BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
3051 FlashPoint_AbortCCB(HostAdapter->CardHandle, CCB);
3052
3053
3054
3055
3056
3057 if (CCB->Status == BusLogic_CCB_Completed) {
3058 BusLogic_ProcessCompletedCCBs(HostAdapter);
3059 }
3060 return SUCCESS;
3061 }
3062 return SUCCESS;
3063}
3064
3065#endif
3066
3067
3068
3069
3070
3071static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter, bool HardReset)
3072{
3073 struct BusLogic_CCB *CCB;
3074 int TargetID;
3075
3076
3077
3078
3079
3080 if (!(BusLogic_HardwareResetHostAdapter(HostAdapter, HardReset) && BusLogic_InitializeHostAdapter(HostAdapter))) {
3081 BusLogic_Error("Resetting %s Failed\n", HostAdapter, HostAdapter->FullModelName);
3082 return FAILURE;
3083 }
3084
3085
3086
3087
3088
3089 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3090 if (CCB->Status == BusLogic_CCB_Active)
3091 BusLogic_DeallocateCCB(CCB);
3092
3093
3094
3095
3096
3097
3098
3099 if (HardReset) {
3100 spin_unlock_irq(HostAdapter->SCSI_Host->host_lock);
3101 BusLogic_Delay(HostAdapter->BusSettleTime);
3102 spin_lock_irq(HostAdapter->SCSI_Host->host_lock);
3103 }
3104
3105 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3106 HostAdapter->LastResetAttempted[TargetID] = jiffies;
3107 HostAdapter->LastResetCompleted[TargetID] = jiffies;
3108 }
3109 return SUCCESS;
3110}
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129static int BusLogic_BIOSDiskParameters(struct scsi_device *sdev, struct block_device *Device, sector_t capacity, int *Parameters)
3130{
3131 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) sdev->host->hostdata;
3132 struct BIOS_DiskParameters *DiskParameters = (struct BIOS_DiskParameters *) Parameters;
3133 unsigned char *buf;
3134 if (HostAdapter->ExtendedTranslationEnabled && capacity >= 2 * 1024 * 1024 ) {
3135 if (capacity >= 4 * 1024 * 1024 ) {
3136 DiskParameters->Heads = 255;
3137 DiskParameters->Sectors = 63;
3138 } else {
3139 DiskParameters->Heads = 128;
3140 DiskParameters->Sectors = 32;
3141 }
3142 } else {
3143 DiskParameters->Heads = 64;
3144 DiskParameters->Sectors = 32;
3145 }
3146 DiskParameters->Cylinders = (unsigned long) capacity / (DiskParameters->Heads * DiskParameters->Sectors);
3147 buf = scsi_bios_ptable(Device);
3148 if (buf == NULL)
3149 return 0;
3150
3151
3152
3153
3154
3155 if (*(unsigned short *) (buf + 64) == 0xAA55) {
3156 struct partition *FirstPartitionEntry = (struct partition *) buf;
3157 struct partition *PartitionEntry = FirstPartitionEntry;
3158 int SavedCylinders = DiskParameters->Cylinders, PartitionNumber;
3159 unsigned char PartitionEntryEndHead = 0, PartitionEntryEndSector = 0;
3160 for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++) {
3161 PartitionEntryEndHead = PartitionEntry->end_head;
3162 PartitionEntryEndSector = PartitionEntry->end_sector & 0x3F;
3163 if (PartitionEntryEndHead == 64 - 1) {
3164 DiskParameters->Heads = 64;
3165 DiskParameters->Sectors = 32;
3166 break;
3167 } else if (PartitionEntryEndHead == 128 - 1) {
3168 DiskParameters->Heads = 128;
3169 DiskParameters->Sectors = 32;
3170 break;
3171 } else if (PartitionEntryEndHead == 255 - 1) {
3172 DiskParameters->Heads = 255;
3173 DiskParameters->Sectors = 63;
3174 break;
3175 }
3176 PartitionEntry++;
3177 }
3178 if (PartitionNumber == 4) {
3179 PartitionEntryEndHead = FirstPartitionEntry->end_head;
3180 PartitionEntryEndSector = FirstPartitionEntry->end_sector & 0x3F;
3181 }
3182 DiskParameters->Cylinders = (unsigned long) capacity / (DiskParameters->Heads * DiskParameters->Sectors);
3183 if (PartitionNumber < 4 && PartitionEntryEndSector == DiskParameters->Sectors) {
3184 if (DiskParameters->Cylinders != SavedCylinders)
3185 BusLogic_Warning("Adopting Geometry %d/%d from Partition Table\n", HostAdapter, DiskParameters->Heads, DiskParameters->Sectors);
3186 } else if (PartitionEntryEndHead > 0 || PartitionEntryEndSector > 0) {
3187 BusLogic_Warning("Warning: Partition Table appears to " "have Geometry %d/%d which is\n", HostAdapter, PartitionEntryEndHead + 1, PartitionEntryEndSector);
3188 BusLogic_Warning("not compatible with current BusLogic " "Host Adapter Geometry %d/%d\n", HostAdapter, DiskParameters->Heads, DiskParameters->Sectors);
3189 }
3190 }
3191 kfree(buf);
3192 return 0;
3193}
3194
3195
3196
3197
3198
3199
3200static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *shost, char *ProcBuffer, char **StartPointer, off_t Offset, int BytesAvailable, int WriteFlag)
3201{
3202 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) shost->hostdata;
3203 struct BusLogic_TargetStatistics *TargetStatistics;
3204 int TargetID, Length;
3205 char *Buffer;
3206
3207 TargetStatistics = HostAdapter->TargetStatistics;
3208 if (WriteFlag) {
3209 HostAdapter->ExternalHostAdapterResets = 0;
3210 HostAdapter->HostAdapterInternalErrors = 0;
3211 memset(TargetStatistics, 0, BusLogic_MaxTargetDevices * sizeof(struct BusLogic_TargetStatistics));
3212 return 0;
3213 }
3214 Buffer = HostAdapter->MessageBuffer;
3215 Length = HostAdapter->MessageBufferLength;
3216 Length += sprintf(&Buffer[Length], "\n\
3217Current Driver Queue Depth: %d\n\
3218Currently Allocated CCBs: %d\n", HostAdapter->DriverQueueDepth, HostAdapter->AllocatedCCBs);
3219 Length += sprintf(&Buffer[Length], "\n\n\
3220 DATA TRANSFER STATISTICS\n\
3221\n\
3222Target Tagged Queuing Queue Depth Active Attempted Completed\n\
3223====== ============== =========== ====== ========= =========\n");
3224 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3225 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3226 if (!TargetFlags->TargetExists)
3227 continue;
3228 Length += sprintf(&Buffer[Length], " %2d %s", TargetID, (TargetFlags->TaggedQueuingSupported ? (TargetFlags->TaggedQueuingActive ? " Active" : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)
3229 ? " Permitted" : " Disabled"))
3230 : "Not Supported"));
3231 Length += sprintf(&Buffer[Length],
3232 " %3d %3u %9u %9u\n", HostAdapter->QueueDepth[TargetID], HostAdapter->ActiveCommands[TargetID], TargetStatistics[TargetID].CommandsAttempted, TargetStatistics[TargetID].CommandsCompleted);
3233 }
3234 Length += sprintf(&Buffer[Length], "\n\
3235Target Read Commands Write Commands Total Bytes Read Total Bytes Written\n\
3236====== ============= ============== =================== ===================\n");
3237 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3238 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3239 if (!TargetFlags->TargetExists)
3240 continue;
3241 Length += sprintf(&Buffer[Length], " %2d %9u %9u", TargetID, TargetStatistics[TargetID].ReadCommands, TargetStatistics[TargetID].WriteCommands);
3242 if (TargetStatistics[TargetID].TotalBytesRead.Billions > 0)
3243 Length += sprintf(&Buffer[Length], " %9u%09u", TargetStatistics[TargetID].TotalBytesRead.Billions, TargetStatistics[TargetID].TotalBytesRead.Units);
3244 else
3245 Length += sprintf(&Buffer[Length], " %9u", TargetStatistics[TargetID].TotalBytesRead.Units);
3246 if (TargetStatistics[TargetID].TotalBytesWritten.Billions > 0)
3247 Length += sprintf(&Buffer[Length], " %9u%09u\n", TargetStatistics[TargetID].TotalBytesWritten.Billions, TargetStatistics[TargetID].TotalBytesWritten.Units);
3248 else
3249 Length += sprintf(&Buffer[Length], " %9u\n", TargetStatistics[TargetID].TotalBytesWritten.Units);
3250 }
3251 Length += sprintf(&Buffer[Length], "\n\
3252Target Command 0-1KB 1-2KB 2-4KB 4-8KB 8-16KB\n\
3253====== ======= ========= ========= ========= ========= =========\n");
3254 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3255 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3256 if (!TargetFlags->TargetExists)
3257 continue;
3258 Length +=
3259 sprintf(&Buffer[Length],
3260 " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
3261 TargetStatistics[TargetID].ReadCommandSizeBuckets[0],
3262 TargetStatistics[TargetID].ReadCommandSizeBuckets[1], TargetStatistics[TargetID].ReadCommandSizeBuckets[2], TargetStatistics[TargetID].ReadCommandSizeBuckets[3], TargetStatistics[TargetID].ReadCommandSizeBuckets[4]);
3263 Length +=
3264 sprintf(&Buffer[Length],
3265 " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
3266 TargetStatistics[TargetID].WriteCommandSizeBuckets[0],
3267 TargetStatistics[TargetID].WriteCommandSizeBuckets[1], TargetStatistics[TargetID].WriteCommandSizeBuckets[2], TargetStatistics[TargetID].WriteCommandSizeBuckets[3], TargetStatistics[TargetID].WriteCommandSizeBuckets[4]);
3268 }
3269 Length += sprintf(&Buffer[Length], "\n\
3270Target Command 16-32KB 32-64KB 64-128KB 128-256KB 256KB+\n\
3271====== ======= ========= ========= ========= ========= =========\n");
3272 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3273 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3274 if (!TargetFlags->TargetExists)
3275 continue;
3276 Length +=
3277 sprintf(&Buffer[Length],
3278 " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
3279 TargetStatistics[TargetID].ReadCommandSizeBuckets[5],
3280 TargetStatistics[TargetID].ReadCommandSizeBuckets[6], TargetStatistics[TargetID].ReadCommandSizeBuckets[7], TargetStatistics[TargetID].ReadCommandSizeBuckets[8], TargetStatistics[TargetID].ReadCommandSizeBuckets[9]);
3281 Length +=
3282 sprintf(&Buffer[Length],
3283 " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
3284 TargetStatistics[TargetID].WriteCommandSizeBuckets[5],
3285 TargetStatistics[TargetID].WriteCommandSizeBuckets[6], TargetStatistics[TargetID].WriteCommandSizeBuckets[7], TargetStatistics[TargetID].WriteCommandSizeBuckets[8], TargetStatistics[TargetID].WriteCommandSizeBuckets[9]);
3286 }
3287 Length += sprintf(&Buffer[Length], "\n\n\
3288 ERROR RECOVERY STATISTICS\n\
3289\n\
3290 Command Aborts Bus Device Resets Host Adapter Resets\n\
3291Target Requested Completed Requested Completed Requested Completed\n\
3292 ID \\\\\\\\ Attempted
3293====== ===== ===== ===== ===== ===== ===== ===== ===== =====\n");
3294 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3295 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3296 if (!TargetFlags->TargetExists)
3297 continue;
3298 Length += sprintf(&Buffer[Length], "\
3299 %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);
3300 }
3301 Length += sprintf(&Buffer[Length], "\nExternal Host Adapter Resets: %d\n", HostAdapter->ExternalHostAdapterResets);
3302 Length += sprintf(&Buffer[Length], "Host Adapter Internal Errors: %d\n", HostAdapter->HostAdapterInternalErrors);
3303 if (Length >= BusLogic_MessageBufferSize)
3304 BusLogic_Error("Message Buffer length %d exceeds size %d\n", HostAdapter, Length, BusLogic_MessageBufferSize);
3305 if ((Length -= Offset) <= 0)
3306 return 0;
3307 if (Length >= BytesAvailable)
3308 Length = BytesAvailable;
3309 memcpy(ProcBuffer, HostAdapter->MessageBuffer + Offset, Length);
3310 *StartPointer = ProcBuffer;
3311 return Length;
3312}
3313
3314
3315
3316
3317
3318
3319static void BusLogic_Message(enum BusLogic_MessageLevel MessageLevel, char *Format, struct BusLogic_HostAdapter *HostAdapter, ...)
3320{
3321 static char Buffer[BusLogic_LineBufferSize];
3322 static bool BeginningOfLine = true;
3323 va_list Arguments;
3324 int Length = 0;
3325 va_start(Arguments, HostAdapter);
3326 Length = vsprintf(Buffer, Format, Arguments);
3327 va_end(Arguments);
3328 if (MessageLevel == BusLogic_AnnounceLevel) {
3329 static int AnnouncementLines = 0;
3330 strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength], Buffer);
3331 HostAdapter->MessageBufferLength += Length;
3332 if (++AnnouncementLines <= 2)
3333 printk("%sscsi: %s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
3334 } else if (MessageLevel == BusLogic_InfoLevel) {
3335 strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength], Buffer);
3336 HostAdapter->MessageBufferLength += Length;
3337 if (BeginningOfLine) {
3338 if (Buffer[0] != '\n' || Length > 1)
3339 printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel], HostAdapter->HostNumber, Buffer);
3340 } else
3341 printk("%s", Buffer);
3342 } else {
3343 if (BeginningOfLine) {
3344 if (HostAdapter != NULL && HostAdapter->HostAdapterInitialized)
3345 printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel], HostAdapter->HostNumber, Buffer);
3346 else
3347 printk("%s%s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
3348 } else
3349 printk("%s", Buffer);
3350 }
3351 BeginningOfLine = (Buffer[Length - 1] == '\n');
3352}
3353
3354
3355
3356
3357
3358
3359
3360static bool __init BusLogic_ParseKeyword(char **StringPointer, char *Keyword)
3361{
3362 char *Pointer = *StringPointer;
3363 while (*Keyword != '\0') {
3364 char StringChar = *Pointer++;
3365 char KeywordChar = *Keyword++;
3366 if (StringChar >= 'A' && StringChar <= 'Z')
3367 StringChar += 'a' - 'Z';
3368 if (KeywordChar >= 'A' && KeywordChar <= 'Z')
3369 KeywordChar += 'a' - 'Z';
3370 if (StringChar != KeywordChar)
3371 return false;
3372 }
3373 *StringPointer = Pointer;
3374 return true;
3375}
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395static int __init BusLogic_ParseDriverOptions(char *OptionsString)
3396{
3397 while (true) {
3398 struct BusLogic_DriverOptions *DriverOptions = &BusLogic_DriverOptions[BusLogic_DriverOptionsCount++];
3399 int TargetID;
3400 memset(DriverOptions, 0, sizeof(struct BusLogic_DriverOptions));
3401 while (*OptionsString != '\0' && *OptionsString != ';') {
3402
3403 if (BusLogic_ParseKeyword(&OptionsString, "IO:")) {
3404 unsigned long IO_Address = simple_strtoul(OptionsString, &OptionsString, 0);
3405 BusLogic_ProbeOptions.LimitedProbeISA = true;
3406 switch (IO_Address) {
3407 case 0x330:
3408 BusLogic_ProbeOptions.Probe330 = true;
3409 break;
3410 case 0x334:
3411 BusLogic_ProbeOptions.Probe334 = true;
3412 break;
3413 case 0x230:
3414 BusLogic_ProbeOptions.Probe230 = true;
3415 break;
3416 case 0x234:
3417 BusLogic_ProbeOptions.Probe234 = true;
3418 break;
3419 case 0x130:
3420 BusLogic_ProbeOptions.Probe130 = true;
3421 break;
3422 case 0x134:
3423 BusLogic_ProbeOptions.Probe134 = true;
3424 break;
3425 default:
3426 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid I/O Address 0x%X)\n", NULL, IO_Address);
3427 return 0;
3428 }
3429 } else if (BusLogic_ParseKeyword(&OptionsString, "NoProbeISA"))
3430 BusLogic_ProbeOptions.NoProbeISA = true;
3431 else if (BusLogic_ParseKeyword(&OptionsString, "NoProbePCI"))
3432 BusLogic_ProbeOptions.NoProbePCI = true;
3433 else if (BusLogic_ParseKeyword(&OptionsString, "NoProbe"))
3434 BusLogic_ProbeOptions.NoProbe = true;
3435 else if (BusLogic_ParseKeyword(&OptionsString, "NoSortPCI"))
3436 BusLogic_ProbeOptions.NoSortPCI = true;
3437 else if (BusLogic_ParseKeyword(&OptionsString, "MultiMasterFirst"))
3438 BusLogic_ProbeOptions.MultiMasterFirst = true;
3439 else if (BusLogic_ParseKeyword(&OptionsString, "FlashPointFirst"))
3440 BusLogic_ProbeOptions.FlashPointFirst = true;
3441
3442 else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:[") || BusLogic_ParseKeyword(&OptionsString, "QD:[")) {
3443 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) {
3444 unsigned short QueueDepth = simple_strtoul(OptionsString, &OptionsString, 0);
3445 if (QueueDepth > BusLogic_MaxTaggedQueueDepth) {
3446 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, QueueDepth);
3447 return 0;
3448 }
3449 DriverOptions->QueueDepth[TargetID] = QueueDepth;
3450 if (*OptionsString == ',')
3451 OptionsString++;
3452 else if (*OptionsString == ']')
3453 break;
3454 else {
3455 BusLogic_Error("BusLogic: Invalid Driver Options " "(',' or ']' expected at '%s')\n", NULL, OptionsString);
3456 return 0;
3457 }
3458 }
3459 if (*OptionsString != ']') {
3460 BusLogic_Error("BusLogic: Invalid Driver Options " "(']' expected at '%s')\n", NULL, OptionsString);
3461 return 0;
3462 } else
3463 OptionsString++;
3464 } else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:") || BusLogic_ParseKeyword(&OptionsString, "QD:")) {
3465 unsigned short QueueDepth = simple_strtoul(OptionsString, &OptionsString, 0);
3466 if (QueueDepth == 0 || QueueDepth > BusLogic_MaxTaggedQueueDepth) {
3467 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, QueueDepth);
3468 return 0;
3469 }
3470 DriverOptions->CommonQueueDepth = QueueDepth;
3471 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
3472 DriverOptions->QueueDepth[TargetID] = QueueDepth;
3473 } else if (BusLogic_ParseKeyword(&OptionsString, "TaggedQueuing:") || BusLogic_ParseKeyword(&OptionsString, "TQ:")) {
3474 if (BusLogic_ParseKeyword(&OptionsString, "Default")) {
3475 DriverOptions->TaggedQueuingPermitted = 0x0000;
3476 DriverOptions->TaggedQueuingPermittedMask = 0x0000;
3477 } else if (BusLogic_ParseKeyword(&OptionsString, "Enable")) {
3478 DriverOptions->TaggedQueuingPermitted = 0xFFFF;
3479 DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
3480 } else if (BusLogic_ParseKeyword(&OptionsString, "Disable")) {
3481 DriverOptions->TaggedQueuingPermitted = 0x0000;
3482 DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
3483 } else {
3484 unsigned short TargetBit;
3485 for (TargetID = 0, TargetBit = 1; TargetID < BusLogic_MaxTargetDevices; TargetID++, TargetBit <<= 1)
3486 switch (*OptionsString++) {
3487 case 'Y':
3488 DriverOptions->TaggedQueuingPermitted |= TargetBit;
3489 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
3490 break;
3491 case 'N':
3492 DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
3493 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
3494 break;
3495 case 'X':
3496 break;
3497 default:
3498 OptionsString--;
3499 TargetID = BusLogic_MaxTargetDevices;
3500 break;
3501 }
3502 }
3503 }
3504
3505 else if (BusLogic_ParseKeyword(&OptionsString, "BusSettleTime:") || BusLogic_ParseKeyword(&OptionsString, "BST:")) {
3506 unsigned short BusSettleTime = simple_strtoul(OptionsString, &OptionsString, 0);
3507 if (BusSettleTime > 5 * 60) {
3508 BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Bus Settle Time %d)\n", NULL, BusSettleTime);
3509 return 0;
3510 }
3511 DriverOptions->BusSettleTime = BusSettleTime;
3512 } else if (BusLogic_ParseKeyword(&OptionsString, "InhibitTargetInquiry"))
3513 DriverOptions->LocalOptions.InhibitTargetInquiry = true;
3514
3515 else if (BusLogic_ParseKeyword(&OptionsString, "TraceProbe"))
3516 BusLogic_GlobalOptions.TraceProbe = true;
3517 else if (BusLogic_ParseKeyword(&OptionsString, "TraceHardwareReset"))
3518 BusLogic_GlobalOptions.TraceHardwareReset = true;
3519 else if (BusLogic_ParseKeyword(&OptionsString, "TraceConfiguration"))
3520 BusLogic_GlobalOptions.TraceConfiguration = true;
3521 else if (BusLogic_ParseKeyword(&OptionsString, "TraceErrors"))
3522 BusLogic_GlobalOptions.TraceErrors = true;
3523 else if (BusLogic_ParseKeyword(&OptionsString, "Debug")) {
3524 BusLogic_GlobalOptions.TraceProbe = true;
3525 BusLogic_GlobalOptions.TraceHardwareReset = true;
3526 BusLogic_GlobalOptions.TraceConfiguration = true;
3527 BusLogic_GlobalOptions.TraceErrors = true;
3528 }
3529 if (*OptionsString == ',')
3530 OptionsString++;
3531 else if (*OptionsString != ';' && *OptionsString != '\0') {
3532 BusLogic_Error("BusLogic: Unexpected Driver Option '%s' " "ignored\n", NULL, OptionsString);
3533 *OptionsString = '\0';
3534 }
3535 }
3536 if (!(BusLogic_DriverOptionsCount == 0 || BusLogic_ProbeInfoCount == 0 || BusLogic_DriverOptionsCount == BusLogic_ProbeInfoCount)) {
3537 BusLogic_Error("BusLogic: Invalid Driver Options " "(all or no I/O Addresses must be specified)\n", NULL);
3538 return 0;
3539 }
3540
3541
3542
3543
3544 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
3545 if (DriverOptions->QueueDepth[TargetID] == 1) {
3546 unsigned short TargetBit = 1 << TargetID;
3547 DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
3548 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
3549 }
3550 if (*OptionsString == ';')
3551 OptionsString++;
3552 if (*OptionsString == '\0')
3553 return 0;
3554 }
3555 return 1;
3556}
3557
3558
3559
3560
3561
3562static struct scsi_host_template Bus_Logic_template = {
3563 .module = THIS_MODULE,
3564 .proc_name = "BusLogic",
3565 .proc_info = BusLogic_ProcDirectoryInfo,
3566 .name = "BusLogic",
3567 .info = BusLogic_DriverInfo,
3568 .queuecommand = BusLogic_QueueCommand,
3569 .slave_configure = BusLogic_SlaveConfigure,
3570 .bios_param = BusLogic_BIOSDiskParameters,
3571 .eh_host_reset_handler = BusLogic_host_reset,
3572#if 0
3573 .eh_abort_handler = BusLogic_AbortCommand,
3574#endif
3575 .unchecked_isa_dma = 1,
3576 .max_sectors = 128,
3577 .use_clustering = ENABLE_CLUSTERING,
3578 .use_sg_chaining = ENABLE_SG_CHAINING,
3579};
3580
3581
3582
3583
3584
3585static int __init BusLogic_Setup(char *str)
3586{
3587 int ints[3];
3588
3589 (void) get_options(str, ARRAY_SIZE(ints), ints);
3590
3591 if (ints[0] != 0) {
3592 BusLogic_Error("BusLogic: Obsolete Command Line Entry " "Format Ignored\n", NULL);
3593 return 0;
3594 }
3595 if (str == NULL || *str == '\0')
3596 return 0;
3597 return BusLogic_ParseDriverOptions(str);
3598}
3599
3600
3601
3602
3603
3604static void __exit BusLogic_exit(void)
3605{
3606 struct BusLogic_HostAdapter *ha, *next;
3607
3608 list_for_each_entry_safe(ha, next, &BusLogic_host_list, host_list)
3609 BusLogic_ReleaseHostAdapter(ha);
3610}
3611
3612__setup("BusLogic=", BusLogic_Setup);
3613
3614#ifdef MODULE
3615static struct pci_device_id BusLogic_pci_tbl[] __devinitdata = {
3616 { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
3617 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
3618 { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
3619 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
3620 { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
3621 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
3622 { }
3623};
3624#endif
3625MODULE_DEVICE_TABLE(pci, BusLogic_pci_tbl);
3626
3627module_init(BusLogic_init);
3628module_exit(BusLogic_exit);
3629