Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 
0003 /*
0004 
0005   Linux Driver for BusLogic MultiMaster and FlashPoint SCSI Host Adapters
0006 
0007   Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>
0008 
0009 
0010   The author respectfully requests that any modifications to this software be
0011   sent directly to him for evaluation and testing.
0012 
0013   Special thanks to Wayne Yen, Jin-Lon Hon, and Alex Win of BusLogic, whose
0014   advice has been invaluable, to David Gentzel, for writing the original Linux
0015   BusLogic driver, and to Paul Gortmaker, for being such a dedicated test site.
0016 
0017   Finally, special thanks to Mylex/BusLogic for making the FlashPoint SCCB
0018   Manager available as freely redistributable source code.
0019 
0020 */
0021 
0022 #define blogic_drvr_version     "2.1.17"
0023 #define blogic_drvr_date        "12 September 2013"
0024 
0025 #include <linux/module.h>
0026 #include <linux/init.h>
0027 #include <linux/interrupt.h>
0028 #include <linux/types.h>
0029 #include <linux/blkdev.h>
0030 #include <linux/delay.h>
0031 #include <linux/ioport.h>
0032 #include <linux/mm.h>
0033 #include <linux/stat.h>
0034 #include <linux/pci.h>
0035 #include <linux/spinlock.h>
0036 #include <linux/jiffies.h>
0037 #include <linux/dma-mapping.h>
0038 #include <linux/slab.h>
0039 #include <linux/msdos_partition.h>
0040 #include <scsi/scsicam.h>
0041 
0042 #include <asm/dma.h>
0043 #include <asm/io.h>
0044 
0045 #include <scsi/scsi.h>
0046 #include <scsi/scsi_cmnd.h>
0047 #include <scsi/scsi_device.h>
0048 #include <scsi/scsi_host.h>
0049 #include <scsi/scsi_tcq.h>
0050 #include "BusLogic.h"
0051 #include "FlashPoint.c"
0052 
0053 #ifndef FAILURE
0054 #define FAILURE (-1)
0055 #endif
0056 
0057 static struct scsi_host_template blogic_template;
0058 
0059 /*
0060   blogic_drvr_options_count is a count of the number of BusLogic Driver
0061   Options specifications provided via the Linux Kernel Command Line or via
0062   the Loadable Kernel Module Installation Facility.
0063 */
0064 
0065 static int blogic_drvr_options_count;
0066 
0067 
0068 /*
0069   blogic_drvr_options is an array of Driver Options structures representing
0070   BusLogic Driver Options specifications provided via the Linux Kernel Command
0071   Line or via the Loadable Kernel Module Installation Facility.
0072 */
0073 
0074 static struct blogic_drvr_options blogic_drvr_options[BLOGIC_MAX_ADAPTERS];
0075 
0076 
0077 /*
0078   BusLogic can be assigned a string by insmod.
0079 */
0080 
0081 MODULE_LICENSE("GPL");
0082 #ifdef MODULE
0083 static char *BusLogic;
0084 module_param(BusLogic, charp, 0);
0085 #endif
0086 
0087 
0088 /*
0089   blogic_probe_options is a set of Probe Options to be applied across
0090   all BusLogic Host Adapters.
0091 */
0092 
0093 static struct blogic_probe_options blogic_probe_options;
0094 
0095 
0096 /*
0097   blogic_global_options is a set of Global Options to be applied across
0098   all BusLogic Host Adapters.
0099 */
0100 
0101 static struct blogic_global_options blogic_global_options;
0102 
0103 static LIST_HEAD(blogic_host_list);
0104 
0105 /*
0106   blogic_probeinfo_count is the number of entries in blogic_probeinfo_list.
0107 */
0108 
0109 static int blogic_probeinfo_count;
0110 
0111 
0112 /*
0113   blogic_probeinfo_list is the list of I/O Addresses and Bus Probe Information
0114   to be checked for potential BusLogic Host Adapters.  It is initialized by
0115   interrogating the PCI Configuration Space on PCI machines as well as from the
0116   list of standard BusLogic I/O Addresses.
0117 */
0118 
0119 static struct blogic_probeinfo *blogic_probeinfo_list;
0120 
0121 
0122 /*
0123   blogic_cmd_failure_reason holds a string identifying the reason why a
0124   call to blogic_cmd failed.  It is only non-NULL when blogic_cmd
0125   returns a failure code.
0126 */
0127 
0128 static char *blogic_cmd_failure_reason;
0129 
0130 /*
0131   blogic_announce_drvr announces the Driver Version and Date, Author's
0132   Name, Copyright Notice, and Electronic Mail Address.
0133 */
0134 
0135 static void blogic_announce_drvr(struct blogic_adapter *adapter)
0136 {
0137     blogic_announce("***** BusLogic SCSI Driver Version " blogic_drvr_version " of " blogic_drvr_date " *****\n", adapter);
0138     blogic_announce("Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>\n", adapter);
0139 }
0140 
0141 
0142 /*
0143   blogic_drvr_info returns the Host Adapter Name to identify this SCSI
0144   Driver and Host Adapter.
0145 */
0146 
0147 static const char *blogic_drvr_info(struct Scsi_Host *host)
0148 {
0149     struct blogic_adapter *adapter =
0150                 (struct blogic_adapter *) host->hostdata;
0151     return adapter->full_model;
0152 }
0153 
0154 /*
0155   blogic_init_ccbs initializes a group of Command Control Blocks (CCBs)
0156   for Host Adapter from the blk_size bytes located at blk_pointer.  The newly
0157   created CCBs are added to Host Adapter's free list.
0158 */
0159 
0160 static void blogic_init_ccbs(struct blogic_adapter *adapter, void *blk_pointer,
0161                 int blk_size, dma_addr_t blkp)
0162 {
0163     struct blogic_ccb *ccb = (struct blogic_ccb *) blk_pointer;
0164     unsigned int offset = 0;
0165     memset(blk_pointer, 0, blk_size);
0166     ccb->allocgrp_head = blkp;
0167     ccb->allocgrp_size = blk_size;
0168     while ((blk_size -= sizeof(struct blogic_ccb)) >= 0) {
0169         ccb->status = BLOGIC_CCB_FREE;
0170         ccb->adapter = adapter;
0171         ccb->dma_handle = (u32) blkp + offset;
0172         if (blogic_flashpoint_type(adapter)) {
0173             ccb->callback = blogic_qcompleted_ccb;
0174             ccb->base_addr = adapter->fpinfo.base_addr;
0175         }
0176         ccb->next = adapter->free_ccbs;
0177         ccb->next_all = adapter->all_ccbs;
0178         adapter->free_ccbs = ccb;
0179         adapter->all_ccbs = ccb;
0180         adapter->alloc_ccbs++;
0181         ccb++;
0182         offset += sizeof(struct blogic_ccb);
0183     }
0184 }
0185 
0186 
0187 /*
0188   blogic_create_initccbs allocates the initial CCBs for Host Adapter.
0189 */
0190 
0191 static bool __init blogic_create_initccbs(struct blogic_adapter *adapter)
0192 {
0193     int blk_size = BLOGIC_CCB_GRP_ALLOCSIZE * sizeof(struct blogic_ccb);
0194     void *blk_pointer;
0195     dma_addr_t blkp;
0196 
0197     while (adapter->alloc_ccbs < adapter->initccbs) {
0198         blk_pointer = dma_alloc_coherent(&adapter->pci_device->dev,
0199                 blk_size, &blkp, GFP_KERNEL);
0200         if (blk_pointer == NULL) {
0201             blogic_err("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n",
0202                     adapter);
0203             return false;
0204         }
0205         blogic_init_ccbs(adapter, blk_pointer, blk_size, blkp);
0206     }
0207     return true;
0208 }
0209 
0210 
0211 /*
0212   blogic_destroy_ccbs deallocates the CCBs for Host Adapter.
0213 */
0214 
0215 static void blogic_destroy_ccbs(struct blogic_adapter *adapter)
0216 {
0217     struct blogic_ccb *next_ccb = adapter->all_ccbs, *ccb, *lastccb = NULL;
0218     adapter->all_ccbs = NULL;
0219     adapter->free_ccbs = NULL;
0220     while ((ccb = next_ccb) != NULL) {
0221         next_ccb = ccb->next_all;
0222         if (ccb->allocgrp_head) {
0223             if (lastccb)
0224                 dma_free_coherent(&adapter->pci_device->dev,
0225                         lastccb->allocgrp_size, lastccb,
0226                         lastccb->allocgrp_head);
0227             lastccb = ccb;
0228         }
0229     }
0230     if (lastccb)
0231         dma_free_coherent(&adapter->pci_device->dev,
0232                 lastccb->allocgrp_size, lastccb,
0233                 lastccb->allocgrp_head);
0234 }
0235 
0236 
0237 /*
0238   blogic_create_addlccbs allocates Additional CCBs for Host Adapter.  If
0239   allocation fails and there are no remaining CCBs available, the Driver Queue
0240   Depth is decreased to a known safe value to avoid potential deadlocks when
0241   multiple host adapters share the same IRQ Channel.
0242 */
0243 
0244 static void blogic_create_addlccbs(struct blogic_adapter *adapter,
0245                     int addl_ccbs, bool print_success)
0246 {
0247     int blk_size = BLOGIC_CCB_GRP_ALLOCSIZE * sizeof(struct blogic_ccb);
0248     int prev_alloc = adapter->alloc_ccbs;
0249     void *blk_pointer;
0250     dma_addr_t blkp;
0251     if (addl_ccbs <= 0)
0252         return;
0253     while (adapter->alloc_ccbs - prev_alloc < addl_ccbs) {
0254         blk_pointer = dma_alloc_coherent(&adapter->pci_device->dev,
0255                 blk_size, &blkp, GFP_KERNEL);
0256         if (blk_pointer == NULL)
0257             break;
0258         blogic_init_ccbs(adapter, blk_pointer, blk_size, blkp);
0259     }
0260     if (adapter->alloc_ccbs > prev_alloc) {
0261         if (print_success)
0262             blogic_notice("Allocated %d additional CCBs (total now %d)\n", adapter, adapter->alloc_ccbs - prev_alloc, adapter->alloc_ccbs);
0263         return;
0264     }
0265     blogic_notice("Failed to allocate additional CCBs\n", adapter);
0266     if (adapter->drvr_qdepth > adapter->alloc_ccbs - adapter->tgt_count) {
0267         adapter->drvr_qdepth = adapter->alloc_ccbs - adapter->tgt_count;
0268         adapter->scsi_host->can_queue = adapter->drvr_qdepth;
0269     }
0270 }
0271 
0272 /*
0273   blogic_alloc_ccb allocates a CCB from Host Adapter's free list,
0274   allocating more memory from the Kernel if necessary.  The Host Adapter's
0275   Lock should already have been acquired by the caller.
0276 */
0277 
0278 static struct blogic_ccb *blogic_alloc_ccb(struct blogic_adapter *adapter)
0279 {
0280     static unsigned long serial;
0281     struct blogic_ccb *ccb;
0282     ccb = adapter->free_ccbs;
0283     if (ccb != NULL) {
0284         ccb->serial = ++serial;
0285         adapter->free_ccbs = ccb->next;
0286         ccb->next = NULL;
0287         if (adapter->free_ccbs == NULL)
0288             blogic_create_addlccbs(adapter, adapter->inc_ccbs,
0289                         true);
0290         return ccb;
0291     }
0292     blogic_create_addlccbs(adapter, adapter->inc_ccbs, true);
0293     ccb = adapter->free_ccbs;
0294     if (ccb == NULL)
0295         return NULL;
0296     ccb->serial = ++serial;
0297     adapter->free_ccbs = ccb->next;
0298     ccb->next = NULL;
0299     return ccb;
0300 }
0301 
0302 
0303 /*
0304   blogic_dealloc_ccb deallocates a CCB, returning it to the Host Adapter's
0305   free list.  The Host Adapter's Lock should already have been acquired by the
0306   caller.
0307 */
0308 
0309 static void blogic_dealloc_ccb(struct blogic_ccb *ccb, int dma_unmap)
0310 {
0311     struct blogic_adapter *adapter = ccb->adapter;
0312 
0313     if (ccb->command != NULL)
0314         scsi_dma_unmap(ccb->command);
0315     if (dma_unmap)
0316         dma_unmap_single(&adapter->pci_device->dev, ccb->sensedata,
0317              ccb->sense_datalen, DMA_FROM_DEVICE);
0318 
0319     ccb->command = NULL;
0320     ccb->status = BLOGIC_CCB_FREE;
0321     ccb->next = adapter->free_ccbs;
0322     adapter->free_ccbs = ccb;
0323 }
0324 
0325 
0326 /*
0327   blogic_cmd sends the command opcode to adapter, optionally
0328   providing paramlen bytes of param and receiving at most
0329   replylen bytes of reply; any excess reply data is received but
0330   discarded.
0331 
0332   On success, this function returns the number of reply bytes read from
0333   the Host Adapter (including any discarded data); on failure, it returns
0334   -1 if the command was invalid, or -2 if a timeout occurred.
0335 
0336   blogic_cmd is called exclusively during host adapter detection and
0337   initialization, so performance and latency are not critical, and exclusive
0338   access to the Host Adapter hardware is assumed.  Once the host adapter and
0339   driver are initialized, the only Host Adapter command that is issued is the
0340   single byte Execute Mailbox Command operation code, which does not require
0341   waiting for the Host Adapter Ready bit to be set in the Status Register.
0342 */
0343 
0344 static int blogic_cmd(struct blogic_adapter *adapter, enum blogic_opcode opcode,
0345             void *param, int paramlen, void *reply, int replylen)
0346 {
0347     unsigned char *param_p = (unsigned char *) param;
0348     unsigned char *reply_p = (unsigned char *) reply;
0349     union blogic_stat_reg statusreg;
0350     union blogic_int_reg intreg;
0351     unsigned long processor_flag = 0;
0352     int reply_b = 0, result;
0353     long timeout;
0354     /*
0355        Clear out the Reply Data if provided.
0356      */
0357     if (replylen > 0)
0358         memset(reply, 0, replylen);
0359     /*
0360        If the IRQ Channel has not yet been acquired, then interrupts
0361        must be disabled while issuing host adapter commands since a
0362        Command Complete interrupt could occur if the IRQ Channel was
0363        previously enabled by another BusLogic Host Adapter or another
0364        driver sharing the same IRQ Channel.
0365      */
0366     if (!adapter->irq_acquired)
0367         local_irq_save(processor_flag);
0368     /*
0369        Wait for the Host Adapter Ready bit to be set and the
0370        Command/Parameter Register Busy bit to be reset in the Status
0371        Register.
0372      */
0373     timeout = 10000;
0374     while (--timeout >= 0) {
0375         statusreg.all = blogic_rdstatus(adapter);
0376         if (statusreg.sr.adapter_ready && !statusreg.sr.cmd_param_busy)
0377             break;
0378         udelay(100);
0379     }
0380     if (timeout < 0) {
0381         blogic_cmd_failure_reason =
0382                 "Timeout waiting for Host Adapter Ready";
0383         result = -2;
0384         goto done;
0385     }
0386     /*
0387        Write the opcode to the Command/Parameter Register.
0388      */
0389     adapter->adapter_cmd_complete = false;
0390     blogic_setcmdparam(adapter, opcode);
0391     /*
0392        Write any additional Parameter Bytes.
0393      */
0394     timeout = 10000;
0395     while (paramlen > 0 && --timeout >= 0) {
0396         /*
0397            Wait 100 microseconds to give the Host Adapter enough
0398            time to determine whether the last value written to the
0399            Command/Parameter Register was valid or not. If the
0400            Command Complete bit is set in the Interrupt Register,
0401            then the Command Invalid bit in the Status Register will
0402            be reset if the Operation Code or Parameter was valid
0403            and the command has completed, or set if the Operation
0404            Code or Parameter was invalid. If the Data In Register
0405            Ready bit is set in the Status Register, then the
0406            Operation Code was valid, and data is waiting to be read
0407            back from the Host Adapter. Otherwise, wait for the
0408            Command/Parameter Register Busy bit in the Status
0409            Register to be reset.
0410          */
0411         udelay(100);
0412         intreg.all = blogic_rdint(adapter);
0413         statusreg.all = blogic_rdstatus(adapter);
0414         if (intreg.ir.cmd_complete)
0415             break;
0416         if (adapter->adapter_cmd_complete)
0417             break;
0418         if (statusreg.sr.datain_ready)
0419             break;
0420         if (statusreg.sr.cmd_param_busy)
0421             continue;
0422         blogic_setcmdparam(adapter, *param_p++);
0423         paramlen--;
0424     }
0425     if (timeout < 0) {
0426         blogic_cmd_failure_reason =
0427                 "Timeout waiting for Parameter Acceptance";
0428         result = -2;
0429         goto done;
0430     }
0431     /*
0432        The Modify I/O Address command does not cause a Command Complete
0433        Interrupt.
0434      */
0435     if (opcode == BLOGIC_MOD_IOADDR) {
0436         statusreg.all = blogic_rdstatus(adapter);
0437         if (statusreg.sr.cmd_invalid) {
0438             blogic_cmd_failure_reason =
0439                     "Modify I/O Address Invalid";
0440             result = -1;
0441             goto done;
0442         }
0443         if (blogic_global_options.trace_config)
0444             blogic_notice("blogic_cmd(%02X) Status = %02X: (Modify I/O Address)\n", adapter, opcode, statusreg.all);
0445         result = 0;
0446         goto done;
0447     }
0448     /*
0449        Select an appropriate timeout value for awaiting command completion.
0450      */
0451     switch (opcode) {
0452     case BLOGIC_INQ_DEV0TO7:
0453     case BLOGIC_INQ_DEV8TO15:
0454     case BLOGIC_INQ_DEV:
0455         /* Approximately 60 seconds. */
0456         timeout = 60 * 10000;
0457         break;
0458     default:
0459         /* Approximately 1 second. */
0460         timeout = 10000;
0461         break;
0462     }
0463     /*
0464        Receive any Reply Bytes, waiting for either the Command
0465        Complete bit to be set in the Interrupt Register, or for the
0466        Interrupt Handler to set the Host Adapter Command Completed
0467        bit in the Host Adapter structure.
0468      */
0469     while (--timeout >= 0) {
0470         intreg.all = blogic_rdint(adapter);
0471         statusreg.all = blogic_rdstatus(adapter);
0472         if (intreg.ir.cmd_complete)
0473             break;
0474         if (adapter->adapter_cmd_complete)
0475             break;
0476         if (statusreg.sr.datain_ready) {
0477             if (++reply_b <= replylen)
0478                 *reply_p++ = blogic_rddatain(adapter);
0479             else
0480                 blogic_rddatain(adapter);
0481         }
0482         if (opcode == BLOGIC_FETCH_LOCALRAM &&
0483                 statusreg.sr.adapter_ready)
0484             break;
0485         udelay(100);
0486     }
0487     if (timeout < 0) {
0488         blogic_cmd_failure_reason =
0489                     "Timeout waiting for Command Complete";
0490         result = -2;
0491         goto done;
0492     }
0493     /*
0494        Clear any pending Command Complete Interrupt.
0495      */
0496     blogic_intreset(adapter);
0497     /*
0498        Provide tracing information if requested.
0499      */
0500     if (blogic_global_options.trace_config) {
0501         int i;
0502         blogic_notice("blogic_cmd(%02X) Status = %02X: %2d ==> %2d:",
0503                 adapter, opcode, statusreg.all, replylen,
0504                 reply_b);
0505         if (replylen > reply_b)
0506             replylen = reply_b;
0507         for (i = 0; i < replylen; i++)
0508             blogic_notice(" %02X", adapter,
0509                     ((unsigned char *) reply)[i]);
0510         blogic_notice("\n", adapter);
0511     }
0512     /*
0513        Process Command Invalid conditions.
0514      */
0515     if (statusreg.sr.cmd_invalid) {
0516         /*
0517            Some early BusLogic Host Adapters may not recover
0518            properly from a Command Invalid condition, so if this
0519            appears to be the case, a Soft Reset is issued to the
0520            Host Adapter.  Potentially invalid commands are never
0521            attempted after Mailbox Initialization is performed,
0522            so there should be no Host Adapter state lost by a
0523            Soft Reset in response to a Command Invalid condition.
0524          */
0525         udelay(1000);
0526         statusreg.all = blogic_rdstatus(adapter);
0527         if (statusreg.sr.cmd_invalid || statusreg.sr.rsvd ||
0528                 statusreg.sr.datain_ready ||
0529                 statusreg.sr.cmd_param_busy ||
0530                 !statusreg.sr.adapter_ready ||
0531                 !statusreg.sr.init_reqd ||
0532                 statusreg.sr.diag_active ||
0533                 statusreg.sr.diag_failed) {
0534             blogic_softreset(adapter);
0535             udelay(1000);
0536         }
0537         blogic_cmd_failure_reason = "Command Invalid";
0538         result = -1;
0539         goto done;
0540     }
0541     /*
0542        Handle Excess Parameters Supplied conditions.
0543      */
0544     if (paramlen > 0) {
0545         blogic_cmd_failure_reason = "Excess Parameters Supplied";
0546         result = -1;
0547         goto done;
0548     }
0549     /*
0550        Indicate the command completed successfully.
0551      */
0552     blogic_cmd_failure_reason = NULL;
0553     result = reply_b;
0554     /*
0555        Restore the interrupt status if necessary and return.
0556      */
0557 done:
0558     if (!adapter->irq_acquired)
0559         local_irq_restore(processor_flag);
0560     return result;
0561 }
0562 
0563 
0564 /*
0565   blogic_sort_probeinfo sorts a section of blogic_probeinfo_list in order
0566   of increasing PCI Bus and Device Number.
0567 */
0568 
0569 static void __init blogic_sort_probeinfo(struct blogic_probeinfo
0570                     *probeinfo_list, int probeinfo_cnt)
0571 {
0572     int last_exchange = probeinfo_cnt - 1, bound, j;
0573 
0574     while (last_exchange > 0) {
0575         bound = last_exchange;
0576         last_exchange = 0;
0577         for (j = 0; j < bound; j++) {
0578             struct blogic_probeinfo *probeinfo1 =
0579                             &probeinfo_list[j];
0580             struct blogic_probeinfo *probeinfo2 =
0581                             &probeinfo_list[j + 1];
0582             if (probeinfo1->bus > probeinfo2->bus ||
0583                 (probeinfo1->bus == probeinfo2->bus &&
0584                 (probeinfo1->dev > probeinfo2->dev))) {
0585                 struct blogic_probeinfo tmp_probeinfo;
0586 
0587                 memcpy(&tmp_probeinfo, probeinfo1,
0588                     sizeof(struct blogic_probeinfo));
0589                 memcpy(probeinfo1, probeinfo2,
0590                     sizeof(struct blogic_probeinfo));
0591                 memcpy(probeinfo2, &tmp_probeinfo,
0592                     sizeof(struct blogic_probeinfo));
0593                 last_exchange = j;
0594             }
0595         }
0596     }
0597 }
0598 
0599 
0600 /*
0601   blogic_init_mm_probeinfo initializes the list of I/O Address
0602   and Bus Probe Information to be checked for potential BusLogic MultiMaster
0603   SCSI Host Adapters by interrogating the PCI Configuration Space on PCI
0604   machines as well as from the list of standard BusLogic MultiMaster ISA
0605   I/O Addresses.  It returns the number of PCI MultiMaster Host Adapters found.
0606 */
0607 
0608 static int __init blogic_init_mm_probeinfo(struct blogic_adapter *adapter)
0609 {
0610     struct blogic_probeinfo *pr_probeinfo =
0611         &blogic_probeinfo_list[blogic_probeinfo_count];
0612     int nonpr_mmindex = blogic_probeinfo_count + 1;
0613     int nonpr_mmcount = 0, mmcount = 0;
0614     bool force_scan_order = false;
0615     bool force_scan_order_checked = false;
0616     struct pci_dev *pci_device = NULL;
0617     int i;
0618     if (blogic_probeinfo_count >= BLOGIC_MAX_ADAPTERS)
0619         return 0;
0620     blogic_probeinfo_count++;
0621     /*
0622        Iterate over the MultiMaster PCI Host Adapters.  For each
0623        enumerated host adapter, determine whether its ISA Compatible
0624        I/O Port is enabled and if so, whether it is assigned the
0625        Primary I/O Address.  A host adapter that is assigned the
0626        Primary I/O Address will always be the preferred boot device.
0627        The MultiMaster BIOS will first recognize a host adapter at
0628        the Primary I/O Address, then any other PCI host adapters,
0629        and finally any host adapters located at the remaining
0630        standard ISA I/O Addresses.  When a PCI host adapter is found
0631        with its ISA Compatible I/O Port enabled, a command is issued
0632        to disable the ISA Compatible I/O Port, and it is noted that the
0633        particular standard ISA I/O Address need not be probed.
0634      */
0635     pr_probeinfo->io_addr = 0;
0636     while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
0637                     PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
0638                     pci_device)) != NULL) {
0639         struct blogic_adapter *host_adapter = adapter;
0640         struct blogic_adapter_info adapter_info;
0641         enum blogic_isa_ioport mod_ioaddr_req;
0642         unsigned char bus;
0643         unsigned char device;
0644         unsigned int irq_ch;
0645         unsigned long base_addr0;
0646         unsigned long base_addr1;
0647         unsigned long io_addr;
0648         unsigned long pci_addr;
0649 
0650         if (pci_enable_device(pci_device))
0651             continue;
0652 
0653         if (dma_set_mask(&pci_device->dev, DMA_BIT_MASK(32)))
0654             continue;
0655 
0656         bus = pci_device->bus->number;
0657         device = pci_device->devfn >> 3;
0658         irq_ch = pci_device->irq;
0659         io_addr = base_addr0 = pci_resource_start(pci_device, 0);
0660         pci_addr = base_addr1 = pci_resource_start(pci_device, 1);
0661 
0662         if (pci_resource_flags(pci_device, 0) & IORESOURCE_MEM) {
0663             blogic_err("BusLogic: Base Address0 0x%lX not I/O for MultiMaster Host Adapter\n", NULL, base_addr0);
0664             blogic_err("at PCI Bus %d Device %d I/O Address 0x%lX\n", NULL, bus, device, io_addr);
0665             continue;
0666         }
0667         if (pci_resource_flags(pci_device, 1) & IORESOURCE_IO) {
0668             blogic_err("BusLogic: Base Address1 0x%lX not Memory for MultiMaster Host Adapter\n", NULL, base_addr1);
0669             blogic_err("at PCI Bus %d Device %d PCI Address 0x%lX\n", NULL, bus, device, pci_addr);
0670             continue;
0671         }
0672         if (irq_ch == 0) {
0673             blogic_err("BusLogic: IRQ Channel %d invalid for MultiMaster Host Adapter\n", NULL, irq_ch);
0674             blogic_err("at PCI Bus %d Device %d I/O Address 0x%lX\n", NULL, bus, device, io_addr);
0675             continue;
0676         }
0677         if (blogic_global_options.trace_probe) {
0678             blogic_notice("BusLogic: PCI MultiMaster Host Adapter detected at\n", NULL);
0679             blogic_notice("BusLogic: PCI Bus %d Device %d I/O Address 0x%lX PCI Address 0x%lX\n", NULL, bus, device, io_addr, pci_addr);
0680         }
0681         /*
0682            Issue the Inquire PCI Host Adapter Information command to determine
0683            the ISA Compatible I/O Port.  If the ISA Compatible I/O Port is
0684            known and enabled, note that the particular Standard ISA I/O
0685            Address should not be probed.
0686          */
0687         host_adapter->io_addr = io_addr;
0688         blogic_intreset(host_adapter);
0689         if (blogic_cmd(host_adapter, BLOGIC_INQ_PCI_INFO, NULL, 0,
0690                 &adapter_info, sizeof(adapter_info)) !=
0691                 sizeof(adapter_info))
0692             adapter_info.isa_port = BLOGIC_IO_DISABLE;
0693         /*
0694            Issue the Modify I/O Address command to disable the
0695            ISA Compatible I/O Port. On PCI Host Adapters, the
0696            Modify I/O Address command allows modification of the
0697            ISA compatible I/O Address that the Host Adapter
0698            responds to; it does not affect the PCI compliant
0699            I/O Address assigned at system initialization.
0700          */
0701         mod_ioaddr_req = BLOGIC_IO_DISABLE;
0702         blogic_cmd(host_adapter, BLOGIC_MOD_IOADDR, &mod_ioaddr_req,
0703                 sizeof(mod_ioaddr_req), NULL, 0);
0704         /*
0705            For the first MultiMaster Host Adapter enumerated,
0706            issue the Fetch Host Adapter Local RAM command to read
0707            byte 45 of the AutoSCSI area, for the setting of the
0708            "Use Bus And Device # For PCI Scanning Seq." option.
0709            Issue the Inquire Board ID command since this option is
0710            only valid for the BT-948/958/958D.
0711          */
0712         if (!force_scan_order_checked) {
0713             struct blogic_fetch_localram fetch_localram;
0714             struct blogic_autoscsi_byte45 autoscsi_byte45;
0715             struct blogic_board_id id;
0716 
0717             fetch_localram.offset = BLOGIC_AUTOSCSI_BASE + 45;
0718             fetch_localram.count = sizeof(autoscsi_byte45);
0719             blogic_cmd(host_adapter, BLOGIC_FETCH_LOCALRAM,
0720                     &fetch_localram, sizeof(fetch_localram),
0721                     &autoscsi_byte45,
0722                     sizeof(autoscsi_byte45));
0723             blogic_cmd(host_adapter, BLOGIC_GET_BOARD_ID, NULL, 0,
0724                     &id, sizeof(id));
0725             if (id.fw_ver_digit1 == '5')
0726                 force_scan_order =
0727                     autoscsi_byte45.force_scan_order;
0728             force_scan_order_checked = true;
0729         }
0730         /*
0731            Determine whether this MultiMaster Host Adapter has its
0732            ISA Compatible I/O Port enabled and is assigned the
0733            Primary I/O Address. If it does, then it is the Primary
0734            MultiMaster Host Adapter and must be recognized first.
0735            If it does not, then it is added to the list for probing
0736            after any Primary MultiMaster Host Adapter is probed.
0737          */
0738         if (adapter_info.isa_port == BLOGIC_IO_330) {
0739             pr_probeinfo->adapter_type = BLOGIC_MULTIMASTER;
0740             pr_probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
0741             pr_probeinfo->io_addr = io_addr;
0742             pr_probeinfo->pci_addr = pci_addr;
0743             pr_probeinfo->bus = bus;
0744             pr_probeinfo->dev = device;
0745             pr_probeinfo->irq_ch = irq_ch;
0746             pr_probeinfo->pci_device = pci_dev_get(pci_device);
0747             mmcount++;
0748         } else if (blogic_probeinfo_count < BLOGIC_MAX_ADAPTERS) {
0749             struct blogic_probeinfo *probeinfo =
0750                 &blogic_probeinfo_list[blogic_probeinfo_count++];
0751             probeinfo->adapter_type = BLOGIC_MULTIMASTER;
0752             probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
0753             probeinfo->io_addr = io_addr;
0754             probeinfo->pci_addr = pci_addr;
0755             probeinfo->bus = bus;
0756             probeinfo->dev = device;
0757             probeinfo->irq_ch = irq_ch;
0758             probeinfo->pci_device = pci_dev_get(pci_device);
0759             nonpr_mmcount++;
0760             mmcount++;
0761         } else
0762             blogic_warn("BusLogic: Too many Host Adapters detected\n", NULL);
0763     }
0764     /*
0765        If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq."
0766        option is ON for the first enumerated MultiMaster Host Adapter,
0767        and if that host adapter is a BT-948/958/958D, then the
0768        MultiMaster BIOS will recognize MultiMaster Host Adapters in
0769        the order of increasing PCI Bus and Device Number. In that case,
0770        sort the probe information into the same order the BIOS uses.
0771        If this option is OFF, then the MultiMaster BIOS will recognize
0772        MultiMaster Host Adapters in the order they are enumerated by
0773        the PCI BIOS, and hence no sorting is necessary.
0774      */
0775     if (force_scan_order)
0776         blogic_sort_probeinfo(&blogic_probeinfo_list[nonpr_mmindex],
0777                     nonpr_mmcount);
0778     /*
0779        Iterate over the older non-compliant MultiMaster PCI Host Adapters,
0780        noting the PCI bus location and assigned IRQ Channel.
0781      */
0782     pci_device = NULL;
0783     while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
0784                     PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
0785                     pci_device)) != NULL) {
0786         unsigned char bus;
0787         unsigned char device;
0788         unsigned int irq_ch;
0789         unsigned long io_addr;
0790 
0791         if (pci_enable_device(pci_device))
0792             continue;
0793 
0794         if (dma_set_mask(&pci_device->dev, DMA_BIT_MASK(32)))
0795             continue;
0796 
0797         bus = pci_device->bus->number;
0798         device = pci_device->devfn >> 3;
0799         irq_ch = pci_device->irq;
0800         io_addr = pci_resource_start(pci_device, 0);
0801 
0802         if (io_addr == 0 || irq_ch == 0)
0803             continue;
0804         for (i = 0; i < blogic_probeinfo_count; i++) {
0805             struct blogic_probeinfo *probeinfo =
0806                         &blogic_probeinfo_list[i];
0807             if (probeinfo->io_addr == io_addr &&
0808                 probeinfo->adapter_type == BLOGIC_MULTIMASTER) {
0809                 probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
0810                 probeinfo->pci_addr = 0;
0811                 probeinfo->bus = bus;
0812                 probeinfo->dev = device;
0813                 probeinfo->irq_ch = irq_ch;
0814                 probeinfo->pci_device = pci_dev_get(pci_device);
0815                 break;
0816             }
0817         }
0818     }
0819     return mmcount;
0820 }
0821 
0822 
0823 /*
0824   blogic_init_fp_probeinfo initializes the list of I/O Address
0825   and Bus Probe Information to be checked for potential BusLogic FlashPoint
0826   Host Adapters by interrogating the PCI Configuration Space.  It returns the
0827   number of FlashPoint Host Adapters found.
0828 */
0829 
0830 static int __init blogic_init_fp_probeinfo(struct blogic_adapter *adapter)
0831 {
0832     int fpindex = blogic_probeinfo_count, fpcount = 0;
0833     struct pci_dev *pci_device = NULL;
0834     /*
0835        Interrogate PCI Configuration Space for any FlashPoint Host Adapters.
0836      */
0837     while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
0838                     PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
0839                     pci_device)) != NULL) {
0840         unsigned char bus;
0841         unsigned char device;
0842         unsigned int irq_ch;
0843         unsigned long base_addr0;
0844         unsigned long base_addr1;
0845         unsigned long io_addr;
0846         unsigned long pci_addr;
0847 
0848         if (pci_enable_device(pci_device))
0849             continue;
0850 
0851         if (dma_set_mask(&pci_device->dev, DMA_BIT_MASK(32)))
0852             continue;
0853 
0854         bus = pci_device->bus->number;
0855         device = pci_device->devfn >> 3;
0856         irq_ch = pci_device->irq;
0857         io_addr = base_addr0 = pci_resource_start(pci_device, 0);
0858         pci_addr = base_addr1 = pci_resource_start(pci_device, 1);
0859 #ifdef CONFIG_SCSI_FLASHPOINT
0860         if (pci_resource_flags(pci_device, 0) & IORESOURCE_MEM) {
0861             blogic_err("BusLogic: Base Address0 0x%lX not I/O for FlashPoint Host Adapter\n", NULL, base_addr0);
0862             blogic_err("at PCI Bus %d Device %d I/O Address 0x%lX\n", NULL, bus, device, io_addr);
0863             continue;
0864         }
0865         if (pci_resource_flags(pci_device, 1) & IORESOURCE_IO) {
0866             blogic_err("BusLogic: Base Address1 0x%lX not Memory for FlashPoint Host Adapter\n", NULL, base_addr1);
0867             blogic_err("at PCI Bus %d Device %d PCI Address 0x%lX\n", NULL, bus, device, pci_addr);
0868             continue;
0869         }
0870         if (irq_ch == 0) {
0871             blogic_err("BusLogic: IRQ Channel %d invalid for FlashPoint Host Adapter\n", NULL, irq_ch);
0872             blogic_err("at PCI Bus %d Device %d I/O Address 0x%lX\n", NULL, bus, device, io_addr);
0873             continue;
0874         }
0875         if (blogic_global_options.trace_probe) {
0876             blogic_notice("BusLogic: FlashPoint Host Adapter detected at\n", NULL);
0877             blogic_notice("BusLogic: PCI Bus %d Device %d I/O Address 0x%lX PCI Address 0x%lX\n", NULL, bus, device, io_addr, pci_addr);
0878         }
0879         if (blogic_probeinfo_count < BLOGIC_MAX_ADAPTERS) {
0880             struct blogic_probeinfo *probeinfo =
0881                 &blogic_probeinfo_list[blogic_probeinfo_count++];
0882             probeinfo->adapter_type = BLOGIC_FLASHPOINT;
0883             probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
0884             probeinfo->io_addr = io_addr;
0885             probeinfo->pci_addr = pci_addr;
0886             probeinfo->bus = bus;
0887             probeinfo->dev = device;
0888             probeinfo->irq_ch = irq_ch;
0889             probeinfo->pci_device = pci_dev_get(pci_device);
0890             fpcount++;
0891         } else
0892             blogic_warn("BusLogic: Too many Host Adapters detected\n", NULL);
0893 #else
0894         blogic_err("BusLogic: FlashPoint Host Adapter detected at PCI Bus %d Device %d\n", NULL, bus, device);
0895         blogic_err("BusLogic: I/O Address 0x%lX PCI Address 0x%lX, irq %d, but FlashPoint\n", NULL, io_addr, pci_addr, irq_ch);
0896         blogic_err("BusLogic: support was omitted in this kernel configuration.\n", NULL);
0897 #endif
0898     }
0899     /*
0900        The FlashPoint BIOS will scan for FlashPoint Host Adapters in the order of
0901        increasing PCI Bus and Device Number, so sort the probe information into
0902        the same order the BIOS uses.
0903      */
0904     blogic_sort_probeinfo(&blogic_probeinfo_list[fpindex], fpcount);
0905     return fpcount;
0906 }
0907 
0908 
0909 /*
0910   blogic_init_probeinfo_list initializes the list of I/O Address and Bus
0911   Probe Information to be checked for potential BusLogic SCSI Host Adapters by
0912   interrogating the PCI Configuration Space on PCI machines as well as from the
0913   list of standard BusLogic MultiMaster ISA I/O Addresses.  By default, if both
0914   FlashPoint and PCI MultiMaster Host Adapters are present, this driver will
0915   probe for FlashPoint Host Adapters first unless the BIOS primary disk is
0916   controlled by the first PCI MultiMaster Host Adapter, in which case
0917   MultiMaster Host Adapters will be probed first.  The BusLogic Driver Options
0918   specifications "MultiMasterFirst" and "FlashPointFirst" can be used to force
0919   a particular probe order.
0920 */
0921 
0922 static void __init blogic_init_probeinfo_list(struct blogic_adapter *adapter)
0923 {
0924     /*
0925        If a PCI BIOS is present, interrogate it for MultiMaster and
0926        FlashPoint Host Adapters; otherwise, default to the standard
0927        ISA MultiMaster probe.
0928      */
0929     if (!blogic_probe_options.noprobe_pci) {
0930         if (blogic_probe_options.multimaster_first) {
0931             blogic_init_mm_probeinfo(adapter);
0932             blogic_init_fp_probeinfo(adapter);
0933         } else if (blogic_probe_options.flashpoint_first) {
0934             blogic_init_fp_probeinfo(adapter);
0935             blogic_init_mm_probeinfo(adapter);
0936         } else {
0937             int fpcount = blogic_init_fp_probeinfo(adapter);
0938             int mmcount = blogic_init_mm_probeinfo(adapter);
0939             if (fpcount > 0 && mmcount > 0) {
0940                 struct blogic_probeinfo *probeinfo =
0941                     &blogic_probeinfo_list[fpcount];
0942                 struct blogic_adapter *myadapter = adapter;
0943                 struct blogic_fetch_localram fetch_localram;
0944                 struct blogic_bios_drvmap d0_mapbyte;
0945 
0946                 while (probeinfo->adapter_bus_type !=
0947                         BLOGIC_PCI_BUS)
0948                     probeinfo++;
0949                 myadapter->io_addr = probeinfo->io_addr;
0950                 fetch_localram.offset =
0951                     BLOGIC_BIOS_BASE + BLOGIC_BIOS_DRVMAP;
0952                 fetch_localram.count = sizeof(d0_mapbyte);
0953                 blogic_cmd(myadapter, BLOGIC_FETCH_LOCALRAM,
0954                         &fetch_localram,
0955                         sizeof(fetch_localram),
0956                         &d0_mapbyte,
0957                         sizeof(d0_mapbyte));
0958                 /*
0959                    If the Map Byte for BIOS Drive 0 indicates
0960                    that BIOS Drive 0 is controlled by this
0961                    PCI MultiMaster Host Adapter, then reverse
0962                    the probe order so that MultiMaster Host
0963                    Adapters are probed before FlashPoint Host
0964                    Adapters.
0965                  */
0966                 if (d0_mapbyte.diskgeom != BLOGIC_BIOS_NODISK) {
0967                     struct blogic_probeinfo saved_probeinfo[BLOGIC_MAX_ADAPTERS];
0968                     int mmcount = blogic_probeinfo_count - fpcount;
0969 
0970                     memcpy(saved_probeinfo,
0971                         blogic_probeinfo_list,
0972                         blogic_probeinfo_count * sizeof(struct blogic_probeinfo));
0973                     memcpy(&blogic_probeinfo_list[0],
0974                         &saved_probeinfo[fpcount],
0975                         mmcount * sizeof(struct blogic_probeinfo));
0976                     memcpy(&blogic_probeinfo_list[mmcount],
0977                         &saved_probeinfo[0],
0978                         fpcount * sizeof(struct blogic_probeinfo));
0979                 }
0980             }
0981         }
0982     }
0983 }
0984 
0985 
0986 /*
0987   blogic_failure prints a standardized error message, and then returns false.
0988 */
0989 
0990 static bool blogic_failure(struct blogic_adapter *adapter, char *msg)
0991 {
0992     blogic_announce_drvr(adapter);
0993     if (adapter->adapter_bus_type == BLOGIC_PCI_BUS) {
0994         blogic_err("While configuring BusLogic PCI Host Adapter at\n",
0995                 adapter);
0996         blogic_err("Bus %d Device %d I/O Address 0x%lX PCI Address 0x%lX:\n", adapter, adapter->bus, adapter->dev, adapter->io_addr, adapter->pci_addr);
0997     } else
0998         blogic_err("While configuring BusLogic Host Adapter at I/O Address 0x%lX:\n", adapter, adapter->io_addr);
0999     blogic_err("%s FAILED - DETACHING\n", adapter, msg);
1000     if (blogic_cmd_failure_reason != NULL)
1001         blogic_err("ADDITIONAL FAILURE INFO - %s\n", adapter,
1002                 blogic_cmd_failure_reason);
1003     return false;
1004 }
1005 
1006 
1007 /*
1008   blogic_probe probes for a BusLogic Host Adapter.
1009 */
1010 
1011 static bool __init blogic_probe(struct blogic_adapter *adapter)
1012 {
1013     union blogic_stat_reg statusreg;
1014     union blogic_int_reg intreg;
1015     union blogic_geo_reg georeg;
1016     /*
1017        FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager.
1018      */
1019     if (blogic_flashpoint_type(adapter)) {
1020         struct fpoint_info *fpinfo = &adapter->fpinfo;
1021         fpinfo->base_addr = (u32) adapter->io_addr;
1022         fpinfo->irq_ch = adapter->irq_ch;
1023         fpinfo->present = false;
1024         if (!(FlashPoint_ProbeHostAdapter(fpinfo) == 0 &&
1025                     fpinfo->present)) {
1026             blogic_err("BusLogic: FlashPoint Host Adapter detected at PCI Bus %d Device %d\n", adapter, adapter->bus, adapter->dev);
1027             blogic_err("BusLogic: I/O Address 0x%lX PCI Address 0x%lX, but FlashPoint\n", adapter, adapter->io_addr, adapter->pci_addr);
1028             blogic_err("BusLogic: Probe Function failed to validate it.\n", adapter);
1029             return false;
1030         }
1031         if (blogic_global_options.trace_probe)
1032             blogic_notice("BusLogic_Probe(0x%lX): FlashPoint Found\n", adapter, adapter->io_addr);
1033         /*
1034            Indicate the Host Adapter Probe completed successfully.
1035          */
1036         return true;
1037     }
1038     /*
1039        Read the Status, Interrupt, and Geometry Registers to test if there are I/O
1040        ports that respond, and to check the values to determine if they are from a
1041        BusLogic Host Adapter.  A nonexistent I/O port will return 0xFF, in which
1042        case there is definitely no BusLogic Host Adapter at this base I/O Address.
1043        The test here is a subset of that used by the BusLogic Host Adapter BIOS.
1044      */
1045     statusreg.all = blogic_rdstatus(adapter);
1046     intreg.all = blogic_rdint(adapter);
1047     georeg.all = blogic_rdgeom(adapter);
1048     if (blogic_global_options.trace_probe)
1049         blogic_notice("BusLogic_Probe(0x%lX): Status 0x%02X, Interrupt 0x%02X, Geometry 0x%02X\n", adapter, adapter->io_addr, statusreg.all, intreg.all, georeg.all);
1050     if (statusreg.all == 0 || statusreg.sr.diag_active ||
1051             statusreg.sr.cmd_param_busy || statusreg.sr.rsvd ||
1052             statusreg.sr.cmd_invalid || intreg.ir.rsvd != 0)
1053         return false;
1054     /*
1055        Check the undocumented Geometry Register to test if there is
1056        an I/O port that responded.  Adaptec Host Adapters do not
1057        implement the Geometry Register, so this test helps serve to
1058        avoid incorrectly recognizing an Adaptec 1542A or 1542B as a
1059        BusLogic.  Unfortunately, the Adaptec 1542C series does respond
1060        to the Geometry Register I/O port, but it will be rejected
1061        later when the Inquire Extended Setup Information command is
1062        issued in blogic_checkadapter.  The AMI FastDisk Host Adapter
1063        is a BusLogic clone that implements the same interface as
1064        earlier BusLogic Host Adapters, including the undocumented
1065        commands, and is therefore supported by this driver. However,
1066        the AMI FastDisk always returns 0x00 upon reading the Geometry
1067        Register, so the extended translation option should always be
1068        left disabled on the AMI FastDisk.
1069      */
1070     if (georeg.all == 0xFF)
1071         return false;
1072     /*
1073        Indicate the Host Adapter Probe completed successfully.
1074      */
1075     return true;
1076 }
1077 
1078 
1079 /*
1080   blogic_hwreset issues a Hardware Reset to the Host Adapter
1081   and waits for Host Adapter Diagnostics to complete.  If hard_reset is true, a
1082   Hard Reset is performed which also initiates a SCSI Bus Reset.  Otherwise, a
1083   Soft Reset is performed which only resets the Host Adapter without forcing a
1084   SCSI Bus Reset.
1085 */
1086 
1087 static bool blogic_hwreset(struct blogic_adapter *adapter, bool hard_reset)
1088 {
1089     union blogic_stat_reg statusreg;
1090     int timeout;
1091     /*
1092        FlashPoint Host Adapters are Hard Reset by the FlashPoint
1093        SCCB Manager.
1094      */
1095     if (blogic_flashpoint_type(adapter)) {
1096         struct fpoint_info *fpinfo = &adapter->fpinfo;
1097         fpinfo->softreset = !hard_reset;
1098         fpinfo->report_underrun = true;
1099         adapter->cardhandle =
1100             FlashPoint_HardwareResetHostAdapter(fpinfo);
1101         if (adapter->cardhandle == (void *)FPOINT_BADCARD_HANDLE)
1102             return false;
1103         /*
1104            Indicate the Host Adapter Hard Reset completed successfully.
1105          */
1106         return true;
1107     }
1108     /*
1109        Issue a Hard Reset or Soft Reset Command to the Host Adapter.
1110        The Host Adapter should respond by setting Diagnostic Active in
1111        the Status Register.
1112      */
1113     if (hard_reset)
1114         blogic_hardreset(adapter);
1115     else
1116         blogic_softreset(adapter);
1117     /*
1118        Wait until Diagnostic Active is set in the Status Register.
1119      */
1120     timeout = 5 * 10000;
1121     while (--timeout >= 0) {
1122         statusreg.all = blogic_rdstatus(adapter);
1123         if (statusreg.sr.diag_active)
1124             break;
1125         udelay(100);
1126     }
1127     if (blogic_global_options.trace_hw_reset)
1128         blogic_notice("BusLogic_HardwareReset(0x%lX): Diagnostic Active, Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
1129     if (timeout < 0)
1130         return false;
1131     /*
1132        Wait 100 microseconds to allow completion of any initial diagnostic
1133        activity which might leave the contents of the Status Register
1134        unpredictable.
1135      */
1136     udelay(100);
1137     /*
1138        Wait until Diagnostic Active is reset in the Status Register.
1139      */
1140     timeout = 10 * 10000;
1141     while (--timeout >= 0) {
1142         statusreg.all = blogic_rdstatus(adapter);
1143         if (!statusreg.sr.diag_active)
1144             break;
1145         udelay(100);
1146     }
1147     if (blogic_global_options.trace_hw_reset)
1148         blogic_notice("BusLogic_HardwareReset(0x%lX): Diagnostic Completed, Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
1149     if (timeout < 0)
1150         return false;
1151     /*
1152        Wait until at least one of the Diagnostic Failure, Host Adapter
1153        Ready, or Data In Register Ready bits is set in the Status Register.
1154      */
1155     timeout = 10000;
1156     while (--timeout >= 0) {
1157         statusreg.all = blogic_rdstatus(adapter);
1158         if (statusreg.sr.diag_failed || statusreg.sr.adapter_ready ||
1159                 statusreg.sr.datain_ready)
1160             break;
1161         udelay(100);
1162     }
1163     if (blogic_global_options.trace_hw_reset)
1164         blogic_notice("BusLogic_HardwareReset(0x%lX): Host Adapter Ready, Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
1165     if (timeout < 0)
1166         return false;
1167     /*
1168        If Diagnostic Failure is set or Host Adapter Ready is reset,
1169        then an error occurred during the Host Adapter diagnostics.
1170        If Data In Register Ready is set, then there is an Error Code
1171        available.
1172      */
1173     if (statusreg.sr.diag_failed || !statusreg.sr.adapter_ready) {
1174         blogic_cmd_failure_reason = NULL;
1175         blogic_failure(adapter, "HARD RESET DIAGNOSTICS");
1176         blogic_err("HOST ADAPTER STATUS REGISTER = %02X\n", adapter,
1177                 statusreg.all);
1178         if (statusreg.sr.datain_ready)
1179             blogic_err("HOST ADAPTER ERROR CODE = %d\n", adapter,
1180                     blogic_rddatain(adapter));
1181         return false;
1182     }
1183     /*
1184        Indicate the Host Adapter Hard Reset completed successfully.
1185      */
1186     return true;
1187 }
1188 
1189 
1190 /*
1191   blogic_checkadapter checks to be sure this really is a BusLogic
1192   Host Adapter.
1193 */
1194 
1195 static bool __init blogic_checkadapter(struct blogic_adapter *adapter)
1196 {
1197     struct blogic_ext_setup ext_setupinfo;
1198     unsigned char req_replylen;
1199     bool result = true;
1200     /*
1201        FlashPoint Host Adapters do not require this protection.
1202      */
1203     if (blogic_flashpoint_type(adapter))
1204         return true;
1205     /*
1206        Issue the Inquire Extended Setup Information command. Only genuine
1207        BusLogic Host Adapters and true clones support this command.
1208        Adaptec 1542C series Host Adapters that respond to the Geometry
1209        Register I/O port will fail this command.
1210      */
1211     req_replylen = sizeof(ext_setupinfo);
1212     if (blogic_cmd(adapter, BLOGIC_INQ_EXTSETUP, &req_replylen,
1213                 sizeof(req_replylen), &ext_setupinfo,
1214                 sizeof(ext_setupinfo)) != sizeof(ext_setupinfo))
1215         result = false;
1216     /*
1217        Provide tracing information if requested and return.
1218      */
1219     if (blogic_global_options.trace_probe)
1220         blogic_notice("BusLogic_Check(0x%lX): MultiMaster %s\n", adapter,
1221                 adapter->io_addr,
1222                 (result ? "Found" : "Not Found"));
1223     return result;
1224 }
1225 
1226 
1227 /*
1228   blogic_rdconfig reads the Configuration Information
1229   from Host Adapter and initializes the Host Adapter structure.
1230 */
1231 
1232 static bool __init blogic_rdconfig(struct blogic_adapter *adapter)
1233 {
1234     struct blogic_board_id id;
1235     struct blogic_config config;
1236     struct blogic_setup_info setupinfo;
1237     struct blogic_ext_setup ext_setupinfo;
1238     unsigned char model[5];
1239     unsigned char fw_ver_digit3;
1240     unsigned char fw_ver_letter;
1241     struct blogic_adapter_info adapter_info;
1242     struct blogic_fetch_localram fetch_localram;
1243     struct blogic_autoscsi autoscsi;
1244     union blogic_geo_reg georeg;
1245     unsigned char req_replylen;
1246     unsigned char *tgt, ch;
1247     int tgt_id, i;
1248     /*
1249        Configuration Information for FlashPoint Host Adapters is
1250        provided in the fpoint_info structure by the FlashPoint
1251        SCCB Manager's Probe Function. Initialize fields in the
1252        Host Adapter structure from the fpoint_info structure.
1253      */
1254     if (blogic_flashpoint_type(adapter)) {
1255         struct fpoint_info *fpinfo = &adapter->fpinfo;
1256         tgt = adapter->model;
1257         *tgt++ = 'B';
1258         *tgt++ = 'T';
1259         *tgt++ = '-';
1260         for (i = 0; i < sizeof(fpinfo->model); i++)
1261             *tgt++ = fpinfo->model[i];
1262         *tgt++ = '\0';
1263         strcpy(adapter->fw_ver, FLASHPOINT_FW_VER);
1264         adapter->scsi_id = fpinfo->scsi_id;
1265         adapter->ext_trans_enable = fpinfo->ext_trans_enable;
1266         adapter->parity = fpinfo->parity;
1267         adapter->reset_enabled = !fpinfo->softreset;
1268         adapter->level_int = true;
1269         adapter->wide = fpinfo->wide;
1270         adapter->differential = false;
1271         adapter->scam = true;
1272         adapter->ultra = true;
1273         adapter->ext_lun = true;
1274         adapter->terminfo_valid = true;
1275         adapter->low_term = fpinfo->low_term;
1276         adapter->high_term = fpinfo->high_term;
1277         adapter->scam_enabled = fpinfo->scam_enabled;
1278         adapter->scam_lev2 = fpinfo->scam_lev2;
1279         adapter->drvr_sglimit = BLOGIC_SG_LIMIT;
1280         adapter->maxdev = (adapter->wide ? 16 : 8);
1281         adapter->maxlun = 32;
1282         adapter->initccbs = 4 * BLOGIC_CCB_GRP_ALLOCSIZE;
1283         adapter->inc_ccbs = BLOGIC_CCB_GRP_ALLOCSIZE;
1284         adapter->drvr_qdepth = 255;
1285         adapter->adapter_qdepth = adapter->drvr_qdepth;
1286         adapter->sync_ok = fpinfo->sync_ok;
1287         adapter->fast_ok = fpinfo->fast_ok;
1288         adapter->ultra_ok = fpinfo->ultra_ok;
1289         adapter->wide_ok = fpinfo->wide_ok;
1290         adapter->discon_ok = fpinfo->discon_ok;
1291         adapter->tagq_ok = 0xFFFF;
1292         goto common;
1293     }
1294     /*
1295        Issue the Inquire Board ID command.
1296      */
1297     if (blogic_cmd(adapter, BLOGIC_GET_BOARD_ID, NULL, 0, &id,
1298                 sizeof(id)) != sizeof(id))
1299         return blogic_failure(adapter, "INQUIRE BOARD ID");
1300     /*
1301        Issue the Inquire Configuration command.
1302      */
1303     if (blogic_cmd(adapter, BLOGIC_INQ_CONFIG, NULL, 0, &config,
1304                 sizeof(config))
1305         != sizeof(config))
1306         return blogic_failure(adapter, "INQUIRE CONFIGURATION");
1307     /*
1308        Issue the Inquire Setup Information command.
1309      */
1310     req_replylen = sizeof(setupinfo);
1311     if (blogic_cmd(adapter, BLOGIC_INQ_SETUPINFO, &req_replylen,
1312                 sizeof(req_replylen), &setupinfo,
1313                 sizeof(setupinfo)) != sizeof(setupinfo))
1314         return blogic_failure(adapter, "INQUIRE SETUP INFORMATION");
1315     /*
1316        Issue the Inquire Extended Setup Information command.
1317      */
1318     req_replylen = sizeof(ext_setupinfo);
1319     if (blogic_cmd(adapter, BLOGIC_INQ_EXTSETUP, &req_replylen,
1320                 sizeof(req_replylen), &ext_setupinfo,
1321                 sizeof(ext_setupinfo)) != sizeof(ext_setupinfo))
1322         return blogic_failure(adapter,
1323                     "INQUIRE EXTENDED SETUP INFORMATION");
1324     /*
1325        Issue the Inquire Firmware Version 3rd Digit command.
1326      */
1327     fw_ver_digit3 = '\0';
1328     if (id.fw_ver_digit1 > '0')
1329         if (blogic_cmd(adapter, BLOGIC_INQ_FWVER_D3, NULL, 0,
1330                 &fw_ver_digit3,
1331                 sizeof(fw_ver_digit3)) != sizeof(fw_ver_digit3))
1332             return blogic_failure(adapter,
1333                         "INQUIRE FIRMWARE 3RD DIGIT");
1334     /*
1335        Issue the Inquire Host Adapter Model Number command.
1336      */
1337     if (ext_setupinfo.bus_type == 'A' && id.fw_ver_digit1 == '2')
1338         /* BusLogic BT-542B ISA 2.xx */
1339         strcpy(model, "542B");
1340     else if (ext_setupinfo.bus_type == 'E' && id.fw_ver_digit1 == '2' &&
1341             (id.fw_ver_digit2 <= '1' || (id.fw_ver_digit2 == '2' &&
1342                              fw_ver_digit3 == '0')))
1343         /* BusLogic BT-742A EISA 2.1x or 2.20 */
1344         strcpy(model, "742A");
1345     else if (ext_setupinfo.bus_type == 'E' && id.fw_ver_digit1 == '0')
1346         /* AMI FastDisk EISA Series 441 0.x */
1347         strcpy(model, "747A");
1348     else {
1349         req_replylen = sizeof(model);
1350         if (blogic_cmd(adapter, BLOGIC_INQ_MODELNO, &req_replylen,
1351                     sizeof(req_replylen), &model,
1352                     sizeof(model)) != sizeof(model))
1353             return blogic_failure(adapter,
1354                     "INQUIRE HOST ADAPTER MODEL NUMBER");
1355     }
1356     /*
1357        BusLogic MultiMaster Host Adapters can be identified by their
1358        model number and the major version number of their firmware
1359        as follows:
1360 
1361        5.xx       BusLogic "W" Series Host Adapters:
1362        BT-948/958/958D
1363        4.xx       BusLogic "C" Series Host Adapters:
1364        BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
1365        3.xx       BusLogic "S" Series Host Adapters:
1366        BT-747S/747D/757S/757D/445S/545S/542D
1367        BT-542B/742A (revision H)
1368        2.xx       BusLogic "A" Series Host Adapters:
1369        BT-542B/742A (revision G and below)
1370        0.xx       AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
1371      */
1372     /*
1373        Save the Model Name and Host Adapter Name in the Host Adapter
1374        structure.
1375      */
1376     tgt = adapter->model;
1377     *tgt++ = 'B';
1378     *tgt++ = 'T';
1379     *tgt++ = '-';
1380     for (i = 0; i < sizeof(model); i++) {
1381         ch = model[i];
1382         if (ch == ' ' || ch == '\0')
1383             break;
1384         *tgt++ = ch;
1385     }
1386     *tgt++ = '\0';
1387     /*
1388        Save the Firmware Version in the Host Adapter structure.
1389      */
1390     tgt = adapter->fw_ver;
1391     *tgt++ = id.fw_ver_digit1;
1392     *tgt++ = '.';
1393     *tgt++ = id.fw_ver_digit2;
1394     if (fw_ver_digit3 != ' ' && fw_ver_digit3 != '\0')
1395         *tgt++ = fw_ver_digit3;
1396     *tgt = '\0';
1397     /*
1398        Issue the Inquire Firmware Version Letter command.
1399      */
1400     if (strcmp(adapter->fw_ver, "3.3") >= 0) {
1401         if (blogic_cmd(adapter, BLOGIC_INQ_FWVER_LETTER, NULL, 0,
1402                 &fw_ver_letter,
1403                 sizeof(fw_ver_letter)) != sizeof(fw_ver_letter))
1404             return blogic_failure(adapter,
1405                     "INQUIRE FIRMWARE VERSION LETTER");
1406         if (fw_ver_letter != ' ' && fw_ver_letter != '\0')
1407             *tgt++ = fw_ver_letter;
1408         *tgt = '\0';
1409     }
1410     /*
1411        Save the Host Adapter SCSI ID in the Host Adapter structure.
1412      */
1413     adapter->scsi_id = config.id;
1414     /*
1415        Determine the Bus Type and save it in the Host Adapter structure,
1416        determine and save the IRQ Channel if necessary, and determine
1417        and save the DMA Channel for ISA Host Adapters.
1418      */
1419     adapter->adapter_bus_type =
1420             blogic_adater_bus_types[adapter->model[3] - '4'];
1421     if (adapter->irq_ch == 0) {
1422         if (config.irq_ch9)
1423             adapter->irq_ch = 9;
1424         else if (config.irq_ch10)
1425             adapter->irq_ch = 10;
1426         else if (config.irq_ch11)
1427             adapter->irq_ch = 11;
1428         else if (config.irq_ch12)
1429             adapter->irq_ch = 12;
1430         else if (config.irq_ch14)
1431             adapter->irq_ch = 14;
1432         else if (config.irq_ch15)
1433             adapter->irq_ch = 15;
1434     }
1435     /*
1436        Determine whether Extended Translation is enabled and save it in
1437        the Host Adapter structure.
1438      */
1439     georeg.all = blogic_rdgeom(adapter);
1440     adapter->ext_trans_enable = georeg.gr.ext_trans_enable;
1441     /*
1442        Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide
1443        SCSI flag, Differential SCSI flag, SCAM Supported flag, and
1444        Ultra SCSI flag in the Host Adapter structure.
1445      */
1446     adapter->adapter_sglimit = ext_setupinfo.sg_limit;
1447     adapter->drvr_sglimit = adapter->adapter_sglimit;
1448     if (adapter->adapter_sglimit > BLOGIC_SG_LIMIT)
1449         adapter->drvr_sglimit = BLOGIC_SG_LIMIT;
1450     if (ext_setupinfo.misc.level_int)
1451         adapter->level_int = true;
1452     adapter->wide = ext_setupinfo.wide;
1453     adapter->differential = ext_setupinfo.differential;
1454     adapter->scam = ext_setupinfo.scam;
1455     adapter->ultra = ext_setupinfo.ultra;
1456     /*
1457        Determine whether Extended LUN Format CCBs are supported and save the
1458        information in the Host Adapter structure.
1459      */
1460     if (adapter->fw_ver[0] == '5' || (adapter->fw_ver[0] == '4' &&
1461                 adapter->wide))
1462         adapter->ext_lun = true;
1463     /*
1464        Issue the Inquire PCI Host Adapter Information command to read the
1465        Termination Information from "W" series MultiMaster Host Adapters.
1466      */
1467     if (adapter->fw_ver[0] == '5') {
1468         if (blogic_cmd(adapter, BLOGIC_INQ_PCI_INFO, NULL, 0,
1469                 &adapter_info,
1470                 sizeof(adapter_info)) != sizeof(adapter_info))
1471             return blogic_failure(adapter,
1472                     "INQUIRE PCI HOST ADAPTER INFORMATION");
1473         /*
1474            Save the Termination Information in the Host Adapter
1475            structure.
1476          */
1477         if (adapter_info.genericinfo_valid) {
1478             adapter->terminfo_valid = true;
1479             adapter->low_term = adapter_info.low_term;
1480             adapter->high_term = adapter_info.high_term;
1481         }
1482     }
1483     /*
1484        Issue the Fetch Host Adapter Local RAM command to read the
1485        AutoSCSI data from "W" and "C" series MultiMaster Host Adapters.
1486      */
1487     if (adapter->fw_ver[0] >= '4') {
1488         fetch_localram.offset = BLOGIC_AUTOSCSI_BASE;
1489         fetch_localram.count = sizeof(autoscsi);
1490         if (blogic_cmd(adapter, BLOGIC_FETCH_LOCALRAM, &fetch_localram,
1491                     sizeof(fetch_localram), &autoscsi,
1492                     sizeof(autoscsi)) != sizeof(autoscsi))
1493             return blogic_failure(adapter,
1494                         "FETCH HOST ADAPTER LOCAL RAM");
1495         /*
1496            Save the Parity Checking Enabled, Bus Reset Enabled,
1497            and Termination Information in the Host Adapter structure.
1498          */
1499         adapter->parity = autoscsi.parity;
1500         adapter->reset_enabled = autoscsi.reset_enabled;
1501         if (adapter->fw_ver[0] == '4') {
1502             adapter->terminfo_valid = true;
1503             adapter->low_term = autoscsi.low_term;
1504             adapter->high_term = autoscsi.high_term;
1505         }
1506         /*
1507            Save the Wide Permitted, Fast Permitted, Synchronous
1508            Permitted, Disconnect Permitted, Ultra Permitted, and
1509            SCAM Information in the Host Adapter structure.
1510          */
1511         adapter->wide_ok = autoscsi.wide_ok;
1512         adapter->fast_ok = autoscsi.fast_ok;
1513         adapter->sync_ok = autoscsi.sync_ok;
1514         adapter->discon_ok = autoscsi.discon_ok;
1515         if (adapter->ultra)
1516             adapter->ultra_ok = autoscsi.ultra_ok;
1517         if (adapter->scam) {
1518             adapter->scam_enabled = autoscsi.scam_enabled;
1519             adapter->scam_lev2 = autoscsi.scam_lev2;
1520         }
1521     }
1522     /*
1523        Initialize fields in the Host Adapter structure for "S" and "A"
1524        series MultiMaster Host Adapters.
1525      */
1526     if (adapter->fw_ver[0] < '4') {
1527         if (setupinfo.sync) {
1528             adapter->sync_ok = 0xFF;
1529             if (adapter->adapter_bus_type == BLOGIC_EISA_BUS) {
1530                 if (ext_setupinfo.misc.fast_on_eisa)
1531                     adapter->fast_ok = 0xFF;
1532                 if (strcmp(adapter->model, "BT-757") == 0)
1533                     adapter->wide_ok = 0xFF;
1534             }
1535         }
1536         adapter->discon_ok = 0xFF;
1537         adapter->parity = setupinfo.parity;
1538         adapter->reset_enabled = true;
1539     }
1540     /*
1541        Determine the maximum number of Target IDs and Logical Units
1542        supported by this driver for Wide and Narrow Host Adapters.
1543      */
1544     adapter->maxdev = (adapter->wide ? 16 : 8);
1545     adapter->maxlun = (adapter->ext_lun ? 32 : 8);
1546     /*
1547        Select appropriate values for the Mailbox Count, Driver Queue Depth,
1548        Initial CCBs, and Incremental CCBs variables based on whether
1549        or not Strict Round Robin Mode is supported.  If Strict Round
1550        Robin Mode is supported, then there is no performance degradation
1551        in using the maximum possible number of Outgoing and Incoming
1552        Mailboxes and allowing the Tagged and Untagged Queue Depths to
1553        determine the actual utilization.  If Strict Round Robin Mode is
1554        not supported, then the Host Adapter must scan all the Outgoing
1555        Mailboxes whenever an Outgoing Mailbox entry is made, which can
1556        cause a substantial performance penalty.  The host adapters
1557        actually have room to store the following number of CCBs
1558        internally; that is, they can internally queue and manage this
1559        many active commands on the SCSI bus simultaneously.  Performance
1560        measurements demonstrate that the Driver Queue Depth should be
1561        set to the Mailbox Count, rather than the Host Adapter Queue
1562        Depth (internal CCB capacity), as it is more efficient to have the
1563        queued commands waiting in Outgoing Mailboxes if necessary than
1564        to block the process in the higher levels of the SCSI Subsystem.
1565 
1566        192          BT-948/958/958D
1567        100          BT-946C/956C/956CD/747C/757C/757CD/445C
1568        50   BT-545C/540CF
1569        30   BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
1570      */
1571     if (adapter->fw_ver[0] == '5')
1572         adapter->adapter_qdepth = 192;
1573     else if (adapter->fw_ver[0] == '4')
1574         adapter->adapter_qdepth = 100;
1575     else
1576         adapter->adapter_qdepth = 30;
1577     if (strcmp(adapter->fw_ver, "3.31") >= 0) {
1578         adapter->strict_rr = true;
1579         adapter->mbox_count = BLOGIC_MAX_MAILBOX;
1580     } else {
1581         adapter->strict_rr = false;
1582         adapter->mbox_count = 32;
1583     }
1584     adapter->drvr_qdepth = adapter->mbox_count;
1585     adapter->initccbs = 4 * BLOGIC_CCB_GRP_ALLOCSIZE;
1586     adapter->inc_ccbs = BLOGIC_CCB_GRP_ALLOCSIZE;
1587     /*
1588        Tagged Queuing support is available and operates properly on
1589        all "W" series MultiMaster Host Adapters, on "C" series
1590        MultiMaster Host Adapters with firmware version 4.22 and above,
1591        and on "S" series MultiMaster Host Adapters with firmware version
1592        3.35 and above.
1593      */
1594     adapter->tagq_ok = 0;
1595     switch (adapter->fw_ver[0]) {
1596     case '5':
1597         adapter->tagq_ok = 0xFFFF;
1598         break;
1599     case '4':
1600         if (strcmp(adapter->fw_ver, "4.22") >= 0)
1601             adapter->tagq_ok = 0xFFFF;
1602         break;
1603     case '3':
1604         if (strcmp(adapter->fw_ver, "3.35") >= 0)
1605             adapter->tagq_ok = 0xFFFF;
1606         break;
1607     }
1608     /*
1609        Determine the Host Adapter BIOS Address if the BIOS is enabled and
1610        save it in the Host Adapter structure.  The BIOS is disabled if the
1611        bios_addr is 0.
1612      */
1613     adapter->bios_addr = ext_setupinfo.bios_addr << 12;
1614     /*
1615        BusLogic BT-445S Host Adapters prior to board revision E have a
1616        hardware bug whereby when the BIOS is enabled, transfers to/from
1617        the same address range the BIOS occupies modulo 16MB are handled
1618        incorrectly.  Only properly functioning BT-445S Host Adapters
1619        have firmware version 3.37.
1620      */
1621     if (adapter->bios_addr > 0 &&
1622         strcmp(adapter->model, "BT-445S") == 0 &&
1623         strcmp(adapter->fw_ver, "3.37") < 0)
1624         return blogic_failure(adapter, "Too old firmware");
1625     /*
1626        Initialize parameters common to MultiMaster and FlashPoint
1627        Host Adapters.
1628      */
1629 common:
1630     /*
1631        Initialize the Host Adapter Full Model Name from the Model Name.
1632      */
1633     strcpy(adapter->full_model, "BusLogic ");
1634     strcat(adapter->full_model, adapter->model);
1635     /*
1636        Select an appropriate value for the Tagged Queue Depth either from a
1637        BusLogic Driver Options specification, or based on whether this Host
1638        Adapter requires that ISA Bounce Buffers be used.  The Tagged Queue
1639        Depth is left at 0 for automatic determination in
1640        BusLogic_SelectQueueDepths. Initialize the Untagged Queue Depth.
1641      */
1642     for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++) {
1643         unsigned char qdepth = 0;
1644         if (adapter->drvr_opts != NULL &&
1645                 adapter->drvr_opts->qdepth[tgt_id] > 0)
1646             qdepth = adapter->drvr_opts->qdepth[tgt_id];
1647         adapter->qdepth[tgt_id] = qdepth;
1648     }
1649     adapter->untag_qdepth = BLOGIC_UNTAG_DEPTH;
1650     if (adapter->drvr_opts != NULL)
1651         adapter->common_qdepth = adapter->drvr_opts->common_qdepth;
1652     if (adapter->common_qdepth > 0 &&
1653             adapter->common_qdepth < adapter->untag_qdepth)
1654         adapter->untag_qdepth = adapter->common_qdepth;
1655     /*
1656        Tagged Queuing is only allowed if Disconnect/Reconnect is permitted.
1657        Therefore, mask the Tagged Queuing Permitted Default bits with the
1658        Disconnect/Reconnect Permitted bits.
1659      */
1660     adapter->tagq_ok &= adapter->discon_ok;
1661     /*
1662        Combine the default Tagged Queuing Permitted bits with any
1663        BusLogic Driver Options Tagged Queuing specification.
1664      */
1665     if (adapter->drvr_opts != NULL)
1666         adapter->tagq_ok = (adapter->drvr_opts->tagq_ok &
1667                 adapter->drvr_opts->tagq_ok_mask) |
1668             (adapter->tagq_ok & ~adapter->drvr_opts->tagq_ok_mask);
1669 
1670     /*
1671        Select an appropriate value for Bus Settle Time either from a
1672        BusLogic Driver Options specification, or from
1673        BLOGIC_BUS_SETTLE_TIME.
1674      */
1675     if (adapter->drvr_opts != NULL &&
1676             adapter->drvr_opts->bus_settle_time > 0)
1677         adapter->bus_settle_time = adapter->drvr_opts->bus_settle_time;
1678     else
1679         adapter->bus_settle_time = BLOGIC_BUS_SETTLE_TIME;
1680     /*
1681        Indicate reading the Host Adapter Configuration completed
1682        successfully.
1683      */
1684     return true;
1685 }
1686 
1687 
1688 /*
1689   blogic_reportconfig reports the configuration of Host Adapter.
1690 */
1691 
1692 static bool __init blogic_reportconfig(struct blogic_adapter *adapter)
1693 {
1694     unsigned short alltgt_mask = (1 << adapter->maxdev) - 1;
1695     unsigned short sync_ok, fast_ok;
1696     unsigned short ultra_ok, wide_ok;
1697     unsigned short discon_ok, tagq_ok;
1698     bool common_syncneg, common_tagq_depth;
1699     char syncstr[BLOGIC_MAXDEV + 1];
1700     char widestr[BLOGIC_MAXDEV + 1];
1701     char discon_str[BLOGIC_MAXDEV + 1];
1702     char tagq_str[BLOGIC_MAXDEV + 1];
1703     char *syncmsg = syncstr;
1704     char *widemsg = widestr;
1705     char *discon_msg = discon_str;
1706     char *tagq_msg = tagq_str;
1707     int tgt_id;
1708 
1709     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" : ""));
1710     blogic_info("  Firmware Version: %s, I/O Address: 0x%lX, IRQ Channel: %d/%s\n", adapter, adapter->fw_ver, adapter->io_addr, adapter->irq_ch, (adapter->level_int ? "Level" : "Edge"));
1711     if (adapter->adapter_bus_type != BLOGIC_PCI_BUS) {
1712         blogic_info("  DMA Channel: None, ", adapter);
1713         if (adapter->bios_addr > 0)
1714             blogic_info("BIOS Address: 0x%X, ", adapter,
1715                     adapter->bios_addr);
1716         else
1717             blogic_info("BIOS Address: None, ", adapter);
1718     } else {
1719         blogic_info("  PCI Bus: %d, Device: %d, Address: ", adapter,
1720                 adapter->bus, adapter->dev);
1721         if (adapter->pci_addr > 0)
1722             blogic_info("0x%lX, ", adapter, adapter->pci_addr);
1723         else
1724             blogic_info("Unassigned, ", adapter);
1725     }
1726     blogic_info("Host Adapter SCSI ID: %d\n", adapter, adapter->scsi_id);
1727     blogic_info("  Parity Checking: %s, Extended Translation: %s\n",
1728             adapter, (adapter->parity ? "Enabled" : "Disabled"),
1729             (adapter->ext_trans_enable ? "Enabled" : "Disabled"));
1730     alltgt_mask &= ~(1 << adapter->scsi_id);
1731     sync_ok = adapter->sync_ok & alltgt_mask;
1732     fast_ok = adapter->fast_ok & alltgt_mask;
1733     ultra_ok = adapter->ultra_ok & alltgt_mask;
1734     if ((blogic_multimaster_type(adapter) &&
1735             (adapter->fw_ver[0] >= '4' ||
1736              adapter->adapter_bus_type == BLOGIC_EISA_BUS)) ||
1737             blogic_flashpoint_type(adapter)) {
1738         common_syncneg = false;
1739         if (sync_ok == 0) {
1740             syncmsg = "Disabled";
1741             common_syncneg = true;
1742         } else if (sync_ok == alltgt_mask) {
1743             if (fast_ok == 0) {
1744                 syncmsg = "Slow";
1745                 common_syncneg = true;
1746             } else if (fast_ok == alltgt_mask) {
1747                 if (ultra_ok == 0) {
1748                     syncmsg = "Fast";
1749                     common_syncneg = true;
1750                 } else if (ultra_ok == alltgt_mask) {
1751                     syncmsg = "Ultra";
1752                     common_syncneg = true;
1753                 }
1754             }
1755         }
1756         if (!common_syncneg) {
1757             for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
1758                 syncstr[tgt_id] = ((!(sync_ok & (1 << tgt_id))) ? 'N' : (!(fast_ok & (1 << tgt_id)) ? 'S' : (!(ultra_ok & (1 << tgt_id)) ? 'F' : 'U')));
1759             syncstr[adapter->scsi_id] = '#';
1760             syncstr[adapter->maxdev] = '\0';
1761         }
1762     } else
1763         syncmsg = (sync_ok == 0 ? "Disabled" : "Enabled");
1764     wide_ok = adapter->wide_ok & alltgt_mask;
1765     if (wide_ok == 0)
1766         widemsg = "Disabled";
1767     else if (wide_ok == alltgt_mask)
1768         widemsg = "Enabled";
1769     else {
1770         for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
1771             widestr[tgt_id] = ((wide_ok & (1 << tgt_id)) ? 'Y' : 'N');
1772         widestr[adapter->scsi_id] = '#';
1773         widestr[adapter->maxdev] = '\0';
1774     }
1775     discon_ok = adapter->discon_ok & alltgt_mask;
1776     if (discon_ok == 0)
1777         discon_msg = "Disabled";
1778     else if (discon_ok == alltgt_mask)
1779         discon_msg = "Enabled";
1780     else {
1781         for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
1782             discon_str[tgt_id] = ((discon_ok & (1 << tgt_id)) ? 'Y' : 'N');
1783         discon_str[adapter->scsi_id] = '#';
1784         discon_str[adapter->maxdev] = '\0';
1785     }
1786     tagq_ok = adapter->tagq_ok & alltgt_mask;
1787     if (tagq_ok == 0)
1788         tagq_msg = "Disabled";
1789     else if (tagq_ok == alltgt_mask)
1790         tagq_msg = "Enabled";
1791     else {
1792         for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
1793             tagq_str[tgt_id] = ((tagq_ok & (1 << tgt_id)) ? 'Y' : 'N');
1794         tagq_str[adapter->scsi_id] = '#';
1795         tagq_str[adapter->maxdev] = '\0';
1796     }
1797     blogic_info("  Synchronous Negotiation: %s, Wide Negotiation: %s\n",
1798             adapter, syncmsg, widemsg);
1799     blogic_info("  Disconnect/Reconnect: %s, Tagged Queuing: %s\n", adapter,
1800             discon_msg, tagq_msg);
1801     if (blogic_multimaster_type(adapter)) {
1802         blogic_info("  Scatter/Gather Limit: %d of %d segments, Mailboxes: %d\n", adapter, adapter->drvr_sglimit, adapter->adapter_sglimit, adapter->mbox_count);
1803         blogic_info("  Driver Queue Depth: %d, Host Adapter Queue Depth: %d\n", adapter, adapter->drvr_qdepth, adapter->adapter_qdepth);
1804     } else
1805         blogic_info("  Driver Queue Depth: %d, Scatter/Gather Limit: %d segments\n", adapter, adapter->drvr_qdepth, adapter->drvr_sglimit);
1806     blogic_info("  Tagged Queue Depth: ", adapter);
1807     common_tagq_depth = true;
1808     for (tgt_id = 1; tgt_id < adapter->maxdev; tgt_id++)
1809         if (adapter->qdepth[tgt_id] != adapter->qdepth[0]) {
1810             common_tagq_depth = false;
1811             break;
1812         }
1813     if (common_tagq_depth) {
1814         if (adapter->qdepth[0] > 0)
1815             blogic_info("%d", adapter, adapter->qdepth[0]);
1816         else
1817             blogic_info("Automatic", adapter);
1818     } else
1819         blogic_info("Individual", adapter);
1820     blogic_info(", Untagged Queue Depth: %d\n", adapter,
1821             adapter->untag_qdepth);
1822     if (adapter->terminfo_valid) {
1823         if (adapter->wide)
1824             blogic_info("  SCSI Bus Termination: %s", adapter,
1825                 (adapter->low_term ? (adapter->high_term ? "Both Enabled" : "Low Enabled") : (adapter->high_term ? "High Enabled" : "Both Disabled")));
1826         else
1827             blogic_info("  SCSI Bus Termination: %s", adapter,
1828                 (adapter->low_term ? "Enabled" : "Disabled"));
1829         if (adapter->scam)
1830             blogic_info(", SCAM: %s", adapter,
1831                 (adapter->scam_enabled ? (adapter->scam_lev2 ? "Enabled, Level 2" : "Enabled, Level 1") : "Disabled"));
1832         blogic_info("\n", adapter);
1833     }
1834     /*
1835        Indicate reporting the Host Adapter configuration completed
1836        successfully.
1837      */
1838     return true;
1839 }
1840 
1841 
1842 /*
1843   blogic_getres acquires the system resources necessary to use
1844   Host Adapter.
1845 */
1846 
1847 static bool __init blogic_getres(struct blogic_adapter *adapter)
1848 {
1849     if (adapter->irq_ch == 0) {
1850         blogic_err("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n",
1851                 adapter);
1852         return false;
1853     }
1854     /*
1855        Acquire shared access to the IRQ Channel.
1856      */
1857     if (request_irq(adapter->irq_ch, blogic_inthandler, IRQF_SHARED,
1858                 adapter->full_model, adapter) < 0) {
1859         blogic_err("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
1860                 adapter, adapter->irq_ch);
1861         return false;
1862     }
1863     adapter->irq_acquired = true;
1864     /*
1865        Indicate the System Resource Acquisition completed successfully,
1866      */
1867     return true;
1868 }
1869 
1870 
1871 /*
1872   blogic_relres releases any system resources previously acquired
1873   by blogic_getres.
1874 */
1875 
1876 static void blogic_relres(struct blogic_adapter *adapter)
1877 {
1878     /*
1879        Release shared access to the IRQ Channel.
1880      */
1881     if (adapter->irq_acquired)
1882         free_irq(adapter->irq_ch, adapter);
1883     /*
1884        Release any allocated memory structs not released elsewhere
1885      */
1886     if (adapter->mbox_space)
1887         dma_free_coherent(&adapter->pci_device->dev, adapter->mbox_sz,
1888             adapter->mbox_space, adapter->mbox_space_handle);
1889     pci_dev_put(adapter->pci_device);
1890     adapter->mbox_space = NULL;
1891     adapter->mbox_space_handle = 0;
1892     adapter->mbox_sz = 0;
1893 }
1894 
1895 
1896 /*
1897   blogic_initadapter initializes Host Adapter.  This is the only
1898   function called during SCSI Host Adapter detection which modifies the state
1899   of the Host Adapter from its initial power on or hard reset state.
1900 */
1901 
1902 static bool blogic_initadapter(struct blogic_adapter *adapter)
1903 {
1904     struct blogic_extmbox_req extmbox_req;
1905     enum blogic_rr_req rr_req;
1906     enum blogic_setccb_fmt setccb_fmt;
1907     int tgt_id;
1908 
1909     /*
1910        Initialize the pointers to the first and last CCBs that are
1911        queued for completion processing.
1912      */
1913     adapter->firstccb = NULL;
1914     adapter->lastccb = NULL;
1915 
1916     /*
1917        Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active,
1918        Command Successful Flag, Active Commands, and Commands Since Reset
1919        for each Target Device.
1920      */
1921     for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) {
1922         adapter->bdr_pend[tgt_id] = NULL;
1923         adapter->tgt_flags[tgt_id].tagq_active = false;
1924         adapter->tgt_flags[tgt_id].cmd_good = false;
1925         adapter->active_cmds[tgt_id] = 0;
1926         adapter->cmds_since_rst[tgt_id] = 0;
1927     }
1928 
1929     /*
1930        FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes.
1931      */
1932     if (blogic_flashpoint_type(adapter))
1933         goto done;
1934 
1935     /*
1936        Initialize the Outgoing and Incoming Mailbox pointers.
1937      */
1938     adapter->mbox_sz = adapter->mbox_count * (sizeof(struct blogic_outbox) + sizeof(struct blogic_inbox));
1939     adapter->mbox_space = dma_alloc_coherent(&adapter->pci_device->dev,
1940                 adapter->mbox_sz, &adapter->mbox_space_handle,
1941                 GFP_KERNEL);
1942     if (adapter->mbox_space == NULL)
1943         return blogic_failure(adapter, "MAILBOX ALLOCATION");
1944     adapter->first_outbox = (struct blogic_outbox *) adapter->mbox_space;
1945     adapter->last_outbox = adapter->first_outbox + adapter->mbox_count - 1;
1946     adapter->next_outbox = adapter->first_outbox;
1947     adapter->first_inbox = (struct blogic_inbox *) (adapter->last_outbox + 1);
1948     adapter->last_inbox = adapter->first_inbox + adapter->mbox_count - 1;
1949     adapter->next_inbox = adapter->first_inbox;
1950 
1951     /*
1952        Initialize the Outgoing and Incoming Mailbox structures.
1953      */
1954     memset(adapter->first_outbox, 0,
1955             adapter->mbox_count * sizeof(struct blogic_outbox));
1956     memset(adapter->first_inbox, 0,
1957             adapter->mbox_count * sizeof(struct blogic_inbox));
1958 
1959     /*
1960        Initialize the Host Adapter's Pointer to the Outgoing/Incoming
1961        Mailboxes.
1962      */
1963     extmbox_req.mbox_count = adapter->mbox_count;
1964     extmbox_req.base_mbox_addr = (u32) adapter->mbox_space_handle;
1965     if (blogic_cmd(adapter, BLOGIC_INIT_EXT_MBOX, &extmbox_req,
1966                 sizeof(extmbox_req), NULL, 0) < 0)
1967         return blogic_failure(adapter, "MAILBOX INITIALIZATION");
1968     /*
1969        Enable Strict Round Robin Mode if supported by the Host Adapter. In
1970        Strict Round Robin Mode, the Host Adapter only looks at the next
1971        Outgoing Mailbox for each new command, rather than scanning
1972        through all the Outgoing Mailboxes to find any that have new
1973        commands in them.  Strict Round Robin Mode is significantly more
1974        efficient.
1975      */
1976     if (adapter->strict_rr) {
1977         rr_req = BLOGIC_STRICT_RR_MODE;
1978         if (blogic_cmd(adapter, BLOGIC_STRICT_RR, &rr_req,
1979                     sizeof(rr_req), NULL, 0) < 0)
1980             return blogic_failure(adapter,
1981                     "ENABLE STRICT ROUND ROBIN MODE");
1982     }
1983 
1984     /*
1985        For Host Adapters that support Extended LUN Format CCBs, issue the
1986        Set CCB Format command to allow 32 Logical Units per Target Device.
1987      */
1988     if (adapter->ext_lun) {
1989         setccb_fmt = BLOGIC_EXT_LUN_CCB;
1990         if (blogic_cmd(adapter, BLOGIC_SETCCB_FMT, &setccb_fmt,
1991                     sizeof(setccb_fmt), NULL, 0) < 0)
1992             return blogic_failure(adapter, "SET CCB FORMAT");
1993     }
1994 
1995     /*
1996        Announce Successful Initialization.
1997      */
1998 done:
1999     if (!adapter->adapter_initd) {
2000         blogic_info("*** %s Initialized Successfully ***\n", adapter,
2001                 adapter->full_model);
2002         blogic_info("\n", adapter);
2003     } else
2004         blogic_warn("*** %s Initialized Successfully ***\n", adapter,
2005                 adapter->full_model);
2006     adapter->adapter_initd = true;
2007 
2008     /*
2009        Indicate the Host Adapter Initialization completed successfully.
2010      */
2011     return true;
2012 }
2013 
2014 
2015 /*
2016   blogic_inquiry inquires about the Target Devices accessible
2017   through Host Adapter.
2018 */
2019 
2020 static bool __init blogic_inquiry(struct blogic_adapter *adapter)
2021 {
2022     u16 installed_devs;
2023     u8 installed_devs0to7[8];
2024     struct blogic_setup_info setupinfo;
2025     u8 sync_period[BLOGIC_MAXDEV];
2026     unsigned char req_replylen;
2027     int tgt_id;
2028 
2029     /*
2030        Wait a few seconds between the Host Adapter Hard Reset which
2031        initiates a SCSI Bus Reset and issuing any SCSI Commands. Some
2032        SCSI devices get confused if they receive SCSI Commands too soon
2033        after a SCSI Bus Reset.
2034      */
2035     blogic_delay(adapter->bus_settle_time);
2036     /*
2037        FlashPoint Host Adapters do not provide for Target Device Inquiry.
2038      */
2039     if (blogic_flashpoint_type(adapter))
2040         return true;
2041     /*
2042        Inhibit the Target Device Inquiry if requested.
2043      */
2044     if (adapter->drvr_opts != NULL && adapter->drvr_opts->stop_tgt_inquiry)
2045         return true;
2046     /*
2047        Issue the Inquire Target Devices command for host adapters with
2048        firmware version 4.25 or later, or the Inquire Installed Devices
2049        ID 0 to 7 command for older host adapters.  This is necessary to
2050        force Synchronous Transfer Negotiation so that the Inquire Setup
2051        Information and Inquire Synchronous Period commands will return
2052        valid data.  The Inquire Target Devices command is preferable to
2053        Inquire Installed Devices ID 0 to 7 since it only probes Logical
2054        Unit 0 of each Target Device.
2055      */
2056     if (strcmp(adapter->fw_ver, "4.25") >= 0) {
2057 
2058         /*
2059            Issue a Inquire Target Devices command. Inquire Target
2060            Devices only tests Logical Unit 0 of each Target Device
2061            unlike the Inquire Installed Devices commands which test
2062            Logical Units 0 - 7.  Two bytes are returned, where byte
2063            0 bit 0 set indicates that Target Device 0 exists, and so on.
2064          */
2065 
2066         if (blogic_cmd(adapter, BLOGIC_INQ_DEV, NULL, 0,
2067                     &installed_devs, sizeof(installed_devs))
2068             != sizeof(installed_devs))
2069             return blogic_failure(adapter, "INQUIRE TARGET DEVICES");
2070         for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
2071             adapter->tgt_flags[tgt_id].tgt_exists =
2072                 (installed_devs & (1 << tgt_id) ? true : false);
2073     } else {
2074 
2075         /*
2076            Issue an Inquire Installed Devices command. For each
2077            Target Device, a byte is returned where bit 0 set
2078            indicates that Logical Unit 0 * exists, bit 1 set
2079            indicates that Logical Unit 1 exists, and so on.
2080          */
2081 
2082         if (blogic_cmd(adapter, BLOGIC_INQ_DEV0TO7, NULL, 0,
2083                 &installed_devs0to7, sizeof(installed_devs0to7))
2084             != sizeof(installed_devs0to7))
2085             return blogic_failure(adapter,
2086                     "INQUIRE INSTALLED DEVICES ID 0 TO 7");
2087         for (tgt_id = 0; tgt_id < 8; tgt_id++)
2088             adapter->tgt_flags[tgt_id].tgt_exists =
2089                 installed_devs0to7[tgt_id] != 0;
2090     }
2091     /*
2092        Issue the Inquire Setup Information command.
2093      */
2094     req_replylen = sizeof(setupinfo);
2095     if (blogic_cmd(adapter, BLOGIC_INQ_SETUPINFO, &req_replylen,
2096             sizeof(req_replylen), &setupinfo, sizeof(setupinfo))
2097         != sizeof(setupinfo))
2098         return blogic_failure(adapter, "INQUIRE SETUP INFORMATION");
2099     for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
2100         adapter->sync_offset[tgt_id] = (tgt_id < 8 ? setupinfo.sync0to7[tgt_id].offset : setupinfo.sync8to15[tgt_id - 8].offset);
2101     if (strcmp(adapter->fw_ver, "5.06L") >= 0)
2102         for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
2103             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));
2104     /*
2105        Issue the Inquire Synchronous Period command.
2106      */
2107     if (adapter->fw_ver[0] >= '3') {
2108 
2109         /* Issue a Inquire Synchronous Period command. For each
2110            Target Device, a byte is returned which represents the
2111            Synchronous Transfer Period in units of 10 nanoseconds.
2112          */
2113 
2114         req_replylen = sizeof(sync_period);
2115         if (blogic_cmd(adapter, BLOGIC_INQ_SYNC_PERIOD, &req_replylen,
2116                 sizeof(req_replylen), &sync_period,
2117                 sizeof(sync_period)) != sizeof(sync_period))
2118             return blogic_failure(adapter,
2119                     "INQUIRE SYNCHRONOUS PERIOD");
2120         for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
2121             adapter->sync_period[tgt_id] = sync_period[tgt_id];
2122     } else
2123         for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
2124             if (setupinfo.sync0to7[tgt_id].offset > 0)
2125                 adapter->sync_period[tgt_id] = 20 + 5 * setupinfo.sync0to7[tgt_id].tx_period;
2126     /*
2127        Indicate the Target Device Inquiry completed successfully.
2128      */
2129     return true;
2130 }
2131 
2132 /*
2133   blogic_inithoststruct initializes the fields in the SCSI Host
2134   structure.  The base, io_port, n_io_ports, irq, and dma_channel fields in the
2135   SCSI Host structure are intentionally left uninitialized, as this driver
2136   handles acquisition and release of these resources explicitly, as well as
2137   ensuring exclusive access to the Host Adapter hardware and data structures
2138   through explicit acquisition and release of the Host Adapter's Lock.
2139 */
2140 
2141 static void __init blogic_inithoststruct(struct blogic_adapter *adapter,
2142         struct Scsi_Host *host)
2143 {
2144     host->max_id = adapter->maxdev;
2145     host->max_lun = adapter->maxlun;
2146     host->max_channel = 0;
2147     host->unique_id = adapter->io_addr;
2148     host->this_id = adapter->scsi_id;
2149     host->can_queue = adapter->drvr_qdepth;
2150     host->sg_tablesize = adapter->drvr_sglimit;
2151     host->cmd_per_lun = adapter->untag_qdepth;
2152 }
2153 
2154 /*
2155   blogic_slaveconfig will actually set the queue depth on individual
2156   scsi devices as they are permanently added to the device chain.  We
2157   shamelessly rip off the SelectQueueDepths code to make this work mostly
2158   like it used to.  Since we don't get called once at the end of the scan
2159   but instead get called for each device, we have to do things a bit
2160   differently.
2161 */
2162 static int blogic_slaveconfig(struct scsi_device *dev)
2163 {
2164     struct blogic_adapter *adapter =
2165         (struct blogic_adapter *) dev->host->hostdata;
2166     int tgt_id = dev->id;
2167     int qdepth = adapter->qdepth[tgt_id];
2168 
2169     if (adapter->tgt_flags[tgt_id].tagq_ok &&
2170             (adapter->tagq_ok & (1 << tgt_id))) {
2171         if (qdepth == 0)
2172             qdepth = BLOGIC_MAX_AUTO_TAG_DEPTH;
2173         adapter->qdepth[tgt_id] = qdepth;
2174         scsi_change_queue_depth(dev, qdepth);
2175     } else {
2176         adapter->tagq_ok &= ~(1 << tgt_id);
2177         qdepth = adapter->untag_qdepth;
2178         adapter->qdepth[tgt_id] = qdepth;
2179         scsi_change_queue_depth(dev, qdepth);
2180     }
2181     qdepth = 0;
2182     for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
2183         if (adapter->tgt_flags[tgt_id].tgt_exists)
2184             qdepth += adapter->qdepth[tgt_id];
2185     if (qdepth > adapter->alloc_ccbs)
2186         blogic_create_addlccbs(adapter, qdepth - adapter->alloc_ccbs,
2187                 false);
2188     return 0;
2189 }
2190 
2191 /*
2192   blogic_init probes for BusLogic Host Adapters at the standard
2193   I/O Addresses where they may be located, initializing, registering, and
2194   reporting the configuration of each BusLogic Host Adapter it finds.  It
2195   returns the number of BusLogic Host Adapters successfully initialized and
2196   registered.
2197 */
2198 
2199 static int __init blogic_init(void)
2200 {
2201     int adapter_count = 0, drvr_optindex = 0, probeindex;
2202     struct blogic_adapter *adapter;
2203     int ret = 0;
2204 
2205 #ifdef MODULE
2206     if (BusLogic)
2207         blogic_setup(BusLogic);
2208 #endif
2209 
2210     if (blogic_probe_options.noprobe)
2211         return -ENODEV;
2212     blogic_probeinfo_list =
2213         kcalloc(BLOGIC_MAX_ADAPTERS, sizeof(struct blogic_probeinfo),
2214                 GFP_KERNEL);
2215     if (blogic_probeinfo_list == NULL) {
2216         blogic_err("BusLogic: Unable to allocate Probe Info List\n",
2217                 NULL);
2218         return -ENOMEM;
2219     }
2220 
2221     adapter = kzalloc(sizeof(struct blogic_adapter), GFP_KERNEL);
2222     if (adapter == NULL) {
2223         kfree(blogic_probeinfo_list);
2224         blogic_err("BusLogic: Unable to allocate Prototype Host Adapter\n", NULL);
2225         return -ENOMEM;
2226     }
2227 
2228 #ifdef MODULE
2229     if (BusLogic != NULL)
2230         blogic_setup(BusLogic);
2231 #endif
2232     blogic_init_probeinfo_list(adapter);
2233     for (probeindex = 0; probeindex < blogic_probeinfo_count; probeindex++) {
2234         struct blogic_probeinfo *probeinfo =
2235             &blogic_probeinfo_list[probeindex];
2236         struct blogic_adapter *myadapter = adapter;
2237         struct Scsi_Host *host;
2238 
2239         if (probeinfo->io_addr == 0)
2240             continue;
2241         memset(myadapter, 0, sizeof(struct blogic_adapter));
2242         myadapter->adapter_type = probeinfo->adapter_type;
2243         myadapter->adapter_bus_type = probeinfo->adapter_bus_type;
2244         myadapter->io_addr = probeinfo->io_addr;
2245         myadapter->pci_addr = probeinfo->pci_addr;
2246         myadapter->bus = probeinfo->bus;
2247         myadapter->dev = probeinfo->dev;
2248         myadapter->pci_device = probeinfo->pci_device;
2249         myadapter->irq_ch = probeinfo->irq_ch;
2250         myadapter->addr_count =
2251             blogic_adapter_addr_count[myadapter->adapter_type];
2252 
2253         /*
2254            Make sure region is free prior to probing.
2255          */
2256         if (!request_region(myadapter->io_addr, myadapter->addr_count,
2257                     "BusLogic"))
2258             continue;
2259         /*
2260            Probe the Host Adapter. If unsuccessful, abort further
2261            initialization.
2262          */
2263         if (!blogic_probe(myadapter)) {
2264             release_region(myadapter->io_addr,
2265                     myadapter->addr_count);
2266             continue;
2267         }
2268         /*
2269            Hard Reset the Host Adapter.  If unsuccessful, abort further
2270            initialization.
2271          */
2272         if (!blogic_hwreset(myadapter, true)) {
2273             release_region(myadapter->io_addr,
2274                     myadapter->addr_count);
2275             continue;
2276         }
2277         /*
2278            Check the Host Adapter.  If unsuccessful, abort further
2279            initialization.
2280          */
2281         if (!blogic_checkadapter(myadapter)) {
2282             release_region(myadapter->io_addr,
2283                     myadapter->addr_count);
2284             continue;
2285         }
2286         /*
2287            Initialize the Driver Options field if provided.
2288          */
2289         if (drvr_optindex < blogic_drvr_options_count)
2290             myadapter->drvr_opts =
2291                 &blogic_drvr_options[drvr_optindex++];
2292         /*
2293            Announce the Driver Version and Date, Author's Name,
2294            Copyright Notice, and Electronic Mail Address.
2295          */
2296         blogic_announce_drvr(myadapter);
2297         /*
2298            Register the SCSI Host structure.
2299          */
2300 
2301         host = scsi_host_alloc(&blogic_template,
2302                 sizeof(struct blogic_adapter));
2303         if (host == NULL) {
2304             release_region(myadapter->io_addr,
2305                     myadapter->addr_count);
2306             continue;
2307         }
2308         myadapter = (struct blogic_adapter *) host->hostdata;
2309         memcpy(myadapter, adapter, sizeof(struct blogic_adapter));
2310         myadapter->scsi_host = host;
2311         myadapter->host_no = host->host_no;
2312         /*
2313            Add Host Adapter to the end of the list of registered
2314            BusLogic Host Adapters.
2315          */
2316         list_add_tail(&myadapter->host_list, &blogic_host_list);
2317 
2318         /*
2319            Read the Host Adapter Configuration, Configure the Host
2320            Adapter, Acquire the System Resources necessary to use
2321            the Host Adapter, then Create the Initial CCBs, Initialize
2322            the Host Adapter, and finally perform Target Device
2323            Inquiry. From this point onward, any failure will be
2324            assumed to be due to a problem with the Host Adapter,
2325            rather than due to having mistakenly identified this port
2326            as belonging to a BusLogic Host Adapter. The I/O Address
2327            range will not be released, thereby preventing it from
2328            being incorrectly identified as any other type of Host
2329            Adapter.
2330          */
2331         if (blogic_rdconfig(myadapter) &&
2332             blogic_reportconfig(myadapter) &&
2333             blogic_getres(myadapter) &&
2334             blogic_create_initccbs(myadapter) &&
2335             blogic_initadapter(myadapter) &&
2336             blogic_inquiry(myadapter)) {
2337             /*
2338                Initialization has been completed successfully.
2339                Release and re-register usage of the I/O Address
2340                range so that the Model Name of the Host Adapter
2341                will appear, and initialize the SCSI Host structure.
2342              */
2343             release_region(myadapter->io_addr,
2344                        myadapter->addr_count);
2345             if (!request_region(myadapter->io_addr,
2346                         myadapter->addr_count,
2347                         myadapter->full_model)) {
2348                 printk(KERN_WARNING
2349                     "BusLogic: Release and re-register of "
2350                     "port 0x%04lx failed \n",
2351                     (unsigned long)myadapter->io_addr);
2352                 blogic_destroy_ccbs(myadapter);
2353                 blogic_relres(myadapter);
2354                 list_del(&myadapter->host_list);
2355                 scsi_host_put(host);
2356                 ret = -ENOMEM;
2357             } else {
2358                 blogic_inithoststruct(myadapter,
2359                                  host);
2360                 if (scsi_add_host(host, myadapter->pci_device
2361                         ? &myadapter->pci_device->dev
2362                           : NULL)) {
2363                     printk(KERN_WARNING
2364                            "BusLogic: scsi_add_host()"
2365                            "failed!\n");
2366                     blogic_destroy_ccbs(myadapter);
2367                     blogic_relres(myadapter);
2368                     list_del(&myadapter->host_list);
2369                     scsi_host_put(host);
2370                     ret = -ENODEV;
2371                 } else {
2372                     scsi_scan_host(host);
2373                     adapter_count++;
2374                 }
2375             }
2376         } else {
2377             /*
2378                An error occurred during Host Adapter Configuration
2379                Querying, Host Adapter Configuration, Resource
2380                Acquisition, CCB Creation, Host Adapter
2381                Initialization, or Target Device Inquiry, so
2382                remove Host Adapter from the list of registered
2383                BusLogic Host Adapters, destroy the CCBs, Release
2384                the System Resources, and Unregister the SCSI
2385                Host.
2386              */
2387             blogic_destroy_ccbs(myadapter);
2388             blogic_relres(myadapter);
2389             list_del(&myadapter->host_list);
2390             scsi_host_put(host);
2391             ret = -ENODEV;
2392         }
2393     }
2394     kfree(adapter);
2395     kfree(blogic_probeinfo_list);
2396     blogic_probeinfo_list = NULL;
2397     return ret;
2398 }
2399 
2400 
2401 /*
2402   blogic_deladapter releases all resources previously acquired to
2403   support a specific Host Adapter, including the I/O Address range, and
2404   unregisters the BusLogic Host Adapter.
2405 */
2406 
2407 static int __exit blogic_deladapter(struct blogic_adapter *adapter)
2408 {
2409     struct Scsi_Host *host = adapter->scsi_host;
2410 
2411     scsi_remove_host(host);
2412 
2413     /*
2414        FlashPoint Host Adapters must first be released by the FlashPoint
2415        SCCB Manager.
2416      */
2417     if (blogic_flashpoint_type(adapter))
2418         FlashPoint_ReleaseHostAdapter(adapter->cardhandle);
2419     /*
2420        Destroy the CCBs and release any system resources acquired to
2421        support Host Adapter.
2422      */
2423     blogic_destroy_ccbs(adapter);
2424     blogic_relres(adapter);
2425     /*
2426        Release usage of the I/O Address range.
2427      */
2428     release_region(adapter->io_addr, adapter->addr_count);
2429     /*
2430        Remove Host Adapter from the list of registered BusLogic
2431        Host Adapters.
2432      */
2433     list_del(&adapter->host_list);
2434 
2435     scsi_host_put(host);
2436     return 0;
2437 }
2438 
2439 
2440 /*
2441   blogic_qcompleted_ccb queues CCB for completion processing.
2442 */
2443 
2444 static void blogic_qcompleted_ccb(struct blogic_ccb *ccb)
2445 {
2446     struct blogic_adapter *adapter = ccb->adapter;
2447 
2448     ccb->status = BLOGIC_CCB_COMPLETE;
2449     ccb->next = NULL;
2450     if (adapter->firstccb == NULL) {
2451         adapter->firstccb = ccb;
2452         adapter->lastccb = ccb;
2453     } else {
2454         adapter->lastccb->next = ccb;
2455         adapter->lastccb = ccb;
2456     }
2457     adapter->active_cmds[ccb->tgt_id]--;
2458 }
2459 
2460 
2461 /*
2462   blogic_resultcode computes a SCSI Subsystem Result Code from
2463   the Host Adapter Status and Target Device Status.
2464 */
2465 
2466 static int blogic_resultcode(struct blogic_adapter *adapter,
2467         enum blogic_adapter_status adapter_status,
2468         enum blogic_tgt_status tgt_status)
2469 {
2470     int hoststatus;
2471 
2472     switch (adapter_status) {
2473     case BLOGIC_CMD_CMPLT_NORMAL:
2474     case BLOGIC_LINK_CMD_CMPLT:
2475     case BLOGIC_LINK_CMD_CMPLT_FLAG:
2476         hoststatus = DID_OK;
2477         break;
2478     case BLOGIC_SELECT_TIMEOUT:
2479         hoststatus = DID_TIME_OUT;
2480         break;
2481     case BLOGIC_INVALID_OUTBOX_CODE:
2482     case BLOGIC_INVALID_CMD_CODE:
2483     case BLOGIC_BAD_CMD_PARAM:
2484         blogic_warn("BusLogic Driver Protocol Error 0x%02X\n",
2485                 adapter, adapter_status);
2486         fallthrough;
2487     case BLOGIC_DATA_UNDERRUN:
2488     case BLOGIC_DATA_OVERRUN:
2489     case BLOGIC_NOEXPECT_BUSFREE:
2490     case BLOGIC_LINKCCB_BADLUN:
2491     case BLOGIC_AUTOREQSENSE_FAIL:
2492     case BLOGIC_TAGQUEUE_REJECT:
2493     case BLOGIC_BAD_MSG_RCVD:
2494     case BLOGIC_HW_FAIL:
2495     case BLOGIC_BAD_RECONNECT:
2496     case BLOGIC_ABRT_QUEUE:
2497     case BLOGIC_ADAPTER_SW_ERROR:
2498     case BLOGIC_HW_TIMEOUT:
2499     case BLOGIC_PARITY_ERR:
2500         hoststatus = DID_ERROR;
2501         break;
2502     case BLOGIC_INVALID_BUSPHASE:
2503     case BLOGIC_NORESPONSE_TO_ATN:
2504     case BLOGIC_HW_RESET:
2505     case BLOGIC_RST_FROM_OTHERDEV:
2506     case BLOGIC_HW_BDR:
2507         hoststatus = DID_RESET;
2508         break;
2509     default:
2510         blogic_warn("Unknown Host Adapter Status 0x%02X\n", adapter,
2511                 adapter_status);
2512         hoststatus = DID_ERROR;
2513         break;
2514     }
2515     return (hoststatus << 16) | tgt_status;
2516 }
2517 
2518 /*
2519  * turn the dma address from an inbox into a ccb pointer
2520  * This is rather inefficient.
2521  */
2522 static struct blogic_ccb *
2523 blogic_inbox_to_ccb(struct blogic_adapter *adapter, struct blogic_inbox *inbox)
2524 {
2525     struct blogic_ccb *ccb;
2526 
2527     for (ccb = adapter->all_ccbs; ccb; ccb = ccb->next_all)
2528         if (inbox->ccb == ccb->dma_handle)
2529             break;
2530 
2531     return ccb;
2532 }
2533 
2534 /*
2535   blogic_scan_inbox scans the Incoming Mailboxes saving any
2536   Incoming Mailbox entries for completion processing.
2537 */
2538 static void blogic_scan_inbox(struct blogic_adapter *adapter)
2539 {
2540     /*
2541        Scan through the Incoming Mailboxes in Strict Round Robin
2542        fashion, saving any completed CCBs for further processing. It
2543        is essential that for each CCB and SCSI Command issued, command
2544        completion processing is performed exactly once.  Therefore,
2545        only Incoming Mailboxes with completion code Command Completed
2546        Without Error, Command Completed With Error, or Command Aborted
2547        At Host Request are saved for completion processing. When an
2548        Incoming Mailbox has a completion code of Aborted Command Not
2549        Found, the CCB had already completed or been aborted before the
2550        current Abort request was processed, and so completion processing
2551        has already occurred and no further action should be taken.
2552      */
2553     struct blogic_inbox *next_inbox = adapter->next_inbox;
2554     enum blogic_cmplt_code comp_code;
2555 
2556     while ((comp_code = next_inbox->comp_code) != BLOGIC_INBOX_FREE) {
2557         struct blogic_ccb *ccb = blogic_inbox_to_ccb(adapter, next_inbox);
2558         if (!ccb) {
2559             /*
2560              * This should never happen, unless the CCB list is
2561              * corrupted in memory.
2562              */
2563             blogic_warn("Could not find CCB for dma address %x\n", adapter, next_inbox->ccb);
2564         } else if (comp_code != BLOGIC_CMD_NOTFOUND) {
2565             if (ccb->status == BLOGIC_CCB_ACTIVE ||
2566                     ccb->status == BLOGIC_CCB_RESET) {
2567                 /*
2568                    Save the Completion Code for this CCB and
2569                    queue the CCB for completion processing.
2570                  */
2571                 ccb->comp_code = comp_code;
2572                 blogic_qcompleted_ccb(ccb);
2573             } else {
2574                 /*
2575                    If a CCB ever appears in an Incoming Mailbox
2576                    and is not marked as status Active or Reset,
2577                    then there is most likely a bug in
2578                    the Host Adapter firmware.
2579                  */
2580                 blogic_warn("Illegal CCB #%ld status %d in Incoming Mailbox\n", adapter, ccb->serial, ccb->status);
2581             }
2582         }
2583         next_inbox->comp_code = BLOGIC_INBOX_FREE;
2584         if (++next_inbox > adapter->last_inbox)
2585             next_inbox = adapter->first_inbox;
2586     }
2587     adapter->next_inbox = next_inbox;
2588 }
2589 
2590 
2591 /*
2592   blogic_process_ccbs iterates over the completed CCBs for Host
2593   Adapter setting the SCSI Command Result Codes, deallocating the CCBs, and
2594   calling the SCSI Subsystem Completion Routines.  The Host Adapter's Lock
2595   should already have been acquired by the caller.
2596 */
2597 
2598 static void blogic_process_ccbs(struct blogic_adapter *adapter)
2599 {
2600     if (adapter->processing_ccbs)
2601         return;
2602     adapter->processing_ccbs = true;
2603     while (adapter->firstccb != NULL) {
2604         struct blogic_ccb *ccb = adapter->firstccb;
2605         struct scsi_cmnd *command = ccb->command;
2606         adapter->firstccb = ccb->next;
2607         if (adapter->firstccb == NULL)
2608             adapter->lastccb = NULL;
2609         /*
2610            Process the Completed CCB.
2611          */
2612         if (ccb->opcode == BLOGIC_BDR) {
2613             int tgt_id = ccb->tgt_id;
2614 
2615             blogic_warn("Bus Device Reset CCB #%ld to Target %d Completed\n", adapter, ccb->serial, tgt_id);
2616             blogic_inc_count(&adapter->tgt_stats[tgt_id].bdr_done);
2617             adapter->tgt_flags[tgt_id].tagq_active = false;
2618             adapter->cmds_since_rst[tgt_id] = 0;
2619             adapter->last_resetdone[tgt_id] = jiffies;
2620             /*
2621                Place CCB back on the Host Adapter's free list.
2622              */
2623             blogic_dealloc_ccb(ccb, 1);
2624 #if 0           /* this needs to be redone different for new EH */
2625             /*
2626                Bus Device Reset CCBs have the command field
2627                non-NULL only when a Bus Device Reset was requested
2628                for a command that did not have a currently active
2629                CCB in the Host Adapter (i.e., a Synchronous Bus
2630                Device Reset), and hence would not have its
2631                Completion Routine called otherwise.
2632              */
2633             while (command != NULL) {
2634                 struct scsi_cmnd *nxt_cmd =
2635                     command->reset_chain;
2636                 command->reset_chain = NULL;
2637                 command->result = DID_RESET << 16;
2638                 scsi_done(command);
2639                 command = nxt_cmd;
2640             }
2641 #endif
2642             /*
2643                Iterate over the CCBs for this Host Adapter
2644                performing completion processing for any CCBs
2645                marked as Reset for this Target.
2646              */
2647             for (ccb = adapter->all_ccbs; ccb != NULL;
2648                     ccb = ccb->next_all)
2649                 if (ccb->status == BLOGIC_CCB_RESET &&
2650                         ccb->tgt_id == tgt_id) {
2651                     command = ccb->command;
2652                     blogic_dealloc_ccb(ccb, 1);
2653                     adapter->active_cmds[tgt_id]--;
2654                     command->result = DID_RESET << 16;
2655                     scsi_done(command);
2656                 }
2657             adapter->bdr_pend[tgt_id] = NULL;
2658         } else {
2659             /*
2660                Translate the Completion Code, Host Adapter Status,
2661                and Target Device Status into a SCSI Subsystem
2662                Result Code.
2663              */
2664             switch (ccb->comp_code) {
2665             case BLOGIC_INBOX_FREE:
2666             case BLOGIC_CMD_NOTFOUND:
2667             case BLOGIC_INVALID_CCB:
2668                 blogic_warn("CCB #%ld to Target %d Impossible State\n", adapter, ccb->serial, ccb->tgt_id);
2669                 break;
2670             case BLOGIC_CMD_COMPLETE_GOOD:
2671                 adapter->tgt_stats[ccb->tgt_id]
2672                     .cmds_complete++;
2673                 adapter->tgt_flags[ccb->tgt_id]
2674                     .cmd_good = true;
2675                 command->result = DID_OK << 16;
2676                 break;
2677             case BLOGIC_CMD_ABORT_BY_HOST:
2678                 blogic_warn("CCB #%ld to Target %d Aborted\n",
2679                     adapter, ccb->serial, ccb->tgt_id);
2680                 blogic_inc_count(&adapter->tgt_stats[ccb->tgt_id].aborts_done);
2681                 command->result = DID_ABORT << 16;
2682                 break;
2683             case BLOGIC_CMD_COMPLETE_ERROR:
2684                 command->result = blogic_resultcode(adapter,
2685                     ccb->adapter_status, ccb->tgt_status);
2686                 if (ccb->adapter_status != BLOGIC_SELECT_TIMEOUT) {
2687                     adapter->tgt_stats[ccb->tgt_id]
2688                         .cmds_complete++;
2689                     if (blogic_global_options.trace_err) {
2690                         int i;
2691                         blogic_notice("CCB #%ld Target %d: Result %X Host "
2692                                 "Adapter Status %02X Target Status %02X\n", adapter, ccb->serial, ccb->tgt_id, command->result, ccb->adapter_status, ccb->tgt_status);
2693                         blogic_notice("CDB   ", adapter);
2694                         for (i = 0; i < ccb->cdblen; i++)
2695                             blogic_notice(" %02X", adapter, ccb->cdb[i]);
2696                         blogic_notice("\n", adapter);
2697                         blogic_notice("Sense ", adapter);
2698                         for (i = 0; i < ccb->sense_datalen; i++)
2699                             blogic_notice(" %02X", adapter, command->sense_buffer[i]);
2700                         blogic_notice("\n", adapter);
2701                     }
2702                 }
2703                 break;
2704             }
2705             /*
2706                When an INQUIRY command completes normally, save the
2707                CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit
2708                Wide Data Transfers Supported) bits.
2709              */
2710             if (ccb->cdb[0] == INQUIRY && ccb->cdb[1] == 0 &&
2711                 ccb->adapter_status == BLOGIC_CMD_CMPLT_NORMAL) {
2712                 struct blogic_tgt_flags *tgt_flags =
2713                     &adapter->tgt_flags[ccb->tgt_id];
2714                 struct scsi_inquiry *inquiry =
2715                     (struct scsi_inquiry *) scsi_sglist(command);
2716                 tgt_flags->tgt_exists = true;
2717                 tgt_flags->tagq_ok = inquiry->CmdQue;
2718                 tgt_flags->wide_ok = inquiry->WBus16;
2719             }
2720             /*
2721                Place CCB back on the Host Adapter's free list.
2722              */
2723             blogic_dealloc_ccb(ccb, 1);
2724             /*
2725                Call the SCSI Command Completion Routine.
2726              */
2727             scsi_done(command);
2728         }
2729     }
2730     adapter->processing_ccbs = false;
2731 }
2732 
2733 
2734 /*
2735   blogic_inthandler handles hardware interrupts from BusLogic Host
2736   Adapters.
2737 */
2738 
2739 static irqreturn_t blogic_inthandler(int irq_ch, void *devid)
2740 {
2741     struct blogic_adapter *adapter = (struct blogic_adapter *) devid;
2742     unsigned long processor_flag;
2743     /*
2744        Acquire exclusive access to Host Adapter.
2745      */
2746     spin_lock_irqsave(adapter->scsi_host->host_lock, processor_flag);
2747     /*
2748        Handle Interrupts appropriately for each Host Adapter type.
2749      */
2750     if (blogic_multimaster_type(adapter)) {
2751         union blogic_int_reg intreg;
2752         /*
2753            Read the Host Adapter Interrupt Register.
2754          */
2755         intreg.all = blogic_rdint(adapter);
2756         if (intreg.ir.int_valid) {
2757             /*
2758                Acknowledge the interrupt and reset the Host Adapter
2759                Interrupt Register.
2760              */
2761             blogic_intreset(adapter);
2762             /*
2763                Process valid External SCSI Bus Reset and Incoming
2764                Mailbox Loaded Interrupts. Command Complete
2765                Interrupts are noted, and Outgoing Mailbox Available
2766                Interrupts are ignored, as they are never enabled.
2767              */
2768             if (intreg.ir.ext_busreset)
2769                 adapter->adapter_extreset = true;
2770             else if (intreg.ir.mailin_loaded)
2771                 blogic_scan_inbox(adapter);
2772             else if (intreg.ir.cmd_complete)
2773                 adapter->adapter_cmd_complete = true;
2774         }
2775     } else {
2776         /*
2777            Check if there is a pending interrupt for this Host Adapter.
2778          */
2779         if (FlashPoint_InterruptPending(adapter->cardhandle))
2780             switch (FlashPoint_HandleInterrupt(adapter->cardhandle)) {
2781             case FPOINT_NORMAL_INT:
2782                 break;
2783             case FPOINT_EXT_RESET:
2784                 adapter->adapter_extreset = true;
2785                 break;
2786             case FPOINT_INTERN_ERR:
2787                 blogic_warn("Internal FlashPoint Error detected - Resetting Host Adapter\n", adapter);
2788                 adapter->adapter_intern_err = true;
2789                 break;
2790             }
2791     }
2792     /*
2793        Process any completed CCBs.
2794      */
2795     if (adapter->firstccb != NULL)
2796         blogic_process_ccbs(adapter);
2797     /*
2798        Reset the Host Adapter if requested.
2799      */
2800     if (adapter->adapter_extreset) {
2801         blogic_warn("Resetting %s due to External SCSI Bus Reset\n", adapter, adapter->full_model);
2802         blogic_inc_count(&adapter->ext_resets);
2803         blogic_resetadapter(adapter, false);
2804         adapter->adapter_extreset = false;
2805     } else if (adapter->adapter_intern_err) {
2806         blogic_warn("Resetting %s due to Host Adapter Internal Error\n", adapter, adapter->full_model);
2807         blogic_inc_count(&adapter->adapter_intern_errors);
2808         blogic_resetadapter(adapter, true);
2809         adapter->adapter_intern_err = false;
2810     }
2811     /*
2812        Release exclusive access to Host Adapter.
2813      */
2814     spin_unlock_irqrestore(adapter->scsi_host->host_lock, processor_flag);
2815     return IRQ_HANDLED;
2816 }
2817 
2818 
2819 /*
2820   blogic_write_outbox places CCB and Action Code into an Outgoing
2821   Mailbox for execution by Host Adapter.  The Host Adapter's Lock should
2822   already have been acquired by the caller.
2823 */
2824 
2825 static bool blogic_write_outbox(struct blogic_adapter *adapter,
2826         enum blogic_action action, struct blogic_ccb *ccb)
2827 {
2828     struct blogic_outbox *next_outbox;
2829 
2830     next_outbox = adapter->next_outbox;
2831     if (next_outbox->action == BLOGIC_OUTBOX_FREE) {
2832         ccb->status = BLOGIC_CCB_ACTIVE;
2833         /*
2834            The CCB field must be written before the Action Code field
2835            since the Host Adapter is operating asynchronously and the
2836            locking code does not protect against simultaneous access
2837            by the Host Adapter.
2838          */
2839         next_outbox->ccb = ccb->dma_handle;
2840         next_outbox->action = action;
2841         blogic_execmbox(adapter);
2842         if (++next_outbox > adapter->last_outbox)
2843             next_outbox = adapter->first_outbox;
2844         adapter->next_outbox = next_outbox;
2845         if (action == BLOGIC_MBOX_START) {
2846             adapter->active_cmds[ccb->tgt_id]++;
2847             if (ccb->opcode != BLOGIC_BDR)
2848                 adapter->tgt_stats[ccb->tgt_id].cmds_tried++;
2849         }
2850         return true;
2851     }
2852     return false;
2853 }
2854 
2855 /* Error Handling (EH) support */
2856 
2857 static int blogic_hostreset(struct scsi_cmnd *SCpnt)
2858 {
2859     struct blogic_adapter *adapter =
2860         (struct blogic_adapter *) SCpnt->device->host->hostdata;
2861 
2862     unsigned int id = SCpnt->device->id;
2863     struct blogic_tgt_stats *stats = &adapter->tgt_stats[id];
2864     int rc;
2865 
2866     spin_lock_irq(SCpnt->device->host->host_lock);
2867 
2868     blogic_inc_count(&stats->adapter_reset_req);
2869 
2870     rc = blogic_resetadapter(adapter, false);
2871     spin_unlock_irq(SCpnt->device->host->host_lock);
2872     return rc;
2873 }
2874 
2875 /*
2876   blogic_qcmd creates a CCB for Command and places it into an
2877   Outgoing Mailbox for execution by the associated Host Adapter.
2878 */
2879 
2880 static int blogic_qcmd_lck(struct scsi_cmnd *command)
2881 {
2882     void (*comp_cb)(struct scsi_cmnd *) = scsi_done;
2883     struct blogic_adapter *adapter =
2884         (struct blogic_adapter *) command->device->host->hostdata;
2885     struct blogic_tgt_flags *tgt_flags =
2886         &adapter->tgt_flags[command->device->id];
2887     struct blogic_tgt_stats *tgt_stats = adapter->tgt_stats;
2888     unsigned char *cdb = command->cmnd;
2889     int cdblen = command->cmd_len;
2890     int tgt_id = command->device->id;
2891     int lun = command->device->lun;
2892     int buflen = scsi_bufflen(command);
2893     int count;
2894     struct blogic_ccb *ccb;
2895     dma_addr_t sense_buf;
2896 
2897     /*
2898        SCSI REQUEST_SENSE commands will be executed automatically by the
2899        Host Adapter for any errors, so they should not be executed
2900        explicitly unless the Sense Data is zero indicating that no error
2901        occurred.
2902      */
2903     if (cdb[0] == REQUEST_SENSE && command->sense_buffer[0] != 0) {
2904         command->result = DID_OK << 16;
2905         comp_cb(command);
2906         return 0;
2907     }
2908     /*
2909        Allocate a CCB from the Host Adapter's free list. In the unlikely
2910        event that there are none available and memory allocation fails,
2911        wait 1 second and try again. If that fails, the Host Adapter is
2912        probably hung so signal an error as a Host Adapter Hard Reset
2913        should be initiated soon.
2914      */
2915     ccb = blogic_alloc_ccb(adapter);
2916     if (ccb == NULL) {
2917         spin_unlock_irq(adapter->scsi_host->host_lock);
2918         blogic_delay(1);
2919         spin_lock_irq(adapter->scsi_host->host_lock);
2920         ccb = blogic_alloc_ccb(adapter);
2921         if (ccb == NULL) {
2922             command->result = DID_ERROR << 16;
2923             comp_cb(command);
2924             return 0;
2925         }
2926     }
2927 
2928     /*
2929        Initialize the fields in the BusLogic Command Control Block (CCB).
2930      */
2931     count = scsi_dma_map(command);
2932     BUG_ON(count < 0);
2933     if (count) {
2934         struct scatterlist *sg;
2935         int i;
2936 
2937         ccb->opcode = BLOGIC_INITIATOR_CCB_SG;
2938         ccb->datalen = count * sizeof(struct blogic_sg_seg);
2939         if (blogic_multimaster_type(adapter))
2940             ccb->data = (unsigned int) ccb->dma_handle +
2941                     ((unsigned long) &ccb->sglist -
2942                     (unsigned long) ccb);
2943         else
2944             ccb->data = virt_to_32bit_virt(ccb->sglist);
2945 
2946         scsi_for_each_sg(command, sg, count, i) {
2947             ccb->sglist[i].segbytes = sg_dma_len(sg);
2948             ccb->sglist[i].segdata = sg_dma_address(sg);
2949         }
2950     } else if (!count) {
2951         ccb->opcode = BLOGIC_INITIATOR_CCB;
2952         ccb->datalen = buflen;
2953         ccb->data = 0;
2954     }
2955 
2956     switch (cdb[0]) {
2957     case READ_6:
2958     case READ_10:
2959         ccb->datadir = BLOGIC_DATAIN_CHECKED;
2960         tgt_stats[tgt_id].read_cmds++;
2961         blogic_addcount(&tgt_stats[tgt_id].bytesread, buflen);
2962         blogic_incszbucket(tgt_stats[tgt_id].read_sz_buckets, buflen);
2963         break;
2964     case WRITE_6:
2965     case WRITE_10:
2966         ccb->datadir = BLOGIC_DATAOUT_CHECKED;
2967         tgt_stats[tgt_id].write_cmds++;
2968         blogic_addcount(&tgt_stats[tgt_id].byteswritten, buflen);
2969         blogic_incszbucket(tgt_stats[tgt_id].write_sz_buckets, buflen);
2970         break;
2971     default:
2972         ccb->datadir = BLOGIC_UNCHECKED_TX;
2973         break;
2974     }
2975     ccb->cdblen = cdblen;
2976     ccb->adapter_status = 0;
2977     ccb->tgt_status = 0;
2978     ccb->tgt_id = tgt_id;
2979     ccb->lun = lun;
2980     ccb->tag_enable = false;
2981     ccb->legacytag_enable = false;
2982     /*
2983        BusLogic recommends that after a Reset the first couple of
2984        commands that are sent to a Target Device be sent in a non
2985        Tagged Queue fashion so that the Host Adapter and Target Device
2986        can establish Synchronous and Wide Transfer before Queue Tag
2987        messages can interfere with the Synchronous and Wide Negotiation
2988        messages.  By waiting to enable Tagged Queuing until after the
2989        first BLOGIC_MAX_TAG_DEPTH commands have been queued, it is
2990        assured that after a Reset any pending commands are requeued
2991        before Tagged Queuing is enabled and that the Tagged Queuing
2992        message will not occur while the partition table is being printed.
2993        In addition, some devices do not properly handle the transition
2994        from non-tagged to tagged commands, so it is necessary to wait
2995        until there are no pending commands for a target device
2996        before queuing tagged commands.
2997      */
2998     if (adapter->cmds_since_rst[tgt_id]++ >= BLOGIC_MAX_TAG_DEPTH &&
2999             !tgt_flags->tagq_active &&
3000             adapter->active_cmds[tgt_id] == 0
3001             && tgt_flags->tagq_ok &&
3002             (adapter->tagq_ok & (1 << tgt_id))) {
3003         tgt_flags->tagq_active = true;
3004         blogic_notice("Tagged Queuing now active for Target %d\n",
3005                     adapter, tgt_id);
3006     }
3007     if (tgt_flags->tagq_active) {
3008         enum blogic_queuetag queuetag = BLOGIC_SIMPLETAG;
3009         /*
3010            When using Tagged Queuing with Simple Queue Tags, it
3011            appears that disk drive controllers do not guarantee that
3012            a queued command will not remain in a disconnected state
3013            indefinitely if commands that read or write nearer the
3014            head position continue to arrive without interruption.
3015            Therefore, for each Target Device this driver keeps track
3016            of the last time either the queue was empty or an Ordered
3017            Queue Tag was issued. If more than 4 seconds (one fifth
3018            of the 20 second disk timeout) have elapsed since this
3019            last sequence point, this command will be issued with an
3020            Ordered Queue Tag rather than a Simple Queue Tag, which
3021            forces the Target Device to complete all previously
3022            queued commands before this command may be executed.
3023          */
3024         if (adapter->active_cmds[tgt_id] == 0)
3025             adapter->last_seqpoint[tgt_id] = jiffies;
3026         else if (time_after(jiffies,
3027                 adapter->last_seqpoint[tgt_id] + 4 * HZ)) {
3028             adapter->last_seqpoint[tgt_id] = jiffies;
3029             queuetag = BLOGIC_ORDEREDTAG;
3030         }
3031         if (adapter->ext_lun) {
3032             ccb->tag_enable = true;
3033             ccb->queuetag = queuetag;
3034         } else {
3035             ccb->legacytag_enable = true;
3036             ccb->legacy_tag = queuetag;
3037         }
3038     }
3039     memcpy(ccb->cdb, cdb, cdblen);
3040     ccb->sense_datalen = SCSI_SENSE_BUFFERSIZE;
3041     ccb->command = command;
3042     sense_buf = dma_map_single(&adapter->pci_device->dev,
3043                 command->sense_buffer, ccb->sense_datalen,
3044                 DMA_FROM_DEVICE);
3045     if (dma_mapping_error(&adapter->pci_device->dev, sense_buf)) {
3046         blogic_err("DMA mapping for sense data buffer failed\n",
3047                 adapter);
3048         blogic_dealloc_ccb(ccb, 0);
3049         return SCSI_MLQUEUE_HOST_BUSY;
3050     }
3051     ccb->sensedata = sense_buf;
3052     if (blogic_multimaster_type(adapter)) {
3053         /*
3054            Place the CCB in an Outgoing Mailbox. The higher levels
3055            of the SCSI Subsystem should not attempt to queue more
3056            commands than can be placed in Outgoing Mailboxes, so
3057            there should always be one free.  In the unlikely event
3058            that there are none available, wait 1 second and try
3059            again. If that fails, the Host Adapter is probably hung
3060            so signal an error as a Host Adapter Hard Reset should
3061            be initiated soon.
3062          */
3063         if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START, ccb)) {
3064             spin_unlock_irq(adapter->scsi_host->host_lock);
3065             blogic_warn("Unable to write Outgoing Mailbox - Pausing for 1 second\n", adapter);
3066             blogic_delay(1);
3067             spin_lock_irq(adapter->scsi_host->host_lock);
3068             if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START,
3069                         ccb)) {
3070                 blogic_warn("Still unable to write Outgoing Mailbox - Host Adapter Dead?\n", adapter);
3071                 blogic_dealloc_ccb(ccb, 1);
3072                 command->result = DID_ERROR << 16;
3073                 scsi_done(command);
3074             }
3075         }
3076     } else {
3077         /*
3078            Call the FlashPoint SCCB Manager to start execution of
3079            the CCB.
3080          */
3081         ccb->status = BLOGIC_CCB_ACTIVE;
3082         adapter->active_cmds[tgt_id]++;
3083         tgt_stats[tgt_id].cmds_tried++;
3084         FlashPoint_StartCCB(adapter->cardhandle, ccb);
3085         /*
3086            The Command may have already completed and
3087            blogic_qcompleted_ccb been called, or it may still be
3088            pending.
3089          */
3090         if (ccb->status == BLOGIC_CCB_COMPLETE)
3091             blogic_process_ccbs(adapter);
3092     }
3093     return 0;
3094 }
3095 
3096 static DEF_SCSI_QCMD(blogic_qcmd)
3097 
3098 #if 0
3099 /*
3100   blogic_abort aborts Command if possible.
3101 */
3102 
3103 static int blogic_abort(struct scsi_cmnd *command)
3104 {
3105     struct blogic_adapter *adapter =
3106         (struct blogic_adapter *) command->device->host->hostdata;
3107 
3108     int tgt_id = command->device->id;
3109     struct blogic_ccb *ccb;
3110     blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_request);
3111 
3112     /*
3113        Attempt to find an Active CCB for this Command. If no Active
3114        CCB for this Command is found, then no Abort is necessary.
3115      */
3116     for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all)
3117         if (ccb->command == command)
3118             break;
3119     if (ccb == NULL) {
3120         blogic_warn("Unable to Abort Command to Target %d - No CCB Found\n", adapter, tgt_id);
3121         return SUCCESS;
3122     } else if (ccb->status == BLOGIC_CCB_COMPLETE) {
3123         blogic_warn("Unable to Abort Command to Target %d - CCB Completed\n", adapter, tgt_id);
3124         return SUCCESS;
3125     } else if (ccb->status == BLOGIC_CCB_RESET) {
3126         blogic_warn("Unable to Abort Command to Target %d - CCB Reset\n", adapter, tgt_id);
3127         return SUCCESS;
3128     }
3129     if (blogic_multimaster_type(adapter)) {
3130         /*
3131            Attempt to Abort this CCB.  MultiMaster Firmware versions
3132            prior to 5.xx do not generate Abort Tag messages, but only
3133            generate the non-tagged Abort message.  Since non-tagged
3134            commands are not sent by the Host Adapter until the queue
3135            of outstanding tagged commands has completed, and the
3136            Abort message is treated as a non-tagged command, it is
3137            effectively impossible to abort commands when Tagged
3138            Queuing is active. Firmware version 5.xx does generate
3139            Abort Tag messages, so it is possible to abort commands
3140            when Tagged Queuing is active.
3141          */
3142         if (adapter->tgt_flags[tgt_id].tagq_active &&
3143                 adapter->fw_ver[0] < '5') {
3144             blogic_warn("Unable to Abort CCB #%ld to Target %d - Abort Tag Not Supported\n", adapter, ccb->serial, tgt_id);
3145             return FAILURE;
3146         } else if (blogic_write_outbox(adapter, BLOGIC_MBOX_ABORT,
3147                     ccb)) {
3148             blogic_warn("Aborting CCB #%ld to Target %d\n",
3149                     adapter, ccb->serial, tgt_id);
3150             blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_tried);
3151             return SUCCESS;
3152         } else {
3153             blogic_warn("Unable to Abort CCB #%ld to Target %d - No Outgoing Mailboxes\n", adapter, ccb->serial, tgt_id);
3154             return FAILURE;
3155         }
3156     } else {
3157         /*
3158            Call the FlashPoint SCCB Manager to abort execution of
3159            the CCB.
3160          */
3161         blogic_warn("Aborting CCB #%ld to Target %d\n", adapter,
3162                 ccb->serial, tgt_id);
3163         blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_tried);
3164         FlashPoint_AbortCCB(adapter->cardhandle, ccb);
3165         /*
3166            The Abort may have already been completed and
3167            blogic_qcompleted_ccb been called, or it
3168            may still be pending.
3169          */
3170         if (ccb->status == BLOGIC_CCB_COMPLETE)
3171             blogic_process_ccbs(adapter);
3172         return SUCCESS;
3173     }
3174     return SUCCESS;
3175 }
3176 
3177 #endif
3178 /*
3179   blogic_resetadapter resets Host Adapter if possible, marking all
3180   currently executing SCSI Commands as having been Reset.
3181 */
3182 
3183 static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset)
3184 {
3185     struct blogic_ccb *ccb;
3186     int tgt_id;
3187 
3188     /*
3189      * Attempt to Reset and Reinitialize the Host Adapter.
3190      */
3191 
3192     if (!(blogic_hwreset(adapter, hard_reset) &&
3193                 blogic_initadapter(adapter))) {
3194         blogic_err("Resetting %s Failed\n", adapter,
3195                         adapter->full_model);
3196         return FAILURE;
3197     }
3198 
3199     /*
3200      * Deallocate all currently executing CCBs.
3201      */
3202 
3203     for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all)
3204         if (ccb->status == BLOGIC_CCB_ACTIVE)
3205             blogic_dealloc_ccb(ccb, 1);
3206     /*
3207      * Wait a few seconds between the Host Adapter Hard Reset which
3208      * initiates a SCSI Bus Reset and issuing any SCSI Commands.  Some
3209      * SCSI devices get confused if they receive SCSI Commands too soon
3210      * after a SCSI Bus Reset.
3211      */
3212 
3213     if (hard_reset) {
3214         spin_unlock_irq(adapter->scsi_host->host_lock);
3215         blogic_delay(adapter->bus_settle_time);
3216         spin_lock_irq(adapter->scsi_host->host_lock);
3217     }
3218 
3219     for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) {
3220         adapter->last_resettried[tgt_id] = jiffies;
3221         adapter->last_resetdone[tgt_id] = jiffies;
3222     }
3223     return SUCCESS;
3224 }
3225 
3226 /*
3227   blogic_diskparam returns the Heads/Sectors/Cylinders BIOS Disk
3228   Parameters for Disk.  The default disk geometry is 64 heads, 32 sectors, and
3229   the appropriate number of cylinders so as not to exceed drive capacity.  In
3230   order for disks equal to or larger than 1 GB to be addressable by the BIOS
3231   without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
3232   may be enabled in AutoSCSI on FlashPoint Host Adapters and on "W" and "C"
3233   series MultiMaster Host Adapters, or by a dip switch setting on "S" and "A"
3234   series MultiMaster Host Adapters.  With Extended Translation enabled, drives
3235   between 1 GB inclusive and 2 GB exclusive are given a disk geometry of 128
3236   heads and 32 sectors, and drives above 2 GB inclusive are given a disk
3237   geometry of 255 heads and 63 sectors.  However, if the BIOS detects that the
3238   Extended Translation setting does not match the geometry in the partition
3239   table, then the translation inferred from the partition table will be used by
3240   the BIOS, and a warning may be displayed.
3241 */
3242 
3243 static int blogic_diskparam(struct scsi_device *sdev, struct block_device *dev,
3244         sector_t capacity, int *params)
3245 {
3246     struct blogic_adapter *adapter =
3247                 (struct blogic_adapter *) sdev->host->hostdata;
3248     struct bios_diskparam *diskparam = (struct bios_diskparam *) params;
3249     unsigned char *buf;
3250 
3251     if (adapter->ext_trans_enable && capacity >= 2 * 1024 * 1024 /* 1 GB in 512 byte sectors */) {
3252         if (capacity >= 4 * 1024 * 1024 /* 2 GB in 512 byte sectors */) {
3253             diskparam->heads = 255;
3254             diskparam->sectors = 63;
3255         } else {
3256             diskparam->heads = 128;
3257             diskparam->sectors = 32;
3258         }
3259     } else {
3260         diskparam->heads = 64;
3261         diskparam->sectors = 32;
3262     }
3263     diskparam->cylinders = (unsigned long) capacity / (diskparam->heads * diskparam->sectors);
3264     buf = scsi_bios_ptable(dev);
3265     if (buf == NULL)
3266         return 0;
3267     /*
3268        If the boot sector partition table flag is valid, search for
3269        a partition table entry whose end_head matches one of the
3270        standard BusLogic geometry translations (64/32, 128/32, or 255/63).
3271      */
3272     if (*(unsigned short *) (buf + 64) == MSDOS_LABEL_MAGIC) {
3273         struct msdos_partition *part1_entry =
3274                 (struct msdos_partition *)buf;
3275         struct msdos_partition *part_entry = part1_entry;
3276         int saved_cyl = diskparam->cylinders, part_no;
3277         unsigned char part_end_head = 0, part_end_sector = 0;
3278 
3279         for (part_no = 0; part_no < 4; part_no++) {
3280             part_end_head = part_entry->end_head;
3281             part_end_sector = part_entry->end_sector & 0x3F;
3282             if (part_end_head == 64 - 1) {
3283                 diskparam->heads = 64;
3284                 diskparam->sectors = 32;
3285                 break;
3286             } else if (part_end_head == 128 - 1) {
3287                 diskparam->heads = 128;
3288                 diskparam->sectors = 32;
3289                 break;
3290             } else if (part_end_head == 255 - 1) {
3291                 diskparam->heads = 255;
3292                 diskparam->sectors = 63;
3293                 break;
3294             }
3295             part_entry++;
3296         }
3297         if (part_no == 4) {
3298             part_end_head = part1_entry->end_head;
3299             part_end_sector = part1_entry->end_sector & 0x3F;
3300         }
3301         diskparam->cylinders = (unsigned long) capacity / (diskparam->heads * diskparam->sectors);
3302         if (part_no < 4 && part_end_sector == diskparam->sectors) {
3303             if (diskparam->cylinders != saved_cyl)
3304                 blogic_warn("Adopting Geometry %d/%d from Partition Table\n", adapter, diskparam->heads, diskparam->sectors);
3305         } else if (part_end_head > 0 || part_end_sector > 0) {
3306             blogic_warn("Warning: Partition Table appears to have Geometry %d/%d which is\n", adapter, part_end_head + 1, part_end_sector);
3307             blogic_warn("not compatible with current BusLogic Host Adapter Geometry %d/%d\n", adapter, diskparam->heads, diskparam->sectors);
3308         }
3309     }
3310     kfree(buf);
3311     return 0;
3312 }
3313 
3314 
3315 /*
3316   BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>.
3317 */
3318 
3319 static int blogic_write_info(struct Scsi_Host *shost, char *procbuf,
3320                 int bytes_avail)
3321 {
3322     struct blogic_adapter *adapter =
3323                 (struct blogic_adapter *) shost->hostdata;
3324     struct blogic_tgt_stats *tgt_stats;
3325 
3326     tgt_stats = adapter->tgt_stats;
3327     adapter->ext_resets = 0;
3328     adapter->adapter_intern_errors = 0;
3329     memset(tgt_stats, 0, BLOGIC_MAXDEV * sizeof(struct blogic_tgt_stats));
3330     return 0;
3331 }
3332 
3333 static int blogic_show_info(struct seq_file *m, struct Scsi_Host *shost)
3334 {
3335     struct blogic_adapter *adapter = (struct blogic_adapter *) shost->hostdata;
3336     struct blogic_tgt_stats *tgt_stats;
3337     int tgt;
3338 
3339     tgt_stats = adapter->tgt_stats;
3340     seq_write(m, adapter->msgbuf, adapter->msgbuflen);
3341     seq_printf(m, "\n\
3342 Current Driver Queue Depth: %d\n\
3343 Currently Allocated CCBs:   %d\n", adapter->drvr_qdepth, adapter->alloc_ccbs);
3344     seq_puts(m, "\n\n\
3345                DATA TRANSFER STATISTICS\n\
3346 \n\
3347 Target  Tagged Queuing  Queue Depth  Active  Attempted  Completed\n\
3348 ======  ==============  ===========  ======  =========  =========\n");
3349     for (tgt = 0; tgt < adapter->maxdev; tgt++) {
3350         struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
3351         if (!tgt_flags->tgt_exists)
3352             continue;
3353         seq_printf(m, "  %2d    %s", tgt, (tgt_flags->tagq_ok ? (tgt_flags->tagq_active ? "    Active" : (adapter->tagq_ok & (1 << tgt)
3354                                                                                     ? "  Permitted" : "   Disabled"))
3355                                       : "Not Supported"));
3356         seq_printf(m,
3357                   "     %3d       %3u    %9u    %9u\n", adapter->qdepth[tgt], adapter->active_cmds[tgt], tgt_stats[tgt].cmds_tried, tgt_stats[tgt].cmds_complete);
3358     }
3359     seq_puts(m, "\n\
3360 Target  Read Commands  Write Commands   Total Bytes Read    Total Bytes Written\n\
3361 ======  =============  ==============  ===================  ===================\n");
3362     for (tgt = 0; tgt < adapter->maxdev; tgt++) {
3363         struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
3364         if (!tgt_flags->tgt_exists)
3365             continue;
3366         seq_printf(m, "  %2d      %9u    %9u", tgt, tgt_stats[tgt].read_cmds, tgt_stats[tgt].write_cmds);
3367         if (tgt_stats[tgt].bytesread.billions > 0)
3368             seq_printf(m, "     %9u%09u", tgt_stats[tgt].bytesread.billions, tgt_stats[tgt].bytesread.units);
3369         else
3370             seq_printf(m, "     %9u", tgt_stats[tgt].bytesread.units);
3371         if (tgt_stats[tgt].byteswritten.billions > 0)
3372             seq_printf(m, "   %9u%09u\n", tgt_stats[tgt].byteswritten.billions, tgt_stats[tgt].byteswritten.units);
3373         else
3374             seq_printf(m, "      %9u\n", tgt_stats[tgt].byteswritten.units);
3375     }
3376     seq_puts(m, "\n\
3377 Target  Command    0-1KB      1-2KB      2-4KB      4-8KB     8-16KB\n\
3378 ======  =======  =========  =========  =========  =========  =========\n");
3379     for (tgt = 0; tgt < adapter->maxdev; tgt++) {
3380         struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
3381         if (!tgt_flags->tgt_exists)
3382             continue;
3383         seq_printf(m,
3384                 "  %2d   Read    %9u  %9u  %9u  %9u  %9u\n", tgt,
3385                 tgt_stats[tgt].read_sz_buckets[0],
3386                 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]);
3387         seq_printf(m,
3388                 "  %2d   Write   %9u  %9u  %9u  %9u  %9u\n", tgt,
3389                 tgt_stats[tgt].write_sz_buckets[0],
3390                 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]);
3391     }
3392     seq_puts(m, "\n\
3393 Target  Command   16-32KB    32-64KB   64-128KB   128-256KB   256KB+\n\
3394 ======  =======  =========  =========  =========  =========  =========\n");
3395     for (tgt = 0; tgt < adapter->maxdev; tgt++) {
3396         struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
3397         if (!tgt_flags->tgt_exists)
3398             continue;
3399         seq_printf(m,
3400                 "  %2d   Read    %9u  %9u  %9u  %9u  %9u\n", tgt,
3401                 tgt_stats[tgt].read_sz_buckets[5],
3402                 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]);
3403         seq_printf(m,
3404                 "  %2d   Write   %9u  %9u  %9u  %9u  %9u\n", tgt,
3405                 tgt_stats[tgt].write_sz_buckets[5],
3406                 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]);
3407     }
3408     seq_puts(m, "\n\n\
3409                ERROR RECOVERY STATISTICS\n\
3410 \n\
3411       Command Aborts      Bus Device Resets   Host Adapter Resets\n\
3412 Target  Requested Completed  Requested Completed  Requested Completed\n\
3413   ID    \\\\\\\\ Attempted ////  \\\\\\\\ Attempted ////  \\\\\\\\ Attempted ////\n\
3414 ======   ===== ===== =====    ===== ===== =====    ===== ===== =====\n");
3415     for (tgt = 0; tgt < adapter->maxdev; tgt++) {
3416         struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
3417         if (!tgt_flags->tgt_exists)
3418             continue;
3419         seq_printf(m, "  %2d     %5d %5d %5d    %5d %5d %5d    %5d %5d %5d\n",
3420                tgt, tgt_stats[tgt].aborts_request,
3421                tgt_stats[tgt].aborts_tried,
3422                tgt_stats[tgt].aborts_done,
3423                tgt_stats[tgt].bdr_request,
3424                tgt_stats[tgt].bdr_tried,
3425                tgt_stats[tgt].bdr_done,
3426                tgt_stats[tgt].adapter_reset_req,
3427                tgt_stats[tgt].adapter_reset_attempt,
3428                tgt_stats[tgt].adapter_reset_done);
3429     }
3430     seq_printf(m, "\nExternal Host Adapter Resets: %d\n", adapter->ext_resets);
3431     seq_printf(m, "Host Adapter Internal Errors: %d\n", adapter->adapter_intern_errors);
3432     return 0;
3433 }
3434 
3435 
3436 /*
3437   blogic_msg prints Driver Messages.
3438 */
3439 __printf(2, 4)
3440 static void blogic_msg(enum blogic_msglevel msglevel, char *fmt,
3441             struct blogic_adapter *adapter, ...)
3442 {
3443     static char buf[BLOGIC_LINEBUF_SIZE];
3444     static bool begin = true;
3445     va_list args;
3446     int len = 0;
3447 
3448     va_start(args, adapter);
3449     len = vscnprintf(buf, sizeof(buf), fmt, args);
3450     va_end(args);
3451     if (msglevel == BLOGIC_ANNOUNCE_LEVEL) {
3452         static int msglines = 0;
3453         strcpy(&adapter->msgbuf[adapter->msgbuflen], buf);
3454         adapter->msgbuflen += len;
3455         if (++msglines <= 2)
3456             printk("%sscsi: %s", blogic_msglevelmap[msglevel], buf);
3457     } else if (msglevel == BLOGIC_INFO_LEVEL) {
3458         strcpy(&adapter->msgbuf[adapter->msgbuflen], buf);
3459         adapter->msgbuflen += len;
3460         if (begin) {
3461             if (buf[0] != '\n' || len > 1)
3462                 printk("%sscsi%d: %s", blogic_msglevelmap[msglevel], adapter->host_no, buf);
3463         } else
3464             pr_cont("%s", buf);
3465     } else {
3466         if (begin) {
3467             if (adapter != NULL && adapter->adapter_initd)
3468                 printk("%sscsi%d: %s", blogic_msglevelmap[msglevel], adapter->host_no, buf);
3469             else
3470                 printk("%s%s", blogic_msglevelmap[msglevel], buf);
3471         } else
3472             pr_cont("%s", buf);
3473     }
3474     begin = (buf[len - 1] == '\n');
3475 }
3476 
3477 
3478 /*
3479   blogic_parse parses an individual option keyword.  It returns true
3480   and updates the pointer if the keyword is recognized and false otherwise.
3481 */
3482 
3483 static bool __init blogic_parse(char **str, char *keyword)
3484 {
3485     char *pointer = *str;
3486     while (*keyword != '\0') {
3487         char strch = *pointer++;
3488         char keywordch = *keyword++;
3489         if (strch >= 'A' && strch <= 'Z')
3490             strch += 'a' - 'Z';
3491         if (keywordch >= 'A' && keywordch <= 'Z')
3492             keywordch += 'a' - 'Z';
3493         if (strch != keywordch)
3494             return false;
3495     }
3496     *str = pointer;
3497     return true;
3498 }
3499 
3500 
3501 /*
3502   blogic_parseopts handles processing of BusLogic Driver Options
3503   specifications.
3504 
3505   BusLogic Driver Options may be specified either via the Linux Kernel Command
3506   Line or via the Loadable Kernel Module Installation Facility.  Driver Options
3507   for multiple host adapters may be specified either by separating the option
3508   strings by a semicolon, or by specifying multiple "BusLogic=" strings on the
3509   command line.  Individual option specifications for a single host adapter are
3510   separated by commas.  The Probing and Debugging Options apply to all host
3511   adapters whereas the remaining options apply individually only to the
3512   selected host adapter.
3513 
3514   The BusLogic Driver Probing Options are described in
3515   <file:Documentation/scsi/BusLogic.rst>.
3516 */
3517 
3518 static int __init blogic_parseopts(char *options)
3519 {
3520     while (true) {
3521         struct blogic_drvr_options *drvr_opts =
3522             &blogic_drvr_options[blogic_drvr_options_count++];
3523         int tgt_id;
3524 
3525         memset(drvr_opts, 0, sizeof(struct blogic_drvr_options));
3526         while (*options != '\0' && *options != ';') {
3527             if (blogic_parse(&options, "NoProbePCI"))
3528                 blogic_probe_options.noprobe_pci = true;
3529             else if (blogic_parse(&options, "NoProbe"))
3530                 blogic_probe_options.noprobe = true;
3531             else if (blogic_parse(&options, "NoSortPCI"))
3532                 blogic_probe_options.nosort_pci = true;
3533             else if (blogic_parse(&options, "MultiMasterFirst"))
3534                 blogic_probe_options.multimaster_first = true;
3535             else if (blogic_parse(&options, "FlashPointFirst"))
3536                 blogic_probe_options.flashpoint_first = true;
3537             /* Tagged Queuing Options. */
3538             else if (blogic_parse(&options, "QueueDepth:[") ||
3539                     blogic_parse(&options, "QD:[")) {
3540                 for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++) {
3541                     unsigned short qdepth = simple_strtoul(options, &options, 0);
3542                     if (qdepth > BLOGIC_MAX_TAG_DEPTH) {
3543                         blogic_err("BusLogic: Invalid Driver Options (invalid Queue Depth %d)\n", NULL, qdepth);
3544                         return 0;
3545                     }
3546                     drvr_opts->qdepth[tgt_id] = qdepth;
3547                     if (*options == ',')
3548                         options++;
3549                     else if (*options == ']')
3550                         break;
3551                     else {
3552                         blogic_err("BusLogic: Invalid Driver Options (',' or ']' expected at '%s')\n", NULL, options);
3553                         return 0;
3554                     }
3555                 }
3556                 if (*options != ']') {
3557                     blogic_err("BusLogic: Invalid Driver Options (']' expected at '%s')\n", NULL, options);
3558                     return 0;
3559                 } else
3560                     options++;
3561             } else if (blogic_parse(&options, "QueueDepth:") || blogic_parse(&options, "QD:")) {
3562                 unsigned short qdepth = simple_strtoul(options, &options, 0);
3563                 if (qdepth == 0 ||
3564                         qdepth > BLOGIC_MAX_TAG_DEPTH) {
3565                     blogic_err("BusLogic: Invalid Driver Options (invalid Queue Depth %d)\n", NULL, qdepth);
3566                     return 0;
3567                 }
3568                 drvr_opts->common_qdepth = qdepth;
3569                 for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++)
3570                     drvr_opts->qdepth[tgt_id] = qdepth;
3571             } else if (blogic_parse(&options, "TaggedQueuing:") ||
3572                     blogic_parse(&options, "TQ:")) {
3573                 if (blogic_parse(&options, "Default")) {
3574                     drvr_opts->tagq_ok = 0x0000;
3575                     drvr_opts->tagq_ok_mask = 0x0000;
3576                 } else if (blogic_parse(&options, "Enable")) {
3577                     drvr_opts->tagq_ok = 0xFFFF;
3578                     drvr_opts->tagq_ok_mask = 0xFFFF;
3579                 } else if (blogic_parse(&options, "Disable")) {
3580                     drvr_opts->tagq_ok = 0x0000;
3581                     drvr_opts->tagq_ok_mask = 0xFFFF;
3582                 } else {
3583                     unsigned short tgt_bit;
3584                     for (tgt_id = 0, tgt_bit = 1;
3585                         tgt_id < BLOGIC_MAXDEV;
3586                         tgt_id++, tgt_bit <<= 1)
3587                         switch (*options++) {
3588                         case 'Y':
3589                             drvr_opts->tagq_ok |= tgt_bit;
3590                             drvr_opts->tagq_ok_mask |= tgt_bit;
3591                             break;
3592                         case 'N':
3593                             drvr_opts->tagq_ok &= ~tgt_bit;
3594                             drvr_opts->tagq_ok_mask |= tgt_bit;
3595                             break;
3596                         case 'X':
3597                             break;
3598                         default:
3599                             options--;
3600                             tgt_id = BLOGIC_MAXDEV;
3601                             break;
3602                         }
3603                 }
3604             }
3605             /* Miscellaneous Options. */
3606             else if (blogic_parse(&options, "BusSettleTime:") ||
3607                     blogic_parse(&options, "BST:")) {
3608                 unsigned short bus_settle_time =
3609                     simple_strtoul(options, &options, 0);
3610                 if (bus_settle_time > 5 * 60) {
3611                     blogic_err("BusLogic: Invalid Driver Options (invalid Bus Settle Time %d)\n", NULL, bus_settle_time);
3612                     return 0;
3613                 }
3614                 drvr_opts->bus_settle_time = bus_settle_time;
3615             } else if (blogic_parse(&options,
3616                         "InhibitTargetInquiry"))
3617                 drvr_opts->stop_tgt_inquiry = true;
3618             /* Debugging Options. */
3619             else if (blogic_parse(&options, "TraceProbe"))
3620                 blogic_global_options.trace_probe = true;
3621             else if (blogic_parse(&options, "TraceHardwareReset"))
3622                 blogic_global_options.trace_hw_reset = true;
3623             else if (blogic_parse(&options, "TraceConfiguration"))
3624                 blogic_global_options.trace_config = true;
3625             else if (blogic_parse(&options, "TraceErrors"))
3626                 blogic_global_options.trace_err = true;
3627             else if (blogic_parse(&options, "Debug")) {
3628                 blogic_global_options.trace_probe = true;
3629                 blogic_global_options.trace_hw_reset = true;
3630                 blogic_global_options.trace_config = true;
3631                 blogic_global_options.trace_err = true;
3632             }
3633             if (*options == ',')
3634                 options++;
3635             else if (*options != ';' && *options != '\0') {
3636                 blogic_err("BusLogic: Unexpected Driver Option '%s' ignored\n", NULL, options);
3637                 *options = '\0';
3638             }
3639         }
3640         if (!(blogic_drvr_options_count == 0 ||
3641             blogic_probeinfo_count == 0 ||
3642             blogic_drvr_options_count == blogic_probeinfo_count)) {
3643             blogic_err("BusLogic: Invalid Driver Options (all or no I/O Addresses must be specified)\n", NULL);
3644             return 0;
3645         }
3646         /*
3647            Tagged Queuing is disabled when the Queue Depth is 1 since queuing
3648            multiple commands is not possible.
3649          */
3650         for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++)
3651             if (drvr_opts->qdepth[tgt_id] == 1) {
3652                 unsigned short tgt_bit = 1 << tgt_id;
3653                 drvr_opts->tagq_ok &= ~tgt_bit;
3654                 drvr_opts->tagq_ok_mask |= tgt_bit;
3655             }
3656         if (*options == ';')
3657             options++;
3658         if (*options == '\0')
3659             return 0;
3660     }
3661     return 1;
3662 }
3663 
3664 /*
3665   Get it all started
3666 */
3667 
3668 static struct scsi_host_template blogic_template = {
3669     .module = THIS_MODULE,
3670     .proc_name = "BusLogic",
3671     .write_info = blogic_write_info,
3672     .show_info = blogic_show_info,
3673     .name = "BusLogic",
3674     .info = blogic_drvr_info,
3675     .queuecommand = blogic_qcmd,
3676     .slave_configure = blogic_slaveconfig,
3677     .bios_param = blogic_diskparam,
3678     .eh_host_reset_handler = blogic_hostreset,
3679 #if 0
3680     .eh_abort_handler = blogic_abort,
3681 #endif
3682     .max_sectors = 128,
3683 };
3684 
3685 /*
3686   blogic_setup handles processing of Kernel Command Line Arguments.
3687 */
3688 
3689 static int __init blogic_setup(char *str)
3690 {
3691     int ints[3];
3692 
3693     (void) get_options(str, ARRAY_SIZE(ints), ints);
3694 
3695     if (ints[0] != 0) {
3696         blogic_err("BusLogic: Obsolete Command Line Entry Format Ignored\n", NULL);
3697         return 0;
3698     }
3699     if (str == NULL || *str == '\0')
3700         return 0;
3701     return blogic_parseopts(str);
3702 }
3703 
3704 /*
3705  * Exit function.  Deletes all hosts associated with this driver.
3706  */
3707 
3708 static void __exit blogic_exit(void)
3709 {
3710     struct blogic_adapter *ha, *next;
3711 
3712     list_for_each_entry_safe(ha, next, &blogic_host_list, host_list)
3713         blogic_deladapter(ha);
3714 }
3715 
3716 __setup("BusLogic=", blogic_setup);
3717 
3718 #ifdef MODULE
3719 /*static struct pci_device_id blogic_pci_tbl[] = {
3720     { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
3721       PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
3722     { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
3723       PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
3724     { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
3725       PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
3726     { }
3727 };*/
3728 static const struct pci_device_id blogic_pci_tbl[] = {
3729     {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER)},
3730     {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC)},
3731     {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT)},
3732     {0, },
3733 };
3734 #endif
3735 MODULE_DEVICE_TABLE(pci, blogic_pci_tbl);
3736 
3737 module_init(blogic_init);
3738 module_exit(blogic_exit);