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