/*
 * Copyright (c) 2012 - 2015 UNISYS CORPORATION
 * All rights reserved.
 *
 * 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, GOOD TITLE or
 * NON INFRINGEMENT.  See the GNU General Public License for more
 * details.
 */

#include <linux/debugfs.h>
#include <linux/kthread.h>
#include <linux/idr.h>
#include <linux/seq_file.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>

#include "visorbus.h"
#include "iochannel.h"

/* The Send and Receive Buffers of the IO Queue may both be full */

#define IOS_ERROR_THRESHOLD  1000
#define MAX_PENDING_REQUESTS (MIN_NUMSIGNALS * 2)
#define VISORHBA_ERROR_COUNT 30

static struct dentry *visorhba_debugfs_dir;

/* GUIDS for HBA channel type supported by this driver */
static struct visor_channeltype_descriptor visorhba_channel_types[] = {
	/* Note that the only channel type we expect to be reported by the
	 * bus driver is the VISOR_VHBA channel.
	 */
	{ VISOR_VHBA_CHANNEL_GUID, "sparvhba" },
	{}
};

MODULE_DEVICE_TABLE(visorbus, visorhba_channel_types);
MODULE_ALIAS("visorbus:" VISOR_VHBA_CHANNEL_GUID_STR);

struct visordisk_info {
	struct scsi_device *sdev;
	u32 valid;
	atomic_t ios_threshold;
	atomic_t error_count;
	struct visordisk_info *next;
};

struct scsipending {
	struct uiscmdrsp cmdrsp;
	/* The Data being tracked */
	void *sent;
	/* Type of pointer that is being stored */
	char cmdtype;
};

/* Each scsi_host has a host_data area that contains this struct. */
struct visorhba_devdata {
	struct Scsi_Host *scsihost;
	struct visor_device *dev;
	struct list_head dev_info_list;
	/* Tracks the requests that have been forwarded to
	 * the IOVM and haven't returned yet
	 */
	struct scsipending pending[MAX_PENDING_REQUESTS];
	/* Start search for next pending free slot here */
	unsigned int nextinsert;
	/* lock to protect data in devdata */
	spinlock_t privlock;
	bool serverdown;
	bool serverchangingstate;
	unsigned long long acquire_failed_cnt;
	unsigned long long interrupts_rcvd;
	unsigned long long interrupts_notme;
	unsigned long long interrupts_disabled;
	u64 __iomem *flags_addr;
	atomic_t interrupt_rcvd;
	wait_queue_head_t rsp_queue;
	struct visordisk_info head;
	unsigned int max_buff_len;
	int devnum;
	struct task_struct *thread;
	int thread_wait_ms;

	/*
	 * allows us to pass int handles back-and-forth between us and
	 * iovm, instead of raw pointers
	 */
	struct idr idr;

	struct dentry *debugfs_dir;
	struct dentry *debugfs_info;
};

struct visorhba_devices_open {
	struct visorhba_devdata *devdata;
};

/*
 * visor_thread_start - Starts a thread for the device
 * @threadfn:   Function the thread starts
 * @thrcontext: Context to pass to the thread, i.e. devdata
 * @name:	String describing name of thread
 *
 * Starts a thread for the device.
 *
 * Return: The task_struct * denoting the thread on success,
 *	   or NULL on failure
 */
static struct task_struct *visor_thread_start(int (*threadfn)(void *),
					      void *thrcontext, char *name)
{
	struct task_struct *task;

	task = kthread_run(threadfn, thrcontext, "%s", name);
	if (IS_ERR(task)) {
		pr_err("visorbus failed to start thread\n");
		return NULL;
	}
	return task;
}

/*
 * visor_thread_stop - Stops the thread if it is running
 * @task: Description of process to stop
 */
static void visor_thread_stop(struct task_struct *task)
{
	kthread_stop(task);
}

/*
 * add_scsipending_entry - Save off io command that is pending in
 *			   Service Partition
 * @devdata: Pointer to devdata
 * @cmdtype: Specifies the type of command pending
 * @new:     The command to be saved
 *
 * Saves off the io command that is being handled by the Service
 * Partition so that it can be handled when it completes. If new is
 * NULL it is assumed the entry refers only to the cmdrsp.
 *
 * Return: Insert_location where entry was added on success,
 *	   -EBUSY if it can't
 */
static int add_scsipending_entry(struct visorhba_devdata *devdata,
				 char cmdtype, void *new)
{
	unsigned long flags;
	struct scsipending *entry;
	int insert_location;

	spin_lock_irqsave(&devdata->privlock, flags);
	insert_location = devdata->nextinsert;
	while (devdata->pending[insert_location].sent) {
		insert_location = (insert_location + 1) % MAX_PENDING_REQUESTS;
		if (insert_location == (int)devdata->nextinsert) {
			spin_unlock_irqrestore(&devdata->privlock, flags);
			return -EBUSY;
		}
	}

	entry = &devdata->pending[insert_location];
	memset(&entry->cmdrsp, 0, sizeof(entry->cmdrsp));
	entry->cmdtype = cmdtype;
	if (new)
		entry->sent = new;
	/* wants to send cmdrsp */
	else
		entry->sent = &entry->cmdrsp;
	devdata->nextinsert = (insert_location + 1) % MAX_PENDING_REQUESTS;
	spin_unlock_irqrestore(&devdata->privlock, flags);

	return insert_location;
}

