linux/drivers/scsi/BusLogic.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2
   3/*
   4
   5  Linux Driver for BusLogic MultiMaster and FlashPoint SCSI Host Adapters
   6
   7  Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>
   8
   9
  10  The author respectfully requests that any modifications to this software be
  11  sent directly to him for evaluation and testing.
  12
  13  Special thanks to Wayne Yen, Jin-Lon Hon, and Alex Win of BusLogic, whose
  14  advice has been invaluable, to David Gentzel, for writing the original Linux
  15  BusLogic driver, and to Paul Gortmaker, for being such a dedicated test site.
  16
  17  Finally, special thanks to Mylex/BusLogic for making the FlashPoint SCCB
  18  Manager available as freely redistributable source code.
  19
  20*/
  21
  22#define blogic_drvr_version             "2.1.17"
  23#define blogic_drvr_date                "12 September 2013"
  24
  25#include <linux/module.h>
  26#include <linux/init.h>
  27#include <linux/interrupt.h>
  28#include <linux/types.h>
  29#include <linux/blkdev.h>
  30#include <linux/delay.h>
  31#include <linux/ioport.h>
  32#include <linux/mm.h>
  33#include <linux/stat.h>
  34#include <linux/pci.h>
  35#include <linux/spinlock.h>
  36#include <linux/jiffies.h>
  37#include <linux/dma-mapping.h>
  38#include <linux/slab.h>
  39#include <scsi/scsicam.h>
  40
  41#include <asm/dma.h>
  42#include <asm/io.h>
  43
  44#include <scsi/scsi.h>
  45#include <scsi/scsi_cmnd.h>
  46#include <scsi/scsi_device.h>
  47#include <scsi/scsi_host.h>
  48#include <scsi/scsi_tcq.h>
  49#include "BusLogic.h"
  50#include "FlashPoint.c"
  51
  52#ifndef FAILURE
  53#define FAILURE (-1)
  54#endif
  55
  56static struct scsi_host_template blogic_template;
  57
  58/*
  59  blogic_drvr_options_count is a count of the number of BusLogic Driver
  60  Options specifications provided via the Linux Kernel Command Line or via
  61  the Loadable Kernel Module Installation Facility.
  62*/
  63
  64static int blogic_drvr_options_count;
  65
  66
  67/*
  68  blogic_drvr_options is an array of Driver Options structures representing
  69  BusLogic Driver Options specifications provided via the Linux Kernel Command
  70  Line or via the Loadable Kernel Module Installation Facility.
  71*/
  72
  73static struct blogic_drvr_options blogic_drvr_options[BLOGIC_MAX_ADAPTERS];
  74
  75
  76/*
  77  BusLogic can be assigned a string by insmod.
  78*/
  79
  80MODULE_LICENSE("GPL");
  81#ifdef MODULE
  82static char *BusLogic;
  83module_param(BusLogic, charp, 0);
  84#endif
  85
  86
  87/*
  88  blogic_probe_options is a set of Probe Options to be applied across
  89  all BusLogic Host Adapters.
  90*/
  91
  92static struct blogic_probe_options blogic_probe_options;
  93
  94
  95/*
  96  blogic_global_options is a set of Global Options to be applied across
  97  all BusLogic Host Adapters.
  98*/
  99
 100static struct blogic_global_options blogic_global_options;
 101
 102static LIST_HEAD(blogic_host_list);
 103
 104/*
 105  blogic_probeinfo_count is the number of entries in blogic_probeinfo_list.
 106*/
 107
 108static int blogic_probeinfo_count;
 109
 110
 111/*
 112  blogic_probeinfo_list is the list of I/O Addresses and Bus Probe Information
 113  to be checked for potential BusLogic Host Adapters.  It is initialized by
 114  interrogating the PCI Configuration Space on PCI machines as well as from the
 115  list of standard BusLogic I/O Addresses.
 116*/
 117
 118static struct blogic_probeinfo *blogic_probeinfo_list;
 119
 120
 121/*
 122  blogic_cmd_failure_reason holds a string identifying the reason why a
 123  call to blogic_cmd failed.  It is only non-NULL when blogic_cmd
 124  returns a failure code.
 125*/
 126
 127static char *blogic_cmd_failure_reason;
 128
 129/*
 130  blogic_announce_drvr announces the Driver Version and Date, Author's
 131  Name, Copyright Notice, and Electronic Mail Address.
 132*/
 133
 134static void blogic_announce_drvr(struct blogic_adapter *adapter)
 135{
 136        blogic_announce("***** BusLogic SCSI Driver Version " blogic_drvr_version " of " blogic_drvr_date " *****\n", adapter);
 137        blogic_announce("Copyright 1995-1998 by Leonard N. Zubkoff " "<lnz@dandelion.com>\n", adapter);
 138}
 139
 140
 141/*
 142  blogic_drvr_info returns the Host Adapter Name to identify this SCSI
 143  Driver and Host Adapter.
 144*/
 145
 146static const char *blogic_drvr_info(struct Scsi_Host *host)
 147{
 148        struct blogic_adapter *adapter =
 149                                (struct blogic_adapter *) host->hostdata;
 150        return adapter->full_model;
 151}
 152
 153/*
 154  blogic_init_ccbs initializes a group of Command Control Blocks (CCBs)
 155  for Host Adapter from the blk_size bytes located at blk_pointer.  The newly
 156  created CCBs are added to Host Adapter's free list.
 157*/
 158
 159static void blogic_init_ccbs(struct blogic_adapter *adapter, void *blk_pointer,
 160                                int blk_size, dma_addr_t blkp)
 161{
 162        struct blogic_ccb *ccb = (struct blogic_ccb *) blk_pointer;
 163        unsigned int offset = 0;
 164        memset(blk_pointer, 0, blk_size);
 165        ccb->allocgrp_head = blkp;
 166        ccb->allocgrp_size = blk_size;
 167        while ((blk_size -= sizeof(struct blogic_ccb)) >= 0) {
 168                ccb->status = BLOGIC_CCB_FREE;
 169                ccb->adapter = adapter;
 170                ccb->dma_handle = (u32) blkp + offset;
 171                if (blogic_flashpoint_type(adapter)) {
 172                        ccb->callback = blogic_qcompleted_ccb;
 173                        ccb->base_addr = adapter->fpinfo.base_addr;
 174                }
 175                ccb->next = adapter->free_ccbs;
 176                ccb->next_all = adapter->all_ccbs;
 177                adapter->free_ccbs = ccb;
 178                adapter->all_ccbs = ccb;
 179                adapter->alloc_ccbs++;
 180                ccb++;
 181                offset += sizeof(struct blogic_ccb);
 182        }
 183}
 184
 185
 186/*
 187  blogic_create_initccbs allocates the initial CCBs for Host Adapter.
 188*/
 189
 190static bool __init blogic_create_initccbs(struct blogic_adapter *adapter)
 191{
 192        int blk_size = BLOGIC_CCB_GRP_ALLOCSIZE * sizeof(struct blogic_ccb);
 193        void *blk_pointer;
 194        dma_addr_t blkp;
 195
 196        while (adapter->alloc_ccbs < adapter->initccbs) {
 197                blk_pointer = dma_alloc_coherent(&adapter->pci_device->dev,
 198                                blk_size, &blkp, GFP_KERNEL);
 199                if (blk_pointer == NULL) {
 200                        blogic_err("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n",
 201                                        adapter);
 202                        return false;
 203                }
 204                blogic_init_ccbs(adapter, blk_pointer, blk_size, blkp);
 205        }
 206        return true;
 207}
 208
 209
 210/*
 211  blogic_destroy_ccbs deallocates the CCBs for Host Adapter.
 212*/
 213
 214static void blogic_destroy_ccbs(struct blogic_adapter *adapter)
 215{
 216        struct blogic_ccb *next_ccb = adapter->all_ccbs, *ccb, *lastccb = NULL;
 217        adapter->all_ccbs = NULL;
 218        adapter->free_ccbs = NULL;
 219        while ((ccb = next_ccb) != NULL) {
 220                next_ccb = ccb->next_all;
 221                if (ccb->allocgrp_head) {
 222                        if (lastccb)
 223                                dma_free_coherent(&adapter->pci_device->dev,
 224                                                lastccb->allocgrp_size, lastccb,
 225                                                lastccb->allocgrp_head);
 226                        lastccb = ccb;
 227                }
 228        }
 229        if (lastccb)
 230                dma_free_coherent(&adapter->pci_device->dev,
 231                                lastccb->allocgrp_size, lastccb,
 232                                lastccb->allocgrp_head);
 233}
 234
 235
 236/*
 237  blogic_create_addlccbs allocates Additional CCBs for Host Adapter.  If
 238  allocation fails and there are no remaining CCBs available, the Driver Queue
 239  Depth is decreased to a known safe value to avoid potential deadlocks when
 240  multiple host adapters share the same IRQ Channel.
 241*/
 242
 243static void blogic_create_addlccbs(struct blogic_adapter *adapter,
 244                                        int addl_ccbs, bool print_success)
 245{
 246        int blk_size = BLOGIC_CCB_GRP_ALLOCSIZE * sizeof(struct blogic_ccb);
 247        int prev_alloc = adapter->alloc_ccbs;
 248        void *blk_pointer;
 249        dma_addr_t blkp;
 250        if (addl_ccbs <= 0)
 251                return;
 252        while (adapter->alloc_ccbs - prev_alloc < addl_ccbs) {
 253                blk_pointer = dma_alloc_coherent(&adapter->pci_device->dev,
 254                                blk_size, &blkp, GFP_KERNEL);
 255                if (blk_pointer == NULL)
 256                        break;
 257                blogic_init_ccbs(adapter, blk_pointer, blk_size, blkp);
 258        }
 259        if (adapter->alloc_ccbs > prev_alloc) {
 260                if (print_success)
 261                        blogic_notice("Allocated %d additional CCBs (total now %d)\n", adapter, adapter->alloc_ccbs - prev_alloc, adapter->alloc_ccbs);
 262                return;
 263        }
 264        blogic_notice("Failed to allocate additional CCBs\n", adapter);
 265        if (adapter->drvr_qdepth > adapter->alloc_ccbs - adapter->tgt_count) {
 266                adapter->drvr_qdepth = adapter->alloc_ccbs - adapter->tgt_count;
 267                adapter->scsi_host->can_queue = adapter->drvr_qdepth;
 268        }
 269}
 270
 271/*
 272  blogic_alloc_ccb allocates a CCB from Host Adapter's free list,
 273  allocating more memory from the Kernel if necessary.  The Host Adapter's
 274  Lock should already have been acquired by the caller.
 275*/
 276
 277static struct blogic_ccb *blogic_alloc_ccb(struct blogic_adapter *adapter)
 278{
 279        static unsigned long serial;
 280        struct blogic_ccb *ccb;
 281        ccb = adapter->free_ccbs;
 282        if (ccb != NULL) {
 283                ccb->serial = ++serial;
 284                adapter->free_ccbs = ccb->next;
 285                ccb->next = NULL;
 286                if (adapter->free_ccbs == NULL)
 287                        blogic_create_addlccbs(adapter, adapter->inc_ccbs,
 288                                                true);
 289                return ccb;
 290        }
 291        blogic_create_addlccbs(adapter, adapter->inc_ccbs, true);
 292        ccb = adapter->free_ccbs;
 293        if (ccb == NULL)
 294                return NULL;
 295        ccb->serial = ++serial;
 296        adapter->free_ccbs = ccb->next;
 297        ccb->next = NULL;
 298        return ccb;
 299}
 300
 301
 302/*
 303  blogic_dealloc_ccb deallocates a CCB, returning it to the Host Adapter's
 304  free list.  The Host Adapter's Lock should already have been acquired by the
 305  caller.
 306*/
 307
 308static void blogic_dealloc_ccb(struct blogic_ccb *ccb, int dma_unmap)
 309{
 310        struct blogic_adapter *adapter = ccb->adapter;
 311
 312        if (ccb->command != NULL)
 313                scsi_dma_unmap(ccb->command);
 314        if (dma_unmap)
 315                dma_unmap_single(&adapter->pci_device->dev, ccb->sensedata,
 316                         ccb->sense_datalen, DMA_FROM_DEVICE);
 317
 318        ccb->command = NULL;
 319        ccb->status = BLOGIC_CCB_FREE;
 320        ccb->next = adapter->free_ccbs;
 321        adapter->free_ccbs = ccb;
 322}
 323
 324
 325/*
 326  blogic_cmd sends the command opcode to adapter, optionally
 327  providing paramlen bytes of param and receiving at most
 328  replylen bytes of reply; any excess reply data is received but
 329  discarded.
 330
 331  On success, this function returns the number of reply bytes read from
 332  the Host Adapter (including any discarded data); on failure, it returns
 333  -1 if the command was invalid, or -2 if a timeout occurred.
 334
 335  blogic_cmd is called exclusively during host adapter detection and
 336  initialization, so performance and latency are not critical, and exclusive
 337  access to the Host Adapter hardware is assumed.  Once the host adapter and
 338  driver are initialized, the only Host Adapter command that is issued is the
 339  single byte Execute Mailbox Command operation code, which does not require
 340  waiting for the Host Adapter Ready bit to be set in the Status Register.
 341*/
 342
 343static int blogic_cmd(struct blogic_adapter *adapter, enum blogic_opcode opcode,
 344                        void *param, int paramlen, void *reply, int replylen)
 345{
 346        unsigned char *param_p = (unsigned char *) param;
 347        unsigned char *reply_p = (unsigned char *) reply;
 348        union blogic_stat_reg statusreg;
 349        union blogic_int_reg intreg;
 350        unsigned long processor_flag = 0;
 351        int reply_b = 0, result;
 352        long timeout;
 353        /*
 354           Clear out the Reply Data if provided.
 355         */
 356        if (replylen > 0)
 357                memset(reply, 0, replylen);
 358        /*
 359           If the IRQ Channel has not yet been acquired, then interrupts
 360           must be disabled while issuing host adapter commands since a
 361           Command Complete interrupt could occur if the IRQ Channel was
 362           previously enabled by another BusLogic Host Adapter or another
 363           driver sharing the same IRQ Channel.
 364         */
 365        if (!adapter->irq_acquired)
 366                local_irq_save(processor_flag);
 367        /*
 368           Wait for the Host Adapter Ready bit to be set and the
 369           Command/Parameter Register Busy bit to be reset in the Status
 370           Register.
 371         */
 372        timeout = 10000;
 373        while (--timeout >= 0) {
 374                statusreg.all = blogic_rdstatus(adapter);
 375                if (statusreg.sr.adapter_ready && !statusreg.sr.cmd_param_busy)
 376                        break;
 377                udelay(100);
 378        }
 379        if (timeout < 0) {
 380                blogic_cmd_failure_reason =
 381                                "Timeout waiting for Host Adapter Ready";
 382                result = -2;
 383                goto done;
 384        }
 385        /*
 386           Write the opcode to the Command/Parameter Register.
 387         */
 388        adapter->adapter_cmd_complete = false;
 389        blogic_setcmdparam(adapter, opcode);
 390        /*
 391           Write any additional Parameter Bytes.
 392         */
 393        timeout = 10000;
 394        while (paramlen > 0 && --timeout >= 0) {
 395                /*
 396                   Wait 100 microseconds to give the Host Adapter enough
 397                   time to determine whether the last value written to the
 398                   Command/Parameter Register was valid or not. If the
 399                   Command Complete bit is set in the Interrupt Register,
 400                   then the Command Invalid bit in the Status Register will
 401                   be reset if the Operation Code or Parameter was valid
 402                   and the command has completed, or set if the Operation
 403                   Code or Parameter was invalid. If the Data In Register
 404                   Ready bit is set in the Status Register, then the
 405                   Operation Code was valid, and data is waiting to be read
 406                   back from the Host Adapter. Otherwise, wait for the
 407                   Command/Parameter Register Busy bit in the Status
 408                   Register to be reset.
 409                 */
 410                udelay(100);
 411                intreg.all = blogic_rdint(adapter);
 412                statusreg.all = blogic_rdstatus(adapter);
 413                if (intreg.ir.cmd_complete)
 414                        break;
 415                if (adapter->adapter_cmd_complete)
 416                        break;
 417                if (statusreg.sr.datain_ready)
 418                        break;
 419                if (statusreg.sr.cmd_param_busy)
 420                        continue;
 421                blogic_setcmdparam(adapter, *param_p++);
 422                paramlen--;
 423        }
 424        if (timeout < 0) {
 425                blogic_cmd_failure_reason =
 426                                "Timeout waiting for Parameter Acceptance";
 427                result = -2;
 428                goto done;
 429        }
 430        /*
 431           The Modify I/O Address command does not cause a Command Complete
 432           Interrupt.
 433         */
 434        if (opcode == BLOGIC_MOD_IOADDR) {
 435                statusreg.all = blogic_rdstatus(adapter);
 436                if (statusreg.sr.cmd_invalid) {
 437                        blogic_cmd_failure_reason =
 438                                        "Modify I/O Address Invalid";
 439                        result = -1;
 440                        goto done;
 441                }
 442                if (blogic_global_options.trace_config)
 443                        blogic_notice("blogic_cmd(%02X) Status = %02X: " "(Modify I/O Address)\n", adapter, opcode, statusreg.all);
 444                result = 0;
 445                goto done;
 446        }
 447        /*
 448           Select an appropriate timeout value for awaiting command completion.
 449         */
 450        switch (opcode) {
 451        case BLOGIC_INQ_DEV0TO7:
 452        case BLOGIC_INQ_DEV8TO15:
 453        case BLOGIC_INQ_DEV:
 454                /* Approximately 60 seconds. */
 455                timeout = 60 * 10000;
 456                break;
 457        default:
 458                /* Approximately 1 second. */
 459                timeout = 10000;
 460                break;
 461        }
 462        /*
 463           Receive any Reply Bytes, waiting for either the Command
 464           Complete bit to be set in the Interrupt Register, or for the
 465           Interrupt Handler to set the Host Adapter Command Completed
 466           bit in the Host Adapter structure.
 467         */
 468        while (--timeout >= 0) {
 469                intreg.all = blogic_rdint(adapter);
 470                statusreg.all = blogic_rdstatus(adapter);
 471                if (intreg.ir.cmd_complete)
 472                        break;
 473                if (adapter->adapter_cmd_complete)
 474                        break;
 475                if (statusreg.sr.datain_ready) {
 476                        if (++reply_b <= replylen)
 477                                *reply_p++ = blogic_rddatain(adapter);
 478                        else
 479                                blogic_rddatain(adapter);
 480                }
 481                if (opcode == BLOGIC_FETCH_LOCALRAM &&
 482                                statusreg.sr.adapter_ready)
 483                        break;
 484                udelay(100);
 485        }
 486        if (timeout < 0) {
 487                blogic_cmd_failure_reason =
 488                                        "Timeout waiting for Command Complete";
 489                result = -2;
 490                goto done;
 491        }
 492        /*
 493           Clear any pending Command Complete Interrupt.
 494         */
 495        blogic_intreset(adapter);
 496        /*
 497           Provide tracing information if requested.
 498         */
 499        if (blogic_global_options.trace_config) {
 500                int i;
 501                blogic_notice("blogic_cmd(%02X) Status = %02X: %2d ==> %2d:",
 502                                adapter, opcode, statusreg.all, replylen,
 503                                reply_b);
 504                if (replylen > reply_b)
 505                        replylen = reply_b;
 506                for (i = 0; i < replylen; i++)
 507                        blogic_notice(" %02X", adapter,
 508                                        ((unsigned char *) reply)[i]);
 509                blogic_notice("\n", adapter);
 510        }
 511        /*
 512           Process Command Invalid conditions.
 513         */
 514        if (statusreg.sr.cmd_invalid) {
 515                /*
 516                   Some early BusLogic Host Adapters may not recover
 517                   properly from a Command Invalid condition, so if this
 518                   appears to be the case, a Soft Reset is issued to the
 519                   Host Adapter.  Potentially invalid commands are never
 520                   attempted after Mailbox Initialization is performed,
 521                   so there should be no Host Adapter state lost by a
 522                   Soft Reset in response to a Command Invalid condition.
 523                 */
 524                udelay(1000);
 525                statusreg.all = blogic_rdstatus(adapter);
 526                if (statusreg.sr.cmd_invalid || statusreg.sr.rsvd ||
 527                                statusreg.sr.datain_ready ||
 528                                statusreg.sr.cmd_param_busy ||
 529                                !statusreg.sr.adapter_ready ||
 530                                !statusreg.sr.init_reqd ||
 531                                statusreg.sr.diag_active ||
 532                                statusreg.sr.diag_failed) {
 533                        blogic_softreset(adapter);
 534                        udelay(1000);
 535                }
 536                blogic_cmd_failure_reason = "Command Invalid";
 537                result = -1;
 538                goto done;
 539        }
 540        /*
 541           Handle Excess Parameters Supplied conditions.
 542         */
 543        if (paramlen > 0) {
 544                blogic_cmd_failure_reason = "Excess Parameters Supplied";
 545                result = -1;
 546                goto done;
 547        }
 548        /*
 549           Indicate the command completed successfully.
 550         */
 551        blogic_cmd_failure_reason = NULL;
 552        result = reply_b;
 553        /*
 554           Restore the interrupt status if necessary and return.
 555         */
 556done:
 557        if (!adapter->irq_acquired)
 558                local_irq_restore(processor_flag);
 559        return result;
 560}
 561
 562
 563/*
 564  blogic_add_probeaddr_isa appends a single ISA I/O Address to the list
 565  of I/O Address and Bus Probe Information to be checked for potential BusLogic
 566  Host Adapters.
 567*/
 568
 569static void __init blogic_add_probeaddr_isa(unsigned long io_addr)
 570{
 571        struct blogic_probeinfo *probeinfo;
 572        if (blogic_probeinfo_count >= BLOGIC_MAX_ADAPTERS)
 573                return;
 574        probeinfo = &blogic_probeinfo_list[blogic_probeinfo_count++];
 575        probeinfo->adapter_type = BLOGIC_MULTIMASTER;
 576        probeinfo->adapter_bus_type = BLOGIC_ISA_BUS;
 577        probeinfo->io_addr = io_addr;
 578        probeinfo->pci_device = NULL;
 579}
 580
 581
 582/*
 583  blogic_init_probeinfo_isa initializes the list of I/O Address and
 584  Bus Probe Information to be checked for potential BusLogic SCSI Host Adapters
 585  only from the list of standard BusLogic MultiMaster ISA I/O Addresses.
 586*/
 587
 588static void __init blogic_init_probeinfo_isa(struct blogic_adapter *adapter)
 589{
 590        /*
 591           If BusLogic Driver Options specifications requested that ISA
 592           Bus Probes be inhibited, do not proceed further.
 593         */
 594        if (blogic_probe_options.noprobe_isa)
 595                return;
 596        /*
 597           Append the list of standard BusLogic MultiMaster ISA I/O Addresses.
 598         */
 599        if (!blogic_probe_options.limited_isa || blogic_probe_options.probe330)
 600                blogic_add_probeaddr_isa(0x330);
 601        if (!blogic_probe_options.limited_isa || blogic_probe_options.probe334)
 602                blogic_add_probeaddr_isa(0x334);
 603        if (!blogic_probe_options.limited_isa || blogic_probe_options.probe230)
 604                blogic_add_probeaddr_isa(0x230);
 605        if (!blogic_probe_options.limited_isa || blogic_probe_options.probe234)
 606                blogic_add_probeaddr_isa(0x234);
 607        if (!blogic_probe_options.limited_isa || blogic_probe_options.probe130)
 608                blogic_add_probeaddr_isa(0x130);
 609        if (!blogic_probe_options.limited_isa || blogic_probe_options.probe134)
 610                blogic_add_probeaddr_isa(0x134);
 611}
 612
 613
 614#ifdef CONFIG_PCI
 615
 616
 617/*
 618  blogic_sort_probeinfo sorts a section of blogic_probeinfo_list in order
 619  of increasing PCI Bus and Device Number.
 620*/
 621
 622static void __init blogic_sort_probeinfo(struct blogic_probeinfo
 623                                        *probeinfo_list, int probeinfo_cnt)
 624{
 625        int last_exchange = probeinfo_cnt - 1, bound, j;
 626
 627        while (last_exchange > 0) {
 628                bound = last_exchange;
 629                last_exchange = 0;
 630                for (j = 0; j < bound; j++) {
 631                        struct blogic_probeinfo *probeinfo1 =
 632                                                        &probeinfo_list[j];
 633                        struct blogic_probeinfo *probeinfo2 =
 634                                                        &probeinfo_list[j + 1];
 635                        if (probeinfo1->bus > probeinfo2->bus ||
 636                                (probeinfo1->bus == probeinfo2->bus &&
 637                                (probeinfo1->dev > probeinfo2->dev))) {
 638                                struct blogic_probeinfo tmp_probeinfo;
 639
 640                                memcpy(&tmp_probeinfo, probeinfo1,
 641                                        sizeof(struct blogic_probeinfo));
 642                                memcpy(probeinfo1, probeinfo2,
 643                                        sizeof(struct blogic_probeinfo));
 644                                memcpy(probeinfo2, &tmp_probeinfo,
 645                                        sizeof(struct blogic_probeinfo));
 646                                last_exchange = j;
 647                        }
 648                }
 649        }
 650}
 651
 652
 653/*
 654  blogic_init_mm_probeinfo initializes the list of I/O Address
 655  and Bus Probe Information to be checked for potential BusLogic MultiMaster
 656  SCSI Host Adapters by interrogating the PCI Configuration Space on PCI
 657  machines as well as from the list of standard BusLogic MultiMaster ISA
 658  I/O Addresses.  It returns the number of PCI MultiMaster Host Adapters found.
 659*/
 660
 661static int __init blogic_init_mm_probeinfo(struct blogic_adapter *adapter)
 662{
 663        struct blogic_probeinfo *pr_probeinfo =
 664                &blogic_probeinfo_list[blogic_probeinfo_count];
 665        int nonpr_mmindex = blogic_probeinfo_count + 1;
 666        int nonpr_mmcount = 0, mmcount = 0;
 667        bool force_scan_order = false;
 668        bool force_scan_order_checked = false;
 669        bool addr_seen[6];
 670        struct pci_dev *pci_device = NULL;
 671        int i;
 672        if (blogic_probeinfo_count >= BLOGIC_MAX_ADAPTERS)
 673                return 0;
 674        blogic_probeinfo_count++;
 675        for (i = 0; i < 6; i++)
 676                addr_seen[i] = false;
 677        /*
 678           Iterate over the MultiMaster PCI Host Adapters.  For each
 679           enumerated host adapter, determine whether its ISA Compatible
 680           I/O Port is enabled and if so, whether it is assigned the
 681           Primary I/O Address.  A host adapter that is assigned the
 682           Primary I/O Address will always be the preferred boot device.
 683           The MultiMaster BIOS will first recognize a host adapter at
 684           the Primary I/O Address, then any other PCI host adapters,
 685           and finally any host adapters located at the remaining
 686           standard ISA I/O Addresses.  When a PCI host adapter is found
 687           with its ISA Compatible I/O Port enabled, a command is issued
 688           to disable the ISA Compatible I/O Port, and it is noted that the
 689           particular standard ISA I/O Address need not be probed.
 690         */
 691        pr_probeinfo->io_addr = 0;
 692        while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
 693                                        PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
 694                                        pci_device)) != NULL) {
 695                struct blogic_adapter *host_adapter = adapter;
 696                struct blogic_adapter_info adapter_info;
 697                enum blogic_isa_ioport mod_ioaddr_req;
 698                unsigned char bus;
 699                unsigned char device;
 700                unsigned int irq_ch;
 701                unsigned long base_addr0;
 702                unsigned long base_addr1;
 703                unsigned long io_addr;
 704                unsigned long pci_addr;
 705
 706                if (pci_enable_device(pci_device))
 707                        continue;
 708
 709                if (dma_set_mask(&pci_device->dev, DMA_BIT_MASK(32)))
 710                        continue;
 711
 712                bus = pci_device->bus->number;
 713                device = pci_device->devfn >> 3;
 714                irq_ch = pci_device->irq;
 715                io_addr = base_addr0 = pci_resource_start(pci_device, 0);
 716                pci_addr = base_addr1 = pci_resource_start(pci_device, 1);
 717
 718                if (pci_resource_flags(pci_device, 0) & IORESOURCE_MEM) {
 719                        blogic_err("BusLogic: Base Address0 0x%X not I/O for " "MultiMaster Host Adapter\n", NULL, base_addr0);
 720                        blogic_err("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, bus, device, io_addr);
 721                        continue;
 722                }
 723                if (pci_resource_flags(pci_device, 1) & IORESOURCE_IO) {
 724                        blogic_err("BusLogic: Base Address1 0x%X not Memory for " "MultiMaster Host Adapter\n", NULL, base_addr1);
 725                        blogic_err("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, bus, device, pci_addr);
 726                        continue;
 727                }
 728                if (irq_ch == 0) {
 729                        blogic_err("BusLogic: IRQ Channel %d invalid for " "MultiMaster Host Adapter\n", NULL, irq_ch);
 730                        blogic_err("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, bus, device, io_addr);
 731                        continue;
 732                }
 733                if (blogic_global_options.trace_probe) {
 734                        blogic_notice("BusLogic: PCI MultiMaster Host Adapter " "detected at\n", NULL);
 735                        blogic_notice("BusLogic: PCI Bus %d Device %d I/O Address " "0x%X PCI Address 0x%X\n", NULL, bus, device, io_addr, pci_addr);
 736                }
 737                /*
 738                   Issue the Inquire PCI Host Adapter Information command to determine
 739                   the ISA Compatible I/O Port.  If the ISA Compatible I/O Port is
 740                   known and enabled, note that the particular Standard ISA I/O
 741                   Address should not be probed.
 742                 */
 743                host_adapter->io_addr = io_addr;
 744                blogic_intreset(host_adapter);
 745                if (blogic_cmd(host_adapter, BLOGIC_INQ_PCI_INFO, NULL, 0,
 746                                &adapter_info, sizeof(adapter_info)) ==
 747                                sizeof(adapter_info)) {
 748                        if (adapter_info.isa_port < 6)
 749                                addr_seen[adapter_info.isa_port] = true;
 750                } else
 751                        adapter_info.isa_port = BLOGIC_IO_DISABLE;
 752                /*
 753                   Issue the Modify I/O Address command to disable the
 754                   ISA Compatible I/O Port. On PCI Host Adapters, the
 755                   Modify I/O Address command allows modification of the
 756                   ISA compatible I/O Address that the Host Adapter
 757                   responds to; it does not affect the PCI compliant
 758                   I/O Address assigned at system initialization.
 759                 */
 760                mod_ioaddr_req = BLOGIC_IO_DISABLE;
 761                blogic_cmd(host_adapter, BLOGIC_MOD_IOADDR, &mod_ioaddr_req,
 762                                sizeof(mod_ioaddr_req), NULL, 0);
 763                /*
 764                   For the first MultiMaster Host Adapter enumerated,
 765                   issue the Fetch Host Adapter Local RAM command to read
 766                   byte 45 of the AutoSCSI area, for the setting of the
 767                   "Use Bus And Device # For PCI Scanning Seq." option.
 768                   Issue the Inquire Board ID command since this option is
 769                   only valid for the BT-948/958/958D.
 770                 */
 771                if (!force_scan_order_checked) {
 772                        struct blogic_fetch_localram fetch_localram;
 773                        struct blogic_autoscsi_byte45 autoscsi_byte45;
 774                        struct blogic_board_id id;
 775
 776                        fetch_localram.offset = BLOGIC_AUTOSCSI_BASE + 45;
 777                        fetch_localram.count = sizeof(autoscsi_byte45);
 778                        blogic_cmd(host_adapter, BLOGIC_FETCH_LOCALRAM,
 779                                        &fetch_localram, sizeof(fetch_localram),
 780                                        &autoscsi_byte45,
 781                                        sizeof(autoscsi_byte45));
 782                        blogic_cmd(host_adapter, BLOGIC_GET_BOARD_ID, NULL, 0,
 783                                        &id, sizeof(id));
 784                        if (id.fw_ver_digit1 == '5')
 785                                force_scan_order =
 786                                        autoscsi_byte45.force_scan_order;
 787                        force_scan_order_checked = true;
 788                }
 789                /*
 790                   Determine whether this MultiMaster Host Adapter has its
 791                   ISA Compatible I/O Port enabled and is assigned the
 792                   Primary I/O Address. If it does, then it is the Primary
 793                   MultiMaster Host Adapter and must be recognized first.
 794                   If it does not, then it is added to the list for probing
 795                   after any Primary MultiMaster Host Adapter is probed.
 796                 */
 797                if (adapter_info.isa_port == BLOGIC_IO_330) {
 798                        pr_probeinfo->adapter_type = BLOGIC_MULTIMASTER;
 799                        pr_probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
 800                        pr_probeinfo->io_addr = io_addr;
 801                        pr_probeinfo->pci_addr = pci_addr;
 802                        pr_probeinfo->bus = bus;
 803                        pr_probeinfo->dev = device;
 804                        pr_probeinfo->irq_ch = irq_ch;
 805                        pr_probeinfo->pci_device = pci_dev_get(pci_device);
 806                        mmcount++;
 807                } else if (blogic_probeinfo_count < BLOGIC_MAX_ADAPTERS) {
 808                        struct blogic_probeinfo *probeinfo =
 809                                &blogic_probeinfo_list[blogic_probeinfo_count++];
 810                        probeinfo->adapter_type = BLOGIC_MULTIMASTER;
 811                        probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
 812                        probeinfo->io_addr = io_addr;
 813                        probeinfo->pci_addr = pci_addr;
 814                        probeinfo->bus = bus;
 815                        probeinfo->dev = device;
 816                        probeinfo->irq_ch = irq_ch;
 817                        probeinfo->pci_device = pci_dev_get(pci_device);
 818                        nonpr_mmcount++;
 819                        mmcount++;
 820                } else
 821                        blogic_warn("BusLogic: Too many Host Adapters " "detected\n", NULL);
 822        }
 823        /*
 824           If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq."
 825           option is ON for the first enumerated MultiMaster Host Adapter,
 826           and if that host adapter is a BT-948/958/958D, then the
 827           MultiMaster BIOS will recognize MultiMaster Host Adapters in
 828           the order of increasing PCI Bus and Device Number. In that case,
 829           sort the probe information into the same order the BIOS uses.
 830           If this option is OFF, then the MultiMaster BIOS will recognize
 831           MultiMaster Host Adapters in the order they are enumerated by
 832           the PCI BIOS, and hence no sorting is necessary.
 833         */
 834        if (force_scan_order)
 835                blogic_sort_probeinfo(&blogic_probeinfo_list[nonpr_mmindex],
 836                                        nonpr_mmcount);
 837        /*
 838           If no PCI MultiMaster Host Adapter is assigned the Primary
 839           I/O Address, then the Primary I/O Address must be probed
 840           explicitly before any PCI host adapters are probed.
 841         */
 842        if (!blogic_probe_options.noprobe_isa)
 843                if (pr_probeinfo->io_addr == 0 &&
 844                                (!blogic_probe_options.limited_isa ||
 845                                 blogic_probe_options.probe330)) {
 846                        pr_probeinfo->adapter_type = BLOGIC_MULTIMASTER;
 847                        pr_probeinfo->adapter_bus_type = BLOGIC_ISA_BUS;
 848                        pr_probeinfo->io_addr = 0x330;
 849                }
 850        /*
 851           Append the list of standard BusLogic MultiMaster ISA I/O Addresses,
 852           omitting the Primary I/O Address which has already been handled.
 853         */
 854        if (!blogic_probe_options.noprobe_isa) {
 855                if (!addr_seen[1] &&
 856                                (!blogic_probe_options.limited_isa ||
 857                                 blogic_probe_options.probe334))
 858                        blogic_add_probeaddr_isa(0x334);
 859                if (!addr_seen[2] &&
 860                                (!blogic_probe_options.limited_isa ||
 861                                 blogic_probe_options.probe230))
 862                        blogic_add_probeaddr_isa(0x230);
 863                if (!addr_seen[3] &&
 864                                (!blogic_probe_options.limited_isa ||
 865                                 blogic_probe_options.probe234))
 866                        blogic_add_probeaddr_isa(0x234);
 867                if (!addr_seen[4] &&
 868                                (!blogic_probe_options.limited_isa ||
 869                                 blogic_probe_options.probe130))
 870                        blogic_add_probeaddr_isa(0x130);
 871                if (!addr_seen[5] &&
 872                                (!blogic_probe_options.limited_isa ||
 873                                 blogic_probe_options.probe134))
 874                        blogic_add_probeaddr_isa(0x134);
 875        }
 876        /*
 877           Iterate over the older non-compliant MultiMaster PCI Host Adapters,
 878           noting the PCI bus location and assigned IRQ Channel.
 879         */
 880        pci_device = NULL;
 881        while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
 882                                        PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
 883                                        pci_device)) != NULL) {
 884                unsigned char bus;
 885                unsigned char device;
 886                unsigned int irq_ch;
 887                unsigned long io_addr;
 888
 889                if (pci_enable_device(pci_device))
 890                        continue;
 891
 892                if (dma_set_mask(&pci_device->dev, DMA_BIT_MASK(32)))
 893                        continue;
 894
 895                bus = pci_device->bus->number;
 896                device = pci_device->devfn >> 3;
 897                irq_ch = pci_device->irq;
 898                io_addr = pci_resource_start(pci_device, 0);
 899
 900                if (io_addr == 0 || irq_ch == 0)
 901                        continue;
 902                for (i = 0; i < blogic_probeinfo_count; i++) {
 903                        struct blogic_probeinfo *probeinfo =
 904                                                &blogic_probeinfo_list[i];
 905                        if (probeinfo->io_addr == io_addr &&
 906                                probeinfo->adapter_type == BLOGIC_MULTIMASTER) {
 907                                probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
 908                                probeinfo->pci_addr = 0;
 909                                probeinfo->bus = bus;
 910                                probeinfo->dev = device;
 911                                probeinfo->irq_ch = irq_ch;
 912                                probeinfo->pci_device = pci_dev_get(pci_device);
 913                                break;
 914                        }
 915                }
 916        }
 917        return mmcount;
 918}
 919
 920
 921/*
 922  blogic_init_fp_probeinfo initializes the list of I/O Address
 923  and Bus Probe Information to be checked for potential BusLogic FlashPoint
 924  Host Adapters by interrogating the PCI Configuration Space.  It returns the
 925  number of FlashPoint Host Adapters found.
 926*/
 927
 928static int __init blogic_init_fp_probeinfo(struct blogic_adapter *adapter)
 929{
 930        int fpindex = blogic_probeinfo_count, fpcount = 0;
 931        struct pci_dev *pci_device = NULL;
 932        /*
 933           Interrogate PCI Configuration Space for any FlashPoint Host Adapters.
 934         */
 935        while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
 936                                        PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
 937                                        pci_device)) != NULL) {
 938                unsigned char bus;
 939                unsigned char device;
 940                unsigned int irq_ch;
 941                unsigned long base_addr0;
 942                unsigned long base_addr1;
 943                unsigned long io_addr;
 944                unsigned long pci_addr;
 945
 946                if (pci_enable_device(pci_device))
 947                        continue;
 948
 949                if (dma_set_mask(&pci_device->dev, DMA_BIT_MASK(32)))
 950                        continue;
 951
 952                bus = pci_device->bus->number;
 953                device = pci_device->devfn >> 3;
 954                irq_ch = pci_device->irq;
 955                io_addr = base_addr0 = pci_resource_start(pci_device, 0);
 956                pci_addr = base_addr1 = pci_resource_start(pci_device, 1);
 957#ifdef CONFIG_SCSI_FLASHPOINT
 958                if (pci_resource_flags(pci_device, 0) & IORESOURCE_MEM) {
 959                        blogic_err("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, base_addr0);
 960                        blogic_err("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, bus, device, io_addr);
 961                        continue;
 962                }
 963                if (pci_resource_flags(pci_device, 1) & IORESOURCE_IO) {
 964                        blogic_err("BusLogic: Base Address1 0x%X not Memory for " "FlashPoint Host Adapter\n", NULL, base_addr1);
 965                        blogic_err("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, bus, device, pci_addr);
 966                        continue;
 967                }
 968                if (irq_ch == 0) {
 969                        blogic_err("BusLogic: IRQ Channel %d invalid for " "FlashPoint Host Adapter\n", NULL, irq_ch);
 970                        blogic_err("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, bus, device, io_addr);
 971                        continue;
 972                }
 973                if (blogic_global_options.trace_probe) {
 974                        blogic_notice("BusLogic: FlashPoint Host Adapter " "detected at\n", NULL);
 975                        blogic_notice("BusLogic: PCI Bus %d Device %d I/O Address " "0x%X PCI Address 0x%X\n", NULL, bus, device, io_addr, pci_addr);
 976                }
 977                if (blogic_probeinfo_count < BLOGIC_MAX_ADAPTERS) {
 978                        struct blogic_probeinfo *probeinfo =
 979                                &blogic_probeinfo_list[blogic_probeinfo_count++];
 980                        probeinfo->adapter_type = BLOGIC_FLASHPOINT;
 981                        probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
 982                        probeinfo->io_addr = io_addr;
 983                        probeinfo->pci_addr = pci_addr;
 984                        probeinfo->bus = bus;
 985                        probeinfo->dev = device;
 986                        probeinfo->irq_ch = irq_ch;
 987                        probeinfo->pci_device = pci_dev_get(pci_device);
 988                        fpcount++;
 989                } else
 990                        blogic_warn("BusLogic: Too many Host Adapters " "detected\n", NULL);
 991#else
 992                blogic_err("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", NULL, bus, device);
 993                blogic_err("BusLogic: I/O Address 0x%X PCI Address 0x%X, irq %d, " "but FlashPoint\n", NULL, io_addr, pci_addr, irq_ch);
 994                blogic_err("BusLogic: support was omitted in this kernel " "configuration.\n", NULL);
 995#endif
 996        }
 997        /*
 998           The FlashPoint BIOS will scan for FlashPoint Host Adapters in the order of
 999           increasing PCI Bus and Device Number, so sort the probe information into
1000           the same order the BIOS uses.
1001         */
1002        blogic_sort_probeinfo(&blogic_probeinfo_list[fpindex], fpcount);
1003        return fpcount;
1004}
1005
1006
1007/*
1008  blogic_init_probeinfo_list initializes the list of I/O Address and Bus
1009  Probe Information to be checked for potential BusLogic SCSI Host Adapters by
1010  interrogating the PCI Configuration Space on PCI machines as well as from the
1011  list of standard BusLogic MultiMaster ISA I/O Addresses.  By default, if both
1012  FlashPoint and PCI MultiMaster Host Adapters are present, this driver will
1013  probe for FlashPoint Host Adapters first unless the BIOS primary disk is
1014  controlled by the first PCI MultiMaster Host Adapter, in which case
1015  MultiMaster Host Adapters will be probed first.  The BusLogic Driver Options
1016  specifications "MultiMasterFirst" and "FlashPointFirst" can be used to force
1017  a particular probe order.
1018*/
1019
1020static void __init blogic_init_probeinfo_list(struct blogic_adapter *adapter)
1021{
1022        /*
1023           If a PCI BIOS is present, interrogate it for MultiMaster and
1024           FlashPoint Host Adapters; otherwise, default to the standard
1025           ISA MultiMaster probe.
1026         */
1027        if (!blogic_probe_options.noprobe_pci) {
1028                if (blogic_probe_options.multimaster_first) {
1029                        blogic_init_mm_probeinfo(adapter);
1030                        blogic_init_fp_probeinfo(adapter);
1031                } else if (blogic_probe_options.flashpoint_first) {
1032                        blogic_init_fp_probeinfo(adapter);
1033                        blogic_init_mm_probeinfo(adapter);
1034                } else {
1035                        int fpcount = blogic_init_fp_probeinfo(adapter);
1036                        int mmcount = blogic_init_mm_probeinfo(adapter);
1037                        if (fpcount > 0 && mmcount > 0) {
1038                                struct blogic_probeinfo *probeinfo =
1039                                        &blogic_probeinfo_list[fpcount];
1040                                struct blogic_adapter *myadapter = adapter;
1041                                struct blogic_fetch_localram fetch_localram;
1042                                struct blogic_bios_drvmap d0_mapbyte;
1043
1044                                while (probeinfo->adapter_bus_type !=
1045                                                BLOGIC_PCI_BUS)
1046                                        probeinfo++;
1047                                myadapter->io_addr = probeinfo->io_addr;
1048                                fetch_localram.offset =
1049                                        BLOGIC_BIOS_BASE + BLOGIC_BIOS_DRVMAP;
1050                                fetch_localram.count = sizeof(d0_mapbyte);
1051                                blogic_cmd(myadapter, BLOGIC_FETCH_LOCALRAM,
1052                                                &fetch_localram,
1053                                                sizeof(fetch_localram),
1054                                                &d0_mapbyte,
1055                                                sizeof(d0_mapbyte));
1056                                /*
1057                                   If the Map Byte for BIOS Drive 0 indicates
1058                                   that BIOS Drive 0 is controlled by this
1059                                   PCI MultiMaster Host Adapter, then reverse
1060                                   the probe order so that MultiMaster Host
1061                                   Adapters are probed before FlashPoint Host
1062                                   Adapters.
1063                                 */
1064                                if (d0_mapbyte.diskgeom != BLOGIC_BIOS_NODISK) {
1065                                        struct blogic_probeinfo saved_probeinfo[BLOGIC_MAX_ADAPTERS];
1066                                        int mmcount = blogic_probeinfo_count - fpcount;
1067
1068                                        memcpy(saved_probeinfo,
1069                                                blogic_probeinfo_list,
1070                                                blogic_probeinfo_count * sizeof(struct blogic_probeinfo));
1071                                        memcpy(&blogic_probeinfo_list[0],
1072                                                &saved_probeinfo[fpcount],
1073                                                mmcount * sizeof(struct blogic_probeinfo));
1074                                        memcpy(&blogic_probeinfo_list[mmcount],
1075                                                &saved_probeinfo[0],
1076                                                fpcount * sizeof(struct blogic_probeinfo));
1077                                }
1078                        }
1079                }
1080        } else {
1081                blogic_init_probeinfo_isa(adapter);
1082        }
1083}
1084
1085
1086#else
1087#define blogic_init_probeinfo_list(adapter) \
1088                blogic_init_probeinfo_isa(adapter)
1089#endif                          /* CONFIG_PCI */
1090
1091
1092/*
1093  blogic_failure prints a standardized error message, and then returns false.
1094*/
1095
1096static bool blogic_failure(struct blogic_adapter *adapter, char *msg)
1097{
1098        blogic_announce_drvr(adapter);
1099        if (adapter->adapter_bus_type == BLOGIC_PCI_BUS) {
1100                blogic_err("While configuring BusLogic PCI Host Adapter at\n",
1101                                adapter);
1102                blogic_err("Bus %d Device %d I/O Address 0x%X PCI Address 0x%X:\n", adapter, adapter->bus, adapter->dev, adapter->io_addr, adapter->pci_addr);
1103        } else
1104                blogic_err("While configuring BusLogic Host Adapter at " "I/O Address 0x%X:\n", adapter, adapter->io_addr);
1105        blogic_err("%s FAILED - DETACHING\n", adapter, msg);
1106        if (blogic_cmd_failure_reason != NULL)
1107                blogic_err("ADDITIONAL FAILURE INFO - %s\n", adapter,
1108                                blogic_cmd_failure_reason);
1109        return false;
1110}
1111
1112
1113/*
1114  blogic_probe probes for a BusLogic Host Adapter.
1115*/
1116
1117static bool __init blogic_probe(struct blogic_adapter *adapter)
1118{
1119        union blogic_stat_reg statusreg;
1120        union blogic_int_reg intreg;
1121        union blogic_geo_reg georeg;
1122        /*
1123           FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager.
1124         */
1125        if (blogic_flashpoint_type(adapter)) {
1126                struct fpoint_info *fpinfo = &adapter->fpinfo;
1127                fpinfo->base_addr = (u32) adapter->io_addr;
1128                fpinfo->irq_ch = adapter->irq_ch;
1129                fpinfo->present = false;
1130                if (!(FlashPoint_ProbeHostAdapter(fpinfo) == 0 &&
1131                                        fpinfo->present)) {
1132                        blogic_err("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", adapter, adapter->bus, adapter->dev);
1133                        blogic_err("BusLogic: I/O Address 0x%X PCI Address 0x%X, " "but FlashPoint\n", adapter, adapter->io_addr, adapter->pci_addr);
1134                        blogic_err("BusLogic: Probe Function failed to validate it.\n", adapter);
1135                        return false;
1136                }
1137                if (blogic_global_options.trace_probe)
1138                        blogic_notice("BusLogic_Probe(0x%X): FlashPoint Found\n", adapter, adapter->io_addr);
1139                /*
1140                   Indicate the Host Adapter Probe completed successfully.
1141                 */
1142                return true;
1143        }
1144        /*
1145           Read the Status, Interrupt, and Geometry Registers to test if there are I/O
1146           ports that respond, and to check the values to determine if they are from a
1147           BusLogic Host Adapter.  A nonexistent I/O port will return 0xFF, in which
1148           case there is definitely no BusLogic Host Adapter at this base I/O Address.
1149           The test here is a subset of that used by the BusLogic Host Adapter BIOS.
1150         */
1151        statusreg.all = blogic_rdstatus(adapter);
1152        intreg.all = blogic_rdint(adapter);
1153        georeg.all = blogic_rdgeom(adapter);
1154        if (blogic_global_options.trace_probe)
1155                blogic_notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, " "Geometry 0x%02X\n", adapter, adapter->io_addr, statusreg.all, intreg.all, georeg.all);
1156        if (statusreg.all == 0 || statusreg.sr.diag_active ||
1157                        statusreg.sr.cmd_param_busy || statusreg.sr.rsvd ||
1158                        statusreg.sr.cmd_invalid || intreg.ir.rsvd != 0)
1159                return false;
1160        /*
1161           Check the undocumented Geometry Register to test if there is
1162           an I/O port that responded.  Adaptec Host Adapters do not
1163           implement the Geometry Register, so this test helps serve to
1164           avoid incorrectly recognizing an Adaptec 1542A or 1542B as a
1165           BusLogic.  Unfortunately, the Adaptec 1542C series does respond
1166           to the Geometry Register I/O port, but it will be rejected
1167           later when the Inquire Extended Setup Information command is
1168           issued in blogic_checkadapter.  The AMI FastDisk Host Adapter
1169           is a BusLogic clone that implements the same interface as
1170           earlier BusLogic Host Adapters, including the undocumented
1171           commands, and is therefore supported by this driver. However,
1172           the AMI FastDisk always returns 0x00 upon reading the Geometry
1173           Register, so the extended translation option should always be
1174           left disabled on the AMI FastDisk.
1175         */
1176        if (georeg.all == 0xFF)
1177                return false;
1178        /*
1179           Indicate the Host Adapter Probe completed successfully.
1180         */
1181        return true;
1182}
1183
1184
1185/*
1186  blogic_hwreset issues a Hardware Reset to the Host Adapter
1187  and waits for Host Adapter Diagnostics to complete.  If hard_reset is true, a
1188  Hard Reset is performed which also initiates a SCSI Bus Reset.  Otherwise, a
1189  Soft Reset is performed which only resets the Host Adapter without forcing a
1190  SCSI Bus Reset.
1191*/
1192
1193static bool blogic_hwreset(struct blogic_adapter *adapter, bool hard_reset)
1194{
1195        union blogic_stat_reg statusreg;
1196        int timeout;
1197        /*
1198           FlashPoint Host Adapters are Hard Reset by the FlashPoint
1199           SCCB Manager.
1200         */
1201        if (blogic_flashpoint_type(adapter)) {
1202                struct fpoint_info *fpinfo = &adapter->fpinfo;
1203                fpinfo->softreset = !hard_reset;
1204                fpinfo->report_underrun = true;
1205                adapter->cardhandle =
1206                        FlashPoint_HardwareResetHostAdapter(fpinfo);
1207                if (adapter->cardhandle == (void *)FPOINT_BADCARD_HANDLE)
1208                        return false;
1209                /*
1210                   Indicate the Host Adapter Hard Reset completed successfully.
1211                 */
1212                return true;
1213        }
1214        /*
1215           Issue a Hard Reset or Soft Reset Command to the Host Adapter.
1216           The Host Adapter should respond by setting Diagnostic Active in
1217           the Status Register.
1218         */
1219        if (hard_reset)
1220                blogic_hardreset(adapter);
1221        else
1222                blogic_softreset(adapter);
1223        /*
1224           Wait until Diagnostic Active is set in the Status Register.
1225         */
1226        timeout = 5 * 10000;
1227        while (--timeout >= 0) {
1228                statusreg.all = blogic_rdstatus(adapter);
1229                if (statusreg.sr.diag_active)
1230                        break;
1231                udelay(100);
1232        }
1233        if (blogic_global_options.trace_hw_reset)
1234                blogic_notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, " "Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
1235        if (timeout < 0)
1236                return false;
1237        /*
1238           Wait 100 microseconds to allow completion of any initial diagnostic
1239           activity which might leave the contents of the Status Register
1240           unpredictable.
1241         */
1242        udelay(100);
1243        /*
1244           Wait until Diagnostic Active is reset in the Status Register.
1245         */
1246        timeout = 10 * 10000;
1247        while (--timeout >= 0) {
1248                statusreg.all = blogic_rdstatus(adapter);
1249                if (!statusreg.sr.diag_active)
1250                        break;
1251                udelay(100);
1252        }
1253        if (blogic_global_options.trace_hw_reset)
1254                blogic_notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, " "Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
1255        if (timeout < 0)
1256                return false;
1257        /*
1258           Wait until at least one of the Diagnostic Failure, Host Adapter
1259           Ready, or Data In Register Ready bits is set in the Status Register.
1260         */
1261        timeout = 10000;
1262        while (--timeout >= 0) {
1263                statusreg.all = blogic_rdstatus(adapter);
1264                if (statusreg.sr.diag_failed || statusreg.sr.adapter_ready ||
1265                                statusreg.sr.datain_ready)
1266                        break;
1267                udelay(100);
1268        }
1269        if (blogic_global_options.trace_hw_reset)
1270                blogic_notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, " "Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
1271        if (timeout < 0)
1272                return false;
1273        /*
1274           If Diagnostic Failure is set or Host Adapter Ready is reset,
1275           then an error occurred during the Host Adapter diagnostics.
1276           If Data In Register Ready is set, then there is an Error Code
1277           available.
1278         */
1279        if (statusreg.sr.diag_failed || !statusreg.sr.adapter_ready) {
1280                blogic_cmd_failure_reason = NULL;
1281                blogic_failure(adapter, "HARD RESET DIAGNOSTICS");
1282                blogic_err("HOST ADAPTER STATUS REGISTER = %02X\n", adapter,
1283                                statusreg.all);
1284                if (statusreg.sr.datain_ready)
1285                        blogic_err("HOST ADAPTER ERROR CODE = %d\n", adapter,
1286                                        blogic_rddatain(adapter));
1287                return false;
1288        }
1289        /*
1290           Indicate the Host Adapter Hard Reset completed successfully.
1291         */
1292        return true;
1293}
1294
1295
1296/*
1297  blogic_checkadapter checks to be sure this really is a BusLogic
1298  Host Adapter.
1299*/
1300
1301static bool __init blogic_checkadapter(struct blogic_adapter *adapter)
1302{
1303        struct blogic_ext_setup ext_setupinfo;
1304        unsigned char req_replylen;
1305        bool result = true;
1306        /*
1307           FlashPoint Host Adapters do not require this protection.
1308         */
1309        if (blogic_flashpoint_type(adapter))
1310                return true;
1311        /*
1312           Issue the Inquire Extended Setup Information command. Only genuine
1313           BusLogic Host Adapters and true clones support this command.
1314           Adaptec 1542C series Host Adapters that respond to the Geometry
1315           Register I/O port will fail this command.
1316         */
1317        req_replylen = sizeof(ext_setupinfo);
1318        if (blogic_cmd(adapter, BLOGIC_INQ_EXTSETUP, &req_replylen,
1319                                sizeof(req_replylen), &ext_setupinfo,
1320                                sizeof(ext_setupinfo)) != sizeof(ext_setupinfo))
1321                result = false;
1322        /*
1323           Provide tracing information if requested and return.
1324         */
1325        if (blogic_global_options.trace_probe)
1326                blogic_notice("BusLogic_Check(0x%X): MultiMaster %s\n", adapter,
1327                                adapter->io_addr,
1328                                (result ? "Found" : "Not Found"));
1329        return result;
1330}
1331
1332
1333/*
1334  blogic_rdconfig reads the Configuration Information
1335  from Host Adapter and initializes the Host Adapter structure.
1336*/
1337
1338static bool __init blogic_rdconfig(struct blogic_adapter *adapter)
1339{
1340        struct blogic_board_id id;
1341        struct blogic_config config;
1342        struct blogic_setup_info setupinfo;
1343        struct blogic_ext_setup ext_setupinfo;
1344        unsigned char model[5];
1345        unsigned char fw_ver_digit3;
1346        unsigned char fw_ver_letter;
1347        struct blogic_adapter_info adapter_info;
1348        struct blogic_fetch_localram fetch_localram;
1349        struct blogic_autoscsi autoscsi;
1350        union blogic_geo_reg georeg;
1351        unsigned char req_replylen;
1352        unsigned char *tgt, ch;
1353        int tgt_id, i;
1354        /*
1355           Configuration Information for FlashPoint Host Adapters is
1356           provided in the fpoint_info structure by the FlashPoint
1357           SCCB Manager's Probe Function. Initialize fields in the
1358           Host Adapter structure from the fpoint_info structure.
1359         */
1360        if (blogic_flashpoint_type(adapter)) {
1361                struct fpoint_info *fpinfo = &adapter->fpinfo;
1362                tgt = adapter->model;
1363                *tgt++ = 'B';
1364                *tgt++ = 'T';
1365                *tgt++ = '-';
1366                for (i = 0; i < sizeof(fpinfo->model); i++)
1367                        *tgt++ = fpinfo->model[i];
1368                *tgt++ = '\0';
1369                strcpy(adapter->fw_ver, FLASHPOINT_FW_VER);
1370                adapter->scsi_id = fpinfo->scsi_id;
1371                adapter->ext_trans_enable = fpinfo->ext_trans_enable;
1372                adapter->parity = fpinfo->parity;
1373                adapter->reset_enabled = !fpinfo->softreset;
1374                adapter->level_int = true;
1375                adapter->wide = fpinfo->wide;
1376                adapter->differential = false;
1377                adapter->scam = true;
1378                adapter->ultra = true;
1379                adapter->ext_lun = true;
1380                adapter->terminfo_valid = true;
1381                adapter->low_term = fpinfo->low_term;
1382                adapter->high_term = fpinfo->high_term;
1383                adapter->scam_enabled = fpinfo->scam_enabled;
1384                adapter->scam_lev2 = fpinfo->scam_lev2;
1385                adapter->drvr_sglimit = BLOGIC_SG_LIMIT;
1386                adapter->maxdev = (adapter->wide ? 16 : 8);
1387                adapter->maxlun = 32;
1388                adapter->initccbs = 4 * BLOGIC_CCB_GRP_ALLOCSIZE;
1389                adapter->inc_ccbs = BLOGIC_CCB_GRP_ALLOCSIZE;
1390                adapter->drvr_qdepth = 255;
1391                adapter->adapter_qdepth = adapter->drvr_qdepth;
1392                adapter->sync_ok = fpinfo->sync_ok;
1393                adapter->fast_ok = fpinfo->fast_ok;
1394                adapter->ultra_ok = fpinfo->ultra_ok;
1395                adapter->wide_ok = fpinfo->wide_ok;
1396                adapter->discon_ok = fpinfo->discon_ok;
1397                adapter->tagq_ok = 0xFFFF;
1398                goto common;
1399        }
1400        /*
1401           Issue the Inquire Board ID command.
1402         */
1403        if (blogic_cmd(adapter, BLOGIC_GET_BOARD_ID, NULL, 0, &id,
1404                                sizeof(id)) != sizeof(id))
1405                return blogic_failure(adapter, "INQUIRE BOARD ID");
1406        /*
1407           Issue the Inquire Configuration command.
1408         */
1409        if (blogic_cmd(adapter, BLOGIC_INQ_CONFIG, NULL, 0, &config,
1410                                sizeof(config))
1411            != sizeof(config))
1412                return blogic_failure(adapter, "INQUIRE CONFIGURATION");
1413        /*
1414           Issue the Inquire Setup Information command.
1415         */
1416        req_replylen = sizeof(setupinfo);
1417        if (blogic_cmd(adapter, BLOGIC_INQ_SETUPINFO, &req_replylen,
1418                                sizeof(req_replylen), &setupinfo,
1419                                sizeof(setupinfo)) != sizeof(setupinfo))
1420                return blogic_failure(adapter, "INQUIRE SETUP INFORMATION");
1421        /*
1422           Issue the Inquire Extended Setup Information command.
1423         */
1424        req_replylen = sizeof(ext_setupinfo);
1425        if (blogic_cmd(adapter, BLOGIC_INQ_EXTSETUP, &req_replylen,
1426                                sizeof(req_replylen), &ext_setupinfo,
1427                                sizeof(ext_setupinfo)) != sizeof(ext_setupinfo))
1428                return blogic_failure(adapter,
1429                                        "INQUIRE EXTENDED SETUP INFORMATION");
1430        /*
1431           Issue the Inquire Firmware Version 3rd Digit command.
1432         */
1433        fw_ver_digit3 = '\0';
1434        if (id.fw_ver_digit1 > '0')
1435                if (blogic_cmd(adapter, BLOGIC_INQ_FWVER_D3, NULL, 0,
1436                                &fw_ver_digit3,
1437                                sizeof(fw_ver_digit3)) != sizeof(fw_ver_digit3))
1438                        return blogic_failure(adapter,
1439                                                "INQUIRE FIRMWARE 3RD DIGIT");
1440        /*
1441           Issue the Inquire Host Adapter Model Number command.
1442         */
1443        if (ext_setupinfo.bus_type == 'A' && id.fw_ver_digit1 == '2')
1444                /* BusLogic BT-542B ISA 2.xx */
1445                strcpy(model, "542B");
1446        else if (ext_setupinfo.bus_type == 'E' && id.fw_ver_digit1 == '2' &&
1447                        (id.fw_ver_digit2 <= '1' || (id.fw_ver_digit2 == '2' &&
1448                                                     fw_ver_digit3 == '0')))
1449                /* BusLogic BT-742A EISA 2.1x or 2.20 */
1450                strcpy(model, "742A");
1451        else if (ext_setupinfo.bus_type == 'E' && id.fw_ver_digit1 == '0')
1452                /* AMI FastDisk EISA Series 441 0.x */
1453                strcpy(model, "747A");
1454        else {
1455                req_replylen = sizeof(model);
1456                if (blogic_cmd(adapter, BLOGIC_INQ_MODELNO, &req_replylen,
1457                                        sizeof(req_replylen), &model,
1458                                        sizeof(model)) != sizeof(model))
1459                        return blogic_failure(adapter,
1460                                        "INQUIRE HOST ADAPTER MODEL NUMBER");
1461        }
1462        /*
1463           BusLogic MultiMaster Host Adapters can be identified by their
1464           model number and the major version number of their firmware
1465           as follows:
1466
1467           5.xx       BusLogic "W" Series Host Adapters:
1468           BT-948/958/958D
1469           4.xx       BusLogic "C" Series Host Adapters:
1470           BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
1471           3.xx       BusLogic "S" Series Host Adapters:
1472           BT-747S/747D/757S/757D/445S/545S/542D
1473           BT-542B/742A (revision H)
1474           2.xx       BusLogic "A" Series Host Adapters:
1475           BT-542B/742A (revision G and below)
1476           0.xx       AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
1477         */
1478        /*
1479           Save the Model Name and Host Adapter Name in the Host Adapter
1480           structure.
1481         */
1482        tgt = adapter->model;
1483        *tgt++ = 'B';
1484        *tgt++ = 'T';
1485        *tgt++ = '-';
1486        for (i = 0; i < sizeof(model); i++) {
1487                ch = model[i];
1488                if (ch == ' ' || ch == '\0')
1489                        break;
1490                *tgt++ = ch;
1491        }
1492        *tgt++ = '\0';
1493        /*
1494           Save the Firmware Version in the Host Adapter structure.
1495         */
1496        tgt = adapter->fw_ver;
1497        *tgt++ = id.fw_ver_digit1;
1498        *tgt++ = '.';
1499        *tgt++ = id.fw_ver_digit2;
1500        if (fw_ver_digit3 != ' ' && fw_ver_digit3 != '\0')
1501                *tgt++ = fw_ver_digit3;
1502        *tgt = '\0';
1503        /*
1504           Issue the Inquire Firmware Version Letter command.
1505         */
1506        if (strcmp(adapter->fw_ver, "3.3") >= 0) {
1507                if (blogic_cmd(adapter, BLOGIC_INQ_FWVER_LETTER, NULL, 0,
1508                                &fw_ver_letter,
1509                                sizeof(fw_ver_letter)) != sizeof(fw_ver_letter))
1510                        return blogic_failure(adapter,
1511                                        "INQUIRE FIRMWARE VERSION LETTER");
1512                if (fw_ver_letter != ' ' && fw_ver_letter != '\0')
1513                        *tgt++ = fw_ver_letter;
1514                *tgt = '\0';
1515        }
1516        /*
1517           Save the Host Adapter SCSI ID in the Host Adapter structure.
1518         */
1519        adapter->scsi_id = config.id;
1520        /*
1521           Determine the Bus Type and save it in the Host Adapter structure,
1522           determine and save the IRQ Channel if necessary, and determine
1523           and save the DMA Channel for ISA Host Adapters.
1524         */
1525        adapter->adapter_bus_type =
1526                        blogic_adater_bus_types[adapter->model[3] - '4'];
1527        if (adapter->irq_ch == 0) {
1528                if (config.irq_ch9)
1529                        adapter->irq_ch = 9;
1530                else if (config.irq_ch10)
1531                        adapter->irq_ch = 10;
1532                else if (config.irq_ch11)
1533                        adapter->irq_ch = 11;
1534                else if (config.irq_ch12)
1535                        adapter->irq_ch = 12;
1536                else if (config.irq_ch14)
1537                        adapter->irq_ch = 14;
1538                else if (config.irq_ch15)
1539                        adapter->irq_ch = 15;
1540        }
1541        if (adapter->adapter_bus_type == BLOGIC_ISA_BUS) {
1542                if (config.dma_ch5)
1543                        adapter->dma_ch = 5;
1544                else if (config.dma_ch6)
1545                        adapter->dma_ch = 6;
1546                else if (config.dma_ch7)
1547                        adapter->dma_ch = 7;
1548        }
1549        /*
1550           Determine whether Extended Translation is enabled and save it in
1551           the Host Adapter structure.
1552         */
1553        georeg.all = blogic_rdgeom(adapter);
1554        adapter->ext_trans_enable = georeg.gr.ext_trans_enable;
1555        /*
1556           Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide
1557           SCSI flag, Differential SCSI flag, SCAM Supported flag, and
1558           Ultra SCSI flag in the Host Adapter structure.
1559         */
1560        adapter->adapter_sglimit = ext_setupinfo.sg_limit;
1561        adapter->drvr_sglimit = adapter->adapter_sglimit;
1562        if (adapter->adapter_sglimit > BLOGIC_SG_LIMIT)
1563                adapter->drvr_sglimit = BLOGIC_SG_LIMIT;
1564        if (ext_setupinfo.misc.level_int)
1565                adapter->level_int = true;
1566        adapter->wide = ext_setupinfo.wide;
1567        adapter->differential = ext_setupinfo.differential;
1568        adapter->scam = ext_setupinfo.scam;
1569        adapter->ultra = ext_setupinfo.ultra;
1570        /*
1571           Determine whether Extended LUN Format CCBs are supported and save the
1572           information in the Host Adapter structure.
1573         */
1574        if (adapter->fw_ver[0] == '5' || (adapter->fw_ver[0] == '4' &&
1575                                adapter->wide))
1576                adapter->ext_lun = true;
1577        /*
1578           Issue the Inquire PCI Host Adapter Information command to read the
1579           Termination Information from "W" series MultiMaster Host Adapters.
1580         */
1581        if (adapter->fw_ver[0] == '5') {
1582                if (blogic_cmd(adapter, BLOGIC_INQ_PCI_INFO, NULL, 0,
1583                                &adapter_info,
1584                                sizeof(adapter_info)) != sizeof(adapter_info))
1585                        return blogic_failure(adapter,
1586                                        "INQUIRE PCI HOST ADAPTER INFORMATION");
1587                /*
1588                   Save the Termination Information in the Host Adapter
1589                   structure.
1590                 */
1591                if (adapter_info.genericinfo_valid) {
1592                        adapter->terminfo_valid = true;
1593                        adapter->low_term = adapter_info.low_term;
1594                        adapter->high_term = adapter_info.high_term;
1595                }
1596        }
1597        /*
1598           Issue the Fetch Host Adapter Local RAM command to read the
1599           AutoSCSI data from "W" and "C" series MultiMaster Host Adapters.
1600         */
1601        if (adapter->fw_ver[0] >= '4') {
1602                fetch_localram.offset = BLOGIC_AUTOSCSI_BASE;
1603                fetch_localram.count = sizeof(autoscsi);
1604                if (blogic_cmd(adapter, BLOGIC_FETCH_LOCALRAM, &fetch_localram,
1605                                        sizeof(fetch_localram), &autoscsi,
1606                                        sizeof(autoscsi)) != sizeof(autoscsi))
1607                        return blogic_failure(adapter,
1608                                                "FETCH HOST ADAPTER LOCAL RAM");
1609                /*
1610                   Save the Parity Checking Enabled, Bus Reset Enabled,
1611                   and Termination Information in the Host Adapter structure.
1612                 */
1613                adapter->parity = autoscsi.parity;
1614                adapter->reset_enabled = autoscsi.reset_enabled;
1615                if (adapter->fw_ver[0] == '4') {
1616                        adapter->terminfo_valid = true;
1617                        adapter->low_term = autoscsi.low_term;
1618                        adapter->high_term = autoscsi.high_term;
1619                }
1620                /*
1621                   Save the Wide Permitted, Fast Permitted, Synchronous
1622                   Permitted, Disconnect Permitted, Ultra Permitted, and
1623                   SCAM Information in the Host Adapter structure.
1624                 */
1625                adapter->wide_ok = autoscsi.wide_ok;
1626                adapter->fast_ok = autoscsi.fast_ok;
1627                adapter->sync_ok = autoscsi.sync_ok;
1628                adapter->discon_ok = autoscsi.discon_ok;
1629                if (adapter->ultra)
1630                        adapter->ultra_ok = autoscsi.ultra_ok;
1631                if (adapter->scam) {
1632                        adapter->scam_enabled = autoscsi.scam_enabled;
1633                        adapter->scam_lev2 = autoscsi.scam_lev2;
1634                }
1635        }
1636        /*
1637           Initialize fields in the Host Adapter structure for "S" and "A"
1638           series MultiMaster Host Adapters.
1639         */
1640        if (adapter->fw_ver[0] < '4') {
1641                if (setupinfo.sync) {
1642                        adapter->sync_ok = 0xFF;
1643                        if (adapter->adapter_bus_type == BLOGIC_EISA_BUS) {
1644                                if (ext_setupinfo.misc.fast_on_eisa)
1645                                        adapter->fast_ok = 0xFF;
1646                                if (strcmp(adapter->model, "BT-757") == 0)
1647                                        adapter->wide_ok = 0xFF;
1648                        }
1649                }
1650                adapter->discon_ok = 0xFF;
1651                adapter->parity = setupinfo.parity;
1652                adapter->reset_enabled = true;
1653        }
1654        /*
1655           Determine the maximum number of Target IDs and Logical Units
1656           supported by this driver for Wide and Narrow Host Adapters.
1657         */
1658        adapter->maxdev = (adapter->wide ? 16 : 8);
1659        adapter->maxlun = (adapter->ext_lun ? 32 : 8);
1660        /*
1661           Select appropriate values for the Mailbox Count, Driver Queue Depth,
1662           Initial CCBs, and Incremental CCBs variables based on whether
1663           or not Strict Round Robin Mode is supported.  If Strict Round
1664           Robin Mode is supported, then there is no performance degradation
1665           in using the maximum possible number of Outgoing and Incoming
1666           Mailboxes and allowing the Tagged and Untagged Queue Depths to
1667           determine the actual utilization.  If Strict Round Robin Mode is
1668           not supported, then the Host Adapter must scan all the Outgoing
1669           Mailboxes whenever an Outgoing Mailbox entry is made, which can
1670           cause a substantial performance penalty.  The host adapters
1671           actually have room to store the following number of CCBs
1672           internally; that is, they can internally queue and manage this
1673           many active commands on the SCSI bus simultaneously.  Performance
1674           measurements demonstrate that the Driver Queue Depth should be
1675           set to the Mailbox Count, rather than the Host Adapter Queue
1676           Depth (internal CCB capacity), as it is more efficient to have the
1677           queued commands waiting in Outgoing Mailboxes if necessary than
1678           to block the process in the higher levels of the SCSI Subsystem.
1679
1680           192          BT-948/958/958D
1681           100          BT-946C/956C/956CD/747C/757C/757CD/445C
1682           50   BT-545C/540CF
1683           30   BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
1684         */
1685        if (adapter->fw_ver[0] == '5')
1686                adapter->adapter_qdepth = 192;
1687        else if (adapter->fw_ver[0] == '4')
1688                adapter->adapter_qdepth = (adapter->adapter_bus_type !=
1689                                                BLOGIC_ISA_BUS ? 100 : 50);
1690        else
1691                adapter->adapter_qdepth = 30;
1692        if (strcmp(adapter->fw_ver, "3.31") >= 0) {
1693                adapter->strict_rr = true;
1694                adapter->mbox_count = BLOGIC_MAX_MAILBOX;
1695        } else {
1696                adapter->strict_rr = false;
1697                adapter->mbox_count = 32;
1698        }
1699        adapter->drvr_qdepth = adapter->mbox_count;
1700        adapter->initccbs = 4 * BLOGIC_CCB_GRP_ALLOCSIZE;
1701        adapter->inc_ccbs = BLOGIC_CCB_GRP_ALLOCSIZE;
1702        /*
1703           Tagged Queuing support is available and operates properly on
1704           all "W" series MultiMaster Host Adapters, on "C" series
1705           MultiMaster Host Adapters with firmware version 4.22 and above,
1706           and on "S" series MultiMaster Host Adapters with firmware version
1707           3.35 and above.
1708         */
1709        adapter->tagq_ok = 0;
1710        switch (adapter->fw_ver[0]) {
1711        case '5':
1712                adapter->tagq_ok = 0xFFFF;
1713                break;
1714        case '4':
1715                if (strcmp(adapter->fw_ver, "4.22") >= 0)
1716                        adapter->tagq_ok = 0xFFFF;
1717                break;
1718        case '3':
1719                if (strcmp(adapter->fw_ver, "3.35") >= 0)
1720                        adapter->tagq_ok = 0xFFFF;
1721                break;
1722        }
1723        /*
1724           Determine the Host Adapter BIOS Address if the BIOS is enabled and
1725           save it in the Host Adapter structure.  The BIOS is disabled if the
1726           bios_addr is 0.
1727         */
1728        adapter->bios_addr = ext_setupinfo.bios_addr << 12;
1729        /*
1730           ISA Host Adapters require Bounce Buffers if there is more than
1731           16MB memory.
1732         */
1733        if (adapter->adapter_bus_type == BLOGIC_ISA_BUS &&
1734                        (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1735                adapter->need_bouncebuf = true;
1736        /*
1737           BusLogic BT-445S Host Adapters prior to board revision E have a
1738           hardware bug whereby when the BIOS is enabled, transfers to/from
1739           the same address range the BIOS occupies modulo 16MB are handled
1740           incorrectly.  Only properly functioning BT-445S Host Adapters
1741           have firmware version 3.37, so require that ISA Bounce Buffers
1742           be used for the buggy BT-445S models if there is more than 16MB
1743           memory.
1744         */
1745        if (adapter->bios_addr > 0 && strcmp(adapter->model, "BT-445S") == 0 &&
1746                        strcmp(adapter->fw_ver, "3.37") < 0 &&
1747                        (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1748                adapter->need_bouncebuf = true;
1749        /*
1750           Initialize parameters common to MultiMaster and FlashPoint
1751           Host Adapters.
1752         */
1753common:
1754        /*
1755           Initialize the Host Adapter Full Model Name from the Model Name.
1756         */
1757        strcpy(adapter->full_model, "BusLogic ");
1758        strcat(adapter->full_model, adapter->model);
1759        /*
1760           Select an appropriate value for the Tagged Queue Depth either from a
1761           BusLogic Driver Options specification, or based on whether this Host
1762           Adapter requires that ISA Bounce Buffers be used.  The Tagged Queue
1763           Depth is left at 0 for automatic determination in
1764           BusLogic_SelectQueueDepths. Initialize the Untagged Queue Depth.
1765         */
1766        for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++) {
1767                unsigned char qdepth = 0;
1768                if (adapter->drvr_opts != NULL &&
1769                                adapter->drvr_opts->qdepth[tgt_id] > 0)
1770                        qdepth = adapter->drvr_opts->qdepth[tgt_id];
1771                else if (adapter->need_bouncebuf)
1772                        qdepth = BLOGIC_TAG_DEPTH_BB;
1773                adapter->qdepth[tgt_id] = qdepth;
1774        }
1775        if (adapter->need_bouncebuf)
1776                adapter->untag_qdepth = BLOGIC_UNTAG_DEPTH_BB;
1777        else
1778                adapter->untag_qdepth = BLOGIC_UNTAG_DEPTH;
1779        if (adapter->drvr_opts != NULL)
1780                adapter->common_qdepth = adapter->drvr_opts->common_qdepth;
1781        if (adapter->common_qdepth > 0 &&
1782                        adapter->common_qdepth < adapter->untag_qdepth)
1783                adapter->untag_qdepth = adapter->common_qdepth;
1784        /*
1785           Tagged Queuing is only allowed if Disconnect/Reconnect is permitted.
1786           Therefore, mask the Tagged Queuing Permitted Default bits with the
1787           Disconnect/Reconnect Permitted bits.
1788         */
1789        adapter->tagq_ok &= adapter->discon_ok;
1790        /*
1791           Combine the default Tagged Queuing Permitted bits with any
1792           BusLogic Driver Options Tagged Queuing specification.
1793         */
1794        if (adapter->drvr_opts != NULL)
1795                adapter->tagq_ok = (adapter->drvr_opts->tagq_ok &
1796                                adapter->drvr_opts->tagq_ok_mask) |
1797                        (adapter->tagq_ok & ~adapter->drvr_opts->tagq_ok_mask);
1798
1799        /*
1800           Select an appropriate value for Bus Settle Time either from a
1801           BusLogic Driver Options specification, or from
1802           BLOGIC_BUS_SETTLE_TIME.
1803         */
1804        if (adapter->drvr_opts != NULL &&
1805                        adapter->drvr_opts->bus_settle_time > 0)
1806                adapter->bus_settle_time = adapter->drvr_opts->bus_settle_time;
1807        else
1808                adapter->bus_settle_time = BLOGIC_BUS_SETTLE_TIME;
1809        /*
1810           Indicate reading the Host Adapter Configuration completed
1811           successfully.
1812         */
1813        return true;
1814}
1815
1816
1817/*
1818  blogic_reportconfig reports the configuration of Host Adapter.
1819*/
1820
1821static bool __init blogic_reportconfig(struct blogic_adapter *adapter)
1822{
1823        unsigned short alltgt_mask = (1 << adapter->maxdev) - 1;
1824        unsigned short sync_ok, fast_ok;
1825        unsigned short ultra_ok, wide_ok;
1826        unsigned short discon_ok, tagq_ok;
1827        bool common_syncneg, common_tagq_depth;
1828        char syncstr[BLOGIC_MAXDEV + 1];
1829        char widestr[BLOGIC_MAXDEV + 1];
1830        char discon_str[BLOGIC_MAXDEV + 1];
1831        char tagq_str[BLOGIC_MAXDEV + 1];
1832        char *syncmsg = syncstr;
1833        char *widemsg = widestr;
1834        char *discon_msg = discon_str;
1835        char *tagq_msg = tagq_str;
1836        int tgt_id;
1837
1838        blogic_info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n", adapter, adapter->model, blogic_adapter_busnames[adapter->adapter_bus_type], (adapter->wide ? " Wide" : ""), (adapter->differential ? " Differential" : ""), (adapter->ultra ? " Ultra" : ""));
1839        blogic_info("  Firmware Version: %s, I/O Address: 0x%X, " "IRQ Channel: %d/%s\n", adapter, adapter->fw_ver, adapter->io_addr, adapter->irq_ch, (adapter->level_int ? "Level" : "Edge"));
1840        if (adapter->adapter_bus_type != BLOGIC_PCI_BUS) {
1841                blogic_info("  DMA Channel: ", adapter);
1842                if (adapter->dma_ch > 0)
1843                        blogic_info("%d, ", adapter, adapter->dma_ch);
1844                else
1845                        blogic_info("None, ", adapter);
1846                if (adapter->bios_addr > 0)
1847                        blogic_info("BIOS Address: 0x%X, ", adapter,
1848                                        adapter->bios_addr);
1849                else
1850                        blogic_info("BIOS Address: None, ", adapter);
1851        } else {
1852                blogic_info("  PCI Bus: %d, Device: %d, Address: ", adapter,
1853                                adapter->bus, adapter->dev);
1854                if (adapter->pci_addr > 0)
1855                        blogic_info("0x%X, ", adapter, adapter->pci_addr);
1856                else
1857                        blogic_info("Unassigned, ", adapter);
1858        }
1859        blogic_info("Host Adapter SCSI ID: %d\n", adapter, adapter->scsi_id);
1860        blogic_info("  Parity Checking: %s, Extended Translation: %s\n",
1861                        adapter, (adapter->parity ? "Enabled" : "Disabled"),
1862                        (adapter->ext_trans_enable ? "Enabled" : "Disabled"));
1863        alltgt_mask &= ~(1 << adapter->scsi_id);
1864        sync_ok = adapter->sync_ok & alltgt_mask;
1865        fast_ok = adapter->fast_ok & alltgt_mask;
1866        ultra_ok = adapter->ultra_ok & alltgt_mask;
1867        if ((blogic_multimaster_type(adapter) &&
1868                        (adapter->fw_ver[0] >= '4' ||
1869                         adapter->adapter_bus_type == BLOGIC_EISA_BUS)) ||
1870                        blogic_flashpoint_type(adapter)) {
1871                common_syncneg = false;
1872                if (sync_ok == 0) {
1873                        syncmsg = "Disabled";
1874                        common_syncneg = true;
1875                } else if (sync_ok == alltgt_mask) {
1876                        if (fast_ok == 0) {
1877                                syncmsg = "Slow";
1878                                common_syncneg = true;
1879                        } else if (fast_ok == alltgt_mask) {
1880                                if (ultra_ok == 0) {
1881                                        syncmsg = "Fast";
1882                                        common_syncneg = true;
1883                                } else if (ultra_ok == alltgt_mask) {
1884                                        syncmsg = "Ultra";
1885                                        common_syncneg = true;
1886                                }
1887                        }
1888                }
1889                if (!common_syncneg) {
1890                        for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
1891                                syncstr[tgt_id] = ((!(sync_ok & (1 << tgt_id))) ? 'N' : (!(fast_ok & (1 << tgt_id)) ? 'S' : (!(ultra_ok & (1 << tgt_id)) ? 'F' : 'U')));
1892                        syncstr[adapter->scsi_id] = '#';
1893                        syncstr[adapter->maxdev] = '\0';
1894                }
1895        } else
1896                syncmsg = (sync_ok == 0 ? "Disabled" : "Enabled");
1897        wide_ok = adapter->wide_ok & alltgt_mask;
1898        if (wide_ok == 0)
1899                widemsg = "Disabled";
1900        else if (wide_ok == alltgt_mask)
1901                widemsg = "Enabled";
1902        else {
1903                for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
1904                        widestr[tgt_id] = ((wide_ok & (1 << tgt_id)) ? 'Y' : 'N');
1905                widestr[adapter->scsi_id] = '#';
1906                widestr[adapter->maxdev] = '\0';
1907        }
1908        discon_ok = adapter->discon_ok & alltgt_mask;
1909        if (discon_ok == 0)
1910                discon_msg = "Disabled";
1911        else if (discon_ok == alltgt_mask)
1912                discon_msg = "Enabled";
1913        else {
1914                for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
1915                        discon_str[tgt_id] = ((discon_ok & (1 << tgt_id)) ? 'Y' : 'N');
1916                discon_str[adapter->scsi_id] = '#';
1917                discon_str[adapter->maxdev] = '\0';
1918        }
1919        tagq_ok = adapter->tagq_ok & alltgt_mask;
1920        if (tagq_ok == 0)
1921                tagq_msg = "Disabled";
1922        else if (tagq_ok == alltgt_mask)
1923                tagq_msg = "Enabled";
1924        else {
1925                for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
1926                        tagq_str[tgt_id] = ((tagq_ok & (1 << tgt_id)) ? 'Y' : 'N');
1927                tagq_str[adapter->scsi_id] = '#';
1928                tagq_str[adapter->maxdev] = '\0';
1929        }
1930        blogic_info("  Synchronous Negotiation: %s, Wide Negotiation: %s\n",
1931                        adapter, syncmsg, widemsg);
1932        blogic_info("  Disconnect/Reconnect: %s, Tagged Queuing: %s\n", adapter,
1933                        discon_msg, tagq_msg);
1934        if (blogic_multimaster_type(adapter)) {
1935                blogic_info("  Scatter/Gather Limit: %d of %d segments, " "Mailboxes: %d\n", adapter, adapter->drvr_sglimit, adapter->adapter_sglimit, adapter->mbox_count);
1936                blogic_info("  Driver Queue Depth: %d, " "Host Adapter Queue Depth: %d\n", adapter, adapter->drvr_qdepth, adapter->adapter_qdepth);
1937        } else
1938                blogic_info("  Driver Queue Depth: %d, " "Scatter/Gather Limit: %d segments\n", adapter, adapter->drvr_qdepth, adapter->drvr_sglimit);
1939        blogic_info("  Tagged Queue Depth: ", adapter);
1940        common_tagq_depth = true;
1941        for (tgt_id = 1; tgt_id < adapter->maxdev; tgt_id++)
1942                if (adapter->qdepth[tgt_id] != adapter->qdepth[0]) {
1943                        common_tagq_depth = false;
1944                        break;
1945                }
1946        if (common_tagq_depth) {
1947                if (adapter->qdepth[0] > 0)
1948                        blogic_info("%d", adapter, adapter->qdepth[0]);
1949                else
1950                        blogic_info("Automatic", adapter);
1951        } else
1952                blogic_info("Individual", adapter);
1953        blogic_info(", Untagged Queue Depth: %d\n", adapter,
1954                        adapter->untag_qdepth);
1955        if (adapter->terminfo_valid) {
1956                if (adapter->wide)
1957                        blogic_info("  SCSI Bus Termination: %s", adapter,
1958                                (adapter->low_term ? (adapter->high_term ? "Both Enabled" : "Low Enabled") : (adapter->high_term ? "High Enabled" : "Both Disabled")));
1959                else
1960                        blogic_info("  SCSI Bus Termination: %s", adapter,
1961                                (adapter->low_term ? "Enabled" : "Disabled"));
1962                if (adapter->scam)
1963                        blogic_info(", SCAM: %s", adapter,
1964                                (adapter->scam_enabled ? (adapter->scam_lev2 ? "Enabled, Level 2" : "Enabled, Level 1") : "Disabled"));
1965                blogic_info("\n", adapter);
1966        }
1967        /*
1968           Indicate reporting the Host Adapter configuration completed
1969           successfully.
1970         */
1971        return true;
1972}
1973
1974
1975/*
1976  blogic_getres acquires the system resources necessary to use
1977  Host Adapter.
1978*/
1979
1980static bool __init blogic_getres(struct blogic_adapter *adapter)
1981{
1982        if (adapter->irq_ch == 0) {
1983                blogic_err("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n",
1984                                adapter);
1985                return false;
1986        }
1987        /*
1988           Acquire shared access to the IRQ Channel.
1989         */
1990        if (request_irq(adapter->irq_ch, blogic_inthandler, IRQF_SHARED,
1991                                adapter->full_model, adapter) < 0) {
1992                blogic_err("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
1993                                adapter, adapter->irq_ch);
1994                return false;
1995        }
1996        adapter->irq_acquired = true;
1997        /*
1998           Acquire exclusive access to the DMA Channel.
1999         */
2000        if (adapter->dma_ch > 0) {
2001                if (request_dma(adapter->dma_ch, adapter->full_model) < 0) {
2002                        blogic_err("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n", adapter, adapter->dma_ch);
2003                        return false;
2004                }
2005                set_dma_mode(adapter->dma_ch, DMA_MODE_CASCADE);
2006                enable_dma(adapter->dma_ch);
2007                adapter->dma_chan_acquired = true;
2008        }
2009        /*
2010           Indicate the System Resource Acquisition completed successfully,
2011         */
2012        return true;
2013}
2014
2015
2016/*
2017  blogic_relres releases any system resources previously acquired
2018  by blogic_getres.
2019*/
2020
2021static void blogic_relres(struct blogic_adapter *adapter)
2022{
2023        /*
2024           Release shared access to the IRQ Channel.
2025         */
2026        if (adapter->irq_acquired)
2027                free_irq(adapter->irq_ch, adapter);
2028        /*
2029           Release exclusive access to the DMA Channel.
2030         */
2031        if (adapter->dma_chan_acquired)
2032                free_dma(adapter->dma_ch);
2033        /*
2034           Release any allocated memory structs not released elsewhere
2035         */
2036        if (adapter->mbox_space)
2037                dma_free_coherent(&adapter->pci_device->dev, adapter->mbox_sz,
2038                        adapter->mbox_space, adapter->mbox_space_handle);
2039        pci_dev_put(adapter->pci_device);
2040        adapter->mbox_space = NULL;
2041        adapter->mbox_space_handle = 0;
2042        adapter->mbox_sz = 0;
2043}
2044
2045
2046/*
2047  blogic_initadapter initializes Host Adapter.  This is the only
2048  function called during SCSI Host Adapter detection which modifies the state
2049  of the Host Adapter from its initial power on or hard reset state.
2050*/
2051
2052static bool blogic_initadapter(struct blogic_adapter *adapter)
2053{
2054        struct blogic_extmbox_req extmbox_req;
2055        enum blogic_rr_req rr_req;
2056        enum blogic_setccb_fmt setccb_fmt;
2057        int tgt_id;
2058
2059        /*
2060           Initialize the pointers to the first and last CCBs that are
2061           queued for completion processing.
2062         */
2063        adapter->firstccb = NULL;
2064        adapter->lastccb = NULL;
2065
2066        /*
2067           Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active,
2068           Command Successful Flag, Active Commands, and Commands Since Reset
2069           for each Target Device.
2070         */
2071        for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) {
2072                adapter->bdr_pend[tgt_id] = NULL;
2073                adapter->tgt_flags[tgt_id].tagq_active = false;
2074                adapter->tgt_flags[tgt_id].cmd_good = false;
2075                adapter->active_cmds[tgt_id] = 0;
2076                adapter->cmds_since_rst[tgt_id] = 0;
2077        }
2078
2079        /*
2080           FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes.
2081         */
2082        if (blogic_flashpoint_type(adapter))
2083                goto done;
2084
2085        /*
2086           Initialize the Outgoing and Incoming Mailbox pointers.
2087         */
2088        adapter->mbox_sz = adapter->mbox_count * (sizeof(struct blogic_outbox) + sizeof(struct blogic_inbox));
2089        adapter->mbox_space = dma_alloc_coherent(&adapter->pci_device->dev,
2090                                adapter->mbox_sz, &adapter->mbox_space_handle,
2091                                GFP_KERNEL);
2092        if (adapter->mbox_space == NULL)
2093                return blogic_failure(adapter, "MAILBOX ALLOCATION");
2094        adapter->first_outbox = (struct blogic_outbox *) adapter->mbox_space;
2095        adapter->last_outbox = adapter->first_outbox + adapter->mbox_count - 1;
2096        adapter->next_outbox = adapter->first_outbox;
2097        adapter->first_inbox = (struct blogic_inbox *) (adapter->last_outbox + 1);
2098        adapter->last_inbox = adapter->first_inbox + adapter->mbox_count - 1;
2099        adapter->next_inbox = adapter->first_inbox;
2100
2101        /*
2102           Initialize the Outgoing and Incoming Mailbox structures.
2103         */
2104        memset(adapter->first_outbox, 0,
2105                        adapter->mbox_count * sizeof(struct blogic_outbox));
2106        memset(adapter->first_inbox, 0,
2107                        adapter->mbox_count * sizeof(struct blogic_inbox));
2108
2109        /*
2110           Initialize the Host Adapter's Pointer to the Outgoing/Incoming
2111           Mailboxes.
2112         */
2113        extmbox_req.mbox_count = adapter->mbox_count;
2114        extmbox_req.base_mbox_addr = (u32) adapter->mbox_space_handle;
2115        if (blogic_cmd(adapter, BLOGIC_INIT_EXT_MBOX, &extmbox_req,
2116                                sizeof(extmbox_req), NULL, 0) < 0)
2117                return blogic_failure(adapter, "MAILBOX INITIALIZATION");
2118        /*
2119           Enable Strict Round Robin Mode if supported by the Host Adapter. In
2120           Strict Round Robin Mode, the Host Adapter only looks at the next
2121           Outgoing Mailbox for each new command, rather than scanning
2122           through all the Outgoing Mailboxes to find any that have new
2123           commands in them.  Strict Round Robin Mode is significantly more
2124           efficient.
2125         */
2126        if (adapter->strict_rr) {
2127                rr_req = BLOGIC_STRICT_RR_MODE;
2128                if (blogic_cmd(adapter, BLOGIC_STRICT_RR, &rr_req,
2129                                        sizeof(rr_req), NULL, 0) < 0)
2130                        return blogic_failure(adapter,
2131                                        "ENABLE STRICT ROUND ROBIN MODE");
2132        }
2133
2134        /*
2135           For Host Adapters that support Extended LUN Format CCBs, issue the
2136           Set CCB Format command to allow 32 Logical Units per Target Device.
2137         */
2138        if (adapter->ext_lun) {
2139                setccb_fmt = BLOGIC_EXT_LUN_CCB;
2140                if (blogic_cmd(adapter, BLOGIC_SETCCB_FMT, &setccb_fmt,
2141                                        sizeof(setccb_fmt), NULL, 0) < 0)
2142                        return blogic_failure(adapter, "SET CCB FORMAT");
2143        }
2144
2145        /*
2146           Announce Successful Initialization.
2147         */
2148done:
2149        if (!adapter->adapter_initd) {
2150                blogic_info("*** %s Initialized Successfully ***\n", adapter,
2151                                adapter->full_model);
2152                blogic_info("\n", adapter);
2153        } else
2154                blogic_warn("*** %s Initialized Successfully ***\n", adapter,
2155                                adapter->full_model);
2156        adapter->adapter_initd = true;
2157
2158        /*
2159           Indicate the Host Adapter Initialization completed successfully.
2160         */
2161        return true;
2162}
2163
2164
2165/*
2166  blogic_inquiry inquires about the Target Devices accessible
2167  through Host Adapter.
2168*/
2169
2170static bool __init blogic_inquiry(struct blogic_adapter *adapter)
2171{
2172        u16 installed_devs;
2173        u8 installed_devs0to7[8];
2174        struct blogic_setup_info setupinfo;
2175        u8 sync_period[BLOGIC_MAXDEV];
2176        unsigned char req_replylen;
2177        int tgt_id;
2178
2179        /*
2180           Wait a few seconds between the Host Adapter Hard Reset which
2181           initiates a SCSI Bus Reset and issuing any SCSI Commands. Some
2182           SCSI devices get confused if they receive SCSI Commands too soon
2183           after a SCSI Bus Reset.
2184         */
2185        blogic_delay(adapter->bus_settle_time);
2186        /*
2187           FlashPoint Host Adapters do not provide for Target Device Inquiry.
2188         */
2189        if (blogic_flashpoint_type(adapter))
2190                return true;
2191        /*
2192           Inhibit the Target Device Inquiry if requested.
2193         */
2194        if (adapter->drvr_opts != NULL && adapter->drvr_opts->stop_tgt_inquiry)
2195                return true;
2196        /*
2197           Issue the Inquire Target Devices command for host adapters with
2198           firmware version 4.25 or later, or the Inquire Installed Devices
2199           ID 0 to 7 command for older host adapters.  This is necessary to
2200           force Synchronous Transfer Negotiation so that the Inquire Setup
2201           Information and Inquire Synchronous Period commands will return
2202           valid data.  The Inquire Target Devices command is preferable to
2203           Inquire Installed Devices ID 0 to 7 since it only probes Logical
2204           Unit 0 of each Target Device.
2205         */
2206        if (strcmp(adapter->fw_ver, "4.25") >= 0) {
2207
2208                /*
2209                   Issue a Inquire Target Devices command. Inquire Target
2210                   Devices only tests Logical Unit 0 of each Target Device
2211                   unlike the Inquire Installed Devices commands which test
2212                   Logical Units 0 - 7.  Two bytes are returned, where byte
2213                   0 bit 0 set indicates that Target Device 0 exists, and so on.
2214                 */
2215
2216                if (blogic_cmd(adapter, BLOGIC_INQ_DEV, NULL, 0,
2217                                        &installed_devs, sizeof(installed_devs))
2218                    != sizeof(installed_devs))
2219                        return blogic_failure(adapter, "INQUIRE TARGET DEVICES");
2220                for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
2221                        adapter->tgt_flags[tgt_id].tgt_exists =
2222                                (installed_devs & (1 << tgt_id) ? true : false);
2223        } else {
2224
2225                /*
2226                   Issue an Inquire Installed Devices command. For each
2227                   Target Device, a byte is returned where bit 0 set
2228                   indicates that Logical Unit 0 * exists, bit 1 set
2229                   indicates that Logical Unit 1 exists, and so on.
2230                 */
2231
2232                if (blogic_cmd(adapter, BLOGIC_INQ_DEV0TO7, NULL, 0,
2233                                &installed_devs0to7, sizeof(installed_devs0to7))
2234                    != sizeof(installed_devs0to7))
2235                        return blogic_failure(adapter,
2236                                        "INQUIRE INSTALLED DEVICES ID 0 TO 7");
2237                for (tgt_id = 0; tgt_id < 8; tgt_id++)
2238                        adapter->tgt_flags[tgt_id].tgt_exists =
2239                                (installed_devs0to7[tgt_id] != 0 ? true : false);
2240        }
2241        /*
2242           Issue the Inquire Setup Information command.
2243         */
2244        req_replylen = sizeof(setupinfo);
2245        if (blogic_cmd(adapter, BLOGIC_INQ_SETUPINFO, &req_replylen,
2246                        sizeof(req_replylen), &setupinfo, sizeof(setupinfo))
2247            != sizeof(setupinfo))
2248                return blogic_failure(adapter, "INQUIRE SETUP INFORMATION");
2249        for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
2250                adapter->sync_offset[tgt_id] = (tgt_id < 8 ? setupinfo.sync0to7[tgt_id].offset : setupinfo.sync8to15[tgt_id - 8].offset);
2251        if (strcmp(adapter->fw_ver, "5.06L") >= 0)
2252                for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
2253                        adapter->tgt_flags[tgt_id].wide_active = (tgt_id < 8 ? (setupinfo.wide_tx_active0to7 & (1 << tgt_id) ? true : false) : (setupinfo.wide_tx_active8to15 & (1 << (tgt_id - 8)) ? true : false));
2254        /*
2255           Issue the Inquire Synchronous Period command.
2256         */
2257        if (adapter->fw_ver[0] >= '3') {
2258
2259                /* Issue a Inquire Synchronous Period command. For each
2260                   Target Device, a byte is returned which represents the
2261                   Synchronous Transfer Period in units of 10 nanoseconds.
2262                 */
2263
2264                req_replylen = sizeof(sync_period);
2265                if (blogic_cmd(adapter, BLOGIC_INQ_SYNC_PERIOD, &req_replylen,
2266                                sizeof(req_replylen), &sync_period,
2267                                sizeof(sync_period)) != sizeof(sync_period))
2268                        return blogic_failure(adapter,
2269                                        "INQUIRE SYNCHRONOUS PERIOD");
2270                for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
2271                        adapter->sync_period[tgt_id] = sync_period[tgt_id];
2272        } else
2273                for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
2274                        if (setupinfo.sync0to7[tgt_id].offset > 0)
2275                                adapter->sync_period[tgt_id] = 20 + 5 * setupinfo.sync0to7[tgt_id].tx_period;
2276        /*
2277           Indicate the Target Device Inquiry completed successfully.
2278         */
2279        return true;
2280}
2281
2282/*
2283  blogic_inithoststruct initializes the fields in the SCSI Host
2284  structure.  The base, io_port, n_io_ports, irq, and dma_channel fields in the
2285  SCSI Host structure are intentionally left uninitialized, as this driver
2286  handles acquisition and release of these resources explicitly, as well as
2287  ensuring exclusive access to the Host Adapter hardware and data structures
2288  through explicit acquisition and release of the Host Adapter's Lock.
2289*/
2290
2291static void __init blogic_inithoststruct(struct blogic_adapter *adapter,
2292                struct Scsi_Host *host)
2293{
2294        host->max_id = adapter->maxdev;
2295        host->max_lun = adapter->maxlun;
2296        host->max_channel = 0;
2297        host->unique_id = adapter->io_addr;
2298        host->this_id = adapter->scsi_id;
2299        host->can_queue = adapter->drvr_qdepth;
2300        host->sg_tablesize = adapter->drvr_sglimit;
2301        host->unchecked_isa_dma = adapter->need_bouncebuf;
2302        host->cmd_per_lun = adapter->untag_qdepth;
2303}
2304
2305/*
2306  blogic_slaveconfig will actually set the queue depth on individual
2307  scsi devices as they are permanently added to the device chain.  We
2308  shamelessly rip off the SelectQueueDepths code to make this work mostly
2309  like it used to.  Since we don't get called once at the end of the scan
2310  but instead get called for each device, we have to do things a bit
2311  differently.
2312*/
2313static int blogic_slaveconfig(struct scsi_device *dev)
2314{
2315        struct blogic_adapter *adapter =
2316                (struct blogic_adapter *) dev->host->hostdata;
2317        int tgt_id = dev->id;
2318        int qdepth = adapter->qdepth[tgt_id];
2319
2320        if (adapter->tgt_flags[tgt_id].tagq_ok &&
2321                        (adapter->tagq_ok & (1 << tgt_id))) {
2322                if (qdepth == 0)
2323                        qdepth = BLOGIC_MAX_AUTO_TAG_DEPTH;
2324                adapter->qdepth[tgt_id] = qdepth;
2325                scsi_change_queue_depth(dev, qdepth);
2326        } else {
2327                adapter->tagq_ok &= ~(1 << tgt_id);
2328                qdepth = adapter->untag_qdepth;
2329                adapter->qdepth[tgt_id] = qdepth;
2330                scsi_change_queue_depth(dev, qdepth);
2331        }
2332        qdepth = 0;
2333        for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
2334                if (adapter->tgt_flags[tgt_id].tgt_exists)
2335                        qdepth += adapter->qdepth[tgt_id];
2336        if (qdepth > adapter->alloc_ccbs)
2337                blogic_create_addlccbs(adapter, qdepth - adapter->alloc_ccbs,
2338                                false);
2339        return 0;
2340}
2341
2342/*
2343  blogic_init probes for BusLogic Host Adapters at the standard
2344  I/O Addresses where they may be located, initializing, registering, and
2345  reporting the configuration of each BusLogic Host Adapter it finds.  It
2346  returns the number of BusLogic Host Adapters successfully initialized and
2347  registered.
2348*/
2349
2350static int __init blogic_init(void)
2351{
2352        int adapter_count = 0, drvr_optindex = 0, probeindex;
2353        struct blogic_adapter *adapter;
2354        int ret = 0;
2355
2356#ifdef MODULE
2357        if (BusLogic)
2358                blogic_setup(BusLogic);
2359#endif
2360
2361        if (blogic_probe_options.noprobe)
2362                return -ENODEV;
2363        blogic_probeinfo_list =
2364            kcalloc(BLOGIC_MAX_ADAPTERS, sizeof(struct blogic_probeinfo),
2365                            GFP_KERNEL);
2366        if (blogic_probeinfo_list == NULL) {
2367                blogic_err("BusLogic: Unable to allocate Probe Info List\n",
2368                                NULL);
2369                return -ENOMEM;
2370        }
2371
2372        adapter = kzalloc(sizeof(struct blogic_adapter), GFP_KERNEL);
2373        if (adapter == NULL) {
2374                kfree(blogic_probeinfo_list);
2375                blogic_err("BusLogic: Unable to allocate Prototype Host Adapter\n", NULL);
2376                return -ENOMEM;
2377        }
2378
2379#ifdef MODULE
2380        if (BusLogic != NULL)
2381                blogic_setup(BusLogic);
2382#endif
2383        blogic_init_probeinfo_list(adapter);
2384        for (probeindex = 0; probeindex < blogic_probeinfo_count; probeindex++) {
2385                struct blogic_probeinfo *probeinfo =
2386                        &blogic_probeinfo_list[probeindex];
2387                struct blogic_adapter *myadapter = adapter;
2388                struct Scsi_Host *host;
2389
2390                if (probeinfo->io_addr == 0)
2391                        continue;
2392                memset(myadapter, 0, sizeof(struct blogic_adapter));
2393                myadapter->adapter_type = probeinfo->adapter_type;
2394                myadapter->adapter_bus_type = probeinfo->adapter_bus_type;
2395                myadapter->io_addr = probeinfo->io_addr;
2396                myadapter->pci_addr = probeinfo->pci_addr;
2397                myadapter->bus = probeinfo->bus;
2398                myadapter->dev = probeinfo->dev;
2399                myadapter->pci_device = probeinfo->pci_device;
2400                myadapter->irq_ch = probeinfo->irq_ch;
2401                myadapter->addr_count =
2402                        blogic_adapter_addr_count[myadapter->adapter_type];
2403
2404                /*
2405                   Make sure region is free prior to probing.
2406                 */
2407                if (!request_region(myadapter->io_addr, myadapter->addr_count,
2408                                        "BusLogic"))
2409                        continue;
2410                /*
2411                   Probe the Host Adapter. If unsuccessful, abort further
2412                   initialization.
2413                 */
2414                if (!blogic_probe(myadapter)) {
2415                        release_region(myadapter->io_addr,
2416                                        myadapter->addr_count);
2417                        continue;
2418                }
2419                /*
2420                   Hard Reset the Host Adapter.  If unsuccessful, abort further
2421                   initialization.
2422                 */
2423                if (!blogic_hwreset(myadapter, true)) {
2424                        release_region(myadapter->io_addr,
2425                                        myadapter->addr_count);
2426                        continue;
2427                }
2428                /*
2429                   Check the Host Adapter.  If unsuccessful, abort further
2430                   initialization.
2431                 */
2432                if (!blogic_checkadapter(myadapter)) {
2433                        release_region(myadapter->io_addr,
2434                                        myadapter->addr_count);
2435                        continue;
2436                }
2437                /*
2438                   Initialize the Driver Options field if provided.
2439                 */
2440                if (drvr_optindex < blogic_drvr_options_count)
2441                        myadapter->drvr_opts =
2442                                &blogic_drvr_options[drvr_optindex++];
2443                /*
2444                   Announce the Driver Version and Date, Author's Name,
2445                   Copyright Notice, and Electronic Mail Address.
2446                 */
2447                blogic_announce_drvr(myadapter);
2448                /*
2449                   Register the SCSI Host structure.
2450                 */
2451
2452                host = scsi_host_alloc(&blogic_template,
2453                                sizeof(struct blogic_adapter));
2454                if (host == NULL) {
2455                        release_region(myadapter->io_addr,
2456                                        myadapter->addr_count);
2457                        continue;
2458                }
2459                myadapter = (struct blogic_adapter *) host->hostdata;
2460                memcpy(myadapter, adapter, sizeof(struct blogic_adapter));
2461                myadapter->scsi_host = host;
2462                myadapter->host_no = host->host_no;
2463                /*
2464                   Add Host Adapter to the end of the list of registered
2465                   BusLogic Host Adapters.
2466                 */
2467                list_add_tail(&myadapter->host_list, &blogic_host_list);
2468
2469                /*
2470                   Read the Host Adapter Configuration, Configure the Host
2471                   Adapter, Acquire the System Resources necessary to use
2472                   the Host Adapter, then Create the Initial CCBs, Initialize
2473                   the Host Adapter, and finally perform Target Device
2474                   Inquiry. From this point onward, any failure will be
2475                   assumed to be due to a problem with the Host Adapter,
2476                   rather than due to having mistakenly identified this port
2477                   as belonging to a BusLogic Host Adapter. The I/O Address
2478                   range will not be released, thereby preventing it from
2479                   being incorrectly identified as any other type of Host
2480                   Adapter.
2481                 */
2482                if (blogic_rdconfig(myadapter) &&
2483                    blogic_reportconfig(myadapter) &&
2484                    blogic_getres(myadapter) &&
2485                    blogic_create_initccbs(myadapter) &&
2486                    blogic_initadapter(myadapter) &&
2487                    blogic_inquiry(myadapter)) {
2488                        /*
2489                           Initialization has been completed successfully.
2490                           Release and re-register usage of the I/O Address
2491                           range so that the Model Name of the Host Adapter
2492                           will appear, and initialize the SCSI Host structure.
2493                         */
2494                        release_region(myadapter->io_addr,
2495                                       myadapter->addr_count);
2496                        if (!request_region(myadapter->io_addr,
2497                                            myadapter->addr_count,
2498                                            myadapter->full_model)) {
2499                                printk(KERN_WARNING
2500                                        "BusLogic: Release and re-register of "
2501                                        "port 0x%04lx failed \n",
2502                                        (unsigned long)myadapter->io_addr);
2503                                blogic_destroy_ccbs(myadapter);
2504                                blogic_relres(myadapter);
2505                                list_del(&myadapter->host_list);
2506                                scsi_host_put(host);
2507                                ret = -ENOMEM;
2508                        } else {
2509                                blogic_inithoststruct(myadapter,
2510                                                                 host);
2511                                if (scsi_add_host(host, myadapter->pci_device
2512                                                ? &myadapter->pci_device->dev
2513                                                  : NULL)) {
2514                                        printk(KERN_WARNING
2515                                               "BusLogic: scsi_add_host()"
2516                                               "failed!\n");
2517                                        blogic_destroy_ccbs(myadapter);
2518                                        blogic_relres(myadapter);
2519                                        list_del(&myadapter->host_list);
2520                                        scsi_host_put(host);
2521                                        ret = -ENODEV;
2522                                } else {
2523                                        scsi_scan_host(host);
2524                                        adapter_count++;
2525                                }
2526                        }
2527                } else {
2528                        /*
2529                           An error occurred during Host Adapter Configuration
2530                           Querying, Host Adapter Configuration, Resource
2531                           Acquisition, CCB Creation, Host Adapter
2532                           Initialization, or Target Device Inquiry, so
2533                           remove Host Adapter from the list of registered
2534                           BusLogic Host Adapters, destroy the CCBs, Release
2535                           the System Resources, and Unregister the SCSI
2536                           Host.
2537                         */
2538                        blogic_destroy_ccbs(myadapter);
2539                        blogic_relres(myadapter);
2540                        list_del(&myadapter->host_list);
2541                        scsi_host_put(host);
2542                        ret = -ENODEV;
2543                }
2544        }
2545        kfree(adapter);
2546        kfree(blogic_probeinfo_list);
2547        blogic_probeinfo_list = NULL;
2548        return ret;
2549}
2550
2551
2552/*
2553  blogic_deladapter releases all resources previously acquired to
2554  support a specific Host Adapter, including the I/O Address range, and
2555  unregisters the BusLogic Host Adapter.
2556*/
2557
2558static int __exit blogic_deladapter(struct blogic_adapter *adapter)
2559{
2560        struct Scsi_Host *host = adapter->scsi_host;
2561
2562        scsi_remove_host(host);
2563
2564        /*
2565           FlashPoint Host Adapters must first be released by the FlashPoint
2566           SCCB Manager.
2567         */
2568        if (blogic_flashpoint_type(adapter))
2569                FlashPoint_ReleaseHostAdapter(adapter->cardhandle);
2570        /*
2571           Destroy the CCBs and release any system resources acquired to
2572           support Host Adapter.
2573         */
2574        blogic_destroy_ccbs(adapter);
2575        blogic_relres(adapter);
2576        /*
2577           Release usage of the I/O Address range.
2578         */
2579        release_region(adapter->io_addr, adapter->addr_count);
2580        /*
2581           Remove Host Adapter from the list of registered BusLogic
2582           Host Adapters.
2583         */
2584        list_del(&adapter->host_list);
2585
2586        scsi_host_put(host);
2587        return 0;
2588}
2589
2590
2591/*
2592  blogic_qcompleted_ccb queues CCB for completion processing.
2593*/
2594
2595static void blogic_qcompleted_ccb(struct blogic_ccb *ccb)
2596{
2597        struct blogic_adapter *adapter = ccb->adapter;
2598
2599        ccb->status = BLOGIC_CCB_COMPLETE;
2600        ccb->next = NULL;
2601        if (adapter->firstccb == NULL) {
2602                adapter->firstccb = ccb;
2603                adapter->lastccb = ccb;
2604        } else {
2605                adapter->lastccb->next = ccb;
2606                adapter->lastccb = ccb;
2607        }
2608        adapter->active_cmds[ccb->tgt_id]--;
2609}
2610
2611
2612/*
2613  blogic_resultcode computes a SCSI Subsystem Result Code from
2614  the Host Adapter Status and Target Device Status.
2615*/
2616
2617static int blogic_resultcode(struct blogic_adapter *adapter,
2618                enum blogic_adapter_status adapter_status,
2619                enum blogic_tgt_status tgt_status)
2620{
2621        int hoststatus;
2622
2623        switch (adapter_status) {
2624        case BLOGIC_CMD_CMPLT_NORMAL:
2625        case BLOGIC_LINK_CMD_CMPLT:
2626        case BLOGIC_LINK_CMD_CMPLT_FLAG:
2627                hoststatus = DID_OK;
2628                break;
2629        case BLOGIC_SELECT_TIMEOUT:
2630                hoststatus = DID_TIME_OUT;
2631                break;
2632        case BLOGIC_INVALID_OUTBOX_CODE:
2633        case BLOGIC_INVALID_CMD_CODE:
2634        case BLOGIC_BAD_CMD_PARAM:
2635                blogic_warn("BusLogic Driver Protocol Error 0x%02X\n",
2636                                adapter, adapter_status);
2637                /* fall through */
2638        case BLOGIC_DATA_UNDERRUN:
2639        case BLOGIC_DATA_OVERRUN:
2640        case BLOGIC_NOEXPECT_BUSFREE:
2641        case BLOGIC_LINKCCB_BADLUN:
2642        case BLOGIC_AUTOREQSENSE_FAIL:
2643        case BLOGIC_TAGQUEUE_REJECT:
2644        case BLOGIC_BAD_MSG_RCVD:
2645        case BLOGIC_HW_FAIL:
2646        case BLOGIC_BAD_RECONNECT:
2647        case BLOGIC_ABRT_QUEUE:
2648        case BLOGIC_ADAPTER_SW_ERROR:
2649        case BLOGIC_HW_TIMEOUT:
2650        case BLOGIC_PARITY_ERR:
2651                hoststatus = DID_ERROR;
2652                break;
2653        case BLOGIC_INVALID_BUSPHASE:
2654        case BLOGIC_NORESPONSE_TO_ATN:
2655        case BLOGIC_HW_RESET:
2656        case BLOGIC_RST_FROM_OTHERDEV:
2657        case BLOGIC_HW_BDR:
2658                hoststatus = DID_RESET;
2659                break;
2660        default:
2661                blogic_warn("Unknown Host Adapter Status 0x%02X\n", adapter,
2662                                adapter_status);
2663                hoststatus = DID_ERROR;
2664                break;
2665        }
2666        return (hoststatus << 16) | tgt_status;
2667}
2668
2669
2670/*
2671  blogic_scan_inbox scans the Incoming Mailboxes saving any
2672  Incoming Mailbox entries for completion processing.
2673*/
2674
2675static void blogic_scan_inbox(struct blogic_adapter *adapter)
2676{
2677        /*
2678           Scan through the Incoming Mailboxes in Strict Round Robin
2679           fashion, saving any completed CCBs for further processing. It
2680           is essential that for each CCB and SCSI Command issued, command
2681           completion processing is performed exactly once.  Therefore,
2682           only Incoming Mailboxes with completion code Command Completed
2683           Without Error, Command Completed With Error, or Command Aborted
2684           At Host Request are saved for completion processing. When an
2685           Incoming Mailbox has a completion code of Aborted Command Not
2686           Found, the CCB had already completed or been aborted before the
2687           current Abort request was processed, and so completion processing
2688           has already occurred and no further action should be taken.
2689         */
2690        struct blogic_inbox *next_inbox = adapter->next_inbox;
2691        enum blogic_cmplt_code comp_code;
2692
2693        while ((comp_code = next_inbox->comp_code) != BLOGIC_INBOX_FREE) {
2694                /*
2695                   We are only allowed to do this because we limit our
2696                   architectures we run on to machines where bus_to_virt(
2697                   actually works.  There *needs* to be a dma_addr_to_virt()
2698                   in the new PCI DMA mapping interface to replace
2699                   bus_to_virt() or else this code is going to become very
2700                   innefficient.
2701                 */
2702                struct blogic_ccb *ccb =
2703                        (struct blogic_ccb *) bus_to_virt(next_inbox->ccb);
2704                if (comp_code != BLOGIC_CMD_NOTFOUND) {
2705                        if (ccb->status == BLOGIC_CCB_ACTIVE ||
2706                                        ccb->status == BLOGIC_CCB_RESET) {
2707                                /*
2708                                   Save the Completion Code for this CCB and
2709                                   queue the CCB for completion processing.
2710                                 */
2711                                ccb->comp_code = comp_code;
2712                                blogic_qcompleted_ccb(ccb);
2713                        } else {
2714                                /*
2715                                   If a CCB ever appears in an Incoming Mailbox
2716                                   and is not marked as status Active or Reset,
2717                                   then there is most likely a bug in
2718                                   the Host Adapter firmware.
2719                                 */
2720                                blogic_warn("Illegal CCB #%ld status %d in " "Incoming Mailbox\n", adapter, ccb->serial, ccb->status);
2721                        }
2722                }
2723                next_inbox->comp_code = BLOGIC_INBOX_FREE;
2724                if (++next_inbox > adapter->last_inbox)
2725                        next_inbox = adapter->first_inbox;
2726        }
2727        adapter->next_inbox = next_inbox;
2728}
2729
2730
2731/*
2732  blogic_process_ccbs iterates over the completed CCBs for Host
2733  Adapter setting the SCSI Command Result Codes, deallocating the CCBs, and
2734  calling the SCSI Subsystem Completion Routines.  The Host Adapter's Lock
2735  should already have been acquired by the caller.
2736*/
2737
2738static void blogic_process_ccbs(struct blogic_adapter *adapter)
2739{
2740        if (adapter->processing_ccbs)
2741                return;
2742        adapter->processing_ccbs = true;
2743        while (adapter->firstccb != NULL) {
2744                struct blogic_ccb *ccb = adapter->firstccb;
2745                struct scsi_cmnd *command = ccb->command;
2746                adapter->firstccb = ccb->next;
2747                if (adapter->firstccb == NULL)
2748                        adapter->lastccb = NULL;
2749                /*
2750                   Process the Completed CCB.
2751                 */
2752                if (ccb->opcode == BLOGIC_BDR) {
2753                        int tgt_id = ccb->tgt_id;
2754
2755                        blogic_warn("Bus Device Reset CCB #%ld to Target " "%d Completed\n", adapter, ccb->serial, tgt_id);
2756                        blogic_inc_count(&adapter->tgt_stats[tgt_id].bdr_done);
2757                        adapter->tgt_flags[tgt_id].tagq_active = false;
2758                        adapter->cmds_since_rst[tgt_id] = 0;
2759                        adapter->last_resetdone[tgt_id] = jiffies;
2760                        /*
2761                           Place CCB back on the Host Adapter's free list.
2762                         */
2763                        blogic_dealloc_ccb(ccb, 1);
2764#if 0                   /* this needs to be redone different for new EH */
2765                        /*
2766                           Bus Device Reset CCBs have the command field
2767                           non-NULL only when a Bus Device Reset was requested
2768                           for a command that did not have a currently active
2769                           CCB in the Host Adapter (i.e., a Synchronous Bus
2770                           Device Reset), and hence would not have its
2771                           Completion Routine called otherwise.
2772                         */
2773                        while (command != NULL) {
2774                                struct scsi_cmnd *nxt_cmd =
2775                                        command->reset_chain;
2776                                command->reset_chain = NULL;
2777                                command->result = DID_RESET << 16;
2778                                command->scsi_done(command);
2779                                command = nxt_cmd;
2780                        }
2781#endif
2782                        /*
2783                           Iterate over the CCBs for this Host Adapter
2784                           performing completion processing for any CCBs
2785                           marked as Reset for this Target.
2786                         */
2787                        for (ccb = adapter->all_ccbs; ccb != NULL;
2788                                        ccb = ccb->next_all)
2789                                if (ccb->status == BLOGIC_CCB_RESET &&
2790                                                ccb->tgt_id == tgt_id) {
2791                                        command = ccb->command;
2792                                        blogic_dealloc_ccb(ccb, 1);
2793                                        adapter->active_cmds[tgt_id]--;
2794                                        command->result = DID_RESET << 16;
2795                                        command->scsi_done(command);
2796                                }
2797                        adapter->bdr_pend[tgt_id] = NULL;
2798                } else {
2799                        /*
2800                           Translate the Completion Code, Host Adapter Status,
2801                           and Target Device Status into a SCSI Subsystem
2802                           Result Code.
2803                         */
2804                        switch (ccb->comp_code) {
2805                        case BLOGIC_INBOX_FREE:
2806                        case BLOGIC_CMD_NOTFOUND:
2807                        case BLOGIC_INVALID_CCB:
2808                                blogic_warn("CCB #%ld to Target %d Impossible State\n", adapter, ccb->serial, ccb->tgt_id);
2809                                break;
2810                        case BLOGIC_CMD_COMPLETE_GOOD:
2811                                adapter->tgt_stats[ccb->tgt_id]
2812                                    .cmds_complete++;
2813                                adapter->tgt_flags[ccb->tgt_id]
2814                                    .cmd_good = true;
2815                                command->result = DID_OK << 16;
2816                                break;
2817                        case BLOGIC_CMD_ABORT_BY_HOST:
2818                                blogic_warn("CCB #%ld to Target %d Aborted\n",
2819                                        adapter, ccb->serial, ccb->tgt_id);
2820                                blogic_inc_count(&adapter->tgt_stats[ccb->tgt_id].aborts_done);
2821                                command->result = DID_ABORT << 16;
2822                                break;
2823                        case BLOGIC_CMD_COMPLETE_ERROR:
2824                                command->result = blogic_resultcode(adapter,
2825                                        ccb->adapter_status, ccb->tgt_status);
2826                                if (ccb->adapter_status != BLOGIC_SELECT_TIMEOUT) {
2827                                        adapter->tgt_stats[ccb->tgt_id]
2828                                            .cmds_complete++;
2829                                        if (blogic_global_options.trace_err) {
2830                                                int i;
2831                                                blogic_notice("CCB #%ld Target %d: Result %X Host "
2832                                                                "Adapter Status %02X " "Target Status %02X\n", adapter, ccb->serial, ccb->tgt_id, command->result, ccb->adapter_status, ccb->tgt_status);
2833                                                blogic_notice("CDB   ", adapter);
2834                                                for (i = 0; i < ccb->cdblen; i++)
2835                                                        blogic_notice(" %02X", adapter, ccb->cdb[i]);
2836                                                blogic_notice("\n", adapter);
2837                                                blogic_notice("Sense ", adapter);
2838                                                for (i = 0; i < ccb->sense_datalen; i++)
2839                                                        blogic_notice(" %02X", adapter, command->sense_buffer[i]);
2840                                                blogic_notice("\n", adapter);
2841                                        }
2842                                }
2843                                break;
2844                        }
2845                        /*
2846                           When an INQUIRY command completes normally, save the
2847                           CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit
2848                           Wide Data Transfers Supported) bits.
2849                         */
2850                        if (ccb->cdb[0] == INQUIRY && ccb->cdb[1] == 0 &&
2851                                ccb->adapter_status == BLOGIC_CMD_CMPLT_NORMAL) {
2852                                struct blogic_tgt_flags *tgt_flags =
2853                                        &adapter->tgt_flags[ccb->tgt_id];
2854                                struct scsi_inquiry *inquiry =
2855                                        (struct scsi_inquiry *) scsi_sglist(command);
2856                                tgt_flags->tgt_exists = true;
2857                                tgt_flags->tagq_ok = inquiry->CmdQue;
2858                                tgt_flags->wide_ok = inquiry->WBus16;
2859                        }
2860                        /*
2861                           Place CCB back on the Host Adapter's free list.
2862                         */
2863                        blogic_dealloc_ccb(ccb, 1);
2864                        /*
2865                           Call the SCSI Command Completion Routine.
2866                         */
2867                        command->scsi_done(command);
2868                }
2869        }
2870        adapter->processing_ccbs = false;
2871}
2872
2873
2874/*
2875  blogic_inthandler handles hardware interrupts from BusLogic Host
2876  Adapters.
2877*/
2878
2879static irqreturn_t blogic_inthandler(int irq_ch, void *devid)
2880{
2881        struct blogic_adapter *adapter = (struct blogic_adapter *) devid;
2882        unsigned long processor_flag;
2883        /*
2884           Acquire exclusive access to Host Adapter.
2885         */
2886        spin_lock_irqsave(adapter->scsi_host->host_lock, processor_flag);
2887        /*
2888           Handle Interrupts appropriately for each Host Adapter type.
2889         */
2890        if (blogic_multimaster_type(adapter)) {
2891                union blogic_int_reg intreg;
2892                /*
2893                   Read the Host Adapter Interrupt Register.
2894                 */
2895                intreg.all = blogic_rdint(adapter);
2896                if (intreg.ir.int_valid) {
2897                        /*
2898                           Acknowledge the interrupt and reset the Host Adapter
2899                           Interrupt Register.
2900                         */
2901                        blogic_intreset(adapter);
2902                        /*
2903                           Process valid External SCSI Bus Reset and Incoming
2904                           Mailbox Loaded Interrupts. Command Complete
2905                           Interrupts are noted, and Outgoing Mailbox Available
2906                           Interrupts are ignored, as they are never enabled.
2907                         */
2908                        if (intreg.ir.ext_busreset)
2909                                adapter->adapter_extreset = true;
2910                        else if (intreg.ir.mailin_loaded)
2911                                blogic_scan_inbox(adapter);
2912                        else if (intreg.ir.cmd_complete)
2913                                adapter->adapter_cmd_complete = true;
2914                }
2915        } else {
2916                /*
2917                   Check if there is a pending interrupt for this Host Adapter.
2918                 */
2919                if (FlashPoint_InterruptPending(adapter->cardhandle))
2920                        switch (FlashPoint_HandleInterrupt(adapter->cardhandle)) {
2921                        case FPOINT_NORMAL_INT:
2922                                break;
2923                        case FPOINT_EXT_RESET:
2924                                adapter->adapter_extreset = true;
2925                                break;
2926                        case FPOINT_INTERN_ERR:
2927                                blogic_warn("Internal FlashPoint Error detected - Resetting Host Adapter\n", adapter);
2928                                adapter->adapter_intern_err = true;
2929                                break;
2930                        }
2931        }
2932        /*
2933           Process any completed CCBs.
2934         */
2935        if (adapter->firstccb != NULL)
2936                blogic_process_ccbs(adapter);
2937        /*
2938           Reset the Host Adapter if requested.
2939         */
2940        if (adapter->adapter_extreset) {
2941                blogic_warn("Resetting %s due to External SCSI Bus Reset\n", adapter, adapter->full_model);
2942                blogic_inc_count(&adapter->ext_resets);
2943                blogic_resetadapter(adapter, false);
2944                adapter->adapter_extreset = false;
2945        } else if (adapter->adapter_intern_err) {
2946                blogic_warn("Resetting %s due to Host Adapter Internal Error\n", adapter, adapter->full_model);
2947                blogic_inc_count(&adapter->adapter_intern_errors);
2948                blogic_resetadapter(adapter, true);
2949                adapter->adapter_intern_err = false;
2950        }
2951        /*
2952           Release exclusive access to Host Adapter.
2953         */
2954        spin_unlock_irqrestore(adapter->scsi_host->host_lock, processor_flag);
2955        return IRQ_HANDLED;
2956}
2957
2958
2959/*
2960  blogic_write_outbox places CCB and Action Code into an Outgoing
2961  Mailbox for execution by Host Adapter.  The Host Adapter's Lock should
2962  already have been acquired by the caller.
2963*/
2964
2965static bool blogic_write_outbox(struct blogic_adapter *adapter,
2966                enum blogic_action action, struct blogic_ccb *ccb)
2967{
2968        struct blogic_outbox *next_outbox;
2969
2970        next_outbox = adapter->next_outbox;
2971        if (next_outbox->action == BLOGIC_OUTBOX_FREE) {
2972                ccb->status = BLOGIC_CCB_ACTIVE;
2973                /*
2974                   The CCB field must be written before the Action Code field
2975                   since the Host Adapter is operating asynchronously and the
2976                   locking code does not protect against simultaneous access
2977                   by the Host Adapter.
2978                 */
2979                next_outbox->ccb = ccb->dma_handle;
2980                next_outbox->action = action;
2981                blogic_execmbox(adapter);
2982                if (++next_outbox > adapter->last_outbox)
2983                        next_outbox = adapter->first_outbox;
2984                adapter->next_outbox = next_outbox;
2985                if (action == BLOGIC_MBOX_START) {
2986                        adapter->active_cmds[ccb->tgt_id]++;
2987                        if (ccb->opcode != BLOGIC_BDR)
2988                                adapter->tgt_stats[ccb->tgt_id].cmds_tried++;
2989                }
2990                return true;
2991        }
2992        return false;
2993}
2994
2995/* Error Handling (EH) support */
2996
2997static int blogic_hostreset(struct scsi_cmnd *SCpnt)
2998{
2999        struct blogic_adapter *adapter =
3000                (struct blogic_adapter *) SCpnt->device->host->hostdata;
3001
3002        unsigned int id = SCpnt->device->id;
3003        struct blogic_tgt_stats *stats = &adapter->tgt_stats[id];
3004        int rc;
3005
3006        spin_lock_irq(SCpnt->device->host->host_lock);
3007
3008        blogic_inc_count(&stats->adapter_reset_req);
3009
3010        rc = blogic_resetadapter(adapter, false);
3011        spin_unlock_irq(SCpnt->device->host->host_lock);
3012        return rc;
3013}
3014
3015/*
3016  blogic_qcmd creates a CCB for Command and places it into an
3017  Outgoing Mailbox for execution by the associated Host Adapter.
3018*/
3019
3020static int blogic_qcmd_lck(struct scsi_cmnd *command,
3021                void (*comp_cb) (struct scsi_cmnd *))
3022{
3023        struct blogic_adapter *adapter =
3024                (struct blogic_adapter *) command->device->host->hostdata;
3025        struct blogic_tgt_flags *tgt_flags =
3026                &adapter->tgt_flags[command->device->id];
3027        struct blogic_tgt_stats *tgt_stats = adapter->tgt_stats;
3028        unsigned char *cdb = command->cmnd;
3029        int cdblen = command->cmd_len;
3030        int tgt_id = command->device->id;
3031        int lun = command->device->lun;
3032        int buflen = scsi_bufflen(command);
3033        int count;
3034        struct blogic_ccb *ccb;
3035        dma_addr_t sense_buf;
3036
3037        /*
3038           SCSI REQUEST_SENSE commands will be executed automatically by the
3039           Host Adapter for any errors, so they should not be executed
3040           explicitly unless the Sense Data is zero indicating that no error
3041           occurred.
3042         */
3043        if (cdb[0] == REQUEST_SENSE && command->sense_buffer[0] != 0) {
3044                command->result = DID_OK << 16;
3045                comp_cb(command);
3046                return 0;
3047        }
3048        /*
3049           Allocate a CCB from the Host Adapter's free list. In the unlikely
3050           event that there are none available and memory allocation fails,
3051           wait 1 second and try again. If that fails, the Host Adapter is
3052           probably hung so signal an error as a Host Adapter Hard Reset
3053           should be initiated soon.
3054         */
3055        ccb = blogic_alloc_ccb(adapter);
3056        if (ccb == NULL) {
3057                spin_unlock_irq(adapter->scsi_host->host_lock);
3058                blogic_delay(1);
3059                spin_lock_irq(adapter->scsi_host->host_lock);
3060                ccb = blogic_alloc_ccb(adapter);
3061                if (ccb == NULL) {
3062                        command->result = DID_ERROR << 16;
3063                        comp_cb(command);
3064                        return 0;
3065                }
3066        }
3067
3068        /*
3069           Initialize the fields in the BusLogic Command Control Block (CCB).
3070         */
3071        count = scsi_dma_map(command);
3072        BUG_ON(count < 0);
3073        if (count) {
3074                struct scatterlist *sg;
3075                int i;
3076
3077                ccb->opcode = BLOGIC_INITIATOR_CCB_SG;
3078                ccb->datalen = count * sizeof(struct blogic_sg_seg);
3079                if (blogic_multimaster_type(adapter))
3080                        ccb->data = (void *)((unsigned int) ccb->dma_handle +
3081                                        ((unsigned long) &ccb->sglist -
3082                                        (unsigned long) ccb));
3083                else
3084                        ccb->data = ccb->sglist;
3085
3086                scsi_for_each_sg(command, sg, count, i) {
3087                        ccb->sglist[i].segbytes = sg_dma_len(sg);
3088                        ccb->sglist[i].segdata = sg_dma_address(sg);
3089                }
3090        } else if (!count) {
3091                ccb->opcode = BLOGIC_INITIATOR_CCB;
3092                ccb->datalen = buflen;
3093                ccb->data = 0;
3094        }
3095
3096        switch (cdb[0]) {
3097        case READ_6:
3098        case READ_10:
3099                ccb->datadir = BLOGIC_DATAIN_CHECKED;
3100                tgt_stats[tgt_id].read_cmds++;
3101                blogic_addcount(&tgt_stats[tgt_id].bytesread, buflen);
3102                blogic_incszbucket(tgt_stats[tgt_id].read_sz_buckets, buflen);
3103                break;
3104        case WRITE_6:
3105        case WRITE_10:
3106                ccb->datadir = BLOGIC_DATAOUT_CHECKED;
3107                tgt_stats[tgt_id].write_cmds++;
3108                blogic_addcount(&tgt_stats[tgt_id].byteswritten, buflen);
3109                blogic_incszbucket(tgt_stats[tgt_id].write_sz_buckets, buflen);
3110                break;
3111        default:
3112                ccb->datadir = BLOGIC_UNCHECKED_TX;
3113                break;
3114        }
3115        ccb->cdblen = cdblen;
3116        ccb->adapter_status = 0;
3117        ccb->tgt_status = 0;
3118        ccb->tgt_id = tgt_id;
3119        ccb->lun = lun;
3120        ccb->tag_enable = false;
3121        ccb->legacytag_enable = false;
3122        /*
3123           BusLogic recommends that after a Reset the first couple of
3124           commands that are sent to a Target Device be sent in a non
3125           Tagged Queue fashion so that the Host Adapter and Target Device
3126           can establish Synchronous and Wide Transfer before Queue Tag
3127           messages can interfere with the Synchronous and Wide Negotiation
3128           messages.  By waiting to enable Tagged Queuing until after the
3129           first BLOGIC_MAX_TAG_DEPTH commands have been queued, it is
3130           assured that after a Reset any pending commands are requeued
3131           before Tagged Queuing is enabled and that the Tagged Queuing
3132           message will not occur while the partition table is being printed.
3133           In addition, some devices do not properly handle the transition
3134           from non-tagged to tagged commands, so it is necessary to wait
3135           until there are no pending commands for a target device
3136           before queuing tagged commands.
3137         */
3138        if (adapter->cmds_since_rst[tgt_id]++ >= BLOGIC_MAX_TAG_DEPTH &&
3139                        !tgt_flags->tagq_active &&
3140                        adapter->active_cmds[tgt_id] == 0
3141                        && tgt_flags->tagq_ok &&
3142                        (adapter->tagq_ok & (1 << tgt_id))) {
3143                tgt_flags->tagq_active = true;
3144                blogic_notice("Tagged Queuing now active for Target %d\n",
3145                                        adapter, tgt_id);
3146        }
3147        if (tgt_flags->tagq_active) {
3148                enum blogic_queuetag queuetag = BLOGIC_SIMPLETAG;
3149                /*
3150                   When using Tagged Queuing with Simple Queue Tags, it
3151                   appears that disk drive controllers do not guarantee that
3152                   a queued command will not remain in a disconnected state
3153                   indefinitely if commands that read or write nearer the
3154                   head position continue to arrive without interruption.
3155                   Therefore, for each Target Device this driver keeps track
3156                   of the last time either the queue was empty or an Ordered
3157                   Queue Tag was issued. If more than 4 seconds (one fifth
3158                   of the 20 second disk timeout) have elapsed since this
3159                   last sequence point, this command will be issued with an
3160                   Ordered Queue Tag rather than a Simple Queue Tag, which
3161                   forces the Target Device to complete all previously
3162                   queued commands before this command may be executed.
3163                 */
3164                if (adapter->active_cmds[tgt_id] == 0)
3165                        adapter->last_seqpoint[tgt_id] = jiffies;
3166                else if (time_after(jiffies,
3167                                adapter->last_seqpoint[tgt_id] + 4 * HZ)) {
3168                        adapter->last_seqpoint[tgt_id] = jiffies;
3169                        queuetag = BLOGIC_ORDEREDTAG;
3170                }
3171                if (adapter->ext_lun) {
3172                        ccb->tag_enable = true;
3173                        ccb->queuetag = queuetag;
3174                } else {
3175                        ccb->legacytag_enable = true;
3176                        ccb->legacy_tag = queuetag;
3177                }
3178        }
3179        memcpy(ccb->cdb, cdb, cdblen);
3180        ccb->sense_datalen = SCSI_SENSE_BUFFERSIZE;
3181        ccb->command = command;
3182        sense_buf = dma_map_single(&adapter->pci_device->dev,
3183                                command->sense_buffer, ccb->sense_datalen,
3184                                DMA_FROM_DEVICE);
3185        if (dma_mapping_error(&adapter->pci_device->dev, sense_buf)) {
3186                blogic_err("DMA mapping for sense data buffer failed\n",
3187                                adapter);
3188                blogic_dealloc_ccb(ccb, 0);
3189                return SCSI_MLQUEUE_HOST_BUSY;
3190        }
3191        ccb->sensedata = sense_buf;
3192        command->scsi_done = comp_cb;
3193        if (blogic_multimaster_type(adapter)) {
3194                /*
3195                   Place the CCB in an Outgoing Mailbox. The higher levels
3196                   of the SCSI Subsystem should not attempt to queue more
3197                   commands than can be placed in Outgoing Mailboxes, so
3198                   there should always be one free.  In the unlikely event
3199                   that there are none available, wait 1 second and try
3200                   again. If that fails, the Host Adapter is probably hung
3201                   so signal an error as a Host Adapter Hard Reset should
3202                   be initiated soon.
3203                 */
3204                if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START, ccb)) {
3205                        spin_unlock_irq(adapter->scsi_host->host_lock);
3206                        blogic_warn("Unable to write Outgoing Mailbox - " "Pausing for 1 second\n", adapter);
3207                        blogic_delay(1);
3208                        spin_lock_irq(adapter->scsi_host->host_lock);
3209                        if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START,
3210                                                ccb)) {
3211                                blogic_warn("Still unable to write Outgoing Mailbox - " "Host Adapter Dead?\n", adapter);
3212                                blogic_dealloc_ccb(ccb, 1);
3213                                command->result = DID_ERROR << 16;
3214                                command->scsi_done(command);
3215                        }
3216                }
3217        } else {
3218                /*
3219                   Call the FlashPoint SCCB Manager to start execution of
3220                   the CCB.
3221                 */
3222                ccb->status = BLOGIC_CCB_ACTIVE;
3223                adapter->active_cmds[tgt_id]++;
3224                tgt_stats[tgt_id].cmds_tried++;
3225                FlashPoint_StartCCB(adapter->cardhandle, ccb);
3226                /*
3227                   The Command may have already completed and
3228                   blogic_qcompleted_ccb been called, or it may still be
3229                   pending.
3230                 */
3231                if (ccb->status == BLOGIC_CCB_COMPLETE)
3232                        blogic_process_ccbs(adapter);
3233        }
3234        return 0;
3235}
3236
3237static DEF_SCSI_QCMD(blogic_qcmd)
3238
3239#if 0
3240/*
3241  blogic_abort aborts Command if possible.
3242*/
3243
3244static int blogic_abort(struct scsi_cmnd *command)
3245{
3246        struct blogic_adapter *adapter =
3247                (struct blogic_adapter *) command->device->host->hostdata;
3248
3249        int tgt_id = command->device->id;
3250        struct blogic_ccb *ccb;
3251        blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_request);
3252
3253        /*
3254           Attempt to find an Active CCB for this Command. If no Active
3255           CCB for this Command is found, then no Abort is necessary.
3256         */
3257        for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all)
3258                if (ccb->command == command)
3259                        break;
3260        if (ccb == NULL) {
3261                blogic_warn("Unable to Abort Command to Target %d - No CCB Found\n", adapter, tgt_id);
3262                return SUCCESS;
3263        } else if (ccb->status == BLOGIC_CCB_COMPLETE) {
3264                blogic_warn("Unable to Abort Command to Target %d - CCB Completed\n", adapter, tgt_id);
3265                return SUCCESS;
3266        } else if (ccb->status == BLOGIC_CCB_RESET) {
3267                blogic_warn("Unable to Abort Command to Target %d - CCB Reset\n", adapter, tgt_id);
3268                return SUCCESS;
3269        }
3270        if (blogic_multimaster_type(adapter)) {
3271                /*
3272                   Attempt to Abort this CCB.  MultiMaster Firmware versions
3273                   prior to 5.xx do not generate Abort Tag messages, but only
3274                   generate the non-tagged Abort message.  Since non-tagged
3275                   commands are not sent by the Host Adapter until the queue
3276                   of outstanding tagged commands has completed, and the
3277                   Abort message is treated as a non-tagged command, it is
3278                   effectively impossible to abort commands when Tagged
3279                   Queuing is active. Firmware version 5.xx does generate
3280                   Abort Tag messages, so it is possible to abort commands
3281                   when Tagged Queuing is active.
3282                 */
3283                if (adapter->tgt_flags[tgt_id].tagq_active &&
3284                                adapter->fw_ver[0] < '5') {
3285                        blogic_warn("Unable to Abort CCB #%ld to Target %d - Abort Tag Not Supported\n", adapter, ccb->serial, tgt_id);
3286                        return FAILURE;
3287                } else if (blogic_write_outbox(adapter, BLOGIC_MBOX_ABORT,
3288                                        ccb)) {
3289                        blogic_warn("Aborting CCB #%ld to Target %d\n",
3290                                        adapter, ccb->serial, tgt_id);
3291                        blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_tried);
3292                        return SUCCESS;
3293                } else {
3294                        blogic_warn("Unable to Abort CCB #%ld to Target %d - No Outgoing Mailboxes\n", adapter, ccb->serial, tgt_id);
3295                        return FAILURE;
3296                }
3297        } else {
3298                /*
3299                   Call the FlashPoint SCCB Manager to abort execution of
3300                   the CCB.
3301                 */
3302                blogic_warn("Aborting CCB #%ld to Target %d\n", adapter,
3303                                ccb->serial, tgt_id);
3304                blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_tried);
3305                FlashPoint_AbortCCB(adapter->cardhandle, ccb);
3306                /*
3307                   The Abort may have already been completed and
3308                   blogic_qcompleted_ccb been called, or it
3309                   may still be pending.
3310                 */
3311                if (ccb->status == BLOGIC_CCB_COMPLETE)
3312                        blogic_process_ccbs(adapter);
3313                return SUCCESS;
3314        }
3315        return SUCCESS;
3316}
3317
3318#endif
3319/*
3320  blogic_resetadapter resets Host Adapter if possible, marking all
3321  currently executing SCSI Commands as having been Reset.
3322*/
3323
3324static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset)
3325{
3326        struct blogic_ccb *ccb;
3327        int tgt_id;
3328
3329        /*
3330         * Attempt to Reset and Reinitialize the Host Adapter.
3331         */
3332
3333        if (!(blogic_hwreset(adapter, hard_reset) &&
3334                                blogic_initadapter(adapter))) {
3335                blogic_err("Resetting %s Failed\n", adapter,
3336                                                adapter->full_model);
3337                return FAILURE;
3338        }
3339
3340        /*
3341         * Deallocate all currently executing CCBs.
3342         */
3343
3344        for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all)
3345                if (ccb->status == BLOGIC_CCB_ACTIVE)
3346                        blogic_dealloc_ccb(ccb, 1);
3347        /*
3348         * Wait a few seconds between the Host Adapter Hard Reset which
3349         * initiates a SCSI Bus Reset and issuing any SCSI Commands.  Some
3350         * SCSI devices get confused if they receive SCSI Commands too soon
3351         * after a SCSI Bus Reset.
3352         */
3353
3354        if (hard_reset) {
3355                spin_unlock_irq(adapter->scsi_host->host_lock);
3356                blogic_delay(adapter->bus_settle_time);
3357                spin_lock_irq(adapter->scsi_host->host_lock);
3358        }
3359
3360        for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) {
3361                adapter->last_resettried[tgt_id] = jiffies;
3362                adapter->last_resetdone[tgt_id] = jiffies;
3363        }
3364        return SUCCESS;
3365}
3366
3367/*
3368  blogic_diskparam returns the Heads/Sectors/Cylinders BIOS Disk
3369  Parameters for Disk.  The default disk geometry is 64 heads, 32 sectors, and
3370  the appropriate number of cylinders so as not to exceed drive capacity.  In
3371  order for disks equal to or larger than 1 GB to be addressable by the BIOS
3372  without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
3373  may be enabled in AutoSCSI on FlashPoint Host Adapters and on "W" and "C"
3374  series MultiMaster Host Adapters, or by a dip switch setting on "S" and "A"
3375  series MultiMaster Host Adapters.  With Extended Translation enabled, drives
3376  between 1 GB inclusive and 2 GB exclusive are given a disk geometry of 128
3377  heads and 32 sectors, and drives above 2 GB inclusive are given a disk
3378  geometry of 255 heads and 63 sectors.  However, if the BIOS detects that the
3379  Extended Translation setting does not match the geometry in the partition
3380  table, then the translation inferred from the partition table will be used by
3381  the BIOS, and a warning may be displayed.
3382*/
3383
3384static int blogic_diskparam(struct scsi_device *sdev, struct block_device *dev,
3385                sector_t capacity, int *params)
3386{
3387        struct blogic_adapter *adapter =
3388                                (struct blogic_adapter *) sdev->host->hostdata;
3389        struct bios_diskparam *diskparam = (struct bios_diskparam *) params;
3390        unsigned char *buf;
3391
3392        if (adapter->ext_trans_enable && capacity >= 2 * 1024 * 1024 /* 1 GB in 512 byte sectors */) {
3393                if (capacity >= 4 * 1024 * 1024 /* 2 GB in 512 byte sectors */) {
3394                        diskparam->heads = 255;
3395                        diskparam->sectors = 63;
3396                } else {
3397                        diskparam->heads = 128;
3398                        diskparam->sectors = 32;
3399                }
3400        } else {
3401                diskparam->heads = 64;
3402                diskparam->sectors = 32;
3403        }
3404        diskparam->cylinders = (unsigned long) capacity / (diskparam->heads * diskparam->sectors);
3405        buf = scsi_bios_ptable(dev);
3406        if (buf == NULL)
3407                return 0;
3408        /*
3409           If the boot sector partition table flag is valid, search for
3410           a partition table entry whose end_head matches one of the
3411           standard BusLogic geometry translations (64/32, 128/32, or 255/63).
3412         */
3413        if (*(unsigned short *) (buf + 64) == 0xAA55) {
3414                struct partition *part1_entry = (struct partition *) buf;
3415                struct partition *part_entry = part1_entry;
3416                int saved_cyl = diskparam->cylinders, part_no;
3417                unsigned char part_end_head = 0, part_end_sector = 0;
3418
3419                for (part_no = 0; part_no < 4; part_no++) {
3420                        part_end_head = part_entry->end_head;
3421                        part_end_sector = part_entry->end_sector & 0x3F;
3422                        if (part_end_head == 64 - 1) {
3423                                diskparam->heads = 64;
3424                                diskparam->sectors = 32;
3425                                break;
3426                        } else if (part_end_head == 128 - 1) {
3427                                diskparam->heads = 128;
3428                                diskparam->sectors = 32;
3429                                break;
3430                        } else if (part_end_head == 255 - 1) {
3431                                diskparam->heads = 255;
3432                                diskparam->sectors = 63;
3433                                break;
3434                        }
3435                        part_entry++;
3436                }
3437                if (part_no == 4) {
3438                        part_end_head = part1_entry->end_head;
3439                        part_end_sector = part1_entry->end_sector & 0x3F;
3440                }
3441                diskparam->cylinders = (unsigned long) capacity / (diskparam->heads * diskparam->sectors);
3442                if (part_no < 4 && part_end_sector == diskparam->sectors) {
3443                        if (diskparam->cylinders != saved_cyl)
3444                                blogic_warn("Adopting Geometry %d/%d from Partition Table\n", adapter, diskparam->heads, diskparam->sectors);
3445                } else if (part_end_head > 0 || part_end_sector > 0) {
3446                        blogic_warn("Warning: Partition Table appears to " "have Geometry %d/%d which is\n", adapter, part_end_head + 1, part_end_sector);
3447                        blogic_warn("not compatible with current BusLogic " "Host Adapter Geometry %d/%d\n", adapter, diskparam->heads, diskparam->sectors);
3448                }
3449        }
3450        kfree(buf);
3451        return 0;
3452}
3453
3454
3455/*
3456  BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>.
3457*/
3458
3459static int blogic_write_info(struct Scsi_Host *shost, char *procbuf,
3460                                int bytes_avail)
3461{
3462        struct blogic_adapter *adapter =
3463                                (struct blogic_adapter *) shost->hostdata;
3464        struct blogic_tgt_stats *tgt_stats;
3465
3466        tgt_stats = adapter->tgt_stats;
3467        adapter->ext_resets = 0;
3468        adapter->adapter_intern_errors = 0;
3469        memset(tgt_stats, 0, BLOGIC_MAXDEV * sizeof(struct blogic_tgt_stats));
3470        return 0;
3471}
3472
3473static int blogic_show_info(struct seq_file *m, struct Scsi_Host *shost)
3474{
3475        struct blogic_adapter *adapter = (struct blogic_adapter *) shost->hostdata;
3476        struct blogic_tgt_stats *tgt_stats;
3477        int tgt;
3478
3479        tgt_stats = adapter->tgt_stats;
3480        seq_write(m, adapter->msgbuf, adapter->msgbuflen);
3481        seq_printf(m, "\n\
3482Current Driver Queue Depth:     %d\n\
3483Currently Allocated CCBs:       %d\n", adapter->drvr_qdepth, adapter->alloc_ccbs);
3484        seq_puts(m, "\n\n\
3485                           DATA TRANSFER STATISTICS\n\
3486\n\
3487Target  Tagged Queuing  Queue Depth  Active  Attempted  Completed\n\
3488======  ==============  ===========  ======  =========  =========\n");
3489        for (tgt = 0; tgt < adapter->maxdev; tgt++) {
3490                struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
3491                if (!tgt_flags->tgt_exists)
3492                        continue;
3493                seq_printf(m, "  %2d    %s", tgt, (tgt_flags->tagq_ok ? (tgt_flags->tagq_active ? "    Active" : (adapter->tagq_ok & (1 << tgt)
3494                                                                                                                                                                    ? "  Permitted" : "   Disabled"))
3495                                                                          : "Not Supported"));
3496                seq_printf(m,
3497                                  "         %3d       %3u    %9u        %9u\n", adapter->qdepth[tgt], adapter->active_cmds[tgt], tgt_stats[tgt].cmds_tried, tgt_stats[tgt].cmds_complete);
3498        }
3499        seq_puts(m, "\n\
3500Target  Read Commands  Write Commands   Total Bytes Read    Total Bytes Written\n\
3501======  =============  ==============  ===================  ===================\n");
3502        for (tgt = 0; tgt < adapter->maxdev; tgt++) {
3503                struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
3504                if (!tgt_flags->tgt_exists)
3505                        continue;
3506                seq_printf(m, "  %2d      %9u    %9u", tgt, tgt_stats[tgt].read_cmds, tgt_stats[tgt].write_cmds);
3507                if (tgt_stats[tgt].bytesread.billions > 0)
3508                        seq_printf(m, "     %9u%09u", tgt_stats[tgt].bytesread.billions, tgt_stats[tgt].bytesread.units);
3509                else
3510                        seq_printf(m, "         %9u", tgt_stats[tgt].bytesread.units);
3511                if (tgt_stats[tgt].byteswritten.billions > 0)
3512                        seq_printf(m, "   %9u%09u\n", tgt_stats[tgt].byteswritten.billions, tgt_stats[tgt].byteswritten.units);
3513                else
3514                        seq_printf(m, "      %9u\n", tgt_stats[tgt].byteswritten.units);
3515        }
3516        seq_puts(m, "\n\
3517Target  Command    0-1KB      1-2KB      2-4KB      4-8KB     8-16KB\n\
3518======  =======  =========  =========  =========  =========  =========\n");
3519        for (tgt = 0; tgt < adapter->maxdev; tgt++) {
3520                struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
3521                if (!tgt_flags->tgt_exists)
3522                        continue;
3523                seq_printf(m,
3524                            "  %2d       Read    %9u  %9u  %9u  %9u  %9u\n", tgt,
3525                            tgt_stats[tgt].read_sz_buckets[0],
3526                            tgt_stats[tgt].read_sz_buckets[1], tgt_stats[tgt].read_sz_buckets[2], tgt_stats[tgt].read_sz_buckets[3], tgt_stats[tgt].read_sz_buckets[4]);
3527                seq_printf(m,
3528                            "  %2d       Write   %9u  %9u  %9u  %9u  %9u\n", tgt,
3529                            tgt_stats[tgt].write_sz_buckets[0],
3530                            tgt_stats[tgt].write_sz_buckets[1], tgt_stats[tgt].write_sz_buckets[2], tgt_stats[tgt].write_sz_buckets[3], tgt_stats[tgt].write_sz_buckets[4]);
3531        }
3532        seq_puts(m, "\n\
3533Target  Command   16-32KB    32-64KB   64-128KB   128-256KB   256KB+\n\
3534======  =======  =========  =========  =========  =========  =========\n");
3535        for (tgt = 0; tgt < adapter->maxdev; tgt++) {
3536                struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
3537                if (!tgt_flags->tgt_exists)
3538                        continue;
3539                seq_printf(m,
3540                            "  %2d       Read    %9u  %9u  %9u  %9u  %9u\n", tgt,
3541                            tgt_stats[tgt].read_sz_buckets[5],
3542                            tgt_stats[tgt].read_sz_buckets[6], tgt_stats[tgt].read_sz_buckets[7], tgt_stats[tgt].read_sz_buckets[8], tgt_stats[tgt].read_sz_buckets[9]);
3543                seq_printf(m,
3544                            "  %2d       Write   %9u  %9u  %9u  %9u  %9u\n", tgt,
3545                            tgt_stats[tgt].write_sz_buckets[5],
3546                            tgt_stats[tgt].write_sz_buckets[6], tgt_stats[tgt].write_sz_buckets[7], tgt_stats[tgt].write_sz_buckets[8], tgt_stats[tgt].write_sz_buckets[9]);
3547        }
3548        seq_puts(m, "\n\n\
3549                           ERROR RECOVERY STATISTICS\n\
3550\n\
3551          Command Aborts      Bus Device Resets   Host Adapter Resets\n\
3552Target  Requested Completed  Requested Completed  Requested Completed\n\
3553  ID    \\\\\\\\ Attempted ////  \\\\\\\\ Attempted ////  \\\\\\\\ Attempted ////\n\
3554======   ===== ===== =====    ===== ===== =====    ===== ===== =====\n");
3555        for (tgt = 0; tgt < adapter->maxdev; tgt++) {
3556                struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
3557                if (!tgt_flags->tgt_exists)
3558                        continue;
3559                seq_printf(m, "  %2d     %5d %5d %5d    %5d %5d %5d        %5d %5d %5d\n",
3560                           tgt, tgt_stats[tgt].aborts_request,
3561                           tgt_stats[tgt].aborts_tried,
3562                           tgt_stats[tgt].aborts_done,
3563                           tgt_stats[tgt].bdr_request,
3564                           tgt_stats[tgt].bdr_tried,
3565                           tgt_stats[tgt].bdr_done,
3566                           tgt_stats[tgt].adapter_reset_req,
3567                           tgt_stats[tgt].adapter_reset_attempt,
3568                           tgt_stats[tgt].adapter_reset_done);
3569        }
3570        seq_printf(m, "\nExternal Host Adapter Resets: %d\n", adapter->ext_resets);
3571        seq_printf(m, "Host Adapter Internal Errors: %d\n", adapter->adapter_intern_errors);
3572        return 0;
3573}
3574
3575
3576/*
3577  blogic_msg prints Driver Messages.
3578*/
3579
3580static void blogic_msg(enum blogic_msglevel msglevel, char *fmt,
3581                        struct blogic_adapter *adapter, ...)
3582{
3583        static char buf[BLOGIC_LINEBUF_SIZE];
3584        static bool begin = true;
3585        va_list args;
3586        int len = 0;
3587
3588        va_start(args, adapter);
3589        len = vsprintf(buf, fmt, args);
3590        va_end(args);
3591        if (msglevel == BLOGIC_ANNOUNCE_LEVEL) {
3592                static int msglines = 0;
3593                strcpy(&adapter->msgbuf[adapter->msgbuflen], buf);
3594                adapter->msgbuflen += len;
3595                if (++msglines <= 2)
3596                        printk("%sscsi: %s", blogic_msglevelmap[msglevel], buf);
3597        } else if (msglevel == BLOGIC_INFO_LEVEL) {
3598                strcpy(&adapter->msgbuf[adapter->msgbuflen], buf);
3599                adapter->msgbuflen += len;
3600                if (begin) {
3601                        if (buf[0] != '\n' || len > 1)
3602                                printk("%sscsi%d: %s", blogic_msglevelmap[msglevel], adapter->host_no, buf);
3603                } else
3604                        printk("%s", buf);
3605        } else {
3606                if (begin) {
3607                        if (adapter != NULL && adapter->adapter_initd)
3608                                printk("%sscsi%d: %s", blogic_msglevelmap[msglevel], adapter->host_no, buf);
3609                        else
3610                                printk("%s%s", blogic_msglevelmap[msglevel], buf);
3611                } else
3612                        printk("%s", buf);
3613        }
3614        begin = (buf[len - 1] == '\n');
3615}
3616
3617
3618/*
3619  blogic_parse parses an individual option keyword.  It returns true
3620  and updates the pointer if the keyword is recognized and false otherwise.
3621*/
3622
3623static bool __init blogic_parse(char **str, char *keyword)
3624{
3625        char *pointer = *str;
3626        while (*keyword != '\0') {
3627                char strch = *pointer++;
3628                char keywordch = *keyword++;
3629                if (strch >= 'A' && strch <= 'Z')
3630                        strch += 'a' - 'Z';
3631                if (keywordch >= 'A' && keywordch <= 'Z')
3632                        keywordch += 'a' - 'Z';
3633                if (strch != keywordch)
3634                        return false;
3635        }
3636        *str = pointer;
3637        return true;
3638}
3639
3640
3641/*
3642  blogic_parseopts handles processing of BusLogic Driver Options
3643  specifications.
3644
3645  BusLogic Driver Options may be specified either via the Linux Kernel Command
3646  Line or via the Loadable Kernel Module Installation Facility.  Driver Options
3647  for multiple host adapters may be specified either by separating the option
3648  strings by a semicolon, or by specifying multiple "BusLogic=" strings on the
3649  command line.  Individual option specifications for a single host adapter are
3650  separated by commas.  The Probing and Debugging Options apply to all host
3651  adapters whereas the remaining options apply individually only to the
3652  selected host adapter.
3653
3654  The BusLogic Driver Probing Options are described in
3655  <file:Documentation/scsi/BusLogic.txt>.
3656*/
3657
3658static int __init blogic_parseopts(char *options)
3659{
3660        while (true) {
3661                struct blogic_drvr_options *drvr_opts =
3662                        &blogic_drvr_options[blogic_drvr_options_count++];
3663                int tgt_id;
3664
3665                memset(drvr_opts, 0, sizeof(struct blogic_drvr_options));
3666                while (*options != '\0' && *options != ';') {
3667                        /* Probing Options. */
3668                        if (blogic_parse(&options, "IO:")) {
3669                                unsigned long io_addr = simple_strtoul(options,
3670                                                                &options, 0);
3671                                blogic_probe_options.limited_isa = true;
3672                                switch (io_addr) {
3673                                case 0x330:
3674                                        blogic_probe_options.probe330 = true;
3675                                        break;
3676                                case 0x334:
3677                                        blogic_probe_options.probe334 = true;
3678                                        break;
3679                                case 0x230:
3680                                        blogic_probe_options.probe230 = true;
3681                                        break;
3682                                case 0x234:
3683                                        blogic_probe_options.probe234 = true;
3684                                        break;
3685                                case 0x130:
3686                                        blogic_probe_options.probe130 = true;
3687                                        break;
3688                                case 0x134:
3689                                        blogic_probe_options.probe134 = true;
3690                                        break;
3691                                default:
3692                                        blogic_err("BusLogic: Invalid Driver Options " "(invalid I/O Address 0x%X)\n", NULL, io_addr);
3693                                        return 0;
3694                                }
3695                        } else if (blogic_parse(&options, "NoProbeISA"))
3696                                blogic_probe_options.noprobe_isa = true;
3697                        else if (blogic_parse(&options, "NoProbePCI"))
3698                                blogic_probe_options.noprobe_pci = true;
3699                        else if (blogic_parse(&options, "NoProbe"))
3700                                blogic_probe_options.noprobe = true;
3701                        else if (blogic_parse(&options, "NoSortPCI"))
3702                                blogic_probe_options.nosort_pci = true;
3703                        else if (blogic_parse(&options, "MultiMasterFirst"))
3704                                blogic_probe_options.multimaster_first = true;
3705                        else if (blogic_parse(&options, "FlashPointFirst"))
3706                                blogic_probe_options.flashpoint_first = true;
3707                        /* Tagged Queuing Options. */
3708                        else if (blogic_parse(&options, "QueueDepth:[") ||
3709                                        blogic_parse(&options, "QD:[")) {
3710                                for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++) {
3711                                        unsigned short qdepth = simple_strtoul(options, &options, 0);
3712                                        if (qdepth > BLOGIC_MAX_TAG_DEPTH) {
3713                                                blogic_err("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, qdepth);
3714                                                return 0;
3715                                        }
3716                                        drvr_opts->qdepth[tgt_id] = qdepth;
3717                                        if (*options == ',')
3718                                                options++;
3719                                        else if (*options == ']')
3720                                                break;
3721                                        else {
3722                                                blogic_err("BusLogic: Invalid Driver Options " "(',' or ']' expected at '%s')\n", NULL, options);
3723                                                return 0;
3724                                        }
3725                                }
3726                                if (*options != ']') {
3727                                        blogic_err("BusLogic: Invalid Driver Options " "(']' expected at '%s')\n", NULL, options);
3728                                        return 0;
3729                                } else
3730                                        options++;
3731                        } else if (blogic_parse(&options, "QueueDepth:") || blogic_parse(&options, "QD:")) {
3732                                unsigned short qdepth = simple_strtoul(options, &options, 0);
3733                                if (qdepth == 0 ||
3734                                                qdepth > BLOGIC_MAX_TAG_DEPTH) {
3735                                        blogic_err("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, qdepth);
3736                                        return 0;
3737                                }
3738                                drvr_opts->common_qdepth = qdepth;
3739                                for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++)
3740                                        drvr_opts->qdepth[tgt_id] = qdepth;
3741                        } else if (blogic_parse(&options, "TaggedQueuing:") ||
3742                                        blogic_parse(&options, "TQ:")) {
3743                                if (blogic_parse(&options, "Default")) {
3744                                        drvr_opts->tagq_ok = 0x0000;
3745                                        drvr_opts->tagq_ok_mask = 0x0000;
3746                                } else if (blogic_parse(&options, "Enable")) {
3747                                        drvr_opts->tagq_ok = 0xFFFF;
3748                                        drvr_opts->tagq_ok_mask = 0xFFFF;
3749                                } else if (blogic_parse(&options, "Disable")) {
3750                                        drvr_opts->tagq_ok = 0x0000;
3751                                        drvr_opts->tagq_ok_mask = 0xFFFF;
3752                                } else {
3753                                        unsigned short tgt_bit;
3754                                        for (tgt_id = 0, tgt_bit = 1;
3755                                                tgt_id < BLOGIC_MAXDEV;
3756                                                tgt_id++, tgt_bit <<= 1)
3757                                                switch (*options++) {
3758                                                case 'Y':
3759                                                        drvr_opts->tagq_ok |= tgt_bit;
3760                                                        drvr_opts->tagq_ok_mask |= tgt_bit;
3761                                                        break;
3762                                                case 'N':
3763                                                        drvr_opts->tagq_ok &= ~tgt_bit;
3764                                                        drvr_opts->tagq_ok_mask |= tgt_bit;
3765                                                        break;
3766                                                case 'X':
3767                                                        break;
3768                                                default:
3769                                                        options--;
3770                                                        tgt_id = BLOGIC_MAXDEV;
3771                                                        break;
3772                                                }
3773                                }
3774                        }
3775                        /* Miscellaneous Options. */
3776                        else if (blogic_parse(&options, "BusSettleTime:") ||
3777                                        blogic_parse(&options, "BST:")) {
3778                                unsigned short bus_settle_time =
3779                                        simple_strtoul(options, &options, 0);
3780                                if (bus_settle_time > 5 * 60) {
3781                                        blogic_err("BusLogic: Invalid Driver Options " "(invalid Bus Settle Time %d)\n", NULL, bus_settle_time);
3782                                        return 0;
3783                                }
3784                                drvr_opts->bus_settle_time = bus_settle_time;
3785                        } else if (blogic_parse(&options,
3786                                                "InhibitTargetInquiry"))
3787                                drvr_opts->stop_tgt_inquiry = true;
3788                        /* Debugging Options. */
3789                        else if (blogic_parse(&options, "TraceProbe"))
3790                                blogic_global_options.trace_probe = true;
3791                        else if (blogic_parse(&options, "TraceHardwareReset"))
3792                                blogic_global_options.trace_hw_reset = true;
3793                        else if (blogic_parse(&options, "TraceConfiguration"))
3794                                blogic_global_options.trace_config = true;
3795                        else if (blogic_parse(&options, "TraceErrors"))
3796                                blogic_global_options.trace_err = true;
3797                        else if (blogic_parse(&options, "Debug")) {
3798                                blogic_global_options.trace_probe = true;
3799                                blogic_global_options.trace_hw_reset = true;
3800                                blogic_global_options.trace_config = true;
3801                                blogic_global_options.trace_err = true;
3802                        }
3803                        if (*options == ',')
3804                                options++;
3805                        else if (*options != ';' && *options != '\0') {
3806                                blogic_err("BusLogic: Unexpected Driver Option '%s' " "ignored\n", NULL, options);
3807                                *options = '\0';
3808                        }
3809                }
3810                if (!(blogic_drvr_options_count == 0 ||
3811                        blogic_probeinfo_count == 0 ||
3812                        blogic_drvr_options_count == blogic_probeinfo_count)) {
3813                        blogic_err("BusLogic: Invalid Driver Options " "(all or no I/O Addresses must be specified)\n", NULL);
3814                        return 0;
3815                }
3816                /*
3817                   Tagged Queuing is disabled when the Queue Depth is 1 since queuing
3818                   multiple commands is not possible.
3819                 */
3820                for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++)
3821                        if (drvr_opts->qdepth[tgt_id] == 1) {
3822                                unsigned short tgt_bit = 1 << tgt_id;
3823                                drvr_opts->tagq_ok &= ~tgt_bit;
3824                                drvr_opts->tagq_ok_mask |= tgt_bit;
3825                        }
3826                if (*options == ';')
3827                        options++;
3828                if (*options == '\0')
3829                        return 0;
3830        }
3831        return 1;
3832}
3833
3834/*
3835  Get it all started
3836*/
3837
3838static struct scsi_host_template blogic_template = {
3839        .module = THIS_MODULE,
3840        .proc_name = "BusLogic",
3841        .write_info = blogic_write_info,
3842        .show_info = blogic_show_info,
3843        .name = "BusLogic",
3844        .info = blogic_drvr_info,
3845        .queuecommand = blogic_qcmd,
3846        .slave_configure = blogic_slaveconfig,
3847        .bios_param = blogic_diskparam,
3848        .eh_host_reset_handler = blogic_hostreset,
3849#if 0
3850        .eh_abort_handler = blogic_abort,
3851#endif
3852        .unchecked_isa_dma = 1,
3853        .max_sectors = 128,
3854};
3855
3856/*
3857  blogic_setup handles processing of Kernel Command Line Arguments.
3858*/
3859
3860static int __init blogic_setup(char *str)
3861{
3862        int ints[3];
3863
3864        (void) get_options(str, ARRAY_SIZE(ints), ints);
3865
3866        if (ints[0] != 0) {
3867                blogic_err("BusLogic: Obsolete Command Line Entry " "Format Ignored\n", NULL);
3868                return 0;
3869        }
3870        if (str == NULL || *str == '\0')
3871                return 0;
3872        return blogic_parseopts(str);
3873}
3874
3875/*
3876 * Exit function.  Deletes all hosts associated with this driver.
3877 */
3878
3879static void __exit blogic_exit(void)
3880{
3881        struct blogic_adapter *ha, *next;
3882
3883        list_for_each_entry_safe(ha, next, &blogic_host_list, host_list)
3884                blogic_deladapter(ha);
3885}
3886
3887__setup("BusLogic=", blogic_setup);
3888
3889#ifdef MODULE
3890/*static struct pci_device_id blogic_pci_tbl[] = {
3891        { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
3892          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
3893        { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
3894          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
3895        { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
3896          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
3897        { }
3898};*/
3899static const struct pci_device_id blogic_pci_tbl[] = {
3900        {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER)},
3901        {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC)},
3902        {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT)},
3903        {0, },
3904};
3905#endif
3906MODULE_DEVICE_TABLE(pci, blogic_pci_tbl);
3907
3908module_init(blogic_init);
3909module_exit(blogic_exit);
3910