/*
 *  linux/drivers/scsi/esas2r/esas2r_init.c
 *      For use with ATTO ExpressSAS R6xx SAS/SATA RAID controllers
 *
 *  Copyright (c) 2001-2013 ATTO Technology, Inc.
 *  (mailto:linuxdrivers@attotech.com)mpt3sas/mpt3sas_trigger_diag.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * NO WARRANTY
 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
 * solely responsible for determining the appropriateness of using and
 * distributing the Program and assumes all risks associated with its
 * exercise of rights under this Agreement, including but not limited to
 * the risks and costs of program errors, damage to or loss of data,
 * programs or equipment, and unavailability or interruption of operations.
 *
 * DISCLAIMER OF LIABILITY
 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
 * USA.
 */

#include "esas2r.h"

static bool esas2r_initmem_alloc(struct esas2r_adapter *a,
				 struct esas2r_mem_desc *mem_desc,
				 u32 align)
{
	mem_desc->esas2r_param = mem_desc->size + align;
	mem_desc->virt_addr = NULL;
	mem_desc->phys_addr = 0;
	mem_desc->esas2r_data = dma_alloc_coherent(&a->pcid->dev,
						   (size_t)mem_desc->
						   esas2r_param,
						   (dma_addr_t *)&mem_desc->
						   phys_addr,
						   GFP_KERNEL);

	if (mem_desc->esas2r_data == NULL) {
		esas2r_log(ESAS2R_LOG_CRIT,
			   "failed to allocate %lu bytes of consistent memory!",
			   (long
			    unsigned
			    int)mem_desc->esas2r_param);
		return false;
	}

	mem_desc->virt_addr = PTR_ALIGN(mem_desc->esas2r_data, align);
	mem_desc->phys_addr = ALIGN(mem_desc->phys_addr, align);
	memset(mem_desc->virt_addr, 0, mem_desc->size);
	return true;
}

static void esas2r_initmem_free(struct esas2r_adapter *a,
				struct esas2r_mem_desc *mem_desc)
{
	if (mem_desc->virt_addr == NULL)
		return;

	/*
	 * Careful!  phys_addr and virt_addr may have been adjusted from the
	 * original allocation in order to return the desired alignment.  That
	 * means we have to use the original address (in esas2r_data) and size
	 * (esas2r_param) and calculate the original physical address based on
	 * the difference between the requested and actual allocation size.
	 */
	if (mem_desc->phys_addr) {
		int unalign = ((u8 *)mem_desc->virt_addr) -
			      ((u8 *)mem_desc->esas2r_data);

		dma_free_coherent(&a->pcid->dev,
				  (size_t)mem_desc->esas2r_param,
				  mem_desc->esas2r_data,
				  (dma_addr_t)(mem_desc->phys_addr - unalign));
	} else {
		kfree(mem_desc->esas2r_data);
	}

	mem_desc->virt_addr = NULL;
}

static bool alloc_vda_req(struct esas2r_adapter *a,
			  struct esas2r_request *rq)
{
	struct esas2r_mem_desc *memdesc = kzalloc(
		sizeof(struct esas2r_mem_desc), GFP_KERNEL);

	if (memdesc == NULL) {
		esas2r_hdebug("could not alloc mem for vda request memdesc\n");
		return false;
	}

	memdesc->size = sizeof(union atto_vda_req) +
			ESAS2R_DATA_BUF_LEN;

	if (!esas2r_initmem_alloc(a, memdesc, 256)) {
		esas2r_hdebug("could not alloc mem for vda request\n");
		kfree(memdesc);
		return false;
	}

	a->num_vrqs++;
	list_add(&memdesc->next_desc, &a->vrq_mds_head);

	rq->vrq_md = memdesc;
	rq->vrq = (union atto_vda_req *)memdesc->virt_addr;
	rq->vrq->scsi.handle = a->num_vrqs;

	return true;
}

static void esas2r_unmap_regions(struct esas2r_adapter *a)
{
	if (a->regs)
		iounmap((void __iomem *)a->regs);

	a->regs = NULL;

	pci_release_region(a->pcid, 2);

	if (a->data_window)
		iounmap((void __iomem *)a->data_window);

	a->data_window = NULL;

	pci_release_region(a->pcid, 0);
}

static int esas2r_map_regions(struct esas2r_adapter *a)
{
	int error;

	a->regs = NULL;
	a->data_window = NULL;

	error = pci_request_region(a->pcid, 2, a->name);
	if (error != 0) {
		esas2r_log(ESAS2R_LOG_CRIT,
			   "pci_request_region(2) failed, error %d",
			   error);

		return error;
	}

	a->regs = (void __force *)ioremap(pci_resource_start(a->pcid, 2),
					  pci_resource_len(a->pcid, 2));
	if (a->regs == NULL) {
		esas2r_log(ESAS2R_LOG_CRIT,
			   "ioremap failed for regs mem region\n");
		pci_release_region(a->pcid, 2);
		return -EFAULT;
	}

	error = pci_request_region(a->pcid, 0, a->name);
	if (error != 0) {
		esas2r_log(ESAS2R_LOG_CRIT,
			   "pci_request_region(2) failed, error %d",
			   error);
		esas2r_unmap_regions(a);
		return error;
	}

	a->data_window = (void __force *)ioremap(pci_resource_start(a->pcid,
								    0),
						 pci_resource_len(a->pcid, 0));
	if (a->data_window == NULL) {
		esas2r_log(ESAS2R_LOG_CRIT,
			   "ioremap failed for data_window mem region\n");
		esas2r_unmap_regions(a);
		return -EFAULT;
	}

	return 0;
}

static void esas2r_setup_interrupts(struct esas2r_adapter *a, int intr_mode)
{
	int i;

	/* Set up interrupt mode based on the requested value */
	switch (intr_mode) {
	case INTR_MODE_LEGACY:
use_legacy_interrupts:
		a->intr_mode = INTR_MODE_LEGACY;
		break;

	case INTR_MODE_MSI:
		i = pci_enable_msi(a->pcid);
		if (i != 0) {
			esas2r_log(ESAS2R_LOG_WARN,
				   "failed to enable MSI for adapter %d, "
				   "falling back to legacy interrupts "
				   "(err=%d)", a->index,
				   i);
			goto use_legacy_interrupts;
		}
		a->intr_mode = INTR_MODE_MSI;
		set_bit(AF2_MSI_ENABLED, &a->flags2);
		break;


	default:
		esas2r_log(ESAS2R_LOG_WARN,
			   "unknown interrupt_mode %d requested, "
			   "falling back to legacy interrupt",
			   interrupt_mode);
		goto use_legacy_interrupts;
	}
}

static void esas2r_claim_interrupts(struct esas2r_adapter *a)
{
	unsigned long flags = 0;

	if (a->intr_mode == INTR_MODE_LEGACY)
		flags |= IRQF_SHARED;

	esas2r_log(ESAS2R_LOG_INFO,
		   "esas2r_claim_interrupts irq=%d (%p, %s, %lx)",
		   a->pcid->irq, a, a->name, flags);

	if (request_irq(a->pcid->irq,
			(a->intr_mode ==
			 INTR_MODE_LEGACY) ? esas2r_interrupt :
			esas2r_msi_interrupt,
			flags,
			a->name,
			a)) {
		esas2r_log(ESAS2R_LOG_CRIT, "unable to request IRQ %02X",
			   a->pcid->irq);
		return;
	}

	set_bit(AF2_IRQ_CLAIMED, &a->flags2);
	esas2r_log(ESAS2R_LOG_INFO,
		   "claimed IRQ %d flags: 0x%lx",
		   a->pcid->irq, flags);
}

