/*
 *  drivers/s390/cio/chsc.c
 *   S/390 common I/O routines -- channel subsystem call
 *   $Revision: 1.119 $
 *
 *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
 *			      IBM Corporation
 *    Author(s): Ingo Adlung (adlung@de.ibm.com)
 *		 Cornelia Huck (cohuck@de.ibm.com)
 *		 Arnd Bergmann (arndb@de.ibm.com)
 */

#include <linux/module.h>
#include <linux/config.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/device.h>

#include <asm/cio.h>

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

static struct channel_path *chps[NR_CHPIDS];

static void *sei_page;

static int new_channel_path(int chpid);

static inline void
set_chp_logically_online(int chp, int onoff)
{
	chps[chp]->state = onoff;
}

static int
get_chp_status(int chp)
{
	return (chps[chp] ? chps[chp]->state : -ENODEV);
}

void
chsc_validate_chpids(struct subchannel *sch)
{
	int mask, chp;

	for (chp = 0; chp <= 7; chp++) {
		mask = 0x80 >> chp;
		if (!get_chp_status(sch->schib.pmcw.chpid[chp]))
			/* disable using this path */
			sch->opm &= ~mask;
	}
}

void
chpid_is_actually_online(int chp)
{
	int state;

	state = get_chp_status(chp);
	if (state < 0) {
		need_rescan = 1;
		queue_work(slow_path_wq, &slow_path_work);
	} else
		WARN_ON(!state);
}

/* FIXME: this is _always_ called for every subchannel. shouldn't we
 *	  process more than one at a time? */
static int
chsc_get_sch_desc_irq(struct subchannel *sch, void *page)
{
	int ccode, j;

	struct {
		struct chsc_header request;
		u16 reserved1;
		u16 f_sch;	  /* first subchannel */
		u16 reserved2;
		u16 l_sch;	  /* last subchannel */
		u32 reserved3;
		struct chsc_header response;
		u32 reserved4;
		u8 sch_valid : 1;
		u8 dev_valid : 1;
		u8 st	     : 3; /* subchannel type */
		u8 zeroes    : 3;
		u8  unit_addr;	  /* unit address */
		u16 devno;	  /* device number */
		u8 path_mask;
		u8 fla_valid_mask;
		u16 sch;	  /* subchannel */
		u8 chpid[8];	  /* chpids 0-7 */
		u16 fla[8];	  /* full link addresses 0-7 */
	} *ssd_area;

	ssd_area = page;

	ssd_area->request = (struct chsc_header) {
		.length = 0x0010,
		.code   = 0x0004,
	};

	ssd_area->f_sch = sch->irq;
	ssd_area->l_sch = sch->irq;

	ccode = chsc(ssd_area);
	if (ccode > 0) {
		pr_debug("chsc returned with ccode = %d\n", ccode);
		return (ccode == 3) ? -ENODEV : -EBUSY;
	}

	switch (ssd_area->response.code) {
	case 0x0001: /* everything ok */
		break;
	case 0x0002:
		CIO_CRW_EVENT(2, "Invalid command!\n");
		return -EINVAL;
	case 0x0003:
		CIO_CRW_EVENT(2, "Error in chsc request block!\n");
		return -EINVAL;
	case 0x0004:
		CIO_CRW_EVENT(2, "Model does not provide ssd\n");
		return -EOPNOTSUPP;
	default:
		CIO_CRW_EVENT(2, "Unknown CHSC response %d\n",
			      ssd_area->response.code);
		return -EIO;
	}

	/*
	 * ssd_area->st stores the type of the detected
	 * subchannel, with the following definitions:
	 *
	 * 0: I/O subchannel:	  All fields have meaning
	 * 1: CHSC subchannel:	  Only sch_val, st and sch
	 *			  have meaning
	 * 2: Message subchannel: All fields except unit_addr
	 *			  have meaning
	 * 3: ADM subchannel:	  Only sch_val, st and sch
	 *			  have meaning
	 *
	 * Other types are currently undefined.
	 */
	if (ssd_area->st > 3) { /* uhm, that looks strange... */
		CIO_CRW_EVENT(0, "Strange subchannel type %d"
			      " for sch %04x\n", ssd_area->st, sch->irq);
		/*
		 * There may have been a new subchannel type defined in the
		 * time since this code was written; since we don't know which
		 * fields have meaning and what to do with it we just jump out
		 */
		return 0;
	} else {
		const char *type[4] = {"I/O", "chsc", "message", "ADM"};
		CIO_CRW_EVENT(6, "ssd: sch %04x is %s subchannel\n",
			      sch->irq, type[ssd_area->st]);

		sch->ssd_info.valid = 1;
		sch->ssd_info.type = ssd_area->st;
	}

	if (ssd_area->st == 0 || ssd_area->st == 2) {
		for (j = 0; j < 8; j++) {
			if (!((0x80 >> j) & ssd_area->path_mask &
			      ssd_area->fla_valid_mask))
				continue;
			sch->ssd_info.chpid[j] = ssd_area->chpid[j];
			sch->ssd_info.fla[j]   = ssd_area->fla[j];
		}
	}
	return 0;
}

