/*
 *  drivers/s390/cio/device_ops.c
 *
 *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
 *			 IBM Corporation
 *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
 *               Cornelia Huck (cornelia.huck@de.ibm.com)
 */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/device.h>
#include <linux/delay.h>

#include <asm/ccwdev.h>
#include <asm/idals.h>

#include "cio.h"
#include "cio_debug.h"
#include "css.h"
#include "chsc.h"
#include "device.h"

int
ccw_device_set_options(struct ccw_device *cdev, unsigned long flags)
{
       /*
	* The flag usage is mutal exclusive ...
	*/
	if ((flags & CCWDEV_EARLY_NOTIFICATION) &&
	    (flags & CCWDEV_REPORT_ALL))
		return -EINVAL;
	cdev->private->options.fast = (flags & CCWDEV_EARLY_NOTIFICATION) != 0;
	cdev->private->options.repall = (flags & CCWDEV_REPORT_ALL) != 0;
	cdev->private->options.pgroup = (flags & CCWDEV_DO_PATHGROUP) != 0;
	cdev->private->options.force = (flags & CCWDEV_ALLOW_FORCE) != 0;
	return 0;
}

int
ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)
{
	struct subchannel *sch;
	int ret;

	if (!cdev)
		return -ENODEV;
	if (cdev->private->state == DEV_STATE_NOT_OPER)
		return -ENODEV;
	if (cdev->private->state != DEV_STATE_ONLINE &&
	    cdev->private->state != DEV_STATE_W4SENSE)
		return -EINVAL;
	sch = to_subchannel(cdev->dev.parent);
	if (!sch)
		return -ENODEV;
	ret = cio_clear(sch);
	if (ret == 0)
		cdev->private->intparm = intparm;
	return ret;
}

int
ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
		     unsigned long intparm, __u8 lpm, __u8 key,
		     unsigned long flags)
{
	struct subchannel *sch;
	int ret;

	if (!cdev)
		return -ENODEV;
	sch = to_subchannel(cdev->dev.parent);
	if (!sch)
		return -ENODEV;
	if (cdev->private->state == DEV_STATE_NOT_OPER)
		return -ENODEV;
	if (cdev->private->state == DEV_STATE_VERIFY ||
	    cdev->private->state == DEV_STATE_CLEAR_VERIFY) {
		/* Remember to fake irb when finished. */
		if (!cdev->private->flags.fake_irb) {
			cdev->private->flags.fake_irb = 1;
			cdev->private->intparm = intparm;
			return 0;
		} else
			/* There's already a fake I/O around. */
			return -EBUSY;
	}
	if (cdev->private->state != DEV_STATE_ONLINE ||
	    ((sch->schib.scsw.stctl & SCSW_STCTL_PRIM_STATUS) &&
	     !(sch->schib.scsw.stctl & SCSW_STCTL_SEC_STATUS)) ||
	    cdev->private->flags.doverify)
		return -EBUSY;
	ret = cio_set_options (sch, flags);
	if (ret)
		return ret;
	/* Adjust requested path mask to excluded varied off paths. */
	if (lpm) {
		lpm &= sch->opm;
		if (lpm == 0)
			return -EACCES;
	}
	ret = cio_start_key (sch, cpa, lpm, key);
	if (ret == 0)
		cdev->private->intparm = intparm;
	return ret;
}


int
ccw_device_start_timeout_key(struct ccw_device *cdev, struct ccw1 *cpa,
			     unsigned long intparm, __u8 lpm, __u8 key,
			     unsigned long flags, int expires)
{
	int ret;

	if (!cdev)
		return -ENODEV;
	ccw_device_set_timeout(cdev, expires);
	ret = ccw_device_start_key(cdev, cpa, intparm, lpm, key, flags);
	if (ret != 0)
		ccw_device_set_timeout(cdev, 0);
	return ret;
}

int
ccw_device_start(struct ccw_device *cdev, struct ccw1 *cpa,
		 unsigned long intparm, __u8 lpm, unsigned long flags)
{
	return ccw_device_start_key(cdev, cpa, intparm, lpm,
				    PAGE_DEFAULT_KEY, flags);
}