int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,
			int index)
{
	struct esas2r_adapter *a;
	u64 bus_addr = 0;
	int i;
	void *next_uncached;
	struct esas2r_request *first_request, *last_request;
	bool dma64 = false;

	if (index >= MAX_ADAPTERS) {
		esas2r_log(ESAS2R_LOG_CRIT,
			   "tried to init invalid adapter index %u!",
			   index);
		return 0;
	}

	if (esas2r_adapters[index]) {
		esas2r_log(ESAS2R_LOG_CRIT,
			   "tried to init existing adapter index %u!",
			   index);
		return 0;
	}

	a = (struct esas2r_adapter *)host->hostdata;
	memset(a, 0, sizeof(struct esas2r_adapter));
	a->pcid = pcid;
	a->host = host;

	if (sizeof(dma_addr_t) > 4 &&
	    dma_get_required_mask(&pcid->dev) > DMA_BIT_MASK(32) &&
	    !dma_set_mask_and_coherent(&pcid->dev, DMA_BIT_MASK(64)))
		dma64 = true;

	if (!dma64 && dma_set_mask_and_coherent(&pcid->dev, DMA_BIT_MASK(32))) {
		esas2r_log(ESAS2R_LOG_CRIT, "failed to set DMA mask");
		esas2r_kill_adapter(index);
		return 0;
	}

	esas2r_log_dev(ESAS2R_LOG_INFO, &pcid->dev,
		       "%s-bit PCI addressing enabled\n", dma64 ? "64" : "32");

	esas2r_adapters[index] = a;
	sprintf(a->name, ESAS2R_DRVR_NAME "_%02d", index);
	esas2r_debug("new adapter %p, name %s", a, a->name);
	spin_lock_init(&a->request_lock);
	spin_lock_init(&a->fw_event_lock);
	mutex_init(&a->fm_api_mutex);
	mutex_init(&a->fs_api_mutex);
	sema_init(&a->nvram_semaphore, 1);

	esas2r_fw_event_off(a);
	snprintf(a->fw_event_q_name, ESAS2R_KOBJ_NAME_LEN, "esas2r/%d",
		 a->index);
	a->fw_event_q = create_singlethread_workqueue(a->fw_event_q_name);

	init_waitqueue_head(&a->buffered_ioctl_waiter);
	init_waitqueue_head(&a->nvram_waiter);
	init_waitqueue_head(&a->fm_api_waiter);
	init_waitqueue_head(&a->fs_api_waiter);
	init_waitqueue_head(&a->vda_waiter);

	INIT_LIST_HEAD(&a->general_req.req_list);
	INIT_LIST_HEAD(&a->active_list);
	INIT_LIST_HEAD(&a->defer_list);
	INIT_LIST_HEAD(&a->free_sg_list_head);
	INIT_LIST_HEAD(&a->avail_request);
	INIT_LIST_HEAD(&a->vrq_mds_head);
	INIT_LIST_HEAD(&a->fw_event_list);

	first_request = (struct esas2r_request *)((u8 *)(a + 1));

	for (last_request = first_request, i = 1; i < num_requests;
	     last_request++, i++) {
		INIT_LIST_HEAD(&last_request->req_list);
		list_add_tail(&last_request->comp_list, &a->avail_request);
		if (!alloc_vda_req(a, last_request)) {
			esas2r_log(ESAS2R_LOG_CRIT,
				   "failed to allocate a VDA request!");
			esas2r_kill_adapter(index);
			return 0;
		}
	}

	esas2r_debug("requests: %p to %p (%d, %d)", first_request,
		     last_request,
		     sizeof(*first_request),
		     num_requests);

	if (esas2r_map_regions(a) != 0) {
		esas2r_log(ESAS2R_LOG_CRIT, "could not map PCI regions!");
		esas2r_kill_adapter(index);
		return 0;
	}

	a->index = index;

	/* interrupts will be disabled until we are done with init */
	atomic_inc(&a->dis_ints_cnt);
	atomic_inc(&a->disable_cnt);
	set_bit(AF_CHPRST_PENDING, &a->flags);
	set_bit(AF_DISC_PENDING, &a->flags);
	set_bit(AF_FIRST_INIT, &a->flags);
	set_bit(AF_LEGACY_SGE_MODE, &a->flags);

	a->init_msg = ESAS2R_INIT_MSG_START;
	a->max_vdareq_size = 128;
	a->build_sgl = esas2r_build_sg_list_sge;

	esas2r_setup_interrupts(a, interrupt_mode);

	a->uncached_size = esas2r_get_uncached_size(a);
	a->uncached = dma_alloc_coherent(&pcid->dev,
					 (size_t)a->uncached_size,
					 (dma_addr_t *)&bus_addr,
					 GFP_KERNEL);
	if (a->uncached == NULL) {
		esas2r_log(ESAS2R_LOG_CRIT,
			   "failed to allocate %d bytes of consistent memory!",
			   a->uncached_size);
		esas2r_kill_adapter(index);
		return 0;
	}

	a->uncached_phys = bus_addr;

	esas2r_debug("%d bytes uncached memory allocated @ %p (%x:%x)",
		     a->uncached_size,
		     a->uncached,
		     upper_32_bits(bus_addr),
		     lower_32_bits(bus_addr));
	memset(a->uncached, 0, a->uncached_size);
	next_uncached = a->uncached;

	if (!esas2r_init_adapter_struct(a,
					&next_uncached)) {
		esas2r_log(ESAS2R_LOG_CRIT,
			   "failed to initialize adapter structure (2)!");
		esas2r_kill_adapter(index);
		return 0;
	}

	tasklet_init(&a->tasklet,
		     esas2r_adapter_tasklet,
		     (unsigned long)a);

	/*
	 * Disable chip interrupts to prevent spurious interrupts
	 * until we claim the IRQ.
	 */
	esas2r_disable_chip_interrupts(a);
	esas2r_check_adapter(a);

	if (!esas2r_init_adapter_hw(a, true)) {
		esas2r_log(ESAS2R_LOG_CRIT, "failed to initialize hardware!");
	} else {
		esas2r_debug("esas2r_init_adapter ok");
	}

	esas2r_claim_interrupts(a);

	if (test_bit(AF2_IRQ_CLAIMED, &a->flags2))
		esas2r_enable_chip_interrupts(a);

	set_bit(AF2_INIT_DONE, &a->flags2);
	if (!test_bit(AF_DEGRADED_MODE, &a->flags))
		esas2r_kickoff_timer(a);
	esas2r_debug("esas2r_init_adapter done for %p (%d)",
		     a, a->disable_cnt);

	return 1;
}

