// SPDX-License-Identifier: GPL-2.0-only

/*

  Linux Driver for BusLogic MultiMaster and FlashPoint SCSI Host Adapters

  Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>


  The author respectfully requests that any modifications to this software be
  sent directly to him for evaluation and testing.

  Special thanks to Wayne Yen, Jin-Lon Hon, and Alex Win of BusLogic, whose
  advice has been invaluable, to David Gentzel, for writing the original Linux
  BusLogic driver, and to Paul Gortmaker, for being such a dedicated test site.

  Finally, special thanks to Mylex/BusLogic for making the FlashPoint SCCB
  Manager available as freely redistributable source code.

*/

#define blogic_drvr_version		"2.1.17"
#define blogic_drvr_date		"12 September 2013"

#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/types.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/stat.h>
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/jiffies.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/msdos_partition.h>
#include <scsi/scsicam.h>

#include <asm/dma.h>
#include <asm/io.h>

#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
#include "BusLogic.h"
#include "FlashPoint.c"

#ifndef FAILURE
#define FAILURE (-1)
#endif

static const struct scsi_host_template blogic_template;

/*
  blogic_drvr_options_count is a count of the number of BusLogic Driver
  Options specifications provided via the Linux Kernel Command Line or via
  the Loadable Kernel Module Installation Facility.
*/

static int blogic_drvr_options_count;


/*
  blogic_drvr_options is an array of Driver Options structures representing
  BusLogic Driver Options specifications provided via the Linux Kernel Command
  Line or via the Loadable Kernel Module Installation Facility.
*/

static struct blogic_drvr_options blogic_drvr_options[BLOGIC_MAX_ADAPTERS];


/*
  BusLogic can be assigned a string by insmod.
*/

MODULE_DESCRIPTION("BusLogic MultiMaster and FlashPoint SCSI Host Adapter driver");
MODULE_LICENSE("GPL");
#ifdef MODULE
static char *BusLogic;
module_param(BusLogic, charp, 0);
#endif


/*
  blogic_probe_options is a set of Probe Options to be applied across
  all BusLogic Host Adapters.
*/

static struct blogic_probe_options blogic_probe_options;


/*
  blogic_global_options is a set of Global Options to be applied across
  all BusLogic Host Adapters.
*/

static struct blogic_global_options blogic_global_options;

static LIST_HEAD(blogic_host_list);

/*
  blogic_probeinfo_count is the number of entries in blogic_probeinfo_list.
*/

static int blogic_probeinfo_count;


/*
  blogic_probeinfo_list is the list of I/O Addresses and Bus Probe Information
  to be checked for potential BusLogic Host Adapters.  It is initialized by
  interrogating the PCI Configuration Space on PCI machines as well as from the
  list of standard BusLogic I/O Addresses.
*/

static struct blogic_probeinfo *blogic_probeinfo_list;


/*
  blogic_cmd_failure_reason holds a string identifying the reason why a
  call to blogic_cmd failed.  It is only non-NULL when blogic_cmd
  returns a failure code.
*/

static char *blogic_cmd_failure_reason;

/*
  blogic_announce_drvr announces the Driver Version and Date, Author's
  Name, Copyright Notice, and Electronic Mail Address.
*/

static void blogic_announce_drvr(struct blogic_adapter *adapter)
{
	blogic_announce("***** BusLogic SCSI Driver Version " blogic_drvr_version " of " blogic_drvr_date " *****\n", adapter);
	blogic_announce("Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>\n", adapter);
}


/*
  blogic_drvr_info returns the Host Adapter Name to identify this SCSI
  Driver and Host Adapter.
*/

static const char *blogic_drvr_info(struct Scsi_Host *host)
{
	struct blogic_adapter *adapter =
				(struct blogic_adapter *) host->hostdata;
	return adapter->full_model;
}

/*
  blogic_init_ccbs initializes a group of Command Control Blocks (CCBs)
  for Host Adapter from the blk_size bytes located at blk_pointer.  The newly
  created CCBs are added to Host Adapter's free list.
*/

static void blogic_init_ccbs(struct blogic_adapter *adapter, void *blk_pointer,
				int blk_size, dma_addr_t blkp)
{
	struct blogic_ccb *ccb = (struct blogic_ccb *) blk_pointer;
	unsigned int offset = 0;
	memset(blk_pointer, 0, blk_size);
	ccb->allocgrp_head = blkp;
	ccb->allocgrp_size = blk_size;
	while ((blk_size -= sizeof(struct blogic_ccb)) >= 0) {
		ccb->status = BLOGIC_CCB_FREE;
		ccb->adapter = adapter;
		ccb->dma_handle = (u32) blkp + offset;
		if (blogic_flashpoint_type(adapter)) {
			ccb->callback = blogic_qcompleted_ccb;
			ccb->base_addr = adapter->fpinfo.base_addr;
		}
		ccb->next = adapter->free_ccbs;
		ccb->next_all = adapter->all_ccbs;
		adapter->free_ccbs = ccb;
		adapter->all_ccbs = ccb;
		adapter->alloc_ccbs++;
		ccb++;
		offset += sizeof(struct blogic_ccb);
	}
}


/*
  blogic_create_initccbs allocates the initial CCBs for Host Adapter.
*/

static bool __init blogic_create_initccbs(struct blogic_adapter *adapter)
{
	int blk_size = BLOGIC_CCB_GRP_ALLOCSIZE * sizeof(struct blogic_ccb);
	void *blk_pointer;
	dma_addr_t blkp;

	while (adapter->alloc_ccbs < adapter->initccbs) {
		blk_pointer = dma_alloc_coherent(&adapter->pci_device->dev,
				blk_size, &blkp, GFP_KERNEL);
		if (blk_pointer == NULL) {
			blogic_err("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n",
					adapter);
			return false;
		}
		blogic_init_ccbs(adapter, blk_pointer, blk_size, blkp);
	}
	return true;
}


/*
  blogic_destroy_ccbs deallocates the CCBs for Host Adapter.
*/

static void blogic_destroy_ccbs(struct blogic_adapter *adapter)
{
	struct blogic_ccb *next_ccb = adapter->all_ccbs, *ccb, *lastccb = NULL;
	adapter->all_ccbs = NULL;
	adapter->free_ccbs = NULL;
	while ((ccb = next_ccb) != NULL) {
		next_ccb = ccb->next_all;
		if (ccb->allocgrp_head) {
			if (lastccb)
				dma_free_coherent(&adapter->pci_device->dev,
						lastccb->allocgrp_size, lastccb,
						lastccb->allocgrp_head);
			lastccb = ccb;
		}
	}
	if (lastccb)
		dma_free_coherent(&adapter->pci_device->dev,
				lastccb->allocgrp_size, lastccb,
				lastccb->allocgrp_head);
}


/*
  blogic_create_addlccbs allocates Additional CCBs for Host Adapter.  If
  allocation fails and there are no remaining CCBs available, the Driver Queue
  Depth is decreased to a known safe value to avoid potential deadlocks when
  multiple host adapters share the same IRQ Channel.
*/

static void blogic_create_addlccbs(struct blogic_adapter *adapter,
					int addl_ccbs, bool print_success)
{
	int blk_size = BLOGIC_CCB_GRP_ALLOCSIZE * sizeof(struct blogic_ccb);
	int prev_alloc = adapter->alloc_ccbs;
	void *blk_pointer;
	dma_addr_t blkp;
	if (addl_ccbs <= 0)
		return;
	while (adapter->alloc_ccbs - prev_alloc < addl_ccbs) {
		blk_pointer = dma_alloc_coherent(&adapter->pci_device->dev,
				blk_size, &blkp, GFP_KERNEL);
		if (blk_pointer == NULL)
			break;
		blogic_init_ccbs(adapter, blk_pointer, blk_size, blkp);
	}
	if (adapter->alloc_ccbs > prev_alloc) {
		if (print_success)
			blogic_notice("Allocated %d additional CCBs (total now %d)\n", adapter, adapter->alloc_ccbs - prev_alloc, adapter->alloc_ccbs);
		return;
	}
	blogic_notice("Failed to allocate additional CCBs\n", adapter);
	if (adapter->drvr_qdepth > adapter->alloc_ccbs - adapter->tgt_count) {
		adapter->drvr_qdepth = adapter->alloc_ccbs - adapter->tgt_count;
		adapter->scsi_host->can_queue = adapter->drvr_qdepth;
	}
}

/*
  blogic_alloc_ccb allocates a CCB from Host Adapter's free list,
  allocating more memory from the Kernel if necessary.  The Host Adapter's
  Lock should already have been acquired by the caller.
*/

static struct blogic_ccb *blogic_alloc_ccb(struct blogic_adapter *adapter)
{
	static unsigned long serial;
	struct blogic_ccb *ccb;
	ccb = adapter->free_ccbs;
	if (ccb != NULL) {
		ccb->serial = ++serial;
		adapter->free_ccbs = ccb->next;
		ccb->next = NULL;
		if (adapter->free_ccbs == NULL)
			blogic_create_addlccbs(adapter, adapter->inc_ccbs,
						true);
		return ccb;
	}
	blogic_create_addlccbs(adapter, adapter->inc_ccbs, true);
	ccb = adapter->free_ccbs;
	if (ccb == NULL)
		return NULL;
	ccb->serial = ++serial;
	adapter->free_ccbs = ccb->next;
	ccb->next = NULL;
	return ccb;
}


/*
  blogic_dealloc_ccb deallocates a CCB, returning it to the Host Adapter's
  free list.  The Host Adapter's Lock should already have been acquired by the
  caller.
*/

static void blogic_dealloc_ccb(struct blogic_ccb *ccb, int dma_unmap)
{
	struct blogic_adapter *adapter = ccb->adapter;

	if (ccb->command != NULL)
		scsi_dma_unmap(ccb->command);
	if (dma_unmap)
		dma_unmap_single(&adapter->pci_device->dev, ccb->sensedata,
			 ccb->sense_datalen, DMA_FROM_DEVICE);

	ccb->command = NULL;
	ccb->status = BLOGIC_CCB_FREE;
	ccb->next = adapter->free_ccbs;
	adapter->free_ccbs = ccb;
}


/*
  blogic_cmd sends the command opcode to adapter, optionally
  providing paramlen bytes of param and receiving at most
  replylen bytes of reply; any excess reply data is received but
  discarded.

  On success, this function returns the number of reply bytes read from
  the Host Adapter (including any discarded data); on failure, it returns
  -1 if the command was invalid, or -2 if a timeout occurred.

  blogic_cmd is called exclusively during host adapter detection and
  initialization, so performance and latency are not critical, and exclusive
  access to the Host Adapter hardware is assumed.  Once the host adapter and
  driver are initialized, the only Host Adapter command that is issued is the
  single byte Execute Mailbox Command operation code, which does not require
  waiting for the Host Adapter Ready bit to be set in the Status Register.
*/

static int blogic_cmd(struct blogic_adapter *adapter, enum blogic_opcode opcode,
			void *param, int paramlen, void *reply, int replylen)
{
	unsigned char *param_p = (unsigned char *) param;
	unsigned char *reply_p = (unsigned char *) reply;
	union blogic_stat_reg statusreg;
	union blogic_int_reg intreg;
	unsigned long processor_flag = 0;
	int reply_b = 0, result;
	long timeout;
	/*
	   Clear out the Reply Data if provided.
	 */
	if (replylen > 0)
		memset(reply, 0, replylen);
	/*
	   If the IRQ Channel has not yet been acquired, then interrupts
	   must be disabled while issuing host adapter commands since a
	   Command Complete interrupt could occur if the IRQ Channel was
	   previously enabled by another BusLogic Host Adapter or another
	   driver sharing the same IRQ Channel.
	 */
	if (!adapter->irq_acquired)
		local_irq_save(processor_flag);
	/*
	   Wait for the Host Adapter Ready bit to be set and the
	   Command/Parameter Register Busy bit to be reset in the Status
	   Register.
	 */
	timeout = 10000;
	while (--timeout >= 0) {
		statusreg.all = blogic_rdstatus(adapter);
		if (statusreg.sr.adapter_ready && !statusreg.sr.cmd_param_busy)
			break;
		udelay(100);
	}
	if (timeout < 0) {
		blogic_cmd_failure_reason =
				"Timeout waiting for Host Adapter Ready";
		result = -2;
		goto done;
	}
	/*
	   Write the opcode to the Command/Parameter Register.
	 */
	adapter->adapter_cmd_complete = false;
	blogic_setcmdparam(adapter, opcode);
	/*
	   Write any additional Parameter Bytes.
	 */
	timeout = 10000;
	while (paramlen > 0 && --timeout >= 0) {
		/*
		   Wait 100 microseconds to give the Host Adapter enough
		   time to determine whether the last value written to the
		   Command/Parameter Register was valid or not. If the
		   Command Complete bit is set in the Interrupt Register,
		   then the Command Invalid bit in the Status Register will
		   be reset if the Operation Code or Parameter was valid
		   and the command has completed, or set if the Operation
		   Code or Parameter was invalid. If the Data In Register
		   Ready bit is set in the Status Register, then the
		   Operation Code was valid, and data is waiting to be read
		   back from the Host Adapter. Otherwise, wait for the
		   Command/Parameter Register Busy bit in the Status
		   Register to be reset.
		 */
		udelay(100);
		intreg.all = blogic_rdint(adapter);
		statusreg.all = blogic_rdstatus(adapter);
		if (intreg.ir.cmd_complete)
			break;
		if (adapter->adapter_cmd_complete)
			break;
		if (statusreg.sr.datain_ready)
			break;
		if (statusreg.sr.cmd_param_busy)
			continue;
		blogic_setcmdparam(adapter, *param_p++);
		paramlen--;
	}
	if (timeout < 0) {
		blogic_cmd_failure_reason =
				"Timeout waiting for Parameter Acceptance";
		result = -2;
		goto done;
	}
	/*
	   The Modify I/O Address command does not cause a Command Complete
	   Interrupt.
	 */
	if (opcode == BLOGIC_MOD_IOADDR) {
		statusreg.all = blogic_rdstatus(adapter);
		if (statusreg.sr.cmd_invalid) {
			blogic_cmd_failure_reason =
					"Modify I/O Address Invalid";
			result = -1;
			goto done;
		}
		if (blogic_global_options.trace_config)
			blogic_notice("blogic_cmd(%02X) Status = %02X: (Modify I/O Address)\n", adapter, opcode, statusreg.all);
		result = 0;
		goto done;
	}
	/*
	   Select an appropriate timeout value for awaiting command completion.
	 */
	switch (opcode) {
	case BLOGIC_INQ_DEV0TO7:
	case BLOGIC_INQ_DEV8TO15:
	case BLOGIC_INQ_DEV:
		/* Approximately 60 seconds. */
		timeout = 60 * 10000;
		break;
	default:
		/* Approximately 1 second. */
		timeout = 10000;
		break;
	}
	/*
	   Receive any Reply Bytes, waiting for either the Command
	   Complete bit to be set in the Interrupt Register, or for the
	   Interrupt Handler to set the Host Adapter Command Completed
	   bit in the Host Adapter structure.
	 */
	while (--timeout >= 0) {
		intreg.all = blogic_rdint(adapter);
		statusreg.all = blogic_rdstatus(adapter);
		if (intreg.ir.cmd_complete)
			break;
		if (adapter->adapter_cmd_complete)
			break;
		if (statusreg.sr.datain_ready) {
			if (++reply_b <= replylen)
				*reply_p++ = blogic_rddatain(adapter);
			else
				blogic_rddatain(adapter);
		}
		if (opcode == BLOGIC_FETCH_LOCALRAM &&
				statusreg.sr.adapter_ready)
			break;
		udelay(100);
	}
	if (timeout < 0) {
		blogic_cmd_failure_reason =
					"Timeout waiting for Command Complete";
		result = -2;
		goto done;
	}
	/*
	   Clear any pending Command Complete Interrupt.
	 */
	blogic_intreset(adapter);
	/*
	   Provide tracing information if requested.
	 */
	if (blogic_global_options.trace_config) {
		int i;
		blogic_notice("blogic_cmd(%02X) Status = %02X: %2d ==> %2d:",
				adapter, opcode, statusreg.all, replylen,
				reply_b);
		if (replylen > reply_b)
			replylen = reply_b;
		for (i = 0; i < replylen; i++)
			blogic_notice(" %02X", adapter,
					((unsigned char *) reply)[i]);
		blogic_notice("\n", adapter);
	}
	/*
	   Process Command Invalid conditions.
	 */
	if (statusreg.sr.cmd_invalid) {
		/*
		   Some early BusLogic Host Adapters may not recover
		   properly from a Command Invalid condition, so if this
		   appears to be the case, a Soft Reset is issued to the
		   Host Adapter.  Potentially invalid commands are never
		   attempted after Mailbox Initialization is performed,
		   so there should be no Host Adapter state lost by a
		   Soft Reset in response to a Command Invalid condition.
		 */
		udelay(1000);
		statusreg.all = blogic_rdstatus(adapter);
		if (statusreg.sr.cmd_invalid || statusreg.sr.rsvd ||
				statusreg.sr.datain_ready ||
				statusreg.sr.cmd_param_busy ||
				!statusreg.sr.adapter_ready ||
				!statusreg.sr.init_reqd ||
				statusreg.sr.diag_active ||
				statusreg.sr.diag_failed) {
			blogic_softreset(adapter);
			udelay(1000);
		}
		blogic_cmd_failure_reason = "Command Invalid";
		result = -1;
		goto done;
	}
	/*
	   Handle Excess Parameters Supplied conditions.
	 */
	if (paramlen > 0) {
		blogic_cmd_failure_reason = "Excess Parameters Supplied";
		result = -1;
		goto done;
	}
	/*
	   Indicate the command completed successfully.
	 */
	blogic_cmd_failure_reason = NULL;
	result = reply_b;
	/*
	   Restore the interrupt status if necessary and return.
	 */
done:
	if (!adapter->irq_acquired)
		local_irq_restore(processor_flag);
	return result;
}