/*
 * del_scsipending_ent - Removes an entry from the pending array
 * @devdata: Device holding the pending array
 * @del:     Entry to remove
 *
 * Removes the entry pointed at by del and returns it.
 *
 * Return: The scsipending entry pointed to on success, NULL on failure
 */
static void *del_scsipending_ent(struct visorhba_devdata *devdata, int del)
{
	unsigned long flags;
	void *sent;

	if (del >= MAX_PENDING_REQUESTS)
		return NULL;

	spin_lock_irqsave(&devdata->privlock, flags);
	sent = devdata->pending[del].sent;
	devdata->pending[del].cmdtype = 0;
	devdata->pending[del].sent = NULL;
	spin_unlock_irqrestore(&devdata->privlock, flags);

	return sent;
}

/*
 * get_scsipending_cmdrsp - Return the cmdrsp stored in a pending entry
 * @ddata: Device holding the pending array
 * @ent:   Entry that stores the cmdrsp
 *
 * Each scsipending entry has a cmdrsp in it. The cmdrsp is only valid
 * if the "sent" field is not NULL.
 *
 * Return: A pointer to the cmdrsp, NULL on failure
 */
static struct uiscmdrsp *get_scsipending_cmdrsp(struct visorhba_devdata *ddata,
						int ent)
{
	if (ddata->pending[ent].sent)
		return &ddata->pending[ent].cmdrsp;

	return NULL;
}

/*
 * simple_idr_get - Associate a provided pointer with an int value
 *		    1 <= value <= INT_MAX, and return this int value;
 *		    the pointer value can be obtained later by passing
 *		    this int value to idr_find()
 * @idrtable: The data object maintaining the pointer<-->int mappings
 * @p:	      The pointer value to be remembered
 * @lock:     A spinlock used when exclusive access to idrtable is needed
 *
 * Return: The id number mapped to pointer 'p', 0 on failure
 */
static unsigned int simple_idr_get(struct idr *idrtable, void *p,
				   spinlock_t *lock)
{
	int id;
	unsigned long flags;

	idr_preload(GFP_KERNEL);
	spin_lock_irqsave(lock, flags);
	id = idr_alloc(idrtable, p, 1, INT_MAX, GFP_NOWAIT);
	spin_unlock_irqrestore(lock, flags);
	idr_preload_end();
	/* failure */
	if (id < 0)
		return 0;
	/* idr_alloc() guarantees > 0 */
	return (unsigned int)(id);
}

/*
 * setup_scsitaskmgmt_handles - Stash the necessary handles so that the
 *				completion processing logic for a taskmgmt
 *				cmd will be able to find who to wake up
 *				and where to stash the result
 * @idrtable: The data object maintaining the pointer<-->int mappings
 * @lock:     A spinlock used when exclusive access to idrtable is needed
 * @cmdrsp:   Response from the IOVM
 * @event:    The event handle to associate with an id
 * @result:   The location to place the result of the event handle into
 */
static void setup_scsitaskmgmt_handles(struct idr *idrtable, spinlock_t *lock,
				       struct uiscmdrsp *cmdrsp,
				       wait_queue_head_t *event, int *result)
{
	/* specify the event that has to be triggered when this */
	/* cmd is complete */
	cmdrsp->scsitaskmgmt.notify_handle =
		simple_idr_get(idrtable, event, lock);
	cmdrsp->scsitaskmgmt.notifyresult_handle =
		simple_idr_get(idrtable, result, lock);
}

/*
 * cleanup_scsitaskmgmt_handles - Forget handles created by
 *				  setup_scsitaskmgmt_handles()
 * @idrtable: The data object maintaining the pointer<-->int mappings
 * @cmdrsp:   Response from the IOVM
 */
static void cleanup_scsitaskmgmt_handles(struct idr *idrtable,
					 struct uiscmdrsp *cmdrsp)
{
	if (cmdrsp->scsitaskmgmt.notify_handle)
		idr_remove(idrtable, cmdrsp->scsitaskmgmt.notify_handle);
	if (cmdrsp->scsitaskmgmt.notifyresult_handle)
		idr_remove(idrtable, cmdrsp->scsitaskmgmt.notifyresult_handle);
}

/*
 * forward_taskmgmt_command - Send taskmegmt command to the Service
 *			      Partition
 * @tasktype: Type of taskmgmt command
 * @scsidev:  Scsidev that issued command
 *
 * Create a cmdrsp packet and send it to the Serivce Partition
 * that will service this request.
 *
 * Return: Int representing whether command was queued successfully or not
 */
static int forward_taskmgmt_command(enum task_mgmt_types tasktype,
				    struct scsi_device *scsidev)
{
	struct uiscmdrsp *cmdrsp;
	struct visorhba_devdata *devdata =
		(struct visorhba_devdata *)scsidev->host->hostdata;
	int notifyresult = 0xffff;
	wait_queue_head_t notifyevent;
	int scsicmd_id = 0;

	if (devdata->serverdown || devdata->serverchangingstate)
		return FAILED;

	scsicmd_id = add_scsipending_entry(devdata, CMD_SCSITASKMGMT_TYPE,
					   NULL);
	if (scsicmd_id < 0)
		return FAILED;

	cmdrsp = get_scsipending_cmdrsp(devdata, scsicmd_id);