static void esas2r_adapter_power_down(struct esas2r_adapter *a,
				      int power_management)
{
	struct esas2r_mem_desc *memdesc, *next;

	if ((test_bit(AF2_INIT_DONE, &a->flags2))
	    &&  (!test_bit(AF_DEGRADED_MODE, &a->flags))) {
		if (!power_management) {
			del_timer_sync(&a->timer);
			tasklet_kill(&a->tasklet);
		}
		esas2r_power_down(a);

		/*
		 * There are versions of firmware that do not handle the sync
		 * cache command correctly.  Stall here to ensure that the
		 * cache is lazily flushed.
		 */
		mdelay(500);
		esas2r_debug("chip halted");
	}

	/* Remove sysfs binary files */
	if (a->sysfs_fw_created) {
		sysfs_remove_bin_file(&a->host->shost_dev.kobj, &bin_attr_fw);
		a->sysfs_fw_created = 0;
	}

	if (a->sysfs_fs_created) {
		sysfs_remove_bin_file(&a->host->shost_dev.kobj, &bin_attr_fs);
		a->sysfs_fs_created = 0;
	}

	if (a->sysfs_vda_created) {
		sysfs_remove_bin_file(&a->host->shost_dev.kobj, &bin_attr_vda);
		a->sysfs_vda_created = 0;
	}

	if (a->sysfs_hw_created) {
		sysfs_remove_bin_file(&a->host->shost_dev.kobj, &bin_attr_hw);
		a->sysfs_hw_created = 0;
	}

	if (a->sysfs_live_nvram_created) {
		sysfs_remove_bin_file(&a->host->shost_dev.kobj,
				      &bin_attr_live_nvram);
		a->sysfs_live_nvram_created = 0;
	}

	if (a->sysfs_default_nvram_created) {
		sysfs_remove_bin_file(&a->host->shost_dev.kobj,
				      &bin_attr_default_nvram);
		a->sysfs_default_nvram_created = 0;
	}

	/* Clean up interrupts */
	if (test_bit(AF2_IRQ_CLAIMED, &a->flags2)) {
		esas2r_log_dev(ESAS2R_LOG_INFO,
			       &(a->pcid->dev),
			       "free_irq(%d) called", a->pcid->irq);

		free_irq(a->pcid->irq, a);
		esas2r_debug("IRQ released");
		clear_bit(AF2_IRQ_CLAIMED, &a->flags2);
	}

	if (test_bit(AF2_MSI_ENABLED, &a->flags2)) {
		pci_disable_msi(a->pcid);
		clear_bit(AF2_MSI_ENABLED, &a->flags2);
		esas2r_debug("MSI disabled");
	}

	if (a->inbound_list_md.virt_addr)
		esas2r_initmem_free(a, &a->inbound_list_md);

	if (a->outbound_list_md.virt_addr)
		esas2r_initmem_free(a, &a->outbound_list_md);

	list_for_each_entry_safe(memdesc, next, &a->free_sg_list_head,
				 next_desc) {
		esas2r_initmem_free(a, memdesc);
	}

	/* Following frees everything allocated via alloc_vda_req */
	list_for_each_entry_safe(memdesc, next, &a->vrq_mds_head, next_desc) {
		esas2r_initmem_free(a, memdesc);
		list_del(&memdesc->next_desc);
		kfree(memdesc);
	}

	kfree(a->first_ae_req);
	a->first_ae_req = NULL;

	kfree(a->sg_list_mds);
	a->sg_list_mds = NULL;

	kfree(a->req_table);
	a->req_table = NULL;

	if (a->regs) {
		esas2r_unmap_regions(a);
		a->regs = NULL;
		a->data_window = NULL;
		esas2r_debug("regions unmapped");
	}
}

/* Release/free allocated resources for specified adapters. */
void esas2r_kill_adapter(int i)
{
	struct esas2r_adapter *a = esas2r_adapters[i];

	if (a) {
		unsigned long flags;
		struct workqueue_struct *wq;
		esas2r_debug("killing adapter %p [%d] ", a, i);
		esas2r_fw_event_off(a);
		esas2r_adapter_power_down(a, 0);
		if (esas2r_buffered_ioctl &&
		    (a->pcid == esas2r_buffered_ioctl_pcid)) {
			dma_free_coherent(&a->pcid->dev,
					  (size_t)esas2r_buffered_ioctl_size,
					  esas2r_buffered_ioctl,
					  esas2r_buffered_ioctl_addr);
			esas2r_buffered_ioctl = NULL;
		}

		if (a->vda_buffer) {
			dma_free_coherent(&a->pcid->dev,
					  (size_t)VDA_MAX_BUFFER_SIZE,
					  a->vda_buffer,
					  (dma_addr_t)a->ppvda_buffer);
			a->vda_buffer = NULL;
		}
		if (a->fs_api_buffer) {
			dma_free_coherent(&a->pcid->dev,
					  (size_t)a->fs_api_buffer_size,
					  a->fs_api_buffer,
					  (dma_addr_t)a->ppfs_api_buffer);
			a->fs_api_buffer = NULL;
		}

		kfree(a->local_atto_ioctl);
		a->local_atto_ioctl = NULL;

		spin_lock_irqsave(&a->fw_event_lock, flags);
		wq = a->fw_event_q;
		a->fw_event_q = NULL;
		spin_unlock_irqrestore(&a->fw_event_lock, flags);
		if (wq)
			destroy_workqueue(wq);

		if (a->uncached) {
			dma_free_coherent(&a->pcid->dev,
					  (size_t)a->uncached_size,
					  a->uncached,
					  (dma_addr_t)a->uncached_phys);
			a->uncached = NULL;
			esas2r_debug("uncached area freed");
		}

		esas2r_log_dev(ESAS2R_LOG_INFO,
			       &(a->pcid->dev),
			       "pci_disable_device() called.  msix_enabled: %d "
			       "msi_enabled: %d irq: %d pin: %d",
			       a->pcid->msix_enabled,
			       a->pcid->msi_enabled,
			       a->pcid->irq,
			       a->pcid->pin);

		esas2r_log_dev(ESAS2R_LOG_INFO,
			       &(a->pcid->dev),
			       "before pci_disable_device() enable_cnt: %d",
			       a->pcid->enable_cnt.counter);

		pci_disable_device(a->pcid);
		esas2r_log_dev(ESAS2R_LOG_INFO,
			       &(a->pcid->dev),
			       "after pci_disable_device() enable_cnt: %d",
			       a->pcid->enable_cnt.counter);

		esas2r_log_dev(ESAS2R_LOG_INFO,
			       &(a->pcid->dev),
			       "pci_set_drv_data(%p, NULL) called",
			       a->pcid);

		pci_set_drvdata(a->pcid, NULL);
		esas2r_adapters[i] = NULL;

		if (test_bit(AF2_INIT_DONE, &a->flags2)) {
			clear_bit(AF2_INIT_DONE, &a->flags2);

			set_bit(AF_DEGRADED_MODE, &a->flags);

			esas2r_log_dev(ESAS2R_LOG_INFO,
				       &(a->host->shost_gendev),
				       "scsi_remove_host() called");

			scsi_remove_host(a->host);

			esas2r_log_dev(ESAS2R_LOG_INFO,
				       &(a->host->shost_gendev),
				       "scsi_host_put() called");

			scsi_host_put(a->host);
		}
	}
}

static int __maybe_unused esas2r_suspend(struct device *dev)
{
	struct Scsi_Host *host = dev_get_drvdata(dev);
	struct esas2r_adapter *a = (struct esas2r_adapter *)host->hostdata;

	esas2r_log_dev(ESAS2R_LOG_INFO, dev, "suspending adapter()");
	if (!a)
		return -ENODEV;

	esas2r_adapter_power_down(a, 1);
	esas2r_log_dev(ESAS2R_LOG_INFO, dev, "esas2r_suspend(): 0");
	return 0;
}