int
css_get_ssd_info(struct subchannel *sch)
{
	int ret;
	void *page;

	page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
	if (!page)
		return -ENOMEM;
	spin_lock_irq(&sch->lock);
	ret = chsc_get_sch_desc_irq(sch, page);
	if (ret) {
		static int cio_chsc_err_msg;
		
		if (!cio_chsc_err_msg) {
			printk(KERN_ERR
			       "chsc_get_sch_descriptions:"
			       " Error %d while doing chsc; "
			       "processing some machine checks may "
			       "not work\n", ret);
			cio_chsc_err_msg = 1;
		}
	}
	spin_unlock_irq(&sch->lock);
	free_page((unsigned long)page);
	if (!ret) {
		int j, chpid;
		/* Allocate channel path structures, if needed. */
		for (j = 0; j < 8; j++) {
			chpid = sch->ssd_info.chpid[j];
			if (chpid && (get_chp_status(chpid) < 0))
			    new_channel_path(chpid);
		}
	}
	return ret;
}

static int
s390_subchannel_remove_chpid(struct device *dev, void *data)
{
	int j;
	int mask;
	struct subchannel *sch;
	__u8 *chpid;
	struct schib schib;

	sch = to_subchannel(dev);
	chpid = data;
	for (j = 0; j < 8; j++)
		if (sch->schib.pmcw.chpid[j] == *chpid)
			break;
	if (j >= 8)
		return 0;

	mask = 0x80 >> j;
	spin_lock(&sch->lock);

	stsch(sch->irq, &schib);
	if (!schib.pmcw.dnv)
		goto out_unreg;
	memcpy(&sch->schib, &schib, sizeof(struct schib));
	/* Check for single path devices. */
	if (sch->schib.pmcw.pim == 0x80)
		goto out_unreg;
	if (sch->vpm == mask)
		goto out_unreg;

	if ((sch->schib.scsw.actl & (SCSW_ACTL_CLEAR_PEND |
				     SCSW_ACTL_HALT_PEND |
				     SCSW_ACTL_START_PEND |
				     SCSW_ACTL_RESUME_PEND)) &&
	    (sch->schib.pmcw.lpum == mask)) {
		int cc = cio_cancel(sch);
		
		if (cc == -ENODEV)
			goto out_unreg;

		if (cc == -EINVAL) {
			cc = cio_clear(sch);
			if (cc == -ENODEV)
				goto out_unreg;
			/* Call handler. */
			if (sch->driver && sch->driver->termination)
				sch->driver->termination(&sch->dev);
			goto out_unlock;
		}
	} else if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) &&
		   (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) &&
		   (sch->schib.pmcw.lpum == mask)) {
		int cc;

		cc = cio_clear(sch);
		if (cc == -ENODEV)
			goto out_unreg;
		/* Call handler. */
		if (sch->driver && sch->driver->termination)
			sch->driver->termination(&sch->dev);
		goto out_unlock;
	}

	/* trigger path verification. */
	if (sch->driver && sch->driver->verify)
		sch->driver->verify(&sch->dev);