int
ccw_device_start_timeout(struct ccw_device *cdev, struct ccw1 *cpa,
			 unsigned long intparm, __u8 lpm, unsigned long flags,
			 int expires)
{
	return ccw_device_start_timeout_key(cdev, cpa, intparm, lpm,
					    PAGE_DEFAULT_KEY, flags,
					    expires);
}


int
ccw_device_halt(struct ccw_device *cdev, unsigned long intparm)
{
	struct subchannel *sch;
	int ret;

	if (!cdev)
		return -ENODEV;
	if (cdev->private->state == DEV_STATE_NOT_OPER)
		return -ENODEV;
	if (cdev->private->state != DEV_STATE_ONLINE &&
	    cdev->private->state != DEV_STATE_W4SENSE)
		return -EINVAL;
	sch = to_subchannel(cdev->dev.parent);
	if (!sch)
		return -ENODEV;
	ret = cio_halt(sch);
	if (ret == 0)
		cdev->private->intparm = intparm;
	return ret;
}

int
ccw_device_resume(struct ccw_device *cdev)
{
	struct subchannel *sch;

	if (!cdev)
		return -ENODEV;
	sch = to_subchannel(cdev->dev.parent);
	if (!sch)
		return -ENODEV;
	if (cdev->private->state == DEV_STATE_NOT_OPER)
		return -ENODEV;
	if (cdev->private->state != DEV_STATE_ONLINE ||
	    !(sch->schib.scsw.actl & SCSW_ACTL_SUSPENDED))
		return -EINVAL;
	return cio_resume(sch);
}

/*
 * Pass interrupt to device driver.
 */
int
ccw_device_call_handler(struct ccw_device *cdev)
{
	struct subchannel *sch;
	unsigned int stctl;
	int ending_status;

	sch = to_subchannel(cdev->dev.parent);

	/*
	 * we allow for the device action handler if .
	 *  - we received ending status
	 *  - the action handler requested to see all interrupts
	 *  - we received an intermediate status
	 *  - fast notification was requested (primary status)
	 *  - unsolicited interrupts
	 */
	stctl = cdev->private->irb.scsw.stctl;
	ending_status = (stctl & SCSW_STCTL_SEC_STATUS) ||
		(stctl == (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)) ||
		(stctl == SCSW_STCTL_STATUS_PEND);
	if (!ending_status &&
	    !cdev->private->options.repall &&
	    !(stctl & SCSW_STCTL_INTER_STATUS) &&
	    !(cdev->private->options.fast &&
	      (stctl & SCSW_STCTL_PRIM_STATUS)))
		return 0;

	/* Clear pending timers for device driver initiated I/O. */
	if (ending_status)
		ccw_device_set_timeout(cdev, 0);
	/*
	 * Now we are ready to call the device driver interrupt handler.
	 */
	if (cdev->handler)
		cdev->handler(cdev, cdev->private->intparm,
			      &cdev->private->irb);

	/*
	 * Clear the old and now useless interrupt response block.
	 */
	memset(&cdev->private->irb, 0, sizeof(struct irb));

	return 1;
}

/*
 * Search for CIW command in extended sense data.
 */
struct ciw *
ccw_device_get_ciw(struct ccw_device *cdev, __u32 ct)
{
	int ciw_cnt;

	if (cdev->private->flags.esid == 0)
		return NULL;
	for (ciw_cnt = 0; ciw_cnt < MAX_CIWS; ciw_cnt++)
		if (cdev->private->senseid.ciw[ciw_cnt].ct == ct)
			return cdev->private->senseid.ciw + ciw_cnt;
	return NULL;
}

__u8
ccw_device_get_path_mask(struct ccw_device *cdev)
{
	struct subchannel *sch;

	sch = to_subchannel(cdev->dev.parent);
	if (!sch)
		return 0;
	else
		return sch->lpm;
}