static int __maybe_unused esas2r_resume(struct device *dev)
{
	struct Scsi_Host *host = dev_get_drvdata(dev);
	struct esas2r_adapter *a = (struct esas2r_adapter *)host->hostdata;
	int rez = 0;

	esas2r_log_dev(ESAS2R_LOG_INFO, dev, "resuming adapter()");

	if (!a) {
		rez = -ENODEV;
		goto error_exit;
	}

	if (esas2r_map_regions(a) != 0) {
		esas2r_log(ESAS2R_LOG_CRIT, "could not re-map PCI regions!");
		rez = -ENOMEM;
		goto error_exit;
	}

	/* Set up interupt mode */
	esas2r_setup_interrupts(a, a->intr_mode);

	/*
	 * Disable chip interrupts to prevent spurious interrupts until we
	 * claim the IRQ.
	 */
	esas2r_disable_chip_interrupts(a);
	if (!esas2r_power_up(a, true)) {
		esas2r_debug("yikes, esas2r_power_up failed");
		rez = -ENOMEM;
		goto error_exit;
	}

	esas2r_claim_interrupts(a);

	if (test_bit(AF2_IRQ_CLAIMED, &a->flags2)) {
		/*
		 * Now that system interrupt(s) are claimed, we can enable
		 * chip interrupts.
		 */
		esas2r_enable_chip_interrupts(a);
		esas2r_kickoff_timer(a);
	} else {
		esas2r_debug("yikes, unable to claim IRQ");
		esas2r_log(ESAS2R_LOG_CRIT, "could not re-claim IRQ!");
		rez = -ENOMEM;
		goto error_exit;
	}

error_exit:
	esas2r_log_dev(ESAS2R_LOG_CRIT, dev, "esas2r_resume(): %d",
		       rez);
	return rez;
}

SIMPLE_DEV_PM_OPS(esas2r_pm_ops, esas2r_suspend, esas2r_resume);

bool esas2r_set_degraded_mode(struct esas2r_adapter *a, char *error_str)
{
	set_bit(AF_DEGRADED_MODE, &a->flags);
	esas2r_log(ESAS2R_LOG_CRIT,
		   "setting adapter to degraded mode: %s\n", error_str);
	return false;
}

u32 esas2r_get_uncached_size(struct esas2r_adapter *a)
{
	return sizeof(struct esas2r_sas_nvram)
	       + ALIGN(ESAS2R_DISC_BUF_LEN, 8)
	       + ALIGN(sizeof(u32), 8) /* outbound list copy pointer */
	       + 8
	       + (num_sg_lists * (u16)sgl_page_size)
	       + ALIGN((num_requests + num_ae_requests + 1 +
			ESAS2R_LIST_EXTRA) *
		       sizeof(struct esas2r_inbound_list_source_entry),
		       8)
	       + ALIGN((num_requests + num_ae_requests + 1 +
			ESAS2R_LIST_EXTRA) *
		       sizeof(struct atto_vda_ob_rsp), 8)
	       + 256; /* VDA request and buffer align */
}

static void esas2r_init_pci_cfg_space(struct esas2r_adapter *a)
{
	if (pci_is_pcie(a->pcid)) {
		u16 devcontrol;

		pcie_capability_read_word(a->pcid, PCI_EXP_DEVCTL, &devcontrol);

		if ((devcontrol & PCI_EXP_DEVCTL_READRQ) >
		     PCI_EXP_DEVCTL_READRQ_512B) {
			esas2r_log(ESAS2R_LOG_INFO,
				   "max read request size > 512B");

			devcontrol &= ~PCI_EXP_DEVCTL_READRQ;
			devcontrol |= PCI_EXP_DEVCTL_READRQ_512B;
			pcie_capability_write_word(a->pcid, PCI_EXP_DEVCTL,
						   devcontrol);
		}
	}
}

/*
 * Determine the organization of the uncached data area and
 * finish initializing the adapter structure
 */
bool esas2r_init_adapter_struct(struct esas2r_adapter *a,
				void **uncached_area)
{
	u32 i;
	u8 *high;
	struct esas2r_inbound_list_source_entry *element;
	struct esas2r_request *rq;
	struct esas2r_mem_desc *sgl;

	spin_lock_init(&a->sg_list_lock);
	spin_lock_init(&a->mem_lock);
	spin_lock_init(&a->queue_lock);

	a->targetdb_end = &a->targetdb[ESAS2R_MAX_TARGETS];

	if (!alloc_vda_req(a, &a->general_req)) {
		esas2r_hdebug(
			"failed to allocate a VDA request for the general req!");
		return false;
	}

	/* allocate requests for asynchronous events */
	a->first_ae_req =
		kcalloc(num_ae_requests, sizeof(struct esas2r_request),
			GFP_KERNEL);

	if (a->first_ae_req == NULL) {
		esas2r_log(ESAS2R_LOG_CRIT,
			   "failed to allocate memory for asynchronous events");
		return false;
	}

	/* allocate the S/G list memory descriptors */
	a->sg_list_mds = kcalloc(num_sg_lists, sizeof(struct esas2r_mem_desc),
				 GFP_KERNEL);

	if (a->sg_list_mds == NULL) {
		esas2r_log(ESAS2R_LOG_CRIT,
			   "failed to allocate memory for s/g list descriptors");
		return false;
	}

	/* allocate the request table */
	a->req_table =
		kcalloc(num_requests + num_ae_requests + 1,
			sizeof(struct esas2r_request *),
			GFP_KERNEL);

	if (a->req_table == NULL) {
		esas2r_log(ESAS2R_LOG_CRIT,
			   "failed to allocate memory for the request table");
		return false;
	}

	/* initialize PCI configuration space */
	esas2r_init_pci_cfg_space(a);

	/*
	 * the thunder_stream boards all have a serial flash part that has a
	 * different base address on the AHB bus.
	 */
	if ((a->pcid->subsystem_vendor == ATTO_VENDOR_ID)
	    && (a->pcid->subsystem_device & ATTO_SSDID_TBT))
		a->flags2 |= AF2_THUNDERBOLT;

	if (test_bit(AF2_THUNDERBOLT, &a->flags2))
		a->flags2 |= AF2_SERIAL_FLASH;

	if (a->pcid->subsystem_device == ATTO_TLSH_1068)
		a->flags2 |= AF2_THUNDERLINK;

	/* Uncached Area */
	high = (u8 *)*uncached_area;

	/* initialize the scatter/gather table pages */

	for (i = 0, sgl = a->sg_list_mds; i < num_sg_lists; i++, sgl++) {
		sgl->size = sgl_page_size;

		list_add_tail(&sgl->next_desc, &a->free_sg_list_head);

		if (!esas2r_initmem_alloc(a, sgl, ESAS2R_SGL_ALIGN)) {
			/* Allow the driver to load if the minimum count met. */
			if (i < NUM_SGL_MIN)
				return false;
			break;
		}
	}

	/* compute the size of the lists */
	a->list_size = num_requests + ESAS2R_LIST_EXTRA;

	/* allocate the inbound list */
	a->inbound_list_md.size = a->list_size *
				  sizeof(struct
					 esas2r_inbound_list_source_entry);

	if (!esas2r_initmem_alloc(a, &a->inbound_list_md, ESAS2R_LIST_ALIGN)) {
		esas2r_hdebug("failed to allocate IB list");
		return false;
	}

	/* allocate the outbound list */
	a->outbound_list_md.size = a->list_size *
				   sizeof(struct atto_vda_ob_rsp);

	if (!esas2r_initmem_alloc(a, &a->outbound_list_md,
				  ESAS2R_LIST_ALIGN)) {
		esas2r_hdebug("failed to allocate IB list");
		return false;
	}

	/* allocate the NVRAM structure */
	a->nvram = (struct esas2r_sas_nvram *)high;
	high += sizeof(struct esas2r_sas_nvram);

	/* allocate the discovery buffer */
	a->disc_buffer = high;
	high += ESAS2R_DISC_BUF_LEN;
	high = PTR_ALIGN(high, 8);

	/* allocate the outbound list copy pointer */
	a->outbound_copy = (u32 volatile *)high;
	high += sizeof(u32);

	if (!test_bit(AF_NVR_VALID, &a->flags))
		esas2r_nvram_set_defaults(a);

	/* update the caller's uncached memory area pointer */
	*uncached_area = (void *)high;

	/* initialize the allocated memory */
	if (test_bit(AF_FIRST_INIT, &a->flags)) {
		esas2r_targ_db_initialize(a);

		/* prime parts of the inbound list */
		element =
			(struct esas2r_inbound_list_source_entry *)a->
			inbound_list_md.
			virt_addr;

		for (i = 0; i < a->list_size; i++) {
			element->address = 0;
			element->reserved = 0;
			element->length = cpu_to_le32(HWILSE_INTERFACE_F0
						      | (sizeof(union
								atto_vda_req)
							 /
							 sizeof(u32)));
			element++;
		}

		/* init the AE requests */
		for (rq = a->first_ae_req, i = 0; i < num_ae_requests; rq++,
		     i++) {
			INIT_LIST_HEAD(&rq->req_list);
			if (!alloc_vda_req(a, rq)) {
				esas2r_hdebug(
					"failed to allocate a VDA request!");
				return false;
			}

			esas2r_rq_init_request(rq, a);

			/* override the completion function */
			rq->comp_cb = esas2r_ae_complete;
		}
	}

	return true;
}

