OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [scsi/] [BusLogic.c] - Blame information for rev 1772

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/*
2
 
3
  Linux Driver for BusLogic MultiMaster and FlashPoint SCSI Host Adapters
4
 
5
  Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>
6
 
7
  This program is free software; you may redistribute and/or modify it under
8
  the terms of the GNU General Public License Version 2 as published by the
9
  Free Software Foundation.
10
 
11
  This program is distributed in the hope that it will be useful, but
12
  WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
13
  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
  for complete details.
15
 
16
  The author respectfully requests that any modifications to this software be
17
  sent directly to him for evaluation and testing.
18
 
19
  Special thanks to Wayne Yen, Jin-Lon Hon, and Alex Win of BusLogic, whose
20
  advice has been invaluable, to David Gentzel, for writing the original Linux
21
  BusLogic driver, and to Paul Gortmaker, for being such a dedicated test site.
22
 
23
  Finally, special thanks to Mylex/BusLogic for making the FlashPoint SCCB
24
  Manager available as freely redistributable source code.
25
 
26
*/
27
 
28
 
29
#define BusLogic_DriverVersion          "2.0.15"
30
#define BusLogic_DriverDate             "17 August 1998"
31
 
32
 
33
#include <linux/version.h>
34
#include <linux/module.h>
35
#include <linux/config.h>
36
#include <linux/types.h>
37
#include <linux/blkdev.h>
38
#include <linux/delay.h>
39
#include <linux/ioport.h>
40
#include <linux/mm.h>
41
#include <linux/sched.h>
42
#include <linux/stat.h>
43
#include <linux/pci.h>
44
#include <linux/bios32.h>
45
#include <asm/dma.h>
46
#include <asm/io.h>
47
#include <asm/irq.h>
48
#include <asm/system.h>
49
#include "scsi.h"
50
#include "hosts.h"
51
#include "sd.h"
52
#include "BusLogic.h"
53
#include "FlashPoint.c"
54
 
55
 
56
/*
57
  BusLogic_DriverOptionsCount is a count of the number of BusLogic Driver
58
  Options specifications provided via the Linux Kernel Command Line or via
59
  the Loadable Kernel Module Installation Facility.
60
*/
61
 
62
static int
63
  BusLogic_DriverOptionsCount =                 0;
64
 
65
 
66
/*
67
  BusLogic_DriverOptions is an array of Driver Options structures representing
68
  BusLogic Driver Options specifications provided via the Linux Kernel Command
69
  Line or via the Loadable Kernel Module Installation Facility.
70
*/
71
 
72
static BusLogic_DriverOptions_T
73
  BusLogic_DriverOptions[BusLogic_MaxHostAdapters];
74
 
75
 
76
/*
77
  BusLogic_Options can be assigned a string by the Loadable Kernel Module
78
  Installation Facility to be parsed for BusLogic Driver Options
79
  specifications.
80
*/
81
 
82
static char
83
  *BusLogic_Options =                           NULL;
84
 
85
 
86
/*
87
  BusLogic_ProbeOptions is a set of Probe Options to be applied across
88
  all BusLogic Host Adapters.
89
*/
90
 
91
static BusLogic_ProbeOptions_T
92
  BusLogic_ProbeOptions =                       { 0 };
93
 
94
 
95
/*
96
  BusLogic_GlobalOptions is a set of Global Options to be applied across
97
  all BusLogic Host Adapters.
98
*/
99
 
100
static BusLogic_GlobalOptions_T
101
  BusLogic_GlobalOptions =                      { 0 };
102
 
103
 
104
/*
105
  BusLogic_FirstRegisteredHostAdapter and BusLogic_LastRegisteredHostAdapter
106
  are pointers to the first and last registered BusLogic Host Adapters.
107
*/
108
 
109
static BusLogic_HostAdapter_T
110
  *BusLogic_FirstRegisteredHostAdapter =        NULL,
111
  *BusLogic_LastRegisteredHostAdapter =         NULL;
112
 
113
 
114
/*
115
  BusLogic_ProbeInfoCount is the number of entries in BusLogic_ProbeInfoList.
116
*/
117
 
118
static int
119
  BusLogic_ProbeInfoCount =                     0;
120
 
121
 
122
/*
123
  BusLogic_ProbeInfoList is the list of I/O Addresses and Bus Probe Information
124
  to be checked for potential BusLogic Host Adapters.  It is initialized by
125
  interrogating the PCI Configuration Space on PCI machines as well as from the
126
  list of standard BusLogic I/O Addresses.
127
*/
128
 
129
static BusLogic_ProbeInfo_T
130
  *BusLogic_ProbeInfoList =                     NULL;
131
 
132
 
133
/*
134
  BusLogic_CommandFailureReason holds a string identifying the reason why a
135
  call to BusLogic_Command failed.  It is only non-NULL when BusLogic_Command
136
  returns a failure code.
137
*/
138
 
139
static char
140
  *BusLogic_CommandFailureReason;
141
 
142
 
143
/*
144
  BusLogic_ProcDirectoryEntry is the BusLogic /proc/scsi directory entry.
145
*/
146
 
147
PROC_DirectoryEntry_T
148
  BusLogic_ProcDirectoryEntry =
149
    { PROC_SCSI_BUSLOGIC, 8, "BusLogic", S_IFDIR | S_IRUGO | S_IXUGO, 2 };
150
 
151
 
152
/*
153
  BusLogic_AnnounceDriver announces the Driver Version and Date, Author's
154
  Name, Copyright Notice, and Electronic Mail Address.
155
*/
156
 
157
static void BusLogic_AnnounceDriver(BusLogic_HostAdapter_T *HostAdapter)
158
{
159
  BusLogic_Announce("***** BusLogic SCSI Driver Version "
160
                    BusLogic_DriverVersion " of "
161
                    BusLogic_DriverDate " *****\n", HostAdapter);
162
  BusLogic_Announce("Copyright 1995-1998 by Leonard N. Zubkoff "
163
                    "<lnz@dandelion.com>\n", HostAdapter);
164
}
165
 
166
 
167
/*
168
  BusLogic_DriverInfo returns the Host Adapter Name to identify this SCSI
169
  Driver and Host Adapter.
170
*/
171
 
172
const char *BusLogic_DriverInfo(SCSI_Host_T *Host)
173
{
174
  BusLogic_HostAdapter_T *HostAdapter =
175
    (BusLogic_HostAdapter_T *) Host->hostdata;
176
  return HostAdapter->FullModelName;
177
}
178
 
179
 
180
/*
181
  BusLogic_RegisterHostAdapter adds Host Adapter to the list of registered
182
  BusLogic Host Adapters.
183
*/
184
 
185
static void BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
186
{
187
  HostAdapter->Next = NULL;
188
  if (BusLogic_FirstRegisteredHostAdapter == NULL)
189
    {
190
      BusLogic_FirstRegisteredHostAdapter = HostAdapter;
191
      BusLogic_LastRegisteredHostAdapter = HostAdapter;
192
    }
193
  else
194
    {
195
      BusLogic_LastRegisteredHostAdapter->Next = HostAdapter;
196
      BusLogic_LastRegisteredHostAdapter = HostAdapter;
197
    }
198
}
199
 
200
 
201
/*
202
  BusLogic_UnregisterHostAdapter removes Host Adapter from the list of
203
  registered BusLogic Host Adapters.
204
*/
205
 
206
static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
207
{
208
  if (HostAdapter == BusLogic_FirstRegisteredHostAdapter)
209
    {
210
      BusLogic_FirstRegisteredHostAdapter =
211
        BusLogic_FirstRegisteredHostAdapter->Next;
212
      if (HostAdapter == BusLogic_LastRegisteredHostAdapter)
213
        BusLogic_LastRegisteredHostAdapter = NULL;
214
    }
215
  else
216
    {
217
      BusLogic_HostAdapter_T *PreviousHostAdapter =
218
        BusLogic_FirstRegisteredHostAdapter;
219
      while (PreviousHostAdapter != NULL &&
220
             PreviousHostAdapter->Next != HostAdapter)
221
        PreviousHostAdapter = PreviousHostAdapter->Next;
222
      if (PreviousHostAdapter != NULL)
223
        PreviousHostAdapter->Next = HostAdapter->Next;
224
    }
225
  HostAdapter->Next = NULL;
226
}
227
 
228
 
229
/*
230
  BusLogic_InitializeCCBs initializes a group of Command Control Blocks (CCBs)
231
  for Host Adapter from the BlockSize bytes located at BlockPointer.  The newly
232
  created CCBs are added to Host Adapter's free list.
233
*/
234
 
235
static void BusLogic_InitializeCCBs(BusLogic_HostAdapter_T *HostAdapter,
236
                                    void *BlockPointer, int BlockSize)
237
{
238
  BusLogic_CCB_T *CCB = (BusLogic_CCB_T *) BlockPointer;
239
  memset(BlockPointer, 0, BlockSize);
240
  CCB->AllocationGroupHead = true;
241
  while ((BlockSize -= sizeof(BusLogic_CCB_T)) >= 0)
242
    {
243
      CCB->Status = BusLogic_CCB_Free;
244
      CCB->HostAdapter = HostAdapter;
245
      if (BusLogic_FlashPointHostAdapterP(HostAdapter))
246
        {
247
          CCB->CallbackFunction = BusLogic_QueueCompletedCCB;
248
          CCB->BaseAddress = HostAdapter->FlashPointInfo.BaseAddress;
249
        }
250
      CCB->Next = HostAdapter->Free_CCBs;
251
      CCB->NextAll = HostAdapter->All_CCBs;
252
      HostAdapter->Free_CCBs = CCB;
253
      HostAdapter->All_CCBs = CCB;
254
      HostAdapter->AllocatedCCBs++;
255
      CCB++;
256
    }
257
}
258
 
259
 
260
/*
261
  BusLogic_CreateInitialCCBs allocates the initial CCBs for Host Adapter.
262
*/
263
 
264
static boolean BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T *HostAdapter)
265
{
266
  int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(BusLogic_CCB_T);
267
  while (HostAdapter->AllocatedCCBs < HostAdapter->InitialCCBs)
268
    {
269
      void *BlockPointer = kmalloc(BlockSize,
270
                                   (HostAdapter->BounceBuffersRequired
271
                                    ? GFP_ATOMIC | GFP_DMA
272
                                    : GFP_ATOMIC));
273
      if (BlockPointer == NULL)
274
        {
275
          BusLogic_Error("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n",
276
                         HostAdapter);
277
          return false;
278
        }
279
      BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize);
280
    }
281
  return true;
282
}
283
 
284
 
285
/*
286
  BusLogic_DestroyCCBs deallocates the CCBs for Host Adapter.
287
*/
288
 
289
static void BusLogic_DestroyCCBs(BusLogic_HostAdapter_T *HostAdapter)
290
{
291
  BusLogic_CCB_T *NextCCB = HostAdapter->All_CCBs, *CCB;
292
  HostAdapter->All_CCBs = NULL;
293
  HostAdapter->Free_CCBs = NULL;
294
  while ((CCB = NextCCB) != NULL)
295
    {
296
      NextCCB = CCB->NextAll;
297
      if (CCB->AllocationGroupHead)
298
        kfree(CCB);
299
    }
300
}
301
 
302
 
303
/*
304
  BusLogic_CreateAdditionalCCBs allocates Additional CCBs for Host Adapter.  If
305
  allocation fails and there are no remaining CCBs available, the Driver Queue
306
  Depth is decreased to a known safe value to avoid potential deadlocks when
307
  multiple host adapters share the same IRQ Channel.
308
*/
309
 
310
static void BusLogic_CreateAdditionalCCBs(BusLogic_HostAdapter_T *HostAdapter,
311
                                          int AdditionalCCBs,
312
                                          boolean SuccessMessageP)
313
{
314
  int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(BusLogic_CCB_T);
315
  int PreviouslyAllocated = HostAdapter->AllocatedCCBs;
316
  if (AdditionalCCBs <= 0) return;
317
  while (HostAdapter->AllocatedCCBs - PreviouslyAllocated < AdditionalCCBs)
318
    {
319
      void *BlockPointer = kmalloc(BlockSize,
320
                                   (HostAdapter->BounceBuffersRequired
321
                                    ? GFP_ATOMIC | GFP_DMA
322
                                    : GFP_ATOMIC));
323
      if (BlockPointer == NULL) break;
324
      BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize);
325
    }
326
  if (HostAdapter->AllocatedCCBs > PreviouslyAllocated)
327
    {
328
      if (SuccessMessageP)
329
        BusLogic_Notice("Allocated %d additional CCBs (total now %d)\n",
330
                        HostAdapter,
331
                        HostAdapter->AllocatedCCBs - PreviouslyAllocated,
332
                        HostAdapter->AllocatedCCBs);
333
      return;
334
    }
335
  BusLogic_Notice("Failed to allocate additional CCBs\n", HostAdapter);
336
  if (HostAdapter->DriverQueueDepth >
337
      HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount)
338
    {
339
      HostAdapter->DriverQueueDepth =
340
        HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount;
341
      HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth;
342
    }
343
}
344
 
345
 
346
/*
347
  BusLogic_AllocateCCB allocates a CCB from Host Adapter's free list,
348
  allocating more memory from the Kernel if necessary.  The Host Adapter's
349
  Lock should already have been acquired by the caller.
350
*/
351
 
352
static BusLogic_CCB_T *BusLogic_AllocateCCB(BusLogic_HostAdapter_T
353
                                            *HostAdapter)
354
{
355
  static unsigned long SerialNumber = 0;
356
  BusLogic_CCB_T *CCB;
357
  CCB = HostAdapter->Free_CCBs;
358
  if (CCB != NULL)
359
    {
360
      CCB->SerialNumber = ++SerialNumber;
361
      HostAdapter->Free_CCBs = CCB->Next;
362
      CCB->Next = NULL;
363
      if (HostAdapter->Free_CCBs == NULL)
364
        BusLogic_CreateAdditionalCCBs(HostAdapter,
365
                                      HostAdapter->IncrementalCCBs,
366
                                      true);
367
      return CCB;
368
    }
369
  BusLogic_CreateAdditionalCCBs(HostAdapter,
370
                                HostAdapter->IncrementalCCBs,
371
                                true);
372
  CCB = HostAdapter->Free_CCBs;
373
  if (CCB == NULL) return NULL;
374
  CCB->SerialNumber = ++SerialNumber;
375
  HostAdapter->Free_CCBs = CCB->Next;
376
  CCB->Next = NULL;
377
  return CCB;
378
}
379
 
380
 
381
/*
382
  BusLogic_DeallocateCCB deallocates a CCB, returning it to the Host Adapter's
383
  free list.  The Host Adapter's Lock should already have been acquired by the
384
  caller.
385
*/
386
 
387
static void BusLogic_DeallocateCCB(BusLogic_CCB_T *CCB)
388
{
389
  BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
390
  CCB->Command = NULL;
391
  CCB->Status = BusLogic_CCB_Free;
392
  CCB->Next = HostAdapter->Free_CCBs;
393
  HostAdapter->Free_CCBs = CCB;
394
}
395
 
396
 
397
/*
398
  BusLogic_Command sends the command OperationCode to HostAdapter, optionally
399
  providing ParameterLength bytes of ParameterData and receiving at most
400
  ReplyLength bytes of ReplyData; any excess reply data is received but
401
  discarded.
402
 
403
  On success, this function returns the number of reply bytes read from
404
  the Host Adapter (including any discarded data); on failure, it returns
405
  -1 if the command was invalid, or -2 if a timeout occurred.
406
 
407
  BusLogic_Command is called exclusively during host adapter detection and
408
  initialization, so performance and latency are not critical, and exclusive
409
  access to the Host Adapter hardware is assumed.  Once the host adapter and
410
  driver are initialized, the only Host Adapter command that is issued is the
411
  single byte Execute Mailbox Command operation code, which does not require
412
  waiting for the Host Adapter Ready bit to be set in the Status Register.
413
*/
414
 
415
static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter,
416
                            BusLogic_OperationCode_T OperationCode,
417
                            void *ParameterData,
418
                            int ParameterLength,
419
                            void *ReplyData,
420
                            int ReplyLength)
421
{
422
  unsigned char *ParameterPointer = (unsigned char *) ParameterData;
423
  unsigned char *ReplyPointer = (unsigned char *) ReplyData;
424
  BusLogic_StatusRegister_T StatusRegister;
425
  BusLogic_InterruptRegister_T InterruptRegister;
426
  ProcessorFlags_T ProcessorFlags = 0;
427
  int ReplyBytes = 0, Result;
428
  long TimeoutCounter;
429
  /*
430
    Clear out the Reply Data if provided.
431
  */
432
  if (ReplyLength > 0)
433
    memset(ReplyData, 0, ReplyLength);
434
  /*
435
    If the IRQ Channel has not yet been acquired, then interrupts must be
436
    disabled while issuing host adapter commands since a Command Complete
437
    interrupt could occur if the IRQ Channel was previously enabled by another
438
    BusLogic Host Adapter or another driver sharing the same IRQ Channel.
439
  */
440
  if (!HostAdapter->IRQ_ChannelAcquired)
441
    {
442
      save_flags(ProcessorFlags);
443
      cli();
444
    }
445
  /*
446
    Wait for the Host Adapter Ready bit to be set and the Command/Parameter
447
    Register Busy bit to be reset in the Status Register.
448
  */
449
  TimeoutCounter = 10000;
450
  while (--TimeoutCounter >= 0)
451
    {
452
      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
453
      if (StatusRegister.Bits.HostAdapterReady &&
454
          !StatusRegister.Bits.CommandParameterRegisterBusy)
455
        break;
456
      udelay(100);
457
    }
458
  if (TimeoutCounter < 0)
459
    {
460
      BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";
461
      Result = -2;
462
      goto Done;
463
    }
464
  /*
465
    Write the OperationCode to the Command/Parameter Register.
466
  */
467
  HostAdapter->HostAdapterCommandCompleted = false;
468
  BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);
469
  /*
470
    Write any additional Parameter Bytes.
471
  */
472
  TimeoutCounter = 10000;
473
  while (ParameterLength > 0 && --TimeoutCounter >= 0)
474
    {
475
      /*
476
        Wait 100 microseconds to give the Host Adapter enough time to determine
477
        whether the last value written to the Command/Parameter Register was
478
        valid or not.  If the Command Complete bit is set in the Interrupt
479
        Register, then the Command Invalid bit in the Status Register will be
480
        reset if the Operation Code or Parameter was valid and the command
481
        has completed, or set if the Operation Code or Parameter was invalid.
482
        If the Data In Register Ready bit is set in the Status Register, then
483
        the Operation Code was valid, and data is waiting to be read back
484
        from the Host Adapter.  Otherwise, wait for the Command/Parameter
485
        Register Busy bit in the Status Register to be reset.
486
      */
487
      udelay(100);
488
      InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
489
      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
490
      if (InterruptRegister.Bits.CommandComplete) break;
491
      if (HostAdapter->HostAdapterCommandCompleted) break;
492
      if (StatusRegister.Bits.DataInRegisterReady) break;
493
      if (StatusRegister.Bits.CommandParameterRegisterBusy) continue;
494
      BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++);
495
      ParameterLength--;
496
    }
497
  if (TimeoutCounter < 0)
498
    {
499
      BusLogic_CommandFailureReason =
500
        "Timeout waiting for Parameter Acceptance";
501
      Result = -2;
502
      goto Done;
503
    }
504
  /*
505
    The Modify I/O Address command does not cause a Command Complete Interrupt.
506
  */
507
  if (OperationCode == BusLogic_ModifyIOAddress)
508
    {
509
      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
510
      if (StatusRegister.Bits.CommandInvalid)
511
        {
512
          BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
513
          Result = -1;
514
          goto Done;
515
        }
516
      if (BusLogic_GlobalOptions.TraceConfiguration)
517
        BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: "
518
                        "(Modify I/O Address)\n", HostAdapter,
519
                        OperationCode, StatusRegister.All);
520
      Result = 0;
521
      goto Done;
522
    }
523
  /*
524
    Select an appropriate timeout value for awaiting command completion.
525
  */
526
  switch (OperationCode)
527
    {
528
    case BusLogic_InquireInstalledDevicesID0to7:
529
    case BusLogic_InquireInstalledDevicesID8to15:
530
    case BusLogic_InquireTargetDevices:
531
      /* Approximately 60 seconds. */
532
      TimeoutCounter = 60*10000;
533
      break;
534
    default:
535
      /* Approximately 1 second. */
536
      TimeoutCounter = 10000;
537
      break;
538
    }
539
  /*
540
    Receive any Reply Bytes, waiting for either the Command Complete bit to
541
    be set in the Interrupt Register, or for the Interrupt Handler to set the
542
    Host Adapter Command Completed bit in the Host Adapter structure.
543
  */
544
  while (--TimeoutCounter >= 0)
545
    {
546
      InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
547
      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
548
      if (InterruptRegister.Bits.CommandComplete) break;
549
      if (HostAdapter->HostAdapterCommandCompleted) break;
550
      if (StatusRegister.Bits.DataInRegisterReady)
551
        {
552
          if (++ReplyBytes <= ReplyLength)
553
            *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
554
          else BusLogic_ReadDataInRegister(HostAdapter);
555
        }
556
      if (OperationCode == BusLogic_FetchHostAdapterLocalRAM &&
557
          StatusRegister.Bits.HostAdapterReady) break;
558
      udelay(100);
559
    }
560
  if (TimeoutCounter < 0)
561
    {
562
      BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";
563
      Result = -2;
564
      goto Done;
565
    }
566
  /*
567
    Clear any pending Command Complete Interrupt.
568
  */
569
  BusLogic_InterruptReset(HostAdapter);
570
  /*
571
    Provide tracing information if requested.
572
  */
573
  if (BusLogic_GlobalOptions.TraceConfiguration)
574
    {
575
      int i;
576
      BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:",
577
                      HostAdapter, OperationCode,
578
                      StatusRegister.All, ReplyLength, ReplyBytes);
579
      if (ReplyLength > ReplyBytes) ReplyLength = ReplyBytes;
580
      for (i = 0; i < ReplyLength; i++)
581
        BusLogic_Notice(" %02X", HostAdapter,
582
                        ((unsigned char *) ReplyData)[i]);
583
      BusLogic_Notice("\n", HostAdapter);
584
    }
585
  /*
586
    Process Command Invalid conditions.
587
  */
588
  if (StatusRegister.Bits.CommandInvalid)
589
    {
590
      /*
591
        Some early BusLogic Host Adapters may not recover properly from
592
        a Command Invalid condition, so if this appears to be the case,
593
        a Soft Reset is issued to the Host Adapter.  Potentially invalid
594
        commands are never attempted after Mailbox Initialization is
595
        performed, so there should be no Host Adapter state lost by a
596
        Soft Reset in response to a Command Invalid condition.
597
      */
598
      udelay(1000);
599
      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
600
      if (StatusRegister.Bits.CommandInvalid ||
601
          StatusRegister.Bits.Reserved ||
602
          StatusRegister.Bits.DataInRegisterReady ||
603
          StatusRegister.Bits.CommandParameterRegisterBusy ||
604
          !StatusRegister.Bits.HostAdapterReady ||
605
          !StatusRegister.Bits.InitializationRequired ||
606
          StatusRegister.Bits.DiagnosticActive ||
607
          StatusRegister.Bits.DiagnosticFailure)
608
        {
609
          BusLogic_SoftReset(HostAdapter);
610
          udelay(1000);
611
        }
612
      BusLogic_CommandFailureReason = "Command Invalid";
613
      Result = -1;
614
      goto Done;
615
    }
616
  /*
617
    Handle Excess Parameters Supplied conditions.
618
  */
619
  if (ParameterLength > 0)
620
    {
621
      BusLogic_CommandFailureReason = "Excess Parameters Supplied";
622
      Result = -1;
623
      goto Done;
624
    }
625
  /*
626
    Indicate the command completed successfully.
627
  */
628
  BusLogic_CommandFailureReason = NULL;
629
  Result = ReplyBytes;
630
  /*
631
    Restore the interrupt status if necessary and return.
632
  */
633
Done:
634
  if (!HostAdapter->IRQ_ChannelAcquired)
635
    restore_flags(ProcessorFlags);
636
  return Result;
637
}
638
 
639
 
640
/*
641
  BusLogic_AppendProbeAddressISA appends a single ISA I/O Address to the list
642
  of I/O Address and Bus Probe Information to be checked for potential BusLogic
643
  Host Adapters.
644
*/
645
 
646
static void BusLogic_AppendProbeAddressISA(BusLogic_IO_Address_T IO_Address)
647
{
648
  BusLogic_ProbeInfo_T *ProbeInfo;
649
  if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) return;
650
  ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
651
  ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
652
  ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
653
  ProbeInfo->IO_Address = IO_Address;
654
}
655
 
656
 
657
/*
658
  BusLogic_InitializeProbeInfoListISA initializes the list of I/O Address and
659
  Bus Probe Information to be checked for potential BusLogic SCSI Host Adapters
660
  only from the list of standard BusLogic MultiMaster ISA I/O Addresses.
661
*/
662
 
663
static void BusLogic_InitializeProbeInfoListISA(BusLogic_HostAdapter_T
664
                                                *PrototypeHostAdapter)
665
{
666
  /*
667
    If BusLogic Driver Options specifications requested that ISA Bus Probes
668
    be inhibited, do not proceed further.
669
  */
670
  if (BusLogic_ProbeOptions.NoProbeISA) return;
671
  /*
672
    Append the list of standard BusLogic MultiMaster ISA I/O Addresses.
673
  */
674
  if (BusLogic_ProbeOptions.LimitedProbeISA
675
      ? BusLogic_ProbeOptions.Probe330
676
      : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0)
677
    BusLogic_AppendProbeAddressISA(0x330);
678
  if (BusLogic_ProbeOptions.LimitedProbeISA
679
      ? BusLogic_ProbeOptions.Probe334
680
      : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0)
681
    BusLogic_AppendProbeAddressISA(0x334);
682
  if (BusLogic_ProbeOptions.LimitedProbeISA
683
      ? BusLogic_ProbeOptions.Probe230
684
      : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0)
685
    BusLogic_AppendProbeAddressISA(0x230);
686
  if (BusLogic_ProbeOptions.LimitedProbeISA
687
      ? BusLogic_ProbeOptions.Probe234
688
      : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0)
689
    BusLogic_AppendProbeAddressISA(0x234);
690
  if (BusLogic_ProbeOptions.LimitedProbeISA
691
      ? BusLogic_ProbeOptions.Probe130
692
      : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0)
693
    BusLogic_AppendProbeAddressISA(0x130);
694
  if (BusLogic_ProbeOptions.LimitedProbeISA
695
      ? BusLogic_ProbeOptions.Probe134
696
      : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0)
697
    BusLogic_AppendProbeAddressISA(0x134);
698
}
699
 
700
 
701
#ifdef CONFIG_PCI
702
 
703
 
704
/*
705
  BusLogic_SortProbeInfo sorts a section of BusLogic_ProbeInfoList in order
706
  of increasing PCI Bus and Device Number.
707
*/
708
 
709
static void BusLogic_SortProbeInfo(BusLogic_ProbeInfo_T *ProbeInfoList,
710
                                   int ProbeInfoCount)
711
{
712
  int LastInterchange = ProbeInfoCount-1, Bound, j;
713
  while (LastInterchange > 0)
714
    {
715
      Bound = LastInterchange;
716
      LastInterchange = 0;
717
      for (j = 0; j < Bound; j++)
718
        {
719
          BusLogic_ProbeInfo_T *ProbeInfo1 = &ProbeInfoList[j];
720
          BusLogic_ProbeInfo_T *ProbeInfo2 = &ProbeInfoList[j+1];
721
          if (ProbeInfo1->Bus > ProbeInfo2->Bus ||
722
              (ProbeInfo1->Bus == ProbeInfo2->Bus &&
723
               (ProbeInfo1->Device > ProbeInfo2->Device)))
724
            {
725
              BusLogic_ProbeInfo_T TempProbeInfo;
726
              memcpy(&TempProbeInfo, ProbeInfo1, sizeof(BusLogic_ProbeInfo_T));
727
              memcpy(ProbeInfo1, ProbeInfo2, sizeof(BusLogic_ProbeInfo_T));
728
              memcpy(ProbeInfo2, &TempProbeInfo, sizeof(BusLogic_ProbeInfo_T));
729
              LastInterchange = j;
730
            }
731
        }
732
    }
733
}
734
 
735
 
