/*
 * drivers/s390/cio/device_pgid.c
 *
 *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
 *			 IBM Corporation
 *    Author(s): Cornelia Huck (cornelia.huck@de.ibm.com)
 *		 Martin Schwidefsky (schwidefsky@de.ibm.com)
 *
 * Path Group ID functions.
 */

#include <linux/module.h>
#include <linux/init.h>

#include <asm/ccwdev.h>
#include <asm/cio.h>
#include <asm/delay.h>
#include <asm/lowcore.h>

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

/*
 * Helper function called from interrupt context to decide whether an
 * operation should be tried again.
 */
static int __ccw_device_should_retry(struct scsw *scsw)
{
	/* CC is only valid if start function bit is set. */
	if ((scsw->fctl & SCSW_FCTL_START_FUNC) && scsw->cc == 1)
		return 1;
	/* No more activity. For sense and set PGID we stubbornly try again. */
	if (!scsw->actl)
		return 1;
	return 0;
}

/*
 * Start Sense Path Group ID helper function. Used in ccw_device_recog
 * and ccw_device_sense_pgid.
 */
static int
__ccw_device_sense_pgid_start(struct ccw_device *cdev)
{
	struct subchannel *sch;
	struct ccw1 *ccw;
	int ret;
	int i;

	sch = to_subchannel(cdev->dev.parent);
	/* Return if we already checked on all paths. */
	if (cdev->private->imask == 0)
		return (sch->lpm == 0) ? -ENODEV : -EACCES;
	i = 8 - ffs(cdev->private->imask);

	/* Setup sense path group id channel program. */
	ccw = cdev->private->iccws;
	ccw->cmd_code = CCW_CMD_SENSE_PGID;
	ccw->count = sizeof (struct pgid);
	ccw->flags = CCW_FLAG_SLI;

	/* Reset device status. */
	memset(&cdev->private->irb, 0, sizeof(struct irb));
	/* Try on every path. */
	ret = -ENODEV;
	while (cdev->private->imask != 0) {
		/* Try every path multiple times. */
		ccw->cda = (__u32) __pa (&cdev->private->pgid[i]);
		if (cdev->private->iretry > 0) {
			cdev->private->iretry--;
			ret = cio_start (sch, cdev->private->iccws, 
					 cdev->private->imask);
			/* ret is 0, -EBUSY, -EACCES or -ENODEV */
			if (ret != -EACCES)
				return ret;
			CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel "
				      "0.%x.%04x, lpm %02X, became 'not "
				      "operational'\n",
				      cdev->private->dev_id.devno,
				      sch->schid.ssid,
				      sch->schid.sch_no, cdev->private->imask);

		}
		cdev->private->imask >>= 1;
		cdev->private->iretry = 5;
		i++;
	}

	return ret;
}

void
ccw_device_sense_pgid_start(struct ccw_device *cdev)
{
	int ret;

	/* Set a timeout of 60s */
	ccw_device_set_timeout(cdev, 60*HZ);

	cdev->private->state = DEV_STATE_SENSE_PGID;
	cdev->private->imask = 0x80;
	cdev->private->iretry = 5;
	memset (&cdev->private->pgid, 0, sizeof (cdev->private->pgid));
	ret = __ccw_device_sense_pgid_start(cdev);
	if (ret && ret != -EBUSY)
		ccw_device_sense_pgid_done(cdev, ret);
}

/*
 * Called from interrupt context to check if a valid answer
 * to Sense Path Group ID was received.
 */
static int
__ccw_device_check_sense_pgid(struct ccw_device *cdev)
{
	struct subchannel *sch;
	struct irb *irb;
	int i;

	sch = to_subchannel(cdev->dev.parent);
	irb = &cdev->private->irb;
	if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC))
		return -ETIME;
	if (irb->esw.esw0.erw.cons &&
	    (irb->ecw[0]&(SNS0_CMD_REJECT|SNS0_INTERVENTION_REQ))) {
		/*
		 * If the device doesn't support the Sense Path Group ID
		 *  command further retries wouldn't help ...
		 */
		return -EOPNOTSUPP;
	}
	if (irb->esw.esw0.erw.cons) {
		CIO_MSG_EVENT(2, "SNID - device 0.%x.%04x, unit check, "
			      "lpum %02X, cnt %02d, sns : "
			      "%02X%02X%02X%02X %02X%02X%02X%02X ...\n",
			      cdev->private->dev_id.ssid,
			      cdev->private->dev_id.devno,
			      irb->esw.esw0.sublog.lpum,
			      irb->esw.esw0.erw.scnt,
			      irb->ecw[0], irb->ecw[1],
			      irb->ecw[2], irb->ecw[3],
			      irb->ecw[4], irb->ecw[5],
			      irb->ecw[6], irb->ecw[7]);
		return -EAGAIN;
	}
	if (irb->scsw.cc == 3) {
		CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x,"
			      " lpm %02X, became 'not operational'\n",
			      cdev->private->dev_id.devno, sch->schid.ssid,
			      sch->schid.sch_no, sch->orb.lpm);
		return -EACCES;
	}
	i = 8 - ffs(cdev->private->imask);
	if (cdev->private->pgid[i].inf.ps.state2 == SNID_STATE2_RESVD_ELSE) {
		CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x "
			      "is reserved by someone else\n",
			      cdev->private->dev_id.devno, sch->schid.ssid,
			      sch->schid.sch_no);
		return -EUSERS;
	}
	return 0;
}

