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