/*
  blogic_sort_probeinfo sorts a section of blogic_probeinfo_list in order
  of increasing PCI Bus and Device Number.
*/

static void __init blogic_sort_probeinfo(struct blogic_probeinfo
					*probeinfo_list, int probeinfo_cnt)
{
	int last_exchange = probeinfo_cnt - 1, bound, j;

	while (last_exchange > 0) {
		bound = last_exchange;
		last_exchange = 0;
		for (j = 0; j < bound; j++) {
			struct blogic_probeinfo *probeinfo1 =
							&probeinfo_list[j];
			struct blogic_probeinfo *probeinfo2 =
							&probeinfo_list[j + 1];
			if (probeinfo1->bus > probeinfo2->bus ||
				(probeinfo1->bus == probeinfo2->bus &&
				(probeinfo1->dev > probeinfo2->dev))) {
				struct blogic_probeinfo tmp_probeinfo;

				memcpy(&tmp_probeinfo, probeinfo1,
					sizeof(struct blogic_probeinfo));
				memcpy(probeinfo1, probeinfo2,
					sizeof(struct blogic_probeinfo));
				memcpy(probeinfo2, &tmp_probeinfo,
					sizeof(struct blogic_probeinfo));
				last_exchange = j;
			}
		}
	}
}


/*
  blogic_init_mm_probeinfo initializes the list of I/O Address
  and Bus Probe Information to be checked for potential BusLogic MultiMaster
  SCSI Host Adapters by interrogating the PCI Configuration Space on PCI
  machines as well as from the list of standard BusLogic MultiMaster ISA
  I/O Addresses.  It returns the number of PCI MultiMaster Host Adapters found.
*/

static int __init blogic_init_mm_probeinfo(struct blogic_adapter *adapter)
{
	struct blogic_probeinfo *pr_probeinfo =
		&blogic_probeinfo_list[blogic_probeinfo_count];
	int nonpr_mmindex = blogic_probeinfo_count + 1;
	int nonpr_mmcount = 0, mmcount = 0;
	bool force_scan_order = false;
	bool force_scan_order_checked = false;
	struct pci_dev *pci_device = NULL;
	int i;
	if (blogic_probeinfo_count >= BLOGIC_MAX_ADAPTERS)
		return 0;
	blogic_probeinfo_count++;
	/*
	   Iterate over the MultiMaster PCI Host Adapters.  For each
	   enumerated host adapter, determine whether its ISA Compatible
	   I/O Port is enabled and if so, whether it is assigned the
	   Primary I/O Address.  A host adapter that is assigned the
	   Primary I/O Address will always be the preferred boot device.
	   The MultiMaster BIOS will first recognize a host adapter at
	   the Primary I/O Address, then any other PCI host adapters,
	   and finally any host adapters located at the remaining
	   standard ISA I/O Addresses.  When a PCI host adapter is found
	   with its ISA Compatible I/O Port enabled, a command is issued
	   to disable the ISA Compatible I/O Port, and it is noted that the
	   particular standard ISA I/O Address need not be probed.
	 */
	pr_probeinfo->io_addr = 0;
	while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
					PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
					pci_device)) != NULL) {
		struct blogic_adapter *host_adapter = adapter;
		struct blogic_adapter_info adapter_info;
		enum blogic_isa_ioport mod_ioaddr_req;
		unsigned char bus;
		unsigned char device;
		unsigned int irq_ch;
		unsigned long base_addr0;
		unsigned long base_addr1;
		unsigned long io_addr;
		unsigned long pci_addr;

		if (pci_enable_device(pci_device))
			continue;

		if (dma_set_mask(&pci_device->dev, DMA_BIT_MASK(32)))
			continue;

		bus = pci_device->bus->number;
		device = pci_device->devfn >> 3;
		irq_ch = pci_device->irq;
		io_addr = base_addr0 = pci_resource_start(pci_device, 0);
		pci_addr = base_addr1 = pci_resource_start(pci_device, 1);

		if (pci_resource_flags(pci_device, 0) & IORESOURCE_MEM) {
			blogic_err("BusLogic: Base Address0 0x%lX not I/O for MultiMaster Host Adapter\n", NULL, base_addr0);
			blogic_err("at PCI Bus %d Device %d I/O Address 0x%lX\n", NULL, bus, device, io_addr);
			continue;
		}
		if (pci_resource_flags(pci_device, 1) & IORESOURCE_IO) {
			blogic_err("BusLogic: Base Address1 0x%lX not Memory for MultiMaster Host Adapter\n", NULL, base_addr1);
			blogic_err("at PCI Bus %d Device %d PCI Address 0x%lX\n", NULL, bus, device, pci_addr);
			continue;
		}
		if (irq_ch == 0) {
			blogic_err("BusLogic: IRQ Channel %d invalid for MultiMaster Host Adapter\n", NULL, irq_ch);
			blogic_err("at PCI Bus %d Device %d I/O Address 0x%lX\n", NULL, bus, device, io_addr);
			continue;
		}
		if (blogic_global_options.trace_probe) {
			blogic_notice("BusLogic: PCI MultiMaster Host Adapter detected at\n", NULL);
			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);
		}
		/*
		   Issue the Inquire PCI Host Adapter Information command to determine
		   the ISA Compatible I/O Port.  If the ISA Compatible I/O Port is
		   known and enabled, note that the particular Standard ISA I/O
		   Address should not be probed.
		 */
		host_adapter->io_addr = io_addr;
		blogic_intreset(host_adapter);
		if (blogic_cmd(host_adapter, BLOGIC_INQ_PCI_INFO, NULL, 0,
				&adapter_info, sizeof(adapter_info)) !=
				sizeof(adapter_info))
			adapter_info.isa_port = BLOGIC_IO_DISABLE;
		/*
		   Issue the Modify I/O Address command to disable the
		   ISA Compatible I/O Port. On PCI Host Adapters, the
		   Modify I/O Address command allows modification of the
		   ISA compatible I/O Address that the Host Adapter
		   responds to; it does not affect the PCI compliant
		   I/O Address assigned at system initialization.
		 */
		mod_ioaddr_req = BLOGIC_IO_DISABLE;
		blogic_cmd(host_adapter, BLOGIC_MOD_IOADDR, &mod_ioaddr_req,
				sizeof(mod_ioaddr_req), NULL, 0);
		/*
		   For the first MultiMaster Host Adapter enumerated,
		   issue the Fetch Host Adapter Local RAM command to read
		   byte 45 of the AutoSCSI area, for the setting of the
		   "Use Bus And Device # For PCI Scanning Seq." option.
		   Issue the Inquire Board ID command since this option is
		   only valid for the BT-948/958/958D.
		 */
		if (!force_scan_order_checked) {
			struct blogic_fetch_localram fetch_localram;
			struct blogic_autoscsi_byte45 autoscsi_byte45;
			struct blogic_board_id id;

			fetch_localram.offset = BLOGIC_AUTOSCSI_BASE + 45;
			fetch_localram.count = sizeof(autoscsi_byte45);
			blogic_cmd(host_adapter, BLOGIC_FETCH_LOCALRAM,
					&fetch_localram, sizeof(fetch_localram),
					&autoscsi_byte45,
					sizeof(autoscsi_byte45));
			blogic_cmd(host_adapter, BLOGIC_GET_BOARD_ID, NULL, 0,
					&id, sizeof(id));
			if (id.fw_ver_digit1 == '5')
				force_scan_order =
					autoscsi_byte45.force_scan_order;
			force_scan_order_checked = true;
		}
		/*
		   Determine whether this MultiMaster Host Adapter has its
		   ISA Compatible I/O Port enabled and is assigned the
		   Primary I/O Address. If it does, then it is the Primary
		   MultiMaster Host Adapter and must be recognized first.
		   If it does not, then it is added to the list for probing
		   after any Primary MultiMaster Host Adapter is probed.
		 */
		if (adapter_info.isa_port == BLOGIC_IO_330) {
			pr_probeinfo->adapter_type = BLOGIC_MULTIMASTER;
			pr_probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
			pr_probeinfo->io_addr = io_addr;
			pr_probeinfo->pci_addr = pci_addr;
			pr_probeinfo->bus = bus;
			pr_probeinfo->dev = device;
			pr_probeinfo->irq_ch = irq_ch;
			pr_probeinfo->pci_device = pci_dev_get(pci_device);
			mmcount++;
		} else if (blogic_probeinfo_count < BLOGIC_MAX_ADAPTERS) {
			struct blogic_probeinfo *probeinfo =
				&blogic_probeinfo_list[blogic_probeinfo_count++];
			probeinfo->adapter_type = BLOGIC_MULTIMASTER;
			probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
			probeinfo->io_addr = io_addr;
			probeinfo->pci_addr = pci_addr;
			probeinfo->bus = bus;
			probeinfo->dev = device;
			probeinfo->irq_ch = irq_ch;
			probeinfo->pci_device = pci_dev_get(pci_device);
			nonpr_mmcount++;
			mmcount++;
		} else
			blogic_warn("BusLogic: Too many Host Adapters detected\n", NULL);
	}
	/*
	   If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq."
	   option is ON for the first enumerated MultiMaster Host Adapter,
	   and if that host adapter is a BT-948/958/958D, then the
	   MultiMaster BIOS will recognize MultiMaster Host Adapters in
	   the order of increasing PCI Bus and Device Number. In that case,
	   sort the probe information into the same order the BIOS uses.
	   If this option is OFF, then the MultiMaster BIOS will recognize
	   MultiMaster Host Adapters in the order they are enumerated by
	   the PCI BIOS, and hence no sorting is necessary.
	 */
	if (force_scan_order)
		blogic_sort_probeinfo(&blogic_probeinfo_list[nonpr_mmindex],
					nonpr_mmcount);
	/*
	   Iterate over the older non-compliant MultiMaster PCI Host Adapters,
	   noting the PCI bus location and assigned IRQ Channel.
	 */
	pci_device = NULL;
	while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
					PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
					pci_device)) != NULL) {
		unsigned char bus;
		unsigned char device;
		unsigned int irq_ch;
		unsigned long io_addr;

		if (pci_enable_device(pci_device))
			continue;

		if (dma_set_mask(&pci_device->dev, DMA_BIT_MASK(32)))
			continue;

		bus = pci_device->bus->number;
		device = pci_device->devfn >> 3;
		irq_ch = pci_device->irq;
		io_addr = pci_resource_start(pci_device, 0);

		if (io_addr == 0 || irq_ch == 0)
			continue;
		for (i = 0; i < blogic_probeinfo_count; i++) {
			struct blogic_probeinfo *probeinfo =
						&blogic_probeinfo_list[i];
			if (probeinfo->io_addr == io_addr &&
				probeinfo->adapter_type == BLOGIC_MULTIMASTER) {
				probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
				probeinfo->pci_addr = 0;
				probeinfo->bus = bus;
				probeinfo->dev = device;
				probeinfo->irq_ch = irq_ch;
				probeinfo->pci_device = pci_dev_get(pci_device);
				break;
			}
		}
	}
	return mmcount;
}


/*
  blogic_init_fp_probeinfo initializes the list of I/O Address
  and Bus Probe Information to be checked for potential BusLogic FlashPoint
  Host Adapters by interrogating the PCI Configuration Space.  It returns the
  number of FlashPoint Host Adapters found.
*/

static int __init blogic_init_fp_probeinfo(struct blogic_adapter *adapter)
{
	int fpindex = blogic_probeinfo_count, fpcount = 0;
	struct pci_dev *pci_device = NULL;
	/*
	   Interrogate PCI Configuration Space for any FlashPoint Host Adapters.
	 */
	while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
					PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
					pci_device)) != NULL) {
		unsigned char bus;
		unsigned char device;
		unsigned int irq_ch;
		unsigned long base_addr0;
		unsigned long base_addr1;
		unsigned long io_addr;
		unsigned long pci_addr;

		if (pci_enable_device(pci_device))
			continue;

		if (dma_set_mask(&pci_device->dev, DMA_BIT_MASK(32)))
			continue;

		bus = pci_device->bus->number;
		device = pci_device->devfn >> 3;
		irq_ch = pci_device->irq;
		io_addr = base_addr0 = pci_resource_start(pci_device, 0);
		pci_addr = base_addr1 = pci_resource_start(pci_device, 1);
#ifdef CONFIG_SCSI_FLASHPOINT
		if (pci_resource_flags(pci_device, 0) & IORESOURCE_MEM) {
			blogic_err("BusLogic: Base Address0 0x%lX not I/O for FlashPoint Host Adapter\n", NULL, base_addr0);
			blogic_err("at PCI Bus %d Device %d I/O Address 0x%lX\n", NULL, bus, device, io_addr);
			continue;
		}
		if (pci_resource_flags(pci_device, 1) & IORESOURCE_IO) {
			blogic_err("BusLogic: Base Address1 0x%lX not Memory for FlashPoint Host Adapter\n", NULL, base_addr1);
			blogic_err("at PCI Bus %d Device %d PCI Address 0x%lX\n", NULL, bus, device, pci_addr);
			continue;
		}
		if (irq_ch == 0) {
			blogic_err("BusLogic: IRQ Channel %d invalid for FlashPoint Host Adapter\n", NULL, irq_ch);
			blogic_err("at PCI Bus %d Device %d I/O Address 0x%lX\n", NULL, bus, device, io_addr);
			continue;
		}
		if (blogic_global_options.trace_probe) {
			blogic_notice("BusLogic: FlashPoint Host Adapter detected at\n", NULL);
			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);
		}
		if (blogic_probeinfo_count < BLOGIC_MAX_ADAPTERS) {
			struct blogic_probeinfo *probeinfo =
				&blogic_probeinfo_list[blogic_probeinfo_count++];
			probeinfo->adapter_type = BLOGIC_FLASHPOINT;
			probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
			probeinfo->io_addr = io_addr;
			probeinfo->pci_addr = pci_addr;
			probeinfo->bus = bus;
			probeinfo->dev = device;
			probeinfo->irq_ch = irq_ch;
			probeinfo->pci_device = pci_dev_get(pci_device);
			fpcount++;
		} else
			blogic_warn("BusLogic: Too many Host Adapters detected\n", NULL);
#else
		blogic_err("BusLogic: FlashPoint Host Adapter detected at PCI Bus %d Device %d\n", NULL, bus, device);
		blogic_err("BusLogic: I/O Address 0x%lX PCI Address 0x%lX, irq %d, but FlashPoint\n", NULL, io_addr, pci_addr, irq_ch);
		blogic_err("BusLogic: support was omitted in this kernel configuration.\n", NULL);
#endif
	}
	/*
	   The FlashPoint BIOS will scan for FlashPoint Host Adapters in the order of
	   increasing PCI Bus and Device Number, so sort the probe information into
	   the same order the BIOS uses.
	 */
	blogic_sort_probeinfo(&blogic_probeinfo_list[fpindex], fpcount);
	return fpcount;
}


/*
  blogic_init_probeinfo_list initializes the list of I/O Address and Bus
  Probe Information to be checked for potential BusLogic SCSI Host Adapters by
  interrogating the PCI Configuration Space on PCI machines as well as from the
  list of standard BusLogic MultiMaster ISA I/O Addresses.  By default, if both
  FlashPoint and PCI MultiMaster Host Adapters are present, this driver will
  probe for FlashPoint Host Adapters first unless the BIOS primary disk is
  controlled by the first PCI MultiMaster Host Adapter, in which case
  MultiMaster Host Adapters will be probed first.  The BusLogic Driver Options
  specifications "MultiMasterFirst" and "FlashPointFirst" can be used to force
  a particular probe order.
*/

static noinline_for_stack void __init
blogic_init_probeinfo_list(struct blogic_adapter *adapter)
{
	/*
	   If a PCI BIOS is present, interrogate it for MultiMaster and
	   FlashPoint Host Adapters; otherwise, default to the standard
	   ISA MultiMaster probe.
	 */
	if (!blogic_probe_options.noprobe_pci) {
		if (blogic_probe_options.multimaster_first) {
			blogic_init_mm_probeinfo(adapter);
			blogic_init_fp_probeinfo(adapter);
		} else if (blogic_probe_options.flashpoint_first) {
			blogic_init_fp_probeinfo(adapter);
			blogic_init_mm_probeinfo(adapter);
		} else {
			int fpcount = blogic_init_fp_probeinfo(adapter);
			int mmcount = blogic_init_mm_probeinfo(adapter);
			if (fpcount > 0 && mmcount > 0) {
				struct blogic_probeinfo *probeinfo =
					&blogic_probeinfo_list[fpcount];
				struct blogic_adapter *myadapter = adapter;
				struct blogic_fetch_localram fetch_localram;
				struct blogic_bios_drvmap d0_mapbyte;

				while (probeinfo->adapter_bus_type !=
						BLOGIC_PCI_BUS)
					probeinfo++;
				myadapter->io_addr = probeinfo->io_addr;
				fetch_localram.offset =
					BLOGIC_BIOS_BASE + BLOGIC_BIOS_DRVMAP;
				fetch_localram.count = sizeof(d0_mapbyte);
				blogic_cmd(myadapter, BLOGIC_FETCH_LOCALRAM,
						&fetch_localram,
						sizeof(fetch_localram),
						&d0_mapbyte,
						sizeof(d0_mapbyte));
				/*
				   If the Map Byte for BIOS Drive 0 indicates
				   that BIOS Drive 0 is controlled by this
				   PCI MultiMaster Host Adapter, then reverse
				   the probe order so that MultiMaster Host
				   Adapters are probed before FlashPoint Host
				   Adapters.
				 */
				if (d0_mapbyte.diskgeom != BLOGIC_BIOS_NODISK) {
					struct blogic_probeinfo saved_probeinfo[BLOGIC_MAX_ADAPTERS];
					int mmcount = blogic_probeinfo_count - fpcount;

					memcpy(saved_probeinfo,
						blogic_probeinfo_list,
						blogic_probeinfo_count * sizeof(struct blogic_probeinfo));
					memcpy(&blogic_probeinfo_list[0],
						&saved_probeinfo[fpcount],
						mmcount * sizeof(struct blogic_probeinfo));
					memcpy(&blogic_probeinfo_list[mmcount],
						&saved_probeinfo[0],
						fpcount * sizeof(struct blogic_probeinfo));
				}
			}
		}
	}
}