static void
ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb)
{
	if (!ip)
		/* unsolicited interrupt */
		return;

	/* Abuse intparm for error reporting. */
	if (IS_ERR(irb))
		cdev->private->intparm = -EIO;
	else if (irb->scsw.cc == 1)
		/* Retry for deferred condition code. */
		cdev->private->intparm = -EAGAIN;
	else if ((irb->scsw.dstat !=
		  (DEV_STAT_CHN_END|DEV_STAT_DEV_END)) ||
		 (irb->scsw.cstat != 0)) {
		/*
		 * We didn't get channel end / device end. Check if path
		 * verification has been started; we can retry after it has
		 * finished. We also retry unit checks except for command reject
		 * or intervention required. Also check for long busy
		 * conditions.
		 */
		 if (cdev->private->flags.doverify ||
			 cdev->private->state == DEV_STATE_VERIFY)
			 cdev->private->intparm = -EAGAIN;
		else if ((irb->scsw.dstat & DEV_STAT_UNIT_CHECK) &&
			 !(irb->ecw[0] &
			   (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ)))
			cdev->private->intparm = -EAGAIN;
		else if ((irb->scsw.dstat & DEV_STAT_ATTENTION) &&
			 (irb->scsw.dstat & DEV_STAT_DEV_END) &&
			 (irb->scsw.dstat & DEV_STAT_UNIT_EXCEP))
			cdev->private->intparm = -EAGAIN;
		 else
			 cdev->private->intparm = -EIO;
			 
	} else
		cdev->private->intparm = 0;
	wake_up(&cdev->private->wait_q);
}

static inline int
__ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic, __u8 lpm)
{
	int ret;
	struct subchannel *sch;

	sch = to_subchannel(cdev->dev.parent);
	do {
		ccw_device_set_timeout(cdev, 60 * HZ);
		ret = cio_start (sch, ccw, lpm);
		if (ret != 0)
			ccw_device_set_timeout(cdev, 0);
		if (ret == -EBUSY) {
			/* Try again later. */
			spin_unlock_irq(sch->lock);
			msleep(10);
			spin_lock_irq(sch->lock);
			continue;
		}
		if (ret != 0)
			/* Non-retryable error. */
			break;
		/* Wait for end of request. */
		cdev->private->intparm = magic;
		spin_unlock_irq(sch->lock);
		wait_event(cdev->private->wait_q,
			   (cdev->private->intparm == -EIO) ||
			   (cdev->private->intparm == -EAGAIN) ||
			   (cdev->private->intparm == 0));
		spin_lock_irq(sch->lock);
		/* Check at least for channel end / device end */
		if (cdev->private->intparm == -EIO) {
			/* Non-retryable error. */
			ret = -EIO;
			break;
		}
		if (cdev->private->intparm == 0)
			/* Success. */
			break;
		/* Try again later. */
		spin_unlock_irq(sch->lock);
		msleep(10);
		spin_lock_irq(sch->lock);
	} while (1);

	return ret;
}

/**
 * read_dev_chars() - read device characteristics
 * @param cdev   target ccw device
 * @param buffer pointer to buffer for rdc data
 * @param length size of rdc data
 * @returns 0 for success, negative error value on failure
 *
 * Context:
 *   called for online device, lock not held
 **/
int
read_dev_chars (struct ccw_device *cdev, void **buffer, int length)
{
	void (*handler)(struct ccw_device *, unsigned long, struct irb *);
	struct subchannel *sch;
	int ret;
	struct ccw1 *rdc_ccw;

	if (!cdev)
		return -ENODEV;
	if (!buffer || !length)
		return -EINVAL;
	sch = to_subchannel(cdev->dev.parent);

	CIO_TRACE_EVENT (4, "rddevch");
	CIO_TRACE_EVENT (4, sch->dev.bus_id);

	rdc_ccw = kzalloc(sizeof(struct ccw1), GFP_KERNEL | GFP_DMA);
	if (!rdc_ccw)
		return -ENOMEM;
	rdc_ccw->cmd_code = CCW_CMD_RDC;
	rdc_ccw->count = length;
	rdc_ccw->flags = CCW_FLAG_SLI;
	ret = set_normalized_cda (rdc_ccw, (*buffer));
	if (ret != 0) {
		kfree(rdc_ccw);
		return ret;
	}

	spin_lock_irq(sch->lock);
	/* Save interrupt handler. */
	handler = cdev->handler;
	/* Temporarily install own handler. */
	cdev->handler = ccw_device_wake_up;
	if (cdev->private->state != DEV_STATE_ONLINE)
		ret = -ENODEV;
	else if (((sch->schib.scsw.stctl & SCSW_STCTL_PRIM_STATUS) &&
		  !(sch->schib.scsw.stctl & SCSW_STCTL_SEC_STATUS)) ||
		 cdev->private->flags.doverify)
		ret = -EBUSY;
	else
		/* 0x00D9C4C3 == ebcdic "RDC" */
		ret = __ccw_device_retry_loop(cdev, rdc_ccw, 0x00D9C4C3, 0);

	/* Restore interrupt handler. */
	cdev->handler = handler;
	spin_unlock_irq(sch->lock);

	clear_normalized_cda (rdc_ccw);
	kfree(rdc_ccw);

	return ret;
}