out_unlock:
	spin_unlock(&sch->lock);
	return 0;
out_unreg:
	spin_unlock(&sch->lock);
	sch->lpm = 0;
	if (css_enqueue_subchannel_slow(sch->irq)) {
		css_clear_subchannel_slow_list();
		need_rescan = 1;
	}
	return 0;
}

static inline void
s390_set_chpid_offline( __u8 chpid)
{
	char dbf_txt[15];

	sprintf(dbf_txt, "chpr%x", chpid);
	CIO_TRACE_EVENT(2, dbf_txt);

	if (get_chp_status(chpid) <= 0)
		return;

	bus_for_each_dev(&css_bus_type, NULL, &chpid,
			 s390_subchannel_remove_chpid);

	if (need_rescan || css_slow_subchannels_exist())
		queue_work(slow_path_wq, &slow_path_work);
}

static int
s390_process_res_acc_sch(u8 chpid, __u16 fla, u32 fla_mask,
			 struct subchannel *sch)
{
	int found;
	int chp;
	int ccode;
	
	found = 0;
	for (chp = 0; chp <= 7; chp++)
		/*
		 * check if chpid is in information updated by ssd
		 */
		if (sch->ssd_info.valid &&
		    sch->ssd_info.chpid[chp] == chpid &&
		    (sch->ssd_info.fla[chp] & fla_mask) == fla) {
			found = 1;
			break;
		}
	
	if (found == 0)
		return 0;

	/*
	 * Do a stsch to update our subchannel structure with the
	 * new path information and eventually check for logically
	 * offline chpids.
	 */
	ccode = stsch(sch->irq, &sch->schib);
	if (ccode > 0)
		return 0;

	return 0x80 >> chp;
}

static int
s390_process_res_acc (u8 chpid, __u16 fla, u32 fla_mask)
{
	struct subchannel *sch;
	int irq, rc;
	char dbf_txt[15];

	sprintf(dbf_txt, "accpr%x", chpid);
	CIO_TRACE_EVENT( 2, dbf_txt);
	if (fla != 0) {
		sprintf(dbf_txt, "fla%x", fla);
		CIO_TRACE_EVENT( 2, dbf_txt);
	}

	/*
	 * I/O resources may have become accessible.
	 * Scan through all subchannels that may be concerned and
	 * do a validation on those.
	 * The more information we have (info), the less scanning
	 * will we have to do.
	 */

	if (!get_chp_status(chpid))
		return 0; /* no need to do the rest */

	rc = 0;
	for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) {
		int chp_mask, old_lpm;

		sch = get_subchannel_by_schid(irq);
		if (!sch) {
			struct schib schib;
			int ret;
			/*
			 * We don't know the device yet, but since a path
			 * may be available now to the device we'll have
			 * to do recognition again.
			 * Since we don't have any idea about which chpid
			 * that beast may be on we'll have to do a stsch
			 * on all devices, grr...
			 */
			if (stsch(irq, &schib)) {
				/* We're through */
				if (need_rescan)
					rc = -EAGAIN;
				break;
			}
			if (need_rescan) {
				rc = -EAGAIN;
				continue;
			}
			/* Put it on the slow path. */
			ret = css_enqueue_subchannel_slow(irq);
			if (ret) {
				css_clear_subchannel_slow_list();
				need_rescan = 1;
			}
			rc = -EAGAIN;
			continue;
		}
	
		spin_lock_irq(&sch->lock);

		chp_mask = s390_process_res_acc_sch(chpid, fla, fla_mask, sch);

		if (chp_mask == 0) {

			spin_unlock_irq(&sch->lock);

			if (fla_mask != 0)
				break;
			else
				continue;
		}
		old_lpm = sch->lpm;
		sch->lpm = ((sch->schib.pmcw.pim &
			     sch->schib.pmcw.pam &
			     sch->schib.pmcw.pom)
			    | chp_mask) & sch->opm;
		if (!old_lpm && sch->lpm)
			device_trigger_reprobe(sch);
		else if (sch->driver && sch->driver->verify)
			sch->driver->verify(&sch->dev);

		spin_unlock_irq(&sch->lock);
		put_device(&sch->dev);
		if (fla_mask != 0)
			break;
	}
	return rc;
}