/*
  blogic_failure prints a standardized error message, and then returns false.
*/

static bool blogic_failure(struct blogic_adapter *adapter, char *msg)
{
	blogic_announce_drvr(adapter);
	if (adapter->adapter_bus_type == BLOGIC_PCI_BUS) {
		blogic_err("While configuring BusLogic PCI Host Adapter at\n",
				adapter);
		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);
	} else
		blogic_err("While configuring BusLogic Host Adapter at I/O Address 0x%lX:\n", adapter, adapter->io_addr);
	blogic_err("%s FAILED - DETACHING\n", adapter, msg);
	if (blogic_cmd_failure_reason != NULL)
		blogic_err("ADDITIONAL FAILURE INFO - %s\n", adapter,
				blogic_cmd_failure_reason);
	return false;
}


/*
  blogic_probe probes for a BusLogic Host Adapter.
*/

static bool __init blogic_probe(struct blogic_adapter *adapter)
{
	union blogic_stat_reg statusreg;
	union blogic_int_reg intreg;
	union blogic_geo_reg georeg;
	/*
	   FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager.
	 */
	if (blogic_flashpoint_type(adapter)) {
		struct fpoint_info *fpinfo = &adapter->fpinfo;
		fpinfo->base_addr = (u32) adapter->io_addr;
		fpinfo->irq_ch = adapter->irq_ch;
		fpinfo->present = false;
		if (!(FlashPoint_ProbeHostAdapter(fpinfo) == 0 &&
					fpinfo->present)) {
			blogic_err("BusLogic: FlashPoint Host Adapter detected at PCI Bus %d Device %d\n", adapter, adapter->bus, adapter->dev);
			blogic_err("BusLogic: I/O Address 0x%lX PCI Address 0x%lX, but FlashPoint\n", adapter, adapter->io_addr, adapter->pci_addr);
			blogic_err("BusLogic: Probe Function failed to validate it.\n", adapter);
			return false;
		}
		if (blogic_global_options.trace_probe)
			blogic_notice("BusLogic_Probe(0x%lX): FlashPoint Found\n", adapter, adapter->io_addr);
		/*
		   Indicate the Host Adapter Probe completed successfully.
		 */
		return true;
	}
	/*
	   Read the Status, Interrupt, and Geometry Registers to test if there are I/O
	   ports that respond, and to check the values to determine if they are from a
	   BusLogic Host Adapter.  A nonexistent I/O port will return 0xFF, in which
	   case there is definitely no BusLogic Host Adapter at this base I/O Address.
	   The test here is a subset of that used by the BusLogic Host Adapter BIOS.
	 */
	statusreg.all = blogic_rdstatus(adapter);
	intreg.all = blogic_rdint(adapter);
	georeg.all = blogic_rdgeom(adapter);
	if (blogic_global_options.trace_probe)
		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);
	if (statusreg.all == 0 || statusreg.sr.diag_active ||
			statusreg.sr.cmd_param_busy || statusreg.sr.rsvd ||
			statusreg.sr.cmd_invalid || intreg.ir.rsvd != 0)
		return false;
	/*
	   Check the undocumented Geometry Register to test if there is
	   an I/O port that responded.  Adaptec Host Adapters do not
	   implement the Geometry Register, so this test helps serve to
	   avoid incorrectly recognizing an Adaptec 1542A or 1542B as a
	   BusLogic.  Unfortunately, the Adaptec 1542C series does respond
	   to the Geometry Register I/O port, but it will be rejected
	   later when the Inquire Extended Setup Information command is
	   issued in blogic_checkadapter.  The AMI FastDisk Host Adapter
	   is a BusLogic clone that implements the same interface as
	   earlier BusLogic Host Adapters, including the undocumented
	   commands, and is therefore supported by this driver. However,
	   the AMI FastDisk always returns 0x00 upon reading the Geometry
	   Register, so the extended translation option should always be
	   left disabled on the AMI FastDisk.
	 */
	if (georeg.all == 0xFF)
		return false;
	/*
	   Indicate the Host Adapter Probe completed successfully.
	 */
	return true;
}


/*
  blogic_hwreset issues a Hardware Reset to the Host Adapter
  and waits for Host Adapter Diagnostics to complete.  If hard_reset is true, a
  Hard Reset is performed which also initiates a SCSI Bus Reset.  Otherwise, a
  Soft Reset is performed which only resets the Host Adapter without forcing a
  SCSI Bus Reset.
*/