/* This code will verify that the chip is operational. */
bool esas2r_check_adapter(struct esas2r_adapter *a)
{
	u32 starttime;
	u32 doorbell;
	u64 ppaddr;
	u32 dw;

	/*
	 * if the chip reset detected flag is set, we can bypass a bunch of
	 * stuff.
	 */
	if (test_bit(AF_CHPRST_DETECTED, &a->flags))
		goto skip_chip_reset;

	/*
	 * BEFORE WE DO ANYTHING, disable the chip interrupts!  the boot driver
	 * may have left them enabled or we may be recovering from a fault.
	 */
	esas2r_write_register_dword(a, MU_INT_MASK_OUT, ESAS2R_INT_DIS_MASK);
	esas2r_flush_register_dword(a, MU_INT_MASK_OUT);

	/*
	 * wait for the firmware to become ready by forcing an interrupt and
	 * waiting for a response.
	 */
	starttime = jiffies_to_msecs(jiffies);

	while (true) {
		esas2r_force_interrupt(a);
		doorbell = esas2r_read_register_dword(a, MU_DOORBELL_OUT);
		if (doorbell == 0xFFFFFFFF) {
			/*
			 * Give the firmware up to two seconds to enable
			 * register access after a reset.
			 */
			if ((jiffies_to_msecs(jiffies) - starttime) > 2000)
				return esas2r_set_degraded_mode(a,
								"unable to access registers");
		} else if (doorbell & DRBL_FORCE_INT) {
			u32 ver = (doorbell & DRBL_FW_VER_MSK);

			/*
			 * This driver supports version 0 and version 1 of
			 * the API
			 */
			esas2r_write_register_dword(a, MU_DOORBELL_OUT,
						    doorbell);

			if (ver == DRBL_FW_VER_0) {
				set_bit(AF_LEGACY_SGE_MODE, &a->flags);

				a->max_vdareq_size = 128;
				a->build_sgl = esas2r_build_sg_list_sge;
			} else if (ver == DRBL_FW_VER_1) {
				clear_bit(AF_LEGACY_SGE_MODE, &a->flags);

				a->max_vdareq_size = 1024;
				a->build_sgl = esas2r_build_sg_list_prd;
			} else {
				return esas2r_set_degraded_mode(a,
								"unknown firmware version");
			}
			break;
		}

		schedule_timeout_interruptible(msecs_to_jiffies(100));

		if ((jiffies_to_msecs(jiffies) - starttime) > 180000) {
			esas2r_hdebug("FW ready TMO");
			esas2r_bugon();

			return esas2r_set_degraded_mode(a,
							"firmware start has timed out");
		}
	}

	/* purge any asynchronous events since we will repost them later */
	esas2r_write_register_dword(a, MU_DOORBELL_IN, DRBL_MSG_IFC_DOWN);
	starttime = jiffies_to_msecs(jiffies);

	while (true) {
		doorbell = esas2r_read_register_dword(a, MU_DOORBELL_OUT);
		if (doorbell & DRBL_MSG_IFC_DOWN) {
			esas2r_write_register_dword(a, MU_DOORBELL_OUT,
						    doorbell);
			break;
		}

		schedule_timeout_interruptible(msecs_to_jiffies(50));

		if ((jiffies_to_msecs(jiffies) - starttime) > 3000) {
			esas2r_hdebug("timeout waiting for interface down");
			break;
		}
	}
skip_chip_reset:
	/*
	 * first things first, before we go changing any of these registers
	 * disable the communication lists.
	 */
	dw = esas2r_read_register_dword(a, MU_IN_LIST_CONFIG);
	dw &= ~MU_ILC_ENABLE;
	esas2r_write_register_dword(a, MU_IN_LIST_CONFIG, dw);
	dw = esas2r_read_register_dword(a, MU_OUT_LIST_CONFIG);
	dw &= ~MU_OLC_ENABLE;
	esas2r_write_register_dword(a, MU_OUT_LIST_CONFIG, dw);

	/* configure the communication list addresses */
	ppaddr = a->inbound_list_md.phys_addr;
	esas2r_write_register_dword(a, MU_IN_LIST_ADDR_LO,
				    lower_32_bits(ppaddr));
	esas2r_write_register_dword(a, MU_IN_LIST_ADDR_HI,
				    upper_32_bits(ppaddr));
	ppaddr = a->outbound_list_md.phys_addr;
	esas2r_write_register_dword(a, MU_OUT_LIST_ADDR_LO,
				    lower_32_bits(ppaddr));
	esas2r_write_register_dword(a, MU_OUT_LIST_ADDR_HI,
				    upper_32_bits(ppaddr));
	ppaddr = a->uncached_phys +
		 ((u8 *)a->outbound_copy - a->uncached);
	esas2r_write_register_dword(a, MU_OUT_LIST_COPY_PTR_LO,
				    lower_32_bits(ppaddr));
	esas2r_write_register_dword(a, MU_OUT_LIST_COPY_PTR_HI,
				    upper_32_bits(ppaddr));

	/* reset the read and write pointers */
	*a->outbound_copy =
		a->last_write =
			a->last_read = a->list_size - 1;
	set_bit(AF_COMM_LIST_TOGGLE, &a->flags);
	esas2r_write_register_dword(a, MU_IN_LIST_WRITE, MU_ILW_TOGGLE |
				    a->last_write);
	esas2r_write_register_dword(a, MU_OUT_LIST_COPY, MU_OLC_TOGGLE |
				    a->last_write);
	esas2r_write_register_dword(a, MU_IN_LIST_READ, MU_ILR_TOGGLE |
				    a->last_write);
	esas2r_write_register_dword(a, MU_OUT_LIST_WRITE,
				    MU_OLW_TOGGLE | a->last_write);

	/* configure the interface select fields */
	dw = esas2r_read_register_dword(a, MU_IN_LIST_IFC_CONFIG);
	dw &= ~(MU_ILIC_LIST | MU_ILIC_DEST);
	esas2r_write_register_dword(a, MU_IN_LIST_IFC_CONFIG,
				    (dw | MU_ILIC_LIST_F0 | MU_ILIC_DEST_DDR));
	dw = esas2r_read_register_dword(a, MU_OUT_LIST_IFC_CONFIG);
	dw &= ~(MU_OLIC_LIST | MU_OLIC_SOURCE);
	esas2r_write_register_dword(a, MU_OUT_LIST_IFC_CONFIG,
				    (dw | MU_OLIC_LIST_F0 |
				     MU_OLIC_SOURCE_DDR));

	/* finish configuring the communication lists */
	dw = esas2r_read_register_dword(a, MU_IN_LIST_CONFIG);
	dw &= ~(MU_ILC_ENTRY_MASK | MU_ILC_NUMBER_MASK);
	dw |= MU_ILC_ENTRY_4_DW | MU_ILC_DYNAMIC_SRC
	      | (a->list_size << MU_ILC_NUMBER_SHIFT);
	esas2r_write_register_dword(a, MU_IN_LIST_CONFIG, dw);
	dw = esas2r_read_register_dword(a, MU_OUT_LIST_CONFIG);
	dw &= ~(MU_OLC_ENTRY_MASK | MU_OLC_NUMBER_MASK);
	dw |= MU_OLC_ENTRY_4_DW | (a->list_size << MU_OLC_NUMBER_SHIFT);
	esas2r_write_register_dword(a, MU_OUT_LIST_CONFIG, dw);

	/*
	 * notify the firmware that we're done setting up the communication
	 * list registers.  wait here until the firmware is done configuring
	 * its lists.  it will signal that it is done by enabling the lists.
	 */
	esas2r_write_register_dword(a, MU_DOORBELL_IN, DRBL_MSG_IFC_INIT);
	starttime = jiffies_to_msecs(jiffies);

	while (true) {
		doorbell = esas2r_read_register_dword(a, MU_DOORBELL_OUT);
		if (doorbell & DRBL_MSG_IFC_INIT) {
			esas2r_write_register_dword(a, MU_DOORBELL_OUT,
						    doorbell);
			break;
		}

		schedule_timeout_interruptible(msecs_to_jiffies(100));

		if ((jiffies_to_msecs(jiffies) - starttime) > 3000) {
			esas2r_hdebug(
				"timeout waiting for communication list init");
			esas2r_bugon();
			return esas2r_set_degraded_mode(a,
							"timeout waiting for communication list init");
		}
	}

	/*
	 * flag whether the firmware supports the power down doorbell.  we
	 * determine this by reading the inbound doorbell enable mask.
	 */
	doorbell = esas2r_read_register_dword(a, MU_DOORBELL_IN_ENB);
	if (doorbell & DRBL_POWER_DOWN)
		set_bit(AF2_VDA_POWER_DOWN, &a->flags2);
	else
		clear_bit(AF2_VDA_POWER_DOWN, &a->flags2);

	/*
	 * enable assertion of outbound queue and doorbell interrupts in the
	 * main interrupt cause register.
	 */
	esas2r_write_register_dword(a, MU_OUT_LIST_INT_MASK, MU_OLIS_MASK);
	esas2r_write_register_dword(a, MU_DOORBELL_OUT_ENB, DRBL_ENB_MASK);
	return true;
}