	init_waitqueue_head(&notifyevent);

	/* issue TASK_MGMT_ABORT_TASK */
	cmdrsp->cmdtype = CMD_SCSITASKMGMT_TYPE;
	setup_scsitaskmgmt_handles(&devdata->idr, &devdata->privlock, cmdrsp,
				   &notifyevent, &notifyresult);

	/* save destination */
	cmdrsp->scsitaskmgmt.tasktype = tasktype;
	cmdrsp->scsitaskmgmt.vdest.channel = scsidev->channel;
	cmdrsp->scsitaskmgmt.vdest.id = scsidev->id;
	cmdrsp->scsitaskmgmt.vdest.lun = scsidev->lun;
	cmdrsp->scsitaskmgmt.handle = scsicmd_id;

	dev_dbg(&scsidev->sdev_gendev,
		"visorhba: initiating type=%d taskmgmt command\n", tasktype);
	if (visorchannel_signalinsert(devdata->dev->visorchannel,
				      IOCHAN_TO_IOPART,
				      cmdrsp))
		goto err_del_scsipending_ent;

	/* It can take the Service Partition up to 35 seconds to complete
	 * an IO in some cases, so wait 45 seconds and error out
	 */
	if (!wait_event_timeout(notifyevent, notifyresult != 0xffff,
				msecs_to_jiffies(45000)))
		goto err_del_scsipending_ent;

	dev_dbg(&scsidev->sdev_gendev,
		"visorhba: taskmgmt type=%d success; result=0x%x\n",
		 tasktype, notifyresult);
	cleanup_scsitaskmgmt_handles(&devdata->idr, cmdrsp);
	return SUCCESS;

err_del_scsipending_ent:
	dev_dbg(&scsidev->sdev_gendev,
		"visorhba: taskmgmt type=%d not executed\n", tasktype);
	del_scsipending_ent(devdata, scsicmd_id);
	cleanup_scsitaskmgmt_handles(&devdata->idr, cmdrsp);
	return FAILED;
}

/*
 * visorhba_abort_handler - Send TASK_MGMT_ABORT_TASK
 * @scsicmd: The scsicmd that needs aborted
 *
 * Return: SUCCESS if inserted, FAILED otherwise
 */
static int visorhba_abort_handler(struct scsi_cmnd *scsicmd)
{
	/* issue TASK_MGMT_ABORT_TASK */
	struct scsi_device *scsidev;
	struct visordisk_info *vdisk;
	int rtn;

	scsidev = scsicmd->device;
	vdisk = scsidev->hostdata;
	if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT)
		atomic_inc(&vdisk->error_count);
	else
		atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
	rtn = forward_taskmgmt_command(TASK_MGMT_ABORT_TASK, scsidev);
	if (rtn == SUCCESS) {
		scsicmd->result = DID_ABORT << 16;
		scsicmd->scsi_done(scsicmd);
	}
	return rtn;
}

/*
 * visorhba_device_reset_handler - Send TASK_MGMT_LUN_RESET
 * @scsicmd: The scsicmd that needs aborted
 *
 * Return: SUCCESS if inserted, FAILED otherwise
 */
static int visorhba_device_reset_handler(struct scsi_cmnd *scsicmd)
{
	/* issue TASK_MGMT_LUN_RESET */
	struct scsi_device *scsidev;
	struct visordisk_info *vdisk;
	int rtn;

	scsidev = scsicmd->device;
	vdisk = scsidev->hostdata;
	if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT)
		atomic_inc(&vdisk->error_count);
	else
		atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
	rtn = forward_taskmgmt_command(TASK_MGMT_LUN_RESET, scsidev);
	if (rtn == SUCCESS) {
		scsicmd->result = DID_RESET << 16;
		scsicmd->scsi_done(scsicmd);
	}
	return rtn;
}

/*
 * visorhba_bus_reset_handler - Send TASK_MGMT_TARGET_RESET for each
 *				target on the bus
 * @scsicmd: The scsicmd that needs aborted
 *
 * Return: SUCCESS if inserted, FAILED otherwise
 */
static int visorhba_bus_reset_handler(struct scsi_cmnd *scsicmd)
{
	struct scsi_device *scsidev;
	struct visordisk_info *vdisk;
	int rtn;

	scsidev = scsicmd->device;
	shost_for_each_device(scsidev, scsidev->host) {
		vdisk = scsidev->hostdata;
		if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT)
			atomic_inc(&vdisk->error_count);
		else
			atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
	}
	rtn = forward_taskmgmt_command(TASK_MGMT_BUS_RESET, scsidev);
	if (rtn == SUCCESS) {
		scsicmd->result = DID_RESET << 16;
		scsicmd->scsi_done(scsicmd);
	}
	return rtn;
}

/*
 * visorhba_host_reset_handler - Not supported
 * @scsicmd: The scsicmd that needs to be aborted
 *
 * Return: Not supported, return SUCCESS
 */
static int visorhba_host_reset_handler(struct scsi_cmnd *scsicmd)
{
	/* issue TASK_MGMT_TARGET_RESET for each target on each bus for host */
	return SUCCESS;
}

/*
 * visorhba_get_info - Get information about SCSI device
 * @shp: Scsi host that is requesting information
 *
 * Return: String with visorhba information
 */
static const char *visorhba_get_info(struct Scsi_Host *shp)
{
	/* Return version string */
	return "visorhba";
}