static bool blogic_hwreset(struct blogic_adapter *adapter, bool hard_reset)
{
	union blogic_stat_reg statusreg;
	int timeout;
	/*
	   FlashPoint Host Adapters are Hard Reset by the FlashPoint
	   SCCB Manager.
	 */
	if (blogic_flashpoint_type(adapter)) {
		struct fpoint_info *fpinfo = &adapter->fpinfo;
		fpinfo->softreset = !hard_reset;
		fpinfo->report_underrun = true;
		adapter->cardhandle =
			FlashPoint_HardwareResetHostAdapter(fpinfo);
		if (adapter->cardhandle == (void *)FPOINT_BADCARD_HANDLE)
			return false;
		/*
		   Indicate the Host Adapter Hard Reset completed successfully.
		 */
		return true;
	}
	/*
	   Issue a Hard Reset or Soft Reset Command to the Host Adapter.
	   The Host Adapter should respond by setting Diagnostic Active in
	   the Status Register.
	 */
	if (hard_reset)
		blogic_hardreset(adapter);
	else
		blogic_softreset(adapter);
	/*
	   Wait until Diagnostic Active is set in the Status Register.
	 */
	timeout = 5 * 10000;
	while (--timeout >= 0) {
		statusreg.all = blogic_rdstatus(adapter);
		if (statusreg.sr.diag_active)
			break;
		udelay(100);
	}
	if (blogic_global_options.trace_hw_reset)
		blogic_notice("BusLogic_HardwareReset(0x%lX): Diagnostic Active, Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
	if (timeout < 0)
		return false;
	/*
	   Wait 100 microseconds to allow completion of any initial diagnostic
	   activity which might leave the contents of the Status Register
	   unpredictable.
	 */
	udelay(100);
	/*
	   Wait until Diagnostic Active is reset in the Status Register.
	 */
	timeout = 10 * 10000;
	while (--timeout >= 0) {
		statusreg.all = blogic_rdstatus(adapter);
		if (!statusreg.sr.diag_active)
			break;
		udelay(100);
	}
	if (blogic_global_options.trace_hw_reset)
		blogic_notice("BusLogic_HardwareReset(0x%lX): Diagnostic Completed, Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
	if (timeout < 0)
		return false;
	/*
	   Wait until at least one of the Diagnostic Failure, Host Adapter
	   Ready, or Data In Register Ready bits is set in the Status Register.
	 */
	timeout = 10000;
	while (--timeout >= 0) {
		statusreg.all = blogic_rdstatus(adapter);
		if (statusreg.sr.diag_failed || statusreg.sr.adapter_ready ||
				statusreg.sr.datain_ready)
			break;
		udelay(100);
	}
	if (blogic_global_options.trace_hw_reset)
		blogic_notice("BusLogic_HardwareReset(0x%lX): Host Adapter Ready, Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
	if (timeout < 0)
		return false;
	/*
	   If Diagnostic Failure is set or Host Adapter Ready is reset,
	   then an error occurred during the Host Adapter diagnostics.
	   If Data In Register Ready is set, then there is an Error Code
	   available.
	 */
	if (statusreg.sr.diag_failed || !statusreg.sr.adapter_ready) {
		blogic_cmd_failure_reason = NULL;
		blogic_failure(adapter, "HARD RESET DIAGNOSTICS");
		blogic_err("HOST ADAPTER STATUS REGISTER = %02X\n", adapter,
				statusreg.all);
		if (statusreg.sr.datain_ready)
			blogic_err("HOST ADAPTER ERROR CODE = %d\n", adapter,
					blogic_rddatain(adapter));
		return false;
	}
	/*
	   Indicate the Host Adapter Hard Reset completed successfully.
	 */
	return true;
}


/*
  blogic_checkadapter checks to be sure this really is a BusLogic
  Host Adapter.
*/

static bool __init blogic_checkadapter(struct blogic_adapter *adapter)
{
	struct blogic_ext_setup ext_setupinfo;
	unsigned char req_replylen;
	bool result = true;
	/*
	   FlashPoint Host Adapters do not require this protection.
	 */
	if (blogic_flashpoint_type(adapter))
		return true;
	/*
	   Issue the Inquire Extended Setup Information command. Only genuine
	   BusLogic Host Adapters and true clones support this command.
	   Adaptec 1542C series Host Adapters that respond to the Geometry
	   Register I/O port will fail this command.
	 */
	req_replylen = sizeof(ext_setupinfo);
	if (blogic_cmd(adapter, BLOGIC_INQ_EXTSETUP, &req_replylen,
				sizeof(req_replylen), &ext_setupinfo,
				sizeof(ext_setupinfo)) != sizeof(ext_setupinfo))
		result = false;
	/*
	   Provide tracing information if requested and return.
	 */
	if (blogic_global_options.trace_probe)
		blogic_notice("BusLogic_Check(0x%lX): MultiMaster %s\n", adapter,
				adapter->io_addr,
				(result ? "Found" : "Not Found"));
	return result;
}


/*
  blogic_rdconfig reads the Configuration Information
  from Host Adapter and initializes the Host Adapter structure.
*/

static bool __init blogic_rdconfig(struct blogic_adapter *adapter)
{
	struct blogic_board_id id;
	struct blogic_config config;
	struct blogic_setup_info setupinfo;
	struct blogic_ext_setup ext_setupinfo;
	unsigned char model[5];
	unsigned char fw_ver_digit3;
	unsigned char fw_ver_letter;
	struct blogic_adapter_info adapter_info;
	struct blogic_fetch_localram fetch_localram;
	struct blogic_autoscsi autoscsi;
	union blogic_geo_reg georeg;
	unsigned char req_replylen;
	unsigned char *tgt, ch;
	int tgt_id, i;
	/*
	   Configuration Information for FlashPoint Host Adapters is
	   provided in the fpoint_info structure by the FlashPoint
	   SCCB Manager's Probe Function. Initialize fields in the
	   Host Adapter structure from the fpoint_info structure.
	 */
	if (blogic_flashpoint_type(adapter)) {
		struct fpoint_info *fpinfo = &adapter->fpinfo;
		tgt = adapter->model;
		*tgt++ = 'B';
		*tgt++ = 'T';
		*tgt++ = '-';
		for (i = 0; i < sizeof(fpinfo->model); i++)
			*tgt++ = fpinfo->model[i];
		*tgt++ = '\0';
		strcpy(adapter->fw_ver, FLASHPOINT_FW_VER);
		adapter->scsi_id = fpinfo->scsi_id;
		adapter->ext_trans_enable = fpinfo->ext_trans_enable;
		adapter->parity = fpinfo->parity;
		adapter->reset_enabled = !fpinfo->softreset;
		adapter->level_int = true;
		adapter->wide = fpinfo->wide;
		adapter->differential = false;
		adapter->scam = true;
		adapter->ultra = true;
		adapter->ext_lun = true;
		adapter->terminfo_valid = true;
		adapter->low_term = fpinfo->low_term;
		adapter->high_term = fpinfo->high_term;
		adapter->scam_enabled = fpinfo->scam_enabled;
		adapter->scam_lev2 = fpinfo->scam_lev2;
		adapter->drvr_sglimit = BLOGIC_SG_LIMIT;
		adapter->maxdev = (adapter->wide ? 16 : 8);
		adapter->maxlun = 32;
		adapter->initccbs = 4 * BLOGIC_CCB_GRP_ALLOCSIZE;
		adapter->inc_ccbs = BLOGIC_CCB_GRP_ALLOCSIZE;
		adapter->drvr_qdepth = 255;
		adapter->adapter_qdepth = adapter->drvr_qdepth;
		adapter->sync_ok = fpinfo->sync_ok;
		adapter->fast_ok = fpinfo->fast_ok;
		adapter->ultra_ok = fpinfo->ultra_ok;
		adapter->wide_ok = fpinfo->wide_ok;
		adapter->discon_ok = fpinfo->discon_ok;
		adapter->tagq_ok = 0xFFFF;
		goto common;
	}
	/*
	   Issue the Inquire Board ID command.
	 */
	if (blogic_cmd(adapter, BLOGIC_GET_BOARD_ID, NULL, 0, &id,
				sizeof(id)) != sizeof(id))
		return blogic_failure(adapter, "INQUIRE BOARD ID");
	/*
	   Issue the Inquire Configuration command.
	 */
	if (blogic_cmd(adapter, BLOGIC_INQ_CONFIG, NULL, 0, &config,
				sizeof(config))
	    != sizeof(config))
		return blogic_failure(adapter, "INQUIRE CONFIGURATION");
	/*
	   Issue the Inquire Setup Information command.
	 */
	req_replylen = sizeof(setupinfo);
	if (blogic_cmd(adapter, BLOGIC_INQ_SETUPINFO, &req_replylen,
				sizeof(req_replylen), &setupinfo,
				sizeof(setupinfo)) != sizeof(setupinfo))
		return blogic_failure(adapter, "INQUIRE SETUP INFORMATION");
	/*
	   Issue the Inquire Extended Setup Information command.
	 */
	req_replylen = sizeof(ext_setupinfo);
	if (blogic_cmd(adapter, BLOGIC_INQ_EXTSETUP, &req_replylen,
				sizeof(req_replylen), &ext_setupinfo,
				sizeof(ext_setupinfo)) != sizeof(ext_setupinfo))
		return blogic_failure(adapter,
					"INQUIRE EXTENDED SETUP INFORMATION");
	/*
	   Issue the Inquire Firmware Version 3rd Digit command.
	 */
	fw_ver_digit3 = '\0';
	if (id.fw_ver_digit1 > '0')
		if (blogic_cmd(adapter, BLOGIC_INQ_FWVER_D3, NULL, 0,
				&fw_ver_digit3,
				sizeof(fw_ver_digit3)) != sizeof(fw_ver_digit3))
			return blogic_failure(adapter,
						"INQUIRE FIRMWARE 3RD DIGIT");
	/*
	   Issue the Inquire Host Adapter Model Number command.
	 */
	if (ext_setupinfo.bus_type == 'A' && id.fw_ver_digit1 == '2')
		/* BusLogic BT-542B ISA 2.xx */
		strcpy(model, "542B");
	else if (ext_setupinfo.bus_type == 'E' && id.fw_ver_digit1 == '2' &&
			(id.fw_ver_digit2 <= '1' || (id.fw_ver_digit2 == '2' &&
						     fw_ver_digit3 == '0')))
		/* BusLogic BT-742A EISA 2.1x or 2.20 */
		strcpy(model, "742A");
	else if (ext_setupinfo.bus_type == 'E' && id.fw_ver_digit1 == '0')
		/* AMI FastDisk EISA Series 441 0.x */
		strcpy(model, "747A");
	else {
		req_replylen = sizeof(model);
		if (blogic_cmd(adapter, BLOGIC_INQ_MODELNO, &req_replylen,
					sizeof(req_replylen), &model,
					sizeof(model)) != sizeof(model))
			return blogic_failure(adapter,
					"INQUIRE HOST ADAPTER MODEL NUMBER");
	}
	/*
	   BusLogic MultiMaster Host Adapters can be identified by their
	   model number and the major version number of their firmware
	   as follows:

	   5.xx       BusLogic "W" Series Host Adapters:
	   BT-948/958/958D
	   4.xx       BusLogic "C" Series Host Adapters:
	   BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
	   3.xx       BusLogic "S" Series Host Adapters:
	   BT-747S/747D/757S/757D/445S/545S/542D
	   BT-542B/742A (revision H)
	   2.xx       BusLogic "A" Series Host Adapters:
	   BT-542B/742A (revision G and below)
	   0.xx       AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
	 */
	/*
	   Save the Model Name and Host Adapter Name in the Host Adapter
	   structure.
	 */
	tgt = adapter->model;
	*tgt++ = 'B';
	*tgt++ = 'T';
	*tgt++ = '-';
	for (i = 0; i < sizeof(model); i++) {
		ch = model[i];
		if (ch == ' ' || ch == '\0')
			break;
		*tgt++ = ch;
	}
	*tgt++ = '\0';
	/*
	   Save the Firmware Version in the Host Adapter structure.
	 */
	tgt = adapter->fw_ver;
	*tgt++ = id.fw_ver_digit1;
	*tgt++ = '.';
	*tgt++ = id.fw_ver_digit2;
	if (fw_ver_digit3 != ' ' && fw_ver_digit3 != '\0')
		*tgt++ = fw_ver_digit3;
	*tgt = '\0';
	/*
	   Issue the Inquire Firmware Version Letter command.
	 */
	if (strcmp(adapter->fw_ver, "3.3") >= 0) {
		if (blogic_cmd(adapter, BLOGIC_INQ_FWVER_LETTER, NULL, 0,
				&fw_ver_letter,
				sizeof(fw_ver_letter)) != sizeof(fw_ver_letter))
			return blogic_failure(adapter,
					"INQUIRE FIRMWARE VERSION LETTER");
		if (fw_ver_letter != ' ' && fw_ver_letter != '\0')
			*tgt++ = fw_ver_letter;
		*tgt = '\0';
	}
	/*
	   Save the Host Adapter SCSI ID in the Host Adapter structure.
	 */
	adapter->scsi_id = config.id;
	/*
	   Determine the Bus Type and save it in the Host Adapter structure,
	   determine and save the IRQ Channel if necessary, and determine
	   and save the DMA Channel for ISA Host Adapters.
	 */
	adapter->adapter_bus_type =
			blogic_adater_bus_types[adapter->model[3] - '4'];
	if (adapter->irq_ch == 0) {
		if (config.irq_ch9)
			adapter->irq_ch = 9;
		else if (config.irq_ch10)
			adapter->irq_ch = 10;
		else if (config.irq_ch11)
			adapter->irq_ch = 11;
		else if (config.irq_ch12)
			adapter->irq_ch = 12;
		else if (config.irq_ch14)
			adapter->irq_ch = 14;
		else if (config.irq_ch15)
			adapter->irq_ch = 15;
	}
	/*
	   Determine whether Extended Translation is enabled and save it in
	   the Host Adapter structure.
	 */
	georeg.all = blogic_rdgeom(adapter);
	adapter->ext_trans_enable = georeg.gr.ext_trans_enable;
	/*
	   Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide
	   SCSI flag, Differential SCSI flag, SCAM Supported flag, and
	   Ultra SCSI flag in the Host Adapter structure.
	 */
	adapter->adapter_sglimit = ext_setupinfo.sg_limit;
	adapter->drvr_sglimit = adapter->adapter_sglimit;
	if (adapter->adapter_sglimit > BLOGIC_SG_LIMIT)
		adapter->drvr_sglimit = BLOGIC_SG_LIMIT;
	if (ext_setupinfo.misc.level_int)
		adapter->level_int = true;
	adapter->wide = ext_setupinfo.wide;
	adapter->differential = ext_setupinfo.differential;
	adapter->scam = ext_setupinfo.scam;
	adapter->ultra = ext_setupinfo.ultra;
	/*
	   Determine whether Extended LUN Format CCBs are supported and save the
	   information in the Host Adapter structure.
	 */
	if (adapter->fw_ver[0] == '5' || (adapter->fw_ver[0] == '4' &&
				adapter->wide))
		adapter->ext_lun = true;
	/*
	   Issue the Inquire PCI Host Adapter Information command to read the
	   Termination Information from "W" series MultiMaster Host Adapters.
	 */
	if (adapter->fw_ver[0] == '5') {
		if (blogic_cmd(adapter, BLOGIC_INQ_PCI_INFO, NULL, 0,
				&adapter_info,
				sizeof(adapter_info)) != sizeof(adapter_info))
			return blogic_failure(adapter,
					"INQUIRE PCI HOST ADAPTER INFORMATION");
		/*
		   Save the Termination Information in the Host Adapter
		   structure.
		 */
		if (adapter_info.genericinfo_valid) {
			adapter->terminfo_valid = true;
			adapter->low_term = adapter_info.low_term;
			adapter->high_term = adapter_info.high_term;
		}
	}
	/*
	   Issue the Fetch Host Adapter Local RAM command to read the
	   AutoSCSI data from "W" and "C" series MultiMaster Host Adapters.
	 */
	if (adapter->fw_ver[0] >= '4') {
		fetch_localram.offset = BLOGIC_AUTOSCSI_BASE;
		fetch_localram.count = sizeof(autoscsi);
		if (blogic_cmd(adapter, BLOGIC_FETCH_LOCALRAM, &fetch_localram,
					sizeof(fetch_localram), &autoscsi,
					sizeof(autoscsi)) != sizeof(autoscsi))
			return blogic_failure(adapter,
						"FETCH HOST ADAPTER LOCAL RAM");
		/*
		   Save the Parity Checking Enabled, Bus Reset Enabled,
		   and Termination Information in the Host Adapter structure.
		 */
		adapter->parity = autoscsi.parity;
		adapter->reset_enabled = autoscsi.reset_enabled;
		if (adapter->fw_ver[0] == '4') {
			adapter->terminfo_valid = true;
			adapter->low_term = autoscsi.low_term;
			adapter->high_term = autoscsi.high_term;
		}
		/*
		   Save the Wide Permitted, Fast Permitted, Synchronous
		   Permitted, Disconnect Permitted, Ultra Permitted, and
		   SCAM Information in the Host Adapter structure.
		 */
		adapter->wide_ok = autoscsi.wide_ok;
		adapter->fast_ok = autoscsi.fast_ok;
		adapter->sync_ok = autoscsi.sync_ok;
		adapter->discon_ok = autoscsi.discon_ok;
		if (adapter->ultra)
			adapter->ultra_ok = autoscsi.ultra_ok;
		if (adapter->scam) {
			adapter->scam_enabled = autoscsi.scam_enabled;
			adapter->scam_lev2 = autoscsi.scam_lev2;
		}
	}
	/*
	   Initialize fields in the Host Adapter structure for "S" and "A"
	   series MultiMaster Host Adapters.
	 */
	if (adapter->fw_ver[0] < '4') {
		if (setupinfo.sync) {
			adapter->sync_ok = 0xFF;
			if (adapter->adapter_bus_type == BLOGIC_EISA_BUS) {
				if (ext_setupinfo.misc.fast_on_eisa)
					adapter->fast_ok = 0xFF;
				if (strcmp(adapter->model, "BT-757") == 0)
					adapter->wide_ok = 0xFF;
			}
		}
		adapter->discon_ok = 0xFF;
		adapter->parity = setupinfo.parity;
		adapter->reset_enabled = true;
	}
	/*
	   Determine the maximum number of Target IDs and Logical Units
	   supported by this driver for Wide and Narrow Host Adapters.
	 */
	adapter->maxdev = (adapter->wide ? 16 : 8);
	adapter->maxlun = (adapter->ext_lun ? 32 : 8);
	/*
	   Select appropriate values for the Mailbox Count, Driver Queue Depth,
	   Initial CCBs, and Incremental CCBs variables based on whether
	   or not Strict Round Robin Mode is supported.  If Strict Round
	   Robin Mode is supported, then there is no performance degradation
	   in using the maximum possible number of Outgoing and Incoming
	   Mailboxes and allowing the Tagged and Untagged Queue Depths to
	   determine the actual utilization.  If Strict Round Robin Mode is
	   not supported, then the Host Adapter must scan all the Outgoing
	   Mailboxes whenever an Outgoing Mailbox entry is made, which can
	   cause a substantial performance penalty.  The host adapters
	   actually have room to store the following number of CCBs
	   internally; that is, they can internally queue and manage this
	   many active commands on the SCSI bus simultaneously.  Performance
	   measurements demonstrate that the Driver Queue Depth should be
	   set to the Mailbox Count, rather than the Host Adapter Queue
	   Depth (internal CCB capacity), as it is more efficient to have the
	   queued commands waiting in Outgoing Mailboxes if necessary than
	   to block the process in the higher levels of the SCSI Subsystem.

	   192          BT-948/958/958D
	   100          BT-946C/956C/956CD/747C/757C/757CD/445C
	   50   BT-545C/540CF
	   30   BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
	 */
	if (adapter->fw_ver[0] == '5')
		adapter->adapter_qdepth = 192;
	else if (adapter->fw_ver[0] == '4')
		adapter->adapter_qdepth = 100;
	else
		adapter->adapter_qdepth = 30;
	if (strcmp(adapter->fw_ver, "3.31") >= 0) {
		adapter->strict_rr = true;
		adapter->mbox_count = BLOGIC_MAX_MAILBOX;
	} else {
		adapter->strict_rr = false;
		adapter->mbox_count = 32;
	}
	adapter->drvr_qdepth = adapter->mbox_count;
	adapter->initccbs = 4 * BLOGIC_CCB_GRP_ALLOCSIZE;
	adapter->inc_ccbs = BLOGIC_CCB_GRP_ALLOCSIZE;
	/*
	   Tagged Queuing support is available and operates properly on
	   all "W" series MultiMaster Host Adapters, on "C" series
	   MultiMaster Host Adapters with firmware version 4.22 and above,
	   and on "S" series MultiMaster Host Adapters with firmware version
	   3.35 and above.
	 */
	adapter->tagq_ok = 0;
	switch (adapter->fw_ver[0]) {
	case '5':
		adapter->tagq_ok = 0xFFFF;
		break;
	case '4':
		if (strcmp(adapter->fw_ver, "4.22") >= 0)
			adapter->tagq_ok = 0xFFFF;
		break;
	case '3':
		if (strcmp(adapter->fw_ver, "3.35") >= 0)
			adapter->tagq_ok = 0xFFFF;
		break;
	}
	/*
	   Determine the Host Adapter BIOS Address if the BIOS is enabled and
	   save it in the Host Adapter structure.  The BIOS is disabled if the
	   bios_addr is 0.
	 */
	adapter->bios_addr = ext_setupinfo.bios_addr << 12;
	/*
	   BusLogic BT-445S Host Adapters prior to board revision E have a
	   hardware bug whereby when the BIOS is enabled, transfers to/from
	   the same address range the BIOS occupies modulo 16MB are handled
	   incorrectly.  Only properly functioning BT-445S Host Adapters
	   have firmware version 3.37.
	 */
	if (adapter->bios_addr > 0 &&
	    strcmp(adapter->model, "BT-445S") == 0 &&
	    strcmp(adapter->fw_ver, "3.37") < 0)
		return blogic_failure(adapter, "Too old firmware");
	/*
	   Initialize parameters common to MultiMaster and FlashPoint
	   Host Adapters.
	 */
common:
	/*
	   Initialize the Host Adapter Full Model Name from the Model Name.
	 */
	strcpy(adapter->full_model, "BusLogic ");
	strcat(adapter->full_model, adapter->model);
	/*
	   Select an appropriate value for the Tagged Queue Depth either from a
	   BusLogic Driver Options specification, or based on whether this Host
	   Adapter requires that ISA Bounce Buffers be used.  The Tagged Queue
	   Depth is left at 0 for automatic determination in
	   BusLogic_SelectQueueDepths. Initialize the Untagged Queue Depth.
	 */
	for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++) {
		unsigned char qdepth = 0;
		if (adapter->drvr_opts != NULL &&
				adapter->drvr_opts->qdepth[tgt_id] > 0)
			qdepth = adapter->drvr_opts->qdepth[tgt_id];
		adapter->qdepth[tgt_id] = qdepth;
	}
	adapter->untag_qdepth = BLOGIC_UNTAG_DEPTH;
	if (adapter->drvr_opts != NULL)
		adapter->common_qdepth = adapter->drvr_opts->common_qdepth;
	if (adapter->common_qdepth > 0 &&
			adapter->common_qdepth < adapter->untag_qdepth)
		adapter->untag_qdepth = adapter->common_qdepth;
	/*
	   Tagged Queuing is only allowed if Disconnect/Reconnect is permitted.
	   Therefore, mask the Tagged Queuing Permitted Default bits with the
	   Disconnect/Reconnect Permitted bits.
	 */
	adapter->tagq_ok &= adapter->discon_ok;
	/*
	   Combine the default Tagged Queuing Permitted bits with any
	   BusLogic Driver Options Tagged Queuing specification.
	 */
	if (adapter->drvr_opts != NULL)
		adapter->tagq_ok = (adapter->drvr_opts->tagq_ok &
				adapter->drvr_opts->tagq_ok_mask) |
			(adapter->tagq_ok & ~adapter->drvr_opts->tagq_ok_mask);

	/*
	   Select an appropriate value for Bus Settle Time either from a
	   BusLogic Driver Options specification, or from
	   BLOGIC_BUS_SETTLE_TIME.
	 */
	if (adapter->drvr_opts != NULL &&
			adapter->drvr_opts->bus_settle_time > 0)
		adapter->bus_settle_time = adapter->drvr_opts->bus_settle_time;
	else
		adapter->bus_settle_time = BLOGIC_BUS_SETTLE_TIME;
	/*
	   Indicate reading the Host Adapter Configuration completed
	   successfully.
	 */
	return true;
}


/*
  blogic_reportconfig reports the configuration of Host Adapter.
*/

static noinline_for_stack bool __init
blogic_reportconfig(struct blogic_adapter *adapter)
{
	unsigned short alltgt_mask = (1 << adapter->maxdev) - 1;
	unsigned short sync_ok, fast_ok;
	unsigned short ultra_ok, wide_ok;
	unsigned short discon_ok, tagq_ok;
	bool common_syncneg, common_tagq_depth;
	char syncstr[BLOGIC_MAXDEV + 1];
	char widestr[BLOGIC_MAXDEV + 1];
	char discon_str[BLOGIC_MAXDEV + 1];
	char tagq_str[BLOGIC_MAXDEV + 1];
	char *syncmsg = syncstr;
	char *widemsg = widestr;
	char *discon_msg = discon_str;
	char *tagq_msg = tagq_str;
	int tgt_id;

	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" : ""));
	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"));
	if (adapter->adapter_bus_type != BLOGIC_PCI_BUS) {
		blogic_info("  DMA Channel: None, ", adapter);
		if (adapter->bios_addr > 0)
			blogic_info("BIOS Address: 0x%X, ", adapter,
					adapter->bios_addr);
		else
			blogic_info("BIOS Address: None, ", adapter);
	} else {
		blogic_info("  PCI Bus: %d, Device: %d, Address: ", adapter,
				adapter->bus, adapter->dev);
		if (adapter->pci_addr > 0)
			blogic_info("0x%lX, ", adapter, adapter->pci_addr);
		else
			blogic_info("Unassigned, ", adapter);
	}
	blogic_info("Host Adapter SCSI ID: %d\n", adapter, adapter->scsi_id);
	blogic_info("  Parity Checking: %s, Extended Translation: %s\n",
			adapter, (adapter->parity ? "Enabled" : "Disabled"),
			(adapter->ext_trans_enable ? "Enabled" : "Disabled"));
	alltgt_mask &= ~(1 << adapter->scsi_id);
	sync_ok = adapter->sync_ok & alltgt_mask;
	fast_ok = adapter->fast_ok & alltgt_mask;
	ultra_ok = adapter->ultra_ok & alltgt_mask;
	if ((blogic_multimaster_type(adapter) &&
			(adapter->fw_ver[0] >= '4' ||
			 adapter->adapter_bus_type == BLOGIC_EISA_BUS)) ||
			blogic_flashpoint_type(adapter)) {
		common_syncneg = false;
		if (sync_ok == 0) {
			syncmsg = "Disabled";
			common_syncneg = true;
		} else if (sync_ok == alltgt_mask) {
			if (fast_ok == 0) {
				syncmsg = "Slow";
				common_syncneg = true;
			} else if (fast_ok == alltgt_mask) {
				if (ultra_ok == 0) {
					syncmsg = "Fast";
					common_syncneg = true;
				} else if (ultra_ok == alltgt_mask) {
					syncmsg = "Ultra";
					common_syncneg = true;
				}
			}
		}
		if (!common_syncneg) {
			for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
				syncstr[tgt_id] = ((!(sync_ok & (1 << tgt_id))) ? 'N' : (!(fast_ok & (1 << tgt_id)) ? 'S' : (!(ultra_ok & (1 << tgt_id)) ? 'F' : 'U')));
			syncstr[adapter->scsi_id] = '#';
			syncstr[adapter->maxdev] = '\0';
		}
	} else
		syncmsg = (sync_ok == 0 ? "Disabled" : "Enabled");
	wide_ok = adapter->wide_ok & alltgt_mask;
	if (wide_ok == 0)
		widemsg = "Disabled";
	else if (wide_ok == alltgt_mask)
		widemsg = "Enabled";
	else {
		for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
			widestr[tgt_id] = ((wide_ok & (1 << tgt_id)) ? 'Y' : 'N');
		widestr[adapter->scsi_id] = '#';
		widestr[adapter->maxdev] = '\0';
	}
	discon_ok = adapter->discon_ok & alltgt_mask;
	if (discon_ok == 0)
		discon_msg = "Disabled";
	else if (discon_ok == alltgt_mask)
		discon_msg = "Enabled";
	else {
		for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
			discon_str[tgt_id] = ((discon_ok & (1 << tgt_id)) ? 'Y' : 'N');
		discon_str[adapter->scsi_id] = '#';
		discon_str[adapter->maxdev] = '\0';
	}
	tagq_ok = adapter->tagq_ok & alltgt_mask;
	if (tagq_ok == 0)
		tagq_msg = "Disabled";
	else if (tagq_ok == alltgt_mask)
		tagq_msg = "Enabled";
	else {
		for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
			tagq_str[tgt_id] = ((tagq_ok & (1 << tgt_id)) ? 'Y' : 'N');
		tagq_str[adapter->scsi_id] = '#';
		tagq_str[adapter->maxdev] = '\0';
	}
	blogic_info("  Synchronous Negotiation: %s, Wide Negotiation: %s\n",
			adapter, syncmsg, widemsg);
	blogic_info("  Disconnect/Reconnect: %s, Tagged Queuing: %s\n", adapter,
			discon_msg, tagq_msg);
	if (blogic_multimaster_type(adapter)) {
		blogic_info("  Scatter/Gather Limit: %d of %d segments, Mailboxes: %d\n", adapter, adapter->drvr_sglimit, adapter->adapter_sglimit, adapter->mbox_count);
		blogic_info("  Driver Queue Depth: %d, Host Adapter Queue Depth: %d\n", adapter, adapter->drvr_qdepth, adapter->adapter_qdepth);
	} else
		blogic_info("  Driver Queue Depth: %d, Scatter/Gather Limit: %d segments\n", adapter, adapter->drvr_qdepth, adapter->drvr_sglimit);
	blogic_info("  Tagged Queue Depth: ", adapter);
	common_tagq_depth = true;
	for (tgt_id = 1; tgt_id < adapter->maxdev; tgt_id++)
		if (adapter->qdepth[tgt_id] != adapter->qdepth[0]) {
			common_tagq_depth = false;
			break;
		}
	if (common_tagq_depth) {
		if (adapter->qdepth[0] > 0)
			blogic_info("%d", adapter, adapter->qdepth[0]);
		else
			blogic_info("Automatic", adapter);
	} else
		blogic_info("Individual", adapter);
	blogic_info(", Untagged Queue Depth: %d\n", adapter,
			adapter->untag_qdepth);
	if (adapter->terminfo_valid) {
		if (adapter->wide)
			blogic_info("  SCSI Bus Termination: %s", adapter,
				(adapter->low_term ? (adapter->high_term ? "Both Enabled" : "Low Enabled") : (adapter->high_term ? "High Enabled" : "Both Disabled")));
		else
			blogic_info("  SCSI Bus Termination: %s", adapter,
				(adapter->low_term ? "Enabled" : "Disabled"));
		if (adapter->scam)
			blogic_info(", SCAM: %s", adapter,
				(adapter->scam_enabled ? (adapter->scam_lev2 ? "Enabled, Level 2" : "Enabled, Level 1") : "Disabled"));
		blogic_info("\n", adapter);
	}
	/*
	   Indicate reporting the Host Adapter configuration completed
	   successfully.
	 */
	return true;
}


/*
  blogic_getres acquires the system resources necessary to use
  Host Adapter.
*/

static bool __init blogic_getres(struct blogic_adapter *adapter)
{
	if (adapter->irq_ch == 0) {
		blogic_err("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n",
				adapter);
		return false;
	}
	/*
	   Acquire shared access to the IRQ Channel.
	 */
	if (request_irq(adapter->irq_ch, blogic_inthandler, IRQF_SHARED,
				adapter->full_model, adapter) < 0) {
		blogic_err("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
				adapter, adapter->irq_ch);
		return false;
	}
	adapter->irq_acquired = true;
	/*
	   Indicate the System Resource Acquisition completed successfully,
	 */
	return true;
}


/*
  blogic_relres releases any system resources previously acquired
  by blogic_getres.
*/

static void blogic_relres(struct blogic_adapter *adapter)
{
	/*
	   Release shared access to the IRQ Channel.
	 */
	if (adapter->irq_acquired)
		free_irq(adapter->irq_ch, adapter);
	/*
	   Release any allocated memory structs not released elsewhere
	 */
	if (adapter->mbox_space)
		dma_free_coherent(&adapter->pci_device->dev, adapter->mbox_sz,
			adapter->mbox_space, adapter->mbox_space_handle);
	pci_dev_put(adapter->pci_device);
	adapter->mbox_space = NULL;
	adapter->mbox_space_handle = 0;
	adapter->mbox_sz = 0;
}


/*
  blogic_initadapter initializes Host Adapter.  This is the only
  function called during SCSI Host Adapter detection which modifies the state
  of the Host Adapter from its initial power on or hard reset state.
*/

static bool blogic_initadapter(struct blogic_adapter *adapter)
{
	struct blogic_extmbox_req extmbox_req;
	enum blogic_rr_req rr_req;
	enum blogic_setccb_fmt setccb_fmt;
	int tgt_id;

	/*
	   Initialize the pointers to the first and last CCBs that are
	   queued for completion processing.
	 */
	adapter->firstccb = NULL;
	adapter->lastccb = NULL;

	/*
	   Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active,
	   Command Successful Flag, Active Commands, and Commands Since Reset
	   for each Target Device.
	 */
	for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) {
		adapter->bdr_pend[tgt_id] = NULL;
		adapter->tgt_flags[tgt_id].tagq_active = false;
		adapter->tgt_flags[tgt_id].cmd_good = false;
		adapter->active_cmds[tgt_id] = 0;
		adapter->cmds_since_rst[tgt_id] = 0;
	}

	/*
	   FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes.
	 */
	if (blogic_flashpoint_type(adapter))
		goto done;

	/*
	   Initialize the Outgoing and Incoming Mailbox pointers.
	 */
	adapter->mbox_sz = adapter->mbox_count * (sizeof(struct blogic_outbox) + sizeof(struct blogic_inbox));
	adapter->mbox_space = dma_alloc_coherent(&adapter->pci_device->dev,
				adapter->mbox_sz, &adapter->mbox_space_handle,
				GFP_KERNEL);
	if (adapter->mbox_space == NULL)
		return blogic_failure(adapter, "MAILBOX ALLOCATION");
	adapter->first_outbox = (struct blogic_outbox *) adapter->mbox_space;
	adapter->last_outbox = adapter->first_outbox + adapter->mbox_count - 1;
	adapter->next_outbox = adapter->first_outbox;
	adapter->first_inbox = (struct blogic_inbox *) (adapter->last_outbox + 1);
	adapter->last_inbox = adapter->first_inbox + adapter->mbox_count - 1;
	adapter->next_inbox = adapter->first_inbox;

	/*
	   Initialize the Outgoing and Incoming Mailbox structures.
	 */
	memset(adapter->first_outbox, 0,
			adapter->mbox_count * sizeof(struct blogic_outbox));
	memset(adapter->first_inbox, 0,
			adapter->mbox_count * sizeof(struct blogic_inbox));

	/*
	   Initialize the Host Adapter's Pointer to the Outgoing/Incoming
	   Mailboxes.
	 */
	extmbox_req.mbox_count = adapter->mbox_count;
	extmbox_req.base_mbox_addr = (u32) adapter->mbox_space_handle;
	if (blogic_cmd(adapter, BLOGIC_INIT_EXT_MBOX, &extmbox_req,
				sizeof(extmbox_req), NULL, 0) < 0)
		return blogic_failure(adapter, "MAILBOX INITIALIZATION");
	/*
	   Enable Strict Round Robin Mode if supported by the Host Adapter. In
	   Strict Round Robin Mode, the Host Adapter only looks at the next
	   Outgoing Mailbox for each new command, rather than scanning
	   through all the Outgoing Mailboxes to find any that have new
	   commands in them.  Strict Round Robin Mode is significantly more
	   efficient.
	 */
	if (adapter->strict_rr) {
		rr_req = BLOGIC_STRICT_RR_MODE;
		if (blogic_cmd(adapter, BLOGIC_STRICT_RR, &rr_req,
					sizeof(rr_req), NULL, 0) < 0)
			return blogic_failure(adapter,
					"ENABLE STRICT ROUND ROBIN MODE");
	}

	/*
	   For Host Adapters that support Extended LUN Format CCBs, issue the
	   Set CCB Format command to allow 32 Logical Units per Target Device.
	 */
	if (adapter->ext_lun) {
		setccb_fmt = BLOGIC_EXT_LUN_CCB;
		if (blogic_cmd(adapter, BLOGIC_SETCCB_FMT, &setccb_fmt,
					sizeof(setccb_fmt), NULL, 0) < 0)
			return blogic_failure(adapter, "SET CCB FORMAT");
	}

	/*
	   Announce Successful Initialization.
	 */
done:
	if (!adapter->adapter_initd) {
		blogic_info("*** %s Initialized Successfully ***\n", adapter,
				adapter->full_model);
		blogic_info("\n", adapter);
	} else
		blogic_warn("*** %s Initialized Successfully ***\n", adapter,
				adapter->full_model);
	adapter->adapter_initd = true;

	/*
	   Indicate the Host Adapter Initialization completed successfully.
	 */
	return true;
}


/*
  blogic_inquiry inquires about the Target Devices accessible
  through Host Adapter.
*/

static bool __init blogic_inquiry(struct blogic_adapter *adapter)
{
	u16 installed_devs;
	u8 installed_devs0to7[8];
	struct blogic_setup_info setupinfo;
	u8 sync_period[BLOGIC_MAXDEV];
	unsigned char req_replylen;
	int tgt_id;

	/*
	   Wait a few seconds between the Host Adapter Hard Reset which
	   initiates a SCSI Bus Reset and issuing any SCSI Commands. Some
	   SCSI devices get confused if they receive SCSI Commands too soon
	   after a SCSI Bus Reset.
	 */
	blogic_delay(adapter->bus_settle_time);
	/*
	   FlashPoint Host Adapters do not provide for Target Device Inquiry.
	 */
	if (blogic_flashpoint_type(adapter))
		return true;
	/*
	   Inhibit the Target Device Inquiry if requested.
	 */
	if (adapter->drvr_opts != NULL && adapter->drvr_opts->stop_tgt_inquiry)
		return true;
	/*
	   Issue the Inquire Target Devices command for host adapters with
	   firmware version 4.25 or later, or the Inquire Installed Devices
	   ID 0 to 7 command for older host adapters.  This is necessary to
	   force Synchronous Transfer Negotiation so that the Inquire Setup
	   Information and Inquire Synchronous Period commands will return
	   valid data.  The Inquire Target Devices command is preferable to
	   Inquire Installed Devices ID 0 to 7 since it only probes Logical
	   Unit 0 of each Target Device.
	 */
	if (strcmp(adapter->fw_ver, "4.25") >= 0) {

		/*
		   Issue a Inquire Target Devices command. Inquire Target
		   Devices only tests Logical Unit 0 of each Target Device
		   unlike the Inquire Installed Devices commands which test
		   Logical Units 0 - 7.  Two bytes are returned, where byte
		   0 bit 0 set indicates that Target Device 0 exists, and so on.
		 */

		if (blogic_cmd(adapter, BLOGIC_INQ_DEV, NULL, 0,
					&installed_devs, sizeof(installed_devs))
		    != sizeof(installed_devs))
			return blogic_failure(adapter, "INQUIRE TARGET DEVICES");
		for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
			adapter->tgt_flags[tgt_id].tgt_exists =
				(installed_devs & (1 << tgt_id) ? true : false);
	} else {

		/*
		   Issue an Inquire Installed Devices command. For each
		   Target Device, a byte is returned where bit 0 set
		   indicates that Logical Unit 0 * exists, bit 1 set
		   indicates that Logical Unit 1 exists, and so on.
		 */

		if (blogic_cmd(adapter, BLOGIC_INQ_DEV0TO7, NULL, 0,
				&installed_devs0to7, sizeof(installed_devs0to7))
		    != sizeof(installed_devs0to7))
			return blogic_failure(adapter,
					"INQUIRE INSTALLED DEVICES ID 0 TO 7");
		for (tgt_id = 0; tgt_id < 8; tgt_id++)
			adapter->tgt_flags[tgt_id].tgt_exists =
				installed_devs0to7[tgt_id] != 0;
	}
	/*
	   Issue the Inquire Setup Information command.
	 */
	req_replylen = sizeof(setupinfo);
	if (blogic_cmd(adapter, BLOGIC_INQ_SETUPINFO, &req_replylen,
			sizeof(req_replylen), &setupinfo, sizeof(setupinfo))
	    != sizeof(setupinfo))
		return blogic_failure(adapter, "INQUIRE SETUP INFORMATION");
	for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
		adapter->sync_offset[tgt_id] = (tgt_id < 8 ? setupinfo.sync0to7[tgt_id].offset : setupinfo.sync8to15[tgt_id - 8].offset);
	if (strcmp(adapter->fw_ver, "5.06L") >= 0)
		for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
			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));
	/*
	   Issue the Inquire Synchronous Period command.
	 */
	if (adapter->fw_ver[0] >= '3') {

		/* Issue a Inquire Synchronous Period command. For each
		   Target Device, a byte is returned which represents the
		   Synchronous Transfer Period in units of 10 nanoseconds.
		 */

		req_replylen = sizeof(sync_period);
		if (blogic_cmd(adapter, BLOGIC_INQ_SYNC_PERIOD, &req_replylen,
				sizeof(req_replylen), &sync_period,
				sizeof(sync_period)) != sizeof(sync_period))
			return blogic_failure(adapter,
					"INQUIRE SYNCHRONOUS PERIOD");
		for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
			adapter->sync_period[tgt_id] = sync_period[tgt_id];
	} else
		for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
			if (setupinfo.sync0to7[tgt_id].offset > 0)
				adapter->sync_period[tgt_id] = 20 + 5 * setupinfo.sync0to7[tgt_id].tx_period;
	/*
	   Indicate the Target Device Inquiry completed successfully.
	 */
	return true;
}