static int
__get_chpid_from_lir(void *data)
{
	struct lir {
		u8  iq;
		u8  ic;
		u16 sci;
		/* incident-node descriptor */
		u32 indesc[28];
		/* attached-node descriptor */
		u32 andesc[28];
		/* incident-specific information */
		u32 isinfo[28];
	} *lir;

	lir = (struct lir*) data;
	if (!(lir->iq&0x80))
		/* NULL link incident record */
		return -EINVAL;
	if (!(lir->indesc[0]&0xc0000000))
		/* node descriptor not valid */
		return -EINVAL;
	if (!(lir->indesc[0]&0x10000000))
		/* don't handle device-type nodes - FIXME */
		return -EINVAL;
	/* Byte 3 contains the chpid. Could also be CTCA, but we don't care */

	return (u16) (lir->indesc[0]&0x000000ff);
}

int
chsc_process_crw(void)
{
	int chpid, ret;
	struct {
		struct chsc_header request;
		u32 reserved1;
		u32 reserved2;
		u32 reserved3;
		struct chsc_header response;
		u32 reserved4;
		u8  flags;
		u8  vf;		/* validity flags */
		u8  rs;		/* reporting source */
		u8  cc;		/* content code */
		u16 fla;	/* full link address */
		u16 rsid;	/* reporting source id */
		u32 reserved5;
		u32 reserved6;
		u32 ccdf[96];	/* content-code dependent field */
		/* ccdf has to be big enough for a link-incident record */
	} *sei_area;

	if (!sei_page)
		return 0;
	/*
	 * build the chsc request block for store event information
	 * and do the call
	 * This function is only called by the machine check handler thread,
	 * so we don't need locking for the sei_page.
	 */
	sei_area = sei_page;

	CIO_TRACE_EVENT( 2, "prcss");
	ret = 0;
	do {
		int ccode, status;
		memset(sei_area, 0, sizeof(*sei_area));

		sei_area->request = (struct chsc_header) {
			.length = 0x0010,
			.code   = 0x000e,
		};

		ccode = chsc(sei_area);
		if (ccode > 0)
			return 0;

		switch (sei_area->response.code) {
			/* for debug purposes, check for problems */
		case 0x0001:
			CIO_CRW_EVENT(4, "chsc_process_crw: event information "
					"successfully stored\n");
			break; /* everything ok */
		case 0x0002:
			CIO_CRW_EVENT(2,
				      "chsc_process_crw: invalid command!\n");
			return 0;
		case 0x0003:
			CIO_CRW_EVENT(2, "chsc_process_crw: error in chsc "
				      "request block!\n");
			return 0;
		case 0x0005:
			CIO_CRW_EVENT(2, "chsc_process_crw: no event "
				      "information stored\n");
			return 0;
		default:
			CIO_CRW_EVENT(2, "chsc_process_crw: chsc response %d\n",
				      sei_area->response.code);
			return 0;
		}

		/* Check if we might have lost some information. */
		if (sei_area->flags & 0x40)
			CIO_CRW_EVENT(2, "chsc_process_crw: Event information "
				       "has been lost due to overflow!\n");

		if (sei_area->rs != 4) {
			CIO_CRW_EVENT(2, "chsc_process_crw: reporting source "
				      "(%04X) isn't a chpid!\n",
				      sei_area->rsid);
			continue;
		}

		/* which kind of information was stored? */
		switch (sei_area->cc) {
		case 1: /* link incident*/
			CIO_CRW_EVENT(4, "chsc_process_crw: "
				      "channel subsystem reports link incident,"
				      " reporting source is chpid %x\n",
				      sei_area->rsid);
			chpid = __get_chpid_from_lir(sei_area->ccdf);
			if (chpid < 0)
				CIO_CRW_EVENT(4, "%s: Invalid LIR, skipping\n",
					      __FUNCTION__);
			else
				s390_set_chpid_offline(chpid);
			break;
			
		case 2: /* i/o resource accessibiliy */
			CIO_CRW_EVENT(4, "chsc_process_crw: "
				      "channel subsystem reports some I/O "
				      "devices may have become accessible\n");
			pr_debug("Data received after sei: \n");
			pr_debug("Validity flags: %x\n", sei_area->vf);
			
			/* allocate a new channel path structure, if needed */
			status = get_chp_status(sei_area->rsid);
			if (status < 0)
				new_channel_path(sei_area->rsid);
			else if (!status)
				return 0;
			if ((sei_area->vf & 0x80) == 0) {
				pr_debug("chpid: %x\n", sei_area->rsid);
				ret = s390_process_res_acc(sei_area->rsid,
							   0, 0);
			} else if ((sei_area->vf & 0xc0) == 0x80) {
				pr_debug("chpid: %x link addr: %x\n",
					 sei_area->rsid, sei_area->fla);
				ret = s390_process_res_acc(sei_area->rsid,
							   sei_area->fla,
							   0xff00);
			} else if ((sei_area->vf & 0xc0) == 0xc0) {
				pr_debug("chpid: %x full link addr: %x\n",
					 sei_area->rsid, sei_area->fla);
				ret = s390_process_res_acc(sei_area->rsid,
							   sei_area->fla,
							   0xffff);
			}
			pr_debug("\n");
			
			break;
			
		default: /* other stuff */
			CIO_CRW_EVENT(4, "chsc_process_crw: event %d\n",
				      sei_area->cc);
			break;
		}
	} while (sei_area->flags & 0x80);
	return ret;
}

