brintos

brintos / linux-shallow public Read only

0
0
Text · 73.1 KiB · 9678c6a Raw
2286 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright IBM Corp. 2001, 20074 * Authors:	Fritz Elfert (felfert@millenux.com)5 * 		Peter Tiedemann (ptiedem@de.ibm.com)6 *	MPC additions :7 *		Belinda Thompson (belindat@us.ibm.com)8 *		Andy Richter (richtera@us.ibm.com)9 */10 11#undef DEBUG12#undef DEBUGDATA13#undef DEBUGCCW14 15#define KMSG_COMPONENT "ctcm"16#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt17 18#include <linux/module.h>19#include <linux/init.h>20#include <linux/kernel.h>21#include <linux/slab.h>22#include <linux/errno.h>23#include <linux/types.h>24#include <linux/interrupt.h>25#include <linux/timer.h>26#include <linux/bitops.h>27 28#include <linux/signal.h>29#include <linux/string.h>30 31#include <linux/ip.h>32#include <linux/if_arp.h>33#include <linux/tcp.h>34#include <linux/skbuff.h>35#include <linux/ctype.h>36#include <net/dst.h>37 38#include <linux/io.h>39#include <asm/ccwdev.h>40#include <asm/ccwgroup.h>41#include <linux/uaccess.h>42 43#include <asm/idals.h>44 45#include "fsm.h"46 47#include "ctcm_dbug.h"48#include "ctcm_main.h"49#include "ctcm_fsms.h"50 51const char *dev_state_names[] = {52	[DEV_STATE_STOPPED]		= "Stopped",53	[DEV_STATE_STARTWAIT_RXTX]	= "StartWait RXTX",54	[DEV_STATE_STARTWAIT_RX]	= "StartWait RX",55	[DEV_STATE_STARTWAIT_TX]	= "StartWait TX",56	[DEV_STATE_STOPWAIT_RXTX]	= "StopWait RXTX",57	[DEV_STATE_STOPWAIT_RX]		= "StopWait RX",58	[DEV_STATE_STOPWAIT_TX]		= "StopWait TX",59	[DEV_STATE_RUNNING]		= "Running",60};61 62const char *dev_event_names[] = {63	[DEV_EVENT_START]	= "Start",64	[DEV_EVENT_STOP]	= "Stop",65	[DEV_EVENT_RXUP]	= "RX up",66	[DEV_EVENT_TXUP]	= "TX up",67	[DEV_EVENT_RXDOWN]	= "RX down",68	[DEV_EVENT_TXDOWN]	= "TX down",69	[DEV_EVENT_RESTART]	= "Restart",70};71 72const char *ctc_ch_event_names[] = {73	[CTC_EVENT_IO_SUCCESS]	= "ccw_device success",74	[CTC_EVENT_IO_EBUSY]	= "ccw_device busy",75	[CTC_EVENT_IO_ENODEV]	= "ccw_device enodev",76	[CTC_EVENT_IO_UNKNOWN]	= "ccw_device unknown",77	[CTC_EVENT_ATTNBUSY]	= "Status ATTN & BUSY",78	[CTC_EVENT_ATTN]	= "Status ATTN",79	[CTC_EVENT_BUSY]	= "Status BUSY",80	[CTC_EVENT_UC_RCRESET]	= "Unit check remote reset",81	[CTC_EVENT_UC_RSRESET]	= "Unit check remote system reset",82	[CTC_EVENT_UC_TXTIMEOUT] = "Unit check TX timeout",83	[CTC_EVENT_UC_TXPARITY]	= "Unit check TX parity",84	[CTC_EVENT_UC_HWFAIL]	= "Unit check Hardware failure",85	[CTC_EVENT_UC_RXPARITY]	= "Unit check RX parity",86	[CTC_EVENT_UC_ZERO]	= "Unit check ZERO",87	[CTC_EVENT_UC_UNKNOWN]	= "Unit check Unknown",88	[CTC_EVENT_SC_UNKNOWN]	= "SubChannel check Unknown",89	[CTC_EVENT_MC_FAIL]	= "Machine check failure",90	[CTC_EVENT_MC_GOOD]	= "Machine check operational",91	[CTC_EVENT_IRQ]		= "IRQ normal",92	[CTC_EVENT_FINSTAT]	= "IRQ final",93	[CTC_EVENT_TIMER]	= "Timer",94	[CTC_EVENT_START]	= "Start",95	[CTC_EVENT_STOP]	= "Stop",96	/*97	* additional MPC events98	*/99	[CTC_EVENT_SEND_XID]	= "XID Exchange",100	[CTC_EVENT_RSWEEP_TIMER] = "MPC Group Sweep Timer",101};102 103const char *ctc_ch_state_names[] = {104	[CTC_STATE_IDLE]	= "Idle",105	[CTC_STATE_STOPPED]	= "Stopped",106	[CTC_STATE_STARTWAIT]	= "StartWait",107	[CTC_STATE_STARTRETRY]	= "StartRetry",108	[CTC_STATE_SETUPWAIT]	= "SetupWait",109	[CTC_STATE_RXINIT]	= "RX init",110	[CTC_STATE_TXINIT]	= "TX init",111	[CTC_STATE_RX]		= "RX",112	[CTC_STATE_TX]		= "TX",113	[CTC_STATE_RXIDLE]	= "RX idle",114	[CTC_STATE_TXIDLE]	= "TX idle",115	[CTC_STATE_RXERR]	= "RX error",116	[CTC_STATE_TXERR]	= "TX error",117	[CTC_STATE_TERM]	= "Terminating",118	[CTC_STATE_DTERM]	= "Restarting",119	[CTC_STATE_NOTOP]	= "Not operational",120	/*121	* additional MPC states122	*/123	[CH_XID0_PENDING]	= "Pending XID0 Start",124	[CH_XID0_INPROGRESS]	= "In XID0 Negotiations ",125	[CH_XID7_PENDING]	= "Pending XID7 P1 Start",126	[CH_XID7_PENDING1]	= "Active XID7 P1 Exchange ",127	[CH_XID7_PENDING2]	= "Pending XID7 P2 Start ",128	[CH_XID7_PENDING3]	= "Active XID7 P2 Exchange ",129	[CH_XID7_PENDING4]	= "XID7 Complete - Pending READY ",130};131 132static void ctcm_action_nop(fsm_instance *fi, int event, void *arg);133 134/*135 * ----- static ctcm actions for channel statemachine -----136 *137*/138static void chx_txdone(fsm_instance *fi, int event, void *arg);139static void chx_rx(fsm_instance *fi, int event, void *arg);140static void chx_rxidle(fsm_instance *fi, int event, void *arg);141static void chx_firstio(fsm_instance *fi, int event, void *arg);142static void ctcm_chx_setmode(fsm_instance *fi, int event, void *arg);143static void ctcm_chx_start(fsm_instance *fi, int event, void *arg);144static void ctcm_chx_haltio(fsm_instance *fi, int event, void *arg);145static void ctcm_chx_stopped(fsm_instance *fi, int event, void *arg);146static void ctcm_chx_stop(fsm_instance *fi, int event, void *arg);147static void ctcm_chx_fail(fsm_instance *fi, int event, void *arg);148static void ctcm_chx_setuperr(fsm_instance *fi, int event, void *arg);149static void ctcm_chx_restart(fsm_instance *fi, int event, void *arg);150static void ctcm_chx_rxiniterr(fsm_instance *fi, int event, void *arg);151static void ctcm_chx_rxinitfail(fsm_instance *fi, int event, void *arg);152static void ctcm_chx_rxdisc(fsm_instance *fi, int event, void *arg);153static void ctcm_chx_txiniterr(fsm_instance *fi, int event, void *arg);154static void ctcm_chx_txretry(fsm_instance *fi, int event, void *arg);155static void ctcm_chx_iofatal(fsm_instance *fi, int event, void *arg);156 157/*158 * ----- static ctcmpc actions for ctcmpc channel statemachine -----159 *160*/161static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg);162static void ctcmpc_chx_rx(fsm_instance *fi, int event, void *arg);163static void ctcmpc_chx_firstio(fsm_instance *fi, int event, void *arg);164/* shared :165static void ctcm_chx_setmode(fsm_instance *fi, int event, void *arg);166static void ctcm_chx_start(fsm_instance *fi, int event, void *arg);167static void ctcm_chx_haltio(fsm_instance *fi, int event, void *arg);168static void ctcm_chx_stopped(fsm_instance *fi, int event, void *arg);169static void ctcm_chx_stop(fsm_instance *fi, int event, void *arg);170static void ctcm_chx_fail(fsm_instance *fi, int event, void *arg);171static void ctcm_chx_setuperr(fsm_instance *fi, int event, void *arg);172static void ctcm_chx_restart(fsm_instance *fi, int event, void *arg);173static void ctcm_chx_rxiniterr(fsm_instance *fi, int event, void *arg);174static void ctcm_chx_rxinitfail(fsm_instance *fi, int event, void *arg);175static void ctcm_chx_rxdisc(fsm_instance *fi, int event, void *arg);176static void ctcm_chx_txiniterr(fsm_instance *fi, int event, void *arg);177static void ctcm_chx_txretry(fsm_instance *fi, int event, void *arg);178static void ctcm_chx_iofatal(fsm_instance *fi, int event, void *arg);179*/180static void ctcmpc_chx_attn(fsm_instance *fsm, int event, void *arg);181static void ctcmpc_chx_attnbusy(fsm_instance *, int, void *);182static void ctcmpc_chx_resend(fsm_instance *, int, void *);183static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg);184 185/*186 * Check return code of a preceding ccw_device call, halt_IO etc...187 *188 * ch	:	The channel, the error belongs to.189 * Returns the error code (!= 0) to inspect.190 */191void ctcm_ccw_check_rc(struct channel *ch, int rc, char *msg)192{193	CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,194		"%s(%s): %s: %04x\n",195		CTCM_FUNTAIL, ch->id, msg, rc);196	switch (rc) {197	case -EBUSY:198		pr_info("%s: The communication peer is busy\n",199			ch->id);200		fsm_event(ch->fsm, CTC_EVENT_IO_EBUSY, ch);201		break;202	case -ENODEV:203		pr_err("%s: The specified target device is not valid\n",204		       ch->id);205		fsm_event(ch->fsm, CTC_EVENT_IO_ENODEV, ch);206		break;207	default:208		pr_err("An I/O operation resulted in error %04x\n",209		       rc);210		fsm_event(ch->fsm, CTC_EVENT_IO_UNKNOWN, ch);211	}212}213 214void ctcm_purge_skb_queue(struct sk_buff_head *q)215{216	struct sk_buff *skb;217 218	CTCM_DBF_TEXT(TRACE, CTC_DBF_DEBUG, __func__);219 220	while ((skb = skb_dequeue(q))) {221		refcount_dec(&skb->users);222		dev_kfree_skb_any(skb);223	}224}225 226/*227 * NOP action for statemachines228 */229static void ctcm_action_nop(fsm_instance *fi, int event, void *arg)230{231}232 233/*234 * Actions for channel - statemachines.235 */236 237/*238 * Normal data has been send. Free the corresponding239 * skb (it's in io_queue), reset dev->tbusy and240 * revert to idle state.241 *242 * fi		An instance of a channel statemachine.243 * event	The event, just happened.244 * arg		Generic pointer, casted from channel * upon call.245 */246static void chx_txdone(fsm_instance *fi, int event, void *arg)247{248	struct channel *ch = arg;249	struct net_device *dev = ch->netdev;250	struct ctcm_priv *priv = dev->ml_priv;251	struct sk_buff *skb;252	int first = 1;253	int i;254	unsigned long duration;255	unsigned long done_stamp = jiffies;256 257	CTCM_PR_DEBUG("%s(%s): %s\n", __func__, ch->id, dev->name);258 259	duration = done_stamp - ch->prof.send_stamp;260	if (duration > ch->prof.tx_time)261		ch->prof.tx_time = duration;262 263	if (ch->irb->scsw.cmd.count != 0)264		CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,265			"%s(%s): TX not complete, remaining %d bytes",266			     CTCM_FUNTAIL, dev->name, ch->irb->scsw.cmd.count);267	fsm_deltimer(&ch->timer);268	while ((skb = skb_dequeue(&ch->io_queue))) {269		priv->stats.tx_packets++;270		priv->stats.tx_bytes += skb->len - LL_HEADER_LENGTH;271		if (first) {272			priv->stats.tx_bytes += 2;273			first = 0;274		}275		refcount_dec(&skb->users);276		dev_kfree_skb_irq(skb);277	}278	spin_lock(&ch->collect_lock);279	clear_normalized_cda(&ch->ccw[4]);280	if (ch->collect_len > 0) {281		int rc;282 283		if (ctcm_checkalloc_buffer(ch)) {284			spin_unlock(&ch->collect_lock);285			return;286		}287		ch->trans_skb->data = ch->trans_skb_data;288		skb_reset_tail_pointer(ch->trans_skb);289		ch->trans_skb->len = 0;290		if (ch->prof.maxmulti < (ch->collect_len + 2))291			ch->prof.maxmulti = ch->collect_len + 2;292		if (ch->prof.maxcqueue < skb_queue_len(&ch->collect_queue))293			ch->prof.maxcqueue = skb_queue_len(&ch->collect_queue);294		*((__u16 *)skb_put(ch->trans_skb, 2)) = ch->collect_len + 2;295		i = 0;296		while ((skb = skb_dequeue(&ch->collect_queue))) {297			skb_copy_from_linear_data(skb,298				skb_put(ch->trans_skb, skb->len), skb->len);299			priv->stats.tx_packets++;300			priv->stats.tx_bytes += skb->len - LL_HEADER_LENGTH;301			refcount_dec(&skb->users);302			dev_kfree_skb_irq(skb);303			i++;304		}305		ch->collect_len = 0;306		spin_unlock(&ch->collect_lock);307		ch->ccw[1].count = ch->trans_skb->len;308		fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);309		ch->prof.send_stamp = jiffies;310		rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);311		ch->prof.doios_multi++;312		if (rc != 0) {313			priv->stats.tx_dropped += i;314			priv->stats.tx_errors += i;315			fsm_deltimer(&ch->timer);316			ctcm_ccw_check_rc(ch, rc, "chained TX");317		}318	} else {319		spin_unlock(&ch->collect_lock);320		fsm_newstate(fi, CTC_STATE_TXIDLE);321	}322	ctcm_clear_busy_do(dev);323}324 325/*326 * Initial data is sent.327 * Notify device statemachine that we are up and328 * running.329 *330 * fi		An instance of a channel statemachine.331 * event	The event, just happened.332 * arg		Generic pointer, casted from channel * upon call.333 */334void ctcm_chx_txidle(fsm_instance *fi, int event, void *arg)335{336	struct channel *ch = arg;337	struct net_device *dev = ch->netdev;338	struct ctcm_priv *priv = dev->ml_priv;339 340	CTCM_PR_DEBUG("%s(%s): %s\n", __func__, ch->id, dev->name);341 342	fsm_deltimer(&ch->timer);343	fsm_newstate(fi, CTC_STATE_TXIDLE);344	fsm_event(priv->fsm, DEV_EVENT_TXUP, ch->netdev);345}346 347/*348 * Got normal data, check for sanity, queue it up, allocate new buffer349 * trigger bottom half, and initiate next read.350 *351 * fi		An instance of a channel statemachine.352 * event	The event, just happened.353 * arg		Generic pointer, casted from channel * upon call.354 */355static void chx_rx(fsm_instance *fi, int event, void *arg)356{357	struct channel *ch = arg;358	struct net_device *dev = ch->netdev;359	struct ctcm_priv *priv = dev->ml_priv;360	int len = ch->max_bufsize - ch->irb->scsw.cmd.count;361	struct sk_buff *skb = ch->trans_skb;362	__u16 block_len = *((__u16 *)skb->data);363	int check_len;364	int rc;365 366	fsm_deltimer(&ch->timer);367	if (len < 8) {368		CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,369			"%s(%s): got packet with length %d < 8\n",370					CTCM_FUNTAIL, dev->name, len);371		priv->stats.rx_dropped++;372		priv->stats.rx_length_errors++;373		goto again;374	}375	if (len > ch->max_bufsize) {376		CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,377			"%s(%s): got packet with length %d > %d\n",378				CTCM_FUNTAIL, dev->name, len, ch->max_bufsize);379		priv->stats.rx_dropped++;380		priv->stats.rx_length_errors++;381		goto again;382	}383 384	/*385	 * VM TCP seems to have a bug sending 2 trailing bytes of garbage.386	 */387	switch (ch->protocol) {388	case CTCM_PROTO_S390:389	case CTCM_PROTO_OS390:390		check_len = block_len + 2;391		break;392	default:393		check_len = block_len;394		break;395	}396	if ((len < block_len) || (len > check_len)) {397		CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,398			"%s(%s): got block length %d != rx length %d\n",399				CTCM_FUNTAIL, dev->name, block_len, len);400		if (do_debug)401			ctcmpc_dump_skb(skb, 0);402 403		*((__u16 *)skb->data) = len;404		priv->stats.rx_dropped++;405		priv->stats.rx_length_errors++;406		goto again;407	}408	if (block_len > 2) {409		*((__u16 *)skb->data) = block_len - 2;410		ctcm_unpack_skb(ch, skb);411	}412 again:413	skb->data = ch->trans_skb_data;414	skb_reset_tail_pointer(skb);415	skb->len = 0;416	if (ctcm_checkalloc_buffer(ch))417		return;418	ch->ccw[1].count = ch->max_bufsize;419	rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);420	if (rc != 0)421		ctcm_ccw_check_rc(ch, rc, "normal RX");422}423 424/*425 * Initialize connection by sending a __u16 of value 0.426 *427 * fi		An instance of a channel statemachine.428 * event	The event, just happened.429 * arg		Generic pointer, casted from channel * upon call.430 */431static void chx_firstio(fsm_instance *fi, int event, void *arg)432{433	int rc;434	struct channel *ch = arg;435	int fsmstate = fsm_getstate(fi);436 437	CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,438		"%s(%s) : %02x",439		CTCM_FUNTAIL, ch->id, fsmstate);440 441	ch->sense_rc = 0;	/* reset unit check report control */442	if (fsmstate == CTC_STATE_TXIDLE)443		CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,444			"%s(%s): remote side issued READ?, init.\n",445				CTCM_FUNTAIL, ch->id);446	fsm_deltimer(&ch->timer);447	if (ctcm_checkalloc_buffer(ch))448		return;449	if ((fsmstate == CTC_STATE_SETUPWAIT) &&450	    (ch->protocol == CTCM_PROTO_OS390)) {451		/* OS/390 resp. z/OS */452		if (CHANNEL_DIRECTION(ch->flags) == CTCM_READ) {453			*((__u16 *)ch->trans_skb->data) = CTCM_INITIAL_BLOCKLEN;454			fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC,455				     CTC_EVENT_TIMER, ch);456			chx_rxidle(fi, event, arg);457		} else {458			struct net_device *dev = ch->netdev;459			struct ctcm_priv *priv = dev->ml_priv;460			fsm_newstate(fi, CTC_STATE_TXIDLE);461			fsm_event(priv->fsm, DEV_EVENT_TXUP, dev);462		}463		return;464	}465	/*466	 * Don't setup a timer for receiving the initial RX frame467	 * if in compatibility mode, since VM TCP delays the initial468	 * frame until it has some data to send.469	 */470	if ((CHANNEL_DIRECTION(ch->flags) == CTCM_WRITE) ||471	    (ch->protocol != CTCM_PROTO_S390))472		fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);473 474	*((__u16 *)ch->trans_skb->data) = CTCM_INITIAL_BLOCKLEN;475	ch->ccw[1].count = 2;	/* Transfer only length */476 477	fsm_newstate(fi, (CHANNEL_DIRECTION(ch->flags) == CTCM_READ)478		     ? CTC_STATE_RXINIT : CTC_STATE_TXINIT);479	rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);480	if (rc != 0) {481		fsm_deltimer(&ch->timer);482		fsm_newstate(fi, CTC_STATE_SETUPWAIT);483		ctcm_ccw_check_rc(ch, rc, "init IO");484	}485	/*486	 * If in compatibility mode since we don't setup a timer, we487	 * also signal RX channel up immediately. This enables us488	 * to send packets early which in turn usually triggers some489	 * reply from VM TCP which brings up the RX channel to it's490	 * final state.491	 */492	if ((CHANNEL_DIRECTION(ch->flags) == CTCM_READ) &&493	    (ch->protocol == CTCM_PROTO_S390)) {494		struct net_device *dev = ch->netdev;495		struct ctcm_priv *priv = dev->ml_priv;496		fsm_event(priv->fsm, DEV_EVENT_RXUP, dev);497	}498}499 500/*501 * Got initial data, check it. If OK,502 * notify device statemachine that we are up and503 * running.504 *505 * fi		An instance of a channel statemachine.506 * event	The event, just happened.507 * arg		Generic pointer, casted from channel * upon call.508 */509static void chx_rxidle(fsm_instance *fi, int event, void *arg)510{511	struct channel *ch = arg;512	struct net_device *dev = ch->netdev;513	struct ctcm_priv *priv = dev->ml_priv;514	__u16 buflen;515	int rc;516 517	fsm_deltimer(&ch->timer);518	buflen = *((__u16 *)ch->trans_skb->data);519	CTCM_PR_DEBUG("%s: %s: Initial RX count = %d\n",520			__func__, dev->name, buflen);521 522	if (buflen >= CTCM_INITIAL_BLOCKLEN) {523		if (ctcm_checkalloc_buffer(ch))524			return;525		ch->ccw[1].count = ch->max_bufsize;526		fsm_newstate(fi, CTC_STATE_RXIDLE);527		rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);528		if (rc != 0) {529			fsm_newstate(fi, CTC_STATE_RXINIT);530			ctcm_ccw_check_rc(ch, rc, "initial RX");531		} else532			fsm_event(priv->fsm, DEV_EVENT_RXUP, dev);533	} else {534		CTCM_PR_DEBUG("%s: %s: Initial RX count %d not %d\n",535				__func__, dev->name,536					buflen, CTCM_INITIAL_BLOCKLEN);537		chx_firstio(fi, event, arg);538	}539}540 541/*542 * Set channel into extended mode.543 *544 * fi		An instance of a channel statemachine.545 * event	The event, just happened.546 * arg		Generic pointer, casted from channel * upon call.547 */548static void ctcm_chx_setmode(fsm_instance *fi, int event, void *arg)549{550	struct channel *ch = arg;551	int rc;552	unsigned long saveflags = 0;553	int timeout = CTCM_TIME_5_SEC;554 555	fsm_deltimer(&ch->timer);556	if (IS_MPC(ch)) {557		timeout = 1500;558		CTCM_PR_DEBUG("enter %s: cp=%i ch=0x%p id=%s\n",559				__func__, smp_processor_id(), ch, ch->id);560	}561	fsm_addtimer(&ch->timer, timeout, CTC_EVENT_TIMER, ch);562	fsm_newstate(fi, CTC_STATE_SETUPWAIT);563	CTCM_CCW_DUMP((char *)&ch->ccw[6], sizeof(struct ccw1) * 2);564 565	if (event == CTC_EVENT_TIMER)	/* only for timer not yet locked */566		spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);567			/* Such conditional locking is undeterministic in568			 * static view. => ignore sparse warnings here. */569 570	rc = ccw_device_start(ch->cdev, &ch->ccw[6], 0, 0xff, 0);571	if (event == CTC_EVENT_TIMER)	/* see above comments */572		spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);573	if (rc != 0) {574		fsm_deltimer(&ch->timer);575		fsm_newstate(fi, CTC_STATE_STARTWAIT);576		ctcm_ccw_check_rc(ch, rc, "set Mode");577	} else578		ch->retry = 0;579}580 581/*582 * Setup channel.583 *584 * fi		An instance of a channel statemachine.585 * event	The event, just happened.586 * arg		Generic pointer, casted from channel * upon call.587 */588static void ctcm_chx_start(fsm_instance *fi, int event, void *arg)589{590	struct channel *ch	= arg;591	unsigned long saveflags;592	int rc;593 594	CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, "%s(%s): %s",595		CTCM_FUNTAIL, ch->id,596		(CHANNEL_DIRECTION(ch->flags) == CTCM_READ) ? "RX" : "TX");597 598	if (ch->trans_skb != NULL) {599		clear_normalized_cda(&ch->ccw[1]);600		dev_kfree_skb(ch->trans_skb);601		ch->trans_skb = NULL;602	}603	if (CHANNEL_DIRECTION(ch->flags) == CTCM_READ) {604		ch->ccw[1].cmd_code = CCW_CMD_READ;605		ch->ccw[1].flags = CCW_FLAG_SLI;606		ch->ccw[1].count = 0;607	} else {608		ch->ccw[1].cmd_code = CCW_CMD_WRITE;609		ch->ccw[1].flags = CCW_FLAG_SLI | CCW_FLAG_CC;610		ch->ccw[1].count = 0;611	}612	if (ctcm_checkalloc_buffer(ch)) {613		CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,614			"%s(%s): %s trans_skb alloc delayed "615			"until first transfer",616			CTCM_FUNTAIL, ch->id,617			(CHANNEL_DIRECTION(ch->flags) == CTCM_READ) ?618				"RX" : "TX");619	}620	ch->ccw[0].cmd_code = CCW_CMD_PREPARE;621	ch->ccw[0].flags = CCW_FLAG_SLI | CCW_FLAG_CC;622	ch->ccw[0].count = 0;623	ch->ccw[0].cda = 0;624	ch->ccw[2].cmd_code = CCW_CMD_NOOP;	/* jointed CE + DE */625	ch->ccw[2].flags = CCW_FLAG_SLI;626	ch->ccw[2].count = 0;627	ch->ccw[2].cda = 0;628	memcpy(&ch->ccw[3], &ch->ccw[0], sizeof(struct ccw1) * 3);629	ch->ccw[4].cda = 0;630	ch->ccw[4].flags &= ~CCW_FLAG_IDA;631 632	fsm_newstate(fi, CTC_STATE_STARTWAIT);633	fsm_addtimer(&ch->timer, 1000, CTC_EVENT_TIMER, ch);634	spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);635	rc = ccw_device_halt(ch->cdev, 0);636	spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);637	if (rc != 0) {638		if (rc != -EBUSY)639			fsm_deltimer(&ch->timer);640		ctcm_ccw_check_rc(ch, rc, "initial HaltIO");641	}642}643 644/*645 * Shutdown a channel.646 *647 * fi		An instance of a channel statemachine.648 * event	The event, just happened.649 * arg		Generic pointer, casted from channel * upon call.650 */651static void ctcm_chx_haltio(fsm_instance *fi, int event, void *arg)652{653	struct channel *ch = arg;654	unsigned long saveflags = 0;655	int rc;656	int oldstate;657 658	fsm_deltimer(&ch->timer);659	if (IS_MPC(ch))660		fsm_deltimer(&ch->sweep_timer);661 662	fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);663 664	if (event == CTC_EVENT_STOP)	/* only for STOP not yet locked */665		spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);666			/* Such conditional locking is undeterministic in667			 * static view. => ignore sparse warnings here. */668	oldstate = fsm_getstate(fi);669	fsm_newstate(fi, CTC_STATE_TERM);670	rc = ccw_device_halt(ch->cdev, 0);671 672	if (event == CTC_EVENT_STOP)673		spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);674			/* see remark above about conditional locking */675 676	if (rc != 0 && rc != -EBUSY) {677		fsm_deltimer(&ch->timer);678		if (event != CTC_EVENT_STOP) {679			fsm_newstate(fi, oldstate);680			ctcm_ccw_check_rc(ch, rc, (char *)__func__);681		}682	}683}684 685/*686 * Cleanup helper for chx_fail and chx_stopped687 * cleanup channels queue and notify interface statemachine.688 *689 * fi		An instance of a channel statemachine.690 * state	The next state (depending on caller).691 * ch		The channel to operate on.692 */693static void ctcm_chx_cleanup(fsm_instance *fi, int state,694		struct channel *ch)695{696	struct net_device *dev = ch->netdev;697	struct ctcm_priv *priv = dev->ml_priv;698 699	CTCM_DBF_TEXT_(SETUP, CTC_DBF_NOTICE,700			"%s(%s): %s[%d]\n",701			CTCM_FUNTAIL, dev->name, ch->id, state);702 703	fsm_deltimer(&ch->timer);704	if (IS_MPC(ch))705		fsm_deltimer(&ch->sweep_timer);706 707	fsm_newstate(fi, state);708	if (state == CTC_STATE_STOPPED && ch->trans_skb != NULL) {709		clear_normalized_cda(&ch->ccw[1]);710		dev_kfree_skb_any(ch->trans_skb);711		ch->trans_skb = NULL;712	}713 714	ch->th_seg = 0x00;715	ch->th_seq_num = 0x00;716	if (CHANNEL_DIRECTION(ch->flags) == CTCM_READ) {717		skb_queue_purge(&ch->io_queue);718		fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev);719	} else {720		ctcm_purge_skb_queue(&ch->io_queue);721		if (IS_MPC(ch))722			ctcm_purge_skb_queue(&ch->sweep_queue);723		spin_lock(&ch->collect_lock);724		ctcm_purge_skb_queue(&ch->collect_queue);725		ch->collect_len = 0;726		spin_unlock(&ch->collect_lock);727		fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);728	}729}730 731/*732 * A channel has successfully been halted.733 * Cleanup it's queue and notify interface statemachine.734 *735 * fi		An instance of a channel statemachine.736 * event	The event, just happened.737 * arg		Generic pointer, casted from channel * upon call.738 */739static void ctcm_chx_stopped(fsm_instance *fi, int event, void *arg)740{741	ctcm_chx_cleanup(fi, CTC_STATE_STOPPED, arg);742}743 744/*745 * A stop command from device statemachine arrived and we are in746 * not operational mode. Set state to stopped.747 *748 * fi		An instance of a channel statemachine.749 * event	The event, just happened.750 * arg		Generic pointer, casted from channel * upon call.751 */752static void ctcm_chx_stop(fsm_instance *fi, int event, void *arg)753{754	fsm_newstate(fi, CTC_STATE_STOPPED);755}756 757/*758 * A machine check for no path, not operational status or gone device has759 * happened.760 * Cleanup queue and notify interface statemachine.761 *762 * fi		An instance of a channel statemachine.763 * event	The event, just happened.764 * arg		Generic pointer, casted from channel * upon call.765 */766static void ctcm_chx_fail(fsm_instance *fi, int event, void *arg)767{768	ctcm_chx_cleanup(fi, CTC_STATE_NOTOP, arg);769}770 771/*772 * Handle error during setup of channel.773 *774 * fi		An instance of a channel statemachine.775 * event	The event, just happened.776 * arg		Generic pointer, casted from channel * upon call.777 */778static void ctcm_chx_setuperr(fsm_instance *fi, int event, void *arg)779{780	struct channel *ch = arg;781	struct net_device *dev = ch->netdev;782	struct ctcm_priv *priv = dev->ml_priv;783 784	/*785	 * Special case: Got UC_RCRESET on setmode.786	 * This means that remote side isn't setup. In this case787	 * simply retry after some 10 secs...788	 */789	if ((fsm_getstate(fi) == CTC_STATE_SETUPWAIT) &&790	    ((event == CTC_EVENT_UC_RCRESET) ||791	     (event == CTC_EVENT_UC_RSRESET))) {792		fsm_newstate(fi, CTC_STATE_STARTRETRY);793		fsm_deltimer(&ch->timer);794		fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);795		if (!IS_MPC(ch) &&796		    (CHANNEL_DIRECTION(ch->flags) == CTCM_READ)) {797			int rc = ccw_device_halt(ch->cdev, 0);798			if (rc != 0)799				ctcm_ccw_check_rc(ch, rc,800					"HaltIO in chx_setuperr");801		}802		return;803	}804 805	CTCM_DBF_TEXT_(ERROR, CTC_DBF_CRIT,806		"%s(%s) : %s error during %s channel setup state=%s\n",807		CTCM_FUNTAIL, dev->name, ctc_ch_event_names[event],808		(CHANNEL_DIRECTION(ch->flags) == CTCM_READ) ? "RX" : "TX",809		fsm_getstate_str(fi));810 811	if (CHANNEL_DIRECTION(ch->flags) == CTCM_READ) {812		fsm_newstate(fi, CTC_STATE_RXERR);813		fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev);814	} else {815		fsm_newstate(fi, CTC_STATE_TXERR);816		fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);817	}818}819 820/*821 * Restart a channel after an error.822 *823 * fi		An instance of a channel statemachine.824 * event	The event, just happened.825 * arg		Generic pointer, casted from channel * upon call.826 */827static void ctcm_chx_restart(fsm_instance *fi, int event, void *arg)828{829	struct channel *ch = arg;830	struct net_device *dev = ch->netdev;831	unsigned long saveflags = 0;832	int oldstate;833	int rc;834 835	CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,836		"%s: %s[%d] of %s\n",837			CTCM_FUNTAIL, ch->id, event, dev->name);838 839	fsm_deltimer(&ch->timer);840 841	fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);842	oldstate = fsm_getstate(fi);843	fsm_newstate(fi, CTC_STATE_STARTWAIT);844	if (event == CTC_EVENT_TIMER)	/* only for timer not yet locked */845		spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);846			/* Such conditional locking is a known problem for847			 * sparse because its undeterministic in static view.848			 * Warnings should be ignored here. */849	rc = ccw_device_halt(ch->cdev, 0);850	if (event == CTC_EVENT_TIMER)851		spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);852	if (rc != 0) {853		if (rc != -EBUSY) {854		    fsm_deltimer(&ch->timer);855		    fsm_newstate(fi, oldstate);856		}857		ctcm_ccw_check_rc(ch, rc, "HaltIO in ctcm_chx_restart");858	}859}860 861/*862 * Handle error during RX initial handshake (exchange of863 * 0-length block header)864 *865 * fi		An instance of a channel statemachine.866 * event	The event, just happened.867 * arg		Generic pointer, casted from channel * upon call.868 */869static void ctcm_chx_rxiniterr(fsm_instance *fi, int event, void *arg)870{871	struct channel *ch = arg;872	struct net_device *dev = ch->netdev;873	struct ctcm_priv *priv = dev->ml_priv;874 875	if (event == CTC_EVENT_TIMER) {876		if (!IS_MPCDEV(dev))877			/* TODO : check if MPC deletes timer somewhere */878			fsm_deltimer(&ch->timer);879		if (ch->retry++ < 3)880			ctcm_chx_restart(fi, event, arg);881		else {882			fsm_newstate(fi, CTC_STATE_RXERR);883			fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev);884		}885	} else {886		CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,887			"%s(%s): %s in %s", CTCM_FUNTAIL, ch->id,888			ctc_ch_event_names[event], fsm_getstate_str(fi));889 890		dev_warn(&dev->dev,891			"Initialization failed with RX/TX init handshake "892			"error %s\n", ctc_ch_event_names[event]);893	}894}895 896/*897 * Notify device statemachine if we gave up initialization898 * of RX channel.899 *900 * fi		An instance of a channel statemachine.901 * event	The event, just happened.902 * arg		Generic pointer, casted from channel * upon call.903 */904static void ctcm_chx_rxinitfail(fsm_instance *fi, int event, void *arg)905{906	struct channel *ch = arg;907	struct net_device *dev = ch->netdev;908	struct ctcm_priv *priv = dev->ml_priv;909 910	CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,911			"%s(%s): RX %s busy, init. fail",912				CTCM_FUNTAIL, dev->name, ch->id);913	fsm_newstate(fi, CTC_STATE_RXERR);914	fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev);915}916 917/*918 * Handle RX Unit check remote reset (remote disconnected)919 *920 * fi		An instance of a channel statemachine.921 * event	The event, just happened.922 * arg		Generic pointer, casted from channel * upon call.923 */924static void ctcm_chx_rxdisc(fsm_instance *fi, int event, void *arg)925{926	struct channel *ch = arg;927	struct channel *ch2;928	struct net_device *dev = ch->netdev;929	struct ctcm_priv *priv = dev->ml_priv;930 931	CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,932			"%s: %s: remote disconnect - re-init ...",933				CTCM_FUNTAIL, dev->name);934	fsm_deltimer(&ch->timer);935	/*936	 * Notify device statemachine937	 */938	fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev);939	fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);940 941	fsm_newstate(fi, CTC_STATE_DTERM);942	ch2 = priv->channel[CTCM_WRITE];943	fsm_newstate(ch2->fsm, CTC_STATE_DTERM);944 945	ccw_device_halt(ch->cdev, 0);946	ccw_device_halt(ch2->cdev, 0);947}948 949/*950 * Handle error during TX channel initialization.951 *952 * fi		An instance of a channel statemachine.953 * event	The event, just happened.954 * arg		Generic pointer, casted from channel * upon call.955 */956static void ctcm_chx_txiniterr(fsm_instance *fi, int event, void *arg)957{958	struct channel *ch = arg;959	struct net_device *dev = ch->netdev;960	struct ctcm_priv *priv = dev->ml_priv;961 962	if (event == CTC_EVENT_TIMER) {963		fsm_deltimer(&ch->timer);964		if (ch->retry++ < 3)965			ctcm_chx_restart(fi, event, arg);966		else {967			fsm_newstate(fi, CTC_STATE_TXERR);968			fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);969		}970	} else {971		CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,972			"%s(%s): %s in %s", CTCM_FUNTAIL, ch->id,973			ctc_ch_event_names[event], fsm_getstate_str(fi));974 975		dev_warn(&dev->dev,976			"Initialization failed with RX/TX init handshake "977			"error %s\n", ctc_ch_event_names[event]);978	}979}980 981/*982 * Handle TX timeout by retrying operation.983 *984 * fi		An instance of a channel statemachine.985 * event	The event, just happened.986 * arg		Generic pointer, casted from channel * upon call.987 */988static void ctcm_chx_txretry(fsm_instance *fi, int event, void *arg)989{990	struct channel *ch = arg;991	struct net_device *dev = ch->netdev;992	struct ctcm_priv *priv = dev->ml_priv;993	struct sk_buff *skb;994 995	CTCM_PR_DEBUG("Enter: %s: cp=%i ch=0x%p id=%s\n",996			__func__, smp_processor_id(), ch, ch->id);997 998	fsm_deltimer(&ch->timer);999	if (ch->retry++ > 3) {1000		struct mpc_group *gptr = priv->mpcg;1001		CTCM_DBF_TEXT_(TRACE, CTC_DBF_INFO,1002				"%s: %s: retries exceeded",1003					CTCM_FUNTAIL, ch->id);1004		fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);1005		/* call restart if not MPC or if MPC and mpcg fsm is ready.1006			use gptr as mpc indicator */1007		if (!(gptr && (fsm_getstate(gptr->fsm) != MPCG_STATE_READY)))1008			ctcm_chx_restart(fi, event, arg);1009		goto done;1010	}1011 1012	CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,1013			"%s : %s: retry %d",1014				CTCM_FUNTAIL, ch->id, ch->retry);1015	skb = skb_peek(&ch->io_queue);1016	if (skb) {1017		int rc = 0;1018		unsigned long saveflags = 0;1019		clear_normalized_cda(&ch->ccw[4]);1020		ch->ccw[4].count = skb->len;1021		if (set_normalized_cda(&ch->ccw[4], skb->data)) {1022			CTCM_DBF_TEXT_(TRACE, CTC_DBF_INFO,1023				"%s: %s: IDAL alloc failed",1024						CTCM_FUNTAIL, ch->id);1025			fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);1026			ctcm_chx_restart(fi, event, arg);1027			goto done;1028		}1029		fsm_addtimer(&ch->timer, 1000, CTC_EVENT_TIMER, ch);1030		if (event == CTC_EVENT_TIMER) /* for TIMER not yet locked */1031			spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);1032			/* Such conditional locking is a known problem for1033			 * sparse because its undeterministic in static view.1034			 * Warnings should be ignored here. */1035		if (do_debug_ccw)1036			ctcmpc_dumpit((char *)&ch->ccw[3],1037					sizeof(struct ccw1) * 3);1038 1039		rc = ccw_device_start(ch->cdev, &ch->ccw[3], 0, 0xff, 0);1040		if (event == CTC_EVENT_TIMER)1041			spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev),1042					saveflags);1043		if (rc != 0) {1044			fsm_deltimer(&ch->timer);1045			ctcm_ccw_check_rc(ch, rc, "TX in chx_txretry");1046			ctcm_purge_skb_queue(&ch->io_queue);1047		}1048	}1049done:1050	return;1051}1052 1053/*1054 * Handle fatal errors during an I/O command.1055 *1056 * fi		An instance of a channel statemachine.1057 * event	The event, just happened.1058 * arg		Generic pointer, casted from channel * upon call.1059 */1060static void ctcm_chx_iofatal(fsm_instance *fi, int event, void *arg)1061{1062	struct channel *ch = arg;1063	struct net_device *dev = ch->netdev;1064	struct ctcm_priv *priv = dev->ml_priv;1065	int rd = CHANNEL_DIRECTION(ch->flags);1066 1067	fsm_deltimer(&ch->timer);1068	CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,1069		"%s: %s: %s unrecoverable channel error",1070			CTCM_FUNTAIL, ch->id, rd == CTCM_READ ? "RX" : "TX");1071 1072	if (IS_MPC(ch)) {1073		priv->stats.tx_dropped++;1074		priv->stats.tx_errors++;1075	}1076	if (rd == CTCM_READ) {1077		fsm_newstate(fi, CTC_STATE_RXERR);1078		fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev);1079	} else {1080		fsm_newstate(fi, CTC_STATE_TXERR);1081		fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);1082	}1083}1084 1085/*1086 * The ctcm statemachine for a channel.1087 */1088const fsm_node ch_fsm[] = {1089	{ CTC_STATE_STOPPED,	CTC_EVENT_STOP,		ctcm_action_nop  },1090	{ CTC_STATE_STOPPED,	CTC_EVENT_START,	ctcm_chx_start  },1091	{ CTC_STATE_STOPPED,	CTC_EVENT_FINSTAT,	ctcm_action_nop  },1092	{ CTC_STATE_STOPPED,	CTC_EVENT_MC_FAIL,	ctcm_action_nop  },1093 1094	{ CTC_STATE_NOTOP,	CTC_EVENT_STOP,		ctcm_chx_stop  },1095	{ CTC_STATE_NOTOP,	CTC_EVENT_START,	ctcm_action_nop  },1096	{ CTC_STATE_NOTOP,	CTC_EVENT_FINSTAT,	ctcm_action_nop  },1097	{ CTC_STATE_NOTOP,	CTC_EVENT_MC_FAIL,	ctcm_action_nop  },1098	{ CTC_STATE_NOTOP,	CTC_EVENT_MC_GOOD,	ctcm_chx_start  },1099 1100	{ CTC_STATE_STARTWAIT,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1101	{ CTC_STATE_STARTWAIT,	CTC_EVENT_START,	ctcm_action_nop  },1102	{ CTC_STATE_STARTWAIT,	CTC_EVENT_FINSTAT,	ctcm_chx_setmode  },1103	{ CTC_STATE_STARTWAIT,	CTC_EVENT_TIMER,	ctcm_chx_setuperr  },1104	{ CTC_STATE_STARTWAIT,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1105	{ CTC_STATE_STARTWAIT,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1106 1107	{ CTC_STATE_STARTRETRY,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1108	{ CTC_STATE_STARTRETRY,	CTC_EVENT_TIMER,	ctcm_chx_setmode  },1109	{ CTC_STATE_STARTRETRY,	CTC_EVENT_FINSTAT,	ctcm_action_nop  },1110	{ CTC_STATE_STARTRETRY,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1111 1112	{ CTC_STATE_SETUPWAIT,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1113	{ CTC_STATE_SETUPWAIT,	CTC_EVENT_START,	ctcm_action_nop  },1114	{ CTC_STATE_SETUPWAIT,	CTC_EVENT_FINSTAT,	chx_firstio  },1115	{ CTC_STATE_SETUPWAIT,	CTC_EVENT_UC_RCRESET,	ctcm_chx_setuperr  },1116	{ CTC_STATE_SETUPWAIT,	CTC_EVENT_UC_RSRESET,	ctcm_chx_setuperr  },1117	{ CTC_STATE_SETUPWAIT,	CTC_EVENT_TIMER,	ctcm_chx_setmode  },1118	{ CTC_STATE_SETUPWAIT,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1119	{ CTC_STATE_SETUPWAIT,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1120 1121	{ CTC_STATE_RXINIT,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1122	{ CTC_STATE_RXINIT,	CTC_EVENT_START,	ctcm_action_nop  },1123	{ CTC_STATE_RXINIT,	CTC_EVENT_FINSTAT,	chx_rxidle  },1124	{ CTC_STATE_RXINIT,	CTC_EVENT_UC_RCRESET,	ctcm_chx_rxiniterr  },1125	{ CTC_STATE_RXINIT,	CTC_EVENT_UC_RSRESET,	ctcm_chx_rxiniterr  },1126	{ CTC_STATE_RXINIT,	CTC_EVENT_TIMER,	ctcm_chx_rxiniterr  },1127	{ CTC_STATE_RXINIT,	CTC_EVENT_ATTNBUSY,	ctcm_chx_rxinitfail  },1128	{ CTC_STATE_RXINIT,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1129	{ CTC_STATE_RXINIT,	CTC_EVENT_UC_ZERO,	chx_firstio  },1130	{ CTC_STATE_RXINIT,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1131 1132	{ CTC_STATE_RXIDLE,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1133	{ CTC_STATE_RXIDLE,	CTC_EVENT_START,	ctcm_action_nop  },1134	{ CTC_STATE_RXIDLE,	CTC_EVENT_FINSTAT,	chx_rx  },1135	{ CTC_STATE_RXIDLE,	CTC_EVENT_UC_RCRESET,	ctcm_chx_rxdisc  },1136	{ CTC_STATE_RXIDLE,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1137	{ CTC_STATE_RXIDLE,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1138	{ CTC_STATE_RXIDLE,	CTC_EVENT_UC_ZERO,	chx_rx  },1139 1140	{ CTC_STATE_TXINIT,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1141	{ CTC_STATE_TXINIT,	CTC_EVENT_START,	ctcm_action_nop  },1142	{ CTC_STATE_TXINIT,	CTC_EVENT_FINSTAT,	ctcm_chx_txidle  },1143	{ CTC_STATE_TXINIT,	CTC_EVENT_UC_RCRESET,	ctcm_chx_txiniterr  },1144	{ CTC_STATE_TXINIT,	CTC_EVENT_UC_RSRESET,	ctcm_chx_txiniterr  },1145	{ CTC_STATE_TXINIT,	CTC_EVENT_TIMER,	ctcm_chx_txiniterr  },1146	{ CTC_STATE_TXINIT,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1147	{ CTC_STATE_TXINIT,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1148 1149	{ CTC_STATE_TXIDLE,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1150	{ CTC_STATE_TXIDLE,	CTC_EVENT_START,	ctcm_action_nop  },1151	{ CTC_STATE_TXIDLE,	CTC_EVENT_FINSTAT,	chx_firstio  },1152	{ CTC_STATE_TXIDLE,	CTC_EVENT_UC_RCRESET,	ctcm_action_nop  },1153	{ CTC_STATE_TXIDLE,	CTC_EVENT_UC_RSRESET,	ctcm_action_nop  },1154	{ CTC_STATE_TXIDLE,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1155	{ CTC_STATE_TXIDLE,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1156 1157	{ CTC_STATE_TERM,	CTC_EVENT_STOP,		ctcm_action_nop  },1158	{ CTC_STATE_TERM,	CTC_EVENT_START,	ctcm_chx_restart  },1159	{ CTC_STATE_TERM,	CTC_EVENT_FINSTAT,	ctcm_chx_stopped  },1160	{ CTC_STATE_TERM,	CTC_EVENT_UC_RCRESET,	ctcm_action_nop  },1161	{ CTC_STATE_TERM,	CTC_EVENT_UC_RSRESET,	ctcm_action_nop  },1162	{ CTC_STATE_TERM,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1163 1164	{ CTC_STATE_DTERM,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1165	{ CTC_STATE_DTERM,	CTC_EVENT_START,	ctcm_chx_restart  },1166	{ CTC_STATE_DTERM,	CTC_EVENT_FINSTAT,	ctcm_chx_setmode  },1167	{ CTC_STATE_DTERM,	CTC_EVENT_UC_RCRESET,	ctcm_action_nop  },1168	{ CTC_STATE_DTERM,	CTC_EVENT_UC_RSRESET,	ctcm_action_nop  },1169	{ CTC_STATE_DTERM,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1170 1171	{ CTC_STATE_TX,		CTC_EVENT_STOP,		ctcm_chx_haltio  },1172	{ CTC_STATE_TX,		CTC_EVENT_START,	ctcm_action_nop  },1173	{ CTC_STATE_TX,		CTC_EVENT_FINSTAT,	chx_txdone  },1174	{ CTC_STATE_TX,		CTC_EVENT_UC_RCRESET,	ctcm_chx_txretry  },1175	{ CTC_STATE_TX,		CTC_EVENT_UC_RSRESET,	ctcm_chx_txretry  },1176	{ CTC_STATE_TX,		CTC_EVENT_TIMER,	ctcm_chx_txretry  },1177	{ CTC_STATE_TX,		CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1178	{ CTC_STATE_TX,		CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1179 1180	{ CTC_STATE_RXERR,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1181	{ CTC_STATE_TXERR,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1182	{ CTC_STATE_TXERR,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1183	{ CTC_STATE_RXERR,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1184};1185 1186int ch_fsm_len = ARRAY_SIZE(ch_fsm);1187 1188/*1189 * MPC actions for mpc channel statemachine1190 * handling of MPC protocol requires extra1191 * statemachine and actions which are prefixed ctcmpc_ .1192 * The ctc_ch_states and ctc_ch_state_names,1193 * ctc_ch_events and ctc_ch_event_names share the ctcm definitions1194 * which are expanded by some elements.1195 */1196 1197/*1198 * Actions for mpc channel statemachine.1199 */1200 1201/*1202 * Normal data has been send. Free the corresponding1203 * skb (it's in io_queue), reset dev->tbusy and1204 * revert to idle state.1205 *1206 * fi		An instance of a channel statemachine.1207 * event	The event, just happened.1208 * arg		Generic pointer, casted from channel * upon call.1209 */1210static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg)1211{1212	struct channel		*ch = arg;1213	struct net_device	*dev = ch->netdev;1214	struct ctcm_priv	*priv = dev->ml_priv;1215	struct mpc_group	*grp = priv->mpcg;1216	struct sk_buff		*skb;1217	int		first = 1;1218	int		i;1219	__u32		data_space;1220	unsigned long	duration;1221	struct sk_buff	*peekskb;1222	int		rc;1223	struct th_header *header;1224	struct pdu	*p_header;1225	unsigned long done_stamp = jiffies;1226 1227	CTCM_PR_DEBUG("Enter %s: %s cp:%i\n",1228			__func__, dev->name, smp_processor_id());1229 1230	duration = done_stamp - ch->prof.send_stamp;1231	if (duration > ch->prof.tx_time)1232		ch->prof.tx_time = duration;1233 1234	if (ch->irb->scsw.cmd.count != 0)1235		CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_DEBUG,1236			"%s(%s): TX not complete, remaining %d bytes",1237			     CTCM_FUNTAIL, dev->name, ch->irb->scsw.cmd.count);1238	fsm_deltimer(&ch->timer);1239	while ((skb = skb_dequeue(&ch->io_queue))) {1240		priv->stats.tx_packets++;1241		priv->stats.tx_bytes += skb->len - TH_HEADER_LENGTH;1242		if (first) {1243			priv->stats.tx_bytes += 2;1244			first = 0;1245		}1246		refcount_dec(&skb->users);1247		dev_kfree_skb_irq(skb);1248	}1249	spin_lock(&ch->collect_lock);1250	clear_normalized_cda(&ch->ccw[4]);1251	if ((ch->collect_len <= 0) || (grp->in_sweep != 0)) {1252		spin_unlock(&ch->collect_lock);1253		fsm_newstate(fi, CTC_STATE_TXIDLE);1254		goto done;1255	}1256 1257	if (ctcm_checkalloc_buffer(ch)) {1258		spin_unlock(&ch->collect_lock);1259		goto done;1260	}1261	ch->trans_skb->data = ch->trans_skb_data;1262	skb_reset_tail_pointer(ch->trans_skb);1263	ch->trans_skb->len = 0;1264	if (ch->prof.maxmulti < (ch->collect_len + TH_HEADER_LENGTH))1265		ch->prof.maxmulti = ch->collect_len + TH_HEADER_LENGTH;1266	if (ch->prof.maxcqueue < skb_queue_len(&ch->collect_queue))1267		ch->prof.maxcqueue = skb_queue_len(&ch->collect_queue);1268	i = 0;1269	p_header = NULL;1270	data_space = grp->group_max_buflen - TH_HEADER_LENGTH;1271 1272	CTCM_PR_DBGDATA("%s: building trans_skb from collect_q"1273		       " data_space:%04x\n",1274		       __func__, data_space);1275 1276	while ((skb = skb_dequeue(&ch->collect_queue))) {1277		skb_put_data(ch->trans_skb, skb->data, skb->len);1278		p_header = (struct pdu *)1279			(skb_tail_pointer(ch->trans_skb) - skb->len);1280		p_header->pdu_flag = 0x00;1281		if (be16_to_cpu(skb->protocol) == ETH_P_SNAP)1282			p_header->pdu_flag |= 0x60;1283		else1284			p_header->pdu_flag |= 0x20;1285 1286		CTCM_PR_DBGDATA("%s: trans_skb len:%04x \n",1287				__func__, ch->trans_skb->len);1288		CTCM_PR_DBGDATA("%s: pdu header and data for up"1289				" to 32 bytes sent to vtam\n", __func__);1290		CTCM_D3_DUMP((char *)p_header, min_t(int, skb->len, 32));1291 1292		ch->collect_len -= skb->len;1293		data_space -= skb->len;1294		priv->stats.tx_packets++;1295		priv->stats.tx_bytes += skb->len;1296		refcount_dec(&skb->users);1297		dev_kfree_skb_any(skb);1298		peekskb = skb_peek(&ch->collect_queue);1299		if (peekskb->len > data_space)1300			break;1301		i++;1302	}1303	/* p_header points to the last one we handled */1304	if (p_header)1305		p_header->pdu_flag |= PDU_LAST;	/*Say it's the last one*/1306 1307	header = skb_push(ch->trans_skb, TH_HEADER_LENGTH);1308	memset(header, 0, TH_HEADER_LENGTH);1309 1310	header->th_ch_flag = TH_HAS_PDU;  /* Normal data */1311	ch->th_seq_num++;1312	header->th_seq_num = ch->th_seq_num;1313 1314	CTCM_PR_DBGDATA("%s: ToVTAM_th_seq= %08x\n" ,1315					__func__, ch->th_seq_num);1316 1317	CTCM_PR_DBGDATA("%s: trans_skb len:%04x \n",1318		       __func__, ch->trans_skb->len);1319	CTCM_PR_DBGDATA("%s: up-to-50 bytes of trans_skb "1320			"data to vtam from collect_q\n", __func__);1321	CTCM_D3_DUMP((char *)ch->trans_skb->data,1322				min_t(int, ch->trans_skb->len, 50));1323 1324	spin_unlock(&ch->collect_lock);1325	clear_normalized_cda(&ch->ccw[1]);1326 1327	CTCM_PR_DBGDATA("ccwcda=0x%p data=0x%p\n",1328			(void *)(u64)dma32_to_u32(ch->ccw[1].cda),1329			ch->trans_skb->data);1330	ch->ccw[1].count = ch->max_bufsize;1331 1332	if (set_normalized_cda(&ch->ccw[1], ch->trans_skb->data)) {1333		dev_kfree_skb_any(ch->trans_skb);1334		ch->trans_skb = NULL;1335		CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_ERROR,1336			"%s: %s: IDAL alloc failed",1337				CTCM_FUNTAIL, ch->id);1338		fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);1339		return;1340	}1341 1342	CTCM_PR_DBGDATA("ccwcda=0x%p data=0x%p\n",1343			(void *)(u64)dma32_to_u32(ch->ccw[1].cda),1344			ch->trans_skb->data);1345 1346	ch->ccw[1].count = ch->trans_skb->len;1347	fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);1348	ch->prof.send_stamp = jiffies;1349	if (do_debug_ccw)1350		ctcmpc_dumpit((char *)&ch->ccw[0], sizeof(struct ccw1) * 3);1351	rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);1352	ch->prof.doios_multi++;1353	if (rc != 0) {1354		priv->stats.tx_dropped += i;1355		priv->stats.tx_errors += i;1356		fsm_deltimer(&ch->timer);1357		ctcm_ccw_check_rc(ch, rc, "chained TX");1358	}1359done:1360	ctcm_clear_busy(dev);1361	return;1362}1363 1364/*1365 * Got normal data, check for sanity, queue it up, allocate new buffer1366 * trigger bottom half, and initiate next read.1367 *1368 * fi		An instance of a channel statemachine.1369 * event	The event, just happened.1370 * arg		Generic pointer, casted from channel * upon call.1371 */1372static void ctcmpc_chx_rx(fsm_instance *fi, int event, void *arg)1373{1374	struct channel		*ch = arg;1375	struct net_device	*dev = ch->netdev;1376	struct ctcm_priv	*priv = dev->ml_priv;1377	struct mpc_group	*grp = priv->mpcg;1378	struct sk_buff		*skb = ch->trans_skb;1379	struct sk_buff		*new_skb;1380	unsigned long		saveflags = 0;	/* avoids compiler warning */1381	int len	= ch->max_bufsize - ch->irb->scsw.cmd.count;1382 1383	CTCM_PR_DEBUG("%s: %s: cp:%i %s maxbuf : %04x, len: %04x\n",1384			CTCM_FUNTAIL, dev->name, smp_processor_id(),1385				ch->id, ch->max_bufsize, len);1386	fsm_deltimer(&ch->timer);1387 1388	if (skb == NULL) {1389		CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,1390			"%s(%s): TRANS_SKB = NULL",1391				CTCM_FUNTAIL, dev->name);1392		goto again;1393	}1394 1395	if (len < TH_HEADER_LENGTH) {1396		CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,1397				"%s(%s): packet length %d too short",1398					CTCM_FUNTAIL, dev->name, len);1399		priv->stats.rx_dropped++;1400		priv->stats.rx_length_errors++;1401	} else {1402		/* must have valid th header or game over */1403		__u32	block_len = len;1404		len = TH_HEADER_LENGTH + XID2_LENGTH + 4;1405		new_skb = __dev_alloc_skb(ch->max_bufsize, GFP_ATOMIC);1406 1407		if (new_skb == NULL) {1408			CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,1409				"%s(%s): skb allocation failed",1410						CTCM_FUNTAIL, dev->name);1411			fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);1412			goto again;1413		}1414		switch (fsm_getstate(grp->fsm)) {1415		case MPCG_STATE_RESET:1416		case MPCG_STATE_INOP:1417			dev_kfree_skb_any(new_skb);1418			break;1419		case MPCG_STATE_FLOWC:1420		case MPCG_STATE_READY:1421			skb_put_data(new_skb, skb->data, block_len);1422			skb_queue_tail(&ch->io_queue, new_skb);1423			tasklet_schedule(&ch->ch_tasklet);1424			break;1425		default:1426			skb_put_data(new_skb, skb->data, len);1427			skb_queue_tail(&ch->io_queue, new_skb);1428			tasklet_hi_schedule(&ch->ch_tasklet);1429			break;1430		}1431	}1432 1433again:1434	switch (fsm_getstate(grp->fsm)) {1435	int rc, dolock;1436	case MPCG_STATE_FLOWC:1437	case MPCG_STATE_READY:1438		if (ctcm_checkalloc_buffer(ch))1439			break;1440		ch->trans_skb->data = ch->trans_skb_data;1441		skb_reset_tail_pointer(ch->trans_skb);1442		ch->trans_skb->len = 0;1443		ch->ccw[1].count = ch->max_bufsize;1444		if (do_debug_ccw)1445			ctcmpc_dumpit((char *)&ch->ccw[0],1446				      sizeof(struct ccw1) * 3);1447		dolock = !in_hardirq();1448		if (dolock)1449			spin_lock_irqsave(1450				get_ccwdev_lock(ch->cdev), saveflags);1451		rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);1452		if (dolock) /* see remark about conditional locking */1453			spin_unlock_irqrestore(1454				get_ccwdev_lock(ch->cdev), saveflags);1455		if (rc != 0)1456			ctcm_ccw_check_rc(ch, rc, "normal RX");1457		break;1458	default:1459		break;1460	}1461 1462	CTCM_PR_DEBUG("Exit %s: %s, ch=0x%p, id=%s\n",1463			__func__, dev->name, ch, ch->id);1464 1465}1466 1467/*1468 * Initialize connection by sending a __u16 of value 0.1469 *1470 * fi		An instance of a channel statemachine.1471 * event	The event, just happened.1472 * arg		Generic pointer, casted from channel * upon call.1473 */1474static void ctcmpc_chx_firstio(fsm_instance *fi, int event, void *arg)1475{1476	struct channel		*ch = arg;1477	struct net_device	*dev = ch->netdev;1478	struct ctcm_priv	*priv = dev->ml_priv;1479	struct mpc_group	*gptr = priv->mpcg;1480 1481	CTCM_PR_DEBUG("Enter %s: id=%s, ch=0x%p\n",1482				__func__, ch->id, ch);1483 1484	CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_INFO,1485			"%s: %s: chstate:%i, grpstate:%i, prot:%i\n",1486			CTCM_FUNTAIL, ch->id, fsm_getstate(fi),1487			fsm_getstate(gptr->fsm), ch->protocol);1488 1489	if (fsm_getstate(fi) == CTC_STATE_TXIDLE)1490		MPC_DBF_DEV_NAME(TRACE, dev, "remote side issued READ? ");1491 1492	fsm_deltimer(&ch->timer);1493	if (ctcm_checkalloc_buffer(ch))1494				goto done;1495 1496	switch (fsm_getstate(fi)) {1497	case CTC_STATE_STARTRETRY:1498	case CTC_STATE_SETUPWAIT:1499		if (CHANNEL_DIRECTION(ch->flags) == CTCM_READ) {1500			ctcmpc_chx_rxidle(fi, event, arg);1501		} else {1502			fsm_newstate(fi, CTC_STATE_TXIDLE);1503			fsm_event(priv->fsm, DEV_EVENT_TXUP, dev);1504		}1505				goto done;1506	default:1507		break;1508	}1509 1510	fsm_newstate(fi, (CHANNEL_DIRECTION(ch->flags) == CTCM_READ)1511		     ? CTC_STATE_RXINIT : CTC_STATE_TXINIT);1512 1513done:1514	CTCM_PR_DEBUG("Exit %s: id=%s, ch=0x%p\n",1515				__func__, ch->id, ch);1516	return;1517}1518 1519/*1520 * Got initial data, check it. If OK,1521 * notify device statemachine that we are up and1522 * running.1523 *1524 * fi		An instance of a channel statemachine.1525 * event	The event, just happened.1526 * arg		Generic pointer, casted from channel * upon call.1527 */1528void ctcmpc_chx_rxidle(fsm_instance *fi, int event, void *arg)1529{1530	struct channel *ch = arg;1531	struct net_device *dev = ch->netdev;1532	struct ctcm_priv  *priv = dev->ml_priv;1533	struct mpc_group  *grp = priv->mpcg;1534	int rc;1535	unsigned long saveflags = 0;	/* avoids compiler warning */1536 1537	fsm_deltimer(&ch->timer);1538	CTCM_PR_DEBUG("%s: %s: %s: cp:%i, chstate:%i grpstate:%i\n",1539			__func__, ch->id, dev->name, smp_processor_id(),1540				fsm_getstate(fi), fsm_getstate(grp->fsm));1541 1542	fsm_newstate(fi, CTC_STATE_RXIDLE);1543	/* XID processing complete */1544 1545	switch (fsm_getstate(grp->fsm)) {1546	case MPCG_STATE_FLOWC:1547	case MPCG_STATE_READY:1548		if (ctcm_checkalloc_buffer(ch))1549				goto done;1550		ch->trans_skb->data = ch->trans_skb_data;1551		skb_reset_tail_pointer(ch->trans_skb);1552		ch->trans_skb->len = 0;1553		ch->ccw[1].count = ch->max_bufsize;1554		CTCM_CCW_DUMP((char *)&ch->ccw[0], sizeof(struct ccw1) * 3);1555		if (event == CTC_EVENT_START)1556			/* see remark about conditional locking */1557			spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);1558		rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);1559		if (event == CTC_EVENT_START)1560			spin_unlock_irqrestore(1561					get_ccwdev_lock(ch->cdev), saveflags);1562		if (rc != 0) {1563			fsm_newstate(fi, CTC_STATE_RXINIT);1564			ctcm_ccw_check_rc(ch, rc, "initial RX");1565			goto done;1566		}1567		break;1568	default:1569		break;1570	}1571 1572	fsm_event(priv->fsm, DEV_EVENT_RXUP, dev);1573done:1574	return;1575}1576 1577/*1578 * ctcmpc channel FSM action1579 * called from several points in ctcmpc_ch_fsm1580 * ctcmpc only1581 */1582static void ctcmpc_chx_attn(fsm_instance *fsm, int event, void *arg)1583{1584	struct channel	  *ch     = arg;1585	struct net_device *dev    = ch->netdev;1586	struct ctcm_priv  *priv   = dev->ml_priv;1587	struct mpc_group  *grp = priv->mpcg;1588 1589	CTCM_PR_DEBUG("%s(%s): %s(ch=0x%p), cp=%i, ChStat:%s, GrpStat:%s\n",1590		__func__, dev->name, ch->id, ch, smp_processor_id(),1591			fsm_getstate_str(ch->fsm), fsm_getstate_str(grp->fsm));1592 1593	switch (fsm_getstate(grp->fsm)) {1594	case MPCG_STATE_XID2INITW:1595		/* ok..start yside xid exchanges */1596		if (!ch->in_mpcgroup)1597			break;1598		if (fsm_getstate(ch->fsm) ==  CH_XID0_PENDING) {1599			fsm_deltimer(&grp->timer);1600			fsm_addtimer(&grp->timer,1601				MPC_XID_TIMEOUT_VALUE,1602				MPCG_EVENT_TIMER, dev);1603			fsm_event(grp->fsm, MPCG_EVENT_XID0DO, ch);1604 1605		} else if (fsm_getstate(ch->fsm) < CH_XID7_PENDING1)1606			/* attn rcvd before xid0 processed via bh */1607			fsm_newstate(ch->fsm, CH_XID7_PENDING1);1608		break;1609	case MPCG_STATE_XID2INITX:1610	case MPCG_STATE_XID0IOWAIT:1611	case MPCG_STATE_XID0IOWAIX:1612		/* attn rcvd before xid0 processed on ch1613		but mid-xid0 processing for group    */1614		if (fsm_getstate(ch->fsm) < CH_XID7_PENDING1)1615			fsm_newstate(ch->fsm, CH_XID7_PENDING1);1616		break;1617	case MPCG_STATE_XID7INITW:1618	case MPCG_STATE_XID7INITX:1619	case MPCG_STATE_XID7INITI:1620	case MPCG_STATE_XID7INITZ:1621		switch (fsm_getstate(ch->fsm)) {1622		case CH_XID7_PENDING:1623			fsm_newstate(ch->fsm, CH_XID7_PENDING1);1624			break;1625		case CH_XID7_PENDING2:1626			fsm_newstate(ch->fsm, CH_XID7_PENDING3);1627			break;1628		}1629		fsm_event(grp->fsm, MPCG_EVENT_XID7DONE, dev);1630		break;1631	}1632 1633	return;1634}1635 1636/*1637 * ctcmpc channel FSM action1638 * called from one point in ctcmpc_ch_fsm1639 * ctcmpc only1640 */1641static void ctcmpc_chx_attnbusy(fsm_instance *fsm, int event, void *arg)1642{1643	struct channel	  *ch     = arg;1644	struct net_device *dev    = ch->netdev;1645	struct ctcm_priv  *priv   = dev->ml_priv;1646	struct mpc_group  *grp    = priv->mpcg;1647 1648	CTCM_PR_DEBUG("%s(%s): %s\n  ChState:%s GrpState:%s\n",1649			__func__, dev->name, ch->id,1650			fsm_getstate_str(ch->fsm), fsm_getstate_str(grp->fsm));1651 1652	fsm_deltimer(&ch->timer);1653 1654	switch (fsm_getstate(grp->fsm)) {1655	case MPCG_STATE_XID0IOWAIT:1656		/* vtam wants to be primary.start yside xid exchanges*/1657		/* only receive one attn-busy at a time so must not  */1658		/* change state each time			     */1659		grp->changed_side = 1;1660		fsm_newstate(grp->fsm, MPCG_STATE_XID2INITW);1661		break;1662	case MPCG_STATE_XID2INITW:1663		if (grp->changed_side == 1) {1664			grp->changed_side = 2;1665			break;1666		}1667		/* process began via call to establish_conn	 */1668		/* so must report failure instead of reverting	 */1669		/* back to ready-for-xid passive state		 */1670		if (grp->estconnfunc)1671				goto done;1672		/* this attnbusy is NOT the result of xside xid  */1673		/* collisions so yside must have been triggered  */1674		/* by an ATTN that was not intended to start XID */1675		/* processing. Revert back to ready-for-xid and  */1676		/* wait for ATTN interrupt to signal xid start	 */1677		if (fsm_getstate(ch->fsm) == CH_XID0_INPROGRESS) {1678			fsm_newstate(ch->fsm, CH_XID0_PENDING) ;1679			fsm_deltimer(&grp->timer);1680			goto done;1681		}1682		fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);1683		goto done;1684	case MPCG_STATE_XID2INITX:1685		/* XID2 was received before ATTN Busy for second1686		   channel.Send yside xid for second channel.1687		*/1688		if (grp->changed_side == 1) {1689			grp->changed_side = 2;1690			break;1691		}1692		fallthrough;1693	case MPCG_STATE_XID0IOWAIX:1694	case MPCG_STATE_XID7INITW:1695	case MPCG_STATE_XID7INITX:1696	case MPCG_STATE_XID7INITI:1697	case MPCG_STATE_XID7INITZ:1698	default:1699		/* multiple attn-busy indicates too out-of-sync      */1700		/* and they are certainly not being received as part */1701		/* of valid mpc group negotiations..		     */1702		fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);1703				goto done;1704	}1705 1706	if (grp->changed_side == 1) {1707		fsm_deltimer(&grp->timer);1708		fsm_addtimer(&grp->timer, MPC_XID_TIMEOUT_VALUE,1709			     MPCG_EVENT_TIMER, dev);1710	}1711	if (ch->in_mpcgroup)1712		fsm_event(grp->fsm, MPCG_EVENT_XID0DO, ch);1713	else1714		CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,1715			"%s(%s): channel %s not added to group",1716				CTCM_FUNTAIL, dev->name, ch->id);1717 1718done:1719	return;1720}1721 1722/*1723 * ctcmpc channel FSM action1724 * called from several points in ctcmpc_ch_fsm1725 * ctcmpc only1726 */1727static void ctcmpc_chx_resend(fsm_instance *fsm, int event, void *arg)1728{1729	struct channel	   *ch	   = arg;1730	struct net_device  *dev    = ch->netdev;1731	struct ctcm_priv   *priv   = dev->ml_priv;1732	struct mpc_group   *grp    = priv->mpcg;1733 1734	fsm_event(grp->fsm, MPCG_EVENT_XID0DO, ch);1735	return;1736}1737 1738/*1739 * ctcmpc channel FSM action1740 * called from several points in ctcmpc_ch_fsm1741 * ctcmpc only1742 */1743static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg)1744{1745	struct channel *ach = arg;1746	struct net_device *dev = ach->netdev;1747	struct ctcm_priv *priv = dev->ml_priv;1748	struct mpc_group *grp = priv->mpcg;1749	struct channel *wch = priv->channel[CTCM_WRITE];1750	struct channel *rch = priv->channel[CTCM_READ];1751	struct sk_buff *skb;1752	struct th_sweep *header;1753	int rc = 0;1754	unsigned long saveflags = 0;1755 1756	CTCM_PR_DEBUG("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",1757			__func__, smp_processor_id(), ach, ach->id);1758 1759	if (grp->in_sweep == 0)1760				goto done;1761 1762	CTCM_PR_DBGDATA("%s: 1: ToVTAM_th_seq= %08x\n" ,1763				__func__, wch->th_seq_num);1764	CTCM_PR_DBGDATA("%s: 1: FromVTAM_th_seq= %08x\n" ,1765				__func__, rch->th_seq_num);1766 1767	if (fsm_getstate(wch->fsm) != CTC_STATE_TXIDLE) {1768		/* give the previous IO time to complete */1769		fsm_addtimer(&wch->sweep_timer,1770			200, CTC_EVENT_RSWEEP_TIMER, wch);1771		goto done;1772	}1773 1774	skb = skb_dequeue(&wch->sweep_queue);1775	if (!skb)1776				goto done;1777 1778	if (set_normalized_cda(&wch->ccw[4], skb->data)) {1779		grp->in_sweep = 0;1780		ctcm_clear_busy_do(dev);1781		dev_kfree_skb_any(skb);1782		fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);1783		goto done;1784	} else {1785		refcount_inc(&skb->users);1786		skb_queue_tail(&wch->io_queue, skb);1787	}1788 1789	/* send out the sweep */1790	wch->ccw[4].count = skb->len;1791 1792	header = (struct th_sweep *)skb->data;1793	switch (header->th.th_ch_flag) {1794	case TH_SWEEP_REQ:1795		grp->sweep_req_pend_num--;1796		break;1797	case TH_SWEEP_RESP:1798		grp->sweep_rsp_pend_num--;1799		break;1800	}1801 1802	header->sw.th_last_seq = wch->th_seq_num;1803 1804	CTCM_CCW_DUMP((char *)&wch->ccw[3], sizeof(struct ccw1) * 3);1805	CTCM_PR_DBGDATA("%s: sweep packet\n", __func__);1806	CTCM_D3_DUMP((char *)header, TH_SWEEP_LENGTH);1807 1808	fsm_addtimer(&wch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, wch);1809	fsm_newstate(wch->fsm, CTC_STATE_TX);1810 1811	spin_lock_irqsave(get_ccwdev_lock(wch->cdev), saveflags);1812	wch->prof.send_stamp = jiffies;1813	rc = ccw_device_start(wch->cdev, &wch->ccw[3], 0, 0xff, 0);1814	spin_unlock_irqrestore(get_ccwdev_lock(wch->cdev), saveflags);1815 1816	if ((grp->sweep_req_pend_num == 0) &&1817	   (grp->sweep_rsp_pend_num == 0)) {1818		grp->in_sweep = 0;1819		rch->th_seq_num = 0x00;1820		wch->th_seq_num = 0x00;1821		ctcm_clear_busy_do(dev);1822	}1823 1824	CTCM_PR_DBGDATA("%s: To-/From-VTAM_th_seq = %08x/%08x\n" ,1825			__func__, wch->th_seq_num, rch->th_seq_num);1826 1827	if (rc != 0)1828		ctcm_ccw_check_rc(wch, rc, "send sweep");1829 1830done:1831	return;1832}1833 1834 1835/*1836 * The ctcmpc statemachine for a channel.1837 */1838 1839const fsm_node ctcmpc_ch_fsm[] = {1840	{ CTC_STATE_STOPPED,	CTC_EVENT_STOP,		ctcm_action_nop  },1841	{ CTC_STATE_STOPPED,	CTC_EVENT_START,	ctcm_chx_start  },1842	{ CTC_STATE_STOPPED,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1843	{ CTC_STATE_STOPPED,	CTC_EVENT_FINSTAT,	ctcm_action_nop  },1844	{ CTC_STATE_STOPPED,	CTC_EVENT_MC_FAIL,	ctcm_action_nop  },1845 1846	{ CTC_STATE_NOTOP,	CTC_EVENT_STOP,		ctcm_chx_stop  },1847	{ CTC_STATE_NOTOP,	CTC_EVENT_START,	ctcm_action_nop  },1848	{ CTC_STATE_NOTOP,	CTC_EVENT_FINSTAT,	ctcm_action_nop  },1849	{ CTC_STATE_NOTOP,	CTC_EVENT_MC_FAIL,	ctcm_action_nop  },1850	{ CTC_STATE_NOTOP,	CTC_EVENT_MC_GOOD,	ctcm_chx_start  },1851	{ CTC_STATE_NOTOP,	CTC_EVENT_UC_RCRESET,	ctcm_chx_stop  },1852	{ CTC_STATE_NOTOP,	CTC_EVENT_UC_RSRESET,	ctcm_chx_stop  },1853	{ CTC_STATE_NOTOP,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1854 1855	{ CTC_STATE_STARTWAIT,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1856	{ CTC_STATE_STARTWAIT,	CTC_EVENT_START,	ctcm_action_nop  },1857	{ CTC_STATE_STARTWAIT,	CTC_EVENT_FINSTAT,	ctcm_chx_setmode  },1858	{ CTC_STATE_STARTWAIT,	CTC_EVENT_TIMER,	ctcm_chx_setuperr  },1859	{ CTC_STATE_STARTWAIT,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1860	{ CTC_STATE_STARTWAIT,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1861 1862	{ CTC_STATE_STARTRETRY,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1863	{ CTC_STATE_STARTRETRY,	CTC_EVENT_TIMER,	ctcm_chx_setmode  },1864	{ CTC_STATE_STARTRETRY,	CTC_EVENT_FINSTAT,	ctcm_chx_setmode  },1865	{ CTC_STATE_STARTRETRY,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1866	{ CTC_STATE_STARTRETRY,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1867 1868	{ CTC_STATE_SETUPWAIT,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1869	{ CTC_STATE_SETUPWAIT,	CTC_EVENT_START,	ctcm_action_nop  },1870	{ CTC_STATE_SETUPWAIT,	CTC_EVENT_FINSTAT,	ctcmpc_chx_firstio  },1871	{ CTC_STATE_SETUPWAIT,	CTC_EVENT_UC_RCRESET,	ctcm_chx_setuperr  },1872	{ CTC_STATE_SETUPWAIT,	CTC_EVENT_UC_RSRESET,	ctcm_chx_setuperr  },1873	{ CTC_STATE_SETUPWAIT,	CTC_EVENT_TIMER,	ctcm_chx_setmode  },1874	{ CTC_STATE_SETUPWAIT,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1875	{ CTC_STATE_SETUPWAIT,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1876 1877	{ CTC_STATE_RXINIT,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1878	{ CTC_STATE_RXINIT,	CTC_EVENT_START,	ctcm_action_nop  },1879	{ CTC_STATE_RXINIT,	CTC_EVENT_FINSTAT,	ctcmpc_chx_rxidle  },1880	{ CTC_STATE_RXINIT,	CTC_EVENT_UC_RCRESET,	ctcm_chx_rxiniterr  },1881	{ CTC_STATE_RXINIT,	CTC_EVENT_UC_RSRESET,	ctcm_chx_rxiniterr  },1882	{ CTC_STATE_RXINIT,	CTC_EVENT_TIMER,	ctcm_chx_rxiniterr  },1883	{ CTC_STATE_RXINIT,	CTC_EVENT_ATTNBUSY,	ctcm_chx_rxinitfail  },1884	{ CTC_STATE_RXINIT,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1885	{ CTC_STATE_RXINIT,	CTC_EVENT_UC_ZERO,	ctcmpc_chx_firstio  },1886	{ CTC_STATE_RXINIT,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1887 1888	{ CH_XID0_PENDING,	CTC_EVENT_FINSTAT,	ctcm_action_nop  },1889	{ CH_XID0_PENDING,	CTC_EVENT_ATTN,		ctcmpc_chx_attn  },1890	{ CH_XID0_PENDING,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1891	{ CH_XID0_PENDING,	CTC_EVENT_START,	ctcm_action_nop  },1892	{ CH_XID0_PENDING,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1893	{ CH_XID0_PENDING,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1894	{ CH_XID0_PENDING,	CTC_EVENT_UC_RCRESET,	ctcm_chx_setuperr  },1895	{ CH_XID0_PENDING,	CTC_EVENT_UC_RSRESET,	ctcm_chx_setuperr  },1896	{ CH_XID0_PENDING,	CTC_EVENT_UC_RSRESET,	ctcm_chx_setuperr  },1897	{ CH_XID0_PENDING,	CTC_EVENT_ATTNBUSY,	ctcm_chx_iofatal  },1898 1899	{ CH_XID0_INPROGRESS,	CTC_EVENT_FINSTAT,	ctcmpc_chx_rx  },1900	{ CH_XID0_INPROGRESS,	CTC_EVENT_ATTN,		ctcmpc_chx_attn  },1901	{ CH_XID0_INPROGRESS,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1902	{ CH_XID0_INPROGRESS,	CTC_EVENT_START,	ctcm_action_nop  },1903	{ CH_XID0_INPROGRESS,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1904	{ CH_XID0_INPROGRESS,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1905	{ CH_XID0_INPROGRESS,	CTC_EVENT_UC_ZERO,	ctcmpc_chx_rx  },1906	{ CH_XID0_INPROGRESS,	CTC_EVENT_UC_RCRESET,	ctcm_chx_setuperr },1907	{ CH_XID0_INPROGRESS,	CTC_EVENT_ATTNBUSY,	ctcmpc_chx_attnbusy  },1908	{ CH_XID0_INPROGRESS,	CTC_EVENT_TIMER,	ctcmpc_chx_resend  },1909	{ CH_XID0_INPROGRESS,	CTC_EVENT_IO_EBUSY,	ctcm_chx_fail  },1910 1911	{ CH_XID7_PENDING,	CTC_EVENT_FINSTAT,	ctcmpc_chx_rx  },1912	{ CH_XID7_PENDING,	CTC_EVENT_ATTN,		ctcmpc_chx_attn  },1913	{ CH_XID7_PENDING,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1914	{ CH_XID7_PENDING,	CTC_EVENT_START,	ctcm_action_nop  },1915	{ CH_XID7_PENDING,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1916	{ CH_XID7_PENDING,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1917	{ CH_XID7_PENDING,	CTC_EVENT_UC_ZERO,	ctcmpc_chx_rx  },1918	{ CH_XID7_PENDING,	CTC_EVENT_UC_RCRESET,	ctcm_chx_setuperr  },1919	{ CH_XID7_PENDING,	CTC_EVENT_UC_RSRESET,	ctcm_chx_setuperr  },1920	{ CH_XID7_PENDING,	CTC_EVENT_UC_RSRESET,	ctcm_chx_setuperr  },1921	{ CH_XID7_PENDING,	CTC_EVENT_ATTNBUSY,	ctcm_chx_iofatal  },1922	{ CH_XID7_PENDING,	CTC_EVENT_TIMER,	ctcmpc_chx_resend  },1923	{ CH_XID7_PENDING,	CTC_EVENT_IO_EBUSY,	ctcm_chx_fail  },1924 1925	{ CH_XID7_PENDING1,	CTC_EVENT_FINSTAT,	ctcmpc_chx_rx  },1926	{ CH_XID7_PENDING1,	CTC_EVENT_ATTN,		ctcmpc_chx_attn  },1927	{ CH_XID7_PENDING1,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1928	{ CH_XID7_PENDING1,	CTC_EVENT_START,	ctcm_action_nop  },1929	{ CH_XID7_PENDING1,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1930	{ CH_XID7_PENDING1,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1931	{ CH_XID7_PENDING1,	CTC_EVENT_UC_ZERO,	ctcmpc_chx_rx  },1932	{ CH_XID7_PENDING1,	CTC_EVENT_UC_RCRESET,	ctcm_chx_setuperr  },1933	{ CH_XID7_PENDING1,	CTC_EVENT_UC_RSRESET,	ctcm_chx_setuperr  },1934	{ CH_XID7_PENDING1,	CTC_EVENT_ATTNBUSY,	ctcm_chx_iofatal  },1935	{ CH_XID7_PENDING1,	CTC_EVENT_TIMER,	ctcmpc_chx_resend  },1936	{ CH_XID7_PENDING1,	CTC_EVENT_IO_EBUSY,	ctcm_chx_fail  },1937 1938	{ CH_XID7_PENDING2,	CTC_EVENT_FINSTAT,	ctcmpc_chx_rx  },1939	{ CH_XID7_PENDING2,	CTC_EVENT_ATTN,		ctcmpc_chx_attn  },1940	{ CH_XID7_PENDING2,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1941	{ CH_XID7_PENDING2,	CTC_EVENT_START,	ctcm_action_nop  },1942	{ CH_XID7_PENDING2,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1943	{ CH_XID7_PENDING2,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1944	{ CH_XID7_PENDING2,	CTC_EVENT_UC_ZERO,	ctcmpc_chx_rx  },1945	{ CH_XID7_PENDING2,	CTC_EVENT_UC_RCRESET,	ctcm_chx_setuperr  },1946	{ CH_XID7_PENDING2,	CTC_EVENT_UC_RSRESET,	ctcm_chx_setuperr  },1947	{ CH_XID7_PENDING2,	CTC_EVENT_ATTNBUSY,	ctcm_chx_iofatal  },1948	{ CH_XID7_PENDING2,	CTC_EVENT_TIMER,	ctcmpc_chx_resend  },1949	{ CH_XID7_PENDING2,	CTC_EVENT_IO_EBUSY,	ctcm_chx_fail  },1950 1951	{ CH_XID7_PENDING3,	CTC_EVENT_FINSTAT,	ctcmpc_chx_rx  },1952	{ CH_XID7_PENDING3,	CTC_EVENT_ATTN,		ctcmpc_chx_attn  },1953	{ CH_XID7_PENDING3,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1954	{ CH_XID7_PENDING3,	CTC_EVENT_START,	ctcm_action_nop  },1955	{ CH_XID7_PENDING3,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1956	{ CH_XID7_PENDING3,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1957	{ CH_XID7_PENDING3,	CTC_EVENT_UC_ZERO,	ctcmpc_chx_rx  },1958	{ CH_XID7_PENDING3,	CTC_EVENT_UC_RCRESET,	ctcm_chx_setuperr  },1959	{ CH_XID7_PENDING3,	CTC_EVENT_UC_RSRESET,	ctcm_chx_setuperr  },1960	{ CH_XID7_PENDING3,	CTC_EVENT_ATTNBUSY,	ctcm_chx_iofatal  },1961	{ CH_XID7_PENDING3,	CTC_EVENT_TIMER,	ctcmpc_chx_resend  },1962	{ CH_XID7_PENDING3,	CTC_EVENT_IO_EBUSY,	ctcm_chx_fail  },1963 1964	{ CH_XID7_PENDING4,	CTC_EVENT_FINSTAT,	ctcmpc_chx_rx  },1965	{ CH_XID7_PENDING4,	CTC_EVENT_ATTN,		ctcmpc_chx_attn  },1966	{ CH_XID7_PENDING4,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1967	{ CH_XID7_PENDING4,	CTC_EVENT_START,	ctcm_action_nop  },1968	{ CH_XID7_PENDING4,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1969	{ CH_XID7_PENDING4,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1970	{ CH_XID7_PENDING4,	CTC_EVENT_UC_ZERO,	ctcmpc_chx_rx  },1971	{ CH_XID7_PENDING4,	CTC_EVENT_UC_RCRESET,	ctcm_chx_setuperr  },1972	{ CH_XID7_PENDING4,	CTC_EVENT_UC_RSRESET,	ctcm_chx_setuperr  },1973	{ CH_XID7_PENDING4,	CTC_EVENT_ATTNBUSY,	ctcm_chx_iofatal  },1974	{ CH_XID7_PENDING4,	CTC_EVENT_TIMER,	ctcmpc_chx_resend  },1975	{ CH_XID7_PENDING4,	CTC_EVENT_IO_EBUSY,	ctcm_chx_fail  },1976 1977	{ CTC_STATE_RXIDLE,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1978	{ CTC_STATE_RXIDLE,	CTC_EVENT_START,	ctcm_action_nop  },1979	{ CTC_STATE_RXIDLE,	CTC_EVENT_FINSTAT,	ctcmpc_chx_rx  },1980	{ CTC_STATE_RXIDLE,	CTC_EVENT_UC_RCRESET,	ctcm_chx_rxdisc  },1981	{ CTC_STATE_RXIDLE,	CTC_EVENT_UC_RSRESET,	ctcm_chx_fail  },1982	{ CTC_STATE_RXIDLE,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1983	{ CTC_STATE_RXIDLE,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1984	{ CTC_STATE_RXIDLE,	CTC_EVENT_UC_ZERO,	ctcmpc_chx_rx  },1985 1986	{ CTC_STATE_TXINIT,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1987	{ CTC_STATE_TXINIT,	CTC_EVENT_START,	ctcm_action_nop  },1988	{ CTC_STATE_TXINIT,	CTC_EVENT_FINSTAT,	ctcm_chx_txidle  },1989	{ CTC_STATE_TXINIT,	CTC_EVENT_UC_RCRESET,	ctcm_chx_txiniterr  },1990	{ CTC_STATE_TXINIT,	CTC_EVENT_UC_RSRESET,	ctcm_chx_txiniterr  },1991	{ CTC_STATE_TXINIT,	CTC_EVENT_TIMER,	ctcm_chx_txiniterr  },1992	{ CTC_STATE_TXINIT,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },1993	{ CTC_STATE_TXINIT,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },1994	{ CTC_STATE_TXINIT,	CTC_EVENT_RSWEEP_TIMER,	ctcmpc_chx_send_sweep },1995 1996	{ CTC_STATE_TXIDLE,	CTC_EVENT_STOP,		ctcm_chx_haltio  },1997	{ CTC_STATE_TXIDLE,	CTC_EVENT_START,	ctcm_action_nop  },1998	{ CTC_STATE_TXIDLE,	CTC_EVENT_FINSTAT,	ctcmpc_chx_firstio  },1999	{ CTC_STATE_TXIDLE,	CTC_EVENT_UC_RCRESET,	ctcm_chx_fail  },2000	{ CTC_STATE_TXIDLE,	CTC_EVENT_UC_RSRESET,	ctcm_chx_fail  },2001	{ CTC_STATE_TXIDLE,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },2002	{ CTC_STATE_TXIDLE,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },2003	{ CTC_STATE_TXIDLE,	CTC_EVENT_RSWEEP_TIMER,	ctcmpc_chx_send_sweep },2004 2005	{ CTC_STATE_TERM,	CTC_EVENT_STOP,		ctcm_action_nop  },2006	{ CTC_STATE_TERM,	CTC_EVENT_START,	ctcm_chx_restart  },2007	{ CTC_STATE_TERM,	CTC_EVENT_FINSTAT,	ctcm_chx_stopped  },2008	{ CTC_STATE_TERM,	CTC_EVENT_UC_RCRESET,	ctcm_action_nop  },2009	{ CTC_STATE_TERM,	CTC_EVENT_UC_RSRESET,	ctcm_action_nop  },2010	{ CTC_STATE_TERM,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },2011	{ CTC_STATE_TERM,	CTC_EVENT_IO_EBUSY,	ctcm_chx_fail  },2012	{ CTC_STATE_TERM,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },2013 2014	{ CTC_STATE_DTERM,	CTC_EVENT_STOP,		ctcm_chx_haltio  },2015	{ CTC_STATE_DTERM,	CTC_EVENT_START,	ctcm_chx_restart  },2016	{ CTC_STATE_DTERM,	CTC_EVENT_FINSTAT,	ctcm_chx_setmode  },2017	{ CTC_STATE_DTERM,	CTC_EVENT_UC_RCRESET,	ctcm_action_nop  },2018	{ CTC_STATE_DTERM,	CTC_EVENT_UC_RSRESET,	ctcm_action_nop  },2019	{ CTC_STATE_DTERM,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },2020	{ CTC_STATE_DTERM,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },2021 2022	{ CTC_STATE_TX,		CTC_EVENT_STOP,		ctcm_chx_haltio  },2023	{ CTC_STATE_TX,		CTC_EVENT_START,	ctcm_action_nop  },2024	{ CTC_STATE_TX,		CTC_EVENT_FINSTAT,	ctcmpc_chx_txdone  },2025	{ CTC_STATE_TX,		CTC_EVENT_UC_RCRESET,	ctcm_chx_fail  },2026	{ CTC_STATE_TX,		CTC_EVENT_UC_RSRESET,	ctcm_chx_fail  },2027	{ CTC_STATE_TX,		CTC_EVENT_TIMER,	ctcm_chx_txretry  },2028	{ CTC_STATE_TX,		CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },2029	{ CTC_STATE_TX,		CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },2030	{ CTC_STATE_TX,		CTC_EVENT_RSWEEP_TIMER,	ctcmpc_chx_send_sweep },2031	{ CTC_STATE_TX,		CTC_EVENT_IO_EBUSY,	ctcm_chx_fail  },2032 2033	{ CTC_STATE_RXERR,	CTC_EVENT_STOP,		ctcm_chx_haltio  },2034	{ CTC_STATE_TXERR,	CTC_EVENT_STOP,		ctcm_chx_haltio  },2035	{ CTC_STATE_TXERR,	CTC_EVENT_IO_ENODEV,	ctcm_chx_iofatal  },2036	{ CTC_STATE_TXERR,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },2037	{ CTC_STATE_RXERR,	CTC_EVENT_MC_FAIL,	ctcm_chx_fail  },2038};2039 2040int mpc_ch_fsm_len = ARRAY_SIZE(ctcmpc_ch_fsm);2041 2042/*2043 * Actions for interface - statemachine.2044 */2045 2046/*2047 * Startup channels by sending CTC_EVENT_START to each channel.2048 *2049 * fi		An instance of an interface statemachine.2050 * event	The event, just happened.2051 * arg		Generic pointer, casted from struct net_device * upon call.2052 */2053static void dev_action_start(fsm_instance *fi, int event, void *arg)2054{2055	struct net_device *dev = arg;2056	struct ctcm_priv *priv = dev->ml_priv;2057	int direction;2058 2059	CTCMY_DBF_DEV_NAME(SETUP, dev, "");2060 2061	fsm_deltimer(&priv->restart_timer);2062	fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX);2063	if (IS_MPC(priv))2064		priv->mpcg->channels_terminating = 0;2065	for (direction = CTCM_READ; direction <= CTCM_WRITE; direction++) {2066		struct channel *ch = priv->channel[direction];2067		fsm_event(ch->fsm, CTC_EVENT_START, ch);2068	}2069}2070 2071/*2072 * Shutdown channels by sending CTC_EVENT_STOP to each channel.2073 *2074 * fi		An instance of an interface statemachine.2075 * event	The event, just happened.2076 * arg		Generic pointer, casted from struct net_device * upon call.2077 */2078static void dev_action_stop(fsm_instance *fi, int event, void *arg)2079{2080	int direction;2081	struct net_device *dev = arg;2082	struct ctcm_priv *priv = dev->ml_priv;2083 2084	CTCMY_DBF_DEV_NAME(SETUP, dev, "");2085 2086	fsm_newstate(fi, DEV_STATE_STOPWAIT_RXTX);2087	for (direction = CTCM_READ; direction <= CTCM_WRITE; direction++) {2088		struct channel *ch = priv->channel[direction];2089		fsm_event(ch->fsm, CTC_EVENT_STOP, ch);2090		ch->th_seq_num = 0x00;2091		CTCM_PR_DEBUG("%s: CH_th_seq= %08x\n",2092				__func__, ch->th_seq_num);2093	}2094	if (IS_MPC(priv))2095		fsm_newstate(priv->mpcg->fsm, MPCG_STATE_RESET);2096}2097 2098static void dev_action_restart(fsm_instance *fi, int event, void *arg)2099{2100	int restart_timer;2101	struct net_device *dev = arg;2102	struct ctcm_priv *priv = dev->ml_priv;2103 2104	CTCMY_DBF_DEV_NAME(TRACE, dev, "");2105 2106	if (IS_MPC(priv)) {2107		restart_timer = CTCM_TIME_1_SEC;2108	} else {2109		restart_timer = CTCM_TIME_5_SEC;2110	}2111	dev_info(&dev->dev, "Restarting device\n");2112 2113	dev_action_stop(fi, event, arg);2114	fsm_event(priv->fsm, DEV_EVENT_STOP, dev);2115	if (IS_MPC(priv))2116		fsm_newstate(priv->mpcg->fsm, MPCG_STATE_RESET);2117 2118	/* going back into start sequence too quickly can	  */2119	/* result in the other side becoming unreachable   due	  */2120	/* to sense reported when IO is aborted			  */2121	fsm_addtimer(&priv->restart_timer, restart_timer,2122			DEV_EVENT_START, dev);2123}2124 2125/*2126 * Called from channel statemachine2127 * when a channel is up and running.2128 *2129 * fi		An instance of an interface statemachine.2130 * event	The event, just happened.2131 * arg		Generic pointer, casted from struct net_device * upon call.2132 */2133static void dev_action_chup(fsm_instance *fi, int event, void *arg)2134{2135	struct net_device *dev = arg;2136	struct ctcm_priv *priv = dev->ml_priv;2137	int dev_stat = fsm_getstate(fi);2138 2139	CTCM_DBF_TEXT_(SETUP, CTC_DBF_NOTICE,2140			"%s(%s): priv = %p [%d,%d]\n ",	CTCM_FUNTAIL,2141				dev->name, dev->ml_priv, dev_stat, event);2142 2143	switch (fsm_getstate(fi)) {2144	case DEV_STATE_STARTWAIT_RXTX:2145		if (event == DEV_EVENT_RXUP)2146			fsm_newstate(fi, DEV_STATE_STARTWAIT_TX);2147		else2148			fsm_newstate(fi, DEV_STATE_STARTWAIT_RX);2149		break;2150	case DEV_STATE_STARTWAIT_RX:2151		if (event == DEV_EVENT_RXUP) {2152			fsm_newstate(fi, DEV_STATE_RUNNING);2153			dev_info(&dev->dev,2154				"Connected with remote side\n");2155			ctcm_clear_busy(dev);2156		}2157		break;2158	case DEV_STATE_STARTWAIT_TX:2159		if (event == DEV_EVENT_TXUP) {2160			fsm_newstate(fi, DEV_STATE_RUNNING);2161			dev_info(&dev->dev,2162				"Connected with remote side\n");2163			ctcm_clear_busy(dev);2164		}2165		break;2166	case DEV_STATE_STOPWAIT_TX:2167		if (event == DEV_EVENT_RXUP)2168			fsm_newstate(fi, DEV_STATE_STOPWAIT_RXTX);2169		break;2170	case DEV_STATE_STOPWAIT_RX:2171		if (event == DEV_EVENT_TXUP)2172			fsm_newstate(fi, DEV_STATE_STOPWAIT_RXTX);2173		break;2174	}2175 2176	if (IS_MPC(priv)) {2177		if (event == DEV_EVENT_RXUP)2178			mpc_channel_action(priv->channel[CTCM_READ],2179				CTCM_READ, MPC_CHANNEL_ADD);2180		else2181			mpc_channel_action(priv->channel[CTCM_WRITE],2182				CTCM_WRITE, MPC_CHANNEL_ADD);2183	}2184}2185 2186/*2187 * Called from device statemachine2188 * when a channel has been shutdown.2189 *2190 * fi		An instance of an interface statemachine.2191 * event	The event, just happened.2192 * arg		Generic pointer, casted from struct net_device * upon call.2193 */2194static void dev_action_chdown(fsm_instance *fi, int event, void *arg)2195{2196 2197	struct net_device *dev = arg;2198	struct ctcm_priv *priv = dev->ml_priv;2199 2200	CTCMY_DBF_DEV_NAME(SETUP, dev, "");2201 2202	switch (fsm_getstate(fi)) {2203	case DEV_STATE_RUNNING:2204		if (event == DEV_EVENT_TXDOWN)2205			fsm_newstate(fi, DEV_STATE_STARTWAIT_TX);2206		else2207			fsm_newstate(fi, DEV_STATE_STARTWAIT_RX);2208		break;2209	case DEV_STATE_STARTWAIT_RX:2210		if (event == DEV_EVENT_TXDOWN)2211			fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX);2212		break;2213	case DEV_STATE_STARTWAIT_TX:2214		if (event == DEV_EVENT_RXDOWN)2215			fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX);2216		break;2217	case DEV_STATE_STOPWAIT_RXTX:2218		if (event == DEV_EVENT_TXDOWN)2219			fsm_newstate(fi, DEV_STATE_STOPWAIT_RX);2220		else2221			fsm_newstate(fi, DEV_STATE_STOPWAIT_TX);2222		break;2223	case DEV_STATE_STOPWAIT_RX:2224		if (event == DEV_EVENT_RXDOWN)2225			fsm_newstate(fi, DEV_STATE_STOPPED);2226		break;2227	case DEV_STATE_STOPWAIT_TX:2228		if (event == DEV_EVENT_TXDOWN)2229			fsm_newstate(fi, DEV_STATE_STOPPED);2230		break;2231	}2232	if (IS_MPC(priv)) {2233		if (event == DEV_EVENT_RXDOWN)2234			mpc_channel_action(priv->channel[CTCM_READ],2235				CTCM_READ, MPC_CHANNEL_REMOVE);2236		else2237			mpc_channel_action(priv->channel[CTCM_WRITE],2238				CTCM_WRITE, MPC_CHANNEL_REMOVE);2239	}2240}2241 2242const fsm_node dev_fsm[] = {2243	{ DEV_STATE_STOPPED,        DEV_EVENT_START,   dev_action_start   },2244	{ DEV_STATE_STOPWAIT_RXTX,  DEV_EVENT_START,   dev_action_start   },2245	{ DEV_STATE_STOPWAIT_RXTX,  DEV_EVENT_RXDOWN,  dev_action_chdown  },2246	{ DEV_STATE_STOPWAIT_RXTX,  DEV_EVENT_TXDOWN,  dev_action_chdown  },2247	{ DEV_STATE_STOPWAIT_RXTX,  DEV_EVENT_RESTART, dev_action_restart },2248	{ DEV_STATE_STOPWAIT_RX,    DEV_EVENT_START,   dev_action_start   },2249	{ DEV_STATE_STOPWAIT_RX,    DEV_EVENT_RXUP,    dev_action_chup    },2250	{ DEV_STATE_STOPWAIT_RX,    DEV_EVENT_TXUP,    dev_action_chup    },2251	{ DEV_STATE_STOPWAIT_RX,    DEV_EVENT_RXDOWN,  dev_action_chdown  },2252	{ DEV_STATE_STOPWAIT_RX,    DEV_EVENT_RESTART, dev_action_restart },2253	{ DEV_STATE_STOPWAIT_TX,    DEV_EVENT_START,   dev_action_start   },2254	{ DEV_STATE_STOPWAIT_TX,    DEV_EVENT_RXUP,    dev_action_chup    },2255	{ DEV_STATE_STOPWAIT_TX,    DEV_EVENT_TXUP,    dev_action_chup    },2256	{ DEV_STATE_STOPWAIT_TX,    DEV_EVENT_TXDOWN,  dev_action_chdown  },2257	{ DEV_STATE_STOPWAIT_TX,    DEV_EVENT_RESTART, dev_action_restart },2258	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_STOP,    dev_action_stop    },2259	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXUP,    dev_action_chup    },2260	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXUP,    dev_action_chup    },2261	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXDOWN,  dev_action_chdown  },2262	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXDOWN,  dev_action_chdown  },2263	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RESTART, dev_action_restart },2264	{ DEV_STATE_STARTWAIT_TX,   DEV_EVENT_STOP,    dev_action_stop    },2265	{ DEV_STATE_STARTWAIT_TX,   DEV_EVENT_RXUP,    dev_action_chup    },2266	{ DEV_STATE_STARTWAIT_TX,   DEV_EVENT_TXUP,    dev_action_chup    },2267	{ DEV_STATE_STARTWAIT_TX,   DEV_EVENT_RXDOWN,  dev_action_chdown  },2268	{ DEV_STATE_STARTWAIT_TX,   DEV_EVENT_RESTART, dev_action_restart },2269	{ DEV_STATE_STARTWAIT_RX,   DEV_EVENT_STOP,    dev_action_stop    },2270	{ DEV_STATE_STARTWAIT_RX,   DEV_EVENT_RXUP,    dev_action_chup    },2271	{ DEV_STATE_STARTWAIT_RX,   DEV_EVENT_TXUP,    dev_action_chup    },2272	{ DEV_STATE_STARTWAIT_RX,   DEV_EVENT_TXDOWN,  dev_action_chdown  },2273	{ DEV_STATE_STARTWAIT_RX,   DEV_EVENT_RESTART, dev_action_restart },2274	{ DEV_STATE_RUNNING,        DEV_EVENT_STOP,    dev_action_stop    },2275	{ DEV_STATE_RUNNING,        DEV_EVENT_RXDOWN,  dev_action_chdown  },2276	{ DEV_STATE_RUNNING,        DEV_EVENT_TXDOWN,  dev_action_chdown  },2277	{ DEV_STATE_RUNNING,        DEV_EVENT_TXUP,    ctcm_action_nop    },2278	{ DEV_STATE_RUNNING,        DEV_EVENT_RXUP,    ctcm_action_nop    },2279	{ DEV_STATE_RUNNING,        DEV_EVENT_RESTART, dev_action_restart },2280};2281 2282int dev_fsm_len = ARRAY_SIZE(dev_fsm);2283 2284/* --- This is the END my friend --- */2285 2286