736
/*
737
  BusLogic_InitializeMultiMasterProbeInfo initializes the list of I/O Address
738
  and Bus Probe Information to be checked for potential BusLogic MultiMaster
739
  SCSI Host Adapters by interrogating the PCI Configuration Space on PCI
740
  machines as well as from the list of standard BusLogic MultiMaster ISA
741
  I/O Addresses.  It returns the number of PCI MultiMaster Host Adapters found.
742
*/
743
 
744
static int BusLogic_InitializeMultiMasterProbeInfo(BusLogic_HostAdapter_T
745
                                                   *PrototypeHostAdapter)
746
{
747
  BusLogic_ProbeInfo_T *PrimaryProbeInfo =
748
    &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount];
749
  int NonPrimaryPCIMultiMasterIndex = BusLogic_ProbeInfoCount + 1;
750
  int NonPrimaryPCIMultiMasterCount = 0, PCIMultiMasterCount = 0;
751
  boolean ForceBusDeviceScanningOrder = false;
752
  boolean ForceBusDeviceScanningOrderChecked = false;
753
  boolean StandardAddressSeen[6];
754
  unsigned char Bus, DeviceFunction;
755
  unsigned int BaseAddress0, BaseAddress1;
756
  unsigned char IRQ_Channel;
757
  BusLogic_IO_Address_T IO_Address;
758
  BusLogic_PCI_Address_T PCI_Address;
759
  unsigned short Index = 0;
760
  int i;
761
  if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) return 0;
762
  BusLogic_ProbeInfoCount++;
763
  for (i = 0; i < 6; i++)
764
    StandardAddressSeen[i] = false;
765
  /*
766
    Iterate over the MultiMaster PCI Host Adapters.  For each enumerated host
767
    adapter, determine whether its ISA Compatible I/O Port is enabled and if
768
    so, whether it is assigned the Primary I/O Address.  A host adapter that is
769
    assigned the Primary I/O Address will always be the preferred boot device.
770
    The MultiMaster BIOS will first recognize a host adapter at the Primary I/O
771
    Address, then any other PCI host adapters, and finally any host adapters
772
    located at the remaining standard ISA I/O Addresses.  When a PCI host
773
    adapter is found with its ISA Compatible I/O Port enabled, a command is
774
    issued to disable the ISA Compatible I/O Port, and it is noted that the
775
    particular standard ISA I/O Address need not be probed.
776
  */
777
  PrimaryProbeInfo->IO_Address = 0;
778
  while (pcibios_find_device(PCI_VENDOR_ID_BUSLOGIC,
779
                             PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
780
                             Index++, &Bus, &DeviceFunction) == 0)
781
    if (pcibios_read_config_dword(Bus, DeviceFunction,
782
                                  PCI_BASE_ADDRESS_0, &BaseAddress0) == 0 &&
783
        pcibios_read_config_dword(Bus, DeviceFunction,
784
                                  PCI_BASE_ADDRESS_1, &BaseAddress1) == 0 &&
785
        pcibios_read_config_byte(Bus, DeviceFunction,
786
                                 PCI_INTERRUPT_LINE, &IRQ_Channel) == 0)
787
      {
788
        BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
789
        BusLogic_PCIHostAdapterInformation_T PCIHostAdapterInformation;
790
        BusLogic_ModifyIOAddressRequest_T ModifyIOAddressRequest;
791
        unsigned char Device = DeviceFunction >> 3;
792
        IO_Address = BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK;
793
        PCI_Address = BaseAddress1 & PCI_BASE_ADDRESS_MEM_MASK;
794
        if ((BaseAddress0 & PCI_BASE_ADDRESS_SPACE)
795
            != PCI_BASE_ADDRESS_SPACE_IO)
796
          {
797
            BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for "
798
                           "MultiMaster Host Adapter\n", NULL, BaseAddress0);
799
            BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
800
                           NULL, Bus, Device, IO_Address);
801
            continue;
802
          }
803
        if ((BaseAddress1 & PCI_BASE_ADDRESS_SPACE)
804
            != PCI_BASE_ADDRESS_SPACE_MEMORY)
805
          {
806
            BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for "
807
                           "MultiMaster Host Adapter\n", NULL, BaseAddress1);
808
            BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n",
809
                           NULL, Bus, Device, PCI_Address);
810
            continue;
811
          }
812
        if (IRQ_Channel == 0 || IRQ_Channel >= NR_IRQS)
813
          {
814
            BusLogic_Error("BusLogic: IRQ Channel %d illegal for "
815
                           "MultiMaster Host Adapter\n", NULL, IRQ_Channel);
816
            BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
817
                           NULL, Bus, Device, IO_Address);
818
            continue;
819
          }
820
        if (BusLogic_GlobalOptions.TraceProbe)
821
          {
822
            BusLogic_Notice("BusLogic: PCI MultiMaster Host Adapter "
823
                            "detected at\n", NULL);
824
            BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address "
825
                            "0x%X PCI Address 0x%X\n", NULL,
826
                            Bus, Device, IO_Address, PCI_Address);
827
          }
828
        /*
829
          Issue the Inquire PCI Host Adapter Information command to determine
830
          the ISA Compatible I/O Port.  If the ISA Compatible I/O Port is
831
          known and enabled, note that the particular Standard ISA I/O
832
          Address should not be probed.
833
        */
834
        HostAdapter->IO_Address = IO_Address;
835
        BusLogic_InterruptReset(HostAdapter);
836
        if (BusLogic_Command(HostAdapter,
837
                             BusLogic_InquirePCIHostAdapterInformation,
838
                             NULL, 0, &PCIHostAdapterInformation,
839
                             sizeof(PCIHostAdapterInformation))
840
            == sizeof(PCIHostAdapterInformation))
841
          {
842
            if (PCIHostAdapterInformation.ISACompatibleIOPort < 6)
843
              StandardAddressSeen[PCIHostAdapterInformation
844
                                  .ISACompatibleIOPort] = true;
845
          }
846
        else PCIHostAdapterInformation.ISACompatibleIOPort =
847
               BusLogic_IO_Disable;
848
        /*
849
          Issue the Modify I/O Address command to disable the ISA Compatible
850
          I/O Port.
851
        */
852
        ModifyIOAddressRequest = BusLogic_IO_Disable;
853
        BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress,
854
                         &ModifyIOAddressRequest,
855
                         sizeof(ModifyIOAddressRequest), NULL, 0);
856
        /*
857
          For the first MultiMaster Host Adapter enumerated, issue the Fetch
858
          Host Adapter Local RAM command to read byte 45 of the AutoSCSI area,
859
          for the setting of the "Use Bus And Device # For PCI Scanning Seq."
860
          option.  Issue the Inquire Board ID command since this option is
861
          only valid for the BT-948/958/958D.
862
        */
863
        if (!ForceBusDeviceScanningOrderChecked)
864
          {
865
            BusLogic_FetchHostAdapterLocalRAMRequest_T
866
              FetchHostAdapterLocalRAMRequest;
867
            BusLogic_AutoSCSIByte45_T AutoSCSIByte45;
868
            BusLogic_BoardID_T BoardID;
869
            FetchHostAdapterLocalRAMRequest.ByteOffset =
870
              BusLogic_AutoSCSI_BaseOffset + 45;
871
            FetchHostAdapterLocalRAMRequest.ByteCount =
872
              sizeof(AutoSCSIByte45);
873
            BusLogic_Command(HostAdapter,
874
                             BusLogic_FetchHostAdapterLocalRAM,
875
                             &FetchHostAdapterLocalRAMRequest,
876
                             sizeof(FetchHostAdapterLocalRAMRequest),
877
                             &AutoSCSIByte45, sizeof(AutoSCSIByte45));
878
            BusLogic_Command(HostAdapter, BusLogic_InquireBoardID,
879
                             NULL, 0, &BoardID, sizeof(BoardID));
880
            if (BoardID.FirmwareVersion1stDigit == '5')
881
              ForceBusDeviceScanningOrder =
882
                AutoSCSIByte45.ForceBusDeviceScanningOrder;
883
            ForceBusDeviceScanningOrderChecked = true;
884
          }
885
        /*
886
          Determine whether this MultiMaster Host Adapter has its ISA
887
          Compatible I/O Port enabled and is assigned the Primary I/O Address.
888
          If it does, then it is the Primary MultiMaster Host Adapter and must
889
          be recognized first.  If it does not, then it is added to the list
890
          for probing after any Primary MultiMaster Host Adapter is probed.
891
        */
892
        if (PCIHostAdapterInformation.ISACompatibleIOPort == BusLogic_IO_330)
893
          {
894
            PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
895
            PrimaryProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
896
            PrimaryProbeInfo->IO_Address = IO_Address;
897
            PrimaryProbeInfo->PCI_Address = PCI_Address;
898
            PrimaryProbeInfo->Bus = Bus;
899
            PrimaryProbeInfo->Device = Device;
900
            PrimaryProbeInfo->IRQ_Channel = IRQ_Channel;
901
            PCIMultiMasterCount++;
902
          }
903
        else if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters)
904
          {
905
            BusLogic_ProbeInfo_T *ProbeInfo =
906
              &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
907
            ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
908
            ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
909
            ProbeInfo->IO_Address = IO_Address;
910
            ProbeInfo->PCI_Address = PCI_Address;
911
            ProbeInfo->Bus = Bus;
912
            ProbeInfo->Device = Device;
913
            ProbeInfo->IRQ_Channel = IRQ_Channel;
914
            NonPrimaryPCIMultiMasterCount++;
915
            PCIMultiMasterCount++;
916
          }
917
        else BusLogic_Warning("BusLogic: Too many Host Adapters "
918
                              "detected\n", NULL);
919
      }
920
  /*
921
    If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option is ON
922
    for the first enumerated MultiMaster Host Adapter, and if that host adapter
923
    is a BT-948/958/958D, then the MultiMaster BIOS will recognize MultiMaster
924
    Host Adapters in the order of increasing PCI Bus and Device Number.  In
925
    that case, sort the probe information into the same order the BIOS uses.
926
    If this option is OFF, then the MultiMaster BIOS will recognize MultiMaster
927
    Host Adapters in the order they are enumerated by the PCI BIOS, and hence
928
    no sorting is necessary.
929
  */
930
  if (ForceBusDeviceScanningOrder)
931
    BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[
932
                              NonPrimaryPCIMultiMasterIndex],
933
                           NonPrimaryPCIMultiMasterCount);
934
  /*
935
    If no PCI MultiMaster Host Adapter is assigned the Primary I/O Address,
936
    then the Primary I/O Address must be probed explicitly before any PCI
937
    host adapters are probed.
938
  */
939
  if (!BusLogic_ProbeOptions.NoProbeISA)
940
    if (PrimaryProbeInfo->IO_Address == 0 &&
941
        (BusLogic_ProbeOptions.LimitedProbeISA
942
         ? BusLogic_ProbeOptions.Probe330
943
         : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0))
944
      {
945
        PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
946
        PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
947
        PrimaryProbeInfo->IO_Address = 0x330;
948
      }
949
  /*
950
    Append the list of standard BusLogic MultiMaster ISA I/O Addresses,
951
    omitting the Primary I/O Address which has already been handled.
952
  */
953
  if (!BusLogic_ProbeOptions.NoProbeISA)
954
    {
955
      if (!StandardAddressSeen[1] &&
956
          (BusLogic_ProbeOptions.LimitedProbeISA
957
           ? BusLogic_ProbeOptions.Probe334
958
           : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0))
959
        BusLogic_AppendProbeAddressISA(0x334);
960
      if (!StandardAddressSeen[2] &&
961
          (BusLogic_ProbeOptions.LimitedProbeISA
962
           ? BusLogic_ProbeOptions.Probe230
963
           : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0))
964
        BusLogic_AppendProbeAddressISA(0x230);
965
      if (!StandardAddressSeen[3] &&
966
          (BusLogic_ProbeOptions.LimitedProbeISA
967
           ? BusLogic_ProbeOptions.Probe234
968
           : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0))
969
        BusLogic_AppendProbeAddressISA(0x234);
970
      if (!StandardAddressSeen[4] &&
971
          (BusLogic_ProbeOptions.LimitedProbeISA
972
           ? BusLogic_ProbeOptions.Probe130
973
           : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0))
974
        BusLogic_AppendProbeAddressISA(0x130);
975
      if (!StandardAddressSeen[5] &&
976
          (BusLogic_ProbeOptions.LimitedProbeISA
977
           ? BusLogic_ProbeOptions.Probe134
978
           : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0))
979
        BusLogic_AppendProbeAddressISA(0x134);
980
    }
981
  /*
982
    Iterate over the older non-compliant MultiMaster PCI Host Adapters,
983
    noting the PCI bus location and assigned IRQ Channel.
984
  */
985
  Index = 0;
986
  while (pcibios_find_device(PCI_VENDOR_ID_BUSLOGIC,
987
                             PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
988
                             Index++, &Bus, &DeviceFunction) == 0)
989
    if (pcibios_read_config_dword(Bus, DeviceFunction,
990
                                  PCI_BASE_ADDRESS_0, &BaseAddress0) == 0 &&
991
        pcibios_read_config_byte(Bus, DeviceFunction,
992
                                 PCI_INTERRUPT_LINE, &IRQ_Channel) == 0)
993
      {
994
        unsigned char Device = DeviceFunction >> 3;
995
        IO_Address = BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK;
996
        if (IO_Address == 0 || IRQ_Channel == 0 || IRQ_Channel >= NR_IRQS)
997
          continue;
998
        for (i = 0; i < BusLogic_ProbeInfoCount; i++)
999
          {
1000
            BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[i];
1001
            if (ProbeInfo->IO_Address == IO_Address &&
1002
                ProbeInfo->HostAdapterType == BusLogic_MultiMaster)
1003
              {
1004
                ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
1005
                ProbeInfo->PCI_Address = 0;
1006
                ProbeInfo->Bus = Bus;
1007
                ProbeInfo->Device = Device;
1008
                ProbeInfo->IRQ_Channel = IRQ_Channel;
1009
                break;
1010
              }
1011
          }
1012
      }
1013
  return PCIMultiMasterCount;
1014
}
1015
 
1016
 
1017
/*
1018
  BusLogic_InitializeFlashPointProbeInfo initializes the list of I/O Address
1019
  and Bus Probe Information to be checked for potential BusLogic FlashPoint
1020
  Host Adapters by interrogating the PCI Configuration Space.  It returns the
1021
  number of FlashPoint Host Adapters found.
1022
*/
1023
 
1024
static int BusLogic_InitializeFlashPointProbeInfo(BusLogic_HostAdapter_T
1025
                                                  *PrototypeHostAdapter)
1026
{
1027
  int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0;
1028
  unsigned char Bus, DeviceFunction;
1029
  unsigned int BaseAddress0, BaseAddress1;
1030
  unsigned char IRQ_Channel;
1031
  BusLogic_IO_Address_T IO_Address;
1032
  BusLogic_PCI_Address_T PCI_Address;
1033
  unsigned short Index = 0;
1034
  /*
1035
    Interrogate PCI Configuration Space for any FlashPoint Host Adapters.
1036
  */
1037
  while (pcibios_find_device(PCI_VENDOR_ID_BUSLOGIC,
1038
                             PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
1039
                             Index++, &Bus, &DeviceFunction) == 0)
1040
    if (pcibios_read_config_dword(Bus, DeviceFunction,
1041
                                  PCI_BASE_ADDRESS_0, &BaseAddress0) == 0 &&
1042
        pcibios_read_config_dword(Bus, DeviceFunction,
1043
                                  PCI_BASE_ADDRESS_1, &BaseAddress1) == 0 &&
1044
        pcibios_read_config_byte(Bus, DeviceFunction,
1045
                                 PCI_INTERRUPT_LINE, &IRQ_Channel) == 0)
1046
      {
1047
        unsigned char Device = DeviceFunction >> 3;
1048
        IO_Address = BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK;
1049
        PCI_Address = BaseAddress1 & PCI_BASE_ADDRESS_MEM_MASK;
1050
#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
1051
        if ((BaseAddress0 & PCI_BASE_ADDRESS_SPACE)
1052
            != PCI_BASE_ADDRESS_SPACE_IO)
1053
          {
1054
            BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for "
1055
                           "FlashPoint Host Adapter\n", NULL, BaseAddress0);
1056
            BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
1057
                           NULL, Bus, Device, IO_Address);
1058
            continue;
1059
          }
1060
        if ((BaseAddress1 & PCI_BASE_ADDRESS_SPACE)
1061
            != PCI_BASE_ADDRESS_SPACE_MEMORY)
1062
          {
1063
            BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for "
1064
                           "FlashPoint Host Adapter\n", NULL, BaseAddress1);
1065
            BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n",
1066
                           NULL, Bus, Device, PCI_Address);
1067
            continue;
1068
          }
1069
        if (IRQ_Channel == 0 || IRQ_Channel >= NR_IRQS)
1070
          {
1071
            BusLogic_Error("BusLogic: IRQ Channel %d illegal for "
1072
                           "FlashPoint Host Adapter\n", NULL, IRQ_Channel);
1073
            BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
1074
                           NULL, Bus, Device, IO_Address);
1075
            continue;
1076
          }
1077
        if (BusLogic_GlobalOptions.TraceProbe)
1078
          {
1079
            BusLogic_Notice("BusLogic: FlashPoint Host Adapter "
1080
                            "detected at\n", NULL);
1081
            BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address "
1082
                            "0x%X PCI Address 0x%X\n", NULL,
1083
                            Bus, Device, IO_Address, PCI_Address);
1084
          }
1085
        if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters)
1086
          {
1087
            BusLogic_ProbeInfo_T *ProbeInfo =
1088
              &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
1089
            ProbeInfo->HostAdapterType = BusLogic_FlashPoint;
1090
            ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
1091
            ProbeInfo->IO_Address = IO_Address;
1092
            ProbeInfo->PCI_Address = PCI_Address;
1093
            ProbeInfo->Bus = Bus;
1094
            ProbeInfo->Device = Device;
1095
            ProbeInfo->IRQ_Channel = IRQ_Channel;
1096
            FlashPointCount++;
1097
          }
1098
        else BusLogic_Warning("BusLogic: Too many Host Adapters "
1099
                              "detected\n", NULL);
1100
#else
1101
        BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at "
1102
                       "PCI Bus %d Device %d\n", NULL, Bus, Device);
1103
        BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, "
1104
                       "but FlashPoint\n", NULL, IO_Address, PCI_Address);
1105
        BusLogic_Error("BusLogic: support was omitted in this kernel "
1106
                       "configuration.\n", NULL);
1107
#endif
1108
      }
1109
  /*
1110
    The FlashPoint BIOS will scan for FlashPoint Host Adapters in the order of
1111
    increasing PCI Bus and Device Number, so sort the probe information into
1112
    the same order the BIOS uses.
1113
  */
1114
  BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[FlashPointIndex],
1115
                         FlashPointCount);
1116
  return FlashPointCount;
1117
}
1118
 
1119
 
1120
/*
1121
  BusLogic_InitializeProbeInfoList initializes the list of I/O Address and Bus
1122
  Probe Information to be checked for potential BusLogic SCSI Host Adapters by
1123
  interrogating the PCI Configuration Space on PCI machines as well as from the
1124
  list of standard BusLogic MultiMaster ISA I/O Addresses.  By default, if both
1125
  FlashPoint and PCI MultiMaster Host Adapters are present, this driver will
1126
  probe for FlashPoint Host Adapters first unless the BIOS primary disk is
1127
  controlled by the first PCI MultiMaster Host Adapter, in which case
1128
  MultiMaster Host Adapters will be probed first.  The BusLogic Driver Options
1129
  specifications "MultiMasterFirst" and "FlashPointFirst" can be used to force
1130
  a particular probe order.
1131
*/
1132
 
1133
static void BusLogic_InitializeProbeInfoList(BusLogic_HostAdapter_T
1134
                                             *PrototypeHostAdapter)
1135
{
1136
  /*
1137
    If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint
1138
    Host Adapters; otherwise, default to the standard ISA MultiMaster probe.
1139
  */
1140
  if (!BusLogic_ProbeOptions.NoProbePCI && pcibios_present())
1141
    {
1142
      if (BusLogic_ProbeOptions.MultiMasterFirst)
1143
        {
1144
          BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
1145
          BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
1146
        }
1147
      else if (BusLogic_ProbeOptions.FlashPointFirst)
1148
        {
1149
          BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
1150
          BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
1151
        }
1152
      else
1153
        {
1154
          int FlashPointCount =
1155
            BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
1156
          int PCIMultiMasterCount =
1157
            BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
1158
          if (FlashPointCount > 0 && PCIMultiMasterCount > 0)
1159
            {
1160
              BusLogic_ProbeInfo_T *ProbeInfo =
1161
                &BusLogic_ProbeInfoList[FlashPointCount];
1162
              BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
1163
              BusLogic_FetchHostAdapterLocalRAMRequest_T
1164
                FetchHostAdapterLocalRAMRequest;
1165
              BusLogic_BIOSDriveMapByte_T Drive0MapByte;
1166
              while (ProbeInfo->HostAdapterBusType != BusLogic_PCI_Bus)
1167
                ProbeInfo++;
1168
              HostAdapter->IO_Address = ProbeInfo->IO_Address;
1169
              FetchHostAdapterLocalRAMRequest.ByteOffset =
1170
                BusLogic_BIOS_BaseOffset + BusLogic_BIOS_DriveMapOffset + 0;
1171
              FetchHostAdapterLocalRAMRequest.ByteCount =
1172
                sizeof(Drive0MapByte);
1173
              BusLogic_Command(HostAdapter,
1174
                               BusLogic_FetchHostAdapterLocalRAM,
1175
                               &FetchHostAdapterLocalRAMRequest,
1176
                               sizeof(FetchHostAdapterLocalRAMRequest),
1177
                               &Drive0MapByte, sizeof(Drive0MapByte));
1178
              /*
1179
                If the Map Byte for BIOS Drive 0 indicates that BIOS Drive 0
1180
                is controlled by this PCI MultiMaster Host Adapter, then
1181
                reverse the probe order so that MultiMaster Host Adapters are
1182
                probed before FlashPoint Host Adapters.
1183
              */
1184
              if (Drive0MapByte.DiskGeometry !=
1185
                  BusLogic_BIOS_Disk_Not_Installed)
1186
                {
1187
                  BusLogic_ProbeInfo_T
1188
                    SavedProbeInfo[BusLogic_MaxHostAdapters];
1189
                  int MultiMasterCount =
1190
                    BusLogic_ProbeInfoCount - FlashPointCount;
1191
                  memcpy(SavedProbeInfo,
1192
                         BusLogic_ProbeInfoList,
1193
                         BusLogic_ProbeInfoCount
1194
                         * sizeof(BusLogic_ProbeInfo_T));
1195
                  memcpy(&BusLogic_ProbeInfoList[0],
1196
                         &SavedProbeInfo[FlashPointCount],
1197
                         MultiMasterCount * sizeof(BusLogic_ProbeInfo_T));
1198
                  memcpy(&BusLogic_ProbeInfoList[MultiMasterCount],
1199
                         &SavedProbeInfo[0],
1200
                         FlashPointCount * sizeof(BusLogic_ProbeInfo_T));
1201
                }
1202
            }
1203
        }
1204
    }
1205
  else BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter);
1206
}
1207
 
1208
 
1209
#endif  /* CONFIG_PCI */
1210
 
1211
 
1212
/*
1213
  BusLogic_Failure prints a standardized error message, and then returns false.
1214
*/
1215
 
1216
static boolean BusLogic_Failure(BusLogic_HostAdapter_T *HostAdapter,
1217
                                char *ErrorMessage)
1218
{
1219
  BusLogic_AnnounceDriver(HostAdapter);
1220
  if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus)
1221
    {
1222
      BusLogic_Error("While configuring BusLogic PCI Host Adapter at\n",
1223
                     HostAdapter);
1224
      BusLogic_Error("Bus %d Device %d I/O Address 0x%X PCI Address 0x%X:\n",
1225
                     HostAdapter, HostAdapter->Bus, HostAdapter->Device,
1226
                     HostAdapter->IO_Address, HostAdapter->PCI_Address);
1227
    }
1228
  else BusLogic_Error("While configuring BusLogic Host Adapter at "
1229
                      "I/O Address 0x%X:\n", HostAdapter,
1230
                      HostAdapter->IO_Address);
1231
  BusLogic_Error("%s FAILED - DETACHING\n", HostAdapter, ErrorMessage);
1232
  if (BusLogic_CommandFailureReason != NULL)
1233
    BusLogic_Error("ADDITIONAL FAILURE INFO - %s\n", HostAdapter,
1234
                   BusLogic_CommandFailureReason);
1235
  return false;
1236
}
1237
 
1238
 
1239
/*
1240
  BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter.
1241
*/
1242
 
1243
static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
1244
{
1245
  BusLogic_StatusRegister_T StatusRegister;
1246
  BusLogic_InterruptRegister_T InterruptRegister;
1247
  BusLogic_GeometryRegister_T GeometryRegister;
1248
  /*
1249
    FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager.
1250
  */
1251
  if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1252
    {
1253
      FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
1254
      FlashPointInfo->BaseAddress =
1255
        (BusLogic_Base_Address_T) HostAdapter->IO_Address;
1256
      FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel;
1257
      FlashPointInfo->Present = false;
1258
      if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 &&
1259
            FlashPointInfo->Present))
1260
        {
1261
          BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at "
1262
                         "PCI Bus %d Device %d\n", HostAdapter,
1263
                         HostAdapter->Bus, HostAdapter->Device);
1264
          BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, "
1265
                         "but FlashPoint\n", HostAdapter,
1266
                         HostAdapter->IO_Address, HostAdapter->PCI_Address);
1267
          BusLogic_Error("BusLogic: Probe Function failed to validate it.\n",
1268
                         HostAdapter);
1269
          return false;
1270
        }
1271
      if (BusLogic_GlobalOptions.TraceProbe)
1272
        BusLogic_Notice("BusLogic_Probe(0x%X): FlashPoint Found\n",
1273
                        HostAdapter, HostAdapter->IO_Address);
1274
      /*
1275
        Indicate the Host Adapter Probe completed successfully.
1276
      */
1277
      return true;
1278
    }
1279
  /*
1280
    Read the Status, Interrupt, and Geometry Registers to test if there are I/O
1281
    ports that respond, and to check the values to determine if they are from a
1282
    BusLogic Host Adapter.  A nonexistent I/O port will return 0xFF, in which
1283
    case there is definitely no BusLogic Host Adapter at this base I/O Address.
1284
    The test here is a subset of that used by the BusLogic Host Adapter BIOS.
1285
  */
1286
  StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1287
  InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
1288
  GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1289
  if (BusLogic_GlobalOptions.TraceProbe)
1290
    BusLogic_Notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, "
1291
                    "Geometry 0x%02X\n", HostAdapter,
1292
                    HostAdapter->IO_Address, StatusRegister.All,
1293
                    InterruptRegister.All, GeometryRegister.All);
1294
  if (StatusRegister.All == 0 ||
1295
      StatusRegister.Bits.DiagnosticActive ||
1296
      StatusRegister.Bits.CommandParameterRegisterBusy ||
1297
      StatusRegister.Bits.Reserved ||
1298
      StatusRegister.Bits.CommandInvalid ||
1299
      InterruptRegister.Bits.Reserved != 0)
1300
    return false;
1301
  /*
1302
    Check the undocumented Geometry Register to test if there is an I/O port
1303
    that responded.  Adaptec Host Adapters do not implement the Geometry
1304
    Register, so this test helps serve to avoid incorrectly recognizing an
1305
    Adaptec 1542A or 1542B as a BusLogic.  Unfortunately, the Adaptec 1542C
1306
    series does respond to the Geometry Register I/O port, but it will be
1307
    rejected later when the Inquire Extended Setup Information command is
1308
    issued in BusLogic_CheckHostAdapter.  The AMI FastDisk Host Adapter is a
1309
    BusLogic clone that implements the same interface as earlier BusLogic
1310
    Host Adapters, including the undocumented commands, and is therefore
1311
    supported by this driver.  However, the AMI FastDisk always returns 0x00
1312
    upon reading the Geometry Register, so the extended translation option
1313
    should always be left disabled on the AMI FastDisk.
1314
  */
1315
  if (GeometryRegister.All == 0xFF) return false;
1316
  /*
1317
    Indicate the Host Adapter Probe completed successfully.
1318
  */
1319
  return true;
1320
}
1321
 