static int
chp_add(int chpid)
{
	struct subchannel *sch;
	int irq, ret, rc;
	char dbf_txt[15];

	if (!get_chp_status(chpid))
		return 0; /* no need to do the rest */
	
	sprintf(dbf_txt, "cadd%x", chpid);
	CIO_TRACE_EVENT(2, dbf_txt);

	rc = 0;
	for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) {
		int i;

		sch = get_subchannel_by_schid(irq);
		if (!sch) {
			struct schib schib;

			if (stsch(irq, &schib)) {
				/* We're through */
				if (need_rescan)
					rc = -EAGAIN;
				break;
			}
			if (need_rescan) {
				rc = -EAGAIN;
				continue;
			}
			/* Put it on the slow path. */
			ret = css_enqueue_subchannel_slow(irq);
			if (ret) {
				css_clear_subchannel_slow_list();
				need_rescan = 1;
			}
			rc = -EAGAIN;
			continue;
		}
	
		spin_lock(&sch->lock);
		for (i=0; i<8; i++)
			if (sch->schib.pmcw.chpid[i] == chpid) {
				if (stsch(sch->irq, &sch->schib) != 0) {
					/* Endgame. */
					spin_unlock(&sch->lock);
					return rc;
				}
				break;
			}
		if (i==8) {
			spin_unlock(&sch->lock);
			return rc;
		}
		sch->lpm = ((sch->schib.pmcw.pim &
			     sch->schib.pmcw.pam &
			     sch->schib.pmcw.pom)
			    | 0x80 >> i) & sch->opm;

		if (sch->driver && sch->driver->verify)
			sch->driver->verify(&sch->dev);

		spin_unlock(&sch->lock);
		put_device(&sch->dev);
	}
	return rc;
}

/* 
 * Handling of crw machine checks with channel path source.
 */
