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