// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright IBM Corp. 2001, 2009
 * Author(s):
 *	Original CTC driver(s):
 *		Fritz Elfert (felfert@millenux.com)
 *		Dieter Wellerdiek (wel@de.ibm.com)
 *		Martin Schwidefsky (schwidefsky@de.ibm.com)
 *		Denis Joseph Barrow (barrow_dj@yahoo.com)
 *		Jochen Roehrig (roehrig@de.ibm.com)
 *		Cornelia Huck <cornelia.huck@de.ibm.com>
 *	MPC additions:
 *		Belinda Thompson (belindat@us.ibm.com)
 *		Andy Richter (richtera@us.ibm.com)
 *	Revived by:
 *		Peter Tiedemann (ptiedem@de.ibm.com)
 */

#undef DEBUG
#undef DEBUGDATA
#undef DEBUGCCW

#define KMSG_COMPONENT "ctcm"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
#include <linux/bitops.h>

#include <linux/signal.h>
#include <linux/string.h>

#include <linux/ip.h>
#include <linux/if_arp.h>
#include <linux/tcp.h>
#include <linux/skbuff.h>
#include <linux/ctype.h>
#include <net/dst.h>

#include <linux/io.h>
#include <asm/ccwdev.h>
#include <asm/ccwgroup.h>
#include <linux/uaccess.h>

#include <asm/idals.h>

#include "ctcm_fsms.h"
#include "ctcm_main.h"

/* Some common global variables */

/*
 * The root device for ctcm group devices
 */
static struct device *ctcm_root_dev;

/*
 * Linked list of all detected channels.
 */
struct channel *channels;

/*
 * Unpack a just received skb and hand it over to
 * upper layers.
 *
 *  ch		The channel where this skb has been received.
 *  pskb	The received skb.
 */
void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb)
{
	struct net_device *dev = ch->netdev;
	struct ctcm_priv *priv = dev->ml_priv;
	__u16 len = *((__u16 *) pskb->data);

	skb_put(pskb, 2 + LL_HEADER_LENGTH);
	skb_pull(pskb, 2);
	pskb->dev = dev;
	pskb->ip_summed = CHECKSUM_UNNECESSARY;
	while (len > 0) {
		struct sk_buff *skb;
		int skblen;
		struct ll_header *header = (struct ll_header *)pskb->data;

		skb_pull(pskb, LL_HEADER_LENGTH);
		if ((ch->protocol == CTCM_PROTO_S390) &&
		    (header->type != ETH_P_IP)) {
			if (!(ch->logflags & LOG_FLAG_ILLEGALPKT)) {
				ch->logflags |= LOG_FLAG_ILLEGALPKT;
				/*
				 * Check packet type only if we stick strictly
				 * to S/390's protocol of OS390. This only
				 * supports IP. Otherwise allow any packet
				 * type.
				 */
				CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
					"%s(%s): Illegal packet type 0x%04x"
					" - dropping",
					CTCM_FUNTAIL, dev->name, header->type);
			}
			priv->stats.rx_dropped++;
			priv->stats.rx_frame_errors++;
			return;
		}
		pskb->protocol = cpu_to_be16(header->type);
		if ((header->length <= LL_HEADER_LENGTH) ||
		    (len <= LL_HEADER_LENGTH)) {
			if (!(ch->logflags & LOG_FLAG_ILLEGALSIZE)) {
				CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
					"%s(%s): Illegal packet size %d(%d,%d)"
					"- dropping",
					CTCM_FUNTAIL, dev->name,
					header->length, dev->mtu, len);
				ch->logflags |= LOG_FLAG_ILLEGALSIZE;
			}

			priv->stats.rx_dropped++;
			priv->stats.rx_length_errors++;
			return;
		}
		header->length -= LL_HEADER_LENGTH;
		len -= LL_HEADER_LENGTH;
		if ((header->length > skb_tailroom(pskb)) ||
		    (header->length > len)) {
			if (!(ch->logflags & LOG_FLAG_OVERRUN)) {
				CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
					"%s(%s): Packet size %d (overrun)"
					" - dropping", CTCM_FUNTAIL,
						dev->name, header->length);
				ch->logflags |= LOG_FLAG_OVERRUN;
			}

			priv->stats.rx_dropped++;
			priv->stats.rx_length_errors++;
			return;
		}
		skb_put(pskb, header->length);
		skb_reset_mac_header(pskb);
		len -= header->length;
		skb = dev_alloc_skb(pskb->len);
		if (!skb) {
			if (!(ch->logflags & LOG_FLAG_NOMEM)) {
				CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
					"%s(%s): MEMORY allocation error",
						CTCM_FUNTAIL, dev->name);
				ch->logflags |= LOG_FLAG_NOMEM;
			}
			priv->stats.rx_dropped++;
			return;
		}
		skb_copy_from_linear_data(pskb, skb_put(skb, pskb->len),
					  pskb->len);
		skb_reset_mac_header(skb);
		skb->dev = pskb->dev;
		skb->protocol = pskb->protocol;
		pskb->ip_summed = CHECKSUM_UNNECESSARY;
		skblen = skb->len;
		/*
		 * reset logflags
		 */
		ch->logflags = 0;
		priv->stats.rx_packets++;
		priv->stats.rx_bytes += skblen;
		netif_rx(skb);
		if (len > 0) {
			skb_pull(pskb, header->length);
			if (skb_tailroom(pskb) < LL_HEADER_LENGTH) {
				CTCM_DBF_DEV_NAME(TRACE, dev,
					"Overrun in ctcm_unpack_skb");
				ch->logflags |= LOG_FLAG_OVERRUN;
				return;
			}
			skb_put(pskb, LL_HEADER_LENGTH);
		}
	}
}

/*
 * Release a specific channel in the channel list.
 *
 *  ch		Pointer to channel struct to be released.
 */
static void channel_free(struct channel *ch)
{
	CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, "%s(%s)", CTCM_FUNTAIL, ch->id);
	ch->flags &= ~CHANNEL_FLAGS_INUSE;
	fsm_newstate(ch->fsm, CTC_STATE_IDLE);
}

/*
 * Remove a specific channel in the channel list.
 *
 *  ch		Pointer to channel struct to be released.
 */
static void channel_remove(struct channel *ch)
{
	struct channel **c = &channels;
	char chid[CTCM_ID_SIZE];
	int ok = 0;

	if (ch == NULL)
		return;
	else
		strscpy(chid, ch->id, sizeof(chid));

	channel_free(ch);
	while (*c) {
		if (*c == ch) {
			*c = ch->next;
			fsm_deltimer(&ch->timer);
			if (IS_MPC(ch))
				fsm_deltimer(&ch->sweep_timer);

			kfree_fsm(ch->fsm);
			clear_normalized_cda(&ch->ccw[4]);
			if (ch->trans_skb != NULL) {
				clear_normalized_cda(&ch->ccw[1]);
				dev_kfree_skb_any(ch->trans_skb);
			}
			if (IS_MPC(ch)) {
				tasklet_kill(&ch->ch_tasklet);
				tasklet_kill(&ch->ch_disc_tasklet);
				kfree(ch->discontact_th);
			}
			kfree(ch->ccw);
			kfree(ch->irb);
			kfree(ch);
			ok = 1;
			break;
		}
		c = &((*c)->next);
	}

	CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, "%s(%s) %s", CTCM_FUNTAIL,
			chid, ok ? "OK" : "failed");
}

/*
 * Get a specific channel from the channel list.
 *
 *  type	Type of channel we are interested in.
 *  id		Id of channel we are interested in.
 *  direction	Direction we want to use this channel for.
 *
 * returns Pointer to a channel or NULL if no matching channel available.
 */