int
chp_process_crw(int chpid, int on)
{
	if (on == 0) {
		/* Path has gone. We use the link incident routine.*/
		s390_set_chpid_offline(chpid);
		return 0; /* De-register is async anyway. */
	}
	/*
	 * Path has come. Allocate a new channel path structure,
	 * if needed.
	 */
	if (get_chp_status(chpid) < 0)
		new_channel_path(chpid);
	/* Avoid the extra overhead in process_rec_acc. */
	return chp_add(chpid);
}

static inline int
__check_for_io_and_kill(struct subchannel *sch, int index)
{
	int cc;

	if (!device_is_online(sch))
		/* cio could be doing I/O. */
		return 0;
	cc = stsch(sch->irq, &sch->schib);
	if (cc)
		return 0;
	if (sch->schib.scsw.actl && sch->schib.pmcw.lpum == (0x80 >> index)) {
		device_set_waiting(sch);
		return 1;
	}
	return 0;
}

static inline void
__s390_subchannel_vary_chpid(struct subchannel *sch, __u8 chpid, int on)
{
	int chp, old_lpm;
	unsigned long flags;

	if (!sch->ssd_info.valid)
		return;
	
	spin_lock_irqsave(&sch->lock, flags);
	old_lpm = sch->lpm;
	for (chp = 0; chp < 8; chp++) {
		if (sch->ssd_info.chpid[chp] != chpid)
			continue;

		if (on) {
			sch->opm |= (0x80 >> chp);
			sch->lpm |= (0x80 >> chp);
			if (!old_lpm)
				device_trigger_reprobe(sch);
			else if (sch->driver && sch->driver->verify)
				sch->driver->verify(&sch->dev);
		} else {
			sch->opm &= ~(0x80 >> chp);
			sch->lpm &= ~(0x80 >> chp);
			/*
			 * Give running I/O a grace period in which it
			 * can successfully terminate, even using the
			 * just varied off path. Then kill it.
			 */
			if (!__check_for_io_and_kill(sch, chp) && !sch->lpm) {
				if (css_enqueue_subchannel_slow(sch->irq)) {
					css_clear_subchannel_slow_list();
					need_rescan = 1;
				}
			} else if (sch->driver && sch->driver->verify)
				sch->driver->verify(&sch->dev);
		}
		break;
	}
	spin_unlock_irqrestore(&sch->lock, flags);
}

static int
s390_subchannel_vary_chpid_off(struct device *dev, void *data)
{
	struct subchannel *sch;
	__u8 *chpid;

	sch = to_subchannel(dev);
	chpid = data;

	__s390_subchannel_vary_chpid(sch, *chpid, 0);
	return 0;
}

static int
s390_subchannel_vary_chpid_on(struct device *dev, void *data)
{
	struct subchannel *sch;
	__u8 *chpid;

	sch = to_subchannel(dev);
	chpid = data;

	__s390_subchannel_vary_chpid(sch, *chpid, 1);
	return 0;
}

/*
 * Function: s390_vary_chpid
 * Varies the specified chpid online or offline
 */
static int
s390_vary_chpid( __u8 chpid, int on)
{
	char dbf_text[15];
	int status, irq, ret;
	struct subchannel *sch;

	sprintf(dbf_text, on?"varyon%x":"varyoff%x", chpid);
	CIO_TRACE_EVENT( 2, dbf_text);

	status = get_chp_status(chpid);
	if (status < 0) {
		printk(KERN_ERR "Can't vary unknown chpid %02X\n", chpid);
		return -EINVAL;
	}

	if (!on && !status) {
		printk(KERN_ERR "chpid %x is already offline\n", chpid);
		return -EINVAL;
	}

	set_chp_logically_online(chpid, on);

	/*
	 * Redo PathVerification on the devices the chpid connects to
	 */

	bus_for_each_dev(&css_bus_type, NULL, &chpid, on ?
			 s390_subchannel_vary_chpid_on :
			 s390_subchannel_vary_chpid_off);
	if (!on)
		goto out;
	/* Scan for new devices on varied on path. */
	for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) {
		struct schib schib;

		if (need_rescan)
			break;
		sch = get_subchannel_by_schid(irq);
		if (sch) {
			put_device(&sch->dev);
			continue;
		}
		if (stsch(irq, &schib))
			/* We're through */
			break;
		/* Put it on the slow path. */
		ret = css_enqueue_subchannel_slow(irq);
		if (ret) {
			css_clear_subchannel_slow_list();
			need_rescan = 1;
		}
	}