/*
 * dma_data_dir_linux_to_spar - convert dma_data_direction value to
 *				Unisys-specific equivalent
 * @d: dma direction value to convert
 *
 * Returns the Unisys-specific dma direction value corresponding to @d
 */
static u32 dma_data_dir_linux_to_spar(enum dma_data_direction d)
{
	switch (d) {
	case DMA_BIDIRECTIONAL:
		return UIS_DMA_BIDIRECTIONAL;
	case DMA_TO_DEVICE:
		return UIS_DMA_TO_DEVICE;
	case DMA_FROM_DEVICE:
		return UIS_DMA_FROM_DEVICE;
	case DMA_NONE:
		return UIS_DMA_NONE;
	default:
		return UIS_DMA_NONE;
	}
}

/*
 * visorhba_queue_command_lck - Queues command to the Service Partition
 * @scsicmd:		Command to be queued
 * @vsiorhba_cmnd_done: Done command to call when scsicmd is returned
 *
 * Queues to scsicmd to the ServicePartition after converting it to a
 * uiscmdrsp structure.
 *
 * Return: 0 if successfully queued to the Service Partition, otherwise
 *	   error code
 */
static int visorhba_queue_command_lck(struct scsi_cmnd *scsicmd,
				      void (*visorhba_cmnd_done)
					   (struct scsi_cmnd *))
{
	struct uiscmdrsp *cmdrsp;
	struct scsi_device *scsidev = scsicmd->device;
	int insert_location;
	unsigned char *cdb = scsicmd->cmnd;
	struct Scsi_Host *scsihost = scsidev->host;
	unsigned int i;
	struct visorhba_devdata *devdata =
		(struct visorhba_devdata *)scsihost->hostdata;
	struct scatterlist *sg = NULL;
	struct scatterlist *sglist = NULL;

	if (devdata->serverdown || devdata->serverchangingstate)
		return SCSI_MLQUEUE_DEVICE_BUSY;

	insert_location = add_scsipending_entry(devdata, CMD_SCSI_TYPE,
						(void *)scsicmd);
	if (insert_location < 0)
		return SCSI_MLQUEUE_DEVICE_BUSY;

	cmdrsp = get_scsipending_cmdrsp(devdata, insert_location);
	cmdrsp->cmdtype = CMD_SCSI_TYPE;
	/* save the pending insertion location. Deletion from pending
	 * will return the scsicmd pointer for completion
	 */
	cmdrsp->scsi.handle = insert_location;

	/* save done function that we have call when cmd is complete */
	scsicmd->scsi_done = visorhba_cmnd_done;
	/* save destination */
	cmdrsp->scsi.vdest.channel = scsidev->channel;
	cmdrsp->scsi.vdest.id = scsidev->id;
	cmdrsp->scsi.vdest.lun = scsidev->lun;
	/* save datadir */
	cmdrsp->scsi.data_dir =
		dma_data_dir_linux_to_spar(scsicmd->sc_data_direction);
	memcpy(cmdrsp->scsi.cmnd, cdb, MAX_CMND_SIZE);
	cmdrsp->scsi.bufflen = scsi_bufflen(scsicmd);

	/* keep track of the max buffer length so far. */
	if (cmdrsp->scsi.bufflen > devdata->max_buff_len)
		devdata->max_buff_len = cmdrsp->scsi.bufflen;

	if (scsi_sg_count(scsicmd) > MAX_PHYS_INFO)
		goto err_del_scsipending_ent;

	/* convert buffer to phys information  */
	/* buffer is scatterlist - copy it out */
	sglist = scsi_sglist(scsicmd);

	for_each_sg(sglist, sg, scsi_sg_count(scsicmd), i) {
		cmdrsp->scsi.gpi_list[i].address = sg_phys(sg);
		cmdrsp->scsi.gpi_list[i].length = sg->length;
	}
	cmdrsp->scsi.guest_phys_entries = scsi_sg_count(scsicmd);

	if (visorchannel_signalinsert(devdata->dev->visorchannel,
				      IOCHAN_TO_IOPART,
				      cmdrsp))
		/* queue must be full and we aren't going to wait */
		goto err_del_scsipending_ent;

	return 0;

err_del_scsipending_ent:
	del_scsipending_ent(devdata, insert_location);
	return SCSI_MLQUEUE_DEVICE_BUSY;
}

#ifdef DEF_SCSI_QCMD
static DEF_SCSI_QCMD(visorhba_queue_command)
#else
#define visorhba_queue_command visorhba_queue_command_lck
#endif

/*
 * visorhba_slave_alloc - Called when new disk is discovered
 * @scsidev: New disk
 *
 * Create a new visordisk_info structure and add it to our
 * list of vdisks.
 *
 * Return: 0 on success, -ENOMEM on failure.
 */
static int visorhba_slave_alloc(struct scsi_device *scsidev)
{
	/* this is called by the midlayer before scan for new devices --
	 * LLD can alloc any struct & do init if needed.
	 */
	struct visordisk_info *vdisk;
	struct visorhba_devdata *devdata;
	struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;

	/* already allocated return success */
	if (scsidev->hostdata)
		return 0;

	/* even though we errored, treat as success */
	devdata = (struct visorhba_devdata *)scsihost->hostdata;
	if (!devdata)
		return 0;

	vdisk = kzalloc(sizeof(*vdisk), GFP_ATOMIC);
	if (!vdisk)
		return -ENOMEM;

	vdisk->sdev = scsidev;
	scsidev->hostdata = vdisk;
	return 0;
}