static struct channel *channel_get(enum ctcm_channel_types type,
					char *id, int direction)
{
	struct channel *ch = channels;

	while (ch && (strncmp(ch->id, id, CTCM_ID_SIZE) || (ch->type != type)))
		ch = ch->next;
	if (!ch) {
		CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
				"%s(%d, %s, %d) not found in channel list\n",
				CTCM_FUNTAIL, type, id, direction);
	} else {
		if (ch->flags & CHANNEL_FLAGS_INUSE)
			ch = NULL;
		else {
			ch->flags |= CHANNEL_FLAGS_INUSE;
			ch->flags &= ~CHANNEL_FLAGS_RWMASK;
			ch->flags |= (direction == CTCM_WRITE)
			    ? CHANNEL_FLAGS_WRITE : CHANNEL_FLAGS_READ;
			fsm_newstate(ch->fsm, CTC_STATE_STOPPED);
		}
	}
	return ch;
}

static long ctcm_check_irb_error(struct ccw_device *cdev, struct irb *irb)
{
	if (!IS_ERR(irb))
		return 0;

	CTCM_DBF_TEXT_(ERROR, CTC_DBF_WARN,
			"irb error %ld on device %s\n",
				PTR_ERR(irb), dev_name(&cdev->dev));

	switch (PTR_ERR(irb)) {
	case -EIO:
		dev_err(&cdev->dev,
			"An I/O-error occurred on the CTCM device\n");
		break;
	case -ETIMEDOUT:
		dev_err(&cdev->dev,
			"An adapter hardware operation timed out\n");
		break;
	default:
		dev_err(&cdev->dev,
			"An error occurred on the adapter hardware\n");
	}
	return PTR_ERR(irb);
}


/*
 * Check sense of a unit check.
 *
 *  ch		The channel, the sense code belongs to.
 *  sense	The sense code to inspect.
 */
static void ccw_unit_check(struct channel *ch, __u8 sense)
{
	CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,
			"%s(%s): %02x",
				CTCM_FUNTAIL, ch->id, sense);

	if (sense & SNS0_INTERVENTION_REQ) {
		if (sense & 0x01) {
			if (ch->sense_rc != 0x01) {
				pr_notice(
					"%s: The communication peer has "
					"disconnected\n", ch->id);
				ch->sense_rc = 0x01;
			}
			fsm_event(ch->fsm, CTC_EVENT_UC_RCRESET, ch);
		} else {
			if (ch->sense_rc != SNS0_INTERVENTION_REQ) {
				pr_notice(
					"%s: The remote operating system is "
					"not available\n", ch->id);
				ch->sense_rc = SNS0_INTERVENTION_REQ;
			}
			fsm_event(ch->fsm, CTC_EVENT_UC_RSRESET, ch);
		}
	} else if (sense & SNS0_EQUIPMENT_CHECK) {
		if (sense & SNS0_BUS_OUT_CHECK) {
			if (ch->sense_rc != SNS0_BUS_OUT_CHECK) {
				CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
					"%s(%s): remote HW error %02x",
						CTCM_FUNTAIL, ch->id, sense);
				ch->sense_rc = SNS0_BUS_OUT_CHECK;
			}
			fsm_event(ch->fsm, CTC_EVENT_UC_HWFAIL, ch);
		} else {
			if (ch->sense_rc != SNS0_EQUIPMENT_CHECK) {
				CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
					"%s(%s): remote read parity error %02x",
						CTCM_FUNTAIL, ch->id, sense);
				ch->sense_rc = SNS0_EQUIPMENT_CHECK;
			}
			fsm_event(ch->fsm, CTC_EVENT_UC_RXPARITY, ch);
		}
	} else if (sense & SNS0_BUS_OUT_CHECK) {
		if (ch->sense_rc != SNS0_BUS_OUT_CHECK) {
			CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
				"%s(%s): BUS OUT error %02x",
					CTCM_FUNTAIL, ch->id, sense);
			ch->sense_rc = SNS0_BUS_OUT_CHECK;
		}
		if (sense & 0x04)	/* data-streaming timeout */
			fsm_event(ch->fsm, CTC_EVENT_UC_TXTIMEOUT, ch);
		else			/* Data-transfer parity error */
			fsm_event(ch->fsm, CTC_EVENT_UC_TXPARITY, ch);
	} else if (sense & SNS0_CMD_REJECT) {
		if (ch->sense_rc != SNS0_CMD_REJECT) {
			CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
				"%s(%s): Command rejected",
						CTCM_FUNTAIL, ch->id);
			ch->sense_rc = SNS0_CMD_REJECT;
		}
	} else if (sense == 0) {
		CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
			"%s(%s): Unit check ZERO",
					CTCM_FUNTAIL, ch->id);
		fsm_event(ch->fsm, CTC_EVENT_UC_ZERO, ch);
	} else {
		CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
			"%s(%s): Unit check code %02x unknown",
					CTCM_FUNTAIL, ch->id, sense);
		fsm_event(ch->fsm, CTC_EVENT_UC_UNKNOWN, ch);
	}
}

int ctcm_ch_alloc_buffer(struct channel *ch)
{
	clear_normalized_cda(&ch->ccw[1]);
	ch->trans_skb = __dev_alloc_skb(ch->max_bufsize, GFP_ATOMIC | GFP_DMA);
	if (ch->trans_skb == NULL) {
		CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
			"%s(%s): %s trans_skb allocation error",
			CTCM_FUNTAIL, ch->id,
			(CHANNEL_DIRECTION(ch->flags) == CTCM_READ) ?
				"RX" : "TX");
		return -ENOMEM;
	}

	ch->ccw[1].count = ch->max_bufsize;
	if (set_normalized_cda(&ch->ccw[1], ch->trans_skb->data)) {
		dev_kfree_skb(ch->trans_skb);
		ch->trans_skb = NULL;
		CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
			"%s(%s): %s set norm_cda failed",
			CTCM_FUNTAIL, ch->id,
			(CHANNEL_DIRECTION(ch->flags) == CTCM_READ) ?
				"RX" : "TX");
		return -ENOMEM;
	}

	ch->ccw[1].count = 0;
	ch->trans_skb_data = ch->trans_skb->data;
	ch->flags &= ~CHANNEL_FLAGS_BUFSIZE_CHANGED;
	return 0;
}

/*
 * Interface API for upper network layers
 */

/*
 * Open an interface.
 * Called from generic network layer when ifconfig up is run.
 *
 *  dev		Pointer to interface struct.
 *
 * returns 0 on success, -ERRNO on failure. (Never fails.)
 */
int ctcm_open(struct net_device *dev)
{
	struct ctcm_priv *priv = dev->ml_priv;

	CTCMY_DBF_DEV_NAME(SETUP, dev, "");
	if (!IS_MPC(priv))
		fsm_event(priv->fsm,	DEV_EVENT_START, dev);
	return 0;
}

/*
 * Close an interface.
 * Called from generic network layer when ifconfig down is run.
 *
 *  dev		Pointer to interface struct.
 *
 * returns 0 on success, -ERRNO on failure. (Never fails.)
 */
int ctcm_close(struct net_device *dev)
{
	struct ctcm_priv *priv = dev->ml_priv;

	CTCMY_DBF_DEV_NAME(SETUP, dev, "");
	if (!IS_MPC(priv))
		fsm_event(priv->fsm, DEV_EVENT_STOP, dev);
	return 0;
}