/* Process the initialization message just completed and format the next one. */
static bool esas2r_format_init_msg(struct esas2r_adapter *a,
				   struct esas2r_request *rq)
{
	u32 msg = a->init_msg;
	struct atto_vda_cfg_init *ci;

	a->init_msg = 0;

	switch (msg) {
	case ESAS2R_INIT_MSG_START:
	case ESAS2R_INIT_MSG_REINIT:
	{
		esas2r_hdebug("CFG init");
		esas2r_build_cfg_req(a,
				     rq,
				     VDA_CFG_INIT,
				     0,
				     NULL);
		ci = (struct atto_vda_cfg_init *)&rq->vrq->cfg.data.init;
		ci->sgl_page_size = cpu_to_le32(sgl_page_size);
		/* firmware interface overflows in y2106 */
		ci->epoch_time = cpu_to_le32(ktime_get_real_seconds());
		rq->flags |= RF_FAILURE_OK;
		a->init_msg = ESAS2R_INIT_MSG_INIT;
		break;
	}

	case ESAS2R_INIT_MSG_INIT:
		if (rq->req_stat == RS_SUCCESS) {
			u32 major;
			u32 minor;
			u16 fw_release;

			a->fw_version = le16_to_cpu(
				rq->func_rsp.cfg_rsp.vda_version);
			a->fw_build = rq->func_rsp.cfg_rsp.fw_build;
			fw_release = le16_to_cpu(
				rq->func_rsp.cfg_rsp.fw_release);
			major = LOBYTE(fw_release);
			minor = HIBYTE(fw_release);
			a->fw_version += (major << 16) + (minor << 24);
		} else {
			esas2r_hdebug("FAILED");
		}

		/*
		 * the 2.71 and earlier releases of R6xx firmware did not error
		 * unsupported config requests correctly.
		 */

		if ((test_bit(AF2_THUNDERBOLT, &a->flags2))
		    || (be32_to_cpu(a->fw_version) > 0x00524702)) {
			esas2r_hdebug("CFG get init");
			esas2r_build_cfg_req(a,
					     rq,
					     VDA_CFG_GET_INIT2,
					     sizeof(struct atto_vda_cfg_init),
					     NULL);

			rq->vrq->cfg.sg_list_offset = offsetof(
				struct atto_vda_cfg_req,
				data.sge);
			rq->vrq->cfg.data.prde.ctl_len =
				cpu_to_le32(sizeof(struct atto_vda_cfg_init));
			rq->vrq->cfg.data.prde.address = cpu_to_le64(
				rq->vrq_md->phys_addr +
				sizeof(union atto_vda_req));
			rq->flags |= RF_FAILURE_OK;
			a->init_msg = ESAS2R_INIT_MSG_GET_INIT;
			break;
		}
		fallthrough;

	case ESAS2R_INIT_MSG_GET_INIT:
		if (msg == ESAS2R_INIT_MSG_GET_INIT) {
			ci = (struct atto_vda_cfg_init *)rq->data_buf;
			if (rq->req_stat == RS_SUCCESS) {
				a->num_targets_backend =
					le32_to_cpu(ci->num_targets_backend);
				a->ioctl_tunnel =
					le32_to_cpu(ci->ioctl_tunnel);
			} else {
				esas2r_hdebug("FAILED");
			}
		}
		fallthrough;

	default:
		rq->req_stat = RS_SUCCESS;
		return false;
	}
	return true;
}