/*
  blogic_inithoststruct initializes the fields in the SCSI Host
  structure.  The base, io_port, n_io_ports, irq, and dma_channel fields in the
  SCSI Host structure are intentionally left uninitialized, as this driver
  handles acquisition and release of these resources explicitly, as well as
  ensuring exclusive access to the Host Adapter hardware and data structures
  through explicit acquisition and release of the Host Adapter's Lock.
*/

static void __init blogic_inithoststruct(struct blogic_adapter *adapter,
		struct Scsi_Host *host)
{
	host->max_id = adapter->maxdev;
	host->max_lun = adapter->maxlun;
	host->max_channel = 0;
	host->unique_id = adapter->io_addr;
	host->this_id = adapter->scsi_id;
	host->can_queue = adapter->drvr_qdepth;
	host->sg_tablesize = adapter->drvr_sglimit;
	host->cmd_per_lun = adapter->untag_qdepth;
}

/*
  blogic_sdev_configure will actually set the queue depth on individual
  scsi devices as they are permanently added to the device chain.  We
  shamelessly rip off the SelectQueueDepths code to make this work mostly
  like it used to.  Since we don't get called once at the end of the scan
  but instead get called for each device, we have to do things a bit
  differently.
*/
static int blogic_sdev_configure(struct scsi_device *dev,
				 struct queue_limits *lim)
{
	struct blogic_adapter *adapter =
		(struct blogic_adapter *) dev->host->hostdata;
	int tgt_id = dev->id;
	int qdepth = adapter->qdepth[tgt_id];

	if (adapter->tgt_flags[tgt_id].tagq_ok &&
			(adapter->tagq_ok & (1 << tgt_id))) {
		if (qdepth == 0)
			qdepth = BLOGIC_MAX_AUTO_TAG_DEPTH;
		adapter->qdepth[tgt_id] = qdepth;
		scsi_change_queue_depth(dev, qdepth);
	} else {
		adapter->tagq_ok &= ~(1 << tgt_id);
		qdepth = adapter->untag_qdepth;
		adapter->qdepth[tgt_id] = qdepth;
		scsi_change_queue_depth(dev, qdepth);
	}
	qdepth = 0;
	for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
		if (adapter->tgt_flags[tgt_id].tgt_exists)
			qdepth += adapter->qdepth[tgt_id];
	if (qdepth > adapter->alloc_ccbs)
		blogic_create_addlccbs(adapter, qdepth - adapter->alloc_ccbs,
				false);
	return 0;
}

/*
  blogic_init probes for BusLogic Host Adapters at the standard
  I/O Addresses where they may be located, initializing, registering, and
  reporting the configuration of each BusLogic Host Adapter it finds.  It
  returns the number of BusLogic Host Adapters successfully initialized and
  registered.
*/

static int __init blogic_init(void)
{
	int drvr_optindex = 0, probeindex;
	struct blogic_adapter *adapter;
	int ret = 0;

#ifdef MODULE
	if (BusLogic)
		blogic_setup(BusLogic);
#endif

	if (blogic_probe_options.noprobe)
		return -ENODEV;
	blogic_probeinfo_list =
	    kzalloc_objs(struct blogic_probeinfo, BLOGIC_MAX_ADAPTERS);
	if (blogic_probeinfo_list == NULL) {
		blogic_err("BusLogic: Unable to allocate Probe Info List\n",
				NULL);
		return -ENOMEM;
	}

	adapter = kzalloc_obj(struct blogic_adapter);
	if (adapter == NULL) {
		kfree(blogic_probeinfo_list);
		blogic_err("BusLogic: Unable to allocate Prototype Host Adapter\n", NULL);
		return -ENOMEM;
	}

#ifdef MODULE
	if (BusLogic != NULL)
		blogic_setup(BusLogic);
#endif
	blogic_init_probeinfo_list(adapter);
	for (probeindex = 0; probeindex < blogic_probeinfo_count; probeindex++) {
		struct blogic_probeinfo *probeinfo =
			&blogic_probeinfo_list[probeindex];
		struct blogic_adapter *myadapter = adapter;
		struct Scsi_Host *host;

		if (probeinfo->io_addr == 0)
			continue;
		memset(myadapter, 0, sizeof(struct blogic_adapter));
		myadapter->adapter_type = probeinfo->adapter_type;
		myadapter->adapter_bus_type = probeinfo->adapter_bus_type;
		myadapter->io_addr = probeinfo->io_addr;
		myadapter->pci_addr = probeinfo->pci_addr;
		myadapter->bus = probeinfo->bus;
		myadapter->dev = probeinfo->dev;
		myadapter->pci_device = probeinfo->pci_device;
		myadapter->irq_ch = probeinfo->irq_ch;
		myadapter->addr_count =
			blogic_adapter_addr_count[myadapter->adapter_type];

		/*
		   Make sure region is free prior to probing.
		 */
		if (!request_region(myadapter->io_addr, myadapter->addr_count,
					"BusLogic"))
			continue;
		/*
		   Probe the Host Adapter. If unsuccessful, abort further
		   initialization.
		 */
		if (!blogic_probe(myadapter)) {
			release_region(myadapter->io_addr,
					myadapter->addr_count);
			continue;
		}
		/*
		   Hard Reset the Host Adapter.  If unsuccessful, abort further
		   initialization.
		 */
		if (!blogic_hwreset(myadapter, true)) {
			release_region(myadapter->io_addr,
					myadapter->addr_count);
			continue;
		}
		/*
		   Check the Host Adapter.  If unsuccessful, abort further
		   initialization.
		 */
		if (!blogic_checkadapter(myadapter)) {
			release_region(myadapter->io_addr,
					myadapter->addr_count);
			continue;
		}
		/*
		   Initialize the Driver Options field if provided.
		 */
		if (drvr_optindex < blogic_drvr_options_count)
			myadapter->drvr_opts =
				&blogic_drvr_options[drvr_optindex++];
		/*
		   Announce the Driver Version and Date, Author's Name,
		   Copyright Notice, and Electronic Mail Address.
		 */
		blogic_announce_drvr(myadapter);
		/*
		   Register the SCSI Host structure.
		 */

		host = scsi_host_alloc(&blogic_template,
				sizeof(struct blogic_adapter));
		if (host == NULL) {
			release_region(myadapter->io_addr,
					myadapter->addr_count);
			continue;
		}
		myadapter = (struct blogic_adapter *) host->hostdata;
		memcpy(myadapter, adapter, sizeof(struct blogic_adapter));
		myadapter->scsi_host = host;
		myadapter->host_no = host->host_no;
		/*
		   Add Host Adapter to the end of the list of registered
		   BusLogic Host Adapters.
		 */
		list_add_tail(&myadapter->host_list, &blogic_host_list);

		/*
		   Read the Host Adapter Configuration, Configure the Host
		   Adapter, Acquire the System Resources necessary to use
		   the Host Adapter, then Create the Initial CCBs, Initialize
		   the Host Adapter, and finally perform Target Device
		   Inquiry. From this point onward, any failure will be
		   assumed to be due to a problem with the Host Adapter,
		   rather than due to having mistakenly identified this port
		   as belonging to a BusLogic Host Adapter. The I/O Address
		   range will not be released, thereby preventing it from
		   being incorrectly identified as any other type of Host
		   Adapter.
		 */
		if (blogic_rdconfig(myadapter) &&
		    blogic_reportconfig(myadapter) &&
		    blogic_getres(myadapter) &&
		    blogic_create_initccbs(myadapter) &&
		    blogic_initadapter(myadapter) &&
		    blogic_inquiry(myadapter)) {
			/*
			   Initialization has been completed successfully.
			   Release and re-register usage of the I/O Address
			   range so that the Model Name of the Host Adapter
			   will appear, and initialize the SCSI Host structure.
			 */
			release_region(myadapter->io_addr,
				       myadapter->addr_count);
			if (!request_region(myadapter->io_addr,
					    myadapter->addr_count,
					    myadapter->full_model)) {
				printk(KERN_WARNING
					"BusLogic: Release and re-register of "
					"port 0x%04lx failed \n",
					(unsigned long)myadapter->io_addr);
				blogic_destroy_ccbs(myadapter);
				blogic_relres(myadapter);
				list_del(&myadapter->host_list);
				scsi_host_put(host);
				ret = -ENOMEM;
			} else {
				blogic_inithoststruct(myadapter,
								 host);
				if (scsi_add_host(host, myadapter->pci_device
						? &myadapter->pci_device->dev
						  : NULL)) {
					printk(KERN_WARNING
					       "BusLogic: scsi_add_host()"
					       "failed!\n");
					blogic_destroy_ccbs(myadapter);
					blogic_relres(myadapter);
					list_del(&myadapter->host_list);
					scsi_host_put(host);
					ret = -ENODEV;
				} else
					scsi_scan_host(host);
			}
		} else {
			/*
			   An error occurred during Host Adapter Configuration
			   Querying, Host Adapter Configuration, Resource
			   Acquisition, CCB Creation, Host Adapter
			   Initialization, or Target Device Inquiry, so
			   remove Host Adapter from the list of registered
			   BusLogic Host Adapters, destroy the CCBs, Release
			   the System Resources, and Unregister the SCSI
			   Host.
			 */
			blogic_destroy_ccbs(myadapter);
			blogic_relres(myadapter);
			list_del(&myadapter->host_list);
			scsi_host_put(host);
			ret = -ENODEV;
		}
	}
	kfree(adapter);
	kfree(blogic_probeinfo_list);
	blogic_probeinfo_list = NULL;
	return ret;
}