/*
 *  Read Configuration data using path mask
 */
int
read_conf_data_lpm (struct ccw_device *cdev, void **buffer, int *length, __u8 lpm)
{
	void (*handler)(struct ccw_device *, unsigned long, struct irb *);
	struct subchannel *sch;
	struct ciw *ciw;
	char *rcd_buf;
	int ret;
	struct ccw1 *rcd_ccw;

	if (!cdev)
		return -ENODEV;
	if (!buffer || !length)
		return -EINVAL;
	sch = to_subchannel(cdev->dev.parent);

	CIO_TRACE_EVENT (4, "rdconf");
	CIO_TRACE_EVENT (4, sch->dev.bus_id);

	/*
	 * scan for RCD command in extended SenseID data
	 */
	ciw = ccw_device_get_ciw(cdev, CIW_TYPE_RCD);
	if (!ciw || ciw->cmd == 0)
		return -EOPNOTSUPP;

	/* Adjust requested path mask to excluded varied off paths. */
	if (lpm) {
		lpm &= sch->opm;
		if (lpm == 0)
			return -EACCES;
	}

	rcd_ccw = kzalloc(sizeof(struct ccw1), GFP_KERNEL | GFP_DMA);
	if (!rcd_ccw)
		return -ENOMEM;
	rcd_buf = kzalloc(ciw->count, GFP_KERNEL | GFP_DMA);
 	if (!rcd_buf) {
		kfree(rcd_ccw);
		return -ENOMEM;
	}
	rcd_ccw->cmd_code = ciw->cmd;
	rcd_ccw->cda = (__u32) __pa (rcd_buf);
	rcd_ccw->count = ciw->count;
	rcd_ccw->flags = CCW_FLAG_SLI;

	spin_lock_irq(sch->lock);
	/* Save interrupt handler. */
	handler = cdev->handler;
	/* Temporarily install own handler. */
	cdev->handler = ccw_device_wake_up;
	if (cdev->private->state != DEV_STATE_ONLINE)
		ret = -ENODEV;
	else if (((sch->schib.scsw.stctl & SCSW_STCTL_PRIM_STATUS) &&
		  !(sch->schib.scsw.stctl & SCSW_STCTL_SEC_STATUS)) ||
		 cdev->private->flags.doverify)
		ret = -EBUSY;
	else
		/* 0x00D9C3C4 == ebcdic "RCD" */
		ret = __ccw_device_retry_loop(cdev, rcd_ccw, 0x00D9C3C4, lpm);

	/* Restore interrupt handler. */
	cdev->handler = handler;
	spin_unlock_irq(sch->lock);

 	/*
 	 * on success we update the user input parms
 	 */
 	if (ret) {
 		kfree (rcd_buf);
 		*buffer = NULL;
 		*length = 0;
 	} else {
		*length = ciw->count;
		*buffer = rcd_buf;
	}
	kfree(rcd_ccw);

	return ret;
}

/*
 *  Read Configuration data
 */
int
read_conf_data (struct ccw_device *cdev, void **buffer, int *length)
{
	return read_conf_data_lpm (cdev, buffer, length, 0);
}

/*
 * Try to break the lock on a boxed device.
 */