/*
 * Perform initialization messages via the request queue.  Messages are
 * performed with interrupts disabled.
 */
bool esas2r_init_msgs(struct esas2r_adapter *a)
{
	bool success = true;
	struct esas2r_request *rq = &a->general_req;

	esas2r_rq_init_request(rq, a);
	rq->comp_cb = esas2r_dummy_complete;

	if (a->init_msg == 0)
		a->init_msg = ESAS2R_INIT_MSG_REINIT;

	while (a->init_msg) {
		if (esas2r_format_init_msg(a, rq)) {
			unsigned long flags;
			while (true) {
				spin_lock_irqsave(&a->queue_lock, flags);
				esas2r_start_vda_request(a, rq);
				spin_unlock_irqrestore(&a->queue_lock, flags);
				esas2r_wait_request(a, rq);
				if (rq->req_stat != RS_PENDING)
					break;
			}
		}

		if (rq->req_stat == RS_SUCCESS
		    || ((rq->flags & RF_FAILURE_OK)
			&& rq->req_stat != RS_TIMEOUT))
			continue;

		esas2r_log(ESAS2R_LOG_CRIT, "init message %x failed (%x, %x)",
			   a->init_msg, rq->req_stat, rq->flags);
		a->init_msg = ESAS2R_INIT_MSG_START;
		success = false;
		break;
	}

	esas2r_rq_destroy_request(rq, a);
	return success;
}

/* Initialize the adapter chip */
bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll)
{
	bool rslt = false;
	struct esas2r_request *rq;
	u32 i;

	if (test_bit(AF_DEGRADED_MODE, &a->flags))
		goto exit;

	if (!test_bit(AF_NVR_VALID, &a->flags)) {
		if (!esas2r_nvram_read_direct(a))
			esas2r_log(ESAS2R_LOG_WARN,
				   "invalid/missing NVRAM parameters");
	}

	if (!esas2r_init_msgs(a)) {
		esas2r_set_degraded_mode(a, "init messages failed");
		goto exit;
	}

	/* The firmware is ready. */
	clear_bit(AF_DEGRADED_MODE, &a->flags);
	clear_bit(AF_CHPRST_PENDING, &a->flags);

	/* Post all the async event requests */
	for (i = 0, rq = a->first_ae_req; i < num_ae_requests; i++, rq++)
		esas2r_start_ae_request(a, rq);

	if (!a->flash_rev[0])
		esas2r_read_flash_rev(a);

	if (!a->image_type[0])
		esas2r_read_image_type(a);

	if (a->fw_version == 0)
		a->fw_rev[0] = 0;
	else
		sprintf(a->fw_rev, "%1d.%02d",
			(int)LOBYTE(HIWORD(a->fw_version)),
			(int)HIBYTE(HIWORD(a->fw_version)));

	esas2r_hdebug("firmware revision: %s", a->fw_rev);

	if (test_bit(AF_CHPRST_DETECTED, &a->flags)
	    && (test_bit(AF_FIRST_INIT, &a->flags))) {
		esas2r_enable_chip_interrupts(a);
		return true;
	}

	/* initialize discovery */
	esas2r_disc_initialize(a);

	/*
	 * wait for the device wait time to expire here if requested.  this is
	 * usually requested during initial driver load and possibly when
	 * resuming from a low power state.  deferred device waiting will use
	 * interrupts.  chip reset recovery always defers device waiting to
	 * avoid being in a TASKLET too long.
	 */
	if (init_poll) {
		u32 currtime = a->disc_start_time;
		u32 nexttick = 100;
		u32 deltatime;

		/*
		 * Block Tasklets from getting scheduled and indicate this is
		 * polled discovery.
		 */
		set_bit(AF_TASKLET_SCHEDULED, &a->flags);
		set_bit(AF_DISC_POLLED, &a->flags);

		/*
		 * Temporarily bring the disable count to zero to enable
		 * deferred processing.  Note that the count is already zero
		 * after the first initialization.
		 */
		if (test_bit(AF_FIRST_INIT, &a->flags))
			atomic_dec(&a->disable_cnt);

		while (test_bit(AF_DISC_PENDING, &a->flags)) {
			schedule_timeout_interruptible(msecs_to_jiffies(100));

			/*
			 * Determine the need for a timer tick based on the
			 * delta time between this and the last iteration of
			 * this loop.  We don't use the absolute time because
			 * then we would have to worry about when nexttick
			 * wraps and currtime hasn't yet.
			 */
			deltatime = jiffies_to_msecs(jiffies) - currtime;
			currtime += deltatime;

			/*
			 * Process any waiting discovery as long as the chip is
			 * up.  If a chip reset happens during initial polling,
			 * we have to make sure the timer tick processes the
			 * doorbell indicating the firmware is ready.
			 */
			if (!test_bit(AF_CHPRST_PENDING, &a->flags))
				esas2r_disc_check_for_work(a);

			/* Simulate a timer tick. */
			if (nexttick <= deltatime) {

				/* Time for a timer tick */
				nexttick += 100;
				esas2r_timer_tick(a);
			}

			if (nexttick > deltatime)
				nexttick -= deltatime;

			/* Do any deferred processing */
			if (esas2r_is_tasklet_pending(a))
				esas2r_do_tasklet_tasks(a);

		}

		if (test_bit(AF_FIRST_INIT, &a->flags))
			atomic_inc(&a->disable_cnt);

		clear_bit(AF_DISC_POLLED, &a->flags);
		clear_bit(AF_TASKLET_SCHEDULED, &a->flags);
	}


	esas2r_targ_db_report_changes(a);

	/*
	 * For cases where (a) the initialization messages processing may
	 * handle an interrupt for a port event and a discovery is waiting, but
	 * we are not waiting for devices, or (b) the device wait time has been
	 * exhausted but there is still discovery pending, start any leftover
	 * discovery in interrupt driven mode.
	 */
	esas2r_disc_start_waiting(a);

	/* Enable chip interrupts */
	a->int_mask = ESAS2R_INT_STS_MASK;
	esas2r_enable_chip_interrupts(a);
	esas2r_enable_heartbeat(a);
	rslt = true;

exit:
	/*
	 * Regardless of whether initialization was successful, certain things
	 * need to get done before we exit.
	 */

	if (test_bit(AF_CHPRST_DETECTED, &a->flags) &&
	    test_bit(AF_FIRST_INIT, &a->flags)) {
		/*
		 * Reinitialization was performed during the first
		 * initialization.  Only clear the chip reset flag so the
		 * original device polling is not cancelled.
		 */
		if (!rslt)
			clear_bit(AF_CHPRST_PENDING, &a->flags);
	} else {
		/* First initialization or a subsequent re-init is complete. */
		if (!rslt) {
			clear_bit(AF_CHPRST_PENDING, &a->flags);
			clear_bit(AF_DISC_PENDING, &a->flags);
		}


		/* Enable deferred processing after the first initialization. */
		if (test_bit(AF_FIRST_INIT, &a->flags)) {
			clear_bit(AF_FIRST_INIT, &a->flags);

			if (atomic_dec_return(&a->disable_cnt) == 0)
				esas2r_do_deferred_processes(a);
		}
	}

	return rslt;
}

