/*
 *  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;

	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) {
		const uint64_t required_mask = dma_get_required_mask
						       (&pcid->dev);
		if (required_mask > DMA_BIT_MASK(32)
		    && !pci_set_dma_mask(pcid, DMA_BIT_MASK(64))
		    && !pci_set_consistent_dma_mask(pcid,
						    DMA_BIT_MASK(64))) {
			esas2r_log_dev(ESAS2R_LOG_INFO,
				       &(a->pcid->dev),
				       "64-bit PCI addressing enabled\n");
		} else if (!pci_set_dma_mask(pcid, DMA_BIT_MASK(32))
			   && !pci_set_consistent_dma_mask(pcid,
							   DMA_BIT_MASK(32))) {
			esas2r_log_dev(ESAS2R_LOG_INFO,
				       &(a->pcid->dev),
				       "32-bit PCI addressing enabled\n");
		} else {
			esas2r_log(ESAS2R_LOG_CRIT,
				   "failed to set DMA mask");
			esas2r_kill_adapter(index);
			return 0;
		}
	} else {
		if (!pci_set_dma_mask(pcid, DMA_BIT_MASK(32))
		    && !pci_set_consistent_dma_mask(pcid,
						    DMA_BIT_MASK(32))) {
			esas2r_log_dev(ESAS2R_LOG_INFO,
				       &(a->pcid->dev),
				       "32-bit PCI addressing enabled\n");
		} else {
			esas2r_log(ESAS2R_LOG_CRIT,
				   "failed to set DMA mask");
			esas2r_kill_adapter(index);
			return 0;
		}
	}
	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);
		}
	}
}

int esas2r_cleanup(struct Scsi_Host *host)
{
	struct esas2r_adapter *a;
	int index;

	if (host == NULL) {
		int i;

		esas2r_debug("esas2r_cleanup everything");
		for (i = 0; i < MAX_ADAPTERS; i++)
			esas2r_kill_adapter(i);
		return -1;
	}

	esas2r_debug("esas2r_cleanup called for host %p", host);
	a = (struct esas2r_adapter *)host->hostdata;
	index = a->index;
	esas2r_kill_adapter(index);
	return index;
}

int esas2r_suspend(struct pci_dev *pdev, pm_message_t state)
{
	struct Scsi_Host *host = pci_get_drvdata(pdev);
	u32 device_state;
	struct esas2r_adapter *a = (struct esas2r_adapter *)host->hostdata;

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

	esas2r_adapter_power_down(a, 1);
	device_state = pci_choose_state(pdev, state);
	esas2r_log_dev(ESAS2R_LOG_INFO, &(pdev->dev),
		       "pci_save_state() called");
	pci_save_state(pdev);
	esas2r_log_dev(ESAS2R_LOG_INFO, &(pdev->dev),
		       "pci_disable_device() called");
	pci_disable_device(pdev);
	esas2r_log_dev(ESAS2R_LOG_INFO, &(pdev->dev),
		       "pci_set_power_state() called");
	pci_set_power_state(pdev, device_state);
	esas2r_log_dev(ESAS2R_LOG_INFO, &(pdev->dev), "esas2r_suspend(): 0");
	return 0;
}

int esas2r_resume(struct pci_dev *pdev)
{
	struct Scsi_Host *host = pci_get_drvdata(pdev);
	struct esas2r_adapter *a = (struct esas2r_adapter *)host->hostdata;
	int rez;

	esas2r_log_dev(ESAS2R_LOG_INFO, &(pdev->dev), "resuming adapter()");
	esas2r_log_dev(ESAS2R_LOG_INFO, &(pdev->dev),
		       "pci_set_power_state(PCI_D0) "
		       "called");
	pci_set_power_state(pdev, PCI_D0);
	esas2r_log_dev(ESAS2R_LOG_INFO, &(pdev->dev),
		       "pci_enable_wake(PCI_D0, 0) "
		       "called");
	pci_enable_wake(pdev, PCI_D0, 0);
	esas2r_log_dev(ESAS2R_LOG_INFO, &(pdev->dev),
		       "pci_restore_state() called");
	pci_restore_state(pdev);
	esas2r_log_dev(ESAS2R_LOG_INFO, &(pdev->dev),
		       "pci_enable_device() called");
	rez = pci_enable_device(pdev);
	pci_set_master(pdev);

	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, &(pdev->dev), "esas2r_resume(): %d",
		       rez);
	return rez;
}

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)
{
	int pcie_cap_reg;

	pcie_cap_reg = pci_find_capability(a->pcid, PCI_CAP_ID_EXP);
	if (pcie_cap_reg) {
		u16 devcontrol;

		pci_read_config_word(a->pcid, pcie_cap_reg + 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;
			pci_write_config_word(a->pcid,
					      pcie_cap_reg + 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 =
		kzalloc(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 = kzalloc(
		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 =
		kzalloc((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:
	{
		struct timeval now;
		do_gettimeofday(&now);
		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);
		ci->epoch_time = cpu_to_le32(now.tv_sec);
		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;
		}

	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");
			}
		}
	/* fall through */

	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";
}