/*
 * Transmit a packet.
 * This is a helper function for ctcm_tx().
 *
 *  ch		Channel to be used for sending.
 *  skb		Pointer to struct sk_buff of packet to send.
 *            The linklevel header has already been set up
 *            by ctcm_tx().
 *
 * returns 0 on success, -ERRNO on failure. (Never fails.)
 */
static int ctcm_transmit_skb(struct channel *ch, struct sk_buff *skb)
{
	unsigned long saveflags;
	struct ll_header header;
	int rc = 0;
	__u16 block_len;
	int ccw_idx;
	struct sk_buff *nskb;
	unsigned long hi;

	/* we need to acquire the lock for testing the state
	 * otherwise we can have an IRQ changing the state to
	 * TXIDLE after the test but before acquiring the lock.
	 */
	spin_lock_irqsave(&ch->collect_lock, saveflags);
	if (fsm_getstate(ch->fsm) != CTC_STATE_TXIDLE) {
		int l = skb->len + LL_HEADER_LENGTH;

		if (ch->collect_len + l > ch->max_bufsize - 2) {
			spin_unlock_irqrestore(&ch->collect_lock, saveflags);
			return -EBUSY;
		} else {
			refcount_inc(&skb->users);
			header.length = l;
			header.type = be16_to_cpu(skb->protocol);
			header.unused = 0;
			memcpy(skb_push(skb, LL_HEADER_LENGTH), &header,
			       LL_HEADER_LENGTH);
			skb_queue_tail(&ch->collect_queue, skb);
			ch->collect_len += l;
		}
		spin_unlock_irqrestore(&ch->collect_lock, saveflags);
		goto done;
	}
	spin_unlock_irqrestore(&ch->collect_lock, saveflags);
	/*
	 * Protect skb against beeing free'd by upper
	 * layers.
	 */
	refcount_inc(&skb->users);
	ch->prof.txlen += skb->len;
	header.length = skb->len + LL_HEADER_LENGTH;
	header.type = be16_to_cpu(skb->protocol);
	header.unused = 0;
	memcpy(skb_push(skb, LL_HEADER_LENGTH), &header, LL_HEADER_LENGTH);
	block_len = skb->len + 2;
	*((__u16 *)skb_push(skb, 2)) = block_len;

	/*
	 * IDAL support in CTCM is broken, so we have to
	 * care about skb's above 2G ourselves.
	 */
	hi = ((unsigned long)skb_tail_pointer(skb) + LL_HEADER_LENGTH) >> 31;
	if (hi) {
		nskb = alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
		if (!nskb) {
			refcount_dec(&skb->users);
			skb_pull(skb, LL_HEADER_LENGTH + 2);
			ctcm_clear_busy(ch->netdev);
			return -ENOMEM;
		} else {
			skb_put_data(nskb, skb->data, skb->len);
			refcount_inc(&nskb->users);
			refcount_dec(&skb->users);
			dev_kfree_skb_irq(skb);
			skb = nskb;
		}
	}

	ch->ccw[4].count = block_len;
	if (set_normalized_cda(&ch->ccw[4], skb->data)) {
		/*
		 * idal allocation failed, try via copying to
		 * trans_skb. trans_skb usually has a pre-allocated
		 * idal.
		 */
		if (ctcm_checkalloc_buffer(ch)) {
			/*
			 * Remove our header. It gets added
			 * again on retransmit.
			 */
			refcount_dec(&skb->users);
			skb_pull(skb, LL_HEADER_LENGTH + 2);
			ctcm_clear_busy(ch->netdev);
			return -ENOMEM;
		}

		skb_reset_tail_pointer(ch->trans_skb);
		ch->trans_skb->len = 0;
		ch->ccw[1].count = skb->len;
		skb_copy_from_linear_data(skb,
				skb_put(ch->trans_skb, skb->len), skb->len);
		refcount_dec(&skb->users);
		dev_kfree_skb_irq(skb);
		ccw_idx = 0;
	} else {
		skb_queue_tail(&ch->io_queue, skb);
		ccw_idx = 3;
	}
	if (do_debug_ccw)
		ctcmpc_dumpit((char *)&ch->ccw[ccw_idx],
					sizeof(struct ccw1) * 3);
	ch->retry = 0;
	fsm_newstate(ch->fsm, CTC_STATE_TX);
	fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);
	spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
	ch->prof.send_stamp = jiffies;
	rc = ccw_device_start(ch->cdev, &ch->ccw[ccw_idx], 0, 0xff, 0);
	spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
	if (ccw_idx == 3)
		ch->prof.doios_single++;
	if (rc != 0) {
		fsm_deltimer(&ch->timer);
		ctcm_ccw_check_rc(ch, rc, "single skb TX");
		if (ccw_idx == 3)
			skb_dequeue_tail(&ch->io_queue);
		/*
		 * Remove our header. It gets added
		 * again on retransmit.
		 */
		skb_pull(skb, LL_HEADER_LENGTH + 2);
	} else if (ccw_idx == 0) {
		struct net_device *dev = ch->netdev;
		struct ctcm_priv *priv = dev->ml_priv;
		priv->stats.tx_packets++;
		priv->stats.tx_bytes += skb->len - LL_HEADER_LENGTH;
	}
done:
	ctcm_clear_busy(ch->netdev);
	return rc;
}

static void ctcmpc_send_sweep_req(struct channel *rch)
{
	struct net_device *dev = rch->netdev;
	struct ctcm_priv *priv;
	struct mpc_group *grp;
	struct th_sweep *header;
	struct sk_buff *sweep_skb;
	struct channel *ch;
	/* int rc = 0; */

	priv = dev->ml_priv;
	grp = priv->mpcg;
	ch = priv->channel[CTCM_WRITE];

	/* sweep processing is not complete until response and request */
	/* has completed for all read channels in group		       */
	if (grp->in_sweep == 0) {
		grp->in_sweep = 1;
		grp->sweep_rsp_pend_num = grp->active_channels[CTCM_READ];
		grp->sweep_req_pend_num = grp->active_channels[CTCM_READ];
	}

	sweep_skb = __dev_alloc_skb(MPC_BUFSIZE_DEFAULT, GFP_ATOMIC|GFP_DMA);

	if (sweep_skb == NULL)	{
		/* rc = -ENOMEM; */
				goto nomem;
	}

	header = skb_put_zero(sweep_skb, TH_SWEEP_LENGTH);
	header->th.th_ch_flag	= TH_SWEEP_REQ;  /* 0x0f */
	header->sw.th_last_seq	= ch->th_seq_num;

	netif_trans_update(dev);
	skb_queue_tail(&ch->sweep_queue, sweep_skb);

	fsm_addtimer(&ch->sweep_timer, 100, CTC_EVENT_RSWEEP_TIMER, ch);

	return;

nomem:
	grp->in_sweep = 0;
	ctcm_clear_busy(dev);
	fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);

	return;
}

/*
 * MPC mode version of transmit_skb
 */