/*
 * Got interrupt for Sense Path Group ID.
 */
void
ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event)
{
	struct subchannel *sch;
	struct irb *irb;
	int ret;

	irb = (struct irb *) __LC_IRB;

	if (irb->scsw.stctl ==
	    (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
		if (__ccw_device_should_retry(&irb->scsw)) {
			ret = __ccw_device_sense_pgid_start(cdev);
			if (ret && ret != -EBUSY)
				ccw_device_sense_pgid_done(cdev, ret);
		}
		return;
	}
	if (ccw_device_accumulate_and_sense(cdev, irb) != 0)
		return;
	sch = to_subchannel(cdev->dev.parent);
	ret = __ccw_device_check_sense_pgid(cdev);
	memset(&cdev->private->irb, 0, sizeof(struct irb));
	switch (ret) {
	/* 0, -ETIME, -EOPNOTSUPP, -EAGAIN, -EACCES or -EUSERS */
	case -EOPNOTSUPP:	/* Sense Path Group ID not supported */
		ccw_device_sense_pgid_done(cdev, -EOPNOTSUPP);
		break;
	case -ETIME:		/* Sense path group id stopped by timeout. */
		ccw_device_sense_pgid_done(cdev, -ETIME);
		break;
	case -EACCES:		/* channel is not operational. */
		sch->lpm &= ~cdev->private->imask;
		/* Fall through. */
	case 0:			/* Sense Path Group ID successful. */
		cdev->private->imask >>= 1;
		cdev->private->iretry = 5;
		/* Fall through. */
	case -EAGAIN:		/* Try again. */
		ret = __ccw_device_sense_pgid_start(cdev);
		if (ret != 0 && ret != -EBUSY)
			ccw_device_sense_pgid_done(cdev, ret);
		break;
	case -EUSERS:		/* device is reserved for someone else. */
		ccw_device_sense_pgid_done(cdev, -EUSERS);
		break;
	}
}

/*
 * Path Group ID helper function.
 */
static int
__ccw_device_do_pgid(struct ccw_device *cdev, __u8 func)
{
	struct subchannel *sch;
	struct ccw1 *ccw;
	int ret;

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

	/* Setup sense path group id channel program. */
	cdev->private->pgid[0].inf.fc = func;
	ccw = cdev->private->iccws;
	if (!cdev->private->flags.pgid_single) {
		cdev->private->pgid[0].inf.fc |= SPID_FUNC_MULTI_PATH;
		ccw->cmd_code = CCW_CMD_SUSPEND_RECONN;
		ccw->cda = 0;
		ccw->count = 0;
		ccw->flags = CCW_FLAG_SLI | CCW_FLAG_CC;
		ccw++;
	} else
		cdev->private->pgid[0].inf.fc |= SPID_FUNC_SINGLE_PATH;

	ccw->cmd_code = CCW_CMD_SET_PGID;
	ccw->cda = (__u32) __pa (&cdev->private->pgid[0]);
	ccw->count = sizeof (struct pgid);
	ccw->flags = CCW_FLAG_SLI;

	/* Reset device status. */
	memset(&cdev->private->irb, 0, sizeof(struct irb));

	/* Try multiple times. */
	ret = -EACCES;
	if (cdev->private->iretry > 0) {
		cdev->private->iretry--;
		ret = cio_start (sch, cdev->private->iccws,
				 cdev->private->imask);
		/* We expect an interrupt in case of success or busy
		 * indication. */
		if ((ret == 0) || (ret == -EBUSY))
			return ret;
	}
	/* PGID command failed on this path. */
	CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel "
		      "0.%x.%04x, lpm %02X, became 'not operational'\n",
		      cdev->private->dev_id.devno, sch->schid.ssid,
		      sch->schid.sch_no, cdev->private->imask);
	return ret;
}

/*
 * Helper function to send a nop ccw down a path.
 */