out:
	if (need_rescan || css_slow_subchannels_exist())
		queue_work(slow_path_wq, &slow_path_work);
	return 0;
}

/*
 * Files for the channel path entries.
 */
static ssize_t
chp_status_show(struct device *dev, char *buf)
{
	struct channel_path *chp = container_of(dev, struct channel_path, dev);

	if (!chp)
		return 0;
	return (get_chp_status(chp->id) ? sprintf(buf, "online\n") :
		sprintf(buf, "offline\n"));
}

static ssize_t
chp_status_write(struct device *dev, const char *buf, size_t count)
{
	struct channel_path *cp = container_of(dev, struct channel_path, dev);
	char cmd[10];
	int num_args;
	int error;

	num_args = sscanf(buf, "%5s", cmd);
	if (!num_args)
		return count;

	if (!strnicmp(cmd, "on", 2))
		error = s390_vary_chpid(cp->id, 1);
	else if (!strnicmp(cmd, "off", 3))
		error = s390_vary_chpid(cp->id, 0);
	else
		error = -EINVAL;

	return error < 0 ? error : count;

}

static DEVICE_ATTR(status, 0644, chp_status_show, chp_status_write);

static ssize_t
chp_type_show(struct device *dev, char *buf)
{
	struct channel_path *chp = container_of(dev, struct channel_path, dev);

	if (!chp)
		return 0;
	return sprintf(buf, "%x\n", chp->desc.desc);
}

static DEVICE_ATTR(type, 0444, chp_type_show, NULL);

static struct attribute * chp_attrs[] = {
	&dev_attr_status.attr,
	&dev_attr_type.attr,
	NULL,
};

static struct attribute_group chp_attr_group = {
	.attrs = chp_attrs,
};

static void
chp_release(struct device *dev)
{
	struct channel_path *cp;
	
	cp = container_of(dev, struct channel_path, dev);
	kfree(cp);
}

static int
chsc_determine_channel_path_description(int chpid,
					struct channel_path_desc *desc)
{
	int ccode, ret;

	struct {
		struct chsc_header request;
		u32 : 24;
		u32 first_chpid : 8;
		u32 : 24;
		u32 last_chpid : 8;
		u32 zeroes1;
		struct chsc_header response;
		u32 zeroes2;
		struct channel_path_desc desc;
	} *scpd_area;

	scpd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
	if (!scpd_area)
		return -ENOMEM;

	scpd_area->request = (struct chsc_header) {
		.length = 0x0010,
		.code   = 0x0002,
	};

	scpd_area->first_chpid = chpid;
	scpd_area->last_chpid = chpid;

	ccode = chsc(scpd_area);
	if (ccode > 0) {
		ret = (ccode == 3) ? -ENODEV : -EBUSY;
		goto out;
	}

	switch (scpd_area->response.code) {
	case 0x0001: /* Success. */
		memcpy(desc, &scpd_area->desc,
		       sizeof(struct channel_path_desc));
		ret = 0;
		break;
	case 0x0003: /* Invalid block. */
	case 0x0007: /* Invalid format. */
	case 0x0008: /* Other invalid block. */
		CIO_CRW_EVENT(2, "Error in chsc request block!\n");
		ret = -EINVAL;
		break;
	case 0x0004: /* Command not provided in model. */
		CIO_CRW_EVENT(2, "Model does not provide scpd\n");
		ret = -EOPNOTSUPP;
		break;
	default:
		CIO_CRW_EVENT(2, "Unknown CHSC response %d\n",
			      scpd_area->response.code);
		ret = -EIO;
	}
out:
	free_page((unsigned long)scpd_area);
	return ret;
}