static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
{
	struct pdu *p_header;
	struct net_device *dev = ch->netdev;
	struct ctcm_priv *priv = dev->ml_priv;
	struct mpc_group *grp = priv->mpcg;
	struct th_header *header;
	struct sk_buff *nskb;
	int rc = 0;
	int ccw_idx;
	unsigned long hi;
	unsigned long saveflags = 0;	/* avoids compiler warning */

	CTCM_PR_DEBUG("Enter %s: %s, cp=%i ch=0x%p id=%s state=%s\n",
			__func__, dev->name, smp_processor_id(), ch,
					ch->id, fsm_getstate_str(ch->fsm));

	if ((fsm_getstate(ch->fsm) != CTC_STATE_TXIDLE) || grp->in_sweep) {
		spin_lock_irqsave(&ch->collect_lock, saveflags);
		refcount_inc(&skb->users);

		p_header = skb_push(skb, PDU_HEADER_LENGTH);
		p_header->pdu_offset = skb->len - PDU_HEADER_LENGTH;
		p_header->pdu_proto = 0x01;
		if (be16_to_cpu(skb->protocol) == ETH_P_SNAP) {
			p_header->pdu_flag = PDU_FIRST | PDU_CNTL;
		} else {
			p_header->pdu_flag = PDU_FIRST;
		}
		p_header->pdu_seq = 0;

		CTCM_PR_DEBUG("%s(%s): Put on collect_q - skb len: %04x \n"
				"pdu header and data for up to 32 bytes:\n",
				__func__, dev->name, skb->len);
		CTCM_D3_DUMP((char *)skb->data, min_t(int, 32, skb->len));

		skb_queue_tail(&ch->collect_queue, skb);
		ch->collect_len += skb->len;

		spin_unlock_irqrestore(&ch->collect_lock, saveflags);
		goto done;
	}

	/*
	 * Protect skb against beeing free'd by upper
	 * layers.
	 */
	refcount_inc(&skb->users);

	/*
	 * IDAL support in CTCM is broken, so we have to
	 * care about skb's above 2G ourselves.
	 */
	hi = ((unsigned long)skb->tail + TH_HEADER_LENGTH) >> 31;
	if (hi) {
		nskb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
		if (!nskb) {
			goto nomem_exit;
		} else {
			skb_put_data(nskb, skb->data, skb->len);
			refcount_inc(&nskb->users);
			refcount_dec(&skb->users);
			dev_kfree_skb_irq(skb);
			skb = nskb;
		}
	}

	p_header = skb_push(skb, PDU_HEADER_LENGTH);
	p_header->pdu_offset = skb->len - PDU_HEADER_LENGTH;
	p_header->pdu_proto = 0x01;
	p_header->pdu_seq = 0;
	if (be16_to_cpu(skb->protocol) == ETH_P_SNAP) {
		p_header->pdu_flag = PDU_FIRST | PDU_CNTL;
	} else {
		p_header->pdu_flag = PDU_FIRST;
	}

	if (ch->collect_len > 0) {
		spin_lock_irqsave(&ch->collect_lock, saveflags);
		skb_queue_tail(&ch->collect_queue, skb);
		ch->collect_len += skb->len;
		skb = skb_dequeue(&ch->collect_queue);
		ch->collect_len -= skb->len;
		spin_unlock_irqrestore(&ch->collect_lock, saveflags);
	}

	p_header = (struct pdu *)skb->data;
	p_header->pdu_flag |= PDU_LAST;

	ch->prof.txlen += skb->len - PDU_HEADER_LENGTH;

	/* put the TH on the packet */
	header = skb_push(skb, TH_HEADER_LENGTH);
	memset(header, 0, TH_HEADER_LENGTH);

	header->th_ch_flag = TH_HAS_PDU;  /* Normal data */
	ch->th_seq_num++;
	header->th_seq_num = ch->th_seq_num;

	CTCM_PR_DBGDATA("%s(%s) ToVTAM_th_seq= %08x\n" ,
		       __func__, dev->name, ch->th_seq_num);

	CTCM_PR_DBGDATA("%s(%s): skb len: %04x\n - pdu header and data for "
			"up to 32 bytes sent to vtam:\n",
				__func__, dev->name, skb->len);
	CTCM_D3_DUMP((char *)skb->data, min_t(int, 32, skb->len));

	ch->ccw[4].count = skb->len;
	if (set_normalized_cda(&ch->ccw[4], skb->data)) {
		/*
		 * idal allocation failed, try via copying to trans_skb.
		 * trans_skb usually has a pre-allocated idal.
		 */
		if (ctcm_checkalloc_buffer(ch)) {
			/*
			 * Remove our header.
			 * It gets added again on retransmit.
			 */
				goto nomem_exit;
		}

		skb_reset_tail_pointer(ch->trans_skb);
		ch->trans_skb->len = 0;
		ch->ccw[1].count = skb->len;
		skb_put_data(ch->trans_skb, skb->data, skb->len);
		refcount_dec(&skb->users);
		dev_kfree_skb_irq(skb);
		ccw_idx = 0;
		CTCM_PR_DBGDATA("%s(%s): trans_skb len: %04x\n"
				"up to 32 bytes sent to vtam:\n",
				__func__, dev->name, ch->trans_skb->len);
		CTCM_D3_DUMP((char *)ch->trans_skb->data,
				min_t(int, 32, ch->trans_skb->len));
	} else {
		skb_queue_tail(&ch->io_queue, skb);
		ccw_idx = 3;
	}
	ch->retry = 0;
	fsm_newstate(ch->fsm, CTC_STATE_TX);
	fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);

	if (do_debug_ccw)
		ctcmpc_dumpit((char *)&ch->ccw[ccw_idx],
					sizeof(struct ccw1) * 3);

	spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
	ch->prof.send_stamp = jiffies;
	rc = ccw_device_start(ch->cdev, &ch->ccw[ccw_idx], 0, 0xff, 0);
	spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
	if (ccw_idx == 3)
		ch->prof.doios_single++;
	if (rc != 0) {
		fsm_deltimer(&ch->timer);
		ctcm_ccw_check_rc(ch, rc, "single skb TX");
		if (ccw_idx == 3)
			skb_dequeue_tail(&ch->io_queue);
	} else if (ccw_idx == 0) {
		priv->stats.tx_packets++;
		priv->stats.tx_bytes += skb->len - TH_HEADER_LENGTH;
	}
	if (ch->th_seq_num > 0xf0000000)	/* Chose at random. */
		ctcmpc_send_sweep_req(ch);

	goto done;
nomem_exit:
	CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_CRIT,
			"%s(%s): MEMORY allocation ERROR\n",
			CTCM_FUNTAIL, ch->id);
	rc = -ENOMEM;
	refcount_dec(&skb->users);
	dev_kfree_skb_any(skb);
	fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
done:
	CTCM_PR_DEBUG("Exit %s(%s)\n", __func__, dev->name);
	return rc;
}

/*
 * Start transmission of a packet.
 * Called from generic network device layer.
 */
/* first merge version - leaving both functions separated */
static netdev_tx_t ctcm_tx(struct sk_buff *skb, struct net_device *dev)
{
	struct ctcm_priv *priv = dev->ml_priv;

	if (skb == NULL) {
		CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
				"%s(%s): NULL sk_buff passed",
					CTCM_FUNTAIL, dev->name);
		priv->stats.tx_dropped++;
		return NETDEV_TX_OK;
	}
	if (skb_headroom(skb) < (LL_HEADER_LENGTH + 2)) {
		CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
			"%s(%s): Got sk_buff with head room < %ld bytes",
			CTCM_FUNTAIL, dev->name, LL_HEADER_LENGTH + 2);
		dev_kfree_skb(skb);
		priv->stats.tx_dropped++;
		return NETDEV_TX_OK;
	}

	/*
	 * If channels are not running, try to restart them
	 * and throw away packet.
	 */
	if (fsm_getstate(priv->fsm) != DEV_STATE_RUNNING) {
		fsm_event(priv->fsm, DEV_EVENT_START, dev);
		dev_kfree_skb(skb);
		priv->stats.tx_dropped++;
		priv->stats.tx_errors++;
		priv->stats.tx_carrier_errors++;
		return NETDEV_TX_OK;
	}

	if (ctcm_test_and_set_busy(dev))
		return NETDEV_TX_BUSY;

	netif_trans_update(dev);
	if (ctcm_transmit_skb(priv->channel[CTCM_WRITE], skb) != 0)
		return NETDEV_TX_BUSY;
	return NETDEV_TX_OK;
}