static int __ccw_device_do_nop(struct ccw_device *cdev)
{
	struct subchannel *sch;
	struct ccw1 *ccw;
	int ret;

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

	/* Setup nop channel program. */
	ccw = cdev->private->iccws;
	ccw->cmd_code = CCW_CMD_NOOP;
	ccw->cda = 0;
	ccw->count = 0;
	ccw->flags = CCW_FLAG_SLI;

	/* Reset device status. */
	memset(&cdev->private->irb, 0, sizeof(struct irb));

	/* Try multiple times. */
	ret = -EACCES;
	if (cdev->private->iretry > 0) {
		cdev->private->iretry--;
		ret = cio_start (sch, cdev->private->iccws,
				 cdev->private->imask);
		/* We expect an interrupt in case of success or busy
		 * indication. */
		if ((ret == 0) || (ret == -EBUSY))
			return ret;
	}
	/* nop command failed on this path. */
	CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel "
		      "0.%x.%04x, lpm %02X, became 'not operational'\n",
		      cdev->private->dev_id.devno, sch->schid.ssid,
		      sch->schid.sch_no, cdev->private->imask);
	return ret;
}


/*
 * Called from interrupt context to check if a valid answer
 * to Set Path Group ID was received.
 */
static int
__ccw_device_check_pgid(struct ccw_device *cdev)
{
	struct subchannel *sch;
	struct irb *irb;

	sch = to_subchannel(cdev->dev.parent);
	irb = &cdev->private->irb;
	if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC))
		return -ETIME;
	if (irb->esw.esw0.erw.cons) {
		if (irb->ecw[0] & SNS0_CMD_REJECT)
			return -EOPNOTSUPP;
		/* Hmm, whatever happened, try again. */
		CIO_MSG_EVENT(2, "SPID - device 0.%x.%04x, unit check, "
			      "cnt %02d, "
			      "sns : %02X%02X%02X%02X %02X%02X%02X%02X ...\n",
			      cdev->private->dev_id.ssid,
			      cdev->private->dev_id.devno,
			      irb->esw.esw0.erw.scnt,
			      irb->ecw[0], irb->ecw[1],
			      irb->ecw[2], irb->ecw[3],
			      irb->ecw[4], irb->ecw[5],
			      irb->ecw[6], irb->ecw[7]);
		return -EAGAIN;
	}
	if (irb->scsw.cc == 3) {
		CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel 0.%x.%04x,"
			      " lpm %02X, became 'not operational'\n",
			      cdev->private->dev_id.devno, sch->schid.ssid,
			      sch->schid.sch_no, cdev->private->imask);
		return -EACCES;
	}
	return 0;
}

/*
 * Called from interrupt context to check the path status after a nop has
 * been send.
 */
static int __ccw_device_check_nop(struct ccw_device *cdev)
{
	struct subchannel *sch;
	struct irb *irb;

	sch = to_subchannel(cdev->dev.parent);
	irb = &cdev->private->irb;
	if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC))
		return -ETIME;
	if (irb->scsw.cc == 3) {
		CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel 0.%x.%04x,"
			      " lpm %02X, became 'not operational'\n",
			      cdev->private->dev_id.devno, sch->schid.ssid,
			      sch->schid.sch_no, cdev->private->imask);
		return -EACCES;
	}
	return 0;
}

static void
__ccw_device_verify_start(struct ccw_device *cdev)
{
	struct subchannel *sch;
	__u8 func;
	int ret;

	sch = to_subchannel(cdev->dev.parent);
	/* Repeat for all paths. */
	for (; cdev->private->imask; cdev->private->imask >>= 1,
				     cdev->private->iretry = 5) {
		if ((cdev->private->imask & sch->schib.pmcw.pam) == 0)
			/* Path not available, try next. */
			continue;
		if (cdev->private->options.pgroup) {
			if (sch->opm & cdev->private->imask)
				func = SPID_FUNC_ESTABLISH;
			else
				func = SPID_FUNC_RESIGN;
			ret = __ccw_device_do_pgid(cdev, func);
		} else
			ret = __ccw_device_do_nop(cdev);
		/* We expect an interrupt in case of success or busy
		 * indication. */
		if (ret == 0 || ret == -EBUSY)
			return;
		/* Permanent path failure, try next. */
	}
	/* Done with all paths. */
	ccw_device_verify_done(cdev, (sch->vpm != 0) ? 0 : -ENODEV);
}
		
/*
 * Got interrupt for Set Path Group ID.
 */