/*
 * Entries for chpids on the system bus.
 * This replaces /proc/chpids.
 */
static int
new_channel_path(int chpid)
{
	struct channel_path *chp;
	int ret;

	chp = kmalloc(sizeof(struct channel_path), GFP_KERNEL);
	if (!chp)
		return -ENOMEM;
	memset(chp, 0, sizeof(struct channel_path));

	/* fill in status, etc. */
	chp->id = chpid;
	chp->state = 1;
	chp->dev = (struct device) {
		.parent  = &css_bus_device,
		.release = chp_release,
	};
	snprintf(chp->dev.bus_id, BUS_ID_SIZE, "chp0.%x", chpid);

	/* Obtain channel path description and fill it in. */
	ret = chsc_determine_channel_path_description(chpid, &chp->desc);
	if (ret)
		goto out_free;

	/* make it known to the system */
	ret = device_register(&chp->dev);
	if (ret) {
		printk(KERN_WARNING "%s: could not register %02x\n",
		       __func__, chpid);
		goto out_free;
	}
	ret = sysfs_create_group(&chp->dev.kobj, &chp_attr_group);
	if (ret) {
		device_unregister(&chp->dev);
		goto out_free;
	} else
		chps[chpid] = chp;
	return ret;
out_free:
	kfree(chp);
	return ret;
}

void *
chsc_get_chp_desc(struct subchannel *sch, int chp_no)
{
	struct channel_path *chp;
	struct channel_path_desc *desc;

	chp = chps[sch->schib.pmcw.chpid[chp_no]];
	if (!chp)
		return NULL;
	desc = kmalloc(sizeof(struct channel_path_desc), GFP_KERNEL);
	if (!desc)
		return NULL;
	memcpy(desc, &chp->desc, sizeof(struct channel_path_desc));
	return desc;
}


static int __init
chsc_alloc_sei_area(void)
{
	sei_page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
	if (!sei_page)
		printk(KERN_WARNING"Can't allocate page for processing of " \
		       "chsc machine checks!\n");
	return (sei_page ? 0 : -ENOMEM);
}

subsys_initcall(chsc_alloc_sei_area);

struct css_general_char css_general_characteristics;
struct css_chsc_char css_chsc_characteristics;

int __init
chsc_determine_css_characteristics(void)
{
	int result;
	struct {
		struct chsc_header request;
		u32 reserved1;
		u32 reserved2;
		u32 reserved3;
		struct chsc_header response;
		u32 reserved4;
		u32 general_char[510];
		u32 chsc_char[518];
	} *scsc_area;

	scsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
	if (!scsc_area) {
	        printk(KERN_WARNING"cio: Was not able to determine available" \
		       "CHSCs due to no memory.\n");
		return -ENOMEM;
	}

	scsc_area->request = (struct chsc_header) {
		.length = 0x0010,
		.code   = 0x0010,
	};

	result = chsc(scsc_area);
	if (result) {
		printk(KERN_WARNING"cio: Was not able to determine " \
		       "available CHSCs, cc=%i.\n", result);
		result = -EIO;
		goto exit;
	}

	if (scsc_area->response.code != 1) {
		printk(KERN_WARNING"cio: Was not able to determine " \
		       "available CHSCs.\n");
		result = -EIO;
		goto exit;
	}
	memcpy(&css_general_characteristics, scsc_area->general_char,
	       sizeof(css_general_characteristics));
	memcpy(&css_chsc_characteristics, scsc_area->chsc_char,
	       sizeof(css_chsc_characteristics));
exit:
	free_page ((unsigned long) scsc_area);
	return result;
}

EXPORT_SYMBOL_GPL(css_general_characteristics);
EXPORT_SYMBOL_GPL(css_chsc_characteristics);