/* unmerged MPC variant of ctcm_tx */
static netdev_tx_t ctcmpc_tx(struct sk_buff *skb, struct net_device *dev)
{
	int len = 0;
	struct ctcm_priv *priv = dev->ml_priv;
	struct mpc_group *grp  = priv->mpcg;
	struct sk_buff *newskb = NULL;

	/*
	 * Some sanity checks ...
	 */
	if (skb == NULL) {
		CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
			"%s(%s): NULL sk_buff passed",
					CTCM_FUNTAIL, dev->name);
		priv->stats.tx_dropped++;
		goto done;
	}
	if (skb_headroom(skb) < (TH_HEADER_LENGTH + PDU_HEADER_LENGTH)) {
		CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_ERROR,
			"%s(%s): Got sk_buff with head room < %ld bytes",
			CTCM_FUNTAIL, dev->name,
				TH_HEADER_LENGTH + PDU_HEADER_LENGTH);

		CTCM_D3_DUMP((char *)skb->data, min_t(int, 32, skb->len));

		len =  skb->len + TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
		newskb = __dev_alloc_skb(len, GFP_ATOMIC | GFP_DMA);

		if (!newskb) {
			CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_ERROR,
				"%s: %s: __dev_alloc_skb failed",
						__func__, dev->name);

			dev_kfree_skb_any(skb);
			priv->stats.tx_dropped++;
			priv->stats.tx_errors++;
			priv->stats.tx_carrier_errors++;
			fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
			goto done;
		}
		newskb->protocol = skb->protocol;
		skb_reserve(newskb, TH_HEADER_LENGTH + PDU_HEADER_LENGTH);
		skb_put_data(newskb, skb->data, skb->len);
		dev_kfree_skb_any(skb);
		skb = newskb;
	}

	/*
	 * If channels are not running,
	 * notify anybody about a link failure and throw
	 * away packet.
	 */
	if ((fsm_getstate(priv->fsm) != DEV_STATE_RUNNING) ||
	   (fsm_getstate(grp->fsm) <  MPCG_STATE_XID2INITW)) {
		dev_kfree_skb_any(skb);
		CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
			"%s(%s): inactive MPCGROUP - dropped",
					CTCM_FUNTAIL, dev->name);
		priv->stats.tx_dropped++;
		priv->stats.tx_errors++;
		priv->stats.tx_carrier_errors++;
		goto done;
	}

	if (ctcm_test_and_set_busy(dev)) {
		CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
			"%s(%s): device busy - dropped",
					CTCM_FUNTAIL, dev->name);
		dev_kfree_skb_any(skb);
		priv->stats.tx_dropped++;
		priv->stats.tx_errors++;
		priv->stats.tx_carrier_errors++;
		fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
		goto done;
	}

	netif_trans_update(dev);
	if (ctcmpc_transmit_skb(priv->channel[CTCM_WRITE], skb) != 0) {
		CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
			"%s(%s): device error - dropped",
					CTCM_FUNTAIL, dev->name);
		dev_kfree_skb_any(skb);
		priv->stats.tx_dropped++;
		priv->stats.tx_errors++;
		priv->stats.tx_carrier_errors++;
		ctcm_clear_busy(dev);
		fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
		goto done;
	}
	ctcm_clear_busy(dev);
done:
	if (do_debug)
		MPC_DBF_DEV_NAME(TRACE, dev, "exit");

	return NETDEV_TX_OK;	/* handle freeing of skb here */
}


/*
 * Sets MTU of an interface.
 *
 *  dev		Pointer to interface struct.
 *  new_mtu	The new MTU to use for this interface.
 *
 * returns 0 on success, -EINVAL if MTU is out of valid range.
 *         (valid range is 576 .. 65527). If VM is on the
 *         remote side, maximum MTU is 32760, however this is
 *         not checked here.
 */
static int ctcm_change_mtu(struct net_device *dev, int new_mtu)
{
	struct ctcm_priv *priv;
	int max_bufsize;

	priv = dev->ml_priv;
	max_bufsize = priv->channel[CTCM_READ]->max_bufsize;

	if (IS_MPC(priv)) {
		if (new_mtu > max_bufsize - TH_HEADER_LENGTH)
			return -EINVAL;
		dev->hard_header_len = TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
	} else {
		if (new_mtu > max_bufsize - LL_HEADER_LENGTH - 2)
			return -EINVAL;
		dev->hard_header_len = LL_HEADER_LENGTH + 2;
	}
	dev->mtu = new_mtu;
	return 0;
}

/*
 * Returns interface statistics of a device.
 *
 *  dev		Pointer to interface struct.
 *
 * returns Pointer to stats struct of this interface.
 */
static struct net_device_stats *ctcm_stats(struct net_device *dev)
{
	return &((struct ctcm_priv *)dev->ml_priv)->stats;
}

static void ctcm_free_netdevice(struct net_device *dev)
{
	struct ctcm_priv *priv;
	struct mpc_group *grp;

	CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
			"%s(%s)", CTCM_FUNTAIL, dev->name);
	priv = dev->ml_priv;
	if (priv) {
		grp = priv->mpcg;
		if (grp) {
			if (grp->fsm)
				kfree_fsm(grp->fsm);
			dev_kfree_skb(grp->xid_skb);
			dev_kfree_skb(grp->rcvd_xid_skb);
			tasklet_kill(&grp->mpc_tasklet2);
			kfree(grp);
			priv->mpcg = NULL;
		}
		if (priv->fsm) {
			kfree_fsm(priv->fsm);
			priv->fsm = NULL;
		}
		kfree(priv->xid);
		priv->xid = NULL;
	/*
	 * Note: kfree(priv); is done in "opposite" function of
	 * allocator function probe_device which is remove_device.
	 */
	}
#ifdef MODULE
	free_netdev(dev);
#endif
}

struct mpc_group *ctcmpc_init_mpc_group(struct ctcm_priv *priv);

static const struct net_device_ops ctcm_netdev_ops = {
	.ndo_open		= ctcm_open,
	.ndo_stop		= ctcm_close,
	.ndo_get_stats		= ctcm_stats,
	.ndo_change_mtu	   	= ctcm_change_mtu,
	.ndo_start_xmit		= ctcm_tx,
};

static const struct net_device_ops ctcm_mpc_netdev_ops = {
	.ndo_open		= ctcm_open,
	.ndo_stop		= ctcm_close,
	.ndo_get_stats		= ctcm_stats,
	.ndo_change_mtu	   	= ctcm_change_mtu,
	.ndo_start_xmit		= ctcmpc_tx,
};

static void ctcm_dev_setup(struct net_device *dev)
{
	dev->type = ARPHRD_SLIP;
	dev->tx_queue_len = 100;
	dev->flags = IFF_POINTOPOINT | IFF_NOARP;
	dev->min_mtu = 576;
	dev->max_mtu = 65527;
}

/*
 * Initialize everything of the net device except the name and the
 * channel structs.
 */