1322
 
1323
/*
1324
  BusLogic_HardwareResetHostAdapter issues a Hardware Reset to the Host Adapter
1325
  and waits for Host Adapter Diagnostics to complete.  If HardReset is true, a
1326
  Hard Reset is performed which also initiates a SCSI Bus Reset.  Otherwise, a
1327
  Soft Reset is performed which only resets the Host Adapter without forcing a
1328
  SCSI Bus Reset.
1329
*/
1330
 
1331
static boolean BusLogic_HardwareResetHostAdapter(BusLogic_HostAdapter_T
1332
                                                   *HostAdapter,
1333
                                                 boolean HardReset)
1334
{
1335
  BusLogic_StatusRegister_T StatusRegister;
1336
  int TimeoutCounter;
1337
  /*
1338
    FlashPoint Host Adapters are Hard Reset by the FlashPoint SCCB Manager.
1339
  */
1340
  if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1341
    {
1342
      FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
1343
      FlashPointInfo->HostSoftReset = !HardReset;
1344
      FlashPointInfo->ReportDataUnderrun = true;
1345
      HostAdapter->CardHandle =
1346
        FlashPoint_HardwareResetHostAdapter(FlashPointInfo);
1347
      if (HostAdapter->CardHandle == FlashPoint_BadCardHandle) return false;
1348
      /*
1349
        Indicate the Host Adapter Hard Reset completed successfully.
1350
      */
1351
      return true;
1352
    }
1353
  /*
1354
    Issue a Hard Reset or Soft Reset Command to the Host Adapter.  The Host
1355
    Adapter should respond by setting Diagnostic Active in the Status Register.
1356
  */
1357
  if (HardReset)
1358
    BusLogic_HardReset(HostAdapter);
1359
  else BusLogic_SoftReset(HostAdapter);
1360
  /*
1361
    Wait until Diagnostic Active is set in the Status Register.
1362
  */
1363
  TimeoutCounter = 5*10000;
1364
  while (--TimeoutCounter >= 0)
1365
    {
1366
      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1367
      if (StatusRegister.Bits.DiagnosticActive) break;
1368
      udelay(100);
1369
    }
1370
  if (BusLogic_GlobalOptions.TraceHardwareReset)
1371
    BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, "
1372
                    "Status 0x%02X\n", HostAdapter,
1373
                    HostAdapter->IO_Address, StatusRegister.All);
1374
  if (TimeoutCounter < 0) return false;
1375
  /*
1376
    Wait 100 microseconds to allow completion of any initial diagnostic
1377
    activity which might leave the contents of the Status Register
1378
    unpredictable.
1379
  */
1380
  udelay(100);
1381
  /*
1382
    Wait until Diagnostic Active is reset in the Status Register.
1383
  */
1384
  TimeoutCounter = 10*10000;
1385
  while (--TimeoutCounter >= 0)
1386
    {
1387
      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1388
      if (!StatusRegister.Bits.DiagnosticActive) break;
1389
      udelay(100);
1390
    }
1391
  if (BusLogic_GlobalOptions.TraceHardwareReset)
1392
    BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, "
1393
                    "Status 0x%02X\n", HostAdapter,
1394
                    HostAdapter->IO_Address, StatusRegister.All);
1395
  if (TimeoutCounter < 0) return false;
1396
  /*
1397
    Wait until at least one of the Diagnostic Failure, Host Adapter Ready,
1398
    or Data In Register Ready bits is set in the Status Register.
1399
  */
1400
  TimeoutCounter = 10000;
1401
  while (--TimeoutCounter >= 0)
1402
    {
1403
      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1404
      if (StatusRegister.Bits.DiagnosticFailure ||
1405
          StatusRegister.Bits.HostAdapterReady ||
1406
          StatusRegister.Bits.DataInRegisterReady)
1407
        break;
1408
      udelay(100);
1409
    }
1410
  if (BusLogic_GlobalOptions.TraceHardwareReset)
1411
    BusLogic_Notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, "
1412
                    "Status 0x%02X\n", HostAdapter,
1413
                    HostAdapter->IO_Address, StatusRegister.All);
1414
  if (TimeoutCounter < 0) return false;
1415
  /*
1416
    If Diagnostic Failure is set or Host Adapter Ready is reset, then an
1417
    error occurred during the Host Adapter diagnostics.  If Data In Register
1418
    Ready is set, then there is an Error Code available.
1419
  */
1420
  if (StatusRegister.Bits.DiagnosticFailure ||
1421
      !StatusRegister.Bits.HostAdapterReady)
1422
    {
1423
      BusLogic_CommandFailureReason = NULL;
1424
      BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
1425
      BusLogic_Error("HOST ADAPTER STATUS REGISTER = %02X\n",
1426
                     HostAdapter, StatusRegister.All);
1427
      if (StatusRegister.Bits.DataInRegisterReady)
1428
        {
1429
          unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
1430
          BusLogic_Error("HOST ADAPTER ERROR CODE = %d\n",
1431
                         HostAdapter, ErrorCode);
1432
        }
1433
      return false;
1434
    }
1435
  /*
1436
    Indicate the Host Adapter Hard Reset completed successfully.
1437
  */
1438
  return true;
1439
}
1440
 
1441
 
1442
/*
1443
  BusLogic_CheckHostAdapter checks to be sure this really is a BusLogic
1444
  Host Adapter.
1445
*/
1446
 
1447
static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
1448
{
1449
  BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
1450
  BusLogic_RequestedReplyLength_T RequestedReplyLength;
1451
  boolean Result = true;
1452
  /*
1453
    FlashPoint Host Adapters do not require this protection.
1454
  */
1455
  if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
1456
  /*
1457
    Issue the Inquire Extended Setup Information command.  Only genuine
1458
    BusLogic Host Adapters and true clones support this command.  Adaptec 1542C
1459
    series Host Adapters that respond to the Geometry Register I/O port will
1460
    fail this command.
1461
  */
1462
  RequestedReplyLength = sizeof(ExtendedSetupInformation);
1463
  if (BusLogic_Command(HostAdapter,
1464
                       BusLogic_InquireExtendedSetupInformation,
1465
                       &RequestedReplyLength,
1466
                       sizeof(RequestedReplyLength),
1467
                       &ExtendedSetupInformation,
1468
                       sizeof(ExtendedSetupInformation))
1469
      != sizeof(ExtendedSetupInformation))
1470
    Result = false;
1471
  /*
1472
    Provide tracing information if requested and return.
1473
  */
1474
  if (BusLogic_GlobalOptions.TraceProbe)
1475
    BusLogic_Notice("BusLogic_Check(0x%X): MultiMaster %s\n", HostAdapter,
1476
                    HostAdapter->IO_Address, (Result ? "Found" : "Not Found"));
1477
  return Result;
1478
}
1479
 
1480
 
1481
/*
1482
  BusLogic_ReadHostAdapterConfiguration reads the Configuration Information
1483
  from Host Adapter and initializes the Host Adapter structure.
1484
*/
1485
 
1486
static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T
1487
                                                     *HostAdapter)
1488
{
1489
  BusLogic_BoardID_T BoardID;
1490
  BusLogic_Configuration_T Configuration;
1491
  BusLogic_SetupInformation_T SetupInformation;
1492
  BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
1493
  BusLogic_HostAdapterModelNumber_T HostAdapterModelNumber;
1494
  BusLogic_FirmwareVersion3rdDigit_T FirmwareVersion3rdDigit;
1495
  BusLogic_FirmwareVersionLetter_T FirmwareVersionLetter;
1496
  BusLogic_PCIHostAdapterInformation_T PCIHostAdapterInformation;
1497
  BusLogic_FetchHostAdapterLocalRAMRequest_T FetchHostAdapterLocalRAMRequest;
1498
  BusLogic_AutoSCSIData_T AutoSCSIData;
1499
  BusLogic_GeometryRegister_T GeometryRegister;
1500
  BusLogic_RequestedReplyLength_T RequestedReplyLength;
1501
  unsigned char *TargetPointer, Character;
1502
  int TargetID, i;
1503
  /*
1504
    Configuration Information for FlashPoint Host Adapters is provided in the
1505
    FlashPoint_Info structure by the FlashPoint SCCB Manager's Probe Function.
1506
    Initialize fields in the Host Adapter structure from the FlashPoint_Info
1507
    structure.
1508
  */
1509
  if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1510
    {
1511
      FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
1512
      TargetPointer = HostAdapter->ModelName;
1513
      *TargetPointer++ = 'B';
1514
      *TargetPointer++ = 'T';
1515
      *TargetPointer++ = '-';
1516
      for (i = 0; i < sizeof(FlashPointInfo->ModelNumber); i++)
1517
        *TargetPointer++ = FlashPointInfo->ModelNumber[i];
1518
      *TargetPointer++ = '\0';
1519
      strcpy(HostAdapter->FirmwareVersion, FlashPoint_FirmwareVersion);
1520
      HostAdapter->SCSI_ID = FlashPointInfo->SCSI_ID;
1521
      HostAdapter->ExtendedTranslationEnabled =
1522
        FlashPointInfo->ExtendedTranslationEnabled;
1523
      HostAdapter->ParityCheckingEnabled =
1524
        FlashPointInfo->ParityCheckingEnabled;
1525
      HostAdapter->BusResetEnabled = !FlashPointInfo->HostSoftReset;
1526
      HostAdapter->LevelSensitiveInterrupt = true;
1527
      HostAdapter->HostWideSCSI = FlashPointInfo->HostWideSCSI;
1528
      HostAdapter->HostDifferentialSCSI = false;
1529
      HostAdapter->HostSupportsSCAM = true;
1530
      HostAdapter->HostUltraSCSI = true;
1531
      HostAdapter->ExtendedLUNSupport = true;
1532
      HostAdapter->TerminationInfoValid = true;
1533
      HostAdapter->LowByteTerminated = FlashPointInfo->LowByteTerminated;
1534
      HostAdapter->HighByteTerminated = FlashPointInfo->HighByteTerminated;
1535
      HostAdapter->SCAM_Enabled = FlashPointInfo->SCAM_Enabled;
1536
      HostAdapter->SCAM_Level2 = FlashPointInfo->SCAM_Level2;
1537
      HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1538
      HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1539
      HostAdapter->MaxLogicalUnits = 32;
1540
      HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1541
      HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1542
      HostAdapter->DriverQueueDepth = 255;
1543
      HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth;
1544
      HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted;
1545
      HostAdapter->FastPermitted = FlashPointInfo->FastPermitted;
1546
      HostAdapter->UltraPermitted = FlashPointInfo->UltraPermitted;
1547
      HostAdapter->WidePermitted = FlashPointInfo->WidePermitted;
1548
      HostAdapter->DisconnectPermitted = FlashPointInfo->DisconnectPermitted;
1549
      HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1550
      goto Common;
1551
    }
1552
  /*
1553
    Issue the Inquire Board ID command.
1554
  */
1555
  if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0,
1556
                       &BoardID, sizeof(BoardID)) != sizeof(BoardID))
1557
    return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
1558
  /*
1559
    Issue the Inquire Configuration command.
1560
  */
1561
  if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0,
1562
                       &Configuration, sizeof(Configuration))
1563
      != sizeof(Configuration))
1564
    return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
1565
  /*
1566
    Issue the Inquire Setup Information command.
1567
  */
1568
  RequestedReplyLength = sizeof(SetupInformation);
1569
  if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
1570
                       &RequestedReplyLength, sizeof(RequestedReplyLength),
1571
                       &SetupInformation, sizeof(SetupInformation))
1572
      != sizeof(SetupInformation))
1573
    return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
1574
  /*
1575
    Issue the Inquire Extended Setup Information command.
1576
  */
1577
  RequestedReplyLength = sizeof(ExtendedSetupInformation);
1578
  if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation,
1579
                       &RequestedReplyLength, sizeof(RequestedReplyLength),
1580
                       &ExtendedSetupInformation,
1581
                       sizeof(ExtendedSetupInformation))
1582
      != sizeof(ExtendedSetupInformation))
1583
    return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
1584
  /*
1585
    Issue the Inquire Firmware Version 3rd Digit command.
1586
  */
1587
  FirmwareVersion3rdDigit = '\0';
1588
  if (BoardID.FirmwareVersion1stDigit > '0')
1589
    if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit,
1590
                         NULL, 0, &FirmwareVersion3rdDigit,
1591
                         sizeof(FirmwareVersion3rdDigit))
1592
        != sizeof(FirmwareVersion3rdDigit))
1593
      return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
1594
  /*
1595
    Issue the Inquire Host Adapter Model Number command.
1596
  */
1597
  if (ExtendedSetupInformation.BusType == 'A' &&
1598
      BoardID.FirmwareVersion1stDigit == '2')
1599
    /* BusLogic BT-542B ISA 2.xx */
1600
    strcpy(HostAdapterModelNumber, "542B");
1601
  else if (ExtendedSetupInformation.BusType == 'E' &&
1602
           BoardID.FirmwareVersion1stDigit == '2' &&
1603
           (BoardID.FirmwareVersion2ndDigit <= '1' ||
1604
            (BoardID.FirmwareVersion2ndDigit == '2' &&
1605
             FirmwareVersion3rdDigit == '0')))
1606
    /* BusLogic BT-742A EISA 2.1x or 2.20 */
1607
    strcpy(HostAdapterModelNumber, "742A");
1608
  else if (ExtendedSetupInformation.BusType == 'E' &&
1609
           BoardID.FirmwareVersion1stDigit == '0')
1610
    /* AMI FastDisk EISA Series 441 0.x */
1611
    strcpy(HostAdapterModelNumber, "747A");
1612
  else
1613
    {
1614
      RequestedReplyLength = sizeof(HostAdapterModelNumber);
1615
      if (BusLogic_Command(HostAdapter, BusLogic_InquireHostAdapterModelNumber,
1616
                           &RequestedReplyLength, sizeof(RequestedReplyLength),
1617
                           &HostAdapterModelNumber,
1618
                           sizeof(HostAdapterModelNumber))
1619
          != sizeof(HostAdapterModelNumber))
1620
        return BusLogic_Failure(HostAdapter,
1621
                                "INQUIRE HOST ADAPTER MODEL NUMBER");
1622
    }
1623
  /*
1624
    BusLogic MultiMaster Host Adapters can be identified by their model number
1625
    and the major version number of their firmware as follows:
1626
 
1627
    5.xx        BusLogic "W" Series Host Adapters:
1628
                  BT-948/958/958D
1629
    4.xx        BusLogic "C" Series Host Adapters:
1630
                  BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
1631
    3.xx        BusLogic "S" Series Host Adapters:
1632
                  BT-747S/747D/757S/757D/445S/545S/542D
1633
                  BT-542B/742A (revision H)
1634
    2.xx        BusLogic "A" Series Host Adapters:
1635
                  BT-542B/742A (revision G and below)
1636
    0.xx        AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
1637
  */
1638
  /*
1639
    Save the Model Name and Host Adapter Name in the Host Adapter structure.
1640
  */
1641
  TargetPointer = HostAdapter->ModelName;
1642
  *TargetPointer++ = 'B';
1643
  *TargetPointer++ = 'T';
1644
  *TargetPointer++ = '-';
1645
  for (i = 0; i < sizeof(HostAdapterModelNumber); i++)
1646
    {
1647
      Character = HostAdapterModelNumber[i];
1648
      if (Character == ' ' || Character == '\0') break;
1649
      *TargetPointer++ = Character;
1650
    }
1651
  *TargetPointer++ = '\0';
1652
  /*
1653
    Save the Firmware Version in the Host Adapter structure.
1654
  */
1655
  TargetPointer = HostAdapter->FirmwareVersion;
1656
  *TargetPointer++ = BoardID.FirmwareVersion1stDigit;
1657
  *TargetPointer++ = '.';
1658
  *TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
1659
  if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0')
1660
    *TargetPointer++ = FirmwareVersion3rdDigit;
1661
  *TargetPointer = '\0';
1662
  /*
1663
    Issue the Inquire Firmware Version Letter command.
1664
  */
1665
  if (strcmp(HostAdapter->FirmwareVersion, "3.3") >= 0)
1666
    {
1667
      if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter,
1668
                           NULL, 0, &FirmwareVersionLetter,
1669
                           sizeof(FirmwareVersionLetter))
1670
          != sizeof(FirmwareVersionLetter))
1671
        return BusLogic_Failure(HostAdapter,
1672
                                "INQUIRE FIRMWARE VERSION LETTER");
1673
      if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0')
1674
        *TargetPointer++ = FirmwareVersionLetter;
1675
      *TargetPointer = '\0';
1676
    }
1677
  /*
1678
    Save the Host Adapter SCSI ID in the Host Adapter structure.
1679
  */
1680
  HostAdapter->SCSI_ID = Configuration.HostAdapterID;
1681
  /*
1682
    Determine the Bus Type and save it in the Host Adapter structure, determine
1683
    and save the IRQ Channel if necessary, and determine and save the DMA
1684
    Channel for ISA Host Adapters.
1685
  */
1686
  HostAdapter->HostAdapterBusType =
1687
    BusLogic_HostAdapterBusTypes[HostAdapter->ModelName[3] - '4'];
1688
  if (HostAdapter->IRQ_Channel == 0)
1689
    {
1690
      if (Configuration.IRQ_Channel9)
1691
        HostAdapter->IRQ_Channel = 9;
1692
      else if (Configuration.IRQ_Channel10)
1693
        HostAdapter->IRQ_Channel = 10;
1694
      else if (Configuration.IRQ_Channel11)
1695
        HostAdapter->IRQ_Channel = 11;
1696
      else if (Configuration.IRQ_Channel12)
1697
        HostAdapter->IRQ_Channel = 12;
1698
      else if (Configuration.IRQ_Channel14)
1699
        HostAdapter->IRQ_Channel = 14;
1700
      else if (Configuration.IRQ_Channel15)
1701
        HostAdapter->IRQ_Channel = 15;
1702
    }
1703
  if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus)
1704
    {
1705
      if (Configuration.DMA_Channel5)
1706
        HostAdapter->DMA_Channel = 5;
1707
      else if (Configuration.DMA_Channel6)
1708
        HostAdapter->DMA_Channel = 6;
1709
      else if (Configuration.DMA_Channel7)
1710
        HostAdapter->DMA_Channel = 7;
1711
    }
1712
  /*
1713
    Determine whether Extended Translation is enabled and save it in
1714
    the Host Adapter structure.
1715
  */
1716
  GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1717
  HostAdapter->ExtendedTranslationEnabled =
1718
    GeometryRegister.Bits.ExtendedTranslationEnabled;
1719
  /*
1720
    Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide
1721
    SCSI flag, Differential SCSI flag, SCAM Supported flag, and
1722
    Ultra SCSI flag in the Host Adapter structure.
1723
  */
1724
  HostAdapter->HostAdapterScatterGatherLimit =
1725
    ExtendedSetupInformation.ScatterGatherLimit;
1726
  HostAdapter->DriverScatterGatherLimit =
1727
    HostAdapter->HostAdapterScatterGatherLimit;
1728
  if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
1729
    HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1730
  if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupt)
1731
    HostAdapter->LevelSensitiveInterrupt = true;
1732
  HostAdapter->HostWideSCSI = ExtendedSetupInformation.HostWideSCSI;
1733
  HostAdapter->HostDifferentialSCSI =
1734
    ExtendedSetupInformation.HostDifferentialSCSI;
1735
  HostAdapter->HostSupportsSCAM = ExtendedSetupInformation.HostSupportsSCAM;
1736
  HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI;
1737
  /*
1738
    Determine whether Extended LUN Format CCBs are supported and save the
1739
    information in the Host Adapter structure.
1740
  */
1741
  if (HostAdapter->FirmwareVersion[0] == '5' ||
1742
      (HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI))
1743
    HostAdapter->ExtendedLUNSupport = true;
1744
  /*
1745
    Issue the Inquire PCI Host Adapter Information command to read the
1746
    Termination Information from "W" series MultiMaster Host Adapters.
1747
  */
1748
  if (HostAdapter->FirmwareVersion[0] == '5')
1749
    {
1750
      if (BusLogic_Command(HostAdapter,
1751
                           BusLogic_InquirePCIHostAdapterInformation,
1752
                           NULL, 0, &PCIHostAdapterInformation,
1753
                           sizeof(PCIHostAdapterInformation))
1754
          != sizeof(PCIHostAdapterInformation))
1755
        return BusLogic_Failure(HostAdapter,
1756
                                "INQUIRE PCI HOST ADAPTER INFORMATION");
1757
      /*
1758
        Save the Termination Information in the Host Adapter structure.
1759
      */
1760
      if (PCIHostAdapterInformation.GenericInfoValid)
1761
        {
1762
          HostAdapter->TerminationInfoValid = true;
1763
          HostAdapter->LowByteTerminated =
1764
            PCIHostAdapterInformation.LowByteTerminated;
1765
          HostAdapter->HighByteTerminated =
1766
            PCIHostAdapterInformation.HighByteTerminated;
1767
        }
1768
    }
1769
  /*
1770
    Issue the Fetch Host Adapter Local RAM command to read the AutoSCSI data
1771
    from "W" and "C" series MultiMaster Host Adapters.
1772
  */
1773
  if (HostAdapter->FirmwareVersion[0] >= '4')
1774
    {
1775
      FetchHostAdapterLocalRAMRequest.ByteOffset =
1776
        BusLogic_AutoSCSI_BaseOffset;
1777
      FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIData);
1778
      if (BusLogic_Command(HostAdapter,
1779
                           BusLogic_FetchHostAdapterLocalRAM,
1780
                           &FetchHostAdapterLocalRAMRequest,
1781
                           sizeof(FetchHostAdapterLocalRAMRequest),
1782
                           &AutoSCSIData, sizeof(AutoSCSIData))
1783
          != sizeof(AutoSCSIData))
1784
        return BusLogic_Failure(HostAdapter, "FETCH HOST ADAPTER LOCAL RAM");
1785
      /*
1786
        Save the Parity Checking Enabled, Bus Reset Enabled, and Termination
1787
        Information in the Host Adapter structure.
1788
      */
1789
      HostAdapter->ParityCheckingEnabled = AutoSCSIData.ParityCheckingEnabled;
1790
      HostAdapter->BusResetEnabled = AutoSCSIData.BusResetEnabled;
1791
      if (HostAdapter->FirmwareVersion[0] == '4')
1792
        {
1793
          HostAdapter->TerminationInfoValid = true;
1794
          HostAdapter->LowByteTerminated = AutoSCSIData.LowByteTerminated;
1795
          HostAdapter->HighByteTerminated = AutoSCSIData.HighByteTerminated;
1796
        }
1797
      /*
1798
        Save the Wide Permitted, Fast Permitted, Synchronous Permitted,
1799
        Disconnect Permitted, Ultra Permitted, and SCAM Information in the
1800
        Host Adapter structure.
1801
      */
1802
      HostAdapter->WidePermitted = AutoSCSIData.WidePermitted;
1803
      HostAdapter->FastPermitted = AutoSCSIData.FastPermitted;
1804
      HostAdapter->SynchronousPermitted =
1805
        AutoSCSIData.SynchronousPermitted;
1806
      HostAdapter->DisconnectPermitted =
1807
        AutoSCSIData.DisconnectPermitted;
1808
      if (HostAdapter->HostUltraSCSI)
1809
        HostAdapter->UltraPermitted = AutoSCSIData.UltraPermitted;
1810
      if (HostAdapter->HostSupportsSCAM)
1811
        {
1812
          HostAdapter->SCAM_Enabled = AutoSCSIData.SCAM_Enabled;
1813
          HostAdapter->SCAM_Level2 = AutoSCSIData.SCAM_Level2;
1814
        }
1815
    }
1816
  /*
1817
    Initialize fields in the Host Adapter structure for "S" and "A" series
1818
    MultiMaster Host Adapters.
1819
  */
1820
  if (HostAdapter->FirmwareVersion[0] < '4')
1821
    {
1822
      if (SetupInformation.SynchronousInitiationEnabled)
1823
        {
1824
          HostAdapter->SynchronousPermitted = 0xFF;
1825
          if (HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)
1826
            {
1827
              if (ExtendedSetupInformation.Misc.FastOnEISA)
1828
                HostAdapter->FastPermitted = 0xFF;
1829
              if (strcmp(HostAdapter->ModelName, "BT-757") == 0)
1830
                HostAdapter->WidePermitted = 0xFF;
1831
            }
1832
        }
1833
      HostAdapter->DisconnectPermitted = 0xFF;
1834
      HostAdapter->ParityCheckingEnabled =
1835
        SetupInformation.ParityCheckingEnabled;
1836
      HostAdapter->BusResetEnabled = true;
1837
    }
1838
  /*
1839
    Determine the maximum number of Target IDs and Logical Units supported by
1840
    this driver for Wide and Narrow Host Adapters.
1841
  */
1842
  HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1843
  HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8);
1844
  /*
1845
    Select appropriate values for the Mailbox Count, Driver Queue Depth,
1846
    Initial CCBs, and Incremental CCBs variables based on whether or not Strict
1847
    Round Robin Mode is supported.  If Strict Round Robin Mode is supported,
1848
    then there is no performance degradation in using the maximum possible
1849
    number of Outgoing and Incoming Mailboxes and allowing the Tagged and
1850
    Untagged Queue Depths to determine the actual utilization.  If Strict Round
1851
    Robin Mode is not supported, then the Host Adapter must scan all the
1852
    Outgoing Mailboxes whenever an Outgoing Mailbox entry is made, which can
1853
    cause a substantial performance penalty.  The host adapters actually have
1854
    room to store the following number of CCBs internally; that is, they can
1855
    internally queue and manage this many active commands on the SCSI bus
1856
    simultaneously.  Performance measurements demonstrate that the Driver Queue
1857
    Depth should be set to the Mailbox Count, rather than the Host Adapter
1858
    Queue Depth (internal CCB capacity), as it is more efficient to have the
1859
    queued commands waiting in Outgoing Mailboxes if necessary than to block
1860
    the process in the higher levels of the SCSI Subsystem.
1861
 
1862
        192       BT-948/958/958D
1863
        100       BT-946C/956C/956CD/747C/757C/757CD/445C
1864
         50       BT-545C/540CF
1865
         30       BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
1866
  */
1867
  if (HostAdapter->FirmwareVersion[0] == '5')
1868
    HostAdapter->HostAdapterQueueDepth = 192;
1869
  else if (HostAdapter->FirmwareVersion[0] == '4')
1870
    HostAdapter->HostAdapterQueueDepth =
1871
      (HostAdapter->HostAdapterBusType != BusLogic_ISA_Bus ? 100 : 50);
1872
  else HostAdapter->HostAdapterQueueDepth = 30;
1873
  if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0)
1874
    {
1875
      HostAdapter->StrictRoundRobinModeSupport = true;
1876
      HostAdapter->MailboxCount = BusLogic_MaxMailboxes;
1877
    }
1878
  else
1879
    {
1880
      HostAdapter->StrictRoundRobinModeSupport = false;
1881
      HostAdapter->MailboxCount = 32;
1882
    }
1883
  HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount;
1884
  HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1885
  HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1886
  /*
1887
    Tagged Queuing support is available and operates properly on all "W" series
1888
    MultiMaster Host Adapters, on "C" series MultiMaster Host Adapters with
1889
    firmware version 4.22 and above, and on "S" series MultiMaster Host
1890
    Adapters with firmware version 3.35 and above.
1891
  */
1892
  HostAdapter->TaggedQueuingPermitted = 0;
1893
  switch (HostAdapter->FirmwareVersion[0])
1894
    {
1895
    case '5':
1896
      HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1897
      break;
1898
    case '4':
1899
      if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0)
1900
        HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1901
      break;
1902
    case '3':
1903
      if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0)
1904
        HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1905
      break;
1906
    }
1907
  /*
1908
    Determine the Host Adapter BIOS Address if the BIOS is enabled and
1909
    save it in the Host Adapter structure.  The BIOS is disabled if the
1910
    BIOS_Address is 0.
1911
  */
1912
  HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
1913
  /*
1914
    ISA Host Adapters require Bounce Buffers if there is more than 16MB memory.
1915
  */
1916
  if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus &&