/*
  blogic_deladapter releases all resources previously acquired to
  support a specific Host Adapter, including the I/O Address range, and
  unregisters the BusLogic Host Adapter.
*/

static int __exit blogic_deladapter(struct blogic_adapter *adapter)
{
	struct Scsi_Host *host = adapter->scsi_host;

	scsi_remove_host(host);

	/*
	   FlashPoint Host Adapters must first be released by the FlashPoint
	   SCCB Manager.
	 */
	if (blogic_flashpoint_type(adapter))
		FlashPoint_ReleaseHostAdapter(adapter->cardhandle);
	/*
	   Destroy the CCBs and release any system resources acquired to
	   support Host Adapter.
	 */
	blogic_destroy_ccbs(adapter);
	blogic_relres(adapter);
	/*
	   Release usage of the I/O Address range.
	 */
	release_region(adapter->io_addr, adapter->addr_count);
	/*
	   Remove Host Adapter from the list of registered BusLogic
	   Host Adapters.
	 */
	list_del(&adapter->host_list);

	scsi_host_put(host);
	return 0;
}


/*
  blogic_qcompleted_ccb queues CCB for completion processing.
*/

static void blogic_qcompleted_ccb(struct blogic_ccb *ccb)
{
	struct blogic_adapter *adapter = ccb->adapter;

	ccb->status = BLOGIC_CCB_COMPLETE;
	ccb->next = NULL;
	if (adapter->firstccb == NULL) {
		adapter->firstccb = ccb;
		adapter->lastccb = ccb;
	} else {
		adapter->lastccb->next = ccb;
		adapter->lastccb = ccb;
	}
	adapter->active_cmds[ccb->tgt_id]--;
}


/*
  blogic_resultcode computes a SCSI Subsystem Result Code from
  the Host Adapter Status and Target Device Status.
*/

static int blogic_resultcode(struct blogic_adapter *adapter,
		enum blogic_adapter_status adapter_status,
		enum blogic_tgt_status tgt_status)
{
	int hoststatus;

	switch (adapter_status) {
	case BLOGIC_CMD_CMPLT_NORMAL:
	case BLOGIC_LINK_CMD_CMPLT:
	case BLOGIC_LINK_CMD_CMPLT_FLAG:
		hoststatus = DID_OK;
		break;
	case BLOGIC_SELECT_TIMEOUT:
		hoststatus = DID_TIME_OUT;
		break;
	case BLOGIC_INVALID_OUTBOX_CODE:
	case BLOGIC_INVALID_CMD_CODE:
	case BLOGIC_BAD_CMD_PARAM:
		blogic_warn("BusLogic Driver Protocol Error 0x%02X\n",
				adapter, adapter_status);
		fallthrough;
	case BLOGIC_DATA_UNDERRUN:
	case BLOGIC_DATA_OVERRUN:
	case BLOGIC_NOEXPECT_BUSFREE:
	case BLOGIC_LINKCCB_BADLUN:
	case BLOGIC_AUTOREQSENSE_FAIL:
	case BLOGIC_TAGQUEUE_REJECT:
	case BLOGIC_BAD_MSG_RCVD:
	case BLOGIC_HW_FAIL:
	case BLOGIC_BAD_RECONNECT:
	case BLOGIC_ABRT_QUEUE:
	case BLOGIC_ADAPTER_SW_ERROR:
	case BLOGIC_HW_TIMEOUT:
	case BLOGIC_PARITY_ERR:
		hoststatus = DID_ERROR;
		break;
	case BLOGIC_INVALID_BUSPHASE:
	case BLOGIC_NORESPONSE_TO_ATN:
	case BLOGIC_HW_RESET:
	case BLOGIC_RST_FROM_OTHERDEV:
	case BLOGIC_HW_BDR:
		hoststatus = DID_RESET;
		break;
	default:
		blogic_warn("Unknown Host Adapter Status 0x%02X\n", adapter,
				adapter_status);
		hoststatus = DID_ERROR;
		break;
	}
	return (hoststatus << 16) | tgt_status;
}

/*
 * turn the dma address from an inbox into a ccb pointer
 * This is rather inefficient.
 */
static struct blogic_ccb *
blogic_inbox_to_ccb(struct blogic_adapter *adapter, struct blogic_inbox *inbox)
{
	struct blogic_ccb *ccb;

	for (ccb = adapter->all_ccbs; ccb; ccb = ccb->next_all)
		if (inbox->ccb == ccb->dma_handle)
			break;

	return ccb;
}

/*
  blogic_scan_inbox scans the Incoming Mailboxes saving any
  Incoming Mailbox entries for completion processing.
*/
static void blogic_scan_inbox(struct blogic_adapter *adapter)
{
	/*
	   Scan through the Incoming Mailboxes in Strict Round Robin
	   fashion, saving any completed CCBs for further processing. It
	   is essential that for each CCB and SCSI Command issued, command
	   completion processing is performed exactly once.  Therefore,
	   only Incoming Mailboxes with completion code Command Completed
	   Without Error, Command Completed With Error, or Command Aborted
	   At Host Request are saved for completion processing. When an
	   Incoming Mailbox has a completion code of Aborted Command Not
	   Found, the CCB had already completed or been aborted before the
	   current Abort request was processed, and so completion processing
	   has already occurred and no further action should be taken.
	 */
	struct blogic_inbox *next_inbox = adapter->next_inbox;
	enum blogic_cmplt_code comp_code;

	while ((comp_code = next_inbox->comp_code) != BLOGIC_INBOX_FREE) {
		struct blogic_ccb *ccb = blogic_inbox_to_ccb(adapter, next_inbox);
		if (!ccb) {
			/*
			 * This should never happen, unless the CCB list is
			 * corrupted in memory.
			 */
			blogic_warn("Could not find CCB for dma address %x\n", adapter, next_inbox->ccb);
		} else if (comp_code != BLOGIC_CMD_NOTFOUND) {
			if (ccb->status == BLOGIC_CCB_ACTIVE ||
					ccb->status == BLOGIC_CCB_RESET) {
				/*
				   Save the Completion Code for this CCB and
				   queue the CCB for completion processing.
				 */
				ccb->comp_code = comp_code;
				blogic_qcompleted_ccb(ccb);
			} else {
				/*
				   If a CCB ever appears in an Incoming Mailbox
				   and is not marked as status Active or Reset,
				   then there is most likely a bug in
				   the Host Adapter firmware.
				 */
				blogic_warn("Illegal CCB #%ld status %d in Incoming Mailbox\n", adapter, ccb->serial, ccb->status);
			}
		}
		next_inbox->comp_code = BLOGIC_INBOX_FREE;
		if (++next_inbox > adapter->last_inbox)
			next_inbox = adapter->first_inbox;
	}
	adapter->next_inbox = next_inbox;
}


/*
  blogic_process_ccbs iterates over the completed CCBs for Host
  Adapter setting the SCSI Command Result Codes, deallocating the CCBs, and
  calling the SCSI Subsystem Completion Routines.  The Host Adapter's Lock
  should already have been acquired by the caller.
*/

static void blogic_process_ccbs(struct blogic_adapter *adapter)
{
	if (adapter->processing_ccbs)
		return;
	adapter->processing_ccbs = true;
	while (adapter->firstccb != NULL) {
		struct blogic_ccb *ccb = adapter->firstccb;
		struct scsi_cmnd *command = ccb->command;
		adapter->firstccb = ccb->next;
		if (adapter->firstccb == NULL)
			adapter->lastccb = NULL;
		/*
		   Process the Completed CCB.
		 */
		if (ccb->opcode == BLOGIC_BDR) {
			int tgt_id = ccb->tgt_id;

			blogic_warn("Bus Device Reset CCB #%ld to Target %d Completed\n", adapter, ccb->serial, tgt_id);
			blogic_inc_count(&adapter->tgt_stats[tgt_id].bdr_done);
			adapter->tgt_flags[tgt_id].tagq_active = false;
			adapter->cmds_since_rst[tgt_id] = 0;
			adapter->last_resetdone[tgt_id] = jiffies;
			/*
			   Place CCB back on the Host Adapter's free list.
			 */
			blogic_dealloc_ccb(ccb, 1);
#if 0			/* this needs to be redone different for new EH */
			/*
			   Bus Device Reset CCBs have the command field
			   non-NULL only when a Bus Device Reset was requested
			   for a command that did not have a currently active
			   CCB in the Host Adapter (i.e., a Synchronous Bus
			   Device Reset), and hence would not have its
			   Completion Routine called otherwise.
			 */
			while (command != NULL) {
				struct scsi_cmnd *nxt_cmd =
					command->reset_chain;
				command->reset_chain = NULL;
				command->result = DID_RESET << 16;
				scsi_done(command);
				command = nxt_cmd;
			}
#endif
			/*
			   Iterate over the CCBs for this Host Adapter
			   performing completion processing for any CCBs
			   marked as Reset for this Target.
			 */
			for (ccb = adapter->all_ccbs; ccb != NULL;
					ccb = ccb->next_all)
				if (ccb->status == BLOGIC_CCB_RESET &&
						ccb->tgt_id == tgt_id) {
					command = ccb->command;
					blogic_dealloc_ccb(ccb, 1);
					adapter->active_cmds[tgt_id]--;
					command->result = DID_RESET << 16;
					scsi_done(command);
				}
			adapter->bdr_pend[tgt_id] = NULL;
		} else {
			/*
			   Translate the Completion Code, Host Adapter Status,
			   and Target Device Status into a SCSI Subsystem
			   Result Code.
			 */
			switch (ccb->comp_code) {
			case BLOGIC_INBOX_FREE:
			case BLOGIC_CMD_NOTFOUND:
			case BLOGIC_INVALID_CCB:
				blogic_warn("CCB #%ld to Target %d Impossible State\n", adapter, ccb->serial, ccb->tgt_id);
				break;
			case BLOGIC_CMD_COMPLETE_GOOD:
				adapter->tgt_stats[ccb->tgt_id]
				    .cmds_complete++;
				adapter->tgt_flags[ccb->tgt_id]
				    .cmd_good = true;
				command->result = DID_OK << 16;
				break;
			case BLOGIC_CMD_ABORT_BY_HOST:
				blogic_warn("CCB #%ld to Target %d Aborted\n",
					adapter, ccb->serial, ccb->tgt_id);
				blogic_inc_count(&adapter->tgt_stats[ccb->tgt_id].aborts_done);
				command->result = DID_ABORT << 16;
				break;
			case BLOGIC_CMD_COMPLETE_ERROR:
				command->result = blogic_resultcode(adapter,
					ccb->adapter_status, ccb->tgt_status);
				if (ccb->adapter_status != BLOGIC_SELECT_TIMEOUT) {
					adapter->tgt_stats[ccb->tgt_id]
					    .cmds_complete++;
					if (blogic_global_options.trace_err) {
						int i;
						blogic_notice("CCB #%ld Target %d: Result %X Host "
								"Adapter Status %02X Target Status %02X\n", adapter, ccb->serial, ccb->tgt_id, command->result, ccb->adapter_status, ccb->tgt_status);
						blogic_notice("CDB   ", adapter);
						for (i = 0; i < ccb->cdblen; i++)
							blogic_notice(" %02X", adapter, ccb->cdb[i]);
						blogic_notice("\n", adapter);
						blogic_notice("Sense ", adapter);
						for (i = 0; i < ccb->sense_datalen; i++)
							blogic_notice(" %02X", adapter, command->sense_buffer[i]);
						blogic_notice("\n", adapter);
					}
				}
				break;
			}
			/*
			   When an INQUIRY command completes normally, save the
			   CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit
			   Wide Data Transfers Supported) bits.
			 */
			if (ccb->cdb[0] == INQUIRY && ccb->cdb[1] == 0 &&
				ccb->adapter_status == BLOGIC_CMD_CMPLT_NORMAL) {
				struct blogic_tgt_flags *tgt_flags =
					&adapter->tgt_flags[ccb->tgt_id];
				struct scsi_inquiry *inquiry =
					(struct scsi_inquiry *) scsi_sglist(command);
				tgt_flags->tgt_exists = true;
				tgt_flags->tagq_ok = inquiry->CmdQue;
				tgt_flags->wide_ok = inquiry->WBus16;
			}
			/*
			   Place CCB back on the Host Adapter's free list.
			 */
			blogic_dealloc_ccb(ccb, 1);
			/*
			   Call the SCSI Command Completion Routine.
			 */
			scsi_done(command);
		}
	}
	adapter->processing_ccbs = false;
}


/*
  blogic_inthandler handles hardware interrupts from BusLogic Host
  Adapters.
*/

static irqreturn_t blogic_inthandler(int irq_ch, void *devid)
{
	struct blogic_adapter *adapter = (struct blogic_adapter *) devid;
	unsigned long processor_flag;
	/*
	   Acquire exclusive access to Host Adapter.
	 */
	spin_lock_irqsave(adapter->scsi_host->host_lock, processor_flag);
	/*
	   Handle Interrupts appropriately for each Host Adapter type.
	 */
	if (blogic_multimaster_type(adapter)) {
		union blogic_int_reg intreg;
		/*
		   Read the Host Adapter Interrupt Register.
		 */
		intreg.all = blogic_rdint(adapter);
		if (intreg.ir.int_valid) {
			/*
			   Acknowledge the interrupt and reset the Host Adapter
			   Interrupt Register.
			 */
			blogic_intreset(adapter);
			/*
			   Process valid External SCSI Bus Reset and Incoming
			   Mailbox Loaded Interrupts. Command Complete
			   Interrupts are noted, and Outgoing Mailbox Available
			   Interrupts are ignored, as they are never enabled.
			 */
			if (intreg.ir.ext_busreset)
				adapter->adapter_extreset = true;
			else if (intreg.ir.mailin_loaded)
				blogic_scan_inbox(adapter);
			else if (intreg.ir.cmd_complete)
				adapter->adapter_cmd_complete = true;
		}
	} else {
		/*
		   Check if there is a pending interrupt for this Host Adapter.
		 */
		if (FlashPoint_InterruptPending(adapter->cardhandle))
			switch (FlashPoint_HandleInterrupt(adapter->cardhandle)) {
			case FPOINT_NORMAL_INT:
				break;
			case FPOINT_EXT_RESET:
				adapter->adapter_extreset = true;
				break;
			case FPOINT_INTERN_ERR:
				blogic_warn("Internal FlashPoint Error detected - Resetting Host Adapter\n", adapter);
				adapter->adapter_intern_err = true;
				break;
			}
	}
	/*
	   Process any completed CCBs.
	 */
	if (adapter->firstccb != NULL)
		blogic_process_ccbs(adapter);
	/*
	   Reset the Host Adapter if requested.
	 */
	if (adapter->adapter_extreset) {
		blogic_warn("Resetting %s due to External SCSI Bus Reset\n", adapter, adapter->full_model);
		blogic_inc_count(&adapter->ext_resets);
		blogic_resetadapter(adapter, false);
		adapter->adapter_extreset = false;
	} else if (adapter->adapter_intern_err) {
		blogic_warn("Resetting %s due to Host Adapter Internal Error\n", adapter, adapter->full_model);
		blogic_inc_count(&adapter->adapter_intern_errors);
		blogic_resetadapter(adapter, true);
		adapter->adapter_intern_err = false;
	}
	/*
	   Release exclusive access to Host Adapter.
	 */
	spin_unlock_irqrestore(adapter->scsi_host->host_lock, processor_flag);
	return IRQ_HANDLED;
}