/*
 * visorhba_slave_destroy - Disk is going away, clean up resources.
 * @scsidev: Scsi device to destroy
 */
static void visorhba_slave_destroy(struct scsi_device *scsidev)
{
	/* midlevel calls this after device has been quiesced and
	 * before it is to be deleted.
	 */
	struct visordisk_info *vdisk;

	vdisk = scsidev->hostdata;
	scsidev->hostdata = NULL;
	kfree(vdisk);
}

static struct scsi_host_template visorhba_driver_template = {
	.name = "Unisys Visor HBA",
	.info = visorhba_get_info,
	.queuecommand = visorhba_queue_command,
	.eh_abort_handler = visorhba_abort_handler,
	.eh_device_reset_handler = visorhba_device_reset_handler,
	.eh_bus_reset_handler = visorhba_bus_reset_handler,
	.eh_host_reset_handler = visorhba_host_reset_handler,
	.shost_attrs = NULL,
#define visorhba_MAX_CMNDS 128
	.can_queue = visorhba_MAX_CMNDS,
	.sg_tablesize = 64,
	.this_id = -1,
	.slave_alloc = visorhba_slave_alloc,
	.slave_destroy = visorhba_slave_destroy,
	.use_clustering = ENABLE_CLUSTERING,
};

/*
 * info_debugfs_show - Debugfs interface to dump visorhba states
 * @seq: The sequence file to write information to
 * @v:   Unused, but needed for use with seq file single_open invocation
 *
 * Presents a file in the debugfs tree named: /visorhba/vbus<x>:dev<y>/info.
 *
 * Return: SUCCESS
 */
static int info_debugfs_show(struct seq_file *seq, void *v)
{
	struct visorhba_devdata *devdata = seq->private;

	seq_printf(seq, "max_buff_len = %u\n", devdata->max_buff_len);
	seq_printf(seq, "interrupts_rcvd = %llu\n", devdata->interrupts_rcvd);
	seq_printf(seq, "interrupts_disabled = %llu\n",
		   devdata->interrupts_disabled);
	seq_printf(seq, "interrupts_notme = %llu\n",
		   devdata->interrupts_notme);
	seq_printf(seq, "flags_addr = %p\n", devdata->flags_addr);
	if (devdata->flags_addr) {
		u64 phys_flags_addr =
			virt_to_phys((__force  void *)devdata->flags_addr);
		seq_printf(seq, "phys_flags_addr = 0x%016llx\n",
			   phys_flags_addr);
		seq_printf(seq, "FeatureFlags = %llu\n",
			   (u64)readq(devdata->flags_addr));
	}
	seq_printf(seq, "acquire_failed_cnt = %llu\n",
		   devdata->acquire_failed_cnt);

	return 0;
}

static int info_debugfs_open(struct inode *inode, struct file *file)
{
	return single_open(file, info_debugfs_show, inode->i_private);
}

static const struct file_operations info_debugfs_fops = {
	.owner = THIS_MODULE,
	.open = info_debugfs_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
};

/*
 * complete_taskmgmt_command - Complete task management
 * @idrtable: The data object maintaining the pointer<-->int mappings
 * @cmdrsp:   Response from the IOVM
 * @result:   The result of the task management command
 *
 * Service Partition returned the result of the task management
 * command. Wake up anyone waiting for it.
 */
static void complete_taskmgmt_command(struct idr *idrtable,
				      struct uiscmdrsp *cmdrsp, int result)
{
	wait_queue_head_t *wq =
		idr_find(idrtable, cmdrsp->scsitaskmgmt.notify_handle);
	int *scsi_result_ptr =
		idr_find(idrtable, cmdrsp->scsitaskmgmt.notifyresult_handle);
	if (unlikely(!(wq && scsi_result_ptr))) {
		pr_err("visorhba: no completion context; cmd will time out\n");
		return;
	}

	/* copy the result of the taskmgmt and
	 * wake up the error handler that is waiting for this
	 */
	pr_debug("visorhba: notifying initiator with result=0x%x\n", result);
	*scsi_result_ptr = result;
	wake_up_all(wq);
}

/*
 * visorhba_serverdown_complete - Called when we are done cleaning up
 *				  from serverdown
 * @devdata: Visorhba instance on which to complete serverdown
 *
 * Called when we are done cleanning up from serverdown, stop processing
 * queue, fail pending IOs.
 */
static void visorhba_serverdown_complete(struct visorhba_devdata *devdata)
{
	int i;
	struct scsipending *pendingdel = NULL;
	struct scsi_cmnd *scsicmd = NULL;
	struct uiscmdrsp *cmdrsp;
	unsigned long flags;

	/* Stop using the IOVM response queue (queue should be drained
	 * by the end)
	 */
	visor_thread_stop(devdata->thread);

	/* Fail commands that weren't completed */
	spin_lock_irqsave(&devdata->privlock, flags);
	for (i = 0; i < MAX_PENDING_REQUESTS; i++) {
		pendingdel = &devdata->pending[i];
		switch (pendingdel->cmdtype) {
		case CMD_SCSI_TYPE:
			scsicmd = pendingdel->sent;
			scsicmd->result = DID_RESET << 16;
			if (scsicmd->scsi_done)
				scsicmd->scsi_done(scsicmd);
			break;
		case CMD_SCSITASKMGMT_TYPE:
			cmdrsp = pendingdel->sent;
			complete_taskmgmt_command(&devdata->idr, cmdrsp,
						  TASK_MGMT_FAILED);
			break;
		default:
			break;
		}
		pendingdel->cmdtype = 0;
		pendingdel->sent = NULL;
	}
	spin_unlock_irqrestore(&devdata->privlock, flags);

	devdata->serverdown = true;
	devdata->serverchangingstate = false;
}