1917
      (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1918
    HostAdapter->BounceBuffersRequired = true;
1919
  /*
1920
    BusLogic BT-445S Host Adapters prior to board revision E have a hardware
1921
    bug whereby when the BIOS is enabled, transfers to/from the same address
1922
    range the BIOS occupies modulo 16MB are handled incorrectly.  Only properly
1923
    functioning BT-445S Host Adapters have firmware version 3.37, so require
1924
    that ISA Bounce Buffers be used for the buggy BT-445S models if there is
1925
    more than 16MB memory.
1926
  */
1927
  if (HostAdapter->BIOS_Address > 0 &&
1928
      strcmp(HostAdapter->ModelName, "BT-445S") == 0 &&
1929
      strcmp(HostAdapter->FirmwareVersion, "3.37") < 0 &&
1930
      (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1931
    HostAdapter->BounceBuffersRequired = true;
1932
  /*
1933
    Initialize parameters common to MultiMaster and FlashPoint Host Adapters.
1934
  */
1935
Common:
1936
  /*
1937
    Initialize the Host Adapter Full Model Name from the Model Name.
1938
  */
1939
  strcpy(HostAdapter->FullModelName, "BusLogic ");
1940
  strcat(HostAdapter->FullModelName, HostAdapter->ModelName);
1941
  /*
1942
    Select an appropriate value for the Tagged Queue Depth either from a
1943
    BusLogic Driver Options specification, or based on whether this Host
1944
    Adapter requires that ISA Bounce Buffers be used.  The Tagged Queue Depth
1945
    is left at 0 for automatic determination in BusLogic_SelectQueueDepths.
1946
    Initialize the Untagged Queue Depth.
1947
  */
1948
  for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
1949
    {
1950
      unsigned char QueueDepth = 0;
1951
      if (HostAdapter->DriverOptions != NULL &&
1952
          HostAdapter->DriverOptions->QueueDepth[TargetID] > 0)
1953
        QueueDepth = HostAdapter->DriverOptions->QueueDepth[TargetID];
1954
      else if (HostAdapter->BounceBuffersRequired)
1955
        QueueDepth = BusLogic_TaggedQueueDepthBB;
1956
      HostAdapter->QueueDepth[TargetID] = QueueDepth;
1957
    }
1958
  if (HostAdapter->BounceBuffersRequired)
1959
    HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepthBB;
1960
  else HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth;
1961
  if (HostAdapter->DriverOptions != NULL)
1962
    HostAdapter->CommonQueueDepth =
1963
      HostAdapter->DriverOptions->CommonQueueDepth;
1964
  if (HostAdapter->CommonQueueDepth > 0 &&
1965
      HostAdapter->CommonQueueDepth < HostAdapter->UntaggedQueueDepth)
1966
    HostAdapter->UntaggedQueueDepth = HostAdapter->CommonQueueDepth;
1967
  /*
1968
    Tagged Queuing is only allowed if Disconnect/Reconnect is permitted.
1969
    Therefore, mask the Tagged Queuing Permitted Default bits with the
1970
    Disconnect/Reconnect Permitted bits.
1971
  */
1972
  HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted;
1973
  /*
1974
    Combine the default Tagged Queuing Permitted bits with any BusLogic Driver
1975
    Options Tagged Queuing specification.
1976
  */
1977
  if (HostAdapter->DriverOptions != NULL)
1978
    HostAdapter->TaggedQueuingPermitted =
1979
      (HostAdapter->DriverOptions->TaggedQueuingPermitted &
1980
       HostAdapter->DriverOptions->TaggedQueuingPermittedMask) |
1981
      (HostAdapter->TaggedQueuingPermitted &
1982
       ~HostAdapter->DriverOptions->TaggedQueuingPermittedMask);
1983
  /*
1984
    Select appropriate values for the Error Recovery Strategy array
1985
    either from a BusLogic Driver Options specification, or using
1986
    BusLogic_ErrorRecovery_Default.
1987
  */
1988
  for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
1989
    if (HostAdapter->DriverOptions != NULL)
1990
      HostAdapter->ErrorRecoveryStrategy[TargetID] =
1991
        HostAdapter->DriverOptions->ErrorRecoveryStrategy[TargetID];
1992
    else HostAdapter->ErrorRecoveryStrategy[TargetID] =
1993
           BusLogic_ErrorRecovery_Default;
1994
  /*
1995
    Select an appropriate value for Bus Settle Time either from a BusLogic
1996
    Driver Options specification, or from BusLogic_DefaultBusSettleTime.
1997
  */
1998
  if (HostAdapter->DriverOptions != NULL &&
1999
      HostAdapter->DriverOptions->BusSettleTime > 0)
2000
    HostAdapter->BusSettleTime = HostAdapter->DriverOptions->BusSettleTime;
2001
  else HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
2002
  /*
2003
    Indicate reading the Host Adapter Configuration completed successfully.
2004
  */
2005
  return true;
2006
}
2007
 
2008
 
2009
/*
2010
  BusLogic_ReportHostAdapterConfiguration reports the configuration of
2011
  Host Adapter.
2012
*/
2013
 
2014
static boolean BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T
2015
                                                       *HostAdapter)
2016
{
2017
  unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1;
2018
  unsigned short SynchronousPermitted, FastPermitted;
2019
  unsigned short UltraPermitted, WidePermitted;
2020
  unsigned short DisconnectPermitted, TaggedQueuingPermitted;
2021
  boolean CommonSynchronousNegotiation, CommonTaggedQueueDepth;
2022
  boolean CommonErrorRecovery;
2023
  char SynchronousString[BusLogic_MaxTargetDevices+1];
2024
  char WideString[BusLogic_MaxTargetDevices+1];
2025
  char DisconnectString[BusLogic_MaxTargetDevices+1];
2026
  char TaggedQueuingString[BusLogic_MaxTargetDevices+1];
2027
  char ErrorRecoveryString[BusLogic_MaxTargetDevices+1];
2028
  char *SynchronousMessage = SynchronousString;
2029
  char *WideMessage = WideString;
2030
  char *DisconnectMessage = DisconnectString;
2031
  char *TaggedQueuingMessage = TaggedQueuingString;
2032
  char *ErrorRecoveryMessage = ErrorRecoveryString;
2033
  int TargetID;
2034
  BusLogic_Info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n",
2035
                HostAdapter, HostAdapter->ModelName,
2036
                BusLogic_HostAdapterBusNames[HostAdapter->HostAdapterBusType],
2037
                (HostAdapter->HostWideSCSI ? " Wide" : ""),
2038
                (HostAdapter->HostDifferentialSCSI ? " Differential" : ""),
2039
                (HostAdapter->HostUltraSCSI ? " Ultra" : ""));
2040
  BusLogic_Info("  Firmware Version: %s, I/O Address: 0x%X, "
2041
                "IRQ Channel: %d/%s\n", HostAdapter,
2042
                HostAdapter->FirmwareVersion,
2043
                HostAdapter->IO_Address, HostAdapter->IRQ_Channel,
2044
                (HostAdapter->LevelSensitiveInterrupt ? "Level" : "Edge"));
2045
  if (HostAdapter->HostAdapterBusType != BusLogic_PCI_Bus)
2046
    {
2047
      BusLogic_Info("  DMA Channel: ", HostAdapter);
2048
      if (HostAdapter->DMA_Channel > 0)
2049
        BusLogic_Info("%d, ", HostAdapter, HostAdapter->DMA_Channel);
2050
      else BusLogic_Info("None, ", HostAdapter);
2051
      if (HostAdapter->BIOS_Address > 0)
2052
        BusLogic_Info("BIOS Address: 0x%X, ", HostAdapter,
2053
                      HostAdapter->BIOS_Address);
2054
      else BusLogic_Info("BIOS Address: None, ", HostAdapter);
2055
    }
2056
  else
2057
    {
2058
      BusLogic_Info("  PCI Bus: %d, Device: %d, Address: ",
2059
                    HostAdapter, HostAdapter->Bus, HostAdapter->Device);
2060
      if (HostAdapter->PCI_Address > 0)
2061
        BusLogic_Info("0x%X, ", HostAdapter, HostAdapter->PCI_Address);
2062
      else BusLogic_Info("Unassigned, ", HostAdapter);
2063
    }
2064
  BusLogic_Info("Host Adapter SCSI ID: %d\n", HostAdapter,
2065
                HostAdapter->SCSI_ID);
2066
  BusLogic_Info("  Parity Checking: %s, Extended Translation: %s\n",
2067
                HostAdapter,
2068
                (HostAdapter->ParityCheckingEnabled
2069
                 ? "Enabled" : "Disabled"),
2070
                (HostAdapter->ExtendedTranslationEnabled
2071
                 ? "Enabled" : "Disabled"));
2072
  AllTargetsMask &= ~(1 << HostAdapter->SCSI_ID);
2073
  SynchronousPermitted = HostAdapter->SynchronousPermitted & AllTargetsMask;
2074
  FastPermitted = HostAdapter->FastPermitted & AllTargetsMask;
2075
  UltraPermitted = HostAdapter->UltraPermitted & AllTargetsMask;
2076
  if ((BusLogic_MultiMasterHostAdapterP(HostAdapter) &&
2077
       (HostAdapter->FirmwareVersion[0] >= '4' ||
2078
        HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)) ||
2079
      BusLogic_FlashPointHostAdapterP(HostAdapter))
2080
    {
2081
      CommonSynchronousNegotiation = false;
2082
      if (SynchronousPermitted == 0)
2083
        {
2084
          SynchronousMessage = "Disabled";
2085
          CommonSynchronousNegotiation = true;
2086
        }
2087
      else if (SynchronousPermitted == AllTargetsMask)
2088
        {
2089
          if (FastPermitted == 0)
2090
            {
2091
              SynchronousMessage = "Slow";
2092
              CommonSynchronousNegotiation = true;
2093
            }
2094
          else if (FastPermitted == AllTargetsMask)
2095
            {
2096
              if (UltraPermitted == 0)
2097
                {
2098
                  SynchronousMessage = "Fast";
2099
                  CommonSynchronousNegotiation = true;
2100
                }
2101
              else if (UltraPermitted == AllTargetsMask)
2102
                {
2103
                  SynchronousMessage = "Ultra";
2104
                  CommonSynchronousNegotiation = true;
2105
                }
2106
            }
2107
        }
2108
      if (!CommonSynchronousNegotiation)
2109
        {
2110
          for (TargetID = 0;
2111
               TargetID < HostAdapter->MaxTargetDevices;
2112
               TargetID++)
2113
            SynchronousString[TargetID] =
2114
              ((!(SynchronousPermitted & (1 << TargetID))) ? 'N' :
2115
               (!(FastPermitted & (1 << TargetID)) ? 'S' :
2116
                (!(UltraPermitted & (1 << TargetID)) ? 'F' : 'U')));
2117
          SynchronousString[HostAdapter->SCSI_ID] = '#';
2118
          SynchronousString[HostAdapter->MaxTargetDevices] = '\0';
2119
        }
2120
    }
2121
  else SynchronousMessage =
2122
         (SynchronousPermitted == 0 ? "Disabled" : "Enabled");
2123
  WidePermitted = HostAdapter->WidePermitted & AllTargetsMask;
2124
  if (WidePermitted == 0)
2125
    WideMessage = "Disabled";
2126
  else if (WidePermitted == AllTargetsMask)
2127
    WideMessage = "Enabled";
2128
  else
2129
    {
2130
      for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2131
         WideString[TargetID] =
2132
           ((WidePermitted & (1 << TargetID)) ? 'Y' : 'N');
2133
      WideString[HostAdapter->SCSI_ID] = '#';
2134
      WideString[HostAdapter->MaxTargetDevices] = '\0';
2135
    }
2136
  DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
2137
  if (DisconnectPermitted == 0)
2138
    DisconnectMessage = "Disabled";
2139
  else if (DisconnectPermitted == AllTargetsMask)
2140
    DisconnectMessage = "Enabled";
2141
  else
2142
    {
2143
      for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2144
        DisconnectString[TargetID] =
2145
          ((DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
2146
      DisconnectString[HostAdapter->SCSI_ID] = '#';
2147
      DisconnectString[HostAdapter->MaxTargetDevices] = '\0';
2148
    }
2149
  TaggedQueuingPermitted =
2150
    HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
2151
  if (TaggedQueuingPermitted == 0)
2152
    TaggedQueuingMessage = "Disabled";
2153
  else if (TaggedQueuingPermitted == AllTargetsMask)
2154
    TaggedQueuingMessage = "Enabled";
2155
  else
2156
    {
2157
      for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2158
        TaggedQueuingString[TargetID] =
2159
          ((TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
2160
      TaggedQueuingString[HostAdapter->SCSI_ID] = '#';
2161
      TaggedQueuingString[HostAdapter->MaxTargetDevices] = '\0';
2162
    }
2163
  BusLogic_Info("  Synchronous Negotiation: %s, Wide Negotiation: %s\n",
2164
                HostAdapter, SynchronousMessage, WideMessage);
2165
  BusLogic_Info("  Disconnect/Reconnect: %s, Tagged Queuing: %s\n",
2166
                HostAdapter, DisconnectMessage, TaggedQueuingMessage);
2167
  if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
2168
    {
2169
      BusLogic_Info("  Scatter/Gather Limit: %d of %d segments, "
2170
                    "Mailboxes: %d\n", HostAdapter,
2171
                    HostAdapter->DriverScatterGatherLimit,
2172
                    HostAdapter->HostAdapterScatterGatherLimit,
2173
                    HostAdapter->MailboxCount);
2174
      BusLogic_Info("  Driver Queue Depth: %d, "
2175
                    "Host Adapter Queue Depth: %d\n",
2176
                    HostAdapter, HostAdapter->DriverQueueDepth,
2177
                    HostAdapter->HostAdapterQueueDepth);
2178
    }
2179
  else BusLogic_Info("  Driver Queue Depth: %d, "
2180
                     "Scatter/Gather Limit: %d segments\n",
2181
                     HostAdapter, HostAdapter->DriverQueueDepth,
2182
                     HostAdapter->DriverScatterGatherLimit);
2183
  BusLogic_Info("  Tagged Queue Depth: ", HostAdapter);
2184
  CommonTaggedQueueDepth = true;
2185
  for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2186
    if (HostAdapter->QueueDepth[TargetID] != HostAdapter->QueueDepth[0])
2187
      {
2188
        CommonTaggedQueueDepth = false;
2189
        break;
2190
      }
2191
  if (CommonTaggedQueueDepth)
2192
    {
2193
      if (HostAdapter->QueueDepth[0] > 0)
2194
        BusLogic_Info("%d", HostAdapter, HostAdapter->QueueDepth[0]);
2195
      else BusLogic_Info("Automatic", HostAdapter);
2196
    }
2197
  else BusLogic_Info("Individual", HostAdapter);
2198
  BusLogic_Info(", Untagged Queue Depth: %d\n", HostAdapter,
2199
                HostAdapter->UntaggedQueueDepth);
2200
  CommonErrorRecovery = true;
2201
  for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2202
    if (HostAdapter->ErrorRecoveryStrategy[TargetID] !=
2203
        HostAdapter->ErrorRecoveryStrategy[0])
2204
      {
2205
        CommonErrorRecovery = false;
2206
        break;
2207
      }
2208
  if (CommonErrorRecovery)
2209
    ErrorRecoveryMessage =
2210
      BusLogic_ErrorRecoveryStrategyNames[
2211
        HostAdapter->ErrorRecoveryStrategy[0]];
2212
  else
2213
    {
2214
      for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2215
        ErrorRecoveryString[TargetID] =
2216
          BusLogic_ErrorRecoveryStrategyLetters[
2217
            HostAdapter->ErrorRecoveryStrategy[TargetID]];
2218
      ErrorRecoveryString[HostAdapter->SCSI_ID] = '#';
2219
      ErrorRecoveryString[HostAdapter->MaxTargetDevices] = '\0';
2220
    }
2221
  BusLogic_Info("  Error Recovery Strategy: %s, SCSI Bus Reset: %s\n",
2222
                HostAdapter, ErrorRecoveryMessage,
2223
                (HostAdapter->BusResetEnabled ? "Enabled" : "Disabled"));
2224
  if (HostAdapter->TerminationInfoValid)
2225
    {
2226
      if (HostAdapter->HostWideSCSI)
2227
        BusLogic_Info("  SCSI Bus Termination: %s", HostAdapter,
2228
                      (HostAdapter->LowByteTerminated
2229
                       ? (HostAdapter->HighByteTerminated
2230
                          ? "Both Enabled" : "Low Enabled")
2231
                       : (HostAdapter->HighByteTerminated
2232
                          ? "High Enabled" : "Both Disabled")));
2233
      else BusLogic_Info("  SCSI Bus Termination: %s", HostAdapter,
2234
                         (HostAdapter->LowByteTerminated ?
2235
                          "Enabled" : "Disabled"));
2236
      if (HostAdapter->HostSupportsSCAM)
2237
        BusLogic_Info(", SCAM: %s", HostAdapter,
2238
                      (HostAdapter->SCAM_Enabled
2239
                       ? (HostAdapter->SCAM_Level2
2240
                          ? "Enabled, Level 2" : "Enabled, Level 1")
2241
                       : "Disabled"));
2242
      BusLogic_Info("\n", HostAdapter);
2243
    }
2244
  /*
2245
    Indicate reporting the Host Adapter configuration completed successfully.
2246
  */
2247
  return true;
2248
}
2249
 
2250
 
2251
/*
2252
  BusLogic_AcquireResources acquires the system resources necessary to use
2253
  Host Adapter.
2254
*/
2255
 
2256
static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter)
2257
{
2258
  if (HostAdapter->IRQ_Channel == 0)
2259
    {
2260
      BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n",
2261
                     HostAdapter);
2262
      return false;
2263
    }
2264
  /*
2265
    Acquire shared access to the IRQ Channel.
2266
  */
2267
  if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler,
2268
                  SA_INTERRUPT | SA_SHIRQ,
2269
                  HostAdapter->FullModelName, HostAdapter) < 0)
2270
    {
2271
      BusLogic_Error("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
2272
                     HostAdapter, HostAdapter->IRQ_Channel);
2273
      return false;
2274
    }
2275
  HostAdapter->IRQ_ChannelAcquired = true;
2276
  /*
2277
    Acquire exclusive access to the DMA Channel.
2278
  */
2279
  if (HostAdapter->DMA_Channel > 0)
2280
    {
2281
      if (request_dma(HostAdapter->DMA_Channel,
2282
                      HostAdapter->FullModelName) < 0)
2283
        {
2284
          BusLogic_Error("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n",
2285
                         HostAdapter, HostAdapter->DMA_Channel);
2286
          return false;
2287
        }
2288
      set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
2289
      enable_dma(HostAdapter->DMA_Channel);
2290
      HostAdapter->DMA_ChannelAcquired = true;
2291
    }
2292
  /*
2293
    Indicate the System Resource Acquisition completed successfully,
2294
  */
2295
  return true;
2296
}
2297
 
2298
 
2299
/*
2300
  BusLogic_ReleaseResources releases any system resources previously acquired
2301
  by BusLogic_AcquireResources.
2302
*/
2303
 
2304
static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *HostAdapter)
2305
{
2306
  /*
2307
    Release shared access to the IRQ Channel.
2308
  */
2309
  if (HostAdapter->IRQ_ChannelAcquired)
2310
    free_irq(HostAdapter->IRQ_Channel, HostAdapter);
2311
  /*
2312
    Release exclusive access to the DMA Channel.
2313
  */
2314
  if (HostAdapter->DMA_ChannelAcquired)
2315
    free_dma(HostAdapter->DMA_Channel);
2316
}
2317
 
2318
 
2319
/*
2320
  BusLogic_InitializeHostAdapter initializes Host Adapter.  This is the only
2321
  function called during SCSI Host Adapter detection which modifies the state
2322
  of the Host Adapter from its initial power on or hard reset state.
2323
*/
2324
 
2325
static boolean BusLogic_InitializeHostAdapter(BusLogic_HostAdapter_T
2326
                                              *HostAdapter)
2327
{
2328
  BusLogic_ExtendedMailboxRequest_T ExtendedMailboxRequest;
2329
  BusLogic_RoundRobinModeRequest_T RoundRobinModeRequest;
2330
  BusLogic_SetCCBFormatRequest_T SetCCBFormatRequest;
2331
  int TargetID;
2332
  /*
2333
    Initialize the pointers to the first and last CCBs that are queued for
2334
    completion processing.
2335
  */
2336
  HostAdapter->FirstCompletedCCB = NULL;
2337
  HostAdapter->LastCompletedCCB = NULL;
2338
  /*
2339
    Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active,
2340
    Command Successful Flag, Active Commands, and Commands Since Reset
2341
    for each Target Device.
2342
  */
2343
  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2344
    {
2345
      HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
2346
      HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
2347
      HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
2348
      HostAdapter->ActiveCommands[TargetID] = 0;
2349
      HostAdapter->CommandsSinceReset[TargetID] = 0;
2350
    }
2351
  /*
2352
    FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes.
2353
  */
2354
  if (BusLogic_FlashPointHostAdapterP(HostAdapter)) goto Done;
2355
  /*
2356
    Initialize the Outgoing and Incoming Mailbox pointers.
2357
  */
2358
  HostAdapter->FirstOutgoingMailbox =
2359
    (BusLogic_OutgoingMailbox_T *) HostAdapter->MailboxSpace;
2360
  HostAdapter->LastOutgoingMailbox =
2361
    HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1;
2362
  HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
2363
  HostAdapter->FirstIncomingMailbox =
2364
    (BusLogic_IncomingMailbox_T *) (HostAdapter->LastOutgoingMailbox + 1);
2365
  HostAdapter->LastIncomingMailbox =
2366
    HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1;
2367
  HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
2368
  /*
2369
    Initialize the Outgoing and Incoming Mailbox structures.
2370
  */
2371
  memset(HostAdapter->FirstOutgoingMailbox, 0,
2372
         HostAdapter->MailboxCount * sizeof(BusLogic_OutgoingMailbox_T));
2373
  memset(HostAdapter->FirstIncomingMailbox, 0,
2374
         HostAdapter->MailboxCount * sizeof(BusLogic_IncomingMailbox_T));
2375
  /*
2376
    Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes.
2377
  */
2378
  ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount;
2379
  ExtendedMailboxRequest.BaseMailboxAddress =
2380
    Virtual_to_Bus(HostAdapter->FirstOutgoingMailbox);
2381
  if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox,
2382
                       &ExtendedMailboxRequest,
2383
                       sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
2384
    return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION");
2385
  /*
2386
    Enable Strict Round Robin Mode if supported by the Host Adapter.  In
2387
    Strict Round Robin Mode, the Host Adapter only looks at the next Outgoing
2388
    Mailbox for each new command, rather than scanning through all the
2389
    Outgoing Mailboxes to find any that have new commands in them.  Strict
2390
    Round Robin Mode is significantly more efficient.
2391
  */
2392
  if (HostAdapter->StrictRoundRobinModeSupport)
2393
    {
2394
      RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
2395
      if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode,
2396
                           &RoundRobinModeRequest,
2397
                           sizeof(RoundRobinModeRequest), NULL, 0) < 0)
2398
        return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
2399
    }
2400
  /*
2401
    For Host Adapters that support Extended LUN Format CCBs, issue the Set CCB
2402
    Format command to allow 32 Logical Units per Target Device.
2403
  */
2404
  if (HostAdapter->ExtendedLUNSupport)
2405
    {
2406
      SetCCBFormatRequest = BusLogic_ExtendedLUNFormatCCB;
2407
      if (BusLogic_Command(HostAdapter, BusLogic_SetCCBFormat,
2408
                           &SetCCBFormatRequest, sizeof(SetCCBFormatRequest),
2409
                           NULL, 0) < 0)
2410
        return BusLogic_Failure(HostAdapter, "SET CCB FORMAT");
2411
    }
2412
  /*
2413
    Announce Successful Initialization.
2414
  */
2415
Done:
2416
  if (!HostAdapter->HostAdapterInitialized)
2417
    {
2418
      BusLogic_Info("*** %s Initialized Successfully ***\n",
2419
                    HostAdapter, HostAdapter->FullModelName);
2420
      BusLogic_Info("\n", HostAdapter);
2421
    }
2422
  else BusLogic_Warning("*** %s Initialized Successfully ***\n",
2423
                        HostAdapter, HostAdapter->FullModelName);
2424
  HostAdapter->HostAdapterInitialized = true;
2425
  /*
2426
    Indicate the Host Adapter Initialization completed successfully.
2427
  */
2428
  return true;
2429
}
2430
 
2431
 
2432
/*
2433
  BusLogic_TargetDeviceInquiry inquires about the Target Devices accessible
2434
  through Host Adapter.
2435
*/
2436
 
2437
static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T
2438
                                            *HostAdapter)
2439
{
2440
  BusLogic_InstalledDevices_T InstalledDevices;
2441
  BusLogic_InstalledDevices8_T InstalledDevicesID0to7;
2442
  BusLogic_SetupInformation_T SetupInformation;
2443
  BusLogic_SynchronousPeriod_T SynchronousPeriod;
2444
  BusLogic_RequestedReplyLength_T RequestedReplyLength;
2445
  int TargetID;
2446
  /*
2447
    Wait a few seconds between the Host Adapter Hard Reset which initiates
2448
    a SCSI Bus Reset and issuing any SCSI Commands.  Some SCSI devices get
2449
    confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
2450
  */
2451
  BusLogic_Delay(HostAdapter->BusSettleTime);
2452
  /*
2453
    FlashPoint Host Adapters do not provide for Target Device Inquiry.
2454
  */
2455
  if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
2456
  /*
2457
    Inhibit the Target Device Inquiry if requested.
2458
  */
2459
  if (HostAdapter->DriverOptions != NULL &&
2460
      HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
2461
    return true;
2462
  /*
2463
    Issue the Inquire Target Devices command for host adapters with firmware
2464
    version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command
2465
    for older host adapters.  This is necessary to force Synchronous Transfer
2466
    Negotiation so that the Inquire Setup Information and Inquire Synchronous
2467
    Period commands will return valid data.  The Inquire Target Devices command
2468
    is preferable to Inquire Installed Devices ID 0 to 7 since it only probes
2469
    Logical Unit 0 of each Target Device.
2470
  */
2471
  if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0)
2472
    {
2473
      if (BusLogic_Command(HostAdapter, BusLogic_InquireTargetDevices, NULL, 0,
2474
                           &InstalledDevices, sizeof(InstalledDevices))
2475
          != sizeof(InstalledDevices))
2476
        return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES");
2477
      for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2478
        HostAdapter->TargetFlags[TargetID].TargetExists =
2479
          (InstalledDevices & (1 << TargetID) ? true : false);
2480
    }
2481
  else
2482
    {
2483
      if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7,
2484
                           NULL, 0, &InstalledDevicesID0to7,
2485
                           sizeof(InstalledDevicesID0to7))
2486
          != sizeof(InstalledDevicesID0to7))
2487
        return BusLogic_Failure(HostAdapter,
2488
                                "INQUIRE INSTALLED DEVICES ID 0 TO 7");
2489
      for (TargetID = 0; TargetID < 8; TargetID++)
2490
        HostAdapter->TargetFlags[TargetID].TargetExists =
2491
          (InstalledDevicesID0to7[TargetID] != 0 ? true : false);
2492
    }
2493
  /*
2494
    Issue the Inquire Setup Information command.
2495
  */
2496
  RequestedReplyLength = sizeof(SetupInformation);
2497
  if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
2498
                       &RequestedReplyLength, sizeof(RequestedReplyLength),
2499
                       &SetupInformation, sizeof(SetupInformation))
2500
      != sizeof(SetupInformation))
2501
    return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
2502
  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2503
      HostAdapter->SynchronousOffset[TargetID] =
2504
        (TargetID < 8
2505
         ? SetupInformation.SynchronousValuesID0to7[TargetID].Offset
2506
         : SetupInformation.SynchronousValuesID8to15[TargetID-8].Offset);
2507
  if (strcmp(HostAdapter->FirmwareVersion, "5.06L") >= 0)
2508
    for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2509
      HostAdapter->TargetFlags[TargetID].WideTransfersActive =
2510
        (TargetID < 8
2511
         ? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID)
2512
            ? true : false)
2513
         : (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID-8))
2514
            ? true : false));
2515
  /*
2516
    Issue the Inquire Synchronous Period command.
2517
  */
2518
  if (HostAdapter->FirmwareVersion[0] >= '3')
2519
    {
2520
      RequestedReplyLength = sizeof(SynchronousPeriod);
2521
      if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod,
2522
                           &RequestedReplyLength, sizeof(RequestedReplyLength),
2523
                           &SynchronousPeriod, sizeof(SynchronousPeriod))
