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