void
ccw_device_verify_irq(struct ccw_device *cdev, enum dev_event dev_event)
{
	struct subchannel *sch;
	struct irb *irb;
	int ret;

	irb = (struct irb *) __LC_IRB;

	if (irb->scsw.stctl ==
	    (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
		if (__ccw_device_should_retry(&irb->scsw))
			__ccw_device_verify_start(cdev);
		return;
	}
	if (ccw_device_accumulate_and_sense(cdev, irb) != 0)
		return;
	sch = to_subchannel(cdev->dev.parent);
	if (cdev->private->options.pgroup)
		ret = __ccw_device_check_pgid(cdev);
	else
		ret = __ccw_device_check_nop(cdev);
	memset(&cdev->private->irb, 0, sizeof(struct irb));

	switch (ret) {
	/* 0, -ETIME, -EAGAIN, -EOPNOTSUPP or -EACCES */
	case 0:
		/* Path verification ccw finished successfully, update lpm. */
		sch->vpm |= sch->opm & cdev->private->imask;
		/* Go on with next path. */
		cdev->private->imask >>= 1;
		cdev->private->iretry = 5;
		__ccw_device_verify_start(cdev);
		break;
	case -EOPNOTSUPP:
		/*
		 * One of those strange devices which claim to be able
		 * to do multipathing but not for Set Path Group ID.
		 */
		if (cdev->private->flags.pgid_single)
			cdev->private->options.pgroup = 0;
		else
			cdev->private->flags.pgid_single = 1;
		/* Retry */
		sch->vpm = 0;
		cdev->private->imask = 0x80;
		cdev->private->iretry = 5;
		/* fall through. */
	case -EAGAIN:		/* Try again. */
		__ccw_device_verify_start(cdev);
		break;
	case -ETIME:		/* Set path group id stopped by timeout. */
		ccw_device_verify_done(cdev, -ETIME);
		break;
	case -EACCES:		/* channel is not operational. */
		cdev->private->imask >>= 1;
		cdev->private->iretry = 5;
		__ccw_device_verify_start(cdev);
		break;
	}
}

void
ccw_device_verify_start(struct ccw_device *cdev)
{
	struct subchannel *sch = to_subchannel(cdev->dev.parent);

	cdev->private->flags.pgid_single = 0;
	cdev->private->imask = 0x80;
	cdev->private->iretry = 5;

	/* Start with empty vpm. */
	sch->vpm = 0;

	/* Get current pam. */
	if (stsch(sch->schid, &sch->schib)) {
		ccw_device_verify_done(cdev, -ENODEV);
		return;
	}
	/* After 60s path verification is considered to have failed. */
	ccw_device_set_timeout(cdev, 60*HZ);
	__ccw_device_verify_start(cdev);
}

static void
__ccw_device_disband_start(struct ccw_device *cdev)
{
	struct subchannel *sch;
	int ret;

	sch = to_subchannel(cdev->dev.parent);
	while (cdev->private->imask != 0) {
		if (sch->lpm & cdev->private->imask) {
			ret = __ccw_device_do_pgid(cdev, SPID_FUNC_DISBAND);
			if (ret == 0)
				return;
		}
		cdev->private->iretry = 5;
		cdev->private->imask >>= 1;
	}
	ccw_device_disband_done(cdev, (sch->lpm != 0) ? 0 : -ENODEV);
}

/*
 * Got interrupt for Unset Path Group ID.
 */
void
ccw_device_disband_irq(struct ccw_device *cdev, enum dev_event dev_event)
{
	struct subchannel *sch;
	struct irb *irb;
	int ret;

	irb = (struct irb *) __LC_IRB;

	if (irb->scsw.stctl ==
	    (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
		if (__ccw_device_should_retry(&irb->scsw))
			__ccw_device_disband_start(cdev);
		return;
	}
	if (ccw_device_accumulate_and_sense(cdev, irb) != 0)
		return;
	sch = to_subchannel(cdev->dev.parent);
	ret = __ccw_device_check_pgid(cdev);
	memset(&cdev->private->irb, 0, sizeof(struct irb));
	switch (ret) {
	/* 0, -ETIME, -EAGAIN, -EOPNOTSUPP or -EACCES */
	case 0:			/* disband successful. */
		ccw_device_disband_done(cdev, ret);
		break;
	case -EOPNOTSUPP:
		/*
		 * One of those strange devices which claim to be able
		 * to do multipathing but not for Unset Path Group ID.
		 */
		cdev->private->flags.pgid_single = 1;
		/* fall through. */
	case -EAGAIN:		/* Try again. */
		__ccw_device_disband_start(cdev);
		break;
	case -ETIME:		/* Set path group id stopped by timeout. */
		ccw_device_disband_done(cdev, -ETIME);
		break;
	case -EACCES:		/* channel is not operational. */
		cdev->private->imask >>= 1;
		cdev->private->iretry = 5;
		__ccw_device_disband_start(cdev);
		break;
	}
}

void
ccw_device_disband_start(struct ccw_device *cdev)
{
	/* After 60s disbanding is considered to have failed. */
	ccw_device_set_timeout(cdev, 60*HZ);

	cdev->private->flags.pgid_single = 0;
	cdev->private->iretry = 5;
	cdev->private->imask = 0x80;
	__ccw_device_disband_start(cdev);
}