2524
          != sizeof(SynchronousPeriod))
2525
        return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
2526
      for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2527
        HostAdapter->SynchronousPeriod[TargetID] = SynchronousPeriod[TargetID];
2528
    }
2529
  else
2530
    for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2531
      if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
2532
        HostAdapter->SynchronousPeriod[TargetID] =
2533
          20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
2534
                                   .TransferPeriod;
2535
  /*
2536
    Indicate the Target Device Inquiry completed successfully.
2537
  */
2538
  return true;
2539
}
2540
 
2541
 
2542
/*
2543
  BusLogic_ReportTargetDeviceInfo reports about the Target Devices accessible
2544
  through Host Adapter.
2545
*/
2546
 
2547
static void BusLogic_ReportTargetDeviceInfo(BusLogic_HostAdapter_T
2548
                                            *HostAdapter)
2549
{
2550
  int TargetID;
2551
  /*
2552
    Inhibit the Target Device Inquiry and Reporting if requested.
2553
  */
2554
  if (BusLogic_MultiMasterHostAdapterP(HostAdapter) &&
2555
      HostAdapter->DriverOptions != NULL &&
2556
      HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
2557
    return;
2558
  /*
2559
    Report on the Target Devices found.
2560
  */
2561
  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2562
    {
2563
      BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
2564
      if (TargetFlags->TargetExists && !TargetFlags->TargetInfoReported)
2565
        {
2566
          int SynchronousTransferRate = 0;
2567
          if (BusLogic_FlashPointHostAdapterP(HostAdapter))
2568
            {
2569
              boolean WideTransfersActive;
2570
              FlashPoint_InquireTargetInfo(
2571
                HostAdapter->CardHandle, TargetID,
2572
                &HostAdapter->SynchronousPeriod[TargetID],
2573
                &HostAdapter->SynchronousOffset[TargetID],
2574
                &WideTransfersActive);
2575
              TargetFlags->WideTransfersActive = WideTransfersActive;
2576
            }
2577
          else if (TargetFlags->WideTransfersSupported &&
2578
                   (HostAdapter->WidePermitted & (1 << TargetID)) &&
2579
                   strcmp(HostAdapter->FirmwareVersion, "5.06L") < 0)
2580
            TargetFlags->WideTransfersActive = true;
2581
          if (HostAdapter->SynchronousPeriod[TargetID] > 0)
2582
            SynchronousTransferRate =
2583
              100000 / HostAdapter->SynchronousPeriod[TargetID];
2584
          if (TargetFlags->WideTransfersActive)
2585
            SynchronousTransferRate <<= 1;
2586
          if (SynchronousTransferRate >= 9950)
2587
            {
2588
              SynchronousTransferRate = (SynchronousTransferRate + 50) / 100;
2589
              BusLogic_Info("Target %d: Queue Depth %d, %sSynchronous at "
2590
                            "%d.%01d MB/sec, offset %d\n",
2591
                            HostAdapter, TargetID,
2592
                            HostAdapter->QueueDepth[TargetID],
2593
                            (TargetFlags->WideTransfersActive ? "Wide " : ""),
2594
                            SynchronousTransferRate / 10,
2595
                            SynchronousTransferRate % 10,
2596
                            HostAdapter->SynchronousOffset[TargetID]);
2597
            }
2598
          else if (SynchronousTransferRate > 0)
2599
            {
2600
              SynchronousTransferRate = (SynchronousTransferRate + 5) / 10;
2601
              BusLogic_Info("Target %d: Queue Depth %d, %sSynchronous at "
2602
                            "%d.%02d MB/sec, offset %d\n",
2603
                            HostAdapter, TargetID,
2604
                            HostAdapter->QueueDepth[TargetID],
2605
                            (TargetFlags->WideTransfersActive ? "Wide " : ""),
2606
                            SynchronousTransferRate / 100,
2607
                            SynchronousTransferRate % 100,
2608
                            HostAdapter->SynchronousOffset[TargetID]);
2609
            }
2610
          else BusLogic_Info("Target %d: Queue Depth %d, Asynchronous\n",
2611
                             HostAdapter, TargetID,
2612
                             HostAdapter->QueueDepth[TargetID]);
2613
          TargetFlags->TargetInfoReported = true;
2614
        }
2615
    }
2616
}
2617
 
2618
 
2619
/*
2620
  BusLogic_InitializeHostStructure initializes the fields in the SCSI Host
2621
  structure.  The base, io_port, n_io_ports, irq, and dma_channel fields in the
2622
  SCSI Host structure are intentionally left uninitialized, as this driver
2623
  handles acquisition and release of these resources explicitly, as well as
2624
  ensuring exclusive access to the Host Adapter hardware and data structures
2625
  through explicit acquisition and release of the Host Adapter's Lock.
2626
*/
2627
 
2628
static void BusLogic_InitializeHostStructure(BusLogic_HostAdapter_T
2629
                                               *HostAdapter,
2630
                                             SCSI_Host_T *Host)
2631
{
2632
  Host->max_id = HostAdapter->MaxTargetDevices;
2633
  Host->max_lun = HostAdapter->MaxLogicalUnits;
2634
  Host->max_channel = 0;
2635
  Host->unique_id = HostAdapter->IO_Address;
2636
  Host->this_id = HostAdapter->SCSI_ID;
2637
  Host->can_queue = HostAdapter->DriverQueueDepth;
2638
  Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
2639
  Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
2640
  Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth;
2641
}
2642
 
2643
 
2644
/*
2645
  BusLogic_SelectQueueDepths selects Queue Depths for each Target Device based
2646
  on the Host Adapter's Total Queue Depth and the number, type, speed, and
2647
  capabilities of the Target Devices.  When called for the last Host Adapter,
2648
  it reports on the Target Device Information for all BusLogic Host Adapters
2649
  since all the Target Devices have now been probed.
2650
*/
2651
 
2652
static void BusLogic_SelectQueueDepths(SCSI_Host_T *Host,
2653
                                       SCSI_Device_T *DeviceList)
2654
{
2655
  BusLogic_HostAdapter_T *HostAdapter =
2656
    (BusLogic_HostAdapter_T *) Host->hostdata;
2657
  int TaggedDeviceCount = 0, AutomaticTaggedDeviceCount = 0;
2658
  int UntaggedDeviceCount = 0, AutomaticTaggedQueueDepth = 0;
2659
  int AllocatedQueueDepth = 0;
2660
  SCSI_Device_T *Device;
2661
  int TargetID;
2662
  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2663
    if (HostAdapter->TargetFlags[TargetID].TargetExists)
2664
      {
2665
        int QueueDepth = HostAdapter->QueueDepth[TargetID];
2666
        if (HostAdapter->TargetFlags[TargetID].TaggedQueuingSupported &&
2667
            (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
2668
          {
2669
            TaggedDeviceCount++;
2670
            if (QueueDepth == 0) AutomaticTaggedDeviceCount++;
2671
          }
2672
        else
2673
          {
2674
            UntaggedDeviceCount++;
2675
            if (QueueDepth == 0 ||
2676
                QueueDepth > HostAdapter->UntaggedQueueDepth)
2677
              {
2678
                QueueDepth = HostAdapter->UntaggedQueueDepth;
2679
                HostAdapter->QueueDepth[TargetID] = QueueDepth;
2680
              }
2681
          }
2682
        AllocatedQueueDepth += QueueDepth;
2683
        if (QueueDepth == 1)
2684
          HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
2685
      }
2686
  HostAdapter->TargetDeviceCount = TaggedDeviceCount + UntaggedDeviceCount;
2687
  if (AutomaticTaggedDeviceCount > 0)
2688
    {
2689
      AutomaticTaggedQueueDepth =
2690
        (HostAdapter->HostAdapterQueueDepth - AllocatedQueueDepth)
2691
        / AutomaticTaggedDeviceCount;
2692
      if (AutomaticTaggedQueueDepth > BusLogic_MaxAutomaticTaggedQueueDepth)
2693
        AutomaticTaggedQueueDepth = BusLogic_MaxAutomaticTaggedQueueDepth;
2694
      if (AutomaticTaggedQueueDepth < BusLogic_MinAutomaticTaggedQueueDepth)
2695
        AutomaticTaggedQueueDepth = BusLogic_MinAutomaticTaggedQueueDepth;
2696
      for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2697
        if (HostAdapter->TargetFlags[TargetID].TargetExists &&
2698
            HostAdapter->QueueDepth[TargetID] == 0)
2699
          {
2700
            AllocatedQueueDepth += AutomaticTaggedQueueDepth;
2701
            HostAdapter->QueueDepth[TargetID] = AutomaticTaggedQueueDepth;
2702
          }
2703
    }
2704
  for (Device = DeviceList; Device != NULL; Device = Device->next)
2705
    if (Device->host == Host)
2706
      Device->queue_depth = HostAdapter->QueueDepth[Device->id];
2707
  /* Allocate an extra CCB for each Target Device for a Bus Device Reset. */
2708
  AllocatedQueueDepth += HostAdapter->TargetDeviceCount;
2709
  if (AllocatedQueueDepth > HostAdapter->DriverQueueDepth)
2710
    AllocatedQueueDepth = HostAdapter->DriverQueueDepth;
2711
  BusLogic_CreateAdditionalCCBs(HostAdapter,
2712
                                AllocatedQueueDepth
2713
                                - HostAdapter->AllocatedCCBs,
2714
                                false);
2715
  if (HostAdapter == BusLogic_LastRegisteredHostAdapter)
2716
    for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
2717
         HostAdapter != NULL;
2718
         HostAdapter = HostAdapter->Next)
2719
      BusLogic_ReportTargetDeviceInfo(HostAdapter);
2720
}
2721
 
2722
 
2723
/*
2724
  BusLogic_DetectHostAdapter probes for BusLogic Host Adapters at the standard
2725
  I/O Addresses where they may be located, initializing, registering, and
2726
  reporting the configuration of each BusLogic Host Adapter it finds.  It
2727
  returns the number of BusLogic Host Adapters successfully initialized and
2728
  registered.
2729
*/
2730
 
2731
int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate)
2732
{
2733
  int BusLogicHostAdapterCount = 0, DriverOptionsIndex = 0, ProbeIndex;
2734
  BusLogic_HostAdapter_T *PrototypeHostAdapter;
2735
  if (BusLogic_ProbeOptions.NoProbe) return 0;
2736
  BusLogic_ProbeInfoList = (BusLogic_ProbeInfo_T *)
2737
    kmalloc(BusLogic_MaxHostAdapters * sizeof(BusLogic_ProbeInfo_T),
2738
            GFP_ATOMIC);
2739
  if (BusLogic_ProbeInfoList == NULL)
2740
    {
2741
      BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL);
2742
      return 0;
2743
    }
2744
  memset(BusLogic_ProbeInfoList, 0,
2745
         BusLogic_MaxHostAdapters * sizeof(BusLogic_ProbeInfo_T));
2746
  PrototypeHostAdapter = (BusLogic_HostAdapter_T *)
2747
    kmalloc(sizeof(BusLogic_HostAdapter_T), GFP_ATOMIC);
2748
  if (PrototypeHostAdapter == NULL)
2749
    {
2750
      kfree(BusLogic_ProbeInfoList);
2751
      BusLogic_Error("BusLogic: Unable to allocate Prototype "
2752
                     "Host Adapter\n", NULL);
2753
      return 0;
2754
    }
2755
  memset(PrototypeHostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
2756
  if (BusLogic_Options != NULL)
2757
    BusLogic_ParseDriverOptions(BusLogic_Options);
2758
  BusLogic_InitializeProbeInfoList(PrototypeHostAdapter);
2759
  for (ProbeIndex = 0; ProbeIndex < BusLogic_ProbeInfoCount; ProbeIndex++)
2760
    {
2761
      BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[ProbeIndex];
2762
      BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
2763
      SCSI_Host_T *Host;
2764
      if (ProbeInfo->IO_Address == 0) continue;
2765
      memset(HostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
2766
      HostAdapter->HostAdapterType = ProbeInfo->HostAdapterType;
2767
      HostAdapter->HostAdapterBusType = ProbeInfo->HostAdapterBusType;
2768
      HostAdapter->IO_Address = ProbeInfo->IO_Address;
2769
      HostAdapter->PCI_Address = ProbeInfo->PCI_Address;
2770
      HostAdapter->Bus = ProbeInfo->Bus;
2771
      HostAdapter->Device = ProbeInfo->Device;
2772
      HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel;
2773
      HostAdapter->AddressCount =
2774
        BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType];
2775
      /*
2776
        Probe the Host Adapter.  If unsuccessful, abort further initialization.
2777
      */
2778
      if (!BusLogic_ProbeHostAdapter(HostAdapter)) continue;
2779
      /*
2780
        Hard Reset the Host Adapter.  If unsuccessful, abort further
2781
        initialization.
2782
      */
2783
      if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) continue;
2784
      /*
2785
        Check the Host Adapter.  If unsuccessful, abort further initialization.
2786
      */
2787
      if (!BusLogic_CheckHostAdapter(HostAdapter)) continue;
2788
      /*
2789
        Initialize the Driver Options field if provided.
2790
      */
2791
      if (DriverOptionsIndex < BusLogic_DriverOptionsCount)
2792
        HostAdapter->DriverOptions =
2793
          &BusLogic_DriverOptions[DriverOptionsIndex++];
2794
      /*
2795
        Announce the Driver Version and Date, Author's Name, Copyright Notice,
2796
        and Electronic Mail Address.
2797
      */
2798
      BusLogic_AnnounceDriver(HostAdapter);
2799
      /*
2800
        Register usage of the I/O Address range.  From this point onward, any
2801
        failure will be assumed to be due to a problem with the Host Adapter,
2802
        rather than due to having mistakenly identified this port as belonging
2803
        to a BusLogic Host Adapter.  The I/O Address range will not be
2804
        released, thereby preventing it from being incorrectly identified as
2805
        any other type of Host Adapter.
2806
      */
2807
      request_region(HostAdapter->IO_Address, HostAdapter->AddressCount,
2808
                     "BusLogic");
2809
      /*
2810
        Register the SCSI Host structure.
2811
      */
2812
      Host = scsi_register(HostTemplate, sizeof(BusLogic_HostAdapter_T));
2813
      HostAdapter = (BusLogic_HostAdapter_T *) Host->hostdata;
2814
      memcpy(HostAdapter, PrototypeHostAdapter, sizeof(BusLogic_HostAdapter_T));
2815
      HostAdapter->SCSI_Host = Host;
2816
      HostAdapter->HostNumber = Host->host_no;
2817
      Host->select_queue_depths = BusLogic_SelectQueueDepths;
2818
      /*
2819
        Add Host Adapter to the end of the list of registered BusLogic
2820
        Host Adapters.
2821
      */
2822
      BusLogic_RegisterHostAdapter(HostAdapter);
2823
      /*
2824
        Read the Host Adapter Configuration, Configure the Host Adapter,
2825
        Acquire the System Resources necessary to use the Host Adapter, then
2826
        Create the Initial CCBs, Initialize the Host Adapter, and finally
2827
        perform Target Device Inquiry.
2828
      */
2829
      if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
2830
          BusLogic_ReportHostAdapterConfiguration(HostAdapter) &&
2831
          BusLogic_AcquireResources(HostAdapter) &&
2832
          BusLogic_CreateInitialCCBs(HostAdapter) &&
2833
          BusLogic_InitializeHostAdapter(HostAdapter) &&
2834
          BusLogic_TargetDeviceInquiry(HostAdapter))
2835
        {
2836
          /*
2837
            Initialization has been completed successfully.  Release and
2838
            re-register usage of the I/O Address range so that the Model
2839
            Name of the Host Adapter will appear, and initialize the SCSI
2840
            Host structure.
2841
          */
2842
          release_region(HostAdapter->IO_Address,
2843
                         HostAdapter->AddressCount);
2844
          request_region(HostAdapter->IO_Address,
2845
                         HostAdapter->AddressCount,
2846
                         HostAdapter->FullModelName);
2847
          BusLogic_InitializeHostStructure(HostAdapter, Host);
2848
          BusLogicHostAdapterCount++;
2849
        }
2850
      else
2851
        {
2852
          /*
2853
            An error occurred during Host Adapter Configuration Querying, Host
2854
            Adapter Configuration, Resource Acquisition, CCB Creation, Host
2855
            Adapter Initialization, or Target Device Inquiry, so remove Host
2856
            Adapter from the list of registered BusLogic Host Adapters, destroy
2857
            the CCBs, Release the System Resources, and Unregister the SCSI
2858
            Host.
2859
          */
2860
          BusLogic_DestroyCCBs(HostAdapter);
2861
          BusLogic_ReleaseResources(HostAdapter);
2862
          BusLogic_UnregisterHostAdapter(HostAdapter);
2863
          scsi_unregister(Host);
2864
        }
2865
    }
2866
  kfree(PrototypeHostAdapter);
2867
  kfree(BusLogic_ProbeInfoList);
2868
  BusLogic_ProbeInfoList = NULL;
2869
  return BusLogicHostAdapterCount;
2870
}
2871
 
2872
 
2873
/*
2874
  BusLogic_ReleaseHostAdapter releases all resources previously acquired to
2875
  support a specific Host Adapter, including the I/O Address range, and
2876
  unregisters the BusLogic Host Adapter.
2877
*/
2878
 
2879
int BusLogic_ReleaseHostAdapter(SCSI_Host_T *Host)
2880
{
2881
  BusLogic_HostAdapter_T *HostAdapter =
2882
    (BusLogic_HostAdapter_T *) Host->hostdata;
2883
  /*
2884
    FlashPoint Host Adapters must first be released by the FlashPoint
2885
    SCCB Manager.
2886
  */
2887
  if (BusLogic_FlashPointHostAdapterP(HostAdapter))
2888
    FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle);
2889
  /*
2890
    Destroy the CCBs and release any system resources acquired to
2891
    support Host Adapter.
2892
  */
2893
  BusLogic_DestroyCCBs(HostAdapter);
2894
  BusLogic_ReleaseResources(HostAdapter);
2895
  /*
2896
    Release usage of the I/O Address range.
2897
  */
2898
  release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2899
  /*
2900
    Remove Host Adapter from the list of registered BusLogic Host Adapters.
2901
  */
2902
  BusLogic_UnregisterHostAdapter(HostAdapter);
2903
  return 0;
2904
}
2905
 
2906
 
2907
/*
2908
  BusLogic_QueueCompletedCCB queues CCB for completion processing.
2909
*/
2910
 
2911
static void BusLogic_QueueCompletedCCB(BusLogic_CCB_T *CCB)
2912
{
2913
  BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
2914
  CCB->Status = BusLogic_CCB_Completed;
2915
  CCB->Next = NULL;
2916
  if (HostAdapter->FirstCompletedCCB == NULL)
2917
    {
2918
      HostAdapter->FirstCompletedCCB = CCB;
2919
      HostAdapter->LastCompletedCCB = CCB;
2920
    }
2921
  else
2922
    {
2923
      HostAdapter->LastCompletedCCB->Next = CCB;
2924
      HostAdapter->LastCompletedCCB = CCB;
2925
    }
2926
  HostAdapter->ActiveCommands[CCB->TargetID]--;
2927
}
2928
 
2929
 
2930
/*
2931
  BusLogic_ComputeResultCode computes a SCSI Subsystem Result Code from
2932
  the Host Adapter Status and Target Device Status.
2933
*/
2934
 
2935
static int BusLogic_ComputeResultCode(BusLogic_HostAdapter_T *HostAdapter,
2936
                                      BusLogic_HostAdapterStatus_T
2937
                                        HostAdapterStatus,
2938
                                      BusLogic_TargetDeviceStatus_T
2939
                                        TargetDeviceStatus)
2940
{
2941
  int HostStatus;
2942
  switch (HostAdapterStatus)
2943
    {
2944
    case BusLogic_CommandCompletedNormally:
2945
    case BusLogic_LinkedCommandCompleted:
2946
    case BusLogic_LinkedCommandCompletedWithFlag:
2947
      HostStatus = DID_OK;
2948
      break;
2949
    case BusLogic_SCSISelectionTimeout:
2950
      HostStatus = DID_TIME_OUT;
2951
      break;
2952
    case BusLogic_InvalidOutgoingMailboxActionCode:
2953
    case BusLogic_InvalidCommandOperationCode:
2954
    case BusLogic_InvalidCommandParameter:
2955
      BusLogic_Warning("BusLogic Driver Protocol Error 0x%02X\n",
2956
                       HostAdapter, HostAdapterStatus);
2957
    case BusLogic_DataUnderRun:
2958
    case BusLogic_DataOverRun:
2959
    case BusLogic_UnexpectedBusFree:
2960
    case BusLogic_LinkedCCBhasInvalidLUN:
2961
    case BusLogic_AutoRequestSenseFailed:
2962
    case BusLogic_TaggedQueuingMessageRejected:
2963
    case BusLogic_UnsupportedMessageReceived:
2964
    case BusLogic_HostAdapterHardwareFailed:
2965
    case BusLogic_TargetDeviceReconnectedImproperly:
2966
    case BusLogic_AbortQueueGenerated:
2967
    case BusLogic_HostAdapterSoftwareError:
2968
    case BusLogic_HostAdapterHardwareTimeoutError:
2969
    case BusLogic_SCSIParityErrorDetected:
2970
      HostStatus = DID_ERROR;
2971
      break;
2972
    case BusLogic_InvalidBusPhaseRequested:
2973
    case BusLogic_TargetFailedResponseToATN:
2974
    case BusLogic_HostAdapterAssertedRST:
2975
    case BusLogic_OtherDeviceAssertedRST:
2976
    case BusLogic_HostAdapterAssertedBusDeviceReset:
2977
      HostStatus = DID_RESET;
2978
      break;
2979
    default:
2980
      BusLogic_Warning("Unknown Host Adapter Status 0x%02X\n",
2981
                       HostAdapter, HostAdapterStatus);
2982
      HostStatus = DID_ERROR;
2983
      break;
2984
    }
2985
  return (HostStatus << 16) | TargetDeviceStatus;
2986
}
2987
 
2988
 
2989
/*
2990
  BusLogic_ScanIncomingMailboxes scans the Incoming Mailboxes saving any
2991
  Incoming Mailbox entries for completion processing.
2992
*/
2993
 
2994
static void BusLogic_ScanIncomingMailboxes(BusLogic_HostAdapter_T *HostAdapter)
2995
{
2996
  /*
2997
    Scan through the Incoming Mailboxes in Strict Round Robin fashion, saving
2998
    any completed CCBs for further processing.  It is essential that for each
2999
    CCB and SCSI Command issued, command completion processing is performed
3000
    exactly once.  Therefore, only Incoming Mailboxes with completion code
3001
    Command Completed Without Error, Command Completed With Error, or Command
3002
    Aborted At Host Request are saved for completion processing.  When an
3003
    Incoming Mailbox has a completion code of Aborted Command Not Found, the
3004
    CCB had already completed or been aborted before the current Abort request
3005
    was processed, and so completion processing has already occurred and no
3006
    further action should be taken.
3007
  */
3008
  BusLogic_IncomingMailbox_T *NextIncomingMailbox =
3009
    HostAdapter->NextIncomingMailbox;
3010
  BusLogic_CompletionCode_T CompletionCode;
3011
  while ((CompletionCode = NextIncomingMailbox->CompletionCode) !=
3012
         BusLogic_IncomingMailboxFree)
3013
    {
3014
      BusLogic_CCB_T *CCB = (BusLogic_CCB_T *)
3015
        Bus_to_Virtual(NextIncomingMailbox->CCB);
3016
      if (CompletionCode != BusLogic_AbortedCommandNotFound)
3017
        {
3018
          if (CCB->Status == BusLogic_CCB_Active ||
3019
              CCB->Status == BusLogic_CCB_Reset)
3020
            {
3021
              /*
3022
                Save the Completion Code for this CCB and queue the CCB
3023
                for completion processing.
3024
              */
3025
              CCB->CompletionCode = CompletionCode;
3026
              BusLogic_QueueCompletedCCB(CCB);
3027
            }
3028
          else
3029
            {
3030
              /*
3031
                If a CCB ever appears in an Incoming Mailbox and is not marked
3032
                as status Active or Reset, then there is most likely a bug in
3033
                the Host Adapter firmware.
3034
              */
3035
              BusLogic_Warning("Illegal CCB #%ld status %d in "
3036
                               "Incoming Mailbox\n", HostAdapter,
3037
                               CCB->SerialNumber, CCB->Status);
3038
            }
3039
        }
3040
      NextIncomingMailbox->CompletionCode = BusLogic_IncomingMailboxFree;
3041
      if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
3042
        NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
3043
    }
3044
  HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
3045
}
3046
 
3047
 
3048
/*
3049
  BusLogic_ProcessCompletedCCBs iterates over the completed CCBs for Host
3050
  Adapter setting the SCSI Command Result Codes, deallocating the CCBs, and
3051
  calling the SCSI Subsystem Completion Routines.  The Host Adapter's Lock
3052
  should already have been acquired by the caller.
3053
*/
3054
 
3055
static void BusLogic_ProcessCompletedCCBs(BusLogic_HostAdapter_T *HostAdapter)
3056
{
3057
  if (HostAdapter->ProcessCompletedCCBsActive) return;
3058
  HostAdapter->ProcessCompletedCCBsActive = true;
3059
  while (HostAdapter->FirstCompletedCCB != NULL)
3060
    {
3061
      BusLogic_CCB_T *CCB = HostAdapter->FirstCompletedCCB;
3062
      SCSI_Command_T *Command = CCB->Command;
3063
      HostAdapter->FirstCompletedCCB = CCB->Next;
3064
      if (HostAdapter->FirstCompletedCCB == NULL)
3065
        HostAdapter->LastCompletedCCB = NULL;
3066
      /*
3067
        Process the Completed CCB.
3068
      */
3069
      if (CCB->Opcode == BusLogic_BusDeviceReset)
3070
        {
3071
          int TargetID = CCB->TargetID;
3072
          BusLogic_Warning("Bus Device Reset CCB #%ld to Target "
3073
                           "%d Completed\n", HostAdapter,
3074
                           CCB->SerialNumber, TargetID);
3075
          BusLogic_IncrementErrorCounter(
3076
            &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsCompleted);
3077
          HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
3078
          HostAdapter->CommandsSinceReset[TargetID] = 0;
3079
          HostAdapter->LastResetCompleted[TargetID] = jiffies;
3080
          /*
3081
            Place CCB back on the Host Adapter's free list.
3082
          */
3083
          BusLogic_DeallocateCCB(CCB);
3084
          /*
3085
            Bus Device Reset CCBs have the Command field non-NULL only when a
3086
            Bus Device Reset was requested for a Command that did not have a
3087
            currently active CCB in the Host Adapter (i.e., a Synchronous
3088
            Bus Device Reset), and hence would not have its Completion Routine
3089
            called otherwise.
3090
          */
3091
          while (Command != NULL)
3092
            {
3093
              SCSI_Command_T *NextCommand = Command->reset_chain;
3094
              Command->reset_chain = NULL;
3095
              Command->result = DID_RESET << 16;
3096
              Command->scsi_done(Command);
3097
              Command = NextCommand;
3098
            }
3099
          /*
3100
            Iterate over the CCBs for this Host Adapter performing completion
3101
            processing for any CCBs marked as Reset for this Target.
3102
          */
3103
          for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3104
            if (CCB->Status == BusLogic_CCB_Reset && CCB->TargetID == TargetID)
3105
              {
3106
                Command = CCB->Command;
3107
                BusLogic_DeallocateCCB(CCB);
3108
                HostAdapter->ActiveCommands[TargetID]--;
3109
                Command->result = DID_RESET << 16;
3110
                Command->scsi_done(Command);
3111
              }
3112
          HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
3113
        }
3114
      else
3115
        {
3116
          /*
3117
            Translate the Completion Code, Host Adapter Status, and Target
3118
            Device Status into a SCSI Subsystem Result Code.
3119
          */
3120
          switch (CCB->CompletionCode)
3121
            {
3122
            case BusLogic_IncomingMailboxFree:
3123
            case BusLogic_AbortedCommandNotFound:
3124
            case BusLogic_InvalidCCB:
3125
              BusLogic_Warning("CCB #%ld to Target %d Impossible State\n",
3126
                               HostAdapter, CCB->SerialNumber, CCB->TargetID);
3127
              break;
3128
            case BusLogic_CommandCompletedWithoutError:
3129
              HostAdapter->TargetStatistics[CCB->TargetID]
3130
                           .CommandsCompleted++;
3131
              HostAdapter->TargetFlags[CCB->TargetID]
3132
                           .CommandSuccessfulFlag = true;
3133
              Command->result = DID_OK << 16;
3134
              break;
3135
            case BusLogic_CommandAbortedAtHostRequest:
3136
              BusLogic_Warning("CCB #%ld to Target %d Aborted\n",
3137
                               HostAdapter, CCB->SerialNumber, CCB->TargetID);
3138
              BusLogic_IncrementErrorCounter(
3139
                &HostAdapter->TargetStatistics[CCB->TargetID]
3140
                              .CommandAbortsCompleted);
3141
              Command->result = DID_ABORT << 16;
3142
              break;
3143
            case BusLogic_CommandCompletedWithError:
3144
              Command->result =
3145
                BusLogic_ComputeResultCode(HostAdapter,
3146
                                           CCB->HostAdapterStatus,
3147
                                           CCB->TargetDeviceStatus);
3148
              if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout)
3149
                {
3150
                  HostAdapter->TargetStatistics[CCB->TargetID]
3151
                               .CommandsCompleted++;
3152
                  if (BusLogic_GlobalOptions.TraceErrors)
3153
                    {
3154
                      int i;
3155
                      BusLogic_Notice("CCB #%ld Target %d: Result %X Host "
3156
                                      "Adapter Status %02X "
3157
                                      "Target Status %02X\n",
3158
                                      HostAdapter, CCB->SerialNumber,
3159
                                      CCB->TargetID, Command->result,
3160
                                      CCB->HostAdapterStatus,
3161
                                      CCB->TargetDeviceStatus);
3162
                      BusLogic_Notice("CDB   ", HostAdapter);
3163
                      for (i = 0; i < CCB->CDB_Length; i++)
3164
                        BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]);
3165
                      BusLogic_Notice("\n", HostAdapter);
3166
                      BusLogic_Notice("Sense ", HostAdapter);
3167
                      for (i = 0; i < CCB->SenseDataLength; i++)
3168
                        BusLogic_Notice(" %02X", HostAdapter,
3169
                                        Command->sense_buffer[i]);
3170
                      BusLogic_Notice("\n", HostAdapter);
3171
                    }
3172
                }
3173
              break;
3174
            }