/*
  blogic_write_outbox places CCB and Action Code into an Outgoing
  Mailbox for execution by Host Adapter.  The Host Adapter's Lock should
  already have been acquired by the caller.
*/

static bool blogic_write_outbox(struct blogic_adapter *adapter,
		enum blogic_action action, struct blogic_ccb *ccb)
{
	struct blogic_outbox *next_outbox;

	next_outbox = adapter->next_outbox;
	if (next_outbox->action == BLOGIC_OUTBOX_FREE) {
		ccb->status = BLOGIC_CCB_ACTIVE;
		/*
		   The CCB field must be written before the Action Code field
		   since the Host Adapter is operating asynchronously and the
		   locking code does not protect against simultaneous access
		   by the Host Adapter.
		 */
		next_outbox->ccb = ccb->dma_handle;
		next_outbox->action = action;
		blogic_execmbox(adapter);
		if (++next_outbox > adapter->last_outbox)
			next_outbox = adapter->first_outbox;
		adapter->next_outbox = next_outbox;
		if (action == BLOGIC_MBOX_START) {
			adapter->active_cmds[ccb->tgt_id]++;
			if (ccb->opcode != BLOGIC_BDR)
				adapter->tgt_stats[ccb->tgt_id].cmds_tried++;
		}
		return true;
	}
	return false;
}

/* Error Handling (EH) support */

static int blogic_hostreset(struct scsi_cmnd *SCpnt)
{
	struct blogic_adapter *adapter =
		(struct blogic_adapter *) SCpnt->device->host->hostdata;

	unsigned int id = SCpnt->device->id;
	struct blogic_tgt_stats *stats = &adapter->tgt_stats[id];
	int rc;

	spin_lock_irq(SCpnt->device->host->host_lock);

	blogic_inc_count(&stats->adapter_reset_req);

	rc = blogic_resetadapter(adapter, false);
	spin_unlock_irq(SCpnt->device->host->host_lock);
	return rc;
}

/*
  blogic_qcmd creates a CCB for Command and places it into an
  Outgoing Mailbox for execution by the associated Host Adapter.
*/

static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
{
	void (*comp_cb)(struct scsi_cmnd *) = scsi_done;
	struct blogic_adapter *adapter =
		(struct blogic_adapter *) command->device->host->hostdata;
	struct blogic_tgt_flags *tgt_flags =
		&adapter->tgt_flags[command->device->id];
	struct blogic_tgt_stats *tgt_stats = adapter->tgt_stats;
	unsigned char *cdb = command->cmnd;
	int cdblen = command->cmd_len;
	int tgt_id = command->device->id;
	int lun = command->device->lun;
	int buflen = scsi_bufflen(command);
	int count;
	struct blogic_ccb *ccb;
	dma_addr_t sense_buf;

	/*
	   SCSI REQUEST_SENSE commands will be executed automatically by the
	   Host Adapter for any errors, so they should not be executed
	   explicitly unless the Sense Data is zero indicating that no error
	   occurred.
	 */
	if (cdb[0] == REQUEST_SENSE && command->sense_buffer[0] != 0) {
		command->result = DID_OK << 16;
		comp_cb(command);
		return 0;
	}
	/*
	   Allocate a CCB from the Host Adapter's free list. In the unlikely
	   event that there are none available and memory allocation fails,
	   wait 1 second and try again. If that fails, the Host Adapter is
	   probably hung so signal an error as a Host Adapter Hard Reset
	   should be initiated soon.
	 */
	ccb = blogic_alloc_ccb(adapter);
	if (ccb == NULL) {
		spin_unlock_irq(adapter->scsi_host->host_lock);
		blogic_delay(1);
		spin_lock_irq(adapter->scsi_host->host_lock);
		ccb = blogic_alloc_ccb(adapter);
		if (ccb == NULL) {
			command->result = DID_ERROR << 16;
			comp_cb(command);
			return 0;
		}
	}

	/*
	   Initialize the fields in the BusLogic Command Control Block (CCB).
	 */
	count = scsi_dma_map(command);
	BUG_ON(count < 0);
	if (count) {
		struct scatterlist *sg;
		int i;

		ccb->opcode = BLOGIC_INITIATOR_CCB_SG;
		ccb->datalen = count * sizeof(struct blogic_sg_seg);
		if (blogic_multimaster_type(adapter))
			ccb->data = (unsigned int) ccb->dma_handle +
					((unsigned long) &ccb->sglist -
					(unsigned long) ccb);
		else
			ccb->data = virt_to_32bit_virt(ccb->sglist);

		scsi_for_each_sg(command, sg, count, i) {
			ccb->sglist[i].segbytes = sg_dma_len(sg);
			ccb->sglist[i].segdata = sg_dma_address(sg);
		}
	} else if (!count) {
		ccb->opcode = BLOGIC_INITIATOR_CCB;
		ccb->datalen = buflen;
		ccb->data = 0;
	}

	switch (cdb[0]) {
	case READ_6:
	case READ_10:
		ccb->datadir = BLOGIC_DATAIN_CHECKED;
		tgt_stats[tgt_id].read_cmds++;
		blogic_addcount(&tgt_stats[tgt_id].bytesread, buflen);
		blogic_incszbucket(tgt_stats[tgt_id].read_sz_buckets, buflen);
		break;
	case WRITE_6:
	case WRITE_10:
		ccb->datadir = BLOGIC_DATAOUT_CHECKED;
		tgt_stats[tgt_id].write_cmds++;
		blogic_addcount(&tgt_stats[tgt_id].byteswritten, buflen);
		blogic_incszbucket(tgt_stats[tgt_id].write_sz_buckets, buflen);
		break;
	default:
		ccb->datadir = BLOGIC_UNCHECKED_TX;
		break;
	}
	ccb->cdblen = cdblen;
	ccb->adapter_status = 0;
	ccb->tgt_status = 0;
	ccb->tgt_id = tgt_id;
	ccb->lun = lun;
	ccb->tag_enable = false;
	ccb->legacytag_enable = false;
	/*
	   BusLogic recommends that after a Reset the first couple of
	   commands that are sent to a Target Device be sent in a non
	   Tagged Queue fashion so that the Host Adapter and Target Device
	   can establish Synchronous and Wide Transfer before Queue Tag
	   messages can interfere with the Synchronous and Wide Negotiation
	   messages.  By waiting to enable Tagged Queuing until after the
	   first BLOGIC_MAX_TAG_DEPTH commands have been queued, it is
	   assured that after a Reset any pending commands are requeued
	   before Tagged Queuing is enabled and that the Tagged Queuing
	   message will not occur while the partition table is being printed.
	   In addition, some devices do not properly handle the transition
	   from non-tagged to tagged commands, so it is necessary to wait
	   until there are no pending commands for a target device
	   before queuing tagged commands.
	 */
	if (adapter->cmds_since_rst[tgt_id]++ >= BLOGIC_MAX_TAG_DEPTH &&
			!tgt_flags->tagq_active &&
			adapter->active_cmds[tgt_id] == 0
			&& tgt_flags->tagq_ok &&
			(adapter->tagq_ok & (1 << tgt_id))) {
		tgt_flags->tagq_active = true;
		blogic_notice("Tagged Queuing now active for Target %d\n",
					adapter, tgt_id);
	}
	if (tgt_flags->tagq_active) {
		enum blogic_queuetag queuetag = BLOGIC_SIMPLETAG;
		/*
		   When using Tagged Queuing with Simple Queue Tags, it
		   appears that disk drive controllers do not guarantee that
		   a queued command will not remain in a disconnected state
		   indefinitely if commands that read or write nearer the
		   head position continue to arrive without interruption.
		   Therefore, for each Target Device this driver keeps track
		   of the last time either the queue was empty or an Ordered
		   Queue Tag was issued. If more than 4 seconds (one fifth
		   of the 20 second disk timeout) have elapsed since this
		   last sequence point, this command will be issued with an
		   Ordered Queue Tag rather than a Simple Queue Tag, which
		   forces the Target Device to complete all previously
		   queued commands before this command may be executed.
		 */
		if (adapter->active_cmds[tgt_id] == 0)
			adapter->last_seqpoint[tgt_id] = jiffies;
		else if (time_after(jiffies,
				adapter->last_seqpoint[tgt_id] + 4 * HZ)) {
			adapter->last_seqpoint[tgt_id] = jiffies;
			queuetag = BLOGIC_ORDEREDTAG;
		}
		if (adapter->ext_lun) {
			ccb->tag_enable = true;
			ccb->queuetag = queuetag;
		} else {
			ccb->legacytag_enable = true;
			ccb->legacy_tag = queuetag;
		}
	}
	memcpy(ccb->cdb, cdb, cdblen);
	ccb->sense_datalen = SCSI_SENSE_BUFFERSIZE;
	ccb->command = command;
	sense_buf = dma_map_single(&adapter->pci_device->dev,
				command->sense_buffer, ccb->sense_datalen,
				DMA_FROM_DEVICE);
	if (dma_mapping_error(&adapter->pci_device->dev, sense_buf)) {
		blogic_err("DMA mapping for sense data buffer failed\n",
				adapter);
		blogic_dealloc_ccb(ccb, 0);
		return SCSI_MLQUEUE_HOST_BUSY;
	}
	ccb->sensedata = sense_buf;
	if (blogic_multimaster_type(adapter)) {
		/*
		   Place the CCB in an Outgoing Mailbox. The higher levels
		   of the SCSI Subsystem should not attempt to queue more
		   commands than can be placed in Outgoing Mailboxes, so
		   there should always be one free.  In the unlikely event
		   that there are none available, wait 1 second and try
		   again. If that fails, the Host Adapter is probably hung
		   so signal an error as a Host Adapter Hard Reset should
		   be initiated soon.
		 */
		if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START, ccb)) {
			spin_unlock_irq(adapter->scsi_host->host_lock);
			blogic_warn("Unable to write Outgoing Mailbox - Pausing for 1 second\n", adapter);
			blogic_delay(1);
			spin_lock_irq(adapter->scsi_host->host_lock);
			if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START,
						ccb)) {
				blogic_warn("Still unable to write Outgoing Mailbox - Host Adapter Dead?\n", adapter);
				blogic_dealloc_ccb(ccb, 1);
				command->result = DID_ERROR << 16;
				scsi_done(command);
			}
		}
	} else {
		/*
		   Call the FlashPoint SCCB Manager to start execution of
		   the CCB.
		 */
		ccb->status = BLOGIC_CCB_ACTIVE;
		adapter->active_cmds[tgt_id]++;
		tgt_stats[tgt_id].cmds_tried++;
		FlashPoint_StartCCB(adapter->cardhandle, ccb);
		/*
		   The Command may have already completed and
		   blogic_qcompleted_ccb been called, or it may still be
		   pending.
		 */
		if (ccb->status == BLOGIC_CCB_COMPLETE)
			blogic_process_ccbs(adapter);
	}
	return 0;
}

static DEF_SCSI_QCMD(blogic_qcmd)

#if 0
/*
  blogic_abort aborts Command if possible.
*/

static int blogic_abort(struct scsi_cmnd *command)
{
	struct blogic_adapter *adapter =
		(struct blogic_adapter *) command->device->host->hostdata;

	int tgt_id = command->device->id;
	struct blogic_ccb *ccb;
	blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_request);

	/*
	   Attempt to find an Active CCB for this Command. If no Active
	   CCB for this Command is found, then no Abort is necessary.
	 */
	for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all)
		if (ccb->command == command)
			break;
	if (ccb == NULL) {
		blogic_warn("Unable to Abort Command to Target %d - No CCB Found\n", adapter, tgt_id);
		return SUCCESS;
	} else if (ccb->status == BLOGIC_CCB_COMPLETE) {
		blogic_warn("Unable to Abort Command to Target %d - CCB Completed\n", adapter, tgt_id);
		return SUCCESS;
	} else if (ccb->status == BLOGIC_CCB_RESET) {
		blogic_warn("Unable to Abort Command to Target %d - CCB Reset\n", adapter, tgt_id);
		return SUCCESS;
	}
	if (blogic_multimaster_type(adapter)) {
		/*
		   Attempt to Abort this CCB.  MultiMaster Firmware versions
		   prior to 5.xx do not generate Abort Tag messages, but only
		   generate the non-tagged Abort message.  Since non-tagged
		   commands are not sent by the Host Adapter until the queue
		   of outstanding tagged commands has completed, and the
		   Abort message is treated as a non-tagged command, it is
		   effectively impossible to abort commands when Tagged
		   Queuing is active. Firmware version 5.xx does generate
		   Abort Tag messages, so it is possible to abort commands
		   when Tagged Queuing is active.
		 */
		if (adapter->tgt_flags[tgt_id].tagq_active &&
				adapter->fw_ver[0] < '5') {
			blogic_warn("Unable to Abort CCB #%ld to Target %d - Abort Tag Not Supported\n", adapter, ccb->serial, tgt_id);
			return FAILURE;
		} else if (blogic_write_outbox(adapter, BLOGIC_MBOX_ABORT,
					ccb)) {
			blogic_warn("Aborting CCB #%ld to Target %d\n",
					adapter, ccb->serial, tgt_id);
			blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_tried);
			return SUCCESS;
		} else {
			blogic_warn("Unable to Abort CCB #%ld to Target %d - No Outgoing Mailboxes\n", adapter, ccb->serial, tgt_id);
			return FAILURE;
		}
	} else {
		/*
		   Call the FlashPoint SCCB Manager to abort execution of
		   the CCB.
		 */
		blogic_warn("Aborting CCB #%ld to Target %d\n", adapter,
				ccb->serial, tgt_id);
		blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_tried);
		FlashPoint_AbortCCB(adapter->cardhandle, ccb);
		/*
		   The Abort may have already been completed and
		   blogic_qcompleted_ccb been called, or it
		   may still be pending.
		 */
		if (ccb->status == BLOGIC_CCB_COMPLETE)
			blogic_process_ccbs(adapter);
		return SUCCESS;
	}
	return SUCCESS;
}

#endif
/*
  blogic_resetadapter resets Host Adapter if possible, marking all
  currently executing SCSI Commands as having been Reset.
*/

static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset)
{
	struct blogic_ccb *ccb;
	int tgt_id;

	/*
	 * Attempt to Reset and Reinitialize the Host Adapter.
	 */

	if (!(blogic_hwreset(adapter, hard_reset) &&
				blogic_initadapter(adapter))) {
		blogic_err("Resetting %s Failed\n", adapter,
						adapter->full_model);
		return FAILURE;
	}

	/*
	 * Deallocate all currently executing CCBs.
	 */

	for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all)
		if (ccb->status == BLOGIC_CCB_ACTIVE)
			blogic_dealloc_ccb(ccb, 1);
	/*
	 * Wait a few seconds between the Host Adapter Hard Reset which
	 * initiates a SCSI Bus Reset and issuing any SCSI Commands.  Some
	 * SCSI devices get confused if they receive SCSI Commands too soon
	 * after a SCSI Bus Reset.
	 */

	if (hard_reset) {
		spin_unlock_irq(adapter->scsi_host->host_lock);
		blogic_delay(adapter->bus_settle_time);
		spin_lock_irq(adapter->scsi_host->host_lock);
	}

	for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) {
		adapter->last_resettried[tgt_id] = jiffies;
		adapter->last_resetdone[tgt_id] = jiffies;
	}
	return SUCCESS;
}

/*
  blogic_diskparam returns the Heads/Sectors/Cylinders BIOS Disk
  Parameters for Disk.  The default disk geometry is 64 heads, 32 sectors, and
  the appropriate number of cylinders so as not to exceed drive capacity.  In
  order for disks equal to or larger than 1 GB to be addressable by the BIOS
  without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
  may be enabled in AutoSCSI on FlashPoint Host Adapters and on "W" and "C"
  series MultiMaster Host Adapters, or by a dip switch setting on "S" and "A"
  series MultiMaster Host Adapters.  With Extended Translation enabled, drives
  between 1 GB inclusive and 2 GB exclusive are given a disk geometry of 128
  heads and 32 sectors, and drives above 2 GB inclusive are given a disk
  geometry of 255 heads and 63 sectors.  However, if the BIOS detects that the
  Extended Translation setting does not match the geometry in the partition
  table, then the translation inferred from the partition table will be used by
  the BIOS, and a warning may be displayed.
*/

static int blogic_diskparam(struct scsi_device *sdev, struct gendisk *disk,
		sector_t capacity, int *params)
{
	struct blogic_adapter *adapter =
				(struct blogic_adapter *) sdev->host->hostdata;
	struct bios_diskparam *diskparam = (struct bios_diskparam *) params;
	unsigned char *buf;

	if (adapter->ext_trans_enable && capacity >= 2 * 1024 * 1024 /* 1 GB in 512 byte sectors */) {
		if (capacity >= 4 * 1024 * 1024 /* 2 GB in 512 byte sectors */) {
			diskparam->heads = 255;
			diskparam->sectors = 63;
		} else {
			diskparam->heads = 128;
			diskparam->sectors = 32;
		}
	} else {
		diskparam->heads = 64;
		diskparam->sectors = 32;
	}
	diskparam->cylinders = (unsigned long) capacity / (diskparam->heads * diskparam->sectors);
	buf = scsi_bios_ptable(disk);
	if (buf == NULL)
		return 0;
	/*
	   If the boot sector partition table flag is valid, search for
	   a partition table entry whose end_head matches one of the
	   standard BusLogic geometry translations (64/32, 128/32, or 255/63).
	 */
	if (*(unsigned short *) (buf + 64) == MSDOS_LABEL_MAGIC) {
		struct msdos_partition *part1_entry =
				(struct msdos_partition *)buf;
		struct msdos_partition *part_entry = part1_entry;
		int saved_cyl = diskparam->cylinders, part_no;
		unsigned char part_end_head = 0, part_end_sector = 0;

		for (part_no = 0; part_no < 4; part_no++) {
			part_end_head = part_entry->end_head;
			part_end_sector = part_entry->end_sector & 0x3F;
			if (part_end_head == 64 - 1) {
				diskparam->heads = 64;
				diskparam->sectors = 32;
				break;
			} else if (part_end_head == 128 - 1) {
				diskparam->heads = 128;
				diskparam->sectors = 32;
				break;
			} else if (part_end_head == 255 - 1) {
				diskparam->heads = 255;
				diskparam->sectors = 63;
				break;
			}
			part_entry++;
		}
		if (part_no == 4) {
			part_end_head = part1_entry->end_head;
			part_end_sector = part1_entry->end_sector & 0x3F;
		}
		diskparam->cylinders = (unsigned long) capacity / (diskparam->heads * diskparam->sectors);
		if (part_no < 4 && part_end_sector == diskparam->sectors) {
			if (diskparam->cylinders != saved_cyl)
				blogic_warn("Adopting Geometry %d/%d from Partition Table\n", adapter, diskparam->heads, diskparam->sectors);
		} else if (part_end_head > 0 || part_end_sector > 0) {
			blogic_warn("Warning: Partition Table appears to have Geometry %d/%d which is\n", adapter, part_end_head + 1, part_end_sector);
			blogic_warn("not compatible with current BusLogic Host Adapter Geometry %d/%d\n", adapter, diskparam->heads, diskparam->sectors);
		}
	}
	kfree(buf);
	return 0;
}


