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