/*
 * visorhba_serverdown - Got notified that the IOVM is down
 * @devdata: Visorhba that is being serviced by downed IOVM
 *
 * Something happened to the IOVM, return immediately and
 * schedule cleanup work.
 *
 * Return: 0 on success, -EINVAL on failure
 */
static int visorhba_serverdown(struct visorhba_devdata *devdata)
{
	if (!devdata->serverdown && !devdata->serverchangingstate) {
		devdata->serverchangingstate = true;
		visorhba_serverdown_complete(devdata);
	} else if (devdata->serverchangingstate) {
		return -EINVAL;
	}
	return 0;
}

/*
 * do_scsi_linuxstat - Scsi command returned linuxstat
 * @cmdrsp:  Response from IOVM
 * @scsicmd: Command issued
 *
 * Don't log errors for disk-not-present inquiries.
 */
static void do_scsi_linuxstat(struct uiscmdrsp *cmdrsp,
			      struct scsi_cmnd *scsicmd)
{
	struct visordisk_info *vdisk;
	struct scsi_device *scsidev;

	scsidev = scsicmd->device;
	memcpy(scsicmd->sense_buffer, cmdrsp->scsi.sensebuf, MAX_SENSE_SIZE);

	/* Do not log errors for disk-not-present inquiries */
	if ((cmdrsp->scsi.cmnd[0] == INQUIRY) &&
	    (host_byte(cmdrsp->scsi.linuxstat) == DID_NO_CONNECT) &&
	    (cmdrsp->scsi.addlstat == ADDL_SEL_TIMEOUT))
		return;
	/* Okay see what our error_count is here.... */
	vdisk = scsidev->hostdata;
	if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) {
		atomic_inc(&vdisk->error_count);
		atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
	}
}

static int set_no_disk_inquiry_result(unsigned char *buf, size_t len,
				      bool is_lun0)
{
	if (len < NO_DISK_INQUIRY_RESULT_LEN)
		return -EINVAL;
	memset(buf, 0, NO_DISK_INQUIRY_RESULT_LEN);
	buf[2] = SCSI_SPC2_VER;
	if (is_lun0) {
		buf[0] = DEV_DISK_CAPABLE_NOT_PRESENT;
		buf[3] = DEV_HISUPPORT;
	} else {
		buf[0] = DEV_NOT_CAPABLE;
	}
	buf[4] = NO_DISK_INQUIRY_RESULT_LEN - 5;
	strncpy(buf + 8, "DELLPSEUDO DEVICE .", NO_DISK_INQUIRY_RESULT_LEN - 8);
	return 0;
}

/*
 * do_scsi_nolinuxstat - Scsi command didn't have linuxstat
 * @cmdrsp:  Response from IOVM
 * @scsicmd: Command issued
 *
 * Handle response when no linuxstat was returned.
 */
static void do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp,
				struct scsi_cmnd *scsicmd)
{
	struct scsi_device *scsidev;
	unsigned char *buf;
	struct scatterlist *sg;
	unsigned int i;
	char *this_page;
	char *this_page_orig;
	int bufind = 0;
	struct visordisk_info *vdisk;

	scsidev = scsicmd->device;
	if ((cmdrsp->scsi.cmnd[0] == INQUIRY) &&
	    (cmdrsp->scsi.bufflen >= MIN_INQUIRY_RESULT_LEN)) {
		if (cmdrsp->scsi.no_disk_result == 0)
			return;

		buf = kzalloc(sizeof(char) * 36, GFP_KERNEL);
		if (!buf)
			return;

		/* Linux scsi code wants a device at Lun 0
		 * to issue report luns, but we don't want
		 * a disk there so we'll present a processor
		 * there.
		 */
		set_no_disk_inquiry_result(buf, (size_t)cmdrsp->scsi.bufflen,
					   scsidev->lun == 0);

		if (scsi_sg_count(scsicmd) == 0) {
			memcpy(scsi_sglist(scsicmd), buf,
			       cmdrsp->scsi.bufflen);
			kfree(buf);
			return;
		}

		sg = scsi_sglist(scsicmd);
		for (i = 0; i < scsi_sg_count(scsicmd); i++) {
			this_page_orig = kmap_atomic(sg_page(sg + i));
			this_page = (void *)((unsigned long)this_page_orig |
					     sg[i].offset);
			memcpy(this_page, buf + bufind, sg[i].length);
			kunmap_atomic(this_page_orig);
		}
		kfree(buf);
	} else {
		vdisk = scsidev->hostdata;
		if (atomic_read(&vdisk->ios_threshold) > 0) {
			atomic_dec(&vdisk->ios_threshold);
			if (atomic_read(&vdisk->ios_threshold) == 0)
				atomic_set(&vdisk->error_count, 0);
		}
	}
}