/*
  BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>.
*/

static int blogic_write_info(struct Scsi_Host *shost, char *procbuf,
				int bytes_avail)
{
	struct blogic_adapter *adapter =
				(struct blogic_adapter *) shost->hostdata;
	struct blogic_tgt_stats *tgt_stats;

	tgt_stats = adapter->tgt_stats;
	adapter->ext_resets = 0;
	adapter->adapter_intern_errors = 0;
	memset(tgt_stats, 0, BLOGIC_MAXDEV * sizeof(struct blogic_tgt_stats));
	return 0;
}

static int blogic_show_info(struct seq_file *m, struct Scsi_Host *shost)
{
	struct blogic_adapter *adapter = (struct blogic_adapter *) shost->hostdata;
	struct blogic_tgt_stats *tgt_stats;
	int tgt;

	tgt_stats = adapter->tgt_stats;
	seq_write(m, adapter->msgbuf, adapter->msgbuflen);
	seq_printf(m, "\n\
Current Driver Queue Depth:	%d\n\
Currently Allocated CCBs:	%d\n", adapter->drvr_qdepth, adapter->alloc_ccbs);
	seq_puts(m, "\n\n\
			   DATA TRANSFER STATISTICS\n\
\n\
Target	Tagged Queuing	Queue Depth  Active  Attempted	Completed\n\
======	==============	===========  ======  =========	=========\n");
	for (tgt = 0; tgt < adapter->maxdev; tgt++) {
		struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
		if (!tgt_flags->tgt_exists)
			continue;
		seq_printf(m, "  %2d	%s", tgt, (tgt_flags->tagq_ok ? (tgt_flags->tagq_active ? "    Active" : (adapter->tagq_ok & (1 << tgt)
																				    ? "  Permitted" : "   Disabled"))
									  : "Not Supported"));
		seq_printf(m,
				  "	    %3d       %3u    %9u	%9u\n", adapter->qdepth[tgt], adapter->active_cmds[tgt], tgt_stats[tgt].cmds_tried, tgt_stats[tgt].cmds_complete);
	}
	seq_puts(m, "\n\
Target  Read Commands  Write Commands   Total Bytes Read    Total Bytes Written\n\
======  =============  ==============  ===================  ===================\n");
	for (tgt = 0; tgt < adapter->maxdev; tgt++) {
		struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
		if (!tgt_flags->tgt_exists)
			continue;
		seq_printf(m, "  %2d	  %9u	 %9u", tgt, tgt_stats[tgt].read_cmds, tgt_stats[tgt].write_cmds);
		if (tgt_stats[tgt].bytesread.billions > 0)
			seq_printf(m, "     %9u%09u", tgt_stats[tgt].bytesread.billions, tgt_stats[tgt].bytesread.units);
		else
			seq_printf(m, "		%9u", tgt_stats[tgt].bytesread.units);
		if (tgt_stats[tgt].byteswritten.billions > 0)
			seq_printf(m, "   %9u%09u\n", tgt_stats[tgt].byteswritten.billions, tgt_stats[tgt].byteswritten.units);
		else
			seq_printf(m, "	     %9u\n", tgt_stats[tgt].byteswritten.units);
	}
	seq_puts(m, "\n\
Target  Command    0-1KB      1-2KB      2-4KB      4-8KB     8-16KB\n\
======  =======  =========  =========  =========  =========  =========\n");
	for (tgt = 0; tgt < adapter->maxdev; tgt++) {
		struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
		if (!tgt_flags->tgt_exists)
			continue;
		seq_printf(m,
			    "  %2d	 Read	 %9u  %9u  %9u  %9u  %9u\n", tgt,
			    tgt_stats[tgt].read_sz_buckets[0],
			    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]);
		seq_printf(m,
			    "  %2d	 Write	 %9u  %9u  %9u  %9u  %9u\n", tgt,
			    tgt_stats[tgt].write_sz_buckets[0],
			    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]);
	}
	seq_puts(m, "\n\
Target  Command   16-32KB    32-64KB   64-128KB   128-256KB   256KB+\n\
======  =======  =========  =========  =========  =========  =========\n");
	for (tgt = 0; tgt < adapter->maxdev; tgt++) {
		struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
		if (!tgt_flags->tgt_exists)
			continue;
		seq_printf(m,
			    "  %2d	 Read	 %9u  %9u  %9u  %9u  %9u\n", tgt,
			    tgt_stats[tgt].read_sz_buckets[5],
			    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]);
		seq_printf(m,
			    "  %2d	 Write	 %9u  %9u  %9u  %9u  %9u\n", tgt,
			    tgt_stats[tgt].write_sz_buckets[5],
			    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]);
	}
	seq_puts(m, "\n\n\
			   ERROR RECOVERY STATISTICS\n\
\n\
	  Command Aborts      Bus Device Resets	  Host Adapter Resets\n\
Target	Requested Completed  Requested Completed  Requested Completed\n\
  ID	\\\\\\\\ Attempted ////  \\\\\\\\ Attempted ////  \\\\\\\\ Attempted ////\n\
======	 ===== ===== =====    ===== ===== =====	   ===== ===== =====\n");
	for (tgt = 0; tgt < adapter->maxdev; tgt++) {
		struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
		if (!tgt_flags->tgt_exists)
			continue;
		seq_printf(m, "  %2d	 %5d %5d %5d    %5d %5d %5d	   %5d %5d %5d\n",
			   tgt, tgt_stats[tgt].aborts_request,
			   tgt_stats[tgt].aborts_tried,
			   tgt_stats[tgt].aborts_done,
			   tgt_stats[tgt].bdr_request,
			   tgt_stats[tgt].bdr_tried,
			   tgt_stats[tgt].bdr_done,
			   tgt_stats[tgt].adapter_reset_req,
			   tgt_stats[tgt].adapter_reset_attempt,
			   tgt_stats[tgt].adapter_reset_done);
	}
	seq_printf(m, "\nExternal Host Adapter Resets: %d\n", adapter->ext_resets);
	seq_printf(m, "Host Adapter Internal Errors: %d\n", adapter->adapter_intern_errors);
	return 0;
}


/*
  blogic_msg prints Driver Messages.
*/
__printf(2, 4)
static void blogic_msg(enum blogic_msglevel msglevel, char *fmt,
			struct blogic_adapter *adapter, ...)
{
	static char buf[BLOGIC_LINEBUF_SIZE];
	static bool begin = true;
	va_list args;
	int len = 0;

	va_start(args, adapter);
	len = vscnprintf(buf, sizeof(buf), fmt, args);
	va_end(args);
	if (msglevel == BLOGIC_ANNOUNCE_LEVEL) {
		static int msglines = 0;
		strcpy(&adapter->msgbuf[adapter->msgbuflen], buf);
		adapter->msgbuflen += len;
		if (++msglines <= 2)
			printk("%sscsi: %s", blogic_msglevelmap[msglevel], buf);
	} else if (msglevel == BLOGIC_INFO_LEVEL) {
		strcpy(&adapter->msgbuf[adapter->msgbuflen], buf);
		adapter->msgbuflen += len;
		if (begin) {
			if (buf[0] != '\n' || len > 1)
				printk("%sscsi%d: %s", blogic_msglevelmap[msglevel], adapter->host_no, buf);
		} else
			pr_cont("%s", buf);
	} else {
		if (begin) {
			if (adapter != NULL && adapter->adapter_initd)
				printk("%sscsi%d: %s", blogic_msglevelmap[msglevel], adapter->host_no, buf);
			else
				printk("%s%s", blogic_msglevelmap[msglevel], buf);
		} else
			pr_cont("%s", buf);
	}
	begin = (buf[len - 1] == '\n');
}


/*
  blogic_parse parses an individual option keyword.  It returns true
  and updates the pointer if the keyword is recognized and false otherwise.
*/

static bool __init blogic_parse(char **str, char *keyword)
{
	char *pointer = *str;
	while (*keyword != '\0') {
		char strch = *pointer++;
		char keywordch = *keyword++;
		if (strch >= 'A' && strch <= 'Z')
			strch += 'a' - 'Z';
		if (keywordch >= 'A' && keywordch <= 'Z')
			keywordch += 'a' - 'Z';
		if (strch != keywordch)
			return false;
	}
	*str = pointer;
	return true;
}


/*
  blogic_parseopts handles processing of BusLogic Driver Options
  specifications.

  BusLogic Driver Options may be specified either via the Linux Kernel Command
  Line or via the Loadable Kernel Module Installation Facility.  Driver Options
  for multiple host adapters may be specified either by separating the option
  strings by a semicolon, or by specifying multiple "BusLogic=" strings on the
  command line.  Individual option specifications for a single host adapter are
  separated by commas.  The Probing and Debugging Options apply to all host
  adapters whereas the remaining options apply individually only to the
  selected host adapter.

  The BusLogic Driver Probing Options are described in
  <file:Documentation/scsi/BusLogic.rst>.
*/

static int __init blogic_parseopts(char *options)
{
	while (true) {
		struct blogic_drvr_options *drvr_opts =
			&blogic_drvr_options[blogic_drvr_options_count++];
		int tgt_id;

		memset(drvr_opts, 0, sizeof(struct blogic_drvr_options));
		while (*options != '\0' && *options != ';') {
			if (blogic_parse(&options, "NoProbePCI"))
				blogic_probe_options.noprobe_pci = true;
			else if (blogic_parse(&options, "NoProbe"))
				blogic_probe_options.noprobe = true;
			else if (blogic_parse(&options, "NoSortPCI"))
				blogic_probe_options.nosort_pci = true;
			else if (blogic_parse(&options, "MultiMasterFirst"))
				blogic_probe_options.multimaster_first = true;
			else if (blogic_parse(&options, "FlashPointFirst"))
				blogic_probe_options.flashpoint_first = true;
			/* Tagged Queuing Options. */
			else if (blogic_parse(&options, "QueueDepth:[") ||
					blogic_parse(&options, "QD:[")) {
				for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++) {
					unsigned short qdepth = simple_strtoul(options, &options, 0);
					if (qdepth > BLOGIC_MAX_TAG_DEPTH) {
						blogic_err("BusLogic: Invalid Driver Options (invalid Queue Depth %d)\n", NULL, qdepth);
						return 0;
					}
					drvr_opts->qdepth[tgt_id] = qdepth;
					if (*options == ',')
						options++;
					else if (*options == ']')
						break;
					else {
						blogic_err("BusLogic: Invalid Driver Options (',' or ']' expected at '%s')\n", NULL, options);
						return 0;
					}
				}
				if (*options != ']') {
					blogic_err("BusLogic: Invalid Driver Options (']' expected at '%s')\n", NULL, options);
					return 0;
				} else
					options++;
			} else if (blogic_parse(&options, "QueueDepth:") || blogic_parse(&options, "QD:")) {
				unsigned short qdepth = simple_strtoul(options, &options, 0);
				if (qdepth == 0 ||
						qdepth > BLOGIC_MAX_TAG_DEPTH) {
					blogic_err("BusLogic: Invalid Driver Options (invalid Queue Depth %d)\n", NULL, qdepth);
					return 0;
				}
				drvr_opts->common_qdepth = qdepth;
				for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++)
					drvr_opts->qdepth[tgt_id] = qdepth;
			} else if (blogic_parse(&options, "TaggedQueuing:") ||
					blogic_parse(&options, "TQ:")) {
				if (blogic_parse(&options, "Default")) {
					drvr_opts->tagq_ok = 0x0000;
					drvr_opts->tagq_ok_mask = 0x0000;
				} else if (blogic_parse(&options, "Enable")) {
					drvr_opts->tagq_ok = 0xFFFF;
					drvr_opts->tagq_ok_mask = 0xFFFF;
				} else if (blogic_parse(&options, "Disable")) {
					drvr_opts->tagq_ok = 0x0000;
					drvr_opts->tagq_ok_mask = 0xFFFF;
				} else {
					unsigned short tgt_bit;
					for (tgt_id = 0, tgt_bit = 1;
						tgt_id < BLOGIC_MAXDEV;
						tgt_id++, tgt_bit <<= 1)
						switch (*options++) {
						case 'Y':
							drvr_opts->tagq_ok |= tgt_bit;
							drvr_opts->tagq_ok_mask |= tgt_bit;
							break;
						case 'N':
							drvr_opts->tagq_ok &= ~tgt_bit;
							drvr_opts->tagq_ok_mask |= tgt_bit;
							break;
						case 'X':
							break;
						default:
							options--;
							tgt_id = BLOGIC_MAXDEV;
							break;
						}
				}
			}
			/* Miscellaneous Options. */
			else if (blogic_parse(&options, "BusSettleTime:") ||
					blogic_parse(&options, "BST:")) {
				unsigned short bus_settle_time =
					simple_strtoul(options, &options, 0);
				if (bus_settle_time > 5 * 60) {
					blogic_err("BusLogic: Invalid Driver Options (invalid Bus Settle Time %d)\n", NULL, bus_settle_time);
					return 0;
				}
				drvr_opts->bus_settle_time = bus_settle_time;
			} else if (blogic_parse(&options,
						"InhibitTargetInquiry"))
				drvr_opts->stop_tgt_inquiry = true;
			/* Debugging Options. */
			else if (blogic_parse(&options, "TraceProbe"))
				blogic_global_options.trace_probe = true;
			else if (blogic_parse(&options, "TraceHardwareReset"))
				blogic_global_options.trace_hw_reset = true;
			else if (blogic_parse(&options, "TraceConfiguration"))
				blogic_global_options.trace_config = true;
			else if (blogic_parse(&options, "TraceErrors"))
				blogic_global_options.trace_err = true;
			else if (blogic_parse(&options, "Debug")) {
				blogic_global_options.trace_probe = true;
				blogic_global_options.trace_hw_reset = true;
				blogic_global_options.trace_config = true;
				blogic_global_options.trace_err = true;
			}
			if (*options == ',')
				options++;
			else if (*options != ';' && *options != '\0') {
				blogic_err("BusLogic: Unexpected Driver Option '%s' ignored\n", NULL, options);
				*options = '\0';
			}
		}
		if (!(blogic_drvr_options_count == 0 ||
			blogic_probeinfo_count == 0 ||
			blogic_drvr_options_count == blogic_probeinfo_count)) {
			blogic_err("BusLogic: Invalid Driver Options (all or no I/O Addresses must be specified)\n", NULL);
			return 0;
		}
		/*
		   Tagged Queuing is disabled when the Queue Depth is 1 since queuing
		   multiple commands is not possible.
		 */
		for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++)
			if (drvr_opts->qdepth[tgt_id] == 1) {
				unsigned short tgt_bit = 1 << tgt_id;
				drvr_opts->tagq_ok &= ~tgt_bit;
				drvr_opts->tagq_ok_mask |= tgt_bit;
			}
		if (*options == ';')
			options++;
		if (*options == '\0')
			return 0;
	}
	return 1;
}

/*
  Get it all started
*/

static const struct scsi_host_template blogic_template = {
	.module = THIS_MODULE,
	.proc_name = "BusLogic",
	.write_info = blogic_write_info,
	.show_info = blogic_show_info,
	.name = "BusLogic",
	.info = blogic_drvr_info,
	.queuecommand = blogic_qcmd,
	.sdev_configure = blogic_sdev_configure,
	.bios_param = blogic_diskparam,
	.eh_host_reset_handler = blogic_hostreset,
#if 0
	.eh_abort_handler = blogic_abort,
#endif
	.max_sectors = 128,
};

/*
  blogic_setup handles processing of Kernel Command Line Arguments.
*/

static int __init blogic_setup(char *str)
{
	int ints[3];

	(void) get_options(str, ARRAY_SIZE(ints), ints);

	if (ints[0] != 0) {
		blogic_err("BusLogic: Obsolete Command Line Entry Format Ignored\n", NULL);
		return 0;
	}
	if (str == NULL || *str == '\0')
		return 0;
	return blogic_parseopts(str);
}

/*
 * Exit function.  Deletes all hosts associated with this driver.
 */

static void __exit blogic_exit(void)
{
	struct blogic_adapter *ha, *next;

	list_for_each_entry_safe(ha, next, &blogic_host_list, host_list)
		blogic_deladapter(ha);
}

__setup("BusLogic=", blogic_setup);

/*static const struct pci_device_id blogic_pci_tbl[] = {
	{ PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
	{ PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
	{ PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
	{ }
};*/
static const struct pci_device_id blogic_pci_tbl[] __maybe_unused = {
	{PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER)},
	{PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC)},
	{PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT)},
	{0, },
};
MODULE_DEVICE_TABLE(pci, blogic_pci_tbl);

module_init(blogic_init);
module_exit(blogic_exit);
