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

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

	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->ssid, cdev->private->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->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->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;
	/* Retry sense pgid for cc=1. */
	if (irb->scsw.stctl ==
	    (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
		if (irb->scsw.cc == 1) {
			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 = -ENODEV;
	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) && (ret != -ENODEV))
			return ret;
	}
	/* PGID command failed on this path. Switch it off. */
	sch->lpm &= ~cdev->private->imask;
	sch->vpm &= ~cdev->private->imask;
	CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel "
		      "0.%x.%04x, lpm %02X, became 'not operational'\n",
		      cdev->private->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 = -ENODEV;
	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) && (ret != -ENODEV))
			return ret;
	}
	/* nop command failed on this path. Switch it off. */
	sch->lpm &= ~cdev->private->imask;
	sch->vpm &= ~cdev->private->imask;
	CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel "
		      "0.%x.%04x, lpm %02X, became 'not operational'\n",
		      cdev->private->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->ssid,
			      cdev->private->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->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->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 imask, func;
	int ret;

	sch = to_subchannel(cdev->dev.parent);
	while (sch->vpm != sch->lpm) {
		/* Find first unequal bit in vpm vs. lpm */
		for (imask = 0x80; imask != 0; imask >>= 1)
			if ((sch->vpm & imask) != (sch->lpm & imask))
				break;
		cdev->private->imask = imask;
		if (cdev->private->options.pgroup) {
			func = (sch->vpm & imask) ?
				SPID_FUNC_RESIGN : SPID_FUNC_ESTABLISH;
			ret = __ccw_device_do_pgid(cdev, func);
		} else
			ret = __ccw_device_do_nop(cdev);
		if (ret == 0 || ret == -EBUSY)
			return;
		cdev->private->iretry = 5;
	}
	ccw_device_verify_done(cdev, (sch->lpm != 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;
	/* Retry set pgid for cc=1. */
	if (irb->scsw.stctl ==
	    (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
		if (irb->scsw.cc == 1)
			__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:
		/* Establish or Resign Path Group done. Update vpm. */
		if ((sch->lpm & cdev->private->imask) != 0)
			sch->vpm |= cdev->private->imask;
		else
			sch->vpm &= ~cdev->private->imask;
		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;
		/* 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. */
		sch->lpm &= ~cdev->private->imask;
		sch->vpm &= ~cdev->private->imask;
		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->iretry = 5;
	/*
	 * Update sch->lpm with current values to catch paths becoming
	 * available again.
	 */
	if (stsch(sch->schid, &sch->schib)) {
		ccw_device_verify_done(cdev, -ENODEV);
		return;
	}
	sch->lpm = sch->schib.pmcw.pim &
		sch->schib.pmcw.pam &
		sch->schib.pmcw.pom &
		sch->opm;
	__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;
	/* Retry set pgid for cc=1. */
	if (irb->scsw.stctl ==
	    (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
		if (irb->scsw.cc == 1)
			__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. */
		sch->vpm = 0;
		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)
{
	cdev->private->flags.pgid_single = 0;
	cdev->private->iretry = 5;
	cdev->private->imask = 0x80;
	__ccw_device_disband_start(cdev);
}