int
ccw_device_stlck(struct ccw_device *cdev)
{
	void *buf, *buf2;
	unsigned long flags;
	struct subchannel *sch;
	int ret;

	if (!cdev)
		return -ENODEV;

	if (cdev->drv && !cdev->private->options.force)
		return -EINVAL;

	sch = to_subchannel(cdev->dev.parent);
	
	CIO_TRACE_EVENT(2, "stl lock");
	CIO_TRACE_EVENT(2, cdev->dev.bus_id);

	buf = kmalloc(32*sizeof(char), GFP_DMA|GFP_KERNEL);
	if (!buf)
		return -ENOMEM;
	buf2 = kmalloc(32*sizeof(char), GFP_DMA|GFP_KERNEL);
	if (!buf2) {
		kfree(buf);
		return -ENOMEM;
	}
	spin_lock_irqsave(sch->lock, flags);
	ret = cio_enable_subchannel(sch, 3);
	if (ret)
		goto out_unlock;
	/*
	 * Setup ccw. We chain an unconditional reserve and a release so we
	 * only break the lock.
	 */
	cdev->private->iccws[0].cmd_code = CCW_CMD_STLCK;
	cdev->private->iccws[0].cda = (__u32) __pa(buf);
	cdev->private->iccws[0].count = 32;
	cdev->private->iccws[0].flags = CCW_FLAG_CC;
	cdev->private->iccws[1].cmd_code = CCW_CMD_RELEASE;
	cdev->private->iccws[1].cda = (__u32) __pa(buf2);
	cdev->private->iccws[1].count = 32;
	cdev->private->iccws[1].flags = 0;
	ret = cio_start(sch, cdev->private->iccws, 0);
	if (ret) {
		cio_disable_subchannel(sch); //FIXME: return code?
		goto out_unlock;
	}
	cdev->private->irb.scsw.actl |= SCSW_ACTL_START_PEND;
	spin_unlock_irqrestore(sch->lock, flags);
	wait_event(cdev->private->wait_q, cdev->private->irb.scsw.actl == 0);
	spin_lock_irqsave(sch->lock, flags);
	cio_disable_subchannel(sch); //FIXME: return code?
	if ((cdev->private->irb.scsw.dstat !=
	     (DEV_STAT_CHN_END|DEV_STAT_DEV_END)) ||
	    (cdev->private->irb.scsw.cstat != 0))
		ret = -EIO;
	/* Clear irb. */
	memset(&cdev->private->irb, 0, sizeof(struct irb));
out_unlock:
	kfree(buf);
	kfree(buf2);
	spin_unlock_irqrestore(sch->lock, flags);
	return ret;
}

void *
ccw_device_get_chp_desc(struct ccw_device *cdev, int chp_no)
{
	struct subchannel *sch;

	sch = to_subchannel(cdev->dev.parent);
	return chsc_get_chp_desc(sch, chp_no);
}

// FIXME: these have to go:

int
_ccw_device_get_subchannel_number(struct ccw_device *cdev)
{
	return cdev->private->schid.sch_no;
}

int
_ccw_device_get_device_number(struct ccw_device *cdev)
{
	return cdev->private->dev_id.devno;
}


MODULE_LICENSE("GPL");
EXPORT_SYMBOL(ccw_device_set_options);
EXPORT_SYMBOL(ccw_device_clear);
EXPORT_SYMBOL(ccw_device_halt);
EXPORT_SYMBOL(ccw_device_resume);
EXPORT_SYMBOL(ccw_device_start_timeout);
EXPORT_SYMBOL(ccw_device_start);
EXPORT_SYMBOL(ccw_device_start_timeout_key);
EXPORT_SYMBOL(ccw_device_start_key);
EXPORT_SYMBOL(ccw_device_get_ciw);
EXPORT_SYMBOL(ccw_device_get_path_mask);
EXPORT_SYMBOL(read_conf_data);
EXPORT_SYMBOL(read_dev_chars);
EXPORT_SYMBOL(_ccw_device_get_subchannel_number);
EXPORT_SYMBOL(_ccw_device_get_device_number);
EXPORT_SYMBOL_GPL(ccw_device_get_chp_desc);
EXPORT_SYMBOL_GPL(read_conf_data_lpm);
