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