/*
 * complete_scsi_command - Complete a scsi command
 * @uiscmdrsp: Response from Service Partition
 * @scsicmd:   The scsi command
 *
 * Response was returned by the Service Partition. Finish it and send
 * completion to the scsi midlayer.
 */
static void complete_scsi_command(struct uiscmdrsp *cmdrsp,
				  struct scsi_cmnd *scsicmd)
{
	/* take what we need out of cmdrsp and complete the scsicmd */
	scsicmd->result = cmdrsp->scsi.linuxstat;
	if (cmdrsp->scsi.linuxstat)
		do_scsi_linuxstat(cmdrsp, scsicmd);
	else
		do_scsi_nolinuxstat(cmdrsp, scsicmd);

	scsicmd->scsi_done(scsicmd);
}

/*
 * drain_queue - Pull responses out of iochannel
 * @cmdrsp:  Response from the IOSP
 * @devdata: Device that owns this iochannel
 *
 * Pulls responses out of the iochannel and process the responses.
 */
static void drain_queue(struct uiscmdrsp *cmdrsp,
			struct visorhba_devdata *devdata)
{
	struct scsi_cmnd *scsicmd;

	while (1) {
		/* queue empty */
		if (visorchannel_signalremove(devdata->dev->visorchannel,
					      IOCHAN_FROM_IOPART,
					      cmdrsp))
			break;
		if (cmdrsp->cmdtype == CMD_SCSI_TYPE) {
			/* scsicmd location is returned by the
			 * deletion
			 */
			scsicmd = del_scsipending_ent(devdata,
						      cmdrsp->scsi.handle);
			if (!scsicmd)
				break;
			/* complete the orig cmd */
			complete_scsi_command(cmdrsp, scsicmd);
		} else if (cmdrsp->cmdtype == CMD_SCSITASKMGMT_TYPE) {
			if (!del_scsipending_ent(devdata,
						 cmdrsp->scsitaskmgmt.handle))
				break;
			complete_taskmgmt_command(&devdata->idr, cmdrsp,
						  cmdrsp->scsitaskmgmt.result);
		} else if (cmdrsp->cmdtype == CMD_NOTIFYGUEST_TYPE)
			dev_err_once(&devdata->dev->device,
				     "ignoring unsupported NOTIFYGUEST\n");
		/* cmdrsp is now available for re-use */
	}
}

/*
 * process_incoming_rsps - Process responses from IOSP
 * @v:  Void pointer to visorhba_devdata
 *
 * Main function for the thread that processes the responses
 * from the IO Service Partition. When the queue is empty, wait
 * to check to see if it is full again.
 *
 * Return: 0 on success, -ENOMEM on failure
 */
static int process_incoming_rsps(void *v)
{
	struct visorhba_devdata *devdata = v;
	struct uiscmdrsp *cmdrsp = NULL;
	const int size = sizeof(*cmdrsp);

	cmdrsp = kmalloc(size, GFP_ATOMIC);
	if (!cmdrsp)
		return -ENOMEM;

	while (1) {
		if (kthread_should_stop())
			break;
		wait_event_interruptible_timeout(
			devdata->rsp_queue, (atomic_read(
					     &devdata->interrupt_rcvd) == 1),
				msecs_to_jiffies(devdata->thread_wait_ms));
		/* drain queue */
		drain_queue(cmdrsp, devdata);
	}
	kfree(cmdrsp);
	return 0;
}

/*
 * visorhba_pause - Function to handle visorbus pause messages
 * @dev:	   Device that is pausing
 * @complete_func: Function to call when finished
 *
 * Something has happened to the IO Service Partition that is
 * handling this device. Quiet this device and reset commands
 * so that the Service Partition can be corrected.
 *
 * Return: SUCCESS
 */
static int visorhba_pause(struct visor_device *dev,
			  visorbus_state_complete_func complete_func)
{
	struct visorhba_devdata *devdata = dev_get_drvdata(&dev->device);

	visorhba_serverdown(devdata);
	complete_func(dev, 0);
	return 0;
}

/*
 * visorhba_resume - Function called when the IO Service Partition is back
 * @dev:	   Device that is pausing
 * @complete_func: Function to call when finished
 *
 * Yay! The IO Service Partition is back, the channel has been wiped
 * so lets re-establish connection and start processing responses.
 *
 * Return: 0 on success, -EINVAL on failure
 */
static int visorhba_resume(struct visor_device *dev,
			   visorbus_state_complete_func complete_func)
{
	struct visorhba_devdata *devdata;

	devdata = dev_get_drvdata(&dev->device);
	if (!devdata)
		return -EINVAL;

	if (devdata->serverdown && !devdata->serverchangingstate)
		devdata->serverchangingstate = true;

	devdata->thread = visor_thread_start(process_incoming_rsps, devdata,
					     "vhba_incming");
	devdata->serverdown = false;
	devdata->serverchangingstate = false;

	return 0;
}

/*
 * visorhba_probe - Device has been discovered; do acquire
 * @dev: visor_device that was discovered
 *
 * A new HBA was discovered; do the initial connections of it.
 *
 * Return: 0 on success, otherwise error code
 */