3175
          /*
3176
            When an INQUIRY command completes normally, save the
3177
            CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit
3178
            Wide Data Transfers Supported) bits.
3179
          */
3180
          if (CCB->CDB[0] == INQUIRY && CCB->CDB[1] == 0 &&
3181
              CCB->HostAdapterStatus == BusLogic_CommandCompletedNormally)
3182
            {
3183
              BusLogic_TargetFlags_T *TargetFlags =
3184
                &HostAdapter->TargetFlags[CCB->TargetID];
3185
              SCSI_Inquiry_T *InquiryResult =
3186
                (SCSI_Inquiry_T *) Command->request_buffer;
3187
              TargetFlags->TargetExists = true;
3188
              TargetFlags->TaggedQueuingSupported = InquiryResult->CmdQue;
3189
              TargetFlags->WideTransfersSupported = InquiryResult->WBus16;
3190
            }
3191
          /*
3192
            Place CCB back on the Host Adapter's free list.
3193
          */
3194
          BusLogic_DeallocateCCB(CCB);
3195
          /*
3196
            Call the SCSI Command Completion Routine.
3197
          */
3198
          Command->scsi_done(Command);
3199
        }
3200
    }
3201
  HostAdapter->ProcessCompletedCCBsActive = false;
3202
}
3203
 
3204
 
3205
/*
3206
  BusLogic_InterruptHandler handles hardware interrupts from BusLogic Host
3207
  Adapters.
3208
*/
3209
 
3210
static void BusLogic_InterruptHandler(int IRQ_Channel,
3211
                                      void *DeviceIdentifier,
3212
                                      Registers_T *InterruptRegisters)
3213
{
3214
  BusLogic_HostAdapter_T *HostAdapter =
3215
    (BusLogic_HostAdapter_T *) DeviceIdentifier;
3216
  ProcessorFlags_T ProcessorFlags;
3217
  /*
3218
    Acquire exclusive access to Host Adapter.
3219
  */
3220
  BusLogic_AcquireHostAdapterLockIH(HostAdapter, &ProcessorFlags);
3221
  /*
3222
    Handle Interrupts appropriately for each Host Adapter type.
3223
  */
3224
  if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3225
    {
3226
      BusLogic_InterruptRegister_T InterruptRegister;
3227
      /*
3228
        Read the Host Adapter Interrupt Register.
3229
      */
3230
      InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
3231
      if (InterruptRegister.Bits.InterruptValid)
3232
        {
3233
          /*
3234
            Acknowledge the interrupt and reset the Host Adapter
3235
            Interrupt Register.
3236
          */
3237
          BusLogic_InterruptReset(HostAdapter);
3238
          /*
3239
            Process valid External SCSI Bus Reset and Incoming Mailbox
3240
            Loaded Interrupts.  Command Complete Interrupts are noted,
3241
            and Outgoing Mailbox Available Interrupts are ignored, as
3242
            they are never enabled.
3243
          */
3244
          if (InterruptRegister.Bits.ExternalBusReset)
3245
            HostAdapter->HostAdapterExternalReset = true;
3246
          else if (InterruptRegister.Bits.IncomingMailboxLoaded)
3247
            BusLogic_ScanIncomingMailboxes(HostAdapter);
3248
          else if (InterruptRegister.Bits.CommandComplete)
3249
            HostAdapter->HostAdapterCommandCompleted = true;
3250
        }
3251
    }
3252
  else
3253
    {
3254
      /*
3255
        Check if there is a pending interrupt for this Host Adapter.
3256
      */
3257
      if (FlashPoint_InterruptPending(HostAdapter->CardHandle))
3258
        switch (FlashPoint_HandleInterrupt(HostAdapter->CardHandle))
3259
          {
3260
          case FlashPoint_NormalInterrupt:
3261
            break;
3262
          case FlashPoint_ExternalBusReset:
3263
            HostAdapter->HostAdapterExternalReset = true;
3264
            break;
3265
          case FlashPoint_InternalError:
3266
            BusLogic_Warning("Internal FlashPoint Error detected"
3267
                             " - Resetting Host Adapter\n", HostAdapter);
3268
            HostAdapter->HostAdapterInternalError = true;
3269
            break;
3270
          }
3271
    }
3272
  /*
3273
    Process any completed CCBs.
3274
  */
3275
  if (HostAdapter->FirstCompletedCCB != NULL)
3276
    BusLogic_ProcessCompletedCCBs(HostAdapter);
3277
  /*
3278
    Reset the Host Adapter if requested.
3279
  */
3280
  if (HostAdapter->HostAdapterExternalReset ||
3281
      HostAdapter->HostAdapterInternalError)
3282
    {
3283
      BusLogic_ResetHostAdapter(HostAdapter, NULL, 0);
3284
      HostAdapter->HostAdapterExternalReset = false;
3285
      HostAdapter->HostAdapterInternalError = false;
3286
      scsi_mark_host_reset(HostAdapter->SCSI_Host);
3287
    }
3288
  /*
3289
    Release exclusive access to Host Adapter.
3290
  */
3291
  BusLogic_ReleaseHostAdapterLockIH(HostAdapter, &ProcessorFlags);
3292
}
3293
 
3294
 
3295
/*
3296
  BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
3297
  Mailbox for execution by Host Adapter.  The Host Adapter's Lock should
3298
  already have been acquired by the caller.
3299
*/
3300
 
3301
static boolean BusLogic_WriteOutgoingMailbox(BusLogic_HostAdapter_T
3302
                                               *HostAdapter,
3303
                                             BusLogic_ActionCode_T ActionCode,
3304
                                             BusLogic_CCB_T *CCB)
3305
{
3306
  BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
3307
  NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
3308
  if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree)
3309
    {
3310
      CCB->Status = BusLogic_CCB_Active;
3311
      /*
3312
        The CCB field must be written before the Action Code field since
3313
        the Host Adapter is operating asynchronously and the locking code
3314
        does not protect against simultaneous access by the Host Adapter.
3315
      */
3316
      NextOutgoingMailbox->CCB = Virtual_to_Bus(CCB);
3317
      NextOutgoingMailbox->ActionCode = ActionCode;
3318
      BusLogic_StartMailboxCommand(HostAdapter);
3319
      if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
3320
        NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
3321
      HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
3322
      if (ActionCode == BusLogic_MailboxStartCommand)
3323
        {
3324
          HostAdapter->ActiveCommands[CCB->TargetID]++;
3325
          if (CCB->Opcode != BusLogic_BusDeviceReset)
3326
            HostAdapter->TargetStatistics[CCB->TargetID].CommandsAttempted++;
3327
        }
3328
      return true;
3329
    }
3330
  return false;
3331
}
3332
 
3333
 
3334
/*
3335
  BusLogic_QueueCommand creates a CCB for Command and places it into an
3336
  Outgoing Mailbox for execution by the associated Host Adapter.
3337
*/
3338
 
3339
int BusLogic_QueueCommand(SCSI_Command_T *Command,
3340
                          void (*CompletionRoutine)(SCSI_Command_T *))
3341
{
3342
  BusLogic_HostAdapter_T *HostAdapter =
3343
    (BusLogic_HostAdapter_T *) Command->host->hostdata;
3344
  BusLogic_TargetFlags_T *TargetFlags =
3345
    &HostAdapter->TargetFlags[Command->target];
3346
  BusLogic_TargetStatistics_T *TargetStatistics =
3347
    HostAdapter->TargetStatistics;
3348
  unsigned char *CDB = Command->cmnd;
3349
  int CDB_Length = Command->cmd_len;
3350
  int TargetID = Command->target;
3351
  int LogicalUnit = Command->lun;
3352
  void *BufferPointer = Command->request_buffer;
3353
  int BufferLength = Command->request_bufflen;
3354
  int SegmentCount = Command->use_sg;
3355
  ProcessorFlags_T ProcessorFlags;
3356
  BusLogic_CCB_T *CCB;
3357
  /*
3358
    SCSI REQUEST_SENSE commands will be executed automatically by the Host
3359
    Adapter for any errors, so they should not be executed explicitly unless
3360
    the Sense Data is zero indicating that no error occurred.
3361
  */
3362
  if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0)
3363
    {
3364
      Command->result = DID_OK << 16;
3365
      CompletionRoutine(Command);
3366
      return 0;
3367
    }
3368
  /*
3369
    Acquire exclusive access to Host Adapter.
3370
  */
3371
  BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
3372
  /*
3373
    Allocate a CCB from the Host Adapter's free list.  In the unlikely event
3374
    that there are none available and memory allocation fails, wait 1 second
3375
    and try again.  If that fails, the Host Adapter is probably hung so signal
3376
    an error as a Host Adapter Hard Reset should be initiated soon.
3377
  */
3378
  CCB = BusLogic_AllocateCCB(HostAdapter);
3379
  if (CCB == NULL)
3380
    {
3381
      BusLogic_Delay(1);
3382
      CCB = BusLogic_AllocateCCB(HostAdapter);
3383
      if (CCB == NULL)
3384
        {
3385
          Command->result = DID_ERROR << 16;
3386
          CompletionRoutine(Command);
3387
          goto Done;
3388
        }
3389
    }
3390
  /*
3391
    Initialize the fields in the BusLogic Command Control Block (CCB).
3392
  */
3393
  if (SegmentCount == 0)
3394
    {
3395
      CCB->Opcode = BusLogic_InitiatorCCB;
3396
      CCB->DataLength = BufferLength;
3397
      CCB->DataPointer = Virtual_to_Bus(BufferPointer);
3398
    }
3399
  else
3400
    {
3401
      SCSI_ScatterList_T *ScatterList = (SCSI_ScatterList_T *) BufferPointer;
3402
      int Segment;
3403
      CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
3404
      CCB->DataLength = SegmentCount * sizeof(BusLogic_ScatterGatherSegment_T);
3405
      if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3406
        CCB->DataPointer = Virtual_to_Bus(CCB->ScatterGatherList);
3407
      else CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList);
3408
      for (Segment = 0; Segment < SegmentCount; Segment++)
3409
        {
3410
          CCB->ScatterGatherList[Segment].SegmentByteCount =
3411
            ScatterList[Segment].length;
3412
          CCB->ScatterGatherList[Segment].SegmentDataPointer =
3413
            Virtual_to_Bus(ScatterList[Segment].address);
3414
        }
3415
    }
3416
  switch (CDB[0])
3417
    {
3418
    case READ_6:
3419
    case READ_10:
3420
      CCB->DataDirection = BusLogic_DataInLengthChecked;
3421
      TargetStatistics[TargetID].ReadCommands++;
3422
      BusLogic_IncrementByteCounter(
3423
        &TargetStatistics[TargetID].TotalBytesRead, BufferLength);
3424
      BusLogic_IncrementSizeBucket(
3425
        TargetStatistics[TargetID].ReadCommandSizeBuckets, BufferLength);
3426
      break;
3427
    case WRITE_6:
3428
    case WRITE_10:
3429
      CCB->DataDirection = BusLogic_DataOutLengthChecked;
3430
      TargetStatistics[TargetID].WriteCommands++;
3431
      BusLogic_IncrementByteCounter(
3432
        &TargetStatistics[TargetID].TotalBytesWritten, BufferLength);
3433
      BusLogic_IncrementSizeBucket(
3434
        TargetStatistics[TargetID].WriteCommandSizeBuckets, BufferLength);
3435
      break;
3436
    default:
3437
      CCB->DataDirection = BusLogic_UncheckedDataTransfer;
3438
      break;
3439
    }
3440
  CCB->CDB_Length = CDB_Length;
3441
  CCB->SenseDataLength = sizeof(Command->sense_buffer);
3442
  CCB->HostAdapterStatus = 0;
3443
  CCB->TargetDeviceStatus = 0;
3444
  CCB->TargetID = TargetID;
3445
  CCB->LogicalUnit = LogicalUnit;
3446
  CCB->TagEnable = false;
3447
  CCB->LegacyTagEnable = false;
3448
  /*
3449
    BusLogic recommends that after a Reset the first couple of commands that
3450
    are sent to a Target Device be sent in a non Tagged Queue fashion so that
3451
    the Host Adapter and Target Device can establish Synchronous and Wide
3452
    Transfer before Queue Tag messages can interfere with the Synchronous and
3453
    Wide Negotiation messages.  By waiting to enable Tagged Queuing until after
3454
    the first BusLogic_MaxTaggedQueueDepth commands have been queued, it is
3455
    assured that after a Reset any pending commands are requeued before Tagged
3456
    Queuing is enabled and that the Tagged Queuing message will not occur while
3457
    the partition table is being printed.  In addition, some devices do not
3458
    properly handle the transition from non-tagged to tagged commands, so it is
3459
    necessary to wait until there are no pending commands for a target device
3460
    before queuing tagged commands.
3461
  */
3462
  if (HostAdapter->CommandsSinceReset[TargetID]++ >=
3463
        BusLogic_MaxTaggedQueueDepth &&
3464
      !TargetFlags->TaggedQueuingActive &&
3465
      HostAdapter->ActiveCommands[TargetID] == 0 &&
3466
      TargetFlags->TaggedQueuingSupported &&
3467
      (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
3468
    {
3469
      TargetFlags->TaggedQueuingActive = true;
3470
      BusLogic_Notice("Tagged Queuing now active for Target %d\n",
3471
                      HostAdapter, TargetID);
3472
    }
3473
  if (TargetFlags->TaggedQueuingActive)
3474
    {
3475
      BusLogic_QueueTag_T QueueTag = BusLogic_SimpleQueueTag;
3476
      /*
3477
        When using Tagged Queuing with Simple Queue Tags, it appears that disk
3478
        drive controllers do not guarantee that a queued command will not
3479
        remain in a disconnected state indefinitely if commands that read or
3480
        write nearer the head position continue to arrive without interruption.
3481
        Therefore, for each Target Device this driver keeps track of the last
3482
        time either the queue was empty or an Ordered Queue Tag was issued.  If
3483
        more than 4 seconds (one fifth of the 20 second disk timeout) have
3484
        elapsed since this last sequence point, this command will be issued
3485
        with an Ordered Queue Tag rather than a Simple Queue Tag, which forces
3486
        the Target Device to complete all previously queued commands before
3487
        this command may be executed.
3488
      */
3489
      if (HostAdapter->ActiveCommands[TargetID] == 0)
3490
        HostAdapter->LastSequencePoint[TargetID] = jiffies;
3491
      else if (jiffies - HostAdapter->LastSequencePoint[TargetID] > 4*HZ)
3492
        {
3493
          HostAdapter->LastSequencePoint[TargetID] = jiffies;
3494
          QueueTag = BusLogic_OrderedQueueTag;
3495
        }
3496
      if (HostAdapter->ExtendedLUNSupport)
3497
        {
3498
          CCB->TagEnable = true;
3499
          CCB->QueueTag = QueueTag;
3500
        }
3501
      else
3502
        {
3503
          CCB->LegacyTagEnable = true;
3504
          CCB->LegacyQueueTag = QueueTag;
3505
        }
3506
    }
3507
  memcpy(CCB->CDB, CDB, CDB_Length);
3508
  CCB->SenseDataPointer = Virtual_to_Bus(&Command->sense_buffer);
3509
  CCB->Command = Command;
3510
  Command->scsi_done = CompletionRoutine;
3511
  if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3512
    {
3513
      /*
3514
        Place the CCB in an Outgoing Mailbox.  The higher levels of the SCSI
3515
        Subsystem should not attempt to queue more commands than can be placed
3516
        in Outgoing Mailboxes, so there should always be one free.  In the
3517
        unlikely event that there are none available, wait 1 second and try
3518
        again.  If that fails, the Host Adapter is probably hung so signal an
3519
        error as a Host Adapter Hard Reset should be initiated soon.
3520
      */
3521
      if (!BusLogic_WriteOutgoingMailbox(
3522
             HostAdapter, BusLogic_MailboxStartCommand, CCB))
3523
        {
3524
          BusLogic_Warning("Unable to write Outgoing Mailbox - "
3525
                           "Pausing for 1 second\n", HostAdapter);
3526
          BusLogic_Delay(1);
3527
          if (!BusLogic_WriteOutgoingMailbox(
3528
                 HostAdapter, BusLogic_MailboxStartCommand, CCB))
3529
            {
3530
              BusLogic_Warning("Still unable to write Outgoing Mailbox - "
3531
                               "Host Adapter Dead?\n", HostAdapter);
3532
              BusLogic_DeallocateCCB(CCB);
3533
              Command->result = DID_ERROR << 16;
3534
              Command->scsi_done(Command);
3535
            }
3536
        }
3537
    }
3538
  else
3539
    {
3540
      /*
3541
        Call the FlashPoint SCCB Manager to start execution of the CCB.
3542
      */
3543
      CCB->Status = BusLogic_CCB_Active;
3544
      HostAdapter->ActiveCommands[TargetID]++;
3545
      TargetStatistics[TargetID].CommandsAttempted++;
3546
      FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
3547
      /*
3548
        The Command may have already completed and BusLogic_QueueCompletedCCB
3549
        been called, or it may still be pending.
3550
      */
3551
      if (CCB->Status == BusLogic_CCB_Completed)
3552
        BusLogic_ProcessCompletedCCBs(HostAdapter);
3553
    }
3554
  /*
3555
    Release exclusive access to Host Adapter.
3556
  */
3557
Done:
3558
  BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
3559
  return 0;
3560
}
3561
 
3562
 
3563
/*
3564
  BusLogic_AbortCommand aborts Command if possible.
3565
*/
3566
 
3567
int BusLogic_AbortCommand(SCSI_Command_T *Command)
3568
{
3569
  BusLogic_HostAdapter_T *HostAdapter =
3570
    (BusLogic_HostAdapter_T *) Command->host->hostdata;
3571
  int TargetID = Command->target;
3572
  ProcessorFlags_T ProcessorFlags;
3573
  BusLogic_CCB_T *CCB;
3574
  int Result;
3575
  BusLogic_IncrementErrorCounter(
3576
    &HostAdapter->TargetStatistics[TargetID].CommandAbortsRequested);
3577
  /*
3578
    Acquire exclusive access to Host Adapter.
3579
  */
3580
  BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
3581
  /*
3582
    If this Command has already completed, then no Abort is necessary.
3583
  */
3584
  if (Command->serial_number != Command->serial_number_at_timeout)
3585
    {
3586
      BusLogic_Warning("Unable to Abort Command to Target %d - "
3587
                       "Already Completed\n", HostAdapter, TargetID);
3588
      Result = SCSI_ABORT_NOT_RUNNING;
3589
      goto Done;
3590
    }
3591
  /*
3592
    Attempt to find an Active CCB for this Command.  If no Active CCB for this
3593
    Command is found, then no Abort is necessary.
3594
  */
3595
  for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3596
    if (CCB->Command == Command) break;
3597
  if (CCB == NULL)
3598
    {
3599
      BusLogic_Warning("Unable to Abort Command to Target %d - "
3600
                       "No CCB Found\n", HostAdapter, TargetID);
3601
      Result = SCSI_ABORT_NOT_RUNNING;
3602
      goto Done;
3603
    }
3604
  else if (CCB->Status == BusLogic_CCB_Completed)
3605
    {
3606
      BusLogic_Warning("Unable to Abort Command to Target %d - "
3607
                       "CCB Completed\n", HostAdapter, TargetID);
3608
      Result = SCSI_ABORT_NOT_RUNNING;
3609
      goto Done;
3610
    }
3611
  else if (CCB->Status == BusLogic_CCB_Reset)
3612
    {
3613
      BusLogic_Warning("Unable to Abort Command to Target %d - "
3614
                       "CCB Reset\n", HostAdapter, TargetID);
3615
      Result = SCSI_ABORT_PENDING;
3616
      goto Done;
3617
    }
3618
  if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3619
    {
3620
      /*
3621
        Attempt to Abort this CCB.  MultiMaster Firmware versions prior to 5.xx
3622
        do not generate Abort Tag messages, but only generate the non-tagged
3623
        Abort message.  Since non-tagged commands are not sent by the Host
3624
        Adapter until the queue of outstanding tagged commands has completed,
3625
        and the Abort message is treated as a non-tagged command, it is
3626
        effectively impossible to abort commands when Tagged Queuing is active.
3627
        Firmware version 5.xx does generate Abort Tag messages, so it is
3628
        possible to abort commands when Tagged Queuing is active.
3629
      */
3630
      if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
3631
          HostAdapter->FirmwareVersion[0] < '5')
3632
        {
3633
          BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - "
3634
                           "Abort Tag Not Supported\n",
3635
                           HostAdapter, CCB->SerialNumber, TargetID);
3636
          Result = SCSI_ABORT_SNOOZE;
3637
        }
3638
      else if (BusLogic_WriteOutgoingMailbox(
3639
                 HostAdapter, BusLogic_MailboxAbortCommand, CCB))
3640
        {
3641
          BusLogic_Warning("Aborting CCB #%ld to Target %d\n",
3642
                           HostAdapter, CCB->SerialNumber, TargetID);
3643
          BusLogic_IncrementErrorCounter(
3644
            &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
3645
          Result = SCSI_ABORT_PENDING;
3646
        }
3647
      else
3648
        {
3649
          BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - "
3650
                           "No Outgoing Mailboxes\n",
3651
                            HostAdapter, CCB->SerialNumber, TargetID);
3652
          Result = SCSI_ABORT_BUSY;
3653
        }
3654
    }
3655
  else
3656
    {
3657
      /*
3658
        Call the FlashPoint SCCB Manager to abort execution of the CCB.
3659
      */
3660
      BusLogic_Warning("Aborting CCB #%ld to Target %d\n",
3661
                       HostAdapter, CCB->SerialNumber, TargetID);
3662
      BusLogic_IncrementErrorCounter(
3663
        &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
3664
      FlashPoint_AbortCCB(HostAdapter->CardHandle, CCB);
3665
      /*
3666
        The Abort may have already been completed and
3667
        BusLogic_QueueCompletedCCB been called, or it
3668
        may still be pending.
3669
      */
3670
      Result = SCSI_ABORT_PENDING;
3671
      if (CCB->Status == BusLogic_CCB_Completed)
3672
        {
3673
          BusLogic_ProcessCompletedCCBs(HostAdapter);
3674
          Result = SCSI_ABORT_SUCCESS;
3675
        }
3676
    }
3677
  /*
3678
    Release exclusive access to Host Adapter.
3679
  */
3680
Done:
3681
  BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
3682
  return Result;
3683
}
3684
 
3685
 
3686
/*
3687
  BusLogic_ResetHostAdapter resets Host Adapter if possible, marking all
3688
  currently executing SCSI Commands as having been Reset.
3689
*/
3690
 
3691
static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter,
3692
                                     SCSI_Command_T *Command,
3693
                                     unsigned int ResetFlags)
3694
{
3695
  ProcessorFlags_T ProcessorFlags;
3696
  BusLogic_CCB_T *CCB;
3697
  int TargetID, Result;
3698
  boolean HardReset;
3699
  if (HostAdapter->HostAdapterExternalReset)
3700
    {
3701
      BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets);
3702
      HardReset = false;
3703
    }
3704
  else if (HostAdapter->HostAdapterInternalError)
3705
    {
3706
      BusLogic_IncrementErrorCounter(&HostAdapter->HostAdapterInternalErrors);
3707
      HardReset = true;
3708
    }
3709
  else
3710
    {
3711
      BusLogic_IncrementErrorCounter(
3712
        &HostAdapter->TargetStatistics[Command->target]
3713
                      .HostAdapterResetsRequested);
3714
      HardReset = true;
3715
    }
3716
  /*
3717
    Acquire exclusive access to Host Adapter.
3718
  */
3719
  BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
3720
  /*
3721
    If this is an Asynchronous Reset and this Command has already completed,
3722
    then no Reset is necessary.
3723
  */
3724
  if (ResetFlags & SCSI_RESET_ASYNCHRONOUS)
3725
    {
3726
      TargetID = Command->target;
3727
      if (Command->serial_number != Command->serial_number_at_timeout)
3728
        {
3729
          BusLogic_Warning("Unable to Reset Command to Target %d - "
3730
                           "Already Completed or Reset\n",
3731
                           HostAdapter, TargetID);
3732
          Result = SCSI_RESET_NOT_RUNNING;
3733
          goto Done;
3734
      }
3735
      for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3736
        if (CCB->Command == Command) break;
3737
      if (CCB == NULL)
3738
        {
3739
          BusLogic_Warning("Unable to Reset Command to Target %d - "
3740
                           "No CCB Found\n", HostAdapter, TargetID);
3741
          Result = SCSI_RESET_NOT_RUNNING;
3742
          goto Done;
3743
        }
3744
      else if (CCB->Status == BusLogic_CCB_Completed)
3745
        {
3746
          BusLogic_Warning("Unable to Reset Command to Target %d - "
3747
                           "CCB Completed\n", HostAdapter, TargetID);
3748
          Result = SCSI_RESET_NOT_RUNNING;
3749
          goto Done;
3750
        }
3751
      else if (CCB->Status == BusLogic_CCB_Reset &&
3752
               HostAdapter->BusDeviceResetPendingCCB[TargetID] == NULL)
3753
        {
3754
          BusLogic_Warning("Unable to Reset Command to Target %d - "
3755
                           "Reset Pending\n", HostAdapter, TargetID);
3756
          Result = SCSI_RESET_PENDING;
3757
          goto Done;
3758
        }
3759
    }
3760
  if (Command == NULL)
3761
    {
3762
      if (HostAdapter->HostAdapterInternalError)
3763
        BusLogic_Warning("Resetting %s due to Host Adapter Internal Error\n",
3764
                         HostAdapter, HostAdapter->FullModelName);
3765
      else BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n",
3766
                            HostAdapter, HostAdapter->FullModelName);
3767
    }
3768
  else
3769
    {
3770
      BusLogic_Warning("Resetting %s due to Target %d\n", HostAdapter,
3771
                       HostAdapter->FullModelName, Command->target);
3772
      BusLogic_IncrementErrorCounter(
3773
        &HostAdapter->TargetStatistics[Command->target]
3774
                      .HostAdapterResetsAttempted);
3775
    }
3776
  /*
3777
    Attempt to Reset and Reinitialize the Host Adapter.
3778
  */
3779
  if (!(BusLogic_HardwareResetHostAdapter(HostAdapter, HardReset) &&
3780
        BusLogic_InitializeHostAdapter(HostAdapter)))