void esas2r_reset_adapter(struct esas2r_adapter *a)
{
	set_bit(AF_OS_RESET, &a->flags);
	esas2r_local_reset_adapter(a);
	esas2r_schedule_tasklet(a);
}

void esas2r_reset_chip(struct esas2r_adapter *a)
{
	if (!esas2r_is_adapter_present(a))
		return;

	/*
	 * Before we reset the chip, save off the VDA core dump.  The VDA core
	 * dump is located in the upper 512KB of the onchip SRAM.  Make sure
	 * to not overwrite a previous crash that was saved.
	 */
	if (test_bit(AF2_COREDUMP_AVAIL, &a->flags2) &&
	    !test_bit(AF2_COREDUMP_SAVED, &a->flags2)) {
		esas2r_read_mem_block(a,
				      a->fw_coredump_buff,
				      MW_DATA_ADDR_SRAM + 0x80000,
				      ESAS2R_FWCOREDUMP_SZ);

		set_bit(AF2_COREDUMP_SAVED, &a->flags2);
	}

	clear_bit(AF2_COREDUMP_AVAIL, &a->flags2);

	/* Reset the chip */
	if (a->pcid->revision == MVR_FREY_B2)
		esas2r_write_register_dword(a, MU_CTL_STATUS_IN_B2,
					    MU_CTL_IN_FULL_RST2);
	else
		esas2r_write_register_dword(a, MU_CTL_STATUS_IN,
					    MU_CTL_IN_FULL_RST);


	/* Stall a little while to let the reset condition clear */
	mdelay(10);
}

static void esas2r_power_down_notify_firmware(struct esas2r_adapter *a)
{
	u32 starttime;
	u32 doorbell;

	esas2r_write_register_dword(a, MU_DOORBELL_IN, DRBL_POWER_DOWN);
	starttime = jiffies_to_msecs(jiffies);

	while (true) {
		doorbell = esas2r_read_register_dword(a, MU_DOORBELL_OUT);
		if (doorbell & DRBL_POWER_DOWN) {
			esas2r_write_register_dword(a, MU_DOORBELL_OUT,
						    doorbell);
			break;
		}

		schedule_timeout_interruptible(msecs_to_jiffies(100));

		if ((jiffies_to_msecs(jiffies) - starttime) > 30000) {
			esas2r_hdebug("Timeout waiting for power down");
			break;
		}
	}
}

/*
 * Perform power management processing including managing device states, adapter
 * states, interrupts, and I/O.
 */
void esas2r_power_down(struct esas2r_adapter *a)
{
	set_bit(AF_POWER_MGT, &a->flags);
	set_bit(AF_POWER_DOWN, &a->flags);

	if (!test_bit(AF_DEGRADED_MODE, &a->flags)) {
		u32 starttime;
		u32 doorbell;

		/*
		 * We are currently running OK and will be reinitializing later.
		 * increment the disable count to coordinate with
		 * esas2r_init_adapter.  We don't have to do this in degraded
		 * mode since we never enabled interrupts in the first place.
		 */
		esas2r_disable_chip_interrupts(a);
		esas2r_disable_heartbeat(a);

		/* wait for any VDA activity to clear before continuing */
		esas2r_write_register_dword(a, MU_DOORBELL_IN,
					    DRBL_MSG_IFC_DOWN);
		starttime = jiffies_to_msecs(jiffies);

		while (true) {
			doorbell =
				esas2r_read_register_dword(a, MU_DOORBELL_OUT);
			if (doorbell & DRBL_MSG_IFC_DOWN) {
				esas2r_write_register_dword(a, MU_DOORBELL_OUT,
							    doorbell);
				break;
			}

			schedule_timeout_interruptible(msecs_to_jiffies(100));

			if ((jiffies_to_msecs(jiffies) - starttime) > 3000) {
				esas2r_hdebug(
					"timeout waiting for interface down");
				break;
			}
		}

		/*
		 * For versions of firmware that support it tell them the driver
		 * is powering down.
		 */
		if (test_bit(AF2_VDA_POWER_DOWN, &a->flags2))
			esas2r_power_down_notify_firmware(a);
	}

	/* Suspend I/O processing. */
	set_bit(AF_OS_RESET, &a->flags);
	set_bit(AF_DISC_PENDING, &a->flags);
	set_bit(AF_CHPRST_PENDING, &a->flags);

	esas2r_process_adapter_reset(a);

	/* Remove devices now that I/O is cleaned up. */
	a->prev_dev_cnt = esas2r_targ_db_get_tgt_cnt(a);
	esas2r_targ_db_remove_all(a, false);
}

/*
 * Perform power management processing including managing device states, adapter
 * states, interrupts, and I/O.
 */
bool esas2r_power_up(struct esas2r_adapter *a, bool init_poll)
{
	bool ret;

	clear_bit(AF_POWER_DOWN, &a->flags);
	esas2r_init_pci_cfg_space(a);
	set_bit(AF_FIRST_INIT, &a->flags);
	atomic_inc(&a->disable_cnt);

	/* reinitialize the adapter */
	ret = esas2r_check_adapter(a);
	if (!esas2r_init_adapter_hw(a, init_poll))
		ret = false;

	/* send the reset asynchronous event */
	esas2r_send_reset_ae(a, true);

	/* clear this flag after initialization. */
	clear_bit(AF_POWER_MGT, &a->flags);
	return ret;
}

bool esas2r_is_adapter_present(struct esas2r_adapter *a)
{
	if (test_bit(AF_NOT_PRESENT, &a->flags))
		return false;

	if (esas2r_read_register_dword(a, MU_DOORBELL_OUT) == 0xFFFFFFFF) {
		set_bit(AF_NOT_PRESENT, &a->flags);

		return false;
	}
	return true;
}

const char *esas2r_get_model_name(struct esas2r_adapter *a)
{
	switch (a->pcid->subsystem_device) {
	case ATTO_ESAS_R680:
		return "ATTO ExpressSAS R680";

	case ATTO_ESAS_R608:
		return "ATTO ExpressSAS R608";

	case ATTO_ESAS_R60F:
		return "ATTO ExpressSAS R60F";

	case ATTO_ESAS_R6F0:
		return "ATTO ExpressSAS R6F0";

	case ATTO_ESAS_R644:
		return "ATTO ExpressSAS R644";

	case ATTO_ESAS_R648:
		return "ATTO ExpressSAS R648";

	case ATTO_TSSC_3808:
		return "ATTO ThunderStream SC 3808D";

	case ATTO_TSSC_3808E:
		return "ATTO ThunderStream SC 3808E";

	case ATTO_TLSH_1068:
		return "ATTO ThunderLink SH 1068";
	}

	return "ATTO SAS Controller";
}

const char *esas2r_get_model_name_short(struct esas2r_adapter *a)
{
	switch (a->pcid->subsystem_device) {
	case ATTO_ESAS_R680:
		return "R680";

	case ATTO_ESAS_R608:
		return "R608";

	case ATTO_ESAS_R60F:
		return "R60F";

	case ATTO_ESAS_R6F0:
		return "R6F0";

	case ATTO_ESAS_R644:
		return "R644";

	case ATTO_ESAS_R648:
		return "R648";

	case ATTO_TSSC_3808:
		return "SC 3808D";

	case ATTO_TSSC_3808E:
		return "SC 3808E";

	case ATTO_TLSH_1068:
		return "SH 1068";
	}

	return "unknown";
}