static int visorhba_probe(struct visor_device *dev)
{
	struct Scsi_Host *scsihost;
	struct vhba_config_max max;
	struct visorhba_devdata *devdata = NULL;
	int err, channel_offset;
	u64 features;

	scsihost = scsi_host_alloc(&visorhba_driver_template,
				   sizeof(*devdata));
	if (!scsihost)
		return -ENODEV;

	channel_offset = offsetof(struct visor_io_channel, vhba.max);
	err = visorbus_read_channel(dev, channel_offset, &max,
				    sizeof(struct vhba_config_max));
	if (err < 0)
		goto err_scsi_host_put;

	scsihost->max_id = (unsigned int)max.max_id;
	scsihost->max_lun = (unsigned int)max.max_lun;
	scsihost->cmd_per_lun = (unsigned int)max.cmd_per_lun;
	scsihost->max_sectors =
	    (unsigned short)(max.max_io_size >> 9);
	scsihost->sg_tablesize =
	    (unsigned short)(max.max_io_size / PAGE_SIZE);
	if (scsihost->sg_tablesize > MAX_PHYS_INFO)
		scsihost->sg_tablesize = MAX_PHYS_INFO;
	err = scsi_add_host(scsihost, &dev->device);
	if (err < 0)
		goto err_scsi_host_put;

	devdata = (struct visorhba_devdata *)scsihost->hostdata;
	devdata->dev = dev;
	dev_set_drvdata(&dev->device, devdata);

	devdata->debugfs_dir = debugfs_create_dir(dev_name(&dev->device),
						  visorhba_debugfs_dir);
	if (!devdata->debugfs_dir) {
		err = -ENOMEM;
		goto err_scsi_remove_host;
	}
	devdata->debugfs_info =
		debugfs_create_file("info", 0440,
				    devdata->debugfs_dir, devdata,
				    &info_debugfs_fops);
	if (!devdata->debugfs_info) {
		err = -ENOMEM;
		goto err_debugfs_dir;
	}

	init_waitqueue_head(&devdata->rsp_queue);
	spin_lock_init(&devdata->privlock);
	devdata->serverdown = false;
	devdata->serverchangingstate = false;
	devdata->scsihost = scsihost;

	channel_offset = offsetof(struct visor_io_channel,
				  channel_header.features);
	err = visorbus_read_channel(dev, channel_offset, &features, 8);
	if (err)
		goto err_debugfs_info;
	features |= VISOR_CHANNEL_IS_POLLING;
	err = visorbus_write_channel(dev, channel_offset, &features, 8);
	if (err)
		goto err_debugfs_info;

	idr_init(&devdata->idr);

	devdata->thread_wait_ms = 2;
	devdata->thread = visor_thread_start(process_incoming_rsps, devdata,
					     "vhba_incoming");

	scsi_scan_host(scsihost);

	return 0;

err_debugfs_info:
	debugfs_remove(devdata->debugfs_info);

err_debugfs_dir:
	debugfs_remove_recursive(devdata->debugfs_dir);

err_scsi_remove_host:
	scsi_remove_host(scsihost);

err_scsi_host_put:
	scsi_host_put(scsihost);
	return err;
}

/*
 * visorhba_remove - Remove a visorhba device
 * @dev: Device to remove
 *
 * Removes the visorhba device.
 */
static void visorhba_remove(struct visor_device *dev)
{
	struct visorhba_devdata *devdata = dev_get_drvdata(&dev->device);
	struct Scsi_Host *scsihost = NULL;

	if (!devdata)
		return;

	scsihost = devdata->scsihost;
	visor_thread_stop(devdata->thread);
	scsi_remove_host(scsihost);
	scsi_host_put(scsihost);

	idr_destroy(&devdata->idr);

	dev_set_drvdata(&dev->device, NULL);
	debugfs_remove(devdata->debugfs_info);
	debugfs_remove_recursive(devdata->debugfs_dir);
}

/* This is used to tell the visorbus driver which types of visor devices
 * we support, and what functions to call when a visor device that we support
 * is attached or removed.
 */
static struct visor_driver visorhba_driver = {
	.name = "visorhba",
	.owner = THIS_MODULE,
	.channel_types = visorhba_channel_types,
	.probe = visorhba_probe,
	.remove = visorhba_remove,
	.pause = visorhba_pause,
	.resume = visorhba_resume,
	.channel_interrupt = NULL,
};

/*
 * visorhba_init - Driver init routine
 *
 * Initialize the visorhba driver and register it with visorbus
 * to handle s-Par virtual host bus adapter.
 *
 * Return: 0 on success, error code otherwise
 */
static int visorhba_init(void)
{
	int rc = -ENOMEM;

	visorhba_debugfs_dir = debugfs_create_dir("visorhba", NULL);
	if (!visorhba_debugfs_dir)
		return -ENOMEM;

	rc = visorbus_register_visor_driver(&visorhba_driver);
	if (rc)
		goto cleanup_debugfs;

	return 0;

cleanup_debugfs:
	debugfs_remove_recursive(visorhba_debugfs_dir);

	return rc;
}

/*
 * visorhba_exit - Driver exit routine
 *
 * Unregister driver from the bus and free up memory.
 */
static void visorhba_exit(void)
{
	visorbus_unregister_visor_driver(&visorhba_driver);
	debugfs_remove_recursive(visorhba_debugfs_dir);
}

module_init(visorhba_init);
module_exit(visorhba_exit);

MODULE_AUTHOR("Unisys");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("s-Par HBA driver for virtual SCSI host busses");