3781
    {
3782
      BusLogic_Error("Resetting %s Failed\n", HostAdapter,
3783
                     HostAdapter->FullModelName);
3784
      Result = SCSI_RESET_ERROR;
3785
      goto Done;
3786
    }
3787
  if (Command != NULL)
3788
    BusLogic_IncrementErrorCounter(
3789
      &HostAdapter->TargetStatistics[Command->target]
3790
                    .HostAdapterResetsCompleted);
3791
  /*
3792
    Mark all currently executing CCBs as having been Reset.
3793
  */
3794
  for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3795
    if (CCB->Status == BusLogic_CCB_Active)
3796
      CCB->Status = BusLogic_CCB_Reset;
3797
  /*
3798
    Wait a few seconds between the Host Adapter Hard Reset which initiates
3799
    a SCSI Bus Reset and issuing any SCSI Commands.  Some SCSI devices get
3800
    confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
3801
    Note that a timer interrupt may occur here, but all active CCBs have
3802
    already been marked Reset and so a reentrant call will return Pending.
3803
  */
3804
  if (HardReset)
3805
    BusLogic_Delay(HostAdapter->BusSettleTime);
3806
  /*
3807
    If this is a Synchronous Reset, perform completion processing for
3808
    the Command being Reset.
3809
  */
3810
  if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
3811
    {
3812
      Command->result = DID_RESET << 16;
3813
      Command->scsi_done(Command);
3814
    }
3815
  /*
3816
    Perform completion processing for all CCBs marked as Reset.
3817
  */
3818
  for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3819
    if (CCB->Status == BusLogic_CCB_Reset)
3820
      {
3821
        Command = CCB->Command;
3822
        BusLogic_DeallocateCCB(CCB);
3823
        while (Command != NULL)
3824
          {
3825
            SCSI_Command_T *NextCommand = Command->reset_chain;
3826
            Command->reset_chain = NULL;
3827
            Command->result = DID_RESET << 16;
3828
            Command->scsi_done(Command);
3829
            Command = NextCommand;
3830
          }
3831
      }
3832
  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
3833
    {
3834
      HostAdapter->LastResetAttempted[TargetID] = jiffies;
3835
      HostAdapter->LastResetCompleted[TargetID] = jiffies;
3836
    }
3837
  Result = SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET;
3838
  /*
3839
    Release exclusive access to Host Adapter.
3840
  */
3841
Done:
3842
  BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
3843
  return Result;
3844
}
3845
 
3846
 
3847
/*
3848
  BusLogic_SendBusDeviceReset sends a Bus Device Reset to the Target
3849
  Device associated with Command.
3850
*/
3851
 
3852
static int BusLogic_SendBusDeviceReset(BusLogic_HostAdapter_T *HostAdapter,
3853
                                       SCSI_Command_T *Command,
3854
                                       unsigned int ResetFlags)
3855
{
3856
  int TargetID = Command->target;
3857
  BusLogic_CCB_T *CCB, *XCCB;
3858
  ProcessorFlags_T ProcessorFlags;
3859
  int Result = -1;
3860
  BusLogic_IncrementErrorCounter(
3861
    &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsRequested);
3862
  /*
3863
    Acquire exclusive access to Host Adapter.
3864
  */
3865
  BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
3866
  /*
3867
    If this is an Asynchronous Reset and this Command has already completed,
3868
    then no Reset is necessary.
3869
  */
3870
  if (ResetFlags & SCSI_RESET_ASYNCHRONOUS)
3871
    {
3872
      if (Command->serial_number != Command->serial_number_at_timeout)
3873
        {
3874
          BusLogic_Warning("Unable to Reset Command to Target %d - "
3875
                           "Already Completed\n", HostAdapter, TargetID);
3876
          Result = SCSI_RESET_NOT_RUNNING;
3877
          goto Done;
3878
        }
3879
      for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3880
        if (CCB->Command == Command) break;
3881
      if (CCB == NULL)
3882
        {
3883
          BusLogic_Warning("Unable to Reset Command to Target %d - "
3884
                           "No CCB Found\n", HostAdapter, TargetID);
3885
          Result = SCSI_RESET_NOT_RUNNING;
3886
          goto Done;
3887
        }
3888
      else if (CCB->Status == BusLogic_CCB_Completed)
3889
        {
3890
          BusLogic_Warning("Unable to Reset Command to Target %d - "
3891
                           "CCB Completed\n", HostAdapter, TargetID);
3892
          Result = SCSI_RESET_NOT_RUNNING;
3893
          goto Done;
3894
        }
3895
      else if (CCB->Status == BusLogic_CCB_Reset)
3896
        {
3897
          BusLogic_Warning("Unable to Reset Command to Target %d - "
3898
                           "Reset Pending\n", HostAdapter, TargetID);
3899
          Result = SCSI_RESET_PENDING;
3900
          goto Done;
3901
        }
3902
      else if (HostAdapter->BusDeviceResetPendingCCB[TargetID] != NULL)
3903
        {
3904
          BusLogic_Warning("Bus Device Reset already pending to Target %d\n",
3905
                           HostAdapter, TargetID);
3906
          goto Done;
3907
        }
3908
    }
3909
  /*
3910
    If this is a Synchronous Reset and a Bus Device Reset is already pending
3911
    for this Target Device, do not send a second one.  Add this Command to
3912
    the list of Commands for which completion processing must be performed
3913
    when the Bus Device Reset CCB completes.
3914
  */
3915
  if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
3916
    if ((CCB = HostAdapter->BusDeviceResetPendingCCB[TargetID]) != NULL)
3917
      {
3918
        Command->reset_chain = CCB->Command;
3919
        CCB->Command = Command;
3920
        BusLogic_Warning("Unable to Reset Command to Target %d - "
3921
                         "Reset Pending\n", HostAdapter, TargetID);
3922
        Result = SCSI_RESET_PENDING;
3923
        goto Done;
3924
      }
3925
  if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3926
    {
3927
      /*
3928
        MultiMaster Firmware versions prior to 5.xx treat a Bus Device Reset as
3929
        a non-tagged command.  Since non-tagged commands are not sent by the
3930
        Host Adapter until the queue of outstanding tagged commands has
3931
        completed, it is effectively impossible to send a Bus Device Reset
3932
        while there are tagged commands outstanding.  Therefore, in that case a
3933
        full Host Adapter Hard Reset and SCSI Bus Reset must be done.
3934
      */
3935
      if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
3936
          HostAdapter->ActiveCommands[TargetID] > 0 &&
3937
          HostAdapter->FirmwareVersion[0] < '5')
3938
        goto Done;
3939
    }
3940
  /*
3941
    Allocate a CCB from the Host Adapter's free list.  In the unlikely event
3942
    that there are none available and memory allocation fails, attempt a full
3943
    Host Adapter Hard Reset and SCSI Bus Reset.
3944
  */
3945
  CCB = BusLogic_AllocateCCB(HostAdapter);
3946
  if (CCB == NULL) goto Done;
3947
  BusLogic_Warning("Sending Bus Device Reset CCB #%ld to Target %d\n",
3948
                   HostAdapter, CCB->SerialNumber, TargetID);
3949
  CCB->Opcode = BusLogic_BusDeviceReset;
3950
  CCB->TargetID = TargetID;
3951
  /*
3952
    For Synchronous Resets, arrange for the interrupt handler to perform
3953
    completion processing for the Command being Reset.
3954
  */
3955
  if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
3956
    {
3957
      Command->reset_chain = NULL;
3958
      CCB->Command = Command;
3959
    }
3960
  if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3961
    {
3962
      /*
3963
        Attempt to write an Outgoing Mailbox with the Bus Device Reset CCB.
3964
        If sending a Bus Device Reset is impossible, attempt a full Host
3965
        Adapter Hard Reset and SCSI Bus Reset.
3966
      */
3967
      if (!(BusLogic_WriteOutgoingMailbox(
3968
              HostAdapter, BusLogic_MailboxStartCommand, CCB)))
3969
        {
3970
          BusLogic_Warning("Unable to write Outgoing Mailbox for "
3971
                           "Bus Device Reset\n", HostAdapter);
3972
          BusLogic_DeallocateCCB(CCB);
3973
          goto Done;
3974
        }
3975
    }
3976
  else
3977
    {
3978
      /*
3979
        Call the FlashPoint SCCB Manager to start execution of the CCB.
3980
      */
3981
      CCB->Status = BusLogic_CCB_Active;
3982
      HostAdapter->ActiveCommands[TargetID]++;
3983
      FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
3984
    }
3985
  /*
3986
    If there is a currently executing CCB in the Host Adapter for this Command
3987
    (i.e. this is an Asynchronous Reset), then an Incoming Mailbox entry may be
3988
    made with a completion code of BusLogic_HostAdapterAssertedBusDeviceReset.
3989
    If there is no active CCB for this Command (i.e. this is a Synchronous
3990
    Reset), then the Bus Device Reset CCB's Command field will have been set
3991
    to the Command so that the interrupt for the completion of the Bus Device
3992
    Reset can call the Completion Routine for the Command.  On successful
3993
    execution of a Bus Device Reset, older firmware versions did return the
3994
    pending CCBs with the appropriate completion code, but more recent firmware
3995
    versions only return the Bus Device Reset CCB itself.  This driver handles
3996
    both cases by marking all the currently executing CCBs to this Target
3997
    Device as Reset.  When the Bus Device Reset CCB is processed by the
3998
    interrupt handler, any remaining CCBs marked as Reset will have completion
3999
    processing performed.
4000
  */
4001
  BusLogic_IncrementErrorCounter(
4002
    &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsAttempted);
4003
  HostAdapter->BusDeviceResetPendingCCB[TargetID] = CCB;
4004
  HostAdapter->LastResetAttempted[TargetID] = jiffies;
4005
  for (XCCB = HostAdapter->All_CCBs; XCCB != NULL; XCCB = XCCB->NextAll)
4006
    if (XCCB->Status == BusLogic_CCB_Active && XCCB->TargetID == TargetID)
4007
      XCCB->Status = BusLogic_CCB_Reset;
4008
  /*
4009
    FlashPoint Host Adapters may have already completed the Bus Device
4010
    Reset and BusLogic_QueueCompletedCCB been called, or it may still be
4011
    pending.
4012
  */
4013
  Result = SCSI_RESET_PENDING;
4014
  if (BusLogic_FlashPointHostAdapterP(HostAdapter))
4015
    if (CCB->Status == BusLogic_CCB_Completed)
4016
      {
4017
        BusLogic_ProcessCompletedCCBs(HostAdapter);
4018
        Result = SCSI_RESET_SUCCESS;
4019
      }
4020
  /*
4021
    If a Bus Device Reset was not possible for some reason, force a full
4022
    Host Adapter Hard Reset and SCSI Bus Reset.
4023
  */
4024
Done:
4025
  if (Result < 0)
4026
    Result = BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
4027
  /*
4028
    Release exclusive access to Host Adapter.
4029
  */
4030
  BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
4031
  return Result;
4032
}
4033
 
4034
 
4035
/*
4036
  BusLogic_ResetCommand takes appropriate action to reset Command.
4037
*/
4038
 
4039
int BusLogic_ResetCommand(SCSI_Command_T *Command, unsigned int ResetFlags)
4040
{
4041
  BusLogic_HostAdapter_T *HostAdapter =
4042
    (BusLogic_HostAdapter_T *) Command->host->hostdata;
4043
  int TargetID = Command->target;
4044
  BusLogic_ErrorRecoveryStrategy_T
4045
    ErrorRecoveryStrategy = HostAdapter->ErrorRecoveryStrategy[TargetID];
4046
  /*
4047
    Disable Tagged Queuing if it is active for this Target Device and if
4048
    it has been less than 10 minutes since the last reset occurred, or since
4049
    the system was initialized if no prior resets have occurred.
4050
  */
4051
  if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
4052
      jiffies - HostAdapter->LastResetCompleted[TargetID] < 10*60*HZ)
4053
    {
4054
      HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
4055
      HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
4056
      BusLogic_Warning("Tagged Queuing now disabled for Target %d\n",
4057
                       HostAdapter, TargetID);
4058
    }
4059
  switch (ErrorRecoveryStrategy)
4060
    {
4061
    case BusLogic_ErrorRecovery_Default:
4062
      if (ResetFlags & SCSI_RESET_SUGGEST_HOST_RESET)
4063
        return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
4064
      else if (ResetFlags & SCSI_RESET_SUGGEST_BUS_RESET)
4065
        return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
4066
      /* Fall through to Bus Device Reset case. */
4067
    case BusLogic_ErrorRecovery_BusDeviceReset:
4068
      /*
4069
        The Bus Device Reset Error Recovery Strategy only graduates to a Hard
4070
        Reset when no commands have completed successfully since the last Bus
4071
        Device Reset and it has been at least 100 milliseconds.  This prevents
4072
        a sequence of commands that all timeout together from immediately
4073
        forcing a Hard Reset before the Bus Device Reset has had a chance to
4074
        clear the error condition.
4075
      */
4076
      if (HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag ||
4077
          jiffies - HostAdapter->LastResetAttempted[TargetID] < HZ/10)
4078
        {
4079
          HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
4080
          return BusLogic_SendBusDeviceReset(HostAdapter, Command, ResetFlags);
4081
        }
4082
      /* Fall through to Hard Reset case. */
4083
    case BusLogic_ErrorRecovery_HardReset:
4084
      return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
4085
    case BusLogic_ErrorRecovery_None:
4086
      BusLogic_Warning("Error Recovery for Target %d Suppressed\n",
4087
                       HostAdapter, TargetID);
4088
      break;
4089
    }
4090
  return SCSI_RESET_PUNT;
4091
}
4092
 
4093
 
4094
/*
4095
  BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk
4096
  Parameters for Disk.  The default disk geometry is 64 heads, 32 sectors, and
4097
  the appropriate number of cylinders so as not to exceed drive capacity.  In
4098
  order for disks equal to or larger than 1 GB to be addressable by the BIOS
4099
  without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
4100
  may be enabled in AutoSCSI on FlashPoint Host Adapters and on "W" and "C"
4101
  series MultiMaster Host Adapters, or by a dip switch setting on "S" and "A"
4102
  series MultiMaster Host Adapters.  With Extended Translation enabled, drives
4103
  between 1 GB inclusive and 2 GB exclusive are given a disk geometry of 128
4104
  heads and 32 sectors, and drives above 2 GB inclusive are given a disk
4105
  geometry of 255 heads and 63 sectors.  However, if the BIOS detects that the
4106
  Extended Translation setting does not match the geometry in the partition
4107
  table, then the translation inferred from the partition table will be used by
4108
  the BIOS, and a warning may be displayed.
4109
*/
4110
 
4111
int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device,
4112
                                int *Parameters)
4113
{
4114
  BusLogic_HostAdapter_T *HostAdapter =
4115
    (BusLogic_HostAdapter_T *) Disk->device->host->hostdata;
4116
  BIOS_DiskParameters_T *DiskParameters = (BIOS_DiskParameters_T *) Parameters;
4117
  struct buffer_head *BufferHead;
4118
  if (HostAdapter->ExtendedTranslationEnabled &&
4119
      Disk->capacity >= 2*1024*1024 /* 1 GB in 512 byte sectors */)
4120
    {
4121
      if (Disk->capacity >= 4*1024*1024 /* 2 GB in 512 byte sectors */)
4122
        {
4123
          DiskParameters->Heads = 255;
4124
          DiskParameters->Sectors = 63;
4125
        }
4126
      else
4127
        {
4128
          DiskParameters->Heads = 128;
4129
          DiskParameters->Sectors = 32;
4130
        }
4131
    }
4132
  else
4133
    {
4134
      DiskParameters->Heads = 64;
4135
      DiskParameters->Sectors = 32;
4136
    }
4137
  DiskParameters->Cylinders =
4138
    Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
4139
  /*
4140
    Attempt to read the first 1024 bytes from the disk device.
4141
  */
4142
  BufferHead = bread(MKDEV(MAJOR(Device), MINOR(Device) & ~0x0F), 0, 1024);
4143
  if (BufferHead == NULL) return 0;
4144
  /*
4145
    If the boot sector partition table flag is valid, search for a partition
4146
    table entry whose end_head matches one of the standard BusLogic geometry
4147
    translations (64/32, 128/32, or 255/63).
4148
  */
4149
  if (*(unsigned short *) (BufferHead->b_data + 0x1FE) == 0xAA55)
4150
    {
4151
      PartitionTable_T *FirstPartitionEntry =
4152
        (PartitionTable_T *) (BufferHead->b_data + 0x1BE);
4153
      PartitionTable_T *PartitionEntry = FirstPartitionEntry;
4154
      int SavedCylinders = DiskParameters->Cylinders, PartitionNumber;
4155
      unsigned char PartitionEntryEndHead, PartitionEntryEndSector;
4156
      for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++)
4157
        {
4158
          PartitionEntryEndHead = PartitionEntry->end_head;
4159
          PartitionEntryEndSector = PartitionEntry->end_sector & 0x3F;
4160
          if (PartitionEntryEndHead == 64-1)
4161
            {
4162
              DiskParameters->Heads = 64;
4163
              DiskParameters->Sectors = 32;
4164
              break;
4165
            }
4166
          else if (PartitionEntryEndHead == 128-1)
4167
            {
4168
              DiskParameters->Heads = 128;
4169
              DiskParameters->Sectors = 32;
4170
              break;
4171
            }
4172
          else if (PartitionEntryEndHead == 255-1)
4173
            {
4174
              DiskParameters->Heads = 255;
4175
              DiskParameters->Sectors = 63;
4176
              break;
4177
            }
4178
          PartitionEntry++;
4179
        }
4180
      if (PartitionNumber == 4)
4181
        {
4182
          PartitionEntryEndHead = FirstPartitionEntry->end_head;
4183
          PartitionEntryEndSector = FirstPartitionEntry->end_sector & 0x3F;
4184
        }
4185
      DiskParameters->Cylinders =
4186
        Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
4187
      if (PartitionNumber < 4 &&
4188
          PartitionEntryEndSector == DiskParameters->Sectors)
4189
        {
4190
          if (DiskParameters->Cylinders != SavedCylinders)
4191
            BusLogic_Warning("Adopting Geometry %d/%d from Partition Table\n",
4192
                             HostAdapter,
4193
                             DiskParameters->Heads, DiskParameters->Sectors);
4194
        }
4195
      else if (PartitionEntryEndHead > 0 || PartitionEntryEndSector > 0)
4196
        {
4197
          BusLogic_Warning("Warning: Partition Table appears to "
4198
                           "have Geometry %d/%d which is\n", HostAdapter,
4199
                           PartitionEntryEndHead + 1,
4200
                           PartitionEntryEndSector);
4201
          BusLogic_Warning("not compatible with current BusLogic "
4202
                           "Host Adapter Geometry %d/%d\n", HostAdapter,
4203
                           DiskParameters->Heads, DiskParameters->Sectors);
4204
        }
4205
    }
4206
  brelse(BufferHead);
4207
  return 0;
4208
}
4209
 
4210
 
4211
/*
4212
  BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>.
4213
*/
4214
 
4215
int BusLogic_ProcDirectoryInfo(char *ProcBuffer, char **StartPointer,
4216
                               off_t Offset, int BytesAvailable,
4217
                               int HostNumber, int WriteFlag)
4218
{
4219
  BusLogic_HostAdapter_T *HostAdapter;
4220
  BusLogic_TargetStatistics_T *TargetStatistics;
4221
  int TargetID, Length;
4222
  char *Buffer;
4223
  for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
4224
       HostAdapter != NULL;
4225
       HostAdapter = HostAdapter->Next)
4226
    if (HostAdapter->HostNumber == HostNumber) break;
4227
  if (HostAdapter == NULL)
4228
    {
4229
      BusLogic_Error("Cannot find Host Adapter for SCSI Host %d\n",
4230
                     NULL, HostNumber);
4231
      return 0;
4232
    }
4233
  TargetStatistics = HostAdapter->TargetStatistics;
4234
  if (WriteFlag)
4235
    {
4236
      HostAdapter->ExternalHostAdapterResets = 0;
4237
      HostAdapter->HostAdapterInternalErrors = 0;
4238
      memset(TargetStatistics, 0,
4239
             BusLogic_MaxTargetDevices * sizeof(BusLogic_TargetStatistics_T));
4240
      return 0;
4241
    }
4242
  Buffer = HostAdapter->MessageBuffer;
4243
  Length = HostAdapter->MessageBufferLength;
4244
  Length += sprintf(&Buffer[Length], "\n\
4245
Current Driver Queue Depth:     %d\n\
4246
Currently Allocated CCBs:       %d\n",
4247
                    HostAdapter->DriverQueueDepth,
4248
                    HostAdapter->AllocatedCCBs);
4249
  Length += sprintf(&Buffer[Length], "\n\n\
4250
                           DATA TRANSFER STATISTICS\n\
4251
\n\
4252
Target  Tagged Queuing  Queue Depth  Active  Attempted  Completed\n\
4253
======  ==============  ===========  ======  =========  =========\n");
4254
  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4255
    {
4256
      BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4257
      if (!TargetFlags->TargetExists) continue;
4258
      Length +=
4259
        sprintf(&Buffer[Length], "  %2d %s", TargetID,
4260
                (TargetFlags->TaggedQueuingSupported
4261
                 ? (TargetFlags->TaggedQueuingActive
4262
                    ? "    Active"
4263
                    : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)
4264
                       ? "  Permitted" : "   Disabled"))
4265
                 : "Not Supported"));
4266
      Length += sprintf(&Buffer[Length],
4267
                        "           %3d       %3u    %9u        %9u\n",
4268
                        HostAdapter->QueueDepth[TargetID],
4269
                        HostAdapter->ActiveCommands[TargetID],
4270
                        TargetStatistics[TargetID].CommandsAttempted,
4271
                        TargetStatistics[TargetID].CommandsCompleted);
4272
    }
4273
  Length += sprintf(&Buffer[Length], "\n\
4274
Target  Read Commands  Write Commands   Total Bytes Read    Total Bytes Written\n\
4275
======  =============  ==============  ===================  ===================\n");
4276
  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4277
    {
4278
      BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4279
      if (!TargetFlags->TargetExists) continue;
4280
      Length +=
4281
        sprintf(&Buffer[Length], "  %2d   %9u    %9u", TargetID,
4282
                TargetStatistics[TargetID].ReadCommands,
4283
                TargetStatistics[TargetID].WriteCommands);
4284
      if (TargetStatistics[TargetID].TotalBytesRead.Billions > 0)
4285
        Length +=
4286
          sprintf(&Buffer[Length], "     %9u%09u",
4287
                  TargetStatistics[TargetID].TotalBytesRead.Billions,
4288
                  TargetStatistics[TargetID].TotalBytesRead.Units);
4289
      else
4290
        Length +=
4291
          sprintf(&Buffer[Length], "            %9u",
4292
                  TargetStatistics[TargetID].TotalBytesRead.Units);
4293
      if (TargetStatistics[TargetID].TotalBytesWritten.Billions > 0)
4294
        Length +=
4295
          sprintf(&Buffer[Length], "   %9u%09u\n",
4296
                  TargetStatistics[TargetID].TotalBytesWritten.Billions,
4297
                  TargetStatistics[TargetID].TotalBytesWritten.Units);
4298
      else
4299
        Length +=
4300
          sprintf(&Buffer[Length], "         %9u\n",
4301
                  TargetStatistics[TargetID].TotalBytesWritten.Units);
4302
    }
4303
  Length += sprintf(&Buffer[Length], "\n\
4304
Target  Command    0-1KB      1-2KB      2-4KB      4-8KB     8-16KB\n\
4305
======  =======  =========  =========  =========  =========  =========\n");
4306
  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4307
    {
4308
      BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4309
      if (!TargetFlags->TargetExists) continue;
4310
      Length +=
4311
        sprintf(&Buffer[Length],
4312
                "  %2d   Read    %9u  %9u  %9u  %9u  %9u\n", TargetID,
4313
                TargetStatistics[TargetID].ReadCommandSizeBuckets[0],
4314
                TargetStatistics[TargetID].ReadCommandSizeBuckets[1],
4315
                TargetStatistics[TargetID].ReadCommandSizeBuckets[2],
4316
                TargetStatistics[TargetID].ReadCommandSizeBuckets[3],
4317
                TargetStatistics[TargetID].ReadCommandSizeBuckets[4]);
4318
      Length +=
4319
        sprintf(&Buffer[Length],
4320
                "  %2d   Write   %9u  %9u  %9u  %9u  %9u\n", TargetID,
4321
                TargetStatistics[TargetID].WriteCommandSizeBuckets[0],
4322
                TargetStatistics[TargetID].WriteCommandSizeBuckets[1],
4323
                TargetStatistics[TargetID].WriteCommandSizeBuckets[2],
4324
                TargetStatistics[TargetID].WriteCommandSizeBuckets[3],
4325
                TargetStatistics[TargetID].WriteCommandSizeBuckets[4]);
4326
    }
4327
  Length += sprintf(&Buffer[Length], "\n\
4328
Target  Command   16-32KB    32-64KB   64-128KB   128-256KB   256KB+\n\
4329
======  =======  =========  =========  =========  =========  =========\n");
4330
  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4331
    {
4332
      BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4333
      if (!TargetFlags->TargetExists) continue;
4334
      Length +=
4335
        sprintf(&Buffer[Length],
4336
                "  %2d   Read    %9u  %9u  %9u  %9u  %9u\n", TargetID,
4337
                TargetStatistics[TargetID].ReadCommandSizeBuckets[5],
4338
                TargetStatistics[TargetID].ReadCommandSizeBuckets[6],
4339
                TargetStatistics[TargetID].ReadCommandSizeBuckets[7],
4340
                TargetStatistics[TargetID].ReadCommandSizeBuckets[8],
4341
                TargetStatistics[TargetID].ReadCommandSizeBuckets[9]);
4342
      Length +=
4343
        sprintf(&Buffer[Length],
4344
                "  %2d   Write   %9u  %9u  %9u  %9u  %9u\n", TargetID,
4345
                TargetStatistics[TargetID].WriteCommandSizeBuckets[5],
4346
                TargetStatistics[TargetID].WriteCommandSizeBuckets[6],
4347
                TargetStatistics[TargetID].WriteCommandSizeBuckets[7],
4348
                TargetStatistics[TargetID].WriteCommandSizeBuckets[8],
4349
                TargetStatistics[TargetID].WriteCommandSizeBuckets[9]);
4350
    }
4351
  Length += sprintf(&Buffer[Length], "\n\n\
4352
                           ERROR RECOVERY STATISTICS\n\
4353
\n\
4354
          Command Aborts      Bus Device Resets   Host Adapter Resets\n\
4355
Target  Requested Completed  Requested Completed  Requested Completed\n\
4356
  ID    \\\\\\\\ Attempted ////  \\\\\\\\ Attempted ////  \\\\\\\\ Attempted ////\n\
4357
======   ===== ===== =====    ===== ===== =====    ===== ===== =====\n");
4358
  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4359
    {
4360
      BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4361
      if (!TargetFlags->TargetExists) continue;
4362
      Length +=
4363
        sprintf(&Buffer[Length], "\
4364
  %2d    %5d %5d %5d    %5d %5d %5d        %5d %5d %5d\n", TargetID,
4365
                TargetStatistics[TargetID].CommandAbortsRequested,
4366
                TargetStatistics[TargetID].CommandAbortsAttempted,
4367
                TargetStatistics[TargetID].CommandAbortsCompleted,
4368
                TargetStatistics[TargetID].BusDeviceResetsRequested,
4369
                TargetStatistics[TargetID].BusDeviceResetsAttempted,
4370
                TargetStatistics[TargetID].BusDeviceResetsCompleted,
4371
                TargetStatistics[TargetID].HostAdapterResetsRequested,
4372
                TargetStatistics[TargetID].HostAdapterResetsAttempted,
4373
                TargetStatistics[TargetID].HostAdapterResetsCompleted);
4374
    }
4375
  Length += sprintf(&Buffer[Length], "\nExternal Host Adapter Resets: %d\n",
4376
                    HostAdapter->ExternalHostAdapterResets);
4377
  Length += sprintf(&Buffer[Length], "Host Adapter Internal Errors: %d\n",
4378
                    HostAdapter->HostAdapterInternalErrors);
4379
  if (Length >= BusLogic_MessageBufferSize)
4380
    BusLogic_Error("Message Buffer length %d exceeds size %d\n",
4381
                   HostAdapter, Length, BusLogic_MessageBufferSize);
4382
  if ((Length -= Offset) <= 0) return 0;
4383
  if (Length >= BytesAvailable) Length = BytesAvailable;
4384
  *StartPointer = &HostAdapter->MessageBuffer[Offset];
4385
  return Length;
4386
}
4387
 
4388
 
4389
/*
4390
  BusLogic_Message prints Driver Messages.
4391
*/
4392
 
4393
static void BusLogic_Message(BusLogic_MessageLevel_T MessageLevel,
4394
                             char *Format,
4395
                             BusLogic_HostAdapter_T *HostAdapter,
4396
                             ...)
4397
{
4398
  static char Buffer[BusLogic_LineBufferSize];
4399
  static boolean BeginningOfLine = true;
4400
  va_list Arguments;
4401
  int Length = 0;
4402
  va_start(Arguments, HostAdapter);
4403
  Length = vsprintf(Buffer, Format, Arguments);
4404
  va_end(Arguments);
4405
  if (MessageLevel == BusLogic_AnnounceLevel)
4406
    {
4407
      static int AnnouncementLines = 0;
4408
      strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength],
4409
             Buffer);
4410
      HostAdapter->MessageBufferLength += Length;
4411
      if (++AnnouncementLines <= 2)
4412
        printk("%sscsi: %s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
4413
    }
4414
  else if (MessageLevel == BusLogic_InfoLevel)
4415
    {
4416
      strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength],
4417
             Buffer);
4418
      HostAdapter->MessageBufferLength += Length;
4419
      if (BeginningOfLine)
4420
        {
4421
          if (Buffer[0] != '\n' || Length > 1)
4422
            printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
4423
                   HostAdapter->HostNumber, Buffer);
4424
        }
4425
      else printk("%s", Buffer);
4426
    }
