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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [scsi/] [BusLogic.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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