static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv)
{
	struct net_device *dev;
	struct mpc_group *grp;
	if (!priv)
		return NULL;

	if (IS_MPC(priv))
		dev = alloc_netdev(0, MPC_DEVICE_GENE, NET_NAME_UNKNOWN,
				   ctcm_dev_setup);
	else
		dev = alloc_netdev(0, CTC_DEVICE_GENE, NET_NAME_UNKNOWN,
				   ctcm_dev_setup);

	if (!dev) {
		CTCM_DBF_TEXT_(ERROR, CTC_DBF_CRIT,
			"%s: MEMORY allocation ERROR",
			CTCM_FUNTAIL);
		return NULL;
	}
	dev->ml_priv = priv;
	priv->fsm = init_fsm("ctcmdev", dev_state_names, dev_event_names,
				CTCM_NR_DEV_STATES, CTCM_NR_DEV_EVENTS,
				dev_fsm, dev_fsm_len, GFP_KERNEL);
	if (priv->fsm == NULL) {
		CTCMY_DBF_DEV(SETUP, dev, "init_fsm error");
		free_netdev(dev);
		return NULL;
	}
	fsm_newstate(priv->fsm, DEV_STATE_STOPPED);
	fsm_settimer(priv->fsm, &priv->restart_timer);

	if (IS_MPC(priv)) {
		/*  MPC Group Initializations  */
		grp = ctcmpc_init_mpc_group(priv);
		if (grp == NULL) {
			MPC_DBF_DEV(SETUP, dev, "init_mpc_group error");
			free_netdev(dev);
			return NULL;
		}
		tasklet_init(&grp->mpc_tasklet2,
				mpc_group_ready, (unsigned long)dev);
		dev->mtu = MPC_BUFSIZE_DEFAULT -
				TH_HEADER_LENGTH - PDU_HEADER_LENGTH;

		dev->netdev_ops = &ctcm_mpc_netdev_ops;
		dev->hard_header_len = TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
		priv->buffer_size = MPC_BUFSIZE_DEFAULT;
	} else {
		dev->mtu = CTCM_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2;
		dev->netdev_ops = &ctcm_netdev_ops;
		dev->hard_header_len = LL_HEADER_LENGTH + 2;
	}

	CTCMY_DBF_DEV(SETUP, dev, "finished");

	return dev;
}

/*
 * Main IRQ handler.
 *
 *  cdev	The ccw_device the interrupt is for.
 *  intparm	interruption parameter.
 *  irb		interruption response block.
 */
static void ctcm_irq_handler(struct ccw_device *cdev,
				unsigned long intparm, struct irb *irb)
{
	struct channel		*ch;
	struct net_device	*dev;
	struct ctcm_priv	*priv;
	struct ccwgroup_device	*cgdev;
	int cstat;
	int dstat;

	CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,
		"Enter %s(%s)", CTCM_FUNTAIL, dev_name(&cdev->dev));

	if (ctcm_check_irb_error(cdev, irb))
		return;

	cgdev = dev_get_drvdata(&cdev->dev);

	cstat = irb->scsw.cmd.cstat;
	dstat = irb->scsw.cmd.dstat;

	/* Check for unsolicited interrupts. */
	if (cgdev == NULL) {
		CTCM_DBF_TEXT_(TRACE, CTC_DBF_ERROR,
			"%s(%s) unsolicited irq: c-%02x d-%02x\n",
			CTCM_FUNTAIL, dev_name(&cdev->dev), cstat, dstat);
		dev_warn(&cdev->dev,
			"The adapter received a non-specific IRQ\n");
		return;
	}

	priv = dev_get_drvdata(&cgdev->dev);

	/* Try to extract channel from driver data. */
	if (priv->channel[CTCM_READ]->cdev == cdev)
		ch = priv->channel[CTCM_READ];
	else if (priv->channel[CTCM_WRITE]->cdev == cdev)
		ch = priv->channel[CTCM_WRITE];
	else {
		dev_err(&cdev->dev,
			"%s: Internal error: Can't determine channel for "
			"interrupt device %s\n",
			__func__, dev_name(&cdev->dev));
			/* Explain: inconsistent internal structures */
		return;
	}

	dev = ch->netdev;
	if (dev == NULL) {
		dev_err(&cdev->dev,
			"%s Internal error: net_device is NULL, ch = 0x%p\n",
			__func__, ch);
			/* Explain: inconsistent internal structures */
		return;
	}

	/* Copy interruption response block. */
	memcpy(ch->irb, irb, sizeof(struct irb));

	/* Issue error message and return on subchannel error code */
	if (irb->scsw.cmd.cstat) {
		fsm_event(ch->fsm, CTC_EVENT_SC_UNKNOWN, ch);
		CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
			"%s(%s): sub-ch check %s: cs=%02x ds=%02x",
				CTCM_FUNTAIL, dev->name, ch->id, cstat, dstat);
		dev_warn(&cdev->dev,
				"A check occurred on the subchannel\n");
		return;
	}

	/* Check the reason-code of a unit check */
	if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) {
		if ((irb->ecw[0] & ch->sense_rc) == 0)
			/* print it only once */
			CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
				"%s(%s): sense=%02x, ds=%02x",
				CTCM_FUNTAIL, ch->id, irb->ecw[0], dstat);
		ccw_unit_check(ch, irb->ecw[0]);
		return;
	}
	if (irb->scsw.cmd.dstat & DEV_STAT_BUSY) {
		if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION)
			fsm_event(ch->fsm, CTC_EVENT_ATTNBUSY, ch);
		else
			fsm_event(ch->fsm, CTC_EVENT_BUSY, ch);
		return;
	}
	if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) {
		fsm_event(ch->fsm, CTC_EVENT_ATTN, ch);
		return;
	}
	if ((irb->scsw.cmd.stctl & SCSW_STCTL_SEC_STATUS) ||
	    (irb->scsw.cmd.stctl == SCSW_STCTL_STATUS_PEND) ||
	    (irb->scsw.cmd.stctl ==
	     (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)))
		fsm_event(ch->fsm, CTC_EVENT_FINSTAT, ch);
	else
		fsm_event(ch->fsm, CTC_EVENT_IRQ, ch);

}

static const struct device_type ctcm_devtype = {
	.name = "ctcm",
	.groups = ctcm_attr_groups,
};

/*
 * Add ctcm specific attributes.
 * Add ctcm private data.
 *
 *  cgdev	pointer to ccwgroup_device just added
 *
 * returns 0 on success, !0 on failure.
 */
static int ctcm_probe_device(struct ccwgroup_device *cgdev)
{
	struct ctcm_priv *priv;

	CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
			"%s %p",
			__func__, cgdev);

	if (!get_device(&cgdev->dev))
		return -ENODEV;

	priv = kzalloc(sizeof(struct ctcm_priv), GFP_KERNEL);
	if (!priv) {
		CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
			"%s: memory allocation failure",
			CTCM_FUNTAIL);
		put_device(&cgdev->dev);
		return -ENOMEM;
	}
	priv->buffer_size = CTCM_BUFSIZE_DEFAULT;
	cgdev->cdev[0]->handler = ctcm_irq_handler;
	cgdev->cdev[1]->handler = ctcm_irq_handler;
	dev_set_drvdata(&cgdev->dev, priv);
	cgdev->dev.type = &ctcm_devtype;

	return 0;
}

/*
 * Add a new channel to the list of channels.
 * Keeps the channel list sorted.
 *
 *  cdev	The ccw_device to be added.
 *  type	The type class of the new channel.
 *  priv	Points to the private data of the ccwgroup_device.
 *
 * returns 0 on success, !0 on error.
 */
static int add_channel(struct ccw_device *cdev, enum ctcm_channel_types type,
				struct ctcm_priv *priv)
{
	struct channel **c = &channels;
	struct channel *ch;
	int ccw_num;
	int rc = 0;

	CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
		"%s(%s), type %d, proto %d",
			__func__, dev_name(&cdev->dev),	type, priv->protocol);

	ch = kzalloc(sizeof(struct channel), GFP_KERNEL);
	if (ch == NULL)
		return -ENOMEM;

	ch->protocol = priv->protocol;
	if (IS_MPC(priv)) {
		ch->discontact_th = kzalloc(TH_HEADER_LENGTH, GFP_KERNEL);
		if (ch->discontact_th == NULL)
					goto nomem_return;

		ch->discontact_th->th_blk_flag = TH_DISCONTACT;
		tasklet_init(&ch->ch_disc_tasklet,
			mpc_action_send_discontact, (unsigned long)ch);

		tasklet_init(&ch->ch_tasklet, ctcmpc_bh, (unsigned long)ch);
		ch->max_bufsize = (MPC_BUFSIZE_DEFAULT - 35);
		ccw_num = 17;
	} else
		ccw_num = 8;

	ch->ccw = kcalloc(ccw_num, sizeof(struct ccw1), GFP_KERNEL | GFP_DMA);
	if (ch->ccw == NULL)
					goto nomem_return;

	ch->cdev = cdev;
	scnprintf(ch->id, CTCM_ID_SIZE, "ch-%s", dev_name(&cdev->dev));
	ch->type = type;

	/*
	 * "static" ccws are used in the following way:
	 *
	 * ccw[0..2] (Channel program for generic I/O):
	 *           0: prepare
	 *           1: read or write (depending on direction) with fixed
	 *              buffer (idal allocated once when buffer is allocated)
	 *           2: nop
	 * ccw[3..5] (Channel program for direct write of packets)
	 *           3: prepare
	 *           4: write (idal allocated on every write).
	 *           5: nop
	 * ccw[6..7] (Channel program for initial channel setup):
	 *           6: set extended mode
	 *           7: nop
	 *
	 * ch->ccw[0..5] are initialized in ch_action_start because
	 * the channel's direction is yet unknown here.
	 *
	 * ccws used for xid2 negotiations
	 *  ch-ccw[8-14] need to be used for the XID exchange either
	 *    X side XID2 Processing
	 *       8:  write control
	 *       9:  write th
	 *	     10: write XID
	 *	     11: read th from secondary
	 *	     12: read XID   from secondary
	 *	     13: read 4 byte ID
	 *	     14: nop
	 *    Y side XID Processing
	 *	     8:  sense
	 *       9:  read th
	 *	     10: read XID
	 *	     11: write th
	 *	     12: write XID
	 *	     13: write 4 byte ID
	 *	     14: nop
	 *
	 *  ccws used for double noop due to VM timing issues
	 *  which result in unrecoverable Busy on channel
	 *       15: nop
	 *       16: nop
	 */
	ch->ccw[6].cmd_code	= CCW_CMD_SET_EXTENDED;
	ch->ccw[6].flags	= CCW_FLAG_SLI;

	ch->ccw[7].cmd_code	= CCW_CMD_NOOP;
	ch->ccw[7].flags	= CCW_FLAG_SLI;

	if (IS_MPC(priv)) {
		ch->ccw[15].cmd_code = CCW_CMD_WRITE;
		ch->ccw[15].flags    = CCW_FLAG_SLI | CCW_FLAG_CC;
		ch->ccw[15].count    = TH_HEADER_LENGTH;
		ch->ccw[15].cda      = virt_to_dma32(ch->discontact_th);

		ch->ccw[16].cmd_code = CCW_CMD_NOOP;
		ch->ccw[16].flags    = CCW_FLAG_SLI;

		ch->fsm = init_fsm(ch->id, ctc_ch_state_names,
				ctc_ch_event_names, CTC_MPC_NR_STATES,
				CTC_MPC_NR_EVENTS, ctcmpc_ch_fsm,
				mpc_ch_fsm_len, GFP_KERNEL);
	} else {
		ch->fsm = init_fsm(ch->id, ctc_ch_state_names,
				ctc_ch_event_names, CTC_NR_STATES,
				CTC_NR_EVENTS, ch_fsm,
				ch_fsm_len, GFP_KERNEL);
	}
	if (ch->fsm == NULL)
				goto nomem_return;

	fsm_newstate(ch->fsm, CTC_STATE_IDLE);

	ch->irb = kzalloc(sizeof(struct irb), GFP_KERNEL);
	if (ch->irb == NULL)
				goto nomem_return;

	while (*c && ctcm_less_than((*c)->id, ch->id))
		c = &(*c)->next;

	if (*c && (!strncmp((*c)->id, ch->id, CTCM_ID_SIZE))) {
		CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
				"%s (%s) already in list, using old entry",
				__func__, (*c)->id);

		goto free_return;
	}

	spin_lock_init(&ch->collect_lock);

	fsm_settimer(ch->fsm, &ch->timer);
	skb_queue_head_init(&ch->io_queue);
	skb_queue_head_init(&ch->collect_queue);

	if (IS_MPC(priv)) {
		fsm_settimer(ch->fsm, &ch->sweep_timer);
		skb_queue_head_init(&ch->sweep_queue);
	}
	ch->next = *c;
	*c = ch;
	return 0;

nomem_return:
	rc = -ENOMEM;

free_return:	/* note that all channel pointers are 0 or valid */
	kfree(ch->ccw);
	kfree(ch->discontact_th);
	kfree_fsm(ch->fsm);
	kfree(ch->irb);
	kfree(ch);
	return rc;
}

/*
 * Return type of a detected device.
 */
static enum ctcm_channel_types get_channel_type(struct ccw_device_id *id)
{
	enum ctcm_channel_types type;
	type = (enum ctcm_channel_types)id->driver_info;

	if (type == ctcm_channel_type_ficon)
		type = ctcm_channel_type_escon;

	return type;
}

/*
 *
 * Setup an interface.
 *
 *  cgdev	Device to be setup.
 *
 * returns 0 on success, !0 on failure.
 */
static int ctcm_new_device(struct ccwgroup_device *cgdev)
{
	char read_id[CTCM_ID_SIZE];
	char write_id[CTCM_ID_SIZE];
	int direction;
	enum ctcm_channel_types type;
	struct ctcm_priv *priv;
	struct net_device *dev;
	struct ccw_device *cdev0;
	struct ccw_device *cdev1;
	struct channel *readc;
	struct channel *writec;
	int ret;
	int result;

	priv = dev_get_drvdata(&cgdev->dev);
	if (!priv) {
		result = -ENODEV;
		goto out_err_result;
	}

	cdev0 = cgdev->cdev[0];
	cdev1 = cgdev->cdev[1];

	type = get_channel_type(&cdev0->id);

	scnprintf(read_id, CTCM_ID_SIZE, "ch-%s", dev_name(&cdev0->dev));
	scnprintf(write_id, CTCM_ID_SIZE, "ch-%s", dev_name(&cdev1->dev));

	ret = add_channel(cdev0, type, priv);
	if (ret) {
		result = ret;
		goto out_err_result;
	}
	ret = add_channel(cdev1, type, priv);
	if (ret) {
		result = ret;
		goto out_remove_channel1;
	}

	ret = ccw_device_set_online(cdev0);
	if (ret != 0) {
		CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
			"%s(%s) set_online rc=%d",
				CTCM_FUNTAIL, read_id, ret);
		result = -EIO;
		goto out_remove_channel2;
	}

	ret = ccw_device_set_online(cdev1);
	if (ret != 0) {
		CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
			"%s(%s) set_online rc=%d",
				CTCM_FUNTAIL, write_id, ret);

		result = -EIO;
		goto out_ccw1;
	}

	dev = ctcm_init_netdevice(priv);
	if (dev == NULL) {
		result = -ENODEV;
		goto out_ccw2;
	}

	for (direction = CTCM_READ; direction <= CTCM_WRITE; direction++) {
		priv->channel[direction] =
			channel_get(type, direction == CTCM_READ ?
				read_id : write_id, direction);
		if (priv->channel[direction] == NULL) {
			if (direction == CTCM_WRITE)
				channel_free(priv->channel[CTCM_READ]);
			result = -ENODEV;
			goto out_dev;
		}
		priv->channel[direction]->netdev = dev;
		priv->channel[direction]->protocol = priv->protocol;
		priv->channel[direction]->max_bufsize = priv->buffer_size;
	}
	/* sysfs magic */
	SET_NETDEV_DEV(dev, &cgdev->dev);

	if (register_netdev(dev)) {
		result = -ENODEV;
		goto out_dev;
	}

	strscpy(priv->fsm->name, dev->name, sizeof(priv->fsm->name));

	dev_info(&dev->dev,
		"setup OK : r/w = %s/%s, protocol : %d\n",
			priv->channel[CTCM_READ]->id,
			priv->channel[CTCM_WRITE]->id, priv->protocol);

	CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
		"setup(%s) OK : r/w = %s/%s, protocol : %d", dev->name,
			priv->channel[CTCM_READ]->id,
			priv->channel[CTCM_WRITE]->id, priv->protocol);

	return 0;
out_dev:
	ctcm_free_netdevice(dev);
out_ccw2:
	ccw_device_set_offline(cgdev->cdev[1]);
out_ccw1:
	ccw_device_set_offline(cgdev->cdev[0]);
out_remove_channel2:
	readc = channel_get(type, read_id, CTCM_READ);
	channel_remove(readc);
out_remove_channel1:
	writec = channel_get(type, write_id, CTCM_WRITE);
	channel_remove(writec);
out_err_result:
	return result;
}

/*
 * Shutdown an interface.
 *
 *  cgdev	Device to be shut down.
 *
 * returns 0 on success, !0 on failure.
 */
static int ctcm_shutdown_device(struct ccwgroup_device *cgdev)
{
	struct ctcm_priv *priv;
	struct net_device *dev;

	priv = dev_get_drvdata(&cgdev->dev);
	if (!priv)
		return -ENODEV;

	if (priv->channel[CTCM_READ]) {
		dev = priv->channel[CTCM_READ]->netdev;
		CTCM_DBF_DEV(SETUP, dev, "");
		/* Close the device */
		ctcm_close(dev);
		dev->flags &= ~IFF_RUNNING;
		channel_free(priv->channel[CTCM_READ]);
	} else
		dev = NULL;

	if (priv->channel[CTCM_WRITE])
		channel_free(priv->channel[CTCM_WRITE]);

	if (dev) {
		unregister_netdev(dev);
		ctcm_free_netdevice(dev);
	}

	if (priv->fsm)
		kfree_fsm(priv->fsm);

	ccw_device_set_offline(cgdev->cdev[1]);
	ccw_device_set_offline(cgdev->cdev[0]);
	channel_remove(priv->channel[CTCM_READ]);
	channel_remove(priv->channel[CTCM_WRITE]);
	priv->channel[CTCM_READ] = priv->channel[CTCM_WRITE] = NULL;

	return 0;

}


static void ctcm_remove_device(struct ccwgroup_device *cgdev)
{
	struct ctcm_priv *priv = dev_get_drvdata(&cgdev->dev);

	CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
			"removing device %p, proto : %d",
			cgdev, priv->protocol);

	if (cgdev->state == CCWGROUP_ONLINE)
		ctcm_shutdown_device(cgdev);
	dev_set_drvdata(&cgdev->dev, NULL);
	kfree(priv);
	put_device(&cgdev->dev);
}

static struct ccw_device_id ctcm_ids[] = {
	{CCW_DEVICE(0x3088, 0x08), .driver_info = ctcm_channel_type_parallel},
	{CCW_DEVICE(0x3088, 0x1e), .driver_info = ctcm_channel_type_ficon},
	{CCW_DEVICE(0x3088, 0x1f), .driver_info = ctcm_channel_type_escon},
	{},
};
MODULE_DEVICE_TABLE(ccw, ctcm_ids);

static struct ccw_driver ctcm_ccw_driver = {
	.driver = {
		.owner	= THIS_MODULE,
		.name	= "ctcm",
	},
	.ids	= ctcm_ids,
	.probe	= ccwgroup_probe_ccwdev,
	.remove	= ccwgroup_remove_ccwdev,
	.int_class = IRQIO_CTC,
};

static struct ccwgroup_driver ctcm_group_driver = {
	.driver = {
		.owner	= THIS_MODULE,
		.name	= CTC_DRIVER_NAME,
	},
	.ccw_driver  = &ctcm_ccw_driver,
	.setup	     = ctcm_probe_device,
	.remove      = ctcm_remove_device,
	.set_online  = ctcm_new_device,
	.set_offline = ctcm_shutdown_device,
};

static ssize_t group_store(struct device_driver *ddrv, const char *buf,
			   size_t count)
{
	int err;

	err = ccwgroup_create_dev(ctcm_root_dev, &ctcm_group_driver, 2, buf);
	return err ? err : count;
}
static DRIVER_ATTR_WO(group);

static struct attribute *ctcm_drv_attrs[] = {
	&driver_attr_group.attr,
	NULL,
};
static struct attribute_group ctcm_drv_attr_group = {
	.attrs = ctcm_drv_attrs,
};
static const struct attribute_group *ctcm_drv_attr_groups[] = {
	&ctcm_drv_attr_group,
	NULL,
};

/*
 * Module related routines
 */

/*
 * Prepare to be unloaded. Free IRQ's and release all resources.
 * This is called just before this module is unloaded. It is
 * not called, if the usage count is !0, so we don't need to check
 * for that.
 */
static void __exit ctcm_exit(void)
{
	ccwgroup_driver_unregister(&ctcm_group_driver);
	ccw_driver_unregister(&ctcm_ccw_driver);
	root_device_unregister(ctcm_root_dev);
	ctcm_unregister_dbf_views();
	pr_info("CTCM driver unloaded\n");
}

/*
 * Print Banner.
 */
static void print_banner(void)
{
	pr_info("CTCM driver initialized\n");
}

/*
 * Initialize module.
 * This is called just after the module is loaded.
 *
 * returns 0 on success, !0 on error.
 */
static int __init ctcm_init(void)
{
	int ret;

	channels = NULL;

	ret = ctcm_register_dbf_views();
	if (ret)
		goto out_err;
	ctcm_root_dev = root_device_register("ctcm");
	ret = PTR_ERR_OR_ZERO(ctcm_root_dev);
	if (ret)
		goto register_err;
	ret = ccw_driver_register(&ctcm_ccw_driver);
	if (ret)
		goto ccw_err;
	ctcm_group_driver.driver.groups = ctcm_drv_attr_groups;
	ret = ccwgroup_driver_register(&ctcm_group_driver);
	if (ret)
		goto ccwgroup_err;
	print_banner();
	return 0;

ccwgroup_err:
	ccw_driver_unregister(&ctcm_ccw_driver);
ccw_err:
	root_device_unregister(ctcm_root_dev);
register_err:
	ctcm_unregister_dbf_views();
out_err:
	pr_err("%s / Initializing the ctcm device driver failed, ret = %d\n",
		__func__, ret);
	return ret;
}

module_init(ctcm_init);
module_exit(ctcm_exit);

MODULE_AUTHOR("Peter Tiedemann <ptiedem@de.ibm.com>");
MODULE_DESCRIPTION("Network driver for S/390 CTC + CTCMPC (SNA)");
MODULE_LICENSE("GPL");