4427
  else
4428
    {
4429
      if (BeginningOfLine)
4430
        {
4431
          if (HostAdapter != NULL && HostAdapter->HostAdapterInitialized)
4432
            printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
4433
                   HostAdapter->HostNumber, Buffer);
4434
          else printk("%s%s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
4435
        }
4436
      else printk("%s", Buffer);
4437
    }
4438
  BeginningOfLine = (Buffer[Length-1] == '\n');
4439
}
4440
 
4441
 
4442
/*
4443
  BusLogic_ParseKeyword parses an individual option keyword.  It returns true
4444
  and updates the pointer if the keyword is recognized and false otherwise.
4445
*/
4446
 
4447
static boolean BusLogic_ParseKeyword(char **StringPointer, char *Keyword)
4448
{
4449
  char *Pointer = *StringPointer;
4450
  while (*Keyword != '\0')
4451
    {
4452
      char StringChar = *Pointer++;
4453
      char KeywordChar = *Keyword++;
4454
      if (StringChar >= 'A' && StringChar <= 'Z')
4455
        StringChar += 'a' - 'Z';
4456
      if (KeywordChar >= 'A' && KeywordChar <= 'Z')
4457
        KeywordChar += 'a' - 'Z';
4458
      if (StringChar != KeywordChar) return false;
4459
    }
4460
  *StringPointer = Pointer;
4461
  return true;
4462
}
4463
 
4464
 
4465
/*
4466
  BusLogic_ParseDriverOptions handles processing of BusLogic Driver Options
4467
  specifications.
4468
 
4469
  BusLogic Driver Options may be specified either via the Linux Kernel Command
4470
  Line or via the Loadable Kernel Module Installation Facility.  Driver Options
4471
  for multiple host adapters may be specified either by separating the option
4472
  strings by a semicolon, or by specifying multiple "BusLogic=" strings on the
4473
  command line.  Individual option specifications for a single host adapter are
4474
  separated by commas.  The Probing and Debugging Options apply to all host
4475
  adapters whereas the remaining options apply individually only to the
4476
  selected host adapter.
4477
 
4478
  The BusLogic Driver Probing Options comprise the following:
4479
 
4480
  IO:<integer>
4481
 
4482
    The "IO:" option specifies an ISA I/O Address to be probed for a non-PCI
4483
    MultiMaster Host Adapter.  If neither "IO:" nor "NoProbeISA" options are
4484
    specified, then the standard list of BusLogic MultiMaster ISA I/O Addresses
4485
    will be probed (0x330, 0x334, 0x230, 0x234, 0x130, and 0x134).  Multiple
4486
    "IO:" options may be specified to precisely determine the I/O Addresses to
4487
    be probed, but the probe order will always follow the standard list.
4488
 
4489
  NoProbe
4490
 
4491
    The "NoProbe" option disables all probing and therefore no BusLogic Host
4492
    Adapters will be detected.
4493
 
4494
  NoProbeISA
4495
 
4496
    The "NoProbeISA" option disables probing of the standard BusLogic ISA I/O
4497
    Addresses and therefore only PCI MultiMaster and FlashPoint Host Adapters
4498
    will be detected.
4499
 
4500
  NoProbePCI
4501
 
4502
    The "NoProbePCI" options disables the interrogation of PCI Configuration
4503
    Space and therefore only ISA Multimaster Host Adapters will be detected, as
4504
    well as PCI Multimaster Host Adapters that have their ISA Compatible I/O
4505
    Port set to "Primary" or "Alternate".
4506
 
4507
  NoSortPCI
4508
 
4509
    The "NoSortPCI" option forces PCI MultiMaster Host Adapters to be
4510
    enumerated in the order provided by the PCI BIOS, ignoring any setting of
4511
    the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option.
4512
 
4513
  MultiMasterFirst
4514
 
4515
    The "MultiMasterFirst" option forces MultiMaster Host Adapters to be probed
4516
    before FlashPoint Host Adapters.  By default, if both FlashPoint and PCI
4517
    MultiMaster Host Adapters are present, this driver will probe for
4518
    FlashPoint Host Adapters first unless the BIOS primary disk is controlled
4519
    by the first PCI MultiMaster Host Adapter, in which case MultiMaster Host
4520
    Adapters will be probed first.
4521
 
4522
  FlashPointFirst
4523
 
4524
    The "FlashPointFirst" option forces FlashPoint Host Adapters to be probed
4525
    before MultiMaster Host Adapters.
4526
 
4527
  The BusLogic Driver Tagged Queuing Options allow for explicitly specifying
4528
  the Queue Depth and whether Tagged Queuing is permitted for each Target
4529
  Device (assuming that the Target Device supports Tagged Queuing).  The Queue
4530
  Depth is the number of SCSI Commands that are allowed to be concurrently
4531
  presented for execution (either to the Host Adapter or Target Device).  Note
4532
  that explicitly enabling Tagged Queuing may lead to problems; the option to
4533
  enable or disable Tagged Queuing is provided primarily to allow disabling
4534
  Tagged Queuing on Target Devices that do not implement it correctly.  The
4535
  following options are available:
4536
 
4537
  QueueDepth:<integer>
4538
 
4539
    The "QueueDepth:" or QD:" option specifies the Queue Depth to use for all
4540
    Target Devices that support Tagged Queuing, as well as the maximum Queue
4541
    Depth for devices that do not support Tagged Queuing.  If no Queue Depth
4542
    option is provided, the Queue Depth will be determined automatically based
4543
    on the Host Adapter's Total Queue Depth and the number, type, speed, and
4544
    capabilities of the detected Target Devices.  For Host Adapters that
4545
    require ISA Bounce Buffers, the Queue Depth is automatically set by default
4546
    to BusLogic_TaggedQueueDepthBB or BusLogic_UntaggedQueueDepthBB to avoid
4547
    excessive preallocation of DMA Bounce Buffer memory.  Target Devices that
4548
    do not support Tagged Queuing always have their Queue Depth set to
4549
    BusLogic_UntaggedQueueDepth or BusLogic_UntaggedQueueDepthBB, unless a
4550
    lower Queue Depth option is provided.  A Queue Depth of 1 automatically
4551
    disables Tagged Queuing.
4552
 
4553
  QueueDepth:[<integer>,<integer>...]
4554
 
4555
    The "QueueDepth:[...]" or "QD:[...]" option specifies the Queue Depth
4556
    individually for each Target Device.  If an <integer> is omitted, the
4557
    associated Target Device will have its Queue Depth selected automatically.
4558
 
4559
  TaggedQueuing:Default
4560
 
4561
    The "TaggedQueuing:Default" or "TQ:Default" option permits Tagged Queuing
4562
    based on the firmware version of the BusLogic Host Adapter and based on
4563
    whether the Queue Depth allows queuing multiple commands.
4564
 
4565
  TaggedQueuing:Enable
4566
 
4567
    The "TaggedQueuing:Enable" or "TQ:Enable" option enables Tagged Queuing for
4568
    all Target Devices on this Host Adapter, overriding any limitation that
4569
    would otherwise be imposed based on the Host Adapter firmware version.
4570
 
4571
  TaggedQueuing:Disable
4572
 
4573
    The "TaggedQueuing:Disable" or "TQ:Disable" option disables Tagged Queuing
4574
    for all Target Devices on this Host Adapter.
4575
 
4576
  TaggedQueuing:<Target-Spec>
4577
 
4578
    The "TaggedQueuing:<Target-Spec>" or "TQ:<Target-Spec>" option controls
4579
    Tagged Queuing individually for each Target Device.  <Target-Spec> is a
4580
    sequence of "Y", "N", and "X" characters.  "Y" enables Tagged Queuing, "N"
4581
    disables Tagged Queuing, and "X" accepts the default based on the firmware
4582
    version.  The first character refers to Target Device 0, the second to
4583
    Target Device 1, and so on; if the sequence of "Y", "N", and "X" characters
4584
    does not cover all the Target Devices, unspecified characters are assumed
4585
    to be "X".
4586
 
4587
  The BusLogic Driver Error Recovery Option allows for explicitly specifying
4588
  the Error Recovery action to be performed when BusLogic_ResetCommand is
4589
  called due to a SCSI Command failing to complete successfully.  The following
4590
  options are available:
4591
 
4592
  ErrorRecovery:Default
4593
 
4594
    The "ErrorRecovery:Default" or "ER:Default" option selects between the Hard
4595
    Reset and Bus Device Reset options based on the recommendation of the SCSI
4596
    Subsystem.
4597
 
4598
  ErrorRecovery:HardReset
4599
 
4600
    The "ErrorRecovery:HardReset" or "ER:HardReset" option will initiate a Host
4601
    Adapter Hard Reset which also causes a SCSI Bus Reset.
4602
 
4603
  ErrorRecovery:BusDeviceReset
4604
 
4605
    The "ErrorRecovery:BusDeviceReset" or "ER:BusDeviceReset" option will send
4606
    a Bus Device Reset message to the individual Target Device causing the
4607
    error.  If Error Recovery is again initiated for this Target Device and no
4608
    SCSI Command to this Target Device has completed successfully since the Bus
4609
    Device Reset message was sent, then a Hard Reset will be attempted.
4610
 
4611
  ErrorRecovery:None
4612
 
4613
    The "ErrorRecovery:None" or "ER:None" option suppresses Error Recovery.
4614
    This option should only be selected if a SCSI Bus Reset or Bus Device Reset
4615
    will cause the Target Device or a critical operation to suffer a complete
4616
    and unrecoverable failure.
4617
 
4618
  ErrorRecovery:<Target-Spec>
4619
 
4620
    The "ErrorRecovery:<Target-Spec>" or "ER:<Target-Spec>" option controls
4621
    Error Recovery individually for each Target Device.  <Target-Spec> is a
4622
    sequence of "D", "H", "B", and "N" characters.  "D" selects Default, "H"
4623
    selects Hard Reset, "B" selects Bus Device Reset, and "N" selects None.
4624
    The first character refers to Target Device 0, the second to Target Device
4625
    1, and so on; if the sequence of "D", "H", "B", and "N" characters does not
4626
    cover all the possible Target Devices, unspecified characters are assumed
4627
    to be "D".
4628
 
4629
  The BusLogic Driver Miscellaneous Options comprise the following:
4630
 
4631
  BusSettleTime:<seconds>
4632
 
4633
    The "BusSettleTime:" or "BST:" option specifies the Bus Settle Time in
4634
    seconds.  The Bus Settle Time is the amount of time to wait between a Host
4635
    Adapter Hard Reset which initiates a SCSI Bus Reset and issuing any SCSI
4636
    Commands.  If unspecified, it defaults to BusLogic_DefaultBusSettleTime.
4637
 
4638
  InhibitTargetInquiry
4639
 
4640
    The "InhibitTargetInquiry" option inhibits the execution of an Inquire
4641
    Target Devices or Inquire Installed Devices command on MultiMaster Host
4642
    Adapters.  This may be necessary with some older Target Devices that do not
4643
    respond correctly when Logical Units above 0 are addressed.
4644
 
4645
  The BusLogic Driver Debugging Options comprise the following:
4646
 
4647
  TraceProbe
4648
 
4649
    The "TraceProbe" option enables tracing of Host Adapter Probing.
4650
 
4651
  TraceHardwareReset
4652
 
4653
    The "TraceHardwareReset" option enables tracing of Host Adapter Hardware
4654
    Reset.
4655
 
4656
  TraceConfiguration
4657
 
4658
    The "TraceConfiguration" option enables tracing of Host Adapter
4659
    Configuration.
4660
 
4661
  TraceErrors
4662
 
4663
    The "TraceErrors" option enables tracing of SCSI Commands that return an
4664
    error from the Target Device.  The CDB and Sense Data will be printed for
4665
    each SCSI Command that fails.
4666
 
4667
  Debug
4668
 
4669
    The "Debug" option enables all debugging options.
4670
 
4671
  The following examples demonstrate setting the Queue Depth for Target Devices
4672
  1 and 2 on the first host adapter to 7 and 15, the Queue Depth for all Target
4673
  Devices on the second host adapter to 31, and the Bus Settle Time on the
4674
  second host adapter to 30 seconds.
4675
 
4676
  Linux Kernel Command Line:
4677
 
4678
    linux BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30
4679
 
4680
  LILO Linux Boot Loader (in /etc/lilo.conf):
4681
 
4682
    append = "BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"
4683
 
4684
  INSMOD Loadable Kernel Module Installation Facility:
4685
 
4686
    insmod BusLogic.o \
4687
        'BusLogic_Options="QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"'
4688
 
4689
  NOTE: Module Utilities 2.1.71 or later is required for correct parsing
4690
        of driver options containing commas.
4691
 
4692
*/
4693
 
4694
static void BusLogic_ParseDriverOptions(char *OptionsString)
4695
{
4696
  while (true)
4697
    {
4698
      BusLogic_DriverOptions_T *DriverOptions =
4699
        &BusLogic_DriverOptions[BusLogic_DriverOptionsCount++];
4700
      int TargetID;
4701
      memset(DriverOptions, 0, sizeof(BusLogic_DriverOptions_T));
4702
      for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
4703
        DriverOptions->ErrorRecoveryStrategy[TargetID] =
4704
          BusLogic_ErrorRecovery_Default;
4705
      while (*OptionsString != '\0' && *OptionsString != ';')
4706
        {
4707
          /* Probing Options. */
4708
          if (BusLogic_ParseKeyword(&OptionsString, "IO:"))
4709
            {
4710
              BusLogic_IO_Address_T IO_Address =
4711
                simple_strtoul(OptionsString, &OptionsString, 0);
4712
              BusLogic_ProbeOptions.LimitedProbeISA = true;
4713
              switch (IO_Address)
4714
                {
4715
                case 0x330:
4716
                  BusLogic_ProbeOptions.Probe330 = true;
4717
                  break;
4718
                case 0x334:
4719
                  BusLogic_ProbeOptions.Probe334 = true;
4720
                  break;
4721
                case 0x230:
4722
                  BusLogic_ProbeOptions.Probe230 = true;
4723
                  break;
4724
                case 0x234:
4725
                  BusLogic_ProbeOptions.Probe234 = true;
4726
                  break;
4727
                case 0x130:
4728
                  BusLogic_ProbeOptions.Probe130 = true;
4729
                  break;
4730
                case 0x134:
4731
                  BusLogic_ProbeOptions.Probe134 = true;
4732
                  break;
4733
                default:
4734
                  BusLogic_Error("BusLogic: Invalid Driver Options "
4735
                                 "(illegal I/O Address 0x%X)\n",
4736
                                 NULL, IO_Address);
4737
                  return;
4738
                }
4739
            }
4740
          else if (BusLogic_ParseKeyword(&OptionsString, "NoProbeISA"))
4741
            BusLogic_ProbeOptions.NoProbeISA = true;
4742
          else if (BusLogic_ParseKeyword(&OptionsString, "NoProbePCI"))
4743
            BusLogic_ProbeOptions.NoProbePCI = true;
4744
          else if (BusLogic_ParseKeyword(&OptionsString, "NoProbe"))
4745
            BusLogic_ProbeOptions.NoProbe = true;
4746
          else if (BusLogic_ParseKeyword(&OptionsString, "NoSortPCI"))
4747
            BusLogic_ProbeOptions.NoSortPCI = true;
4748
          else if (BusLogic_ParseKeyword(&OptionsString, "MultiMasterFirst"))
4749
            BusLogic_ProbeOptions.MultiMasterFirst = true;
4750
          else if (BusLogic_ParseKeyword(&OptionsString, "FlashPointFirst"))
4751
            BusLogic_ProbeOptions.FlashPointFirst = true;
4752
          /* Tagged Queuing Options. */
4753
          else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:[") ||
4754
                   BusLogic_ParseKeyword(&OptionsString, "QD:["))
4755
            {
4756
              for (TargetID = 0;
4757
                   TargetID < BusLogic_MaxTargetDevices;
4758
                   TargetID++)
4759
                {
4760
                  unsigned short QueueDepth =
4761
                    simple_strtoul(OptionsString, &OptionsString, 0);
4762
                  if (QueueDepth > BusLogic_MaxTaggedQueueDepth)
4763
                    {
4764
                      BusLogic_Error("BusLogic: Invalid Driver Options "
4765
                                     "(illegal Queue Depth %d)\n",
4766
                                     NULL, QueueDepth);
4767
                      return;
4768
                    }
4769
                  DriverOptions->QueueDepth[TargetID] = QueueDepth;
4770
                  if (*OptionsString == ',')
4771
                    OptionsString++;
4772
                  else if (*OptionsString == ']')
4773
                    break;
4774
                  else
4775
                    {
4776
                      BusLogic_Error("BusLogic: Invalid Driver Options "
4777
                                     "(',' or ']' expected at '%s')\n",
4778
                                     NULL, OptionsString);
4779
                      return;
4780
                    }
4781
                }
4782
              if (*OptionsString != ']')
4783
                {
4784
                  BusLogic_Error("BusLogic: Invalid Driver Options "
4785
                                 "(']' expected at '%s')\n",
4786
                                 NULL, OptionsString);
4787
                  return;
4788
                }
4789
              else OptionsString++;
4790
            }
4791
          else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:") ||
4792
                   BusLogic_ParseKeyword(&OptionsString, "QD:"))
4793
            {
4794
              unsigned short QueueDepth =
4795
                simple_strtoul(OptionsString, &OptionsString, 0);
4796
              if (QueueDepth == 0 || QueueDepth > BusLogic_MaxTaggedQueueDepth)
4797
                {
4798
                  BusLogic_Error("BusLogic: Invalid Driver Options "
4799
                                 "(illegal Queue Depth %d)\n",
4800
                                 NULL, QueueDepth);
4801
                  return;
4802
                }
4803
              DriverOptions->CommonQueueDepth = QueueDepth;
4804
              for (TargetID = 0;
4805
                   TargetID < BusLogic_MaxTargetDevices;
4806
                   TargetID++)
4807
                DriverOptions->QueueDepth[TargetID] = QueueDepth;
4808
            }
4809
          else if (BusLogic_ParseKeyword(&OptionsString, "TaggedQueuing:") ||
4810
                   BusLogic_ParseKeyword(&OptionsString, "TQ:"))
4811
            {
4812
              if (BusLogic_ParseKeyword(&OptionsString, "Default"))
4813
                {
4814
                  DriverOptions->TaggedQueuingPermitted = 0x0000;
4815
                  DriverOptions->TaggedQueuingPermittedMask = 0x0000;
4816
                }
4817
              else if (BusLogic_ParseKeyword(&OptionsString, "Enable"))
4818
                {
4819
                  DriverOptions->TaggedQueuingPermitted = 0xFFFF;
4820
                  DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
4821
                }
4822
              else if (BusLogic_ParseKeyword(&OptionsString, "Disable"))
4823
                {
4824
                  DriverOptions->TaggedQueuingPermitted = 0x0000;
4825
                  DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
4826
                }
4827
              else
4828
                {
4829
                  unsigned short TargetBit;
4830
                  for (TargetID = 0, TargetBit = 1;
4831
                       TargetID < BusLogic_MaxTargetDevices;
4832
                       TargetID++, TargetBit <<= 1)
4833
                    switch (*OptionsString++)
4834
                      {
4835
                      case 'Y':
4836
                        DriverOptions->TaggedQueuingPermitted |= TargetBit;
4837
                        DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
4838
                        break;
4839
                      case 'N':
4840
                        DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
4841
                        DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
4842
                        break;
4843
                      case 'X':
4844
                        break;
4845
                      default:
4846
                        OptionsString--;
4847
                        TargetID = BusLogic_MaxTargetDevices;
4848
                        break;
4849
                      }
4850
                }
4851
            }
4852
          /* Error Recovery Option. */
4853
          else if (BusLogic_ParseKeyword(&OptionsString, "ErrorRecovery:") ||
4854
                   BusLogic_ParseKeyword(&OptionsString, "ER:"))
4855
            {
4856
              if (BusLogic_ParseKeyword(&OptionsString, "Default"))
4857
                for (TargetID = 0;
4858
                     TargetID < BusLogic_MaxTargetDevices;
4859
                     TargetID++)
4860
                  DriverOptions->ErrorRecoveryStrategy[TargetID] =
4861
                    BusLogic_ErrorRecovery_Default;
4862
              else if (BusLogic_ParseKeyword(&OptionsString, "HardReset"))
4863
                for (TargetID = 0;
4864
                     TargetID < BusLogic_MaxTargetDevices;
4865
                     TargetID++)
4866
                  DriverOptions->ErrorRecoveryStrategy[TargetID] =
4867
                    BusLogic_ErrorRecovery_HardReset;
4868
              else if (BusLogic_ParseKeyword(&OptionsString, "BusDeviceReset"))
4869
                for (TargetID = 0;
4870
                     TargetID < BusLogic_MaxTargetDevices;
4871
                     TargetID++)
4872
                  DriverOptions->ErrorRecoveryStrategy[TargetID] =
4873
                    BusLogic_ErrorRecovery_BusDeviceReset;
4874
              else if (BusLogic_ParseKeyword(&OptionsString, "None"))
4875
                for (TargetID = 0;
4876
                     TargetID < BusLogic_MaxTargetDevices;
4877
                     TargetID++)
4878
                  DriverOptions->ErrorRecoveryStrategy[TargetID] =
4879
                    BusLogic_ErrorRecovery_None;
4880
              else
4881
                for (TargetID = 0;
4882
                     TargetID < BusLogic_MaxTargetDevices;
4883
                     TargetID++)
4884
                  switch (*OptionsString++)
4885
                    {
4886
                    case 'D':
4887
                      DriverOptions->ErrorRecoveryStrategy[TargetID] =
4888
                        BusLogic_ErrorRecovery_Default;
4889
                      break;
4890
                    case 'H':
4891
                      DriverOptions->ErrorRecoveryStrategy[TargetID] =
4892
                        BusLogic_ErrorRecovery_HardReset;
4893
                      break;
4894
                    case 'B':
4895
                      DriverOptions->ErrorRecoveryStrategy[TargetID] =
4896
                        BusLogic_ErrorRecovery_BusDeviceReset;
4897
                      break;
4898
                    case 'N':
4899
                      DriverOptions->ErrorRecoveryStrategy[TargetID] =
4900
                        BusLogic_ErrorRecovery_None;
4901
                      break;
4902
                    default:
4903
                      OptionsString--;
4904
                      TargetID = BusLogic_MaxTargetDevices;
4905
                      break;
4906
                    }
4907
            }
4908
          /* Miscellaneous Options. */
4909
          else if (BusLogic_ParseKeyword(&OptionsString, "BusSettleTime:") ||
4910
                   BusLogic_ParseKeyword(&OptionsString, "BST:"))
4911
            {
4912
              unsigned short BusSettleTime =
4913
                simple_strtoul(OptionsString, &OptionsString, 0);
4914
              if (BusSettleTime > 5 * 60)
4915
                {
4916
                  BusLogic_Error("BusLogic: Invalid Driver Options "
4917
                                 "(illegal Bus Settle Time %d)\n",
4918
                                 NULL, BusSettleTime);
4919
                  return;
4920
                }
4921
              DriverOptions->BusSettleTime = BusSettleTime;
4922
            }
4923
          else if (BusLogic_ParseKeyword(&OptionsString,
4924
                                         "InhibitTargetInquiry"))
4925
            DriverOptions->LocalOptions.InhibitTargetInquiry = true;
4926
          /* Debugging Options. */
4927
          else if (BusLogic_ParseKeyword(&OptionsString, "TraceProbe"))
4928
              BusLogic_GlobalOptions.TraceProbe = true;
4929
          else if (BusLogic_ParseKeyword(&OptionsString, "TraceHardwareReset"))
4930
              BusLogic_GlobalOptions.TraceHardwareReset = true;
4931
          else if (BusLogic_ParseKeyword(&OptionsString, "TraceConfiguration"))
4932
              BusLogic_GlobalOptions.TraceConfiguration = true;
4933
          else if (BusLogic_ParseKeyword(&OptionsString, "TraceErrors"))
4934
              BusLogic_GlobalOptions.TraceErrors = true;
4935
          else if (BusLogic_ParseKeyword(&OptionsString, "Debug"))
4936
            {
4937
              BusLogic_GlobalOptions.TraceProbe = true;
4938
              BusLogic_GlobalOptions.TraceHardwareReset = true;
4939
              BusLogic_GlobalOptions.TraceConfiguration = true;
4940
              BusLogic_GlobalOptions.TraceErrors = true;
4941
            }
4942
          if (*OptionsString == ',')
4943
            OptionsString++;
4944
          else if (*OptionsString != ';' && *OptionsString != '\0')
4945
            {
4946
              BusLogic_Error("BusLogic: Unexpected Driver Option '%s' "
4947
                             "ignored\n", NULL, OptionsString);
4948
              *OptionsString = '\0';
4949
            }
4950
        }
4951
      if (!(BusLogic_DriverOptionsCount == 0 ||
4952
            BusLogic_ProbeInfoCount == 0 ||
4953
            BusLogic_DriverOptionsCount == BusLogic_ProbeInfoCount))
4954
        {
4955
          BusLogic_Error("BusLogic: Invalid Driver Options "
4956
                         "(all or no I/O Addresses must be specified)\n", NULL);
4957
          return;
4958
        }
4959
      /*
4960
        Tagged Queuing is disabled when the Queue Depth is 1 since queuing
4961
        multiple commands is not possible.
4962
      */
4963
      for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
4964
        if (DriverOptions->QueueDepth[TargetID] == 1)
4965
          {
4966
            unsigned short TargetBit = 1 << TargetID;
4967
            DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
4968
            DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
4969
          }
4970
      if (*OptionsString == ';') OptionsString++;
4971
      if (*OptionsString == '\0') return;
4972
    }
4973
}
4974
 
4975
 
4976
/*
4977
  BusLogic_Setup handles processing of Kernel Command Line Arguments.
4978
*/
4979
 
4980
void BusLogic_Setup(char *CommandLineString, int *CommandLineIntegers)
4981
{
4982
  if (CommandLineIntegers[0] != 0)
4983
    {
4984
      BusLogic_Error("BusLogic: Obsolete Command Line Entry "
4985
                     "Format Ignored\n", NULL);
4986
      return;
4987
    }
4988
  if (CommandLineString == NULL || *CommandLineString == '\0') return;
4989
  BusLogic_ParseDriverOptions(CommandLineString);
4990
}
4991
 
4992
 
4993
/*
4994
  Include Module support if requested.
4995
*/
4996
 
4997
#ifdef MODULE
4998
 
4999
SCSI_Host_Template_T driver_template = BUSLOGIC;
5000
 
5001
#include "scsi_module.c"
5002
 
5003
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.