Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ctcm: infrastructure for replaced ctc driver

ctcm driver supports the channel-to-channel connections of the
old ctc driver plus an additional MPC protocol to provide SNA
connectivity.

This new ctcm driver replaces the existing ctc driver.

Signed-off-by: Peter Tiedemann <ptiedem@de.ibm.com>
Signed-off-by: Ursula Braun <braunu@de.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

authored by

Peter Tiedemann and committed by
Jeff Garzik
293d984f f423f735

+7920 -8
+7 -5
drivers/s390/net/Kconfig
··· 11 11 To compile as a module, choose M. The module name is lcs.ko. 12 12 If you do not know what it is, it's safe to choose Y. 13 13 14 - config CTC 15 - tristate "CTC device support" 14 + config CTCM 15 + tristate "CTC and MPC SNA device support" 16 16 depends on CCW && NETDEVICES 17 17 help 18 18 Select this option if you want to use channel-to-channel 19 19 point-to-point networking on IBM System z. 20 20 This device driver supports real CTC coupling using ESCON. 21 21 It also supports virtual CTCs when running under VM. 22 - To compile as a module, choose M. The module name is ctc.ko. 22 + This driver also supports channel-to-channel MPC SNA devices. 23 + MPC is an SNA protocol device used by Communication Server for Linux. 24 + To compile as a module, choose M. The module name is ctcm.ko. 23 25 To compile into the kernel, choose Y. 24 26 If you do not need any channel-to-channel connection, choose N. 25 27 ··· 86 84 802.1q VLAN support in the qeth device driver. 87 85 88 86 config CCWGROUP 89 - tristate 90 - default (LCS || CTC || QETH) 87 + tristate 88 + default (LCS || CTCM || QETH) 91 89 92 90 endmenu
+2 -3
drivers/s390/net/Makefile
··· 2 2 # S/390 network devices 3 3 # 4 4 5 - ctc-objs := ctcmain.o ctcdbug.o 6 - 5 + ctcm-y += ctcm_main.o ctcm_fsms.o ctcm_mpc.o ctcm_sysfs.o ctcm_dbug.o 6 + obj-$(CONFIG_CTCM) += ctcm.o fsm.o cu3088.o 7 7 obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o 8 8 obj-$(CONFIG_SMSGIUCV) += smsgiucv.o 9 - obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o 10 9 obj-$(CONFIG_LCS) += lcs.o cu3088.o 11 10 obj-$(CONFIG_CLAW) += claw.o cu3088.o 12 11 qeth-y := qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o
+67
drivers/s390/net/ctcm_dbug.c
··· 1 + /* 2 + * drivers/s390/net/ctcm_dbug.c 3 + * 4 + * Copyright IBM Corp. 2001, 2007 5 + * Authors: Peter Tiedemann (ptiedem@de.ibm.com) 6 + * 7 + */ 8 + 9 + #include <linux/stddef.h> 10 + #include <linux/kernel.h> 11 + #include <linux/errno.h> 12 + #include <linux/slab.h> 13 + #include <linux/ctype.h> 14 + #include <linux/sysctl.h> 15 + #include <linux/module.h> 16 + #include <linux/init.h> 17 + #include <linux/fs.h> 18 + #include <linux/debugfs.h> 19 + #include "ctcm_dbug.h" 20 + 21 + /* 22 + * Debug Facility Stuff 23 + */ 24 + 25 + DEFINE_PER_CPU(char[256], ctcm_dbf_txt_buf); 26 + 27 + struct ctcm_dbf_info ctcm_dbf[CTCM_DBF_INFOS] = { 28 + [CTCM_DBF_SETUP] = {"ctc_setup", 8, 1, 64, 5, NULL}, 29 + [CTCM_DBF_ERROR] = {"ctc_error", 8, 1, 64, 3, NULL}, 30 + [CTCM_DBF_TRACE] = {"ctc_trace", 8, 1, 64, 3, NULL}, 31 + [CTCM_DBF_MPC_SETUP] = {"mpc_setup", 8, 1, 64, 5, NULL}, 32 + [CTCM_DBF_MPC_ERROR] = {"mpc_error", 8, 1, 64, 3, NULL}, 33 + [CTCM_DBF_MPC_TRACE] = {"mpc_trace", 8, 1, 64, 3, NULL}, 34 + }; 35 + 36 + void ctcm_unregister_dbf_views(void) 37 + { 38 + int x; 39 + for (x = 0; x < CTCM_DBF_INFOS; x++) { 40 + debug_unregister(ctcm_dbf[x].id); 41 + ctcm_dbf[x].id = NULL; 42 + } 43 + } 44 + 45 + int ctcm_register_dbf_views(void) 46 + { 47 + int x; 48 + for (x = 0; x < CTCM_DBF_INFOS; x++) { 49 + /* register the areas */ 50 + ctcm_dbf[x].id = debug_register(ctcm_dbf[x].name, 51 + ctcm_dbf[x].pages, 52 + ctcm_dbf[x].areas, 53 + ctcm_dbf[x].len); 54 + if (ctcm_dbf[x].id == NULL) { 55 + ctcm_unregister_dbf_views(); 56 + return -ENOMEM; 57 + } 58 + 59 + /* register a view */ 60 + debug_register_view(ctcm_dbf[x].id, &debug_hex_ascii_view); 61 + /* set a passing level */ 62 + debug_set_level(ctcm_dbf[x].id, ctcm_dbf[x].level); 63 + } 64 + 65 + return 0; 66 + } 67 +
+158
drivers/s390/net/ctcm_dbug.h
··· 1 + /* 2 + * drivers/s390/net/ctcm_dbug.h 3 + * 4 + * Copyright IBM Corp. 2001, 2007 5 + * Authors: Peter Tiedemann (ptiedem@de.ibm.com) 6 + * 7 + */ 8 + 9 + #ifndef _CTCM_DBUG_H_ 10 + #define _CTCM_DBUG_H_ 11 + 12 + /* 13 + * Debug Facility stuff 14 + */ 15 + 16 + #include <asm/debug.h> 17 + 18 + #ifdef DEBUG 19 + #define do_debug 1 20 + #else 21 + #define do_debug 0 22 + #endif 23 + #ifdef DEBUGDATA 24 + #define do_debug_data 1 25 + #else 26 + #define do_debug_data 0 27 + #endif 28 + #ifdef DEBUGCCW 29 + #define do_debug_ccw 1 30 + #else 31 + #define do_debug_ccw 0 32 + #endif 33 + 34 + /* define dbf debug levels similar to kernel msg levels */ 35 + #define CTC_DBF_ALWAYS 0 /* always print this */ 36 + #define CTC_DBF_EMERG 0 /* system is unusable */ 37 + #define CTC_DBF_ALERT 1 /* action must be taken immediately */ 38 + #define CTC_DBF_CRIT 2 /* critical conditions */ 39 + #define CTC_DBF_ERROR 3 /* error conditions */ 40 + #define CTC_DBF_WARN 4 /* warning conditions */ 41 + #define CTC_DBF_NOTICE 5 /* normal but significant condition */ 42 + #define CTC_DBF_INFO 5 /* informational */ 43 + #define CTC_DBF_DEBUG 6 /* debug-level messages */ 44 + 45 + DECLARE_PER_CPU(char[256], ctcm_dbf_txt_buf); 46 + 47 + enum ctcm_dbf_names { 48 + CTCM_DBF_SETUP, 49 + CTCM_DBF_ERROR, 50 + CTCM_DBF_TRACE, 51 + CTCM_DBF_MPC_SETUP, 52 + CTCM_DBF_MPC_ERROR, 53 + CTCM_DBF_MPC_TRACE, 54 + CTCM_DBF_INFOS /* must be last element */ 55 + }; 56 + 57 + struct ctcm_dbf_info { 58 + char name[DEBUG_MAX_NAME_LEN]; 59 + int pages; 60 + int areas; 61 + int len; 62 + int level; 63 + debug_info_t *id; 64 + }; 65 + 66 + extern struct ctcm_dbf_info ctcm_dbf[CTCM_DBF_INFOS]; 67 + 68 + int ctcm_register_dbf_views(void); 69 + void ctcm_unregister_dbf_views(void); 70 + 71 + static inline const char *strtail(const char *s, int n) 72 + { 73 + int l = strlen(s); 74 + return (l > n) ? s + (l - n) : s; 75 + } 76 + 77 + /* sort out levels early to avoid unnecessary sprintfs */ 78 + static inline int ctcm_dbf_passes(debug_info_t *dbf_grp, int level) 79 + { 80 + return (dbf_grp->level >= level); 81 + } 82 + 83 + #define CTCM_FUNTAIL strtail((char *)__func__, 16) 84 + 85 + #define CTCM_DBF_TEXT(name, level, text) \ 86 + do { \ 87 + debug_text_event(ctcm_dbf[CTCM_DBF_##name].id, level, text); \ 88 + } while (0) 89 + 90 + #define CTCM_DBF_HEX(name, level, addr, len) \ 91 + do { \ 92 + debug_event(ctcm_dbf[CTCM_DBF_##name].id, \ 93 + level, (void *)(addr), len); \ 94 + } while (0) 95 + 96 + #define CTCM_DBF_TEXT_(name, level, text...) \ 97 + do { \ 98 + if (ctcm_dbf_passes(ctcm_dbf[CTCM_DBF_##name].id, level)) { \ 99 + char *ctcm_dbf_txt_buf = \ 100 + get_cpu_var(ctcm_dbf_txt_buf); \ 101 + sprintf(ctcm_dbf_txt_buf, text); \ 102 + debug_text_event(ctcm_dbf[CTCM_DBF_##name].id, \ 103 + level, ctcm_dbf_txt_buf); \ 104 + put_cpu_var(ctcm_dbf_txt_buf); \ 105 + } \ 106 + } while (0) 107 + 108 + /* 109 + * cat : one of {setup, mpc_setup, trace, mpc_trace, error, mpc_error}. 110 + * dev : netdevice with valid name field. 111 + * text: any text string. 112 + */ 113 + #define CTCM_DBF_DEV_NAME(cat, dev, text) \ 114 + do { \ 115 + CTCM_DBF_TEXT_(cat, CTC_DBF_INFO, "%s(%s) : %s", \ 116 + CTCM_FUNTAIL, dev->name, text); \ 117 + } while (0) 118 + 119 + #define MPC_DBF_DEV_NAME(cat, dev, text) \ 120 + do { \ 121 + CTCM_DBF_TEXT_(MPC_##cat, CTC_DBF_INFO, "%s(%s) : %s", \ 122 + CTCM_FUNTAIL, dev->name, text); \ 123 + } while (0) 124 + 125 + #define CTCMY_DBF_DEV_NAME(cat, dev, text) \ 126 + do { \ 127 + if (IS_MPCDEV(dev)) \ 128 + MPC_DBF_DEV_NAME(cat, dev, text); \ 129 + else \ 130 + CTCM_DBF_DEV_NAME(cat, dev, text); \ 131 + } while (0) 132 + 133 + /* 134 + * cat : one of {setup, mpc_setup, trace, mpc_trace, error, mpc_error}. 135 + * dev : netdevice. 136 + * text: any text string. 137 + */ 138 + #define CTCM_DBF_DEV(cat, dev, text) \ 139 + do { \ 140 + CTCM_DBF_TEXT_(cat, CTC_DBF_INFO, "%s(%p) : %s", \ 141 + CTCM_FUNTAIL, dev, text); \ 142 + } while (0) 143 + 144 + #define MPC_DBF_DEV(cat, dev, text) \ 145 + do { \ 146 + CTCM_DBF_TEXT_(MPC_##cat, CTC_DBF_INFO, "%s(%p) : %s", \ 147 + CTCM_FUNTAIL, dev, text); \ 148 + } while (0) 149 + 150 + #define CTCMY_DBF_DEV(cat, dev, text) \ 151 + do { \ 152 + if (IS_MPCDEV(dev)) \ 153 + MPC_DBF_DEV(cat, dev, text); \ 154 + else \ 155 + CTCM_DBF_DEV(cat, dev, text); \ 156 + } while (0) 157 + 158 + #endif
+2347
drivers/s390/net/ctcm_fsms.c
··· 1 + /* 2 + * drivers/s390/net/ctcm_fsms.c 3 + * 4 + * Copyright IBM Corp. 2001, 2007 5 + * Authors: Fritz Elfert (felfert@millenux.com) 6 + * Peter Tiedemann (ptiedem@de.ibm.com) 7 + * MPC additions : 8 + * Belinda Thompson (belindat@us.ibm.com) 9 + * Andy Richter (richtera@us.ibm.com) 10 + */ 11 + 12 + #undef DEBUG 13 + #undef DEBUGDATA 14 + #undef DEBUGCCW 15 + 16 + #include <linux/module.h> 17 + #include <linux/init.h> 18 + #include <linux/kernel.h> 19 + #include <linux/slab.h> 20 + #include <linux/errno.h> 21 + #include <linux/types.h> 22 + #include <linux/interrupt.h> 23 + #include <linux/timer.h> 24 + #include <linux/bitops.h> 25 + 26 + #include <linux/signal.h> 27 + #include <linux/string.h> 28 + 29 + #include <linux/ip.h> 30 + #include <linux/if_arp.h> 31 + #include <linux/tcp.h> 32 + #include <linux/skbuff.h> 33 + #include <linux/ctype.h> 34 + #include <net/dst.h> 35 + 36 + #include <linux/io.h> 37 + #include <asm/ccwdev.h> 38 + #include <asm/ccwgroup.h> 39 + #include <linux/uaccess.h> 40 + 41 + #include <asm/idals.h> 42 + 43 + #include "fsm.h" 44 + #include "cu3088.h" 45 + 46 + #include "ctcm_dbug.h" 47 + #include "ctcm_main.h" 48 + #include "ctcm_fsms.h" 49 + 50 + const char *dev_state_names[] = { 51 + [DEV_STATE_STOPPED] = "Stopped", 52 + [DEV_STATE_STARTWAIT_RXTX] = "StartWait RXTX", 53 + [DEV_STATE_STARTWAIT_RX] = "StartWait RX", 54 + [DEV_STATE_STARTWAIT_TX] = "StartWait TX", 55 + [DEV_STATE_STOPWAIT_RXTX] = "StopWait RXTX", 56 + [DEV_STATE_STOPWAIT_RX] = "StopWait RX", 57 + [DEV_STATE_STOPWAIT_TX] = "StopWait TX", 58 + [DEV_STATE_RUNNING] = "Running", 59 + }; 60 + 61 + const char *dev_event_names[] = { 62 + [DEV_EVENT_START] = "Start", 63 + [DEV_EVENT_STOP] = "Stop", 64 + [DEV_EVENT_RXUP] = "RX up", 65 + [DEV_EVENT_TXUP] = "TX up", 66 + [DEV_EVENT_RXDOWN] = "RX down", 67 + [DEV_EVENT_TXDOWN] = "TX down", 68 + [DEV_EVENT_RESTART] = "Restart", 69 + }; 70 + 71 + const char *ctc_ch_event_names[] = { 72 + [CTC_EVENT_IO_SUCCESS] = "ccw_device success", 73 + [CTC_EVENT_IO_EBUSY] = "ccw_device busy", 74 + [CTC_EVENT_IO_ENODEV] = "ccw_device enodev", 75 + [CTC_EVENT_IO_UNKNOWN] = "ccw_device unknown", 76 + [CTC_EVENT_ATTNBUSY] = "Status ATTN & BUSY", 77 + [CTC_EVENT_ATTN] = "Status ATTN", 78 + [CTC_EVENT_BUSY] = "Status BUSY", 79 + [CTC_EVENT_UC_RCRESET] = "Unit check remote reset", 80 + [CTC_EVENT_UC_RSRESET] = "Unit check remote system reset", 81 + [CTC_EVENT_UC_TXTIMEOUT] = "Unit check TX timeout", 82 + [CTC_EVENT_UC_TXPARITY] = "Unit check TX parity", 83 + [CTC_EVENT_UC_HWFAIL] = "Unit check Hardware failure", 84 + [CTC_EVENT_UC_RXPARITY] = "Unit check RX parity", 85 + [CTC_EVENT_UC_ZERO] = "Unit check ZERO", 86 + [CTC_EVENT_UC_UNKNOWN] = "Unit check Unknown", 87 + [CTC_EVENT_SC_UNKNOWN] = "SubChannel check Unknown", 88 + [CTC_EVENT_MC_FAIL] = "Machine check failure", 89 + [CTC_EVENT_MC_GOOD] = "Machine check operational", 90 + [CTC_EVENT_IRQ] = "IRQ normal", 91 + [CTC_EVENT_FINSTAT] = "IRQ final", 92 + [CTC_EVENT_TIMER] = "Timer", 93 + [CTC_EVENT_START] = "Start", 94 + [CTC_EVENT_STOP] = "Stop", 95 + /* 96 + * additional MPC events 97 + */ 98 + [CTC_EVENT_SEND_XID] = "XID Exchange", 99 + [CTC_EVENT_RSWEEP_TIMER] = "MPC Group Sweep Timer", 100 + }; 101 + 102 + const char *ctc_ch_state_names[] = { 103 + [CTC_STATE_IDLE] = "Idle", 104 + [CTC_STATE_STOPPED] = "Stopped", 105 + [CTC_STATE_STARTWAIT] = "StartWait", 106 + [CTC_STATE_STARTRETRY] = "StartRetry", 107 + [CTC_STATE_SETUPWAIT] = "SetupWait", 108 + [CTC_STATE_RXINIT] = "RX init", 109 + [CTC_STATE_TXINIT] = "TX init", 110 + [CTC_STATE_RX] = "RX", 111 + [CTC_STATE_TX] = "TX", 112 + [CTC_STATE_RXIDLE] = "RX idle", 113 + [CTC_STATE_TXIDLE] = "TX idle", 114 + [CTC_STATE_RXERR] = "RX error", 115 + [CTC_STATE_TXERR] = "TX error", 116 + [CTC_STATE_TERM] = "Terminating", 117 + [CTC_STATE_DTERM] = "Restarting", 118 + [CTC_STATE_NOTOP] = "Not operational", 119 + /* 120 + * additional MPC states 121 + */ 122 + [CH_XID0_PENDING] = "Pending XID0 Start", 123 + [CH_XID0_INPROGRESS] = "In XID0 Negotiations ", 124 + [CH_XID7_PENDING] = "Pending XID7 P1 Start", 125 + [CH_XID7_PENDING1] = "Active XID7 P1 Exchange ", 126 + [CH_XID7_PENDING2] = "Pending XID7 P2 Start ", 127 + [CH_XID7_PENDING3] = "Active XID7 P2 Exchange ", 128 + [CH_XID7_PENDING4] = "XID7 Complete - Pending READY ", 129 + }; 130 + 131 + static void ctcm_action_nop(fsm_instance *fi, int event, void *arg); 132 + 133 + /* 134 + * ----- static ctcm actions for channel statemachine ----- 135 + * 136 + */ 137 + static void chx_txdone(fsm_instance *fi, int event, void *arg); 138 + static void chx_rx(fsm_instance *fi, int event, void *arg); 139 + static void chx_rxidle(fsm_instance *fi, int event, void *arg); 140 + static void chx_firstio(fsm_instance *fi, int event, void *arg); 141 + static void ctcm_chx_setmode(fsm_instance *fi, int event, void *arg); 142 + static void ctcm_chx_start(fsm_instance *fi, int event, void *arg); 143 + static void ctcm_chx_haltio(fsm_instance *fi, int event, void *arg); 144 + static void ctcm_chx_stopped(fsm_instance *fi, int event, void *arg); 145 + static void ctcm_chx_stop(fsm_instance *fi, int event, void *arg); 146 + static void ctcm_chx_fail(fsm_instance *fi, int event, void *arg); 147 + static void ctcm_chx_setuperr(fsm_instance *fi, int event, void *arg); 148 + static void ctcm_chx_restart(fsm_instance *fi, int event, void *arg); 149 + static void ctcm_chx_rxiniterr(fsm_instance *fi, int event, void *arg); 150 + static void ctcm_chx_rxinitfail(fsm_instance *fi, int event, void *arg); 151 + static void ctcm_chx_rxdisc(fsm_instance *fi, int event, void *arg); 152 + static void ctcm_chx_txiniterr(fsm_instance *fi, int event, void *arg); 153 + static void ctcm_chx_txretry(fsm_instance *fi, int event, void *arg); 154 + static void ctcm_chx_iofatal(fsm_instance *fi, int event, void *arg); 155 + 156 + /* 157 + * ----- static ctcmpc actions for ctcmpc channel statemachine ----- 158 + * 159 + */ 160 + static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg); 161 + static void ctcmpc_chx_rx(fsm_instance *fi, int event, void *arg); 162 + static void ctcmpc_chx_firstio(fsm_instance *fi, int event, void *arg); 163 + /* shared : 164 + static void ctcm_chx_setmode(fsm_instance *fi, int event, void *arg); 165 + static void ctcm_chx_start(fsm_instance *fi, int event, void *arg); 166 + static void ctcm_chx_haltio(fsm_instance *fi, int event, void *arg); 167 + static void ctcm_chx_stopped(fsm_instance *fi, int event, void *arg); 168 + static void ctcm_chx_stop(fsm_instance *fi, int event, void *arg); 169 + static void ctcm_chx_fail(fsm_instance *fi, int event, void *arg); 170 + static void ctcm_chx_setuperr(fsm_instance *fi, int event, void *arg); 171 + static void ctcm_chx_restart(fsm_instance *fi, int event, void *arg); 172 + static void ctcm_chx_rxiniterr(fsm_instance *fi, int event, void *arg); 173 + static void ctcm_chx_rxinitfail(fsm_instance *fi, int event, void *arg); 174 + static void ctcm_chx_rxdisc(fsm_instance *fi, int event, void *arg); 175 + static void ctcm_chx_txiniterr(fsm_instance *fi, int event, void *arg); 176 + static void ctcm_chx_txretry(fsm_instance *fi, int event, void *arg); 177 + static void ctcm_chx_iofatal(fsm_instance *fi, int event, void *arg); 178 + */ 179 + static void ctcmpc_chx_attn(fsm_instance *fsm, int event, void *arg); 180 + static void ctcmpc_chx_attnbusy(fsm_instance *, int, void *); 181 + static void ctcmpc_chx_resend(fsm_instance *, int, void *); 182 + static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg); 183 + 184 + /** 185 + * Check return code of a preceeding ccw_device call, halt_IO etc... 186 + * 187 + * ch : The channel, the error belongs to. 188 + * Returns the error code (!= 0) to inspect. 189 + */ 190 + void ctcm_ccw_check_rc(struct channel *ch, int rc, char *msg) 191 + { 192 + CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR, 193 + "ccw error %s (%s): %04x\n", ch->id, msg, rc); 194 + switch (rc) { 195 + case -EBUSY: 196 + ctcm_pr_warn("%s (%s): Busy !\n", ch->id, msg); 197 + fsm_event(ch->fsm, CTC_EVENT_IO_EBUSY, ch); 198 + break; 199 + case -ENODEV: 200 + ctcm_pr_emerg("%s (%s): Invalid device called for IO\n", 201 + ch->id, msg); 202 + fsm_event(ch->fsm, CTC_EVENT_IO_ENODEV, ch); 203 + break; 204 + default: 205 + ctcm_pr_emerg("%s (%s): Unknown error in do_IO %04x\n", 206 + ch->id, msg, rc); 207 + fsm_event(ch->fsm, CTC_EVENT_IO_UNKNOWN, ch); 208 + } 209 + } 210 + 211 + void ctcm_purge_skb_queue(struct sk_buff_head *q) 212 + { 213 + struct sk_buff *skb; 214 + 215 + CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__); 216 + 217 + while ((skb = skb_dequeue(q))) { 218 + atomic_dec(&skb->users); 219 + dev_kfree_skb_any(skb); 220 + } 221 + } 222 + 223 + /** 224 + * NOP action for statemachines 225 + */ 226 + static void ctcm_action_nop(fsm_instance *fi, int event, void *arg) 227 + { 228 + } 229 + 230 + /* 231 + * Actions for channel - statemachines. 232 + */ 233 + 234 + /** 235 + * Normal data has been send. Free the corresponding 236 + * skb (it's in io_queue), reset dev->tbusy and 237 + * revert to idle state. 238 + * 239 + * fi An instance of a channel statemachine. 240 + * event The event, just happened. 241 + * arg Generic pointer, casted from channel * upon call. 242 + */ 243 + static void chx_txdone(fsm_instance *fi, int event, void *arg) 244 + { 245 + struct channel *ch = arg; 246 + struct net_device *dev = ch->netdev; 247 + struct ctcm_priv *priv = dev->priv; 248 + struct sk_buff *skb; 249 + int first = 1; 250 + int i; 251 + unsigned long duration; 252 + struct timespec done_stamp = current_kernel_time(); /* xtime */ 253 + 254 + duration = 255 + (done_stamp.tv_sec - ch->prof.send_stamp.tv_sec) * 1000000 + 256 + (done_stamp.tv_nsec - ch->prof.send_stamp.tv_nsec) / 1000; 257 + if (duration > ch->prof.tx_time) 258 + ch->prof.tx_time = duration; 259 + 260 + if (ch->irb->scsw.count != 0) 261 + ctcm_pr_debug("%s: TX not complete, remaining %d bytes\n", 262 + dev->name, ch->irb->scsw.count); 263 + fsm_deltimer(&ch->timer); 264 + while ((skb = skb_dequeue(&ch->io_queue))) { 265 + priv->stats.tx_packets++; 266 + priv->stats.tx_bytes += skb->len - LL_HEADER_LENGTH; 267 + if (first) { 268 + priv->stats.tx_bytes += 2; 269 + first = 0; 270 + } 271 + atomic_dec(&skb->users); 272 + dev_kfree_skb_irq(skb); 273 + } 274 + spin_lock(&ch->collect_lock); 275 + clear_normalized_cda(&ch->ccw[4]); 276 + if (ch->collect_len > 0) { 277 + int rc; 278 + 279 + if (ctcm_checkalloc_buffer(ch)) { 280 + spin_unlock(&ch->collect_lock); 281 + return; 282 + } 283 + ch->trans_skb->data = ch->trans_skb_data; 284 + skb_reset_tail_pointer(ch->trans_skb); 285 + ch->trans_skb->len = 0; 286 + if (ch->prof.maxmulti < (ch->collect_len + 2)) 287 + ch->prof.maxmulti = ch->collect_len + 2; 288 + if (ch->prof.maxcqueue < skb_queue_len(&ch->collect_queue)) 289 + ch->prof.maxcqueue = skb_queue_len(&ch->collect_queue); 290 + *((__u16 *)skb_put(ch->trans_skb, 2)) = ch->collect_len + 2; 291 + i = 0; 292 + while ((skb = skb_dequeue(&ch->collect_queue))) { 293 + skb_copy_from_linear_data(skb, 294 + skb_put(ch->trans_skb, skb->len), skb->len); 295 + priv->stats.tx_packets++; 296 + priv->stats.tx_bytes += skb->len - LL_HEADER_LENGTH; 297 + atomic_dec(&skb->users); 298 + dev_kfree_skb_irq(skb); 299 + i++; 300 + } 301 + ch->collect_len = 0; 302 + spin_unlock(&ch->collect_lock); 303 + ch->ccw[1].count = ch->trans_skb->len; 304 + fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch); 305 + ch->prof.send_stamp = current_kernel_time(); /* xtime */ 306 + rc = ccw_device_start(ch->cdev, &ch->ccw[0], 307 + (unsigned long)ch, 0xff, 0); 308 + ch->prof.doios_multi++; 309 + if (rc != 0) { 310 + priv->stats.tx_dropped += i; 311 + priv->stats.tx_errors += i; 312 + fsm_deltimer(&ch->timer); 313 + ctcm_ccw_check_rc(ch, rc, "chained TX"); 314 + } 315 + } else { 316 + spin_unlock(&ch->collect_lock); 317 + fsm_newstate(fi, CTC_STATE_TXIDLE); 318 + } 319 + ctcm_clear_busy_do(dev); 320 + } 321 + 322 + /** 323 + * Initial data is sent. 324 + * Notify device statemachine that we are up and 325 + * running. 326 + * 327 + * fi An instance of a channel statemachine. 328 + * event The event, just happened. 329 + * arg Generic pointer, casted from channel * upon call. 330 + */ 331 + void ctcm_chx_txidle(fsm_instance *fi, int event, void *arg) 332 + { 333 + struct channel *ch = arg; 334 + struct net_device *dev = ch->netdev; 335 + struct ctcm_priv *priv = dev->priv; 336 + 337 + CTCM_DBF_TEXT(TRACE, 6, __FUNCTION__); 338 + fsm_deltimer(&ch->timer); 339 + fsm_newstate(fi, CTC_STATE_TXIDLE); 340 + fsm_event(priv->fsm, DEV_EVENT_TXUP, ch->netdev); 341 + } 342 + 343 + /** 344 + * Got normal data, check for sanity, queue it up, allocate new buffer 345 + * trigger bottom half, and initiate next read. 346 + * 347 + * fi An instance of a channel statemachine. 348 + * event The event, just happened. 349 + * arg Generic pointer, casted from channel * upon call. 350 + */ 351 + static void chx_rx(fsm_instance *fi, int event, void *arg) 352 + { 353 + struct channel *ch = arg; 354 + struct net_device *dev = ch->netdev; 355 + struct ctcm_priv *priv = dev->priv; 356 + int len = ch->max_bufsize - ch->irb->scsw.count; 357 + struct sk_buff *skb = ch->trans_skb; 358 + __u16 block_len = *((__u16 *)skb->data); 359 + int check_len; 360 + int rc; 361 + 362 + fsm_deltimer(&ch->timer); 363 + if (len < 8) { 364 + ctcm_pr_debug("%s: got packet with length %d < 8\n", 365 + dev->name, len); 366 + priv->stats.rx_dropped++; 367 + priv->stats.rx_length_errors++; 368 + goto again; 369 + } 370 + if (len > ch->max_bufsize) { 371 + ctcm_pr_debug("%s: got packet with length %d > %d\n", 372 + dev->name, len, ch->max_bufsize); 373 + priv->stats.rx_dropped++; 374 + priv->stats.rx_length_errors++; 375 + goto again; 376 + } 377 + 378 + /* 379 + * VM TCP seems to have a bug sending 2 trailing bytes of garbage. 380 + */ 381 + switch (ch->protocol) { 382 + case CTCM_PROTO_S390: 383 + case CTCM_PROTO_OS390: 384 + check_len = block_len + 2; 385 + break; 386 + default: 387 + check_len = block_len; 388 + break; 389 + } 390 + if ((len < block_len) || (len > check_len)) { 391 + ctcm_pr_debug("%s: got block length %d != rx length %d\n", 392 + dev->name, block_len, len); 393 + if (do_debug) 394 + ctcmpc_dump_skb(skb, 0); 395 + 396 + *((__u16 *)skb->data) = len; 397 + priv->stats.rx_dropped++; 398 + priv->stats.rx_length_errors++; 399 + goto again; 400 + } 401 + block_len -= 2; 402 + if (block_len > 0) { 403 + *((__u16 *)skb->data) = block_len; 404 + ctcm_unpack_skb(ch, skb); 405 + } 406 + again: 407 + skb->data = ch->trans_skb_data; 408 + skb_reset_tail_pointer(skb); 409 + skb->len = 0; 410 + if (ctcm_checkalloc_buffer(ch)) 411 + return; 412 + ch->ccw[1].count = ch->max_bufsize; 413 + rc = ccw_device_start(ch->cdev, &ch->ccw[0], 414 + (unsigned long)ch, 0xff, 0); 415 + if (rc != 0) 416 + ctcm_ccw_check_rc(ch, rc, "normal RX"); 417 + } 418 + 419 + /** 420 + * Initialize connection by sending a __u16 of value 0. 421 + * 422 + * fi An instance of a channel statemachine. 423 + * event The event, just happened. 424 + * arg Generic pointer, casted from channel * upon call. 425 + */ 426 + static void chx_firstio(fsm_instance *fi, int event, void *arg) 427 + { 428 + struct channel *ch = arg; 429 + int rc; 430 + 431 + CTCM_DBF_TEXT(TRACE, 6, __FUNCTION__); 432 + 433 + if (fsm_getstate(fi) == CTC_STATE_TXIDLE) 434 + ctcm_pr_debug("%s: remote side issued READ?, init.\n", ch->id); 435 + fsm_deltimer(&ch->timer); 436 + if (ctcm_checkalloc_buffer(ch)) 437 + return; 438 + if ((fsm_getstate(fi) == CTC_STATE_SETUPWAIT) && 439 + (ch->protocol == CTCM_PROTO_OS390)) { 440 + /* OS/390 resp. z/OS */ 441 + if (CHANNEL_DIRECTION(ch->flags) == READ) { 442 + *((__u16 *)ch->trans_skb->data) = CTCM_INITIAL_BLOCKLEN; 443 + fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, 444 + CTC_EVENT_TIMER, ch); 445 + chx_rxidle(fi, event, arg); 446 + } else { 447 + struct net_device *dev = ch->netdev; 448 + struct ctcm_priv *priv = dev->priv; 449 + fsm_newstate(fi, CTC_STATE_TXIDLE); 450 + fsm_event(priv->fsm, DEV_EVENT_TXUP, dev); 451 + } 452 + return; 453 + } 454 + 455 + /* 456 + * Don't setup a timer for receiving the initial RX frame 457 + * if in compatibility mode, since VM TCP delays the initial 458 + * frame until it has some data to send. 459 + */ 460 + if ((CHANNEL_DIRECTION(ch->flags) == WRITE) || 461 + (ch->protocol != CTCM_PROTO_S390)) 462 + fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch); 463 + 464 + *((__u16 *)ch->trans_skb->data) = CTCM_INITIAL_BLOCKLEN; 465 + ch->ccw[1].count = 2; /* Transfer only length */ 466 + 467 + fsm_newstate(fi, (CHANNEL_DIRECTION(ch->flags) == READ) 468 + ? CTC_STATE_RXINIT : CTC_STATE_TXINIT); 469 + rc = ccw_device_start(ch->cdev, &ch->ccw[0], 470 + (unsigned long)ch, 0xff, 0); 471 + if (rc != 0) { 472 + fsm_deltimer(&ch->timer); 473 + fsm_newstate(fi, CTC_STATE_SETUPWAIT); 474 + ctcm_ccw_check_rc(ch, rc, "init IO"); 475 + } 476 + /* 477 + * If in compatibility mode since we don't setup a timer, we 478 + * also signal RX channel up immediately. This enables us 479 + * to send packets early which in turn usually triggers some 480 + * reply from VM TCP which brings up the RX channel to it's 481 + * final state. 482 + */ 483 + if ((CHANNEL_DIRECTION(ch->flags) == READ) && 484 + (ch->protocol == CTCM_PROTO_S390)) { 485 + struct net_device *dev = ch->netdev; 486 + struct ctcm_priv *priv = dev->priv; 487 + fsm_event(priv->fsm, DEV_EVENT_RXUP, dev); 488 + } 489 + } 490 + 491 + /** 492 + * Got initial data, check it. If OK, 493 + * notify device statemachine that we are up and 494 + * running. 495 + * 496 + * fi An instance of a channel statemachine. 497 + * event The event, just happened. 498 + * arg Generic pointer, casted from channel * upon call. 499 + */ 500 + static void chx_rxidle(fsm_instance *fi, int event, void *arg) 501 + { 502 + struct channel *ch = arg; 503 + struct net_device *dev = ch->netdev; 504 + struct ctcm_priv *priv = dev->priv; 505 + __u16 buflen; 506 + int rc; 507 + 508 + CTCM_DBF_TEXT(TRACE, 6, __FUNCTION__); 509 + fsm_deltimer(&ch->timer); 510 + buflen = *((__u16 *)ch->trans_skb->data); 511 + if (do_debug) 512 + ctcm_pr_debug("%s: Initial RX count %d\n", dev->name, buflen); 513 + 514 + if (buflen >= CTCM_INITIAL_BLOCKLEN) { 515 + if (ctcm_checkalloc_buffer(ch)) 516 + return; 517 + ch->ccw[1].count = ch->max_bufsize; 518 + fsm_newstate(fi, CTC_STATE_RXIDLE); 519 + rc = ccw_device_start(ch->cdev, &ch->ccw[0], 520 + (unsigned long)ch, 0xff, 0); 521 + if (rc != 0) { 522 + fsm_newstate(fi, CTC_STATE_RXINIT); 523 + ctcm_ccw_check_rc(ch, rc, "initial RX"); 524 + } else 525 + fsm_event(priv->fsm, DEV_EVENT_RXUP, dev); 526 + } else { 527 + if (do_debug) 528 + ctcm_pr_debug("%s: Initial RX count %d not %d\n", 529 + dev->name, buflen, CTCM_INITIAL_BLOCKLEN); 530 + chx_firstio(fi, event, arg); 531 + } 532 + } 533 + 534 + /** 535 + * Set channel into extended mode. 536 + * 537 + * fi An instance of a channel statemachine. 538 + * event The event, just happened. 539 + * arg Generic pointer, casted from channel * upon call. 540 + */ 541 + static void ctcm_chx_setmode(fsm_instance *fi, int event, void *arg) 542 + { 543 + struct channel *ch = arg; 544 + int rc; 545 + unsigned long saveflags = 0; 546 + int timeout = CTCM_TIME_5_SEC; 547 + 548 + fsm_deltimer(&ch->timer); 549 + if (IS_MPC(ch)) { 550 + timeout = 1500; 551 + if (do_debug) 552 + ctcm_pr_debug("ctcm enter: %s(): cp=%i ch=0x%p id=%s\n", 553 + __FUNCTION__, smp_processor_id(), ch, ch->id); 554 + } 555 + fsm_addtimer(&ch->timer, timeout, CTC_EVENT_TIMER, ch); 556 + fsm_newstate(fi, CTC_STATE_SETUPWAIT); 557 + if (do_debug_ccw && IS_MPC(ch)) 558 + ctcmpc_dumpit((char *)&ch->ccw[6], sizeof(struct ccw1) * 2); 559 + 560 + if (event == CTC_EVENT_TIMER) /* only for timer not yet locked */ 561 + spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags); 562 + /* Such conditional locking is undeterministic in 563 + * static view. => ignore sparse warnings here. */ 564 + 565 + rc = ccw_device_start(ch->cdev, &ch->ccw[6], 566 + (unsigned long)ch, 0xff, 0); 567 + if (event == CTC_EVENT_TIMER) /* see above comments */ 568 + spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags); 569 + if (rc != 0) { 570 + fsm_deltimer(&ch->timer); 571 + fsm_newstate(fi, CTC_STATE_STARTWAIT); 572 + ctcm_ccw_check_rc(ch, rc, "set Mode"); 573 + } else 574 + ch->retry = 0; 575 + } 576 + 577 + /** 578 + * Setup channel. 579 + * 580 + * fi An instance of a channel statemachine. 581 + * event The event, just happened. 582 + * arg Generic pointer, casted from channel * upon call. 583 + */ 584 + static void ctcm_chx_start(fsm_instance *fi, int event, void *arg) 585 + { 586 + struct channel *ch = arg; 587 + int rc; 588 + struct net_device *dev; 589 + unsigned long saveflags; 590 + 591 + CTCM_DBF_TEXT(TRACE, 5, __FUNCTION__); 592 + if (ch == NULL) { 593 + ctcm_pr_warn("chx_start ch=NULL\n"); 594 + return; 595 + } 596 + if (ch->netdev == NULL) { 597 + ctcm_pr_warn("chx_start dev=NULL, id=%s\n", ch->id); 598 + return; 599 + } 600 + dev = ch->netdev; 601 + 602 + if (do_debug) 603 + ctcm_pr_debug("%s: %s channel start\n", dev->name, 604 + (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX"); 605 + 606 + if (ch->trans_skb != NULL) { 607 + clear_normalized_cda(&ch->ccw[1]); 608 + dev_kfree_skb(ch->trans_skb); 609 + ch->trans_skb = NULL; 610 + } 611 + if (CHANNEL_DIRECTION(ch->flags) == READ) { 612 + ch->ccw[1].cmd_code = CCW_CMD_READ; 613 + ch->ccw[1].flags = CCW_FLAG_SLI; 614 + ch->ccw[1].count = 0; 615 + } else { 616 + ch->ccw[1].cmd_code = CCW_CMD_WRITE; 617 + ch->ccw[1].flags = CCW_FLAG_SLI | CCW_FLAG_CC; 618 + ch->ccw[1].count = 0; 619 + } 620 + if (ctcm_checkalloc_buffer(ch)) { 621 + ctcm_pr_notice("%s: %s trans_skb allocation delayed " 622 + "until first transfer\n", dev->name, 623 + (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX"); 624 + } 625 + 626 + ch->ccw[0].cmd_code = CCW_CMD_PREPARE; 627 + ch->ccw[0].flags = CCW_FLAG_SLI | CCW_FLAG_CC; 628 + ch->ccw[0].count = 0; 629 + ch->ccw[0].cda = 0; 630 + ch->ccw[2].cmd_code = CCW_CMD_NOOP; /* jointed CE + DE */ 631 + ch->ccw[2].flags = CCW_FLAG_SLI; 632 + ch->ccw[2].count = 0; 633 + ch->ccw[2].cda = 0; 634 + memcpy(&ch->ccw[3], &ch->ccw[0], sizeof(struct ccw1) * 3); 635 + ch->ccw[4].cda = 0; 636 + ch->ccw[4].flags &= ~CCW_FLAG_IDA; 637 + 638 + fsm_newstate(fi, CTC_STATE_STARTWAIT); 639 + fsm_addtimer(&ch->timer, 1000, CTC_EVENT_TIMER, ch); 640 + spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags); 641 + rc = ccw_device_halt(ch->cdev, (unsigned long)ch); 642 + spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags); 643 + if (rc != 0) { 644 + if (rc != -EBUSY) 645 + fsm_deltimer(&ch->timer); 646 + ctcm_ccw_check_rc(ch, rc, "initial HaltIO"); 647 + } 648 + } 649 + 650 + /** 651 + * Shutdown a channel. 652 + * 653 + * fi An instance of a channel statemachine. 654 + * event The event, just happened. 655 + * arg Generic pointer, casted from channel * upon call. 656 + */ 657 + static void ctcm_chx_haltio(fsm_instance *fi, int event, void *arg) 658 + { 659 + struct channel *ch = arg; 660 + unsigned long saveflags = 0; 661 + int rc; 662 + int oldstate; 663 + 664 + CTCM_DBF_TEXT(TRACE, 2, __FUNCTION__); 665 + fsm_deltimer(&ch->timer); 666 + if (IS_MPC(ch)) 667 + fsm_deltimer(&ch->sweep_timer); 668 + 669 + fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch); 670 + 671 + if (event == CTC_EVENT_STOP) /* only for STOP not yet locked */ 672 + spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags); 673 + /* Such conditional locking is undeterministic in 674 + * static view. => ignore sparse warnings here. */ 675 + oldstate = fsm_getstate(fi); 676 + fsm_newstate(fi, CTC_STATE_TERM); 677 + rc = ccw_device_halt(ch->cdev, (unsigned long)ch); 678 + 679 + if (event == CTC_EVENT_STOP) 680 + spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags); 681 + /* see remark above about conditional locking */ 682 + 683 + if (rc != 0 && rc != -EBUSY) { 684 + fsm_deltimer(&ch->timer); 685 + if (event != CTC_EVENT_STOP) { 686 + fsm_newstate(fi, oldstate); 687 + ctcm_ccw_check_rc(ch, rc, (char *)__FUNCTION__); 688 + } 689 + } 690 + } 691 + 692 + /** 693 + * Cleanup helper for chx_fail and chx_stopped 694 + * cleanup channels queue and notify interface statemachine. 695 + * 696 + * fi An instance of a channel statemachine. 697 + * state The next state (depending on caller). 698 + * ch The channel to operate on. 699 + */ 700 + static void ctcm_chx_cleanup(fsm_instance *fi, int state, 701 + struct channel *ch) 702 + { 703 + struct net_device *dev = ch->netdev; 704 + struct ctcm_priv *priv = dev->priv; 705 + 706 + CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__); 707 + 708 + fsm_deltimer(&ch->timer); 709 + if (IS_MPC(ch)) 710 + fsm_deltimer(&ch->sweep_timer); 711 + 712 + fsm_newstate(fi, state); 713 + if (state == CTC_STATE_STOPPED && ch->trans_skb != NULL) { 714 + clear_normalized_cda(&ch->ccw[1]); 715 + dev_kfree_skb_any(ch->trans_skb); 716 + ch->trans_skb = NULL; 717 + } 718 + 719 + ch->th_seg = 0x00; 720 + ch->th_seq_num = 0x00; 721 + if (CHANNEL_DIRECTION(ch->flags) == READ) { 722 + skb_queue_purge(&ch->io_queue); 723 + fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev); 724 + } else { 725 + ctcm_purge_skb_queue(&ch->io_queue); 726 + if (IS_MPC(ch)) 727 + ctcm_purge_skb_queue(&ch->sweep_queue); 728 + spin_lock(&ch->collect_lock); 729 + ctcm_purge_skb_queue(&ch->collect_queue); 730 + ch->collect_len = 0; 731 + spin_unlock(&ch->collect_lock); 732 + fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev); 733 + } 734 + } 735 + 736 + /** 737 + * A channel has successfully been halted. 738 + * Cleanup it's queue and notify interface statemachine. 739 + * 740 + * fi An instance of a channel statemachine. 741 + * event The event, just happened. 742 + * arg Generic pointer, casted from channel * upon call. 743 + */ 744 + static void ctcm_chx_stopped(fsm_instance *fi, int event, void *arg) 745 + { 746 + CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__); 747 + ctcm_chx_cleanup(fi, CTC_STATE_STOPPED, arg); 748 + } 749 + 750 + /** 751 + * A stop command from device statemachine arrived and we are in 752 + * not operational mode. Set state to stopped. 753 + * 754 + * fi An instance of a channel statemachine. 755 + * event The event, just happened. 756 + * arg Generic pointer, casted from channel * upon call. 757 + */ 758 + static void ctcm_chx_stop(fsm_instance *fi, int event, void *arg) 759 + { 760 + fsm_newstate(fi, CTC_STATE_STOPPED); 761 + } 762 + 763 + /** 764 + * A machine check for no path, not operational status or gone device has 765 + * happened. 766 + * Cleanup queue and notify interface statemachine. 767 + * 768 + * fi An instance of a channel statemachine. 769 + * event The event, just happened. 770 + * arg Generic pointer, casted from channel * upon call. 771 + */ 772 + static void ctcm_chx_fail(fsm_instance *fi, int event, void *arg) 773 + { 774 + CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__); 775 + ctcm_chx_cleanup(fi, CTC_STATE_NOTOP, arg); 776 + } 777 + 778 + /** 779 + * Handle error during setup of channel. 780 + * 781 + * fi An instance of a channel statemachine. 782 + * event The event, just happened. 783 + * arg Generic pointer, casted from channel * upon call. 784 + */ 785 + static void ctcm_chx_setuperr(fsm_instance *fi, int event, void *arg) 786 + { 787 + struct channel *ch = arg; 788 + struct net_device *dev = ch->netdev; 789 + struct ctcm_priv *priv = dev->priv; 790 + 791 + /* 792 + * Special case: Got UC_RCRESET on setmode. 793 + * This means that remote side isn't setup. In this case 794 + * simply retry after some 10 secs... 795 + */ 796 + if ((fsm_getstate(fi) == CTC_STATE_SETUPWAIT) && 797 + ((event == CTC_EVENT_UC_RCRESET) || 798 + (event == CTC_EVENT_UC_RSRESET))) { 799 + fsm_newstate(fi, CTC_STATE_STARTRETRY); 800 + fsm_deltimer(&ch->timer); 801 + fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch); 802 + if (!IS_MPC(ch) && (CHANNEL_DIRECTION(ch->flags) == READ)) { 803 + int rc = ccw_device_halt(ch->cdev, (unsigned long)ch); 804 + if (rc != 0) 805 + ctcm_ccw_check_rc(ch, rc, 806 + "HaltIO in chx_setuperr"); 807 + } 808 + return; 809 + } 810 + 811 + CTCM_DBF_TEXT_(ERROR, CTC_DBF_CRIT, 812 + "%s : %s error during %s channel setup state=%s\n", 813 + dev->name, ctc_ch_event_names[event], 814 + (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX", 815 + fsm_getstate_str(fi)); 816 + 817 + if (CHANNEL_DIRECTION(ch->flags) == READ) { 818 + fsm_newstate(fi, CTC_STATE_RXERR); 819 + fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev); 820 + } else { 821 + fsm_newstate(fi, CTC_STATE_TXERR); 822 + fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev); 823 + } 824 + } 825 + 826 + /** 827 + * Restart a channel after an error. 828 + * 829 + * fi An instance of a channel statemachine. 830 + * event The event, just happened. 831 + * arg Generic pointer, casted from channel * upon call. 832 + */ 833 + static void ctcm_chx_restart(fsm_instance *fi, int event, void *arg) 834 + { 835 + struct channel *ch = arg; 836 + struct net_device *dev = ch->netdev; 837 + unsigned long saveflags = 0; 838 + int oldstate; 839 + int rc; 840 + 841 + CTCM_DBF_TEXT(TRACE, CTC_DBF_NOTICE, __FUNCTION__); 842 + fsm_deltimer(&ch->timer); 843 + ctcm_pr_debug("%s: %s channel restart\n", dev->name, 844 + (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX"); 845 + fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch); 846 + oldstate = fsm_getstate(fi); 847 + fsm_newstate(fi, CTC_STATE_STARTWAIT); 848 + if (event == CTC_EVENT_TIMER) /* only for timer not yet locked */ 849 + spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags); 850 + /* Such conditional locking is a known problem for 851 + * sparse because its undeterministic in static view. 852 + * Warnings should be ignored here. */ 853 + rc = ccw_device_halt(ch->cdev, (unsigned long)ch); 854 + if (event == CTC_EVENT_TIMER) 855 + spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags); 856 + if (rc != 0) { 857 + if (rc != -EBUSY) { 858 + fsm_deltimer(&ch->timer); 859 + fsm_newstate(fi, oldstate); 860 + } 861 + ctcm_ccw_check_rc(ch, rc, "HaltIO in ctcm_chx_restart"); 862 + } 863 + } 864 + 865 + /** 866 + * Handle error during RX initial handshake (exchange of 867 + * 0-length block header) 868 + * 869 + * fi An instance of a channel statemachine. 870 + * event The event, just happened. 871 + * arg Generic pointer, casted from channel * upon call. 872 + */ 873 + static void ctcm_chx_rxiniterr(fsm_instance *fi, int event, void *arg) 874 + { 875 + struct channel *ch = arg; 876 + struct net_device *dev = ch->netdev; 877 + struct ctcm_priv *priv = dev->priv; 878 + 879 + CTCM_DBF_TEXT(SETUP, 3, __FUNCTION__); 880 + if (event == CTC_EVENT_TIMER) { 881 + if (!IS_MPCDEV(dev)) 882 + /* TODO : check if MPC deletes timer somewhere */ 883 + fsm_deltimer(&ch->timer); 884 + ctcm_pr_debug("%s: Timeout during RX init handshake\n", 885 + dev->name); 886 + if (ch->retry++ < 3) 887 + ctcm_chx_restart(fi, event, arg); 888 + else { 889 + fsm_newstate(fi, CTC_STATE_RXERR); 890 + fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev); 891 + } 892 + } else 893 + ctcm_pr_warn("%s: Error during RX init handshake\n", dev->name); 894 + } 895 + 896 + /** 897 + * Notify device statemachine if we gave up initialization 898 + * 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 + */ 904 + static 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->priv; 909 + 910 + CTCM_DBF_TEXT(SETUP, 3, __FUNCTION__); 911 + fsm_newstate(fi, CTC_STATE_RXERR); 912 + ctcm_pr_warn("%s: RX busy. Initialization failed\n", dev->name); 913 + fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev); 914 + } 915 + 916 + /** 917 + * Handle RX Unit check remote reset (remote disconnected) 918 + * 919 + * fi An instance of a channel statemachine. 920 + * event The event, just happened. 921 + * arg Generic pointer, casted from channel * upon call. 922 + */ 923 + static void ctcm_chx_rxdisc(fsm_instance *fi, int event, void *arg) 924 + { 925 + struct channel *ch = arg; 926 + struct channel *ch2; 927 + struct net_device *dev = ch->netdev; 928 + struct ctcm_priv *priv = dev->priv; 929 + 930 + CTCM_DBF_DEV_NAME(TRACE, dev, "Got remote disconnect, re-initializing"); 931 + fsm_deltimer(&ch->timer); 932 + if (do_debug) 933 + ctcm_pr_debug("%s: Got remote disconnect, " 934 + "re-initializing ...\n", dev->name); 935 + /* 936 + * Notify device statemachine 937 + */ 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[WRITE]; 943 + fsm_newstate(ch2->fsm, CTC_STATE_DTERM); 944 + 945 + ccw_device_halt(ch->cdev, (unsigned long)ch); 946 + ccw_device_halt(ch2->cdev, (unsigned long)ch2); 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 + */ 956 + static 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->priv; 961 + 962 + if (event == CTC_EVENT_TIMER) { 963 + fsm_deltimer(&ch->timer); 964 + CTCM_DBF_DEV_NAME(ERROR, dev, 965 + "Timeout during TX init handshake"); 966 + if (ch->retry++ < 3) 967 + ctcm_chx_restart(fi, event, arg); 968 + else { 969 + fsm_newstate(fi, CTC_STATE_TXERR); 970 + fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev); 971 + } 972 + } else { 973 + CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR, 974 + "%s : %s error during channel setup state=%s", 975 + dev->name, ctc_ch_event_names[event], 976 + fsm_getstate_str(fi)); 977 + 978 + ctcm_pr_warn("%s: Error during TX init handshake\n", dev->name); 979 + } 980 + } 981 + 982 + /** 983 + * Handle TX timeout by retrying operation. 984 + * 985 + * fi An instance of a channel statemachine. 986 + * event The event, just happened. 987 + * arg Generic pointer, casted from channel * upon call. 988 + */ 989 + static void ctcm_chx_txretry(fsm_instance *fi, int event, void *arg) 990 + { 991 + struct channel *ch = arg; 992 + struct net_device *dev = ch->netdev; 993 + struct ctcm_priv *priv = dev->priv; 994 + struct sk_buff *skb; 995 + 996 + if (do_debug) 997 + ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n", 998 + __FUNCTION__, smp_processor_id(), ch, ch->id); 999 + 1000 + fsm_deltimer(&ch->timer); 1001 + if (ch->retry++ > 3) { 1002 + struct mpc_group *gptr = priv->mpcg; 1003 + ctcm_pr_debug("%s: TX retry failed, restarting channel\n", 1004 + dev->name); 1005 + fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev); 1006 + /* call restart if not MPC or if MPC and mpcg fsm is ready. 1007 + use gptr as mpc indicator */ 1008 + if (!(gptr && (fsm_getstate(gptr->fsm) != MPCG_STATE_READY))) 1009 + ctcm_chx_restart(fi, event, arg); 1010 + goto done; 1011 + } 1012 + 1013 + ctcm_pr_debug("%s: TX retry %d\n", dev->name, ch->retry); 1014 + skb = skb_peek(&ch->io_queue); 1015 + if (skb) { 1016 + int rc = 0; 1017 + unsigned long saveflags = 0; 1018 + clear_normalized_cda(&ch->ccw[4]); 1019 + ch->ccw[4].count = skb->len; 1020 + if (set_normalized_cda(&ch->ccw[4], skb->data)) { 1021 + ctcm_pr_debug("%s: IDAL alloc failed, chan restart\n", 1022 + dev->name); 1023 + fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev); 1024 + ctcm_chx_restart(fi, event, arg); 1025 + goto done; 1026 + } 1027 + fsm_addtimer(&ch->timer, 1000, CTC_EVENT_TIMER, ch); 1028 + if (event == CTC_EVENT_TIMER) /* for TIMER not yet locked */ 1029 + spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags); 1030 + /* Such conditional locking is a known problem for 1031 + * sparse because its undeterministic in static view. 1032 + * Warnings should be ignored here. */ 1033 + if (do_debug_ccw) 1034 + ctcmpc_dumpit((char *)&ch->ccw[3], 1035 + sizeof(struct ccw1) * 3); 1036 + 1037 + rc = ccw_device_start(ch->cdev, &ch->ccw[3], 1038 + (unsigned long)ch, 0xff, 0); 1039 + if (event == CTC_EVENT_TIMER) 1040 + spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), 1041 + saveflags); 1042 + if (rc != 0) { 1043 + fsm_deltimer(&ch->timer); 1044 + ctcm_ccw_check_rc(ch, rc, "TX in chx_txretry"); 1045 + ctcm_purge_skb_queue(&ch->io_queue); 1046 + } 1047 + } 1048 + done: 1049 + return; 1050 + } 1051 + 1052 + /** 1053 + * Handle fatal errors during an I/O command. 1054 + * 1055 + * fi An instance of a channel statemachine. 1056 + * event The event, just happened. 1057 + * arg Generic pointer, casted from channel * upon call. 1058 + */ 1059 + static void ctcm_chx_iofatal(fsm_instance *fi, int event, void *arg) 1060 + { 1061 + struct channel *ch = arg; 1062 + struct net_device *dev = ch->netdev; 1063 + struct ctcm_priv *priv = dev->priv; 1064 + 1065 + CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__); 1066 + fsm_deltimer(&ch->timer); 1067 + ctcm_pr_warn("%s %s : unrecoverable channel error\n", 1068 + CTC_DRIVER_NAME, dev->name); 1069 + if (IS_MPC(ch)) { 1070 + priv->stats.tx_dropped++; 1071 + priv->stats.tx_errors++; 1072 + } 1073 + 1074 + if (CHANNEL_DIRECTION(ch->flags) == READ) { 1075 + ctcm_pr_debug("%s: RX I/O error\n", dev->name); 1076 + fsm_newstate(fi, CTC_STATE_RXERR); 1077 + fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev); 1078 + } else { 1079 + ctcm_pr_debug("%s: TX I/O error\n", dev->name); 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 + */ 1088 + const 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 + 1186 + int ch_fsm_len = ARRAY_SIZE(ch_fsm); 1187 + 1188 + /* 1189 + * MPC actions for mpc channel statemachine 1190 + * handling of MPC protocol requires extra 1191 + * 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 definitions 1194 + * 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 corresponding 1203 + * skb (it's in io_queue), reset dev->tbusy and 1204 + * 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 + */ 1210 + static 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->priv; 1215 + struct mpc_group *grp = priv->mpcg; 1216 + struct sk_buff *skb; 1217 + int first = 1; 1218 + int i; 1219 + struct timespec done_stamp; 1220 + __u32 data_space; 1221 + unsigned long duration; 1222 + struct sk_buff *peekskb; 1223 + int rc; 1224 + struct th_header *header; 1225 + struct pdu *p_header; 1226 + 1227 + if (do_debug) 1228 + ctcm_pr_debug("%s cp:%i enter: %s()\n", 1229 + dev->name, smp_processor_id(), __FUNCTION__); 1230 + 1231 + done_stamp = current_kernel_time(); /* xtime */ 1232 + duration = (done_stamp.tv_sec - ch->prof.send_stamp.tv_sec) * 1000000 1233 + + (done_stamp.tv_nsec - ch->prof.send_stamp.tv_nsec) / 1000; 1234 + if (duration > ch->prof.tx_time) 1235 + ch->prof.tx_time = duration; 1236 + 1237 + if (ch->irb->scsw.count != 0) 1238 + ctcm_pr_debug("%s: TX not complete, remaining %d bytes\n", 1239 + dev->name, ch->irb->scsw.count); 1240 + fsm_deltimer(&ch->timer); 1241 + while ((skb = skb_dequeue(&ch->io_queue))) { 1242 + priv->stats.tx_packets++; 1243 + priv->stats.tx_bytes += skb->len - TH_HEADER_LENGTH; 1244 + if (first) { 1245 + priv->stats.tx_bytes += 2; 1246 + first = 0; 1247 + } 1248 + atomic_dec(&skb->users); 1249 + dev_kfree_skb_irq(skb); 1250 + } 1251 + spin_lock(&ch->collect_lock); 1252 + clear_normalized_cda(&ch->ccw[4]); 1253 + 1254 + if ((ch->collect_len <= 0) || (grp->in_sweep != 0)) { 1255 + spin_unlock(&ch->collect_lock); 1256 + fsm_newstate(fi, CTC_STATE_TXIDLE); 1257 + goto done; 1258 + } 1259 + 1260 + if (ctcm_checkalloc_buffer(ch)) { 1261 + spin_unlock(&ch->collect_lock); 1262 + goto done; 1263 + } 1264 + ch->trans_skb->data = ch->trans_skb_data; 1265 + skb_reset_tail_pointer(ch->trans_skb); 1266 + ch->trans_skb->len = 0; 1267 + if (ch->prof.maxmulti < (ch->collect_len + TH_HEADER_LENGTH)) 1268 + ch->prof.maxmulti = ch->collect_len + TH_HEADER_LENGTH; 1269 + if (ch->prof.maxcqueue < skb_queue_len(&ch->collect_queue)) 1270 + ch->prof.maxcqueue = skb_queue_len(&ch->collect_queue); 1271 + i = 0; 1272 + 1273 + if (do_debug_data) 1274 + ctcm_pr_debug("ctcmpc: %s() building " 1275 + "trans_skb from collect_q \n", __FUNCTION__); 1276 + 1277 + data_space = grp->group_max_buflen - TH_HEADER_LENGTH; 1278 + 1279 + if (do_debug_data) 1280 + ctcm_pr_debug("ctcmpc: %s() building trans_skb from collect_q" 1281 + " data_space:%04x\n", __FUNCTION__, data_space); 1282 + p_header = NULL; 1283 + while ((skb = skb_dequeue(&ch->collect_queue))) { 1284 + memcpy(skb_put(ch->trans_skb, skb->len), skb->data, skb->len); 1285 + p_header = (struct pdu *) 1286 + (skb_tail_pointer(ch->trans_skb) - skb->len); 1287 + p_header->pdu_flag = 0x00; 1288 + if (skb->protocol == ntohs(ETH_P_SNAP)) 1289 + p_header->pdu_flag |= 0x60; 1290 + else 1291 + p_header->pdu_flag |= 0x20; 1292 + 1293 + if (do_debug_data) { 1294 + ctcm_pr_debug("ctcmpc: %s()trans_skb len:%04x \n", 1295 + __FUNCTION__, ch->trans_skb->len); 1296 + ctcm_pr_debug("ctcmpc: %s() pdu header and data" 1297 + " for up to 32 bytes sent to vtam\n", 1298 + __FUNCTION__); 1299 + ctcmpc_dumpit((char *)p_header, 1300 + min_t(int, skb->len, 32)); 1301 + } 1302 + ch->collect_len -= skb->len; 1303 + data_space -= skb->len; 1304 + priv->stats.tx_packets++; 1305 + priv->stats.tx_bytes += skb->len; 1306 + atomic_dec(&skb->users); 1307 + dev_kfree_skb_any(skb); 1308 + peekskb = skb_peek(&ch->collect_queue); 1309 + if (peekskb->len > data_space) 1310 + break; 1311 + i++; 1312 + } 1313 + /* p_header points to the last one we handled */ 1314 + if (p_header) 1315 + p_header->pdu_flag |= PDU_LAST; /*Say it's the last one*/ 1316 + header = kzalloc(TH_HEADER_LENGTH, gfp_type()); 1317 + 1318 + if (!header) { 1319 + printk(KERN_WARNING "ctcmpc: OUT OF MEMORY IN %s()" 1320 + ": Data Lost \n", __FUNCTION__); 1321 + spin_unlock(&ch->collect_lock); 1322 + fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev); 1323 + goto done; 1324 + } 1325 + 1326 + header->th_ch_flag = TH_HAS_PDU; /* Normal data */ 1327 + ch->th_seq_num++; 1328 + header->th_seq_num = ch->th_seq_num; 1329 + 1330 + if (do_debug_data) 1331 + ctcm_pr_debug("%s: ToVTAM_th_seq= %08x\n" , 1332 + __FUNCTION__, ch->th_seq_num); 1333 + 1334 + memcpy(skb_push(ch->trans_skb, TH_HEADER_LENGTH), header, 1335 + TH_HEADER_LENGTH); /* put the TH on the packet */ 1336 + 1337 + kfree(header); 1338 + 1339 + if (do_debug_data) { 1340 + ctcm_pr_debug("ctcmpc: %s()trans_skb len:%04x \n", 1341 + __FUNCTION__, ch->trans_skb->len); 1342 + 1343 + ctcm_pr_debug("ctcmpc: %s() up-to-50 bytes of trans_skb " 1344 + "data to vtam from collect_q\n", __FUNCTION__); 1345 + ctcmpc_dumpit((char *)ch->trans_skb->data, 1346 + min_t(int, ch->trans_skb->len, 50)); 1347 + } 1348 + 1349 + spin_unlock(&ch->collect_lock); 1350 + clear_normalized_cda(&ch->ccw[1]); 1351 + if (set_normalized_cda(&ch->ccw[1], ch->trans_skb->data)) { 1352 + dev_kfree_skb_any(ch->trans_skb); 1353 + ch->trans_skb = NULL; 1354 + printk(KERN_WARNING 1355 + "ctcmpc: %s()CCW failure - data lost\n", 1356 + __FUNCTION__); 1357 + fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev); 1358 + return; 1359 + } 1360 + ch->ccw[1].count = ch->trans_skb->len; 1361 + fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch); 1362 + ch->prof.send_stamp = current_kernel_time(); /* xtime */ 1363 + if (do_debug_ccw) 1364 + ctcmpc_dumpit((char *)&ch->ccw[0], sizeof(struct ccw1) * 3); 1365 + rc = ccw_device_start(ch->cdev, &ch->ccw[0], 1366 + (unsigned long)ch, 0xff, 0); 1367 + ch->prof.doios_multi++; 1368 + if (rc != 0) { 1369 + priv->stats.tx_dropped += i; 1370 + priv->stats.tx_errors += i; 1371 + fsm_deltimer(&ch->timer); 1372 + ctcm_ccw_check_rc(ch, rc, "chained TX"); 1373 + } 1374 + done: 1375 + ctcm_clear_busy(dev); 1376 + ctcm_pr_debug("ctcmpc exit: %s %s()\n", dev->name, __FUNCTION__); 1377 + return; 1378 + } 1379 + 1380 + /** 1381 + * Got normal data, check for sanity, queue it up, allocate new buffer 1382 + * trigger bottom half, and initiate next read. 1383 + * 1384 + * fi An instance of a channel statemachine. 1385 + * event The event, just happened. 1386 + * arg Generic pointer, casted from channel * upon call. 1387 + */ 1388 + static void ctcmpc_chx_rx(fsm_instance *fi, int event, void *arg) 1389 + { 1390 + struct channel *ch = arg; 1391 + struct net_device *dev = ch->netdev; 1392 + struct ctcm_priv *priv = dev->priv; 1393 + struct mpc_group *grp = priv->mpcg; 1394 + struct sk_buff *skb = ch->trans_skb; 1395 + struct sk_buff *new_skb; 1396 + unsigned long saveflags = 0; /* avoids compiler warning */ 1397 + int len = ch->max_bufsize - ch->irb->scsw.count; 1398 + 1399 + if (do_debug_data) { 1400 + CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG, "mpc_ch_rx %s cp:%i %s\n", 1401 + dev->name, smp_processor_id(), ch->id); 1402 + CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG, "mpc_ch_rx: maxbuf: %04x " 1403 + "len: %04x\n", ch->max_bufsize, len); 1404 + } 1405 + fsm_deltimer(&ch->timer); 1406 + 1407 + if (skb == NULL) { 1408 + ctcm_pr_debug("ctcmpc exit: %s() TRANS_SKB = NULL \n", 1409 + __FUNCTION__); 1410 + goto again; 1411 + } 1412 + 1413 + if (len < TH_HEADER_LENGTH) { 1414 + ctcm_pr_info("%s: got packet with invalid length %d\n", 1415 + dev->name, len); 1416 + priv->stats.rx_dropped++; 1417 + priv->stats.rx_length_errors++; 1418 + } else { 1419 + /* must have valid th header or game over */ 1420 + __u32 block_len = len; 1421 + len = TH_HEADER_LENGTH + XID2_LENGTH + 4; 1422 + new_skb = __dev_alloc_skb(ch->max_bufsize, GFP_ATOMIC); 1423 + 1424 + if (new_skb == NULL) { 1425 + printk(KERN_INFO "ctcmpc:%s() NEW_SKB = NULL\n", 1426 + __FUNCTION__); 1427 + printk(KERN_WARNING "ctcmpc: %s() MEMORY ALLOC FAILED" 1428 + " - DATA LOST - MPC FAILED\n", 1429 + __FUNCTION__); 1430 + fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev); 1431 + goto again; 1432 + } 1433 + switch (fsm_getstate(grp->fsm)) { 1434 + case MPCG_STATE_RESET: 1435 + case MPCG_STATE_INOP: 1436 + dev_kfree_skb_any(new_skb); 1437 + break; 1438 + case MPCG_STATE_FLOWC: 1439 + case MPCG_STATE_READY: 1440 + memcpy(skb_put(new_skb, block_len), 1441 + skb->data, block_len); 1442 + skb_queue_tail(&ch->io_queue, new_skb); 1443 + tasklet_schedule(&ch->ch_tasklet); 1444 + break; 1445 + default: 1446 + memcpy(skb_put(new_skb, len), skb->data, len); 1447 + skb_queue_tail(&ch->io_queue, new_skb); 1448 + tasklet_hi_schedule(&ch->ch_tasklet); 1449 + break; 1450 + } 1451 + } 1452 + 1453 + again: 1454 + switch (fsm_getstate(grp->fsm)) { 1455 + int rc, dolock; 1456 + case MPCG_STATE_FLOWC: 1457 + case MPCG_STATE_READY: 1458 + if (ctcm_checkalloc_buffer(ch)) 1459 + break; 1460 + ch->trans_skb->data = ch->trans_skb_data; 1461 + skb_reset_tail_pointer(ch->trans_skb); 1462 + ch->trans_skb->len = 0; 1463 + ch->ccw[1].count = ch->max_bufsize; 1464 + if (do_debug_ccw) 1465 + ctcmpc_dumpit((char *)&ch->ccw[0], 1466 + sizeof(struct ccw1) * 3); 1467 + dolock = !in_irq(); 1468 + if (dolock) 1469 + spin_lock_irqsave( 1470 + get_ccwdev_lock(ch->cdev), saveflags); 1471 + rc = ccw_device_start(ch->cdev, &ch->ccw[0], 1472 + (unsigned long)ch, 0xff, 0); 1473 + if (dolock) /* see remark about conditional locking */ 1474 + spin_unlock_irqrestore( 1475 + get_ccwdev_lock(ch->cdev), saveflags); 1476 + if (rc != 0) 1477 + ctcm_ccw_check_rc(ch, rc, "normal RX"); 1478 + default: 1479 + break; 1480 + } 1481 + 1482 + if (do_debug) 1483 + ctcm_pr_debug("ctcmpc exit : %s %s(): ch=0x%p id=%s\n", 1484 + dev->name, __FUNCTION__, ch, ch->id); 1485 + 1486 + } 1487 + 1488 + /** 1489 + * Initialize connection by sending a __u16 of value 0. 1490 + * 1491 + * fi An instance of a channel statemachine. 1492 + * event The event, just happened. 1493 + * arg Generic pointer, casted from channel * upon call. 1494 + */ 1495 + static void ctcmpc_chx_firstio(fsm_instance *fi, int event, void *arg) 1496 + { 1497 + struct channel *ch = arg; 1498 + struct net_device *dev = ch->netdev; 1499 + struct ctcm_priv *priv = dev->priv; 1500 + 1501 + if (do_debug) { 1502 + struct mpc_group *gptr = priv->mpcg; 1503 + ctcm_pr_debug("ctcmpc enter: %s(): ch=0x%p id=%s\n", 1504 + __FUNCTION__, ch, ch->id); 1505 + ctcm_pr_debug("%s() %s chstate:%i grpstate:%i chprotocol:%i\n", 1506 + __FUNCTION__, ch->id, fsm_getstate(fi), 1507 + fsm_getstate(gptr->fsm), ch->protocol); 1508 + } 1509 + if (fsm_getstate(fi) == CTC_STATE_TXIDLE) 1510 + MPC_DBF_DEV_NAME(TRACE, dev, "remote side issued READ? "); 1511 + 1512 + fsm_deltimer(&ch->timer); 1513 + if (ctcm_checkalloc_buffer(ch)) 1514 + goto done; 1515 + 1516 + switch (fsm_getstate(fi)) { 1517 + case CTC_STATE_STARTRETRY: 1518 + case CTC_STATE_SETUPWAIT: 1519 + if (CHANNEL_DIRECTION(ch->flags) == READ) { 1520 + ctcmpc_chx_rxidle(fi, event, arg); 1521 + } else { 1522 + fsm_newstate(fi, CTC_STATE_TXIDLE); 1523 + fsm_event(priv->fsm, DEV_EVENT_TXUP, dev); 1524 + } 1525 + goto done; 1526 + default: 1527 + break; 1528 + }; 1529 + 1530 + fsm_newstate(fi, (CHANNEL_DIRECTION(ch->flags) == READ) 1531 + ? CTC_STATE_RXINIT : CTC_STATE_TXINIT); 1532 + 1533 + done: 1534 + if (do_debug) 1535 + ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n", 1536 + __FUNCTION__, ch, ch->id); 1537 + return; 1538 + } 1539 + 1540 + /** 1541 + * Got initial data, check it. If OK, 1542 + * notify device statemachine that we are up and 1543 + * running. 1544 + * 1545 + * fi An instance of a channel statemachine. 1546 + * event The event, just happened. 1547 + * arg Generic pointer, casted from channel * upon call. 1548 + */ 1549 + void ctcmpc_chx_rxidle(fsm_instance *fi, int event, void *arg) 1550 + { 1551 + struct channel *ch = arg; 1552 + struct net_device *dev = ch->netdev; 1553 + struct ctcm_priv *priv = dev->priv; 1554 + struct mpc_group *grp = priv->mpcg; 1555 + int rc; 1556 + unsigned long saveflags = 0; /* avoids compiler warning */ 1557 + 1558 + fsm_deltimer(&ch->timer); 1559 + ctcm_pr_debug("%s cp:%i enter: %s()\n", 1560 + dev->name, smp_processor_id(), __FUNCTION__); 1561 + if (do_debug) 1562 + ctcm_pr_debug("%s() %s chstate:%i grpstate:%i\n", 1563 + __FUNCTION__, ch->id, 1564 + fsm_getstate(fi), fsm_getstate(grp->fsm)); 1565 + 1566 + fsm_newstate(fi, CTC_STATE_RXIDLE); 1567 + /* XID processing complete */ 1568 + 1569 + switch (fsm_getstate(grp->fsm)) { 1570 + case MPCG_STATE_FLOWC: 1571 + case MPCG_STATE_READY: 1572 + if (ctcm_checkalloc_buffer(ch)) 1573 + goto done; 1574 + ch->trans_skb->data = ch->trans_skb_data; 1575 + skb_reset_tail_pointer(ch->trans_skb); 1576 + ch->trans_skb->len = 0; 1577 + ch->ccw[1].count = ch->max_bufsize; 1578 + if (do_debug_ccw) 1579 + ctcmpc_dumpit((char *)&ch->ccw[0], 1580 + sizeof(struct ccw1) * 3); 1581 + if (event == CTC_EVENT_START) 1582 + /* see remark about conditional locking */ 1583 + spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags); 1584 + rc = ccw_device_start(ch->cdev, &ch->ccw[0], 1585 + (unsigned long)ch, 0xff, 0); 1586 + if (event == CTC_EVENT_START) 1587 + spin_unlock_irqrestore( 1588 + get_ccwdev_lock(ch->cdev), saveflags); 1589 + if (rc != 0) { 1590 + fsm_newstate(fi, CTC_STATE_RXINIT); 1591 + ctcm_ccw_check_rc(ch, rc, "initial RX"); 1592 + goto done; 1593 + } 1594 + break; 1595 + default: 1596 + break; 1597 + } 1598 + 1599 + fsm_event(priv->fsm, DEV_EVENT_RXUP, dev); 1600 + done: 1601 + if (do_debug) 1602 + ctcm_pr_debug("ctcmpc exit: %s %s()\n", 1603 + dev->name, __FUNCTION__); 1604 + return; 1605 + } 1606 + 1607 + /* 1608 + * ctcmpc channel FSM action 1609 + * called from several points in ctcmpc_ch_fsm 1610 + * ctcmpc only 1611 + */ 1612 + static void ctcmpc_chx_attn(fsm_instance *fsm, int event, void *arg) 1613 + { 1614 + struct channel *ch = arg; 1615 + struct net_device *dev = ch->netdev; 1616 + struct ctcm_priv *priv = dev->priv; 1617 + struct mpc_group *grp = priv->mpcg; 1618 + 1619 + if (do_debug) { 1620 + ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s" 1621 + "GrpState:%s ChState:%s\n", 1622 + __FUNCTION__, smp_processor_id(), ch, ch->id, 1623 + fsm_getstate_str(grp->fsm), 1624 + fsm_getstate_str(ch->fsm)); 1625 + } 1626 + 1627 + switch (fsm_getstate(grp->fsm)) { 1628 + case MPCG_STATE_XID2INITW: 1629 + /* ok..start yside xid exchanges */ 1630 + if (!ch->in_mpcgroup) 1631 + break; 1632 + if (fsm_getstate(ch->fsm) == CH_XID0_PENDING) { 1633 + fsm_deltimer(&grp->timer); 1634 + fsm_addtimer(&grp->timer, 1635 + MPC_XID_TIMEOUT_VALUE, 1636 + MPCG_EVENT_TIMER, dev); 1637 + fsm_event(grp->fsm, MPCG_EVENT_XID0DO, ch); 1638 + 1639 + } else if (fsm_getstate(ch->fsm) < CH_XID7_PENDING1) 1640 + /* attn rcvd before xid0 processed via bh */ 1641 + fsm_newstate(ch->fsm, CH_XID7_PENDING1); 1642 + break; 1643 + case MPCG_STATE_XID2INITX: 1644 + case MPCG_STATE_XID0IOWAIT: 1645 + case MPCG_STATE_XID0IOWAIX: 1646 + /* attn rcvd before xid0 processed on ch 1647 + but mid-xid0 processing for group */ 1648 + if (fsm_getstate(ch->fsm) < CH_XID7_PENDING1) 1649 + fsm_newstate(ch->fsm, CH_XID7_PENDING1); 1650 + break; 1651 + case MPCG_STATE_XID7INITW: 1652 + case MPCG_STATE_XID7INITX: 1653 + case MPCG_STATE_XID7INITI: 1654 + case MPCG_STATE_XID7INITZ: 1655 + switch (fsm_getstate(ch->fsm)) { 1656 + case CH_XID7_PENDING: 1657 + fsm_newstate(ch->fsm, CH_XID7_PENDING1); 1658 + break; 1659 + case CH_XID7_PENDING2: 1660 + fsm_newstate(ch->fsm, CH_XID7_PENDING3); 1661 + break; 1662 + } 1663 + fsm_event(grp->fsm, MPCG_EVENT_XID7DONE, dev); 1664 + break; 1665 + } 1666 + 1667 + if (do_debug) 1668 + ctcm_pr_debug("ctcmpc exit : %s(): cp=%i ch=0x%p id=%s\n", 1669 + __FUNCTION__, smp_processor_id(), ch, ch->id); 1670 + return; 1671 + 1672 + } 1673 + 1674 + /* 1675 + * ctcmpc channel FSM action 1676 + * called from one point in ctcmpc_ch_fsm 1677 + * ctcmpc only 1678 + */ 1679 + static void ctcmpc_chx_attnbusy(fsm_instance *fsm, int event, void *arg) 1680 + { 1681 + struct channel *ch = arg; 1682 + struct net_device *dev = ch->netdev; 1683 + struct ctcm_priv *priv = dev->priv; 1684 + struct mpc_group *grp = priv->mpcg; 1685 + 1686 + ctcm_pr_debug("ctcmpc enter: %s %s() %s \nGrpState:%s ChState:%s\n", 1687 + dev->name, 1688 + __FUNCTION__, ch->id, 1689 + fsm_getstate_str(grp->fsm), 1690 + fsm_getstate_str(ch->fsm)); 1691 + 1692 + fsm_deltimer(&ch->timer); 1693 + 1694 + switch (fsm_getstate(grp->fsm)) { 1695 + case MPCG_STATE_XID0IOWAIT: 1696 + /* vtam wants to be primary.start yside xid exchanges*/ 1697 + /* only receive one attn-busy at a time so must not */ 1698 + /* change state each time */ 1699 + grp->changed_side = 1; 1700 + fsm_newstate(grp->fsm, MPCG_STATE_XID2INITW); 1701 + break; 1702 + case MPCG_STATE_XID2INITW: 1703 + if (grp->changed_side == 1) { 1704 + grp->changed_side = 2; 1705 + break; 1706 + } 1707 + /* process began via call to establish_conn */ 1708 + /* so must report failure instead of reverting */ 1709 + /* back to ready-for-xid passive state */ 1710 + if (grp->estconnfunc) 1711 + goto done; 1712 + /* this attnbusy is NOT the result of xside xid */ 1713 + /* collisions so yside must have been triggered */ 1714 + /* by an ATTN that was not intended to start XID */ 1715 + /* processing. Revert back to ready-for-xid and */ 1716 + /* wait for ATTN interrupt to signal xid start */ 1717 + if (fsm_getstate(ch->fsm) == CH_XID0_INPROGRESS) { 1718 + fsm_newstate(ch->fsm, CH_XID0_PENDING) ; 1719 + fsm_deltimer(&grp->timer); 1720 + goto done; 1721 + } 1722 + fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); 1723 + goto done; 1724 + case MPCG_STATE_XID2INITX: 1725 + /* XID2 was received before ATTN Busy for second 1726 + channel.Send yside xid for second channel. 1727 + */ 1728 + if (grp->changed_side == 1) { 1729 + grp->changed_side = 2; 1730 + break; 1731 + } 1732 + case MPCG_STATE_XID0IOWAIX: 1733 + case MPCG_STATE_XID7INITW: 1734 + case MPCG_STATE_XID7INITX: 1735 + case MPCG_STATE_XID7INITI: 1736 + case MPCG_STATE_XID7INITZ: 1737 + default: 1738 + /* multiple attn-busy indicates too out-of-sync */ 1739 + /* and they are certainly not being received as part */ 1740 + /* of valid mpc group negotiations.. */ 1741 + fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); 1742 + goto done; 1743 + } 1744 + 1745 + if (grp->changed_side == 1) { 1746 + fsm_deltimer(&grp->timer); 1747 + fsm_addtimer(&grp->timer, MPC_XID_TIMEOUT_VALUE, 1748 + MPCG_EVENT_TIMER, dev); 1749 + } 1750 + if (ch->in_mpcgroup) 1751 + fsm_event(grp->fsm, MPCG_EVENT_XID0DO, ch); 1752 + else 1753 + printk(KERN_WARNING "ctcmpc: %s() Not all channels have" 1754 + " been added to group\n", __FUNCTION__); 1755 + 1756 + done: 1757 + if (do_debug) 1758 + ctcm_pr_debug("ctcmpc exit : %s()%s ch=0x%p id=%s\n", 1759 + __FUNCTION__, dev->name, ch, ch->id); 1760 + 1761 + return; 1762 + 1763 + } 1764 + 1765 + /* 1766 + * ctcmpc channel FSM action 1767 + * called from several points in ctcmpc_ch_fsm 1768 + * ctcmpc only 1769 + */ 1770 + static void ctcmpc_chx_resend(fsm_instance *fsm, int event, void *arg) 1771 + { 1772 + struct channel *ch = arg; 1773 + struct net_device *dev = ch->netdev; 1774 + struct ctcm_priv *priv = dev->priv; 1775 + struct mpc_group *grp = priv->mpcg; 1776 + 1777 + ctcm_pr_debug("ctcmpc enter: %s %s() %s \nGrpState:%s ChState:%s\n", 1778 + dev->name, __FUNCTION__, ch->id, 1779 + fsm_getstate_str(grp->fsm), 1780 + fsm_getstate_str(ch->fsm)); 1781 + 1782 + fsm_event(grp->fsm, MPCG_EVENT_XID0DO, ch); 1783 + 1784 + return; 1785 + } 1786 + 1787 + /* 1788 + * ctcmpc channel FSM action 1789 + * called from several points in ctcmpc_ch_fsm 1790 + * ctcmpc only 1791 + */ 1792 + static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg) 1793 + { 1794 + struct channel *ach = arg; 1795 + struct net_device *dev = ach->netdev; 1796 + struct ctcm_priv *priv = dev->priv; 1797 + struct mpc_group *grp = priv->mpcg; 1798 + struct channel *wch = priv->channel[WRITE]; 1799 + struct channel *rch = priv->channel[READ]; 1800 + struct sk_buff *skb; 1801 + struct th_sweep *header; 1802 + int rc = 0; 1803 + unsigned long saveflags = 0; 1804 + 1805 + if (do_debug) 1806 + ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n", 1807 + __FUNCTION__, smp_processor_id(), ach, ach->id); 1808 + 1809 + if (grp->in_sweep == 0) 1810 + goto done; 1811 + 1812 + if (do_debug_data) { 1813 + ctcm_pr_debug("ctcmpc: %s() 1: ToVTAM_th_seq= %08x\n" , 1814 + __FUNCTION__, wch->th_seq_num); 1815 + ctcm_pr_debug("ctcmpc: %s() 1: FromVTAM_th_seq= %08x\n" , 1816 + __FUNCTION__, rch->th_seq_num); 1817 + } 1818 + 1819 + if (fsm_getstate(wch->fsm) != CTC_STATE_TXIDLE) { 1820 + /* give the previous IO time to complete */ 1821 + fsm_addtimer(&wch->sweep_timer, 1822 + 200, CTC_EVENT_RSWEEP_TIMER, wch); 1823 + goto done; 1824 + } 1825 + 1826 + skb = skb_dequeue(&wch->sweep_queue); 1827 + if (!skb) 1828 + goto done; 1829 + 1830 + if (set_normalized_cda(&wch->ccw[4], skb->data)) { 1831 + grp->in_sweep = 0; 1832 + ctcm_clear_busy_do(dev); 1833 + dev_kfree_skb_any(skb); 1834 + fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); 1835 + goto done; 1836 + } else { 1837 + atomic_inc(&skb->users); 1838 + skb_queue_tail(&wch->io_queue, skb); 1839 + } 1840 + 1841 + /* send out the sweep */ 1842 + wch->ccw[4].count = skb->len; 1843 + 1844 + header = (struct th_sweep *)skb->data; 1845 + switch (header->th.th_ch_flag) { 1846 + case TH_SWEEP_REQ: 1847 + grp->sweep_req_pend_num--; 1848 + break; 1849 + case TH_SWEEP_RESP: 1850 + grp->sweep_rsp_pend_num--; 1851 + break; 1852 + } 1853 + 1854 + header->sw.th_last_seq = wch->th_seq_num; 1855 + 1856 + if (do_debug_ccw) 1857 + ctcmpc_dumpit((char *)&wch->ccw[3], sizeof(struct ccw1) * 3); 1858 + 1859 + ctcm_pr_debug("ctcmpc: %s() sweep packet\n", __FUNCTION__); 1860 + ctcmpc_dumpit((char *)header, TH_SWEEP_LENGTH); 1861 + 1862 + fsm_addtimer(&wch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, wch); 1863 + fsm_newstate(wch->fsm, CTC_STATE_TX); 1864 + 1865 + spin_lock_irqsave(get_ccwdev_lock(wch->cdev), saveflags); 1866 + wch->prof.send_stamp = current_kernel_time(); /* xtime */ 1867 + rc = ccw_device_start(wch->cdev, &wch->ccw[3], 1868 + (unsigned long) wch, 0xff, 0); 1869 + spin_unlock_irqrestore(get_ccwdev_lock(wch->cdev), saveflags); 1870 + 1871 + if ((grp->sweep_req_pend_num == 0) && 1872 + (grp->sweep_rsp_pend_num == 0)) { 1873 + grp->in_sweep = 0; 1874 + rch->th_seq_num = 0x00; 1875 + wch->th_seq_num = 0x00; 1876 + ctcm_clear_busy_do(dev); 1877 + } 1878 + 1879 + if (do_debug_data) { 1880 + ctcm_pr_debug("ctcmpc: %s()2: ToVTAM_th_seq= %08x\n" , 1881 + __FUNCTION__, wch->th_seq_num); 1882 + ctcm_pr_debug("ctcmpc: %s()2: FromVTAM_th_seq= %08x\n" , 1883 + __FUNCTION__, rch->th_seq_num); 1884 + } 1885 + 1886 + if (rc != 0) 1887 + ctcm_ccw_check_rc(wch, rc, "send sweep"); 1888 + 1889 + done: 1890 + if (do_debug) 1891 + ctcm_pr_debug("ctcmpc exit: %s() %s\n", __FUNCTION__, ach->id); 1892 + return; 1893 + } 1894 + 1895 + 1896 + /* 1897 + * The ctcmpc statemachine for a channel. 1898 + */ 1899 + 1900 + const fsm_node ctcmpc_ch_fsm[] = { 1901 + { CTC_STATE_STOPPED, CTC_EVENT_STOP, ctcm_action_nop }, 1902 + { CTC_STATE_STOPPED, CTC_EVENT_START, ctcm_chx_start }, 1903 + { CTC_STATE_STOPPED, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 1904 + { CTC_STATE_STOPPED, CTC_EVENT_FINSTAT, ctcm_action_nop }, 1905 + { CTC_STATE_STOPPED, CTC_EVENT_MC_FAIL, ctcm_action_nop }, 1906 + 1907 + { CTC_STATE_NOTOP, CTC_EVENT_STOP, ctcm_chx_stop }, 1908 + { CTC_STATE_NOTOP, CTC_EVENT_START, ctcm_action_nop }, 1909 + { CTC_STATE_NOTOP, CTC_EVENT_FINSTAT, ctcm_action_nop }, 1910 + { CTC_STATE_NOTOP, CTC_EVENT_MC_FAIL, ctcm_action_nop }, 1911 + { CTC_STATE_NOTOP, CTC_EVENT_MC_GOOD, ctcm_chx_start }, 1912 + { CTC_STATE_NOTOP, CTC_EVENT_UC_RCRESET, ctcm_chx_stop }, 1913 + { CTC_STATE_NOTOP, CTC_EVENT_UC_RSRESET, ctcm_chx_stop }, 1914 + { CTC_STATE_NOTOP, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 1915 + 1916 + { CTC_STATE_STARTWAIT, CTC_EVENT_STOP, ctcm_chx_haltio }, 1917 + { CTC_STATE_STARTWAIT, CTC_EVENT_START, ctcm_action_nop }, 1918 + { CTC_STATE_STARTWAIT, CTC_EVENT_FINSTAT, ctcm_chx_setmode }, 1919 + { CTC_STATE_STARTWAIT, CTC_EVENT_TIMER, ctcm_chx_setuperr }, 1920 + { CTC_STATE_STARTWAIT, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 1921 + { CTC_STATE_STARTWAIT, CTC_EVENT_MC_FAIL, ctcm_chx_fail }, 1922 + 1923 + { CTC_STATE_STARTRETRY, CTC_EVENT_STOP, ctcm_chx_haltio }, 1924 + { CTC_STATE_STARTRETRY, CTC_EVENT_TIMER, ctcm_chx_setmode }, 1925 + { CTC_STATE_STARTRETRY, CTC_EVENT_FINSTAT, ctcm_chx_setmode }, 1926 + { CTC_STATE_STARTRETRY, CTC_EVENT_MC_FAIL, ctcm_chx_fail }, 1927 + { CTC_STATE_STARTRETRY, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 1928 + 1929 + { CTC_STATE_SETUPWAIT, CTC_EVENT_STOP, ctcm_chx_haltio }, 1930 + { CTC_STATE_SETUPWAIT, CTC_EVENT_START, ctcm_action_nop }, 1931 + { CTC_STATE_SETUPWAIT, CTC_EVENT_FINSTAT, ctcmpc_chx_firstio }, 1932 + { CTC_STATE_SETUPWAIT, CTC_EVENT_UC_RCRESET, ctcm_chx_setuperr }, 1933 + { CTC_STATE_SETUPWAIT, CTC_EVENT_UC_RSRESET, ctcm_chx_setuperr }, 1934 + { CTC_STATE_SETUPWAIT, CTC_EVENT_TIMER, ctcm_chx_setmode }, 1935 + { CTC_STATE_SETUPWAIT, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 1936 + { CTC_STATE_SETUPWAIT, CTC_EVENT_MC_FAIL, ctcm_chx_fail }, 1937 + 1938 + { CTC_STATE_RXINIT, CTC_EVENT_STOP, ctcm_chx_haltio }, 1939 + { CTC_STATE_RXINIT, CTC_EVENT_START, ctcm_action_nop }, 1940 + { CTC_STATE_RXINIT, CTC_EVENT_FINSTAT, ctcmpc_chx_rxidle }, 1941 + { CTC_STATE_RXINIT, CTC_EVENT_UC_RCRESET, ctcm_chx_rxiniterr }, 1942 + { CTC_STATE_RXINIT, CTC_EVENT_UC_RSRESET, ctcm_chx_rxiniterr }, 1943 + { CTC_STATE_RXINIT, CTC_EVENT_TIMER, ctcm_chx_rxiniterr }, 1944 + { CTC_STATE_RXINIT, CTC_EVENT_ATTNBUSY, ctcm_chx_rxinitfail }, 1945 + { CTC_STATE_RXINIT, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 1946 + { CTC_STATE_RXINIT, CTC_EVENT_UC_ZERO, ctcmpc_chx_firstio }, 1947 + { CTC_STATE_RXINIT, CTC_EVENT_MC_FAIL, ctcm_chx_fail }, 1948 + 1949 + { CH_XID0_PENDING, CTC_EVENT_FINSTAT, ctcm_action_nop }, 1950 + { CH_XID0_PENDING, CTC_EVENT_ATTN, ctcmpc_chx_attn }, 1951 + { CH_XID0_PENDING, CTC_EVENT_STOP, ctcm_chx_haltio }, 1952 + { CH_XID0_PENDING, CTC_EVENT_START, ctcm_action_nop }, 1953 + { CH_XID0_PENDING, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 1954 + { CH_XID0_PENDING, CTC_EVENT_MC_FAIL, ctcm_chx_fail }, 1955 + { CH_XID0_PENDING, CTC_EVENT_UC_RCRESET, ctcm_chx_setuperr }, 1956 + { CH_XID0_PENDING, CTC_EVENT_UC_RSRESET, ctcm_chx_setuperr }, 1957 + { CH_XID0_PENDING, CTC_EVENT_UC_RSRESET, ctcm_chx_setuperr }, 1958 + { CH_XID0_PENDING, CTC_EVENT_ATTNBUSY, ctcm_chx_iofatal }, 1959 + 1960 + { CH_XID0_INPROGRESS, CTC_EVENT_FINSTAT, ctcmpc_chx_rx }, 1961 + { CH_XID0_INPROGRESS, CTC_EVENT_ATTN, ctcmpc_chx_attn }, 1962 + { CH_XID0_INPROGRESS, CTC_EVENT_STOP, ctcm_chx_haltio }, 1963 + { CH_XID0_INPROGRESS, CTC_EVENT_START, ctcm_action_nop }, 1964 + { CH_XID0_INPROGRESS, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 1965 + { CH_XID0_INPROGRESS, CTC_EVENT_MC_FAIL, ctcm_chx_fail }, 1966 + { CH_XID0_INPROGRESS, CTC_EVENT_UC_ZERO, ctcmpc_chx_rx }, 1967 + { CH_XID0_INPROGRESS, CTC_EVENT_UC_RCRESET, ctcm_chx_setuperr }, 1968 + { CH_XID0_INPROGRESS, CTC_EVENT_ATTNBUSY, ctcmpc_chx_attnbusy }, 1969 + { CH_XID0_INPROGRESS, CTC_EVENT_TIMER, ctcmpc_chx_resend }, 1970 + { CH_XID0_INPROGRESS, CTC_EVENT_IO_EBUSY, ctcm_chx_fail }, 1971 + 1972 + { CH_XID7_PENDING, CTC_EVENT_FINSTAT, ctcmpc_chx_rx }, 1973 + { CH_XID7_PENDING, CTC_EVENT_ATTN, ctcmpc_chx_attn }, 1974 + { CH_XID7_PENDING, CTC_EVENT_STOP, ctcm_chx_haltio }, 1975 + { CH_XID7_PENDING, CTC_EVENT_START, ctcm_action_nop }, 1976 + { CH_XID7_PENDING, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 1977 + { CH_XID7_PENDING, CTC_EVENT_MC_FAIL, ctcm_chx_fail }, 1978 + { CH_XID7_PENDING, CTC_EVENT_UC_ZERO, ctcmpc_chx_rx }, 1979 + { CH_XID7_PENDING, CTC_EVENT_UC_RCRESET, ctcm_chx_setuperr }, 1980 + { CH_XID7_PENDING, CTC_EVENT_UC_RSRESET, ctcm_chx_setuperr }, 1981 + { CH_XID7_PENDING, CTC_EVENT_UC_RSRESET, ctcm_chx_setuperr }, 1982 + { CH_XID7_PENDING, CTC_EVENT_ATTNBUSY, ctcm_chx_iofatal }, 1983 + { CH_XID7_PENDING, CTC_EVENT_TIMER, ctcmpc_chx_resend }, 1984 + { CH_XID7_PENDING, CTC_EVENT_IO_EBUSY, ctcm_chx_fail }, 1985 + 1986 + { CH_XID7_PENDING1, CTC_EVENT_FINSTAT, ctcmpc_chx_rx }, 1987 + { CH_XID7_PENDING1, CTC_EVENT_ATTN, ctcmpc_chx_attn }, 1988 + { CH_XID7_PENDING1, CTC_EVENT_STOP, ctcm_chx_haltio }, 1989 + { CH_XID7_PENDING1, CTC_EVENT_START, ctcm_action_nop }, 1990 + { CH_XID7_PENDING1, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 1991 + { CH_XID7_PENDING1, CTC_EVENT_MC_FAIL, ctcm_chx_fail }, 1992 + { CH_XID7_PENDING1, CTC_EVENT_UC_ZERO, ctcmpc_chx_rx }, 1993 + { CH_XID7_PENDING1, CTC_EVENT_UC_RCRESET, ctcm_chx_setuperr }, 1994 + { CH_XID7_PENDING1, CTC_EVENT_UC_RSRESET, ctcm_chx_setuperr }, 1995 + { CH_XID7_PENDING1, CTC_EVENT_ATTNBUSY, ctcm_chx_iofatal }, 1996 + { CH_XID7_PENDING1, CTC_EVENT_TIMER, ctcmpc_chx_resend }, 1997 + { CH_XID7_PENDING1, CTC_EVENT_IO_EBUSY, ctcm_chx_fail }, 1998 + 1999 + { CH_XID7_PENDING2, CTC_EVENT_FINSTAT, ctcmpc_chx_rx }, 2000 + { CH_XID7_PENDING2, CTC_EVENT_ATTN, ctcmpc_chx_attn }, 2001 + { CH_XID7_PENDING2, CTC_EVENT_STOP, ctcm_chx_haltio }, 2002 + { CH_XID7_PENDING2, CTC_EVENT_START, ctcm_action_nop }, 2003 + { CH_XID7_PENDING2, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 2004 + { CH_XID7_PENDING2, CTC_EVENT_MC_FAIL, ctcm_chx_fail }, 2005 + { CH_XID7_PENDING2, CTC_EVENT_UC_ZERO, ctcmpc_chx_rx }, 2006 + { CH_XID7_PENDING2, CTC_EVENT_UC_RCRESET, ctcm_chx_setuperr }, 2007 + { CH_XID7_PENDING2, CTC_EVENT_UC_RSRESET, ctcm_chx_setuperr }, 2008 + { CH_XID7_PENDING2, CTC_EVENT_ATTNBUSY, ctcm_chx_iofatal }, 2009 + { CH_XID7_PENDING2, CTC_EVENT_TIMER, ctcmpc_chx_resend }, 2010 + { CH_XID7_PENDING2, CTC_EVENT_IO_EBUSY, ctcm_chx_fail }, 2011 + 2012 + { CH_XID7_PENDING3, CTC_EVENT_FINSTAT, ctcmpc_chx_rx }, 2013 + { CH_XID7_PENDING3, CTC_EVENT_ATTN, ctcmpc_chx_attn }, 2014 + { CH_XID7_PENDING3, CTC_EVENT_STOP, ctcm_chx_haltio }, 2015 + { CH_XID7_PENDING3, CTC_EVENT_START, ctcm_action_nop }, 2016 + { CH_XID7_PENDING3, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 2017 + { CH_XID7_PENDING3, CTC_EVENT_MC_FAIL, ctcm_chx_fail }, 2018 + { CH_XID7_PENDING3, CTC_EVENT_UC_ZERO, ctcmpc_chx_rx }, 2019 + { CH_XID7_PENDING3, CTC_EVENT_UC_RCRESET, ctcm_chx_setuperr }, 2020 + { CH_XID7_PENDING3, CTC_EVENT_UC_RSRESET, ctcm_chx_setuperr }, 2021 + { CH_XID7_PENDING3, CTC_EVENT_ATTNBUSY, ctcm_chx_iofatal }, 2022 + { CH_XID7_PENDING3, CTC_EVENT_TIMER, ctcmpc_chx_resend }, 2023 + { CH_XID7_PENDING3, CTC_EVENT_IO_EBUSY, ctcm_chx_fail }, 2024 + 2025 + { CH_XID7_PENDING4, CTC_EVENT_FINSTAT, ctcmpc_chx_rx }, 2026 + { CH_XID7_PENDING4, CTC_EVENT_ATTN, ctcmpc_chx_attn }, 2027 + { CH_XID7_PENDING4, CTC_EVENT_STOP, ctcm_chx_haltio }, 2028 + { CH_XID7_PENDING4, CTC_EVENT_START, ctcm_action_nop }, 2029 + { CH_XID7_PENDING4, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 2030 + { CH_XID7_PENDING4, CTC_EVENT_MC_FAIL, ctcm_chx_fail }, 2031 + { CH_XID7_PENDING4, CTC_EVENT_UC_ZERO, ctcmpc_chx_rx }, 2032 + { CH_XID7_PENDING4, CTC_EVENT_UC_RCRESET, ctcm_chx_setuperr }, 2033 + { CH_XID7_PENDING4, CTC_EVENT_UC_RSRESET, ctcm_chx_setuperr }, 2034 + { CH_XID7_PENDING4, CTC_EVENT_ATTNBUSY, ctcm_chx_iofatal }, 2035 + { CH_XID7_PENDING4, CTC_EVENT_TIMER, ctcmpc_chx_resend }, 2036 + { CH_XID7_PENDING4, CTC_EVENT_IO_EBUSY, ctcm_chx_fail }, 2037 + 2038 + { CTC_STATE_RXIDLE, CTC_EVENT_STOP, ctcm_chx_haltio }, 2039 + { CTC_STATE_RXIDLE, CTC_EVENT_START, ctcm_action_nop }, 2040 + { CTC_STATE_RXIDLE, CTC_EVENT_FINSTAT, ctcmpc_chx_rx }, 2041 + { CTC_STATE_RXIDLE, CTC_EVENT_UC_RCRESET, ctcm_chx_rxdisc }, 2042 + { CTC_STATE_RXIDLE, CTC_EVENT_UC_RSRESET, ctcm_chx_fail }, 2043 + { CTC_STATE_RXIDLE, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 2044 + { CTC_STATE_RXIDLE, CTC_EVENT_MC_FAIL, ctcm_chx_fail }, 2045 + { CTC_STATE_RXIDLE, CTC_EVENT_UC_ZERO, ctcmpc_chx_rx }, 2046 + 2047 + { CTC_STATE_TXINIT, CTC_EVENT_STOP, ctcm_chx_haltio }, 2048 + { CTC_STATE_TXINIT, CTC_EVENT_START, ctcm_action_nop }, 2049 + { CTC_STATE_TXINIT, CTC_EVENT_FINSTAT, ctcm_chx_txidle }, 2050 + { CTC_STATE_TXINIT, CTC_EVENT_UC_RCRESET, ctcm_chx_txiniterr }, 2051 + { CTC_STATE_TXINIT, CTC_EVENT_UC_RSRESET, ctcm_chx_txiniterr }, 2052 + { CTC_STATE_TXINIT, CTC_EVENT_TIMER, ctcm_chx_txiniterr }, 2053 + { CTC_STATE_TXINIT, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 2054 + { CTC_STATE_TXINIT, CTC_EVENT_MC_FAIL, ctcm_chx_fail }, 2055 + { CTC_STATE_TXINIT, CTC_EVENT_RSWEEP_TIMER, ctcmpc_chx_send_sweep }, 2056 + 2057 + { CTC_STATE_TXIDLE, CTC_EVENT_STOP, ctcm_chx_haltio }, 2058 + { CTC_STATE_TXIDLE, CTC_EVENT_START, ctcm_action_nop }, 2059 + { CTC_STATE_TXIDLE, CTC_EVENT_FINSTAT, ctcmpc_chx_firstio }, 2060 + { CTC_STATE_TXIDLE, CTC_EVENT_UC_RCRESET, ctcm_chx_fail }, 2061 + { CTC_STATE_TXIDLE, CTC_EVENT_UC_RSRESET, ctcm_chx_fail }, 2062 + { CTC_STATE_TXIDLE, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 2063 + { CTC_STATE_TXIDLE, CTC_EVENT_MC_FAIL, ctcm_chx_fail }, 2064 + { CTC_STATE_TXIDLE, CTC_EVENT_RSWEEP_TIMER, ctcmpc_chx_send_sweep }, 2065 + 2066 + { CTC_STATE_TERM, CTC_EVENT_STOP, ctcm_action_nop }, 2067 + { CTC_STATE_TERM, CTC_EVENT_START, ctcm_chx_restart }, 2068 + { CTC_STATE_TERM, CTC_EVENT_FINSTAT, ctcm_chx_stopped }, 2069 + { CTC_STATE_TERM, CTC_EVENT_UC_RCRESET, ctcm_action_nop }, 2070 + { CTC_STATE_TERM, CTC_EVENT_UC_RSRESET, ctcm_action_nop }, 2071 + { CTC_STATE_TERM, CTC_EVENT_MC_FAIL, ctcm_chx_fail }, 2072 + { CTC_STATE_TERM, CTC_EVENT_IO_EBUSY, ctcm_chx_fail }, 2073 + { CTC_STATE_TERM, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 2074 + 2075 + { CTC_STATE_DTERM, CTC_EVENT_STOP, ctcm_chx_haltio }, 2076 + { CTC_STATE_DTERM, CTC_EVENT_START, ctcm_chx_restart }, 2077 + { CTC_STATE_DTERM, CTC_EVENT_FINSTAT, ctcm_chx_setmode }, 2078 + { CTC_STATE_DTERM, CTC_EVENT_UC_RCRESET, ctcm_action_nop }, 2079 + { CTC_STATE_DTERM, CTC_EVENT_UC_RSRESET, ctcm_action_nop }, 2080 + { CTC_STATE_DTERM, CTC_EVENT_MC_FAIL, ctcm_chx_fail }, 2081 + { CTC_STATE_DTERM, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 2082 + 2083 + { CTC_STATE_TX, CTC_EVENT_STOP, ctcm_chx_haltio }, 2084 + { CTC_STATE_TX, CTC_EVENT_START, ctcm_action_nop }, 2085 + { CTC_STATE_TX, CTC_EVENT_FINSTAT, ctcmpc_chx_txdone }, 2086 + { CTC_STATE_TX, CTC_EVENT_UC_RCRESET, ctcm_chx_fail }, 2087 + { CTC_STATE_TX, CTC_EVENT_UC_RSRESET, ctcm_chx_fail }, 2088 + { CTC_STATE_TX, CTC_EVENT_TIMER, ctcm_chx_txretry }, 2089 + { CTC_STATE_TX, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 2090 + { CTC_STATE_TX, CTC_EVENT_MC_FAIL, ctcm_chx_fail }, 2091 + { CTC_STATE_TX, CTC_EVENT_RSWEEP_TIMER, ctcmpc_chx_send_sweep }, 2092 + { CTC_STATE_TX, CTC_EVENT_IO_EBUSY, ctcm_chx_fail }, 2093 + 2094 + { CTC_STATE_RXERR, CTC_EVENT_STOP, ctcm_chx_haltio }, 2095 + { CTC_STATE_TXERR, CTC_EVENT_STOP, ctcm_chx_haltio }, 2096 + { CTC_STATE_TXERR, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal }, 2097 + { CTC_STATE_TXERR, CTC_EVENT_MC_FAIL, ctcm_chx_fail }, 2098 + { CTC_STATE_RXERR, CTC_EVENT_MC_FAIL, ctcm_chx_fail }, 2099 + }; 2100 + 2101 + int mpc_ch_fsm_len = ARRAY_SIZE(ctcmpc_ch_fsm); 2102 + 2103 + /* 2104 + * Actions for interface - statemachine. 2105 + */ 2106 + 2107 + /** 2108 + * Startup channels by sending CTC_EVENT_START to each channel. 2109 + * 2110 + * fi An instance of an interface statemachine. 2111 + * event The event, just happened. 2112 + * arg Generic pointer, casted from struct net_device * upon call. 2113 + */ 2114 + static void dev_action_start(fsm_instance *fi, int event, void *arg) 2115 + { 2116 + struct net_device *dev = arg; 2117 + struct ctcm_priv *priv = dev->priv; 2118 + int direction; 2119 + 2120 + CTCMY_DBF_DEV_NAME(SETUP, dev, ""); 2121 + 2122 + fsm_deltimer(&priv->restart_timer); 2123 + fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX); 2124 + if (IS_MPC(priv)) 2125 + priv->mpcg->channels_terminating = 0; 2126 + for (direction = READ; direction <= WRITE; direction++) { 2127 + struct channel *ch = priv->channel[direction]; 2128 + fsm_event(ch->fsm, CTC_EVENT_START, ch); 2129 + } 2130 + } 2131 + 2132 + /** 2133 + * Shutdown channels by sending CTC_EVENT_STOP to each channel. 2134 + * 2135 + * fi An instance of an interface statemachine. 2136 + * event The event, just happened. 2137 + * arg Generic pointer, casted from struct net_device * upon call. 2138 + */ 2139 + static void dev_action_stop(fsm_instance *fi, int event, void *arg) 2140 + { 2141 + int direction; 2142 + struct net_device *dev = arg; 2143 + struct ctcm_priv *priv = dev->priv; 2144 + 2145 + CTCMY_DBF_DEV_NAME(SETUP, dev, ""); 2146 + 2147 + fsm_newstate(fi, DEV_STATE_STOPWAIT_RXTX); 2148 + for (direction = READ; direction <= WRITE; direction++) { 2149 + struct channel *ch = priv->channel[direction]; 2150 + fsm_event(ch->fsm, CTC_EVENT_STOP, ch); 2151 + ch->th_seq_num = 0x00; 2152 + if (do_debug) 2153 + ctcm_pr_debug("ctcm: %s() CH_th_seq= %08x\n", 2154 + __FUNCTION__, ch->th_seq_num); 2155 + } 2156 + if (IS_MPC(priv)) 2157 + fsm_newstate(priv->mpcg->fsm, MPCG_STATE_RESET); 2158 + } 2159 + 2160 + static void dev_action_restart(fsm_instance *fi, int event, void *arg) 2161 + { 2162 + int restart_timer; 2163 + struct net_device *dev = arg; 2164 + struct ctcm_priv *priv = dev->priv; 2165 + 2166 + CTCMY_DBF_DEV_NAME(TRACE, dev, ""); 2167 + 2168 + if (IS_MPC(priv)) { 2169 + ctcm_pr_info("ctcm: %s Restarting Device and " 2170 + "MPC Group in 5 seconds\n", 2171 + dev->name); 2172 + restart_timer = CTCM_TIME_1_SEC; 2173 + } else { 2174 + ctcm_pr_info("%s: Restarting\n", dev->name); 2175 + restart_timer = CTCM_TIME_5_SEC; 2176 + } 2177 + 2178 + dev_action_stop(fi, event, arg); 2179 + fsm_event(priv->fsm, DEV_EVENT_STOP, dev); 2180 + if (IS_MPC(priv)) 2181 + fsm_newstate(priv->mpcg->fsm, MPCG_STATE_RESET); 2182 + 2183 + /* going back into start sequence too quickly can */ 2184 + /* result in the other side becoming unreachable due */ 2185 + /* to sense reported when IO is aborted */ 2186 + fsm_addtimer(&priv->restart_timer, restart_timer, 2187 + DEV_EVENT_START, dev); 2188 + } 2189 + 2190 + /** 2191 + * Called from channel statemachine 2192 + * when a channel is up and running. 2193 + * 2194 + * fi An instance of an interface statemachine. 2195 + * event The event, just happened. 2196 + * arg Generic pointer, casted from struct net_device * upon call. 2197 + */ 2198 + static void dev_action_chup(fsm_instance *fi, int event, void *arg) 2199 + { 2200 + struct net_device *dev = arg; 2201 + struct ctcm_priv *priv = dev->priv; 2202 + 2203 + CTCMY_DBF_DEV_NAME(SETUP, dev, ""); 2204 + 2205 + switch (fsm_getstate(fi)) { 2206 + case DEV_STATE_STARTWAIT_RXTX: 2207 + if (event == DEV_EVENT_RXUP) 2208 + fsm_newstate(fi, DEV_STATE_STARTWAIT_TX); 2209 + else 2210 + fsm_newstate(fi, DEV_STATE_STARTWAIT_RX); 2211 + break; 2212 + case DEV_STATE_STARTWAIT_RX: 2213 + if (event == DEV_EVENT_RXUP) { 2214 + fsm_newstate(fi, DEV_STATE_RUNNING); 2215 + ctcm_pr_info("%s: connected with remote side\n", 2216 + dev->name); 2217 + ctcm_clear_busy(dev); 2218 + } 2219 + break; 2220 + case DEV_STATE_STARTWAIT_TX: 2221 + if (event == DEV_EVENT_TXUP) { 2222 + fsm_newstate(fi, DEV_STATE_RUNNING); 2223 + ctcm_pr_info("%s: connected with remote side\n", 2224 + dev->name); 2225 + ctcm_clear_busy(dev); 2226 + } 2227 + break; 2228 + case DEV_STATE_STOPWAIT_TX: 2229 + if (event == DEV_EVENT_RXUP) 2230 + fsm_newstate(fi, DEV_STATE_STOPWAIT_RXTX); 2231 + break; 2232 + case DEV_STATE_STOPWAIT_RX: 2233 + if (event == DEV_EVENT_TXUP) 2234 + fsm_newstate(fi, DEV_STATE_STOPWAIT_RXTX); 2235 + break; 2236 + } 2237 + 2238 + if (IS_MPC(priv)) { 2239 + if (event == DEV_EVENT_RXUP) 2240 + mpc_channel_action(priv->channel[READ], 2241 + READ, MPC_CHANNEL_ADD); 2242 + else 2243 + mpc_channel_action(priv->channel[WRITE], 2244 + WRITE, MPC_CHANNEL_ADD); 2245 + } 2246 + } 2247 + 2248 + /** 2249 + * Called from device statemachine 2250 + * when a channel has been shutdown. 2251 + * 2252 + * fi An instance of an interface statemachine. 2253 + * event The event, just happened. 2254 + * arg Generic pointer, casted from struct net_device * upon call. 2255 + */ 2256 + static void dev_action_chdown(fsm_instance *fi, int event, void *arg) 2257 + { 2258 + 2259 + struct net_device *dev = arg; 2260 + struct ctcm_priv *priv = dev->priv; 2261 + 2262 + CTCMY_DBF_DEV_NAME(SETUP, dev, ""); 2263 + 2264 + switch (fsm_getstate(fi)) { 2265 + case DEV_STATE_RUNNING: 2266 + if (event == DEV_EVENT_TXDOWN) 2267 + fsm_newstate(fi, DEV_STATE_STARTWAIT_TX); 2268 + else 2269 + fsm_newstate(fi, DEV_STATE_STARTWAIT_RX); 2270 + break; 2271 + case DEV_STATE_STARTWAIT_RX: 2272 + if (event == DEV_EVENT_TXDOWN) 2273 + fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX); 2274 + break; 2275 + case DEV_STATE_STARTWAIT_TX: 2276 + if (event == DEV_EVENT_RXDOWN) 2277 + fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX); 2278 + break; 2279 + case DEV_STATE_STOPWAIT_RXTX: 2280 + if (event == DEV_EVENT_TXDOWN) 2281 + fsm_newstate(fi, DEV_STATE_STOPWAIT_RX); 2282 + else 2283 + fsm_newstate(fi, DEV_STATE_STOPWAIT_TX); 2284 + break; 2285 + case DEV_STATE_STOPWAIT_RX: 2286 + if (event == DEV_EVENT_RXDOWN) 2287 + fsm_newstate(fi, DEV_STATE_STOPPED); 2288 + break; 2289 + case DEV_STATE_STOPWAIT_TX: 2290 + if (event == DEV_EVENT_TXDOWN) 2291 + fsm_newstate(fi, DEV_STATE_STOPPED); 2292 + break; 2293 + } 2294 + if (IS_MPC(priv)) { 2295 + if (event == DEV_EVENT_RXDOWN) 2296 + mpc_channel_action(priv->channel[READ], 2297 + READ, MPC_CHANNEL_REMOVE); 2298 + else 2299 + mpc_channel_action(priv->channel[WRITE], 2300 + WRITE, MPC_CHANNEL_REMOVE); 2301 + } 2302 + } 2303 + 2304 + const fsm_node dev_fsm[] = { 2305 + { DEV_STATE_STOPPED, DEV_EVENT_START, dev_action_start }, 2306 + { DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_START, dev_action_start }, 2307 + { DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_RXDOWN, dev_action_chdown }, 2308 + { DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_TXDOWN, dev_action_chdown }, 2309 + { DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_RESTART, dev_action_restart }, 2310 + { DEV_STATE_STOPWAIT_RX, DEV_EVENT_START, dev_action_start }, 2311 + { DEV_STATE_STOPWAIT_RX, DEV_EVENT_RXUP, dev_action_chup }, 2312 + { DEV_STATE_STOPWAIT_RX, DEV_EVENT_TXUP, dev_action_chup }, 2313 + { DEV_STATE_STOPWAIT_RX, DEV_EVENT_RXDOWN, dev_action_chdown }, 2314 + { DEV_STATE_STOPWAIT_RX, DEV_EVENT_RESTART, dev_action_restart }, 2315 + { DEV_STATE_STOPWAIT_TX, DEV_EVENT_START, dev_action_start }, 2316 + { DEV_STATE_STOPWAIT_TX, DEV_EVENT_RXUP, dev_action_chup }, 2317 + { DEV_STATE_STOPWAIT_TX, DEV_EVENT_TXUP, dev_action_chup }, 2318 + { DEV_STATE_STOPWAIT_TX, DEV_EVENT_TXDOWN, dev_action_chdown }, 2319 + { DEV_STATE_STOPWAIT_TX, DEV_EVENT_RESTART, dev_action_restart }, 2320 + { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_STOP, dev_action_stop }, 2321 + { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXUP, dev_action_chup }, 2322 + { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXUP, dev_action_chup }, 2323 + { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXDOWN, dev_action_chdown }, 2324 + { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXDOWN, dev_action_chdown }, 2325 + { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RESTART, dev_action_restart }, 2326 + { DEV_STATE_STARTWAIT_TX, DEV_EVENT_STOP, dev_action_stop }, 2327 + { DEV_STATE_STARTWAIT_TX, DEV_EVENT_RXUP, dev_action_chup }, 2328 + { DEV_STATE_STARTWAIT_TX, DEV_EVENT_TXUP, dev_action_chup }, 2329 + { DEV_STATE_STARTWAIT_TX, DEV_EVENT_RXDOWN, dev_action_chdown }, 2330 + { DEV_STATE_STARTWAIT_TX, DEV_EVENT_RESTART, dev_action_restart }, 2331 + { DEV_STATE_STARTWAIT_RX, DEV_EVENT_STOP, dev_action_stop }, 2332 + { DEV_STATE_STARTWAIT_RX, DEV_EVENT_RXUP, dev_action_chup }, 2333 + { DEV_STATE_STARTWAIT_RX, DEV_EVENT_TXUP, dev_action_chup }, 2334 + { DEV_STATE_STARTWAIT_RX, DEV_EVENT_TXDOWN, dev_action_chdown }, 2335 + { DEV_STATE_STARTWAIT_RX, DEV_EVENT_RESTART, dev_action_restart }, 2336 + { DEV_STATE_RUNNING, DEV_EVENT_STOP, dev_action_stop }, 2337 + { DEV_STATE_RUNNING, DEV_EVENT_RXDOWN, dev_action_chdown }, 2338 + { DEV_STATE_RUNNING, DEV_EVENT_TXDOWN, dev_action_chdown }, 2339 + { DEV_STATE_RUNNING, DEV_EVENT_TXUP, ctcm_action_nop }, 2340 + { DEV_STATE_RUNNING, DEV_EVENT_RXUP, ctcm_action_nop }, 2341 + { DEV_STATE_RUNNING, DEV_EVENT_RESTART, dev_action_restart }, 2342 + }; 2343 + 2344 + int dev_fsm_len = ARRAY_SIZE(dev_fsm); 2345 + 2346 + /* --- This is the END my friend --- */ 2347 +
+359
drivers/s390/net/ctcm_fsms.h
··· 1 + /* 2 + * drivers/s390/net/ctcm_fsms.h 3 + * 4 + * Copyright IBM Corp. 2001, 2007 5 + * Authors: Fritz Elfert (felfert@millenux.com) 6 + * Peter Tiedemann (ptiedem@de.ibm.com) 7 + * MPC additions : 8 + * Belinda Thompson (belindat@us.ibm.com) 9 + * Andy Richter (richtera@us.ibm.com) 10 + */ 11 + #ifndef _CTCM_FSMS_H_ 12 + #define _CTCM_FSMS_H_ 13 + 14 + #include <linux/module.h> 15 + #include <linux/init.h> 16 + #include <linux/kernel.h> 17 + #include <linux/slab.h> 18 + #include <linux/errno.h> 19 + #include <linux/types.h> 20 + #include <linux/interrupt.h> 21 + #include <linux/timer.h> 22 + #include <linux/bitops.h> 23 + 24 + #include <linux/signal.h> 25 + #include <linux/string.h> 26 + 27 + #include <linux/ip.h> 28 + #include <linux/if_arp.h> 29 + #include <linux/tcp.h> 30 + #include <linux/skbuff.h> 31 + #include <linux/ctype.h> 32 + #include <net/dst.h> 33 + 34 + #include <linux/io.h> 35 + #include <asm/ccwdev.h> 36 + #include <asm/ccwgroup.h> 37 + #include <linux/uaccess.h> 38 + 39 + #include <asm/idals.h> 40 + 41 + #include "fsm.h" 42 + #include "cu3088.h" 43 + #include "ctcm_main.h" 44 + 45 + /* 46 + * Definitions for the channel statemachine(s) for ctc and ctcmpc 47 + * 48 + * To allow better kerntyping, prefix-less definitions for channel states 49 + * and channel events have been replaced : 50 + * ch_event... -> ctc_ch_event... 51 + * CH_EVENT... -> CTC_EVENT... 52 + * ch_state... -> ctc_ch_state... 53 + * CH_STATE... -> CTC_STATE... 54 + */ 55 + /* 56 + * Events of the channel statemachine(s) for ctc and ctcmpc 57 + */ 58 + enum ctc_ch_events { 59 + /* 60 + * Events, representing return code of 61 + * I/O operations (ccw_device_start, ccw_device_halt et al.) 62 + */ 63 + CTC_EVENT_IO_SUCCESS, 64 + CTC_EVENT_IO_EBUSY, 65 + CTC_EVENT_IO_ENODEV, 66 + CTC_EVENT_IO_UNKNOWN, 67 + 68 + CTC_EVENT_ATTNBUSY, 69 + CTC_EVENT_ATTN, 70 + CTC_EVENT_BUSY, 71 + /* 72 + * Events, representing unit-check 73 + */ 74 + CTC_EVENT_UC_RCRESET, 75 + CTC_EVENT_UC_RSRESET, 76 + CTC_EVENT_UC_TXTIMEOUT, 77 + CTC_EVENT_UC_TXPARITY, 78 + CTC_EVENT_UC_HWFAIL, 79 + CTC_EVENT_UC_RXPARITY, 80 + CTC_EVENT_UC_ZERO, 81 + CTC_EVENT_UC_UNKNOWN, 82 + /* 83 + * Events, representing subchannel-check 84 + */ 85 + CTC_EVENT_SC_UNKNOWN, 86 + /* 87 + * Events, representing machine checks 88 + */ 89 + CTC_EVENT_MC_FAIL, 90 + CTC_EVENT_MC_GOOD, 91 + /* 92 + * Event, representing normal IRQ 93 + */ 94 + CTC_EVENT_IRQ, 95 + CTC_EVENT_FINSTAT, 96 + /* 97 + * Event, representing timer expiry. 98 + */ 99 + CTC_EVENT_TIMER, 100 + /* 101 + * Events, representing commands from upper levels. 102 + */ 103 + CTC_EVENT_START, 104 + CTC_EVENT_STOP, 105 + CTC_NR_EVENTS, 106 + /* 107 + * additional MPC events 108 + */ 109 + CTC_EVENT_SEND_XID = CTC_NR_EVENTS, 110 + CTC_EVENT_RSWEEP_TIMER, 111 + /* 112 + * MUST be always the last element!! 113 + */ 114 + CTC_MPC_NR_EVENTS, 115 + }; 116 + 117 + /* 118 + * States of the channel statemachine(s) for ctc and ctcmpc. 119 + */ 120 + enum ctc_ch_states { 121 + /* 122 + * Channel not assigned to any device, 123 + * initial state, direction invalid 124 + */ 125 + CTC_STATE_IDLE, 126 + /* 127 + * Channel assigned but not operating 128 + */ 129 + CTC_STATE_STOPPED, 130 + CTC_STATE_STARTWAIT, 131 + CTC_STATE_STARTRETRY, 132 + CTC_STATE_SETUPWAIT, 133 + CTC_STATE_RXINIT, 134 + CTC_STATE_TXINIT, 135 + CTC_STATE_RX, 136 + CTC_STATE_TX, 137 + CTC_STATE_RXIDLE, 138 + CTC_STATE_TXIDLE, 139 + CTC_STATE_RXERR, 140 + CTC_STATE_TXERR, 141 + CTC_STATE_TERM, 142 + CTC_STATE_DTERM, 143 + CTC_STATE_NOTOP, 144 + CTC_NR_STATES, /* MUST be the last element of non-expanded states */ 145 + /* 146 + * additional MPC states 147 + */ 148 + CH_XID0_PENDING = CTC_NR_STATES, 149 + CH_XID0_INPROGRESS, 150 + CH_XID7_PENDING, 151 + CH_XID7_PENDING1, 152 + CH_XID7_PENDING2, 153 + CH_XID7_PENDING3, 154 + CH_XID7_PENDING4, 155 + CTC_MPC_NR_STATES, /* MUST be the last element of expanded mpc states */ 156 + }; 157 + 158 + extern const char *ctc_ch_event_names[]; 159 + 160 + extern const char *ctc_ch_state_names[]; 161 + 162 + void ctcm_ccw_check_rc(struct channel *ch, int rc, char *msg); 163 + void ctcm_purge_skb_queue(struct sk_buff_head *q); 164 + void fsm_action_nop(fsm_instance *fi, int event, void *arg); 165 + 166 + /* 167 + * ----- non-static actions for ctcm channel statemachine ----- 168 + * 169 + */ 170 + void ctcm_chx_txidle(fsm_instance *fi, int event, void *arg); 171 + 172 + /* 173 + * ----- FSM (state/event/action) of the ctcm channel statemachine ----- 174 + */ 175 + extern const fsm_node ch_fsm[]; 176 + extern int ch_fsm_len; 177 + 178 + 179 + /* 180 + * ----- non-static actions for ctcmpc channel statemachine ---- 181 + * 182 + */ 183 + /* shared : 184 + void ctcm_chx_txidle(fsm_instance * fi, int event, void *arg); 185 + */ 186 + void ctcmpc_chx_rxidle(fsm_instance *fi, int event, void *arg); 187 + 188 + /* 189 + * ----- FSM (state/event/action) of the ctcmpc channel statemachine ----- 190 + */ 191 + extern const fsm_node ctcmpc_ch_fsm[]; 192 + extern int mpc_ch_fsm_len; 193 + 194 + /* 195 + * Definitions for the device interface statemachine for ctc and mpc 196 + */ 197 + 198 + /* 199 + * States of the device interface statemachine. 200 + */ 201 + enum dev_states { 202 + DEV_STATE_STOPPED, 203 + DEV_STATE_STARTWAIT_RXTX, 204 + DEV_STATE_STARTWAIT_RX, 205 + DEV_STATE_STARTWAIT_TX, 206 + DEV_STATE_STOPWAIT_RXTX, 207 + DEV_STATE_STOPWAIT_RX, 208 + DEV_STATE_STOPWAIT_TX, 209 + DEV_STATE_RUNNING, 210 + /* 211 + * MUST be always the last element!! 212 + */ 213 + CTCM_NR_DEV_STATES 214 + }; 215 + 216 + extern const char *dev_state_names[]; 217 + 218 + /* 219 + * Events of the device interface statemachine. 220 + * ctcm and ctcmpc 221 + */ 222 + enum dev_events { 223 + DEV_EVENT_START, 224 + DEV_EVENT_STOP, 225 + DEV_EVENT_RXUP, 226 + DEV_EVENT_TXUP, 227 + DEV_EVENT_RXDOWN, 228 + DEV_EVENT_TXDOWN, 229 + DEV_EVENT_RESTART, 230 + /* 231 + * MUST be always the last element!! 232 + */ 233 + CTCM_NR_DEV_EVENTS 234 + }; 235 + 236 + extern const char *dev_event_names[]; 237 + 238 + /* 239 + * Actions for the device interface statemachine. 240 + * ctc and ctcmpc 241 + */ 242 + /* 243 + static void dev_action_start(fsm_instance * fi, int event, void *arg); 244 + static void dev_action_stop(fsm_instance * fi, int event, void *arg); 245 + static void dev_action_restart(fsm_instance *fi, int event, void *arg); 246 + static void dev_action_chup(fsm_instance * fi, int event, void *arg); 247 + static void dev_action_chdown(fsm_instance * fi, int event, void *arg); 248 + */ 249 + 250 + /* 251 + * The (state/event/action) fsm table of the device interface statemachine. 252 + * ctcm and ctcmpc 253 + */ 254 + extern const fsm_node dev_fsm[]; 255 + extern int dev_fsm_len; 256 + 257 + 258 + /* 259 + * Definitions for the MPC Group statemachine 260 + */ 261 + 262 + /* 263 + * MPC Group Station FSM States 264 + 265 + State Name When In This State 266 + ====================== ======================================= 267 + MPCG_STATE_RESET Initial State When Driver Loaded 268 + We receive and send NOTHING 269 + 270 + MPCG_STATE_INOP INOP Received. 271 + Group level non-recoverable error 272 + 273 + MPCG_STATE_READY XID exchanges for at least 1 write and 274 + 1 read channel have completed. 275 + Group is ready for data transfer. 276 + 277 + States from ctc_mpc_alloc_channel 278 + ============================================================== 279 + MPCG_STATE_XID2INITW Awaiting XID2(0) Initiation 280 + ATTN from other side will start 281 + XID negotiations. 282 + Y-side protocol only. 283 + 284 + MPCG_STATE_XID2INITX XID2(0) negotiations are in progress. 285 + At least 1, but not all, XID2(0)'s 286 + have been received from partner. 287 + 288 + MPCG_STATE_XID7INITW XID2(0) complete 289 + No XID2(7)'s have yet been received. 290 + XID2(7) negotiations pending. 291 + 292 + MPCG_STATE_XID7INITX XID2(7) negotiations in progress. 293 + At least 1, but not all, XID2(7)'s 294 + have been received from partner. 295 + 296 + MPCG_STATE_XID7INITF XID2(7) negotiations complete. 297 + Transitioning to READY. 298 + 299 + MPCG_STATE_READY Ready for Data Transfer. 300 + 301 + 302 + States from ctc_mpc_establish_connectivity call 303 + ============================================================== 304 + MPCG_STATE_XID0IOWAIT Initiating XID2(0) negotiations. 305 + X-side protocol only. 306 + ATTN-BUSY from other side will convert 307 + this to Y-side protocol and the 308 + ctc_mpc_alloc_channel flow will begin. 309 + 310 + MPCG_STATE_XID0IOWAIX XID2(0) negotiations are in progress. 311 + At least 1, but not all, XID2(0)'s 312 + have been received from partner. 313 + 314 + MPCG_STATE_XID7INITI XID2(0) complete 315 + No XID2(7)'s have yet been received. 316 + XID2(7) negotiations pending. 317 + 318 + MPCG_STATE_XID7INITZ XID2(7) negotiations in progress. 319 + At least 1, but not all, XID2(7)'s 320 + have been received from partner. 321 + 322 + MPCG_STATE_XID7INITF XID2(7) negotiations complete. 323 + Transitioning to READY. 324 + 325 + MPCG_STATE_READY Ready for Data Transfer. 326 + 327 + */ 328 + 329 + enum mpcg_events { 330 + MPCG_EVENT_INOP, 331 + MPCG_EVENT_DISCONC, 332 + MPCG_EVENT_XID0DO, 333 + MPCG_EVENT_XID2, 334 + MPCG_EVENT_XID2DONE, 335 + MPCG_EVENT_XID7DONE, 336 + MPCG_EVENT_TIMER, 337 + MPCG_EVENT_DOIO, 338 + MPCG_NR_EVENTS, 339 + }; 340 + 341 + enum mpcg_states { 342 + MPCG_STATE_RESET, 343 + MPCG_STATE_INOP, 344 + MPCG_STATE_XID2INITW, 345 + MPCG_STATE_XID2INITX, 346 + MPCG_STATE_XID7INITW, 347 + MPCG_STATE_XID7INITX, 348 + MPCG_STATE_XID0IOWAIT, 349 + MPCG_STATE_XID0IOWAIX, 350 + MPCG_STATE_XID7INITI, 351 + MPCG_STATE_XID7INITZ, 352 + MPCG_STATE_XID7INITF, 353 + MPCG_STATE_FLOWC, 354 + MPCG_STATE_READY, 355 + MPCG_NR_STATES, 356 + }; 357 + 358 + #endif 359 + /* --- This is the END my friend --- */
+1772
drivers/s390/net/ctcm_main.c
··· 1 + /* 2 + * drivers/s390/net/ctcm_main.c 3 + * 4 + * Copyright IBM Corp. 2001, 2007 5 + * Author(s): 6 + * Original CTC driver(s): 7 + * Fritz Elfert (felfert@millenux.com) 8 + * Dieter Wellerdiek (wel@de.ibm.com) 9 + * Martin Schwidefsky (schwidefsky@de.ibm.com) 10 + * Denis Joseph Barrow (barrow_dj@yahoo.com) 11 + * Jochen Roehrig (roehrig@de.ibm.com) 12 + * Cornelia Huck <cornelia.huck@de.ibm.com> 13 + * MPC additions: 14 + * Belinda Thompson (belindat@us.ibm.com) 15 + * Andy Richter (richtera@us.ibm.com) 16 + * Revived by: 17 + * Peter Tiedemann (ptiedem@de.ibm.com) 18 + */ 19 + 20 + #undef DEBUG 21 + #undef DEBUGDATA 22 + #undef DEBUGCCW 23 + 24 + #include <linux/module.h> 25 + #include <linux/init.h> 26 + #include <linux/kernel.h> 27 + #include <linux/slab.h> 28 + #include <linux/errno.h> 29 + #include <linux/types.h> 30 + #include <linux/interrupt.h> 31 + #include <linux/timer.h> 32 + #include <linux/bitops.h> 33 + 34 + #include <linux/signal.h> 35 + #include <linux/string.h> 36 + 37 + #include <linux/ip.h> 38 + #include <linux/if_arp.h> 39 + #include <linux/tcp.h> 40 + #include <linux/skbuff.h> 41 + #include <linux/ctype.h> 42 + #include <net/dst.h> 43 + 44 + #include <linux/io.h> 45 + #include <asm/ccwdev.h> 46 + #include <asm/ccwgroup.h> 47 + #include <linux/uaccess.h> 48 + 49 + #include <asm/idals.h> 50 + 51 + #include "cu3088.h" 52 + #include "ctcm_fsms.h" 53 + #include "ctcm_main.h" 54 + 55 + /* Some common global variables */ 56 + 57 + /* 58 + * Linked list of all detected channels. 59 + */ 60 + struct channel *channels; 61 + 62 + /** 63 + * Unpack a just received skb and hand it over to 64 + * upper layers. 65 + * 66 + * ch The channel where this skb has been received. 67 + * pskb The received skb. 68 + */ 69 + void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb) 70 + { 71 + struct net_device *dev = ch->netdev; 72 + struct ctcm_priv *priv = dev->priv; 73 + __u16 len = *((__u16 *) pskb->data); 74 + 75 + skb_put(pskb, 2 + LL_HEADER_LENGTH); 76 + skb_pull(pskb, 2); 77 + pskb->dev = dev; 78 + pskb->ip_summed = CHECKSUM_UNNECESSARY; 79 + while (len > 0) { 80 + struct sk_buff *skb; 81 + int skblen; 82 + struct ll_header *header = (struct ll_header *)pskb->data; 83 + 84 + skb_pull(pskb, LL_HEADER_LENGTH); 85 + if ((ch->protocol == CTCM_PROTO_S390) && 86 + (header->type != ETH_P_IP)) { 87 + 88 + if (!(ch->logflags & LOG_FLAG_ILLEGALPKT)) { 89 + /* 90 + * Check packet type only if we stick strictly 91 + * to S/390's protocol of OS390. This only 92 + * supports IP. Otherwise allow any packet 93 + * type. 94 + */ 95 + ctcm_pr_warn("%s Illegal packet type 0x%04x " 96 + "received, dropping\n", 97 + dev->name, header->type); 98 + ch->logflags |= LOG_FLAG_ILLEGALPKT; 99 + } 100 + 101 + priv->stats.rx_dropped++; 102 + priv->stats.rx_frame_errors++; 103 + return; 104 + } 105 + pskb->protocol = ntohs(header->type); 106 + if (header->length <= LL_HEADER_LENGTH) { 107 + if (!(ch->logflags & LOG_FLAG_ILLEGALSIZE)) { 108 + ctcm_pr_warn( 109 + "%s Illegal packet size %d " 110 + "received (MTU=%d blocklen=%d), " 111 + "dropping\n", dev->name, header->length, 112 + dev->mtu, len); 113 + ch->logflags |= LOG_FLAG_ILLEGALSIZE; 114 + } 115 + 116 + priv->stats.rx_dropped++; 117 + priv->stats.rx_length_errors++; 118 + return; 119 + } 120 + header->length -= LL_HEADER_LENGTH; 121 + len -= LL_HEADER_LENGTH; 122 + if ((header->length > skb_tailroom(pskb)) || 123 + (header->length > len)) { 124 + if (!(ch->logflags & LOG_FLAG_OVERRUN)) { 125 + ctcm_pr_warn( 126 + "%s Illegal packet size %d (beyond the" 127 + " end of received data), dropping\n", 128 + dev->name, header->length); 129 + ch->logflags |= LOG_FLAG_OVERRUN; 130 + } 131 + 132 + priv->stats.rx_dropped++; 133 + priv->stats.rx_length_errors++; 134 + return; 135 + } 136 + skb_put(pskb, header->length); 137 + skb_reset_mac_header(pskb); 138 + len -= header->length; 139 + skb = dev_alloc_skb(pskb->len); 140 + if (!skb) { 141 + if (!(ch->logflags & LOG_FLAG_NOMEM)) { 142 + ctcm_pr_warn( 143 + "%s Out of memory in ctcm_unpack_skb\n", 144 + dev->name); 145 + ch->logflags |= LOG_FLAG_NOMEM; 146 + } 147 + priv->stats.rx_dropped++; 148 + return; 149 + } 150 + skb_copy_from_linear_data(pskb, skb_put(skb, pskb->len), 151 + pskb->len); 152 + skb_reset_mac_header(skb); 153 + skb->dev = pskb->dev; 154 + skb->protocol = pskb->protocol; 155 + pskb->ip_summed = CHECKSUM_UNNECESSARY; 156 + skblen = skb->len; 157 + /* 158 + * reset logflags 159 + */ 160 + ch->logflags = 0; 161 + priv->stats.rx_packets++; 162 + priv->stats.rx_bytes += skblen; 163 + netif_rx_ni(skb); 164 + dev->last_rx = jiffies; 165 + if (len > 0) { 166 + skb_pull(pskb, header->length); 167 + if (skb_tailroom(pskb) < LL_HEADER_LENGTH) { 168 + if (!(ch->logflags & LOG_FLAG_OVERRUN)) { 169 + CTCM_DBF_DEV_NAME(TRACE, dev, 170 + "Overrun in ctcm_unpack_skb"); 171 + ch->logflags |= LOG_FLAG_OVERRUN; 172 + } 173 + return; 174 + } 175 + skb_put(pskb, LL_HEADER_LENGTH); 176 + } 177 + } 178 + } 179 + 180 + /** 181 + * Release a specific channel in the channel list. 182 + * 183 + * ch Pointer to channel struct to be released. 184 + */ 185 + static void channel_free(struct channel *ch) 186 + { 187 + CTCM_DBF_TEXT(TRACE, 2, __FUNCTION__); 188 + ch->flags &= ~CHANNEL_FLAGS_INUSE; 189 + fsm_newstate(ch->fsm, CTC_STATE_IDLE); 190 + } 191 + 192 + /** 193 + * Remove a specific channel in the channel list. 194 + * 195 + * ch Pointer to channel struct to be released. 196 + */ 197 + static void channel_remove(struct channel *ch) 198 + { 199 + struct channel **c = &channels; 200 + char chid[CTCM_ID_SIZE+1]; 201 + int ok = 0; 202 + 203 + if (ch == NULL) 204 + return; 205 + else 206 + strncpy(chid, ch->id, CTCM_ID_SIZE); 207 + 208 + channel_free(ch); 209 + while (*c) { 210 + if (*c == ch) { 211 + *c = ch->next; 212 + fsm_deltimer(&ch->timer); 213 + if (IS_MPC(ch)) 214 + fsm_deltimer(&ch->sweep_timer); 215 + 216 + kfree_fsm(ch->fsm); 217 + clear_normalized_cda(&ch->ccw[4]); 218 + if (ch->trans_skb != NULL) { 219 + clear_normalized_cda(&ch->ccw[1]); 220 + dev_kfree_skb_any(ch->trans_skb); 221 + } 222 + if (IS_MPC(ch)) { 223 + tasklet_kill(&ch->ch_tasklet); 224 + tasklet_kill(&ch->ch_disc_tasklet); 225 + kfree(ch->discontact_th); 226 + } 227 + kfree(ch->ccw); 228 + kfree(ch->irb); 229 + kfree(ch); 230 + ok = 1; 231 + break; 232 + } 233 + c = &((*c)->next); 234 + } 235 + 236 + CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, "%s(%s) %s", CTCM_FUNTAIL, 237 + chid, ok ? "OK" : "failed"); 238 + } 239 + 240 + /** 241 + * Get a specific channel from the channel list. 242 + * 243 + * type Type of channel we are interested in. 244 + * id Id of channel we are interested in. 245 + * direction Direction we want to use this channel for. 246 + * 247 + * returns Pointer to a channel or NULL if no matching channel available. 248 + */ 249 + static struct channel *channel_get(enum channel_types type, 250 + char *id, int direction) 251 + { 252 + struct channel *ch = channels; 253 + 254 + if (do_debug) { 255 + char buf[64]; 256 + sprintf(buf, "%s(%d, %s, %d)\n", 257 + CTCM_FUNTAIL, type, id, direction); 258 + CTCM_DBF_TEXT(TRACE, CTC_DBF_INFO, buf); 259 + } 260 + while (ch && (strncmp(ch->id, id, CTCM_ID_SIZE) || (ch->type != type))) 261 + ch = ch->next; 262 + if (!ch) { 263 + char buf[64]; 264 + sprintf(buf, "%s(%d, %s, %d) not found in channel list\n", 265 + CTCM_FUNTAIL, type, id, direction); 266 + CTCM_DBF_TEXT(ERROR, CTC_DBF_ERROR, buf); 267 + } else { 268 + if (ch->flags & CHANNEL_FLAGS_INUSE) 269 + ch = NULL; 270 + else { 271 + ch->flags |= CHANNEL_FLAGS_INUSE; 272 + ch->flags &= ~CHANNEL_FLAGS_RWMASK; 273 + ch->flags |= (direction == WRITE) 274 + ? CHANNEL_FLAGS_WRITE : CHANNEL_FLAGS_READ; 275 + fsm_newstate(ch->fsm, CTC_STATE_STOPPED); 276 + } 277 + } 278 + return ch; 279 + } 280 + 281 + static long ctcm_check_irb_error(struct ccw_device *cdev, struct irb *irb) 282 + { 283 + if (!IS_ERR(irb)) 284 + return 0; 285 + 286 + CTCM_DBF_TEXT_(ERROR, CTC_DBF_WARN, "irb error %ld on device %s\n", 287 + PTR_ERR(irb), cdev->dev.bus_id); 288 + 289 + switch (PTR_ERR(irb)) { 290 + case -EIO: 291 + ctcm_pr_warn("i/o-error on device %s\n", cdev->dev.bus_id); 292 + break; 293 + case -ETIMEDOUT: 294 + ctcm_pr_warn("timeout on device %s\n", cdev->dev.bus_id); 295 + break; 296 + default: 297 + ctcm_pr_warn("unknown error %ld on device %s\n", 298 + PTR_ERR(irb), cdev->dev.bus_id); 299 + } 300 + return PTR_ERR(irb); 301 + } 302 + 303 + 304 + /** 305 + * Check sense of a unit check. 306 + * 307 + * ch The channel, the sense code belongs to. 308 + * sense The sense code to inspect. 309 + */ 310 + static inline void ccw_unit_check(struct channel *ch, unsigned char sense) 311 + { 312 + CTCM_DBF_TEXT(TRACE, 5, __FUNCTION__); 313 + if (sense & SNS0_INTERVENTION_REQ) { 314 + if (sense & 0x01) { 315 + ctcm_pr_debug("%s: Interface disc. or Sel. reset " 316 + "(remote)\n", ch->id); 317 + fsm_event(ch->fsm, CTC_EVENT_UC_RCRESET, ch); 318 + } else { 319 + ctcm_pr_debug("%s: System reset (remote)\n", ch->id); 320 + fsm_event(ch->fsm, CTC_EVENT_UC_RSRESET, ch); 321 + } 322 + } else if (sense & SNS0_EQUIPMENT_CHECK) { 323 + if (sense & SNS0_BUS_OUT_CHECK) { 324 + ctcm_pr_warn("%s: Hardware malfunction (remote)\n", 325 + ch->id); 326 + fsm_event(ch->fsm, CTC_EVENT_UC_HWFAIL, ch); 327 + } else { 328 + ctcm_pr_warn("%s: Read-data parity error (remote)\n", 329 + ch->id); 330 + fsm_event(ch->fsm, CTC_EVENT_UC_RXPARITY, ch); 331 + } 332 + } else if (sense & SNS0_BUS_OUT_CHECK) { 333 + if (sense & 0x04) { 334 + ctcm_pr_warn("%s: Data-streaming timeout)\n", ch->id); 335 + fsm_event(ch->fsm, CTC_EVENT_UC_TXTIMEOUT, ch); 336 + } else { 337 + ctcm_pr_warn("%s: Data-transfer parity error\n", 338 + ch->id); 339 + fsm_event(ch->fsm, CTC_EVENT_UC_TXPARITY, ch); 340 + } 341 + } else if (sense & SNS0_CMD_REJECT) { 342 + ctcm_pr_warn("%s: Command reject\n", ch->id); 343 + } else if (sense == 0) { 344 + ctcm_pr_debug("%s: Unit check ZERO\n", ch->id); 345 + fsm_event(ch->fsm, CTC_EVENT_UC_ZERO, ch); 346 + } else { 347 + ctcm_pr_warn("%s: Unit Check with sense code: %02x\n", 348 + ch->id, sense); 349 + fsm_event(ch->fsm, CTC_EVENT_UC_UNKNOWN, ch); 350 + } 351 + } 352 + 353 + int ctcm_ch_alloc_buffer(struct channel *ch) 354 + { 355 + CTCM_DBF_TEXT(TRACE, 5, __FUNCTION__); 356 + 357 + clear_normalized_cda(&ch->ccw[1]); 358 + ch->trans_skb = __dev_alloc_skb(ch->max_bufsize, GFP_ATOMIC | GFP_DMA); 359 + if (ch->trans_skb == NULL) { 360 + ctcm_pr_warn("%s: Couldn't alloc %s trans_skb\n", 361 + ch->id, 362 + (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX"); 363 + return -ENOMEM; 364 + } 365 + 366 + ch->ccw[1].count = ch->max_bufsize; 367 + if (set_normalized_cda(&ch->ccw[1], ch->trans_skb->data)) { 368 + dev_kfree_skb(ch->trans_skb); 369 + ch->trans_skb = NULL; 370 + ctcm_pr_warn("%s: set_normalized_cda for %s " 371 + "trans_skb failed, dropping packets\n", 372 + ch->id, 373 + (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX"); 374 + return -ENOMEM; 375 + } 376 + 377 + ch->ccw[1].count = 0; 378 + ch->trans_skb_data = ch->trans_skb->data; 379 + ch->flags &= ~CHANNEL_FLAGS_BUFSIZE_CHANGED; 380 + return 0; 381 + } 382 + 383 + /* 384 + * Interface API for upper network layers 385 + */ 386 + 387 + /** 388 + * Open an interface. 389 + * Called from generic network layer when ifconfig up is run. 390 + * 391 + * dev Pointer to interface struct. 392 + * 393 + * returns 0 on success, -ERRNO on failure. (Never fails.) 394 + */ 395 + int ctcm_open(struct net_device *dev) 396 + { 397 + struct ctcm_priv *priv = dev->priv; 398 + 399 + CTCMY_DBF_DEV_NAME(SETUP, dev, ""); 400 + if (!IS_MPC(priv)) 401 + fsm_event(priv->fsm, DEV_EVENT_START, dev); 402 + return 0; 403 + } 404 + 405 + /** 406 + * Close an interface. 407 + * Called from generic network layer when ifconfig down is run. 408 + * 409 + * dev Pointer to interface struct. 410 + * 411 + * returns 0 on success, -ERRNO on failure. (Never fails.) 412 + */ 413 + int ctcm_close(struct net_device *dev) 414 + { 415 + struct ctcm_priv *priv = dev->priv; 416 + 417 + CTCMY_DBF_DEV_NAME(SETUP, dev, ""); 418 + if (!IS_MPC(priv)) 419 + fsm_event(priv->fsm, DEV_EVENT_STOP, dev); 420 + return 0; 421 + } 422 + 423 + 424 + /** 425 + * Transmit a packet. 426 + * This is a helper function for ctcm_tx(). 427 + * 428 + * ch Channel to be used for sending. 429 + * skb Pointer to struct sk_buff of packet to send. 430 + * The linklevel header has already been set up 431 + * by ctcm_tx(). 432 + * 433 + * returns 0 on success, -ERRNO on failure. (Never fails.) 434 + */ 435 + static int ctcm_transmit_skb(struct channel *ch, struct sk_buff *skb) 436 + { 437 + unsigned long saveflags; 438 + struct ll_header header; 439 + int rc = 0; 440 + __u16 block_len; 441 + int ccw_idx; 442 + struct sk_buff *nskb; 443 + unsigned long hi; 444 + 445 + /* we need to acquire the lock for testing the state 446 + * otherwise we can have an IRQ changing the state to 447 + * TXIDLE after the test but before acquiring the lock. 448 + */ 449 + spin_lock_irqsave(&ch->collect_lock, saveflags); 450 + if (fsm_getstate(ch->fsm) != CTC_STATE_TXIDLE) { 451 + int l = skb->len + LL_HEADER_LENGTH; 452 + 453 + if (ch->collect_len + l > ch->max_bufsize - 2) { 454 + spin_unlock_irqrestore(&ch->collect_lock, saveflags); 455 + return -EBUSY; 456 + } else { 457 + atomic_inc(&skb->users); 458 + header.length = l; 459 + header.type = skb->protocol; 460 + header.unused = 0; 461 + memcpy(skb_push(skb, LL_HEADER_LENGTH), &header, 462 + LL_HEADER_LENGTH); 463 + skb_queue_tail(&ch->collect_queue, skb); 464 + ch->collect_len += l; 465 + } 466 + spin_unlock_irqrestore(&ch->collect_lock, saveflags); 467 + goto done; 468 + } 469 + spin_unlock_irqrestore(&ch->collect_lock, saveflags); 470 + /* 471 + * Protect skb against beeing free'd by upper 472 + * layers. 473 + */ 474 + atomic_inc(&skb->users); 475 + ch->prof.txlen += skb->len; 476 + header.length = skb->len + LL_HEADER_LENGTH; 477 + header.type = skb->protocol; 478 + header.unused = 0; 479 + memcpy(skb_push(skb, LL_HEADER_LENGTH), &header, LL_HEADER_LENGTH); 480 + block_len = skb->len + 2; 481 + *((__u16 *)skb_push(skb, 2)) = block_len; 482 + 483 + /* 484 + * IDAL support in CTCM is broken, so we have to 485 + * care about skb's above 2G ourselves. 486 + */ 487 + hi = ((unsigned long)skb_tail_pointer(skb) + LL_HEADER_LENGTH) >> 31; 488 + if (hi) { 489 + nskb = alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); 490 + if (!nskb) { 491 + atomic_dec(&skb->users); 492 + skb_pull(skb, LL_HEADER_LENGTH + 2); 493 + ctcm_clear_busy(ch->netdev); 494 + return -ENOMEM; 495 + } else { 496 + memcpy(skb_put(nskb, skb->len), skb->data, skb->len); 497 + atomic_inc(&nskb->users); 498 + atomic_dec(&skb->users); 499 + dev_kfree_skb_irq(skb); 500 + skb = nskb; 501 + } 502 + } 503 + 504 + ch->ccw[4].count = block_len; 505 + if (set_normalized_cda(&ch->ccw[4], skb->data)) { 506 + /* 507 + * idal allocation failed, try via copying to 508 + * trans_skb. trans_skb usually has a pre-allocated 509 + * idal. 510 + */ 511 + if (ctcm_checkalloc_buffer(ch)) { 512 + /* 513 + * Remove our header. It gets added 514 + * again on retransmit. 515 + */ 516 + atomic_dec(&skb->users); 517 + skb_pull(skb, LL_HEADER_LENGTH + 2); 518 + ctcm_clear_busy(ch->netdev); 519 + return -EBUSY; 520 + } 521 + 522 + skb_reset_tail_pointer(ch->trans_skb); 523 + ch->trans_skb->len = 0; 524 + ch->ccw[1].count = skb->len; 525 + skb_copy_from_linear_data(skb, 526 + skb_put(ch->trans_skb, skb->len), skb->len); 527 + atomic_dec(&skb->users); 528 + dev_kfree_skb_irq(skb); 529 + ccw_idx = 0; 530 + } else { 531 + skb_queue_tail(&ch->io_queue, skb); 532 + ccw_idx = 3; 533 + } 534 + ch->retry = 0; 535 + fsm_newstate(ch->fsm, CTC_STATE_TX); 536 + fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch); 537 + spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags); 538 + ch->prof.send_stamp = current_kernel_time(); /* xtime */ 539 + rc = ccw_device_start(ch->cdev, &ch->ccw[ccw_idx], 540 + (unsigned long)ch, 0xff, 0); 541 + spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags); 542 + if (ccw_idx == 3) 543 + ch->prof.doios_single++; 544 + if (rc != 0) { 545 + fsm_deltimer(&ch->timer); 546 + ctcm_ccw_check_rc(ch, rc, "single skb TX"); 547 + if (ccw_idx == 3) 548 + skb_dequeue_tail(&ch->io_queue); 549 + /* 550 + * Remove our header. It gets added 551 + * again on retransmit. 552 + */ 553 + skb_pull(skb, LL_HEADER_LENGTH + 2); 554 + } else if (ccw_idx == 0) { 555 + struct net_device *dev = ch->netdev; 556 + struct ctcm_priv *priv = dev->priv; 557 + priv->stats.tx_packets++; 558 + priv->stats.tx_bytes += skb->len - LL_HEADER_LENGTH; 559 + } 560 + done: 561 + ctcm_clear_busy(ch->netdev); 562 + return rc; 563 + } 564 + 565 + static void ctcmpc_send_sweep_req(struct channel *rch) 566 + { 567 + struct net_device *dev = rch->netdev; 568 + struct ctcm_priv *priv; 569 + struct mpc_group *grp; 570 + struct th_sweep *header; 571 + struct sk_buff *sweep_skb; 572 + struct channel *ch; 573 + int rc = 0; 574 + 575 + priv = dev->priv; 576 + grp = priv->mpcg; 577 + ch = priv->channel[WRITE]; 578 + 579 + if (do_debug) 580 + MPC_DBF_DEV_NAME(TRACE, dev, ch->id); 581 + 582 + /* sweep processing is not complete until response and request */ 583 + /* has completed for all read channels in group */ 584 + if (grp->in_sweep == 0) { 585 + grp->in_sweep = 1; 586 + grp->sweep_rsp_pend_num = grp->active_channels[READ]; 587 + grp->sweep_req_pend_num = grp->active_channels[READ]; 588 + } 589 + 590 + sweep_skb = __dev_alloc_skb(MPC_BUFSIZE_DEFAULT, GFP_ATOMIC|GFP_DMA); 591 + 592 + if (sweep_skb == NULL) { 593 + printk(KERN_INFO "Couldn't alloc sweep_skb\n"); 594 + rc = -ENOMEM; 595 + goto done; 596 + } 597 + 598 + header = kmalloc(TH_SWEEP_LENGTH, gfp_type()); 599 + 600 + if (!header) { 601 + dev_kfree_skb_any(sweep_skb); 602 + rc = -ENOMEM; 603 + goto done; 604 + } 605 + 606 + header->th.th_seg = 0x00 ; 607 + header->th.th_ch_flag = TH_SWEEP_REQ; /* 0x0f */ 608 + header->th.th_blk_flag = 0x00; 609 + header->th.th_is_xid = 0x00; 610 + header->th.th_seq_num = 0x00; 611 + header->sw.th_last_seq = ch->th_seq_num; 612 + 613 + memcpy(skb_put(sweep_skb, TH_SWEEP_LENGTH), header, TH_SWEEP_LENGTH); 614 + 615 + kfree(header); 616 + 617 + dev->trans_start = jiffies; 618 + skb_queue_tail(&ch->sweep_queue, sweep_skb); 619 + 620 + fsm_addtimer(&ch->sweep_timer, 100, CTC_EVENT_RSWEEP_TIMER, ch); 621 + 622 + return; 623 + 624 + done: 625 + if (rc != 0) { 626 + grp->in_sweep = 0; 627 + ctcm_clear_busy(dev); 628 + fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); 629 + } 630 + 631 + return; 632 + } 633 + 634 + /* 635 + * MPC mode version of transmit_skb 636 + */ 637 + static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb) 638 + { 639 + struct pdu *p_header; 640 + struct net_device *dev = ch->netdev; 641 + struct ctcm_priv *priv = dev->priv; 642 + struct mpc_group *grp = priv->mpcg; 643 + struct th_header *header; 644 + struct sk_buff *nskb; 645 + int rc = 0; 646 + int ccw_idx; 647 + unsigned long hi; 648 + unsigned long saveflags = 0; /* avoids compiler warning */ 649 + __u16 block_len; 650 + 651 + if (do_debug) 652 + ctcm_pr_debug( 653 + "ctcm enter: %s(): %s cp=%i ch=0x%p id=%s state=%s\n", 654 + __FUNCTION__, dev->name, smp_processor_id(), ch, 655 + ch->id, fsm_getstate_str(ch->fsm)); 656 + 657 + if ((fsm_getstate(ch->fsm) != CTC_STATE_TXIDLE) || grp->in_sweep) { 658 + spin_lock_irqsave(&ch->collect_lock, saveflags); 659 + atomic_inc(&skb->users); 660 + p_header = kmalloc(PDU_HEADER_LENGTH, gfp_type()); 661 + 662 + if (!p_header) { 663 + printk(KERN_WARNING "ctcm: OUT OF MEMORY IN %s():" 664 + " Data Lost \n", __FUNCTION__); 665 + 666 + atomic_dec(&skb->users); 667 + dev_kfree_skb_any(skb); 668 + spin_unlock_irqrestore(&ch->collect_lock, saveflags); 669 + fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev); 670 + goto done; 671 + } 672 + 673 + p_header->pdu_offset = skb->len; 674 + p_header->pdu_proto = 0x01; 675 + p_header->pdu_flag = 0x00; 676 + if (skb->protocol == ntohs(ETH_P_SNAP)) { 677 + p_header->pdu_flag |= PDU_FIRST | PDU_CNTL; 678 + } else { 679 + p_header->pdu_flag |= PDU_FIRST; 680 + } 681 + p_header->pdu_seq = 0; 682 + memcpy(skb_push(skb, PDU_HEADER_LENGTH), p_header, 683 + PDU_HEADER_LENGTH); 684 + 685 + if (do_debug_data) { 686 + ctcm_pr_debug("ctcm: %s() Putting on collect_q" 687 + " - skb len: %04x \n", __FUNCTION__, skb->len); 688 + ctcm_pr_debug("ctcm: %s() pdu header and data" 689 + " for up to 32 bytes\n", __FUNCTION__); 690 + ctcmpc_dump32((char *)skb->data, skb->len); 691 + } 692 + 693 + skb_queue_tail(&ch->collect_queue, skb); 694 + ch->collect_len += skb->len; 695 + kfree(p_header); 696 + 697 + spin_unlock_irqrestore(&ch->collect_lock, saveflags); 698 + goto done; 699 + } 700 + 701 + /* 702 + * Protect skb against beeing free'd by upper 703 + * layers. 704 + */ 705 + atomic_inc(&skb->users); 706 + 707 + block_len = skb->len + TH_HEADER_LENGTH + PDU_HEADER_LENGTH; 708 + /* 709 + * IDAL support in CTCM is broken, so we have to 710 + * care about skb's above 2G ourselves. 711 + */ 712 + hi = ((unsigned long)skb->tail + TH_HEADER_LENGTH) >> 31; 713 + if (hi) { 714 + nskb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); 715 + if (!nskb) { 716 + printk(KERN_WARNING "ctcm: %s() OUT OF MEMORY" 717 + "- Data Lost \n", __FUNCTION__); 718 + atomic_dec(&skb->users); 719 + dev_kfree_skb_any(skb); 720 + fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev); 721 + goto done; 722 + } else { 723 + memcpy(skb_put(nskb, skb->len), skb->data, skb->len); 724 + atomic_inc(&nskb->users); 725 + atomic_dec(&skb->users); 726 + dev_kfree_skb_irq(skb); 727 + skb = nskb; 728 + } 729 + } 730 + 731 + p_header = kmalloc(PDU_HEADER_LENGTH, gfp_type()); 732 + 733 + if (!p_header) { 734 + printk(KERN_WARNING "ctcm: %s() OUT OF MEMORY" 735 + ": Data Lost \n", __FUNCTION__); 736 + 737 + atomic_dec(&skb->users); 738 + dev_kfree_skb_any(skb); 739 + fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev); 740 + goto done; 741 + } 742 + 743 + p_header->pdu_offset = skb->len; 744 + p_header->pdu_proto = 0x01; 745 + p_header->pdu_flag = 0x00; 746 + p_header->pdu_seq = 0; 747 + if (skb->protocol == ntohs(ETH_P_SNAP)) { 748 + p_header->pdu_flag |= PDU_FIRST | PDU_CNTL; 749 + } else { 750 + p_header->pdu_flag |= PDU_FIRST; 751 + } 752 + memcpy(skb_push(skb, PDU_HEADER_LENGTH), p_header, PDU_HEADER_LENGTH); 753 + 754 + kfree(p_header); 755 + 756 + if (ch->collect_len > 0) { 757 + spin_lock_irqsave(&ch->collect_lock, saveflags); 758 + skb_queue_tail(&ch->collect_queue, skb); 759 + ch->collect_len += skb->len; 760 + skb = skb_dequeue(&ch->collect_queue); 761 + ch->collect_len -= skb->len; 762 + spin_unlock_irqrestore(&ch->collect_lock, saveflags); 763 + } 764 + 765 + p_header = (struct pdu *)skb->data; 766 + p_header->pdu_flag |= PDU_LAST; 767 + 768 + ch->prof.txlen += skb->len - PDU_HEADER_LENGTH; 769 + 770 + header = kmalloc(TH_HEADER_LENGTH, gfp_type()); 771 + 772 + if (!header) { 773 + printk(KERN_WARNING "ctcm: %s() OUT OF MEMORY: Data Lost \n", 774 + __FUNCTION__); 775 + atomic_dec(&skb->users); 776 + dev_kfree_skb_any(skb); 777 + fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev); 778 + goto done; 779 + } 780 + 781 + header->th_seg = 0x00; 782 + header->th_ch_flag = TH_HAS_PDU; /* Normal data */ 783 + header->th_blk_flag = 0x00; 784 + header->th_is_xid = 0x00; /* Just data here */ 785 + ch->th_seq_num++; 786 + header->th_seq_num = ch->th_seq_num; 787 + 788 + if (do_debug_data) 789 + ctcm_pr_debug("ctcm: %s() ToVTAM_th_seq= %08x\n" , 790 + __FUNCTION__, ch->th_seq_num); 791 + 792 + /* put the TH on the packet */ 793 + memcpy(skb_push(skb, TH_HEADER_LENGTH), header, TH_HEADER_LENGTH); 794 + 795 + kfree(header); 796 + 797 + if (do_debug_data) { 798 + ctcm_pr_debug("ctcm: %s(): skb len: %04x \n", 799 + __FUNCTION__, skb->len); 800 + ctcm_pr_debug("ctcm: %s(): pdu header and data for up to 32 " 801 + "bytes sent to vtam\n", __FUNCTION__); 802 + ctcmpc_dump32((char *)skb->data, skb->len); 803 + } 804 + 805 + ch->ccw[4].count = skb->len; 806 + if (set_normalized_cda(&ch->ccw[4], skb->data)) { 807 + /* 808 + * idal allocation failed, try via copying to 809 + * trans_skb. trans_skb usually has a pre-allocated 810 + * idal. 811 + */ 812 + if (ctcm_checkalloc_buffer(ch)) { 813 + /* 814 + * Remove our header. It gets added 815 + * again on retransmit. 816 + */ 817 + atomic_dec(&skb->users); 818 + dev_kfree_skb_any(skb); 819 + printk(KERN_WARNING "ctcm: %s()OUT OF MEMORY:" 820 + " Data Lost \n", __FUNCTION__); 821 + fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev); 822 + goto done; 823 + } 824 + 825 + skb_reset_tail_pointer(ch->trans_skb); 826 + ch->trans_skb->len = 0; 827 + ch->ccw[1].count = skb->len; 828 + memcpy(skb_put(ch->trans_skb, skb->len), skb->data, skb->len); 829 + atomic_dec(&skb->users); 830 + dev_kfree_skb_irq(skb); 831 + ccw_idx = 0; 832 + if (do_debug_data) { 833 + ctcm_pr_debug("ctcm: %s() TRANS skb len: %d \n", 834 + __FUNCTION__, ch->trans_skb->len); 835 + ctcm_pr_debug("ctcm: %s up to 32 bytes of data" 836 + " sent to vtam\n", __FUNCTION__); 837 + ctcmpc_dump32((char *)ch->trans_skb->data, 838 + ch->trans_skb->len); 839 + } 840 + } else { 841 + skb_queue_tail(&ch->io_queue, skb); 842 + ccw_idx = 3; 843 + } 844 + ch->retry = 0; 845 + fsm_newstate(ch->fsm, CTC_STATE_TX); 846 + fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch); 847 + 848 + if (do_debug_ccw) 849 + ctcmpc_dumpit((char *)&ch->ccw[ccw_idx], 850 + sizeof(struct ccw1) * 3); 851 + 852 + spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags); 853 + ch->prof.send_stamp = current_kernel_time(); /* xtime */ 854 + rc = ccw_device_start(ch->cdev, &ch->ccw[ccw_idx], 855 + (unsigned long)ch, 0xff, 0); 856 + spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags); 857 + if (ccw_idx == 3) 858 + ch->prof.doios_single++; 859 + if (rc != 0) { 860 + fsm_deltimer(&ch->timer); 861 + ctcm_ccw_check_rc(ch, rc, "single skb TX"); 862 + if (ccw_idx == 3) 863 + skb_dequeue_tail(&ch->io_queue); 864 + } else if (ccw_idx == 0) { 865 + priv->stats.tx_packets++; 866 + priv->stats.tx_bytes += skb->len - TH_HEADER_LENGTH; 867 + } 868 + if (ch->th_seq_num > 0xf0000000) /* Chose 4Billion at random. */ 869 + ctcmpc_send_sweep_req(ch); 870 + 871 + done: 872 + if (do_debug) 873 + ctcm_pr_debug("ctcm exit: %s %s()\n", dev->name, __FUNCTION__); 874 + return 0; 875 + } 876 + 877 + /** 878 + * Start transmission of a packet. 879 + * Called from generic network device layer. 880 + * 881 + * skb Pointer to buffer containing the packet. 882 + * dev Pointer to interface struct. 883 + * 884 + * returns 0 if packet consumed, !0 if packet rejected. 885 + * Note: If we return !0, then the packet is free'd by 886 + * the generic network layer. 887 + */ 888 + /* first merge version - leaving both functions separated */ 889 + static int ctcm_tx(struct sk_buff *skb, struct net_device *dev) 890 + { 891 + int rc = 0; 892 + struct ctcm_priv *priv; 893 + 894 + CTCM_DBF_TEXT(TRACE, 5, __FUNCTION__); 895 + priv = dev->priv; 896 + 897 + if (skb == NULL) { 898 + ctcm_pr_warn("%s: NULL sk_buff passed\n", dev->name); 899 + priv->stats.tx_dropped++; 900 + return 0; 901 + } 902 + if (skb_headroom(skb) < (LL_HEADER_LENGTH + 2)) { 903 + ctcm_pr_warn("%s: Got sk_buff with head room < %ld bytes\n", 904 + dev->name, LL_HEADER_LENGTH + 2); 905 + dev_kfree_skb(skb); 906 + priv->stats.tx_dropped++; 907 + return 0; 908 + } 909 + 910 + /* 911 + * If channels are not running, try to restart them 912 + * and throw away packet. 913 + */ 914 + if (fsm_getstate(priv->fsm) != DEV_STATE_RUNNING) { 915 + fsm_event(priv->fsm, DEV_EVENT_START, dev); 916 + dev_kfree_skb(skb); 917 + priv->stats.tx_dropped++; 918 + priv->stats.tx_errors++; 919 + priv->stats.tx_carrier_errors++; 920 + return 0; 921 + } 922 + 923 + if (ctcm_test_and_set_busy(dev)) 924 + return -EBUSY; 925 + 926 + dev->trans_start = jiffies; 927 + if (ctcm_transmit_skb(priv->channel[WRITE], skb) != 0) 928 + rc = 1; 929 + return rc; 930 + } 931 + 932 + /* unmerged MPC variant of ctcm_tx */ 933 + static int ctcmpc_tx(struct sk_buff *skb, struct net_device *dev) 934 + { 935 + int len = 0; 936 + struct ctcm_priv *priv = NULL; 937 + struct mpc_group *grp = NULL; 938 + struct sk_buff *newskb = NULL; 939 + 940 + if (do_debug) 941 + ctcm_pr_debug("ctcmpc enter: %s(): skb:%0lx\n", 942 + __FUNCTION__, (unsigned long)skb); 943 + 944 + CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_DEBUG, 945 + "ctcmpc enter: %s(): skb:%0lx\n", 946 + __FUNCTION__, (unsigned long)skb); 947 + 948 + priv = dev->priv; 949 + grp = priv->mpcg; 950 + /* 951 + * Some sanity checks ... 952 + */ 953 + if (skb == NULL) { 954 + ctcm_pr_warn("ctcmpc: %s: NULL sk_buff passed\n", dev->name); 955 + priv->stats.tx_dropped++; 956 + goto done; 957 + } 958 + if (skb_headroom(skb) < (TH_HEADER_LENGTH + PDU_HEADER_LENGTH)) { 959 + CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_WARN, 960 + "%s: Got sk_buff with head room < %ld bytes\n", 961 + dev->name, TH_HEADER_LENGTH + PDU_HEADER_LENGTH); 962 + 963 + if (do_debug_data) 964 + ctcmpc_dump32((char *)skb->data, skb->len); 965 + 966 + len = skb->len + TH_HEADER_LENGTH + PDU_HEADER_LENGTH; 967 + newskb = __dev_alloc_skb(len, gfp_type() | GFP_DMA); 968 + 969 + if (!newskb) { 970 + printk(KERN_WARNING "ctcmpc: %s() OUT OF MEMORY-" 971 + "Data Lost\n", 972 + __FUNCTION__); 973 + 974 + dev_kfree_skb_any(skb); 975 + priv->stats.tx_dropped++; 976 + priv->stats.tx_errors++; 977 + priv->stats.tx_carrier_errors++; 978 + fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); 979 + goto done; 980 + } 981 + newskb->protocol = skb->protocol; 982 + skb_reserve(newskb, TH_HEADER_LENGTH + PDU_HEADER_LENGTH); 983 + memcpy(skb_put(newskb, skb->len), skb->data, skb->len); 984 + dev_kfree_skb_any(skb); 985 + skb = newskb; 986 + } 987 + 988 + /* 989 + * If channels are not running, 990 + * notify anybody about a link failure and throw 991 + * away packet. 992 + */ 993 + if ((fsm_getstate(priv->fsm) != DEV_STATE_RUNNING) || 994 + (fsm_getstate(grp->fsm) < MPCG_STATE_XID2INITW)) { 995 + dev_kfree_skb_any(skb); 996 + printk(KERN_INFO "ctcmpc: %s() DATA RCVD - MPC GROUP " 997 + "NOT ACTIVE - DROPPED\n", 998 + __FUNCTION__); 999 + priv->stats.tx_dropped++; 1000 + priv->stats.tx_errors++; 1001 + priv->stats.tx_carrier_errors++; 1002 + goto done; 1003 + } 1004 + 1005 + if (ctcm_test_and_set_busy(dev)) { 1006 + printk(KERN_WARNING "%s:DEVICE ERR - UNRECOVERABLE DATA LOSS\n", 1007 + __FUNCTION__); 1008 + dev_kfree_skb_any(skb); 1009 + priv->stats.tx_dropped++; 1010 + priv->stats.tx_errors++; 1011 + priv->stats.tx_carrier_errors++; 1012 + fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); 1013 + goto done; 1014 + } 1015 + 1016 + dev->trans_start = jiffies; 1017 + if (ctcmpc_transmit_skb(priv->channel[WRITE], skb) != 0) { 1018 + printk(KERN_WARNING "ctcmpc: %s() DEVICE ERROR" 1019 + ": Data Lost \n", 1020 + __FUNCTION__); 1021 + printk(KERN_WARNING "ctcmpc: %s() DEVICE ERROR" 1022 + " - UNRECOVERABLE DATA LOSS\n", 1023 + __FUNCTION__); 1024 + dev_kfree_skb_any(skb); 1025 + priv->stats.tx_dropped++; 1026 + priv->stats.tx_errors++; 1027 + priv->stats.tx_carrier_errors++; 1028 + ctcm_clear_busy(dev); 1029 + fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); 1030 + goto done; 1031 + } 1032 + ctcm_clear_busy(dev); 1033 + done: 1034 + if (do_debug) 1035 + MPC_DBF_DEV_NAME(TRACE, dev, "exit"); 1036 + 1037 + return 0; /* handle freeing of skb here */ 1038 + } 1039 + 1040 + 1041 + /** 1042 + * Sets MTU of an interface. 1043 + * 1044 + * dev Pointer to interface struct. 1045 + * new_mtu The new MTU to use for this interface. 1046 + * 1047 + * returns 0 on success, -EINVAL if MTU is out of valid range. 1048 + * (valid range is 576 .. 65527). If VM is on the 1049 + * remote side, maximum MTU is 32760, however this is 1050 + * not checked here. 1051 + */ 1052 + static int ctcm_change_mtu(struct net_device *dev, int new_mtu) 1053 + { 1054 + struct ctcm_priv *priv; 1055 + int max_bufsize; 1056 + 1057 + CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__); 1058 + 1059 + if (new_mtu < 576 || new_mtu > 65527) 1060 + return -EINVAL; 1061 + 1062 + priv = dev->priv; 1063 + max_bufsize = priv->channel[READ]->max_bufsize; 1064 + 1065 + if (IS_MPC(priv)) { 1066 + if (new_mtu > max_bufsize - TH_HEADER_LENGTH) 1067 + return -EINVAL; 1068 + dev->hard_header_len = TH_HEADER_LENGTH + PDU_HEADER_LENGTH; 1069 + } else { 1070 + if (new_mtu > max_bufsize - LL_HEADER_LENGTH - 2) 1071 + return -EINVAL; 1072 + dev->hard_header_len = LL_HEADER_LENGTH + 2; 1073 + } 1074 + dev->mtu = new_mtu; 1075 + return 0; 1076 + } 1077 + 1078 + /** 1079 + * Returns interface statistics of a device. 1080 + * 1081 + * dev Pointer to interface struct. 1082 + * 1083 + * returns Pointer to stats struct of this interface. 1084 + */ 1085 + static struct net_device_stats *ctcm_stats(struct net_device *dev) 1086 + { 1087 + return &((struct ctcm_priv *)dev->priv)->stats; 1088 + } 1089 + 1090 + 1091 + static void ctcm_netdev_unregister(struct net_device *dev) 1092 + { 1093 + CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__); 1094 + if (!dev) 1095 + return; 1096 + unregister_netdev(dev); 1097 + } 1098 + 1099 + static int ctcm_netdev_register(struct net_device *dev) 1100 + { 1101 + CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__); 1102 + return register_netdev(dev); 1103 + } 1104 + 1105 + static void ctcm_free_netdevice(struct net_device *dev) 1106 + { 1107 + struct ctcm_priv *priv; 1108 + struct mpc_group *grp; 1109 + 1110 + CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__); 1111 + 1112 + if (!dev) 1113 + return; 1114 + priv = dev->priv; 1115 + if (priv) { 1116 + grp = priv->mpcg; 1117 + if (grp) { 1118 + if (grp->fsm) 1119 + kfree_fsm(grp->fsm); 1120 + if (grp->xid_skb) 1121 + dev_kfree_skb(grp->xid_skb); 1122 + if (grp->rcvd_xid_skb) 1123 + dev_kfree_skb(grp->rcvd_xid_skb); 1124 + tasklet_kill(&grp->mpc_tasklet2); 1125 + kfree(grp); 1126 + priv->mpcg = NULL; 1127 + } 1128 + if (priv->fsm) { 1129 + kfree_fsm(priv->fsm); 1130 + priv->fsm = NULL; 1131 + } 1132 + kfree(priv->xid); 1133 + priv->xid = NULL; 1134 + /* 1135 + * Note: kfree(priv); is done in "opposite" function of 1136 + * allocator function probe_device which is remove_device. 1137 + */ 1138 + } 1139 + #ifdef MODULE 1140 + free_netdev(dev); 1141 + #endif 1142 + } 1143 + 1144 + struct mpc_group *ctcmpc_init_mpc_group(struct ctcm_priv *priv); 1145 + 1146 + void static ctcm_dev_setup(struct net_device *dev) 1147 + { 1148 + dev->open = ctcm_open; 1149 + dev->stop = ctcm_close; 1150 + dev->get_stats = ctcm_stats; 1151 + dev->change_mtu = ctcm_change_mtu; 1152 + dev->type = ARPHRD_SLIP; 1153 + dev->tx_queue_len = 100; 1154 + dev->flags = IFF_POINTOPOINT | IFF_NOARP; 1155 + } 1156 + 1157 + /* 1158 + * Initialize everything of the net device except the name and the 1159 + * channel structs. 1160 + */ 1161 + static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv) 1162 + { 1163 + struct net_device *dev; 1164 + struct mpc_group *grp; 1165 + if (!priv) 1166 + return NULL; 1167 + 1168 + if (IS_MPC(priv)) 1169 + dev = alloc_netdev(0, MPC_DEVICE_GENE, ctcm_dev_setup); 1170 + else 1171 + dev = alloc_netdev(0, CTC_DEVICE_GENE, ctcm_dev_setup); 1172 + 1173 + if (!dev) { 1174 + ctcm_pr_err("%s: Out of memory\n", __FUNCTION__); 1175 + return NULL; 1176 + } 1177 + dev->priv = priv; 1178 + priv->fsm = init_fsm("ctcmdev", dev_state_names, dev_event_names, 1179 + CTCM_NR_DEV_STATES, CTCM_NR_DEV_EVENTS, 1180 + dev_fsm, dev_fsm_len, GFP_KERNEL); 1181 + if (priv->fsm == NULL) { 1182 + CTCMY_DBF_DEV(SETUP, dev, "init_fsm error"); 1183 + kfree(dev); 1184 + return NULL; 1185 + } 1186 + fsm_newstate(priv->fsm, DEV_STATE_STOPPED); 1187 + fsm_settimer(priv->fsm, &priv->restart_timer); 1188 + 1189 + if (IS_MPC(priv)) { 1190 + /* MPC Group Initializations */ 1191 + grp = ctcmpc_init_mpc_group(priv); 1192 + if (grp == NULL) { 1193 + MPC_DBF_DEV(SETUP, dev, "init_mpc_group error"); 1194 + kfree(dev); 1195 + return NULL; 1196 + } 1197 + tasklet_init(&grp->mpc_tasklet2, 1198 + mpc_group_ready, (unsigned long)dev); 1199 + dev->mtu = MPC_BUFSIZE_DEFAULT - 1200 + TH_HEADER_LENGTH - PDU_HEADER_LENGTH; 1201 + 1202 + dev->hard_start_xmit = ctcmpc_tx; 1203 + dev->hard_header_len = TH_HEADER_LENGTH + PDU_HEADER_LENGTH; 1204 + priv->buffer_size = MPC_BUFSIZE_DEFAULT; 1205 + } else { 1206 + dev->mtu = CTCM_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2; 1207 + dev->hard_start_xmit = ctcm_tx; 1208 + dev->hard_header_len = LL_HEADER_LENGTH + 2; 1209 + } 1210 + 1211 + CTCMY_DBF_DEV(SETUP, dev, "finished"); 1212 + return dev; 1213 + } 1214 + 1215 + /** 1216 + * Main IRQ handler. 1217 + * 1218 + * cdev The ccw_device the interrupt is for. 1219 + * intparm interruption parameter. 1220 + * irb interruption response block. 1221 + */ 1222 + static void ctcm_irq_handler(struct ccw_device *cdev, 1223 + unsigned long intparm, struct irb *irb) 1224 + { 1225 + struct channel *ch; 1226 + struct net_device *dev; 1227 + struct ctcm_priv *priv; 1228 + struct ccwgroup_device *cgdev; 1229 + 1230 + CTCM_DBF_TEXT(TRACE, CTC_DBF_DEBUG, __FUNCTION__); 1231 + if (ctcm_check_irb_error(cdev, irb)) 1232 + return; 1233 + 1234 + cgdev = dev_get_drvdata(&cdev->dev); 1235 + 1236 + /* Check for unsolicited interrupts. */ 1237 + if (cgdev == NULL) { 1238 + ctcm_pr_warn("ctcm: Got unsolicited irq: %s c-%02x d-%02x\n", 1239 + cdev->dev.bus_id, irb->scsw.cstat, 1240 + irb->scsw.dstat); 1241 + return; 1242 + } 1243 + 1244 + priv = dev_get_drvdata(&cgdev->dev); 1245 + 1246 + /* Try to extract channel from driver data. */ 1247 + if (priv->channel[READ]->cdev == cdev) 1248 + ch = priv->channel[READ]; 1249 + else if (priv->channel[WRITE]->cdev == cdev) 1250 + ch = priv->channel[WRITE]; 1251 + else { 1252 + ctcm_pr_err("ctcm: Can't determine channel for interrupt, " 1253 + "device %s\n", cdev->dev.bus_id); 1254 + return; 1255 + } 1256 + 1257 + dev = (struct net_device *)(ch->netdev); 1258 + if (dev == NULL) { 1259 + ctcm_pr_crit("ctcm: %s dev=NULL bus_id=%s, ch=0x%p\n", 1260 + __FUNCTION__, cdev->dev.bus_id, ch); 1261 + return; 1262 + } 1263 + 1264 + if (do_debug) 1265 + ctcm_pr_debug("%s: interrupt for device: %s " 1266 + "received c-%02x d-%02x\n", 1267 + dev->name, 1268 + ch->id, 1269 + irb->scsw.cstat, 1270 + irb->scsw.dstat); 1271 + 1272 + /* Copy interruption response block. */ 1273 + memcpy(ch->irb, irb, sizeof(struct irb)); 1274 + 1275 + /* Check for good subchannel return code, otherwise error message */ 1276 + if (irb->scsw.cstat) { 1277 + fsm_event(ch->fsm, CTC_EVENT_SC_UNKNOWN, ch); 1278 + ctcm_pr_warn("%s: subchannel check for dev: %s - %02x %02x\n", 1279 + dev->name, ch->id, irb->scsw.cstat, 1280 + irb->scsw.dstat); 1281 + return; 1282 + } 1283 + 1284 + /* Check the reason-code of a unit check */ 1285 + if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) { 1286 + ccw_unit_check(ch, irb->ecw[0]); 1287 + return; 1288 + } 1289 + if (irb->scsw.dstat & DEV_STAT_BUSY) { 1290 + if (irb->scsw.dstat & DEV_STAT_ATTENTION) 1291 + fsm_event(ch->fsm, CTC_EVENT_ATTNBUSY, ch); 1292 + else 1293 + fsm_event(ch->fsm, CTC_EVENT_BUSY, ch); 1294 + return; 1295 + } 1296 + if (irb->scsw.dstat & DEV_STAT_ATTENTION) { 1297 + fsm_event(ch->fsm, CTC_EVENT_ATTN, ch); 1298 + return; 1299 + } 1300 + if ((irb->scsw.stctl & SCSW_STCTL_SEC_STATUS) || 1301 + (irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) || 1302 + (irb->scsw.stctl == 1303 + (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND))) 1304 + fsm_event(ch->fsm, CTC_EVENT_FINSTAT, ch); 1305 + else 1306 + fsm_event(ch->fsm, CTC_EVENT_IRQ, ch); 1307 + 1308 + } 1309 + 1310 + /** 1311 + * Add ctcm specific attributes. 1312 + * Add ctcm private data. 1313 + * 1314 + * cgdev pointer to ccwgroup_device just added 1315 + * 1316 + * returns 0 on success, !0 on failure. 1317 + */ 1318 + static int ctcm_probe_device(struct ccwgroup_device *cgdev) 1319 + { 1320 + struct ctcm_priv *priv; 1321 + int rc; 1322 + 1323 + CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, "%s %p", __FUNCTION__, cgdev); 1324 + 1325 + if (!get_device(&cgdev->dev)) 1326 + return -ENODEV; 1327 + 1328 + priv = kzalloc(sizeof(struct ctcm_priv), GFP_KERNEL); 1329 + if (!priv) { 1330 + ctcm_pr_err("%s: Out of memory\n", __FUNCTION__); 1331 + put_device(&cgdev->dev); 1332 + return -ENOMEM; 1333 + } 1334 + 1335 + rc = ctcm_add_files(&cgdev->dev); 1336 + if (rc) { 1337 + kfree(priv); 1338 + put_device(&cgdev->dev); 1339 + return rc; 1340 + } 1341 + priv->buffer_size = CTCM_BUFSIZE_DEFAULT; 1342 + cgdev->cdev[0]->handler = ctcm_irq_handler; 1343 + cgdev->cdev[1]->handler = ctcm_irq_handler; 1344 + dev_set_drvdata(&cgdev->dev, priv); 1345 + 1346 + return 0; 1347 + } 1348 + 1349 + /** 1350 + * Add a new channel to the list of channels. 1351 + * Keeps the channel list sorted. 1352 + * 1353 + * cdev The ccw_device to be added. 1354 + * type The type class of the new channel. 1355 + * priv Points to the private data of the ccwgroup_device. 1356 + * 1357 + * returns 0 on success, !0 on error. 1358 + */ 1359 + static int add_channel(struct ccw_device *cdev, enum channel_types type, 1360 + struct ctcm_priv *priv) 1361 + { 1362 + struct channel **c = &channels; 1363 + struct channel *ch; 1364 + int ccw_num; 1365 + int rc = 0; 1366 + 1367 + CTCM_DBF_TEXT(TRACE, 2, __FUNCTION__); 1368 + ch = kzalloc(sizeof(struct channel), GFP_KERNEL); 1369 + if (ch == NULL) 1370 + goto nomem_return; 1371 + 1372 + ch->protocol = priv->protocol; 1373 + if (IS_MPC(priv)) { 1374 + ch->discontact_th = (struct th_header *) 1375 + kzalloc(TH_HEADER_LENGTH, gfp_type()); 1376 + if (ch->discontact_th == NULL) 1377 + goto nomem_return; 1378 + 1379 + ch->discontact_th->th_blk_flag = TH_DISCONTACT; 1380 + tasklet_init(&ch->ch_disc_tasklet, 1381 + mpc_action_send_discontact, (unsigned long)ch); 1382 + 1383 + tasklet_init(&ch->ch_tasklet, ctcmpc_bh, (unsigned long)ch); 1384 + ch->max_bufsize = (MPC_BUFSIZE_DEFAULT - 35); 1385 + ccw_num = 17; 1386 + } else 1387 + ccw_num = 8; 1388 + 1389 + ch->ccw = (struct ccw1 *) 1390 + kzalloc(ccw_num * sizeof(struct ccw1), GFP_KERNEL | GFP_DMA); 1391 + if (ch->ccw == NULL) 1392 + goto nomem_return; 1393 + 1394 + ch->cdev = cdev; 1395 + snprintf(ch->id, CTCM_ID_SIZE, "ch-%s", cdev->dev.bus_id); 1396 + ch->type = type; 1397 + 1398 + /** 1399 + * "static" ccws are used in the following way: 1400 + * 1401 + * ccw[0..2] (Channel program for generic I/O): 1402 + * 0: prepare 1403 + * 1: read or write (depending on direction) with fixed 1404 + * buffer (idal allocated once when buffer is allocated) 1405 + * 2: nop 1406 + * ccw[3..5] (Channel program for direct write of packets) 1407 + * 3: prepare 1408 + * 4: write (idal allocated on every write). 1409 + * 5: nop 1410 + * ccw[6..7] (Channel program for initial channel setup): 1411 + * 6: set extended mode 1412 + * 7: nop 1413 + * 1414 + * ch->ccw[0..5] are initialized in ch_action_start because 1415 + * the channel's direction is yet unknown here. 1416 + * 1417 + * ccws used for xid2 negotiations 1418 + * ch-ccw[8-14] need to be used for the XID exchange either 1419 + * X side XID2 Processing 1420 + * 8: write control 1421 + * 9: write th 1422 + * 10: write XID 1423 + * 11: read th from secondary 1424 + * 12: read XID from secondary 1425 + * 13: read 4 byte ID 1426 + * 14: nop 1427 + * Y side XID Processing 1428 + * 8: sense 1429 + * 9: read th 1430 + * 10: read XID 1431 + * 11: write th 1432 + * 12: write XID 1433 + * 13: write 4 byte ID 1434 + * 14: nop 1435 + * 1436 + * ccws used for double noop due to VM timing issues 1437 + * which result in unrecoverable Busy on channel 1438 + * 15: nop 1439 + * 16: nop 1440 + */ 1441 + ch->ccw[6].cmd_code = CCW_CMD_SET_EXTENDED; 1442 + ch->ccw[6].flags = CCW_FLAG_SLI; 1443 + 1444 + ch->ccw[7].cmd_code = CCW_CMD_NOOP; 1445 + ch->ccw[7].flags = CCW_FLAG_SLI; 1446 + 1447 + if (IS_MPC(priv)) { 1448 + ch->ccw[15].cmd_code = CCW_CMD_WRITE; 1449 + ch->ccw[15].flags = CCW_FLAG_SLI | CCW_FLAG_CC; 1450 + ch->ccw[15].count = TH_HEADER_LENGTH; 1451 + ch->ccw[15].cda = virt_to_phys(ch->discontact_th); 1452 + 1453 + ch->ccw[16].cmd_code = CCW_CMD_NOOP; 1454 + ch->ccw[16].flags = CCW_FLAG_SLI; 1455 + 1456 + ch->fsm = init_fsm(ch->id, ctc_ch_state_names, 1457 + ctc_ch_event_names, CTC_MPC_NR_STATES, 1458 + CTC_MPC_NR_EVENTS, ctcmpc_ch_fsm, 1459 + mpc_ch_fsm_len, GFP_KERNEL); 1460 + } else { 1461 + ch->fsm = init_fsm(ch->id, ctc_ch_state_names, 1462 + ctc_ch_event_names, CTC_NR_STATES, 1463 + CTC_NR_EVENTS, ch_fsm, 1464 + ch_fsm_len, GFP_KERNEL); 1465 + } 1466 + if (ch->fsm == NULL) 1467 + goto free_return; 1468 + 1469 + fsm_newstate(ch->fsm, CTC_STATE_IDLE); 1470 + 1471 + ch->irb = kzalloc(sizeof(struct irb), GFP_KERNEL); 1472 + if (ch->irb == NULL) 1473 + goto nomem_return; 1474 + 1475 + while (*c && ctcm_less_than((*c)->id, ch->id)) 1476 + c = &(*c)->next; 1477 + 1478 + if (*c && (!strncmp((*c)->id, ch->id, CTCM_ID_SIZE))) { 1479 + CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, 1480 + "%s (%s) already in list, using old entry", 1481 + __FUNCTION__, (*c)->id); 1482 + 1483 + goto free_return; 1484 + } 1485 + 1486 + spin_lock_init(&ch->collect_lock); 1487 + 1488 + fsm_settimer(ch->fsm, &ch->timer); 1489 + skb_queue_head_init(&ch->io_queue); 1490 + skb_queue_head_init(&ch->collect_queue); 1491 + 1492 + if (IS_MPC(priv)) { 1493 + fsm_settimer(ch->fsm, &ch->sweep_timer); 1494 + skb_queue_head_init(&ch->sweep_queue); 1495 + } 1496 + ch->next = *c; 1497 + *c = ch; 1498 + return 0; 1499 + 1500 + nomem_return: 1501 + ctcm_pr_warn("ctcm: Out of memory in %s\n", __FUNCTION__); 1502 + rc = -ENOMEM; 1503 + 1504 + free_return: /* note that all channel pointers are 0 or valid */ 1505 + kfree(ch->ccw); /* TODO: check that again */ 1506 + kfree(ch->discontact_th); 1507 + kfree_fsm(ch->fsm); 1508 + kfree(ch->irb); 1509 + kfree(ch); 1510 + return rc; 1511 + } 1512 + 1513 + /* 1514 + * Return type of a detected device. 1515 + */ 1516 + static enum channel_types get_channel_type(struct ccw_device_id *id) 1517 + { 1518 + enum channel_types type; 1519 + type = (enum channel_types)id->driver_info; 1520 + 1521 + if (type == channel_type_ficon) 1522 + type = channel_type_escon; 1523 + 1524 + return type; 1525 + } 1526 + 1527 + /** 1528 + * 1529 + * Setup an interface. 1530 + * 1531 + * cgdev Device to be setup. 1532 + * 1533 + * returns 0 on success, !0 on failure. 1534 + */ 1535 + static int ctcm_new_device(struct ccwgroup_device *cgdev) 1536 + { 1537 + char read_id[CTCM_ID_SIZE]; 1538 + char write_id[CTCM_ID_SIZE]; 1539 + int direction; 1540 + enum channel_types type; 1541 + struct ctcm_priv *priv; 1542 + struct net_device *dev; 1543 + int ret; 1544 + 1545 + CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__); 1546 + 1547 + priv = dev_get_drvdata(&cgdev->dev); 1548 + if (!priv) 1549 + return -ENODEV; 1550 + 1551 + type = get_channel_type(&cgdev->cdev[0]->id); 1552 + 1553 + snprintf(read_id, CTCM_ID_SIZE, "ch-%s", cgdev->cdev[0]->dev.bus_id); 1554 + snprintf(write_id, CTCM_ID_SIZE, "ch-%s", cgdev->cdev[1]->dev.bus_id); 1555 + 1556 + ret = add_channel(cgdev->cdev[0], type, priv); 1557 + if (ret) 1558 + return ret; 1559 + ret = add_channel(cgdev->cdev[1], type, priv); 1560 + if (ret) 1561 + return ret; 1562 + 1563 + ret = ccw_device_set_online(cgdev->cdev[0]); 1564 + if (ret != 0) { 1565 + CTCM_DBF_TEXT(SETUP, CTC_DBF_WARN, 1566 + "ccw_device_set_online (cdev[0]) failed "); 1567 + ctcm_pr_warn("ccw_device_set_online (cdev[0]) failed " 1568 + "with ret = %d\n", ret); 1569 + } 1570 + 1571 + ret = ccw_device_set_online(cgdev->cdev[1]); 1572 + if (ret != 0) { 1573 + CTCM_DBF_TEXT(SETUP, CTC_DBF_WARN, 1574 + "ccw_device_set_online (cdev[1]) failed "); 1575 + ctcm_pr_warn("ccw_device_set_online (cdev[1]) failed " 1576 + "with ret = %d\n", ret); 1577 + } 1578 + 1579 + dev = ctcm_init_netdevice(priv); 1580 + 1581 + if (dev == NULL) { 1582 + ctcm_pr_warn("ctcm_init_netdevice failed\n"); 1583 + goto out; 1584 + } 1585 + 1586 + for (direction = READ; direction <= WRITE; direction++) { 1587 + priv->channel[direction] = 1588 + channel_get(type, direction == READ ? read_id : write_id, 1589 + direction); 1590 + if (priv->channel[direction] == NULL) { 1591 + if (direction == WRITE) 1592 + channel_free(priv->channel[READ]); 1593 + ctcm_free_netdevice(dev); 1594 + goto out; 1595 + } 1596 + priv->channel[direction]->netdev = dev; 1597 + priv->channel[direction]->protocol = priv->protocol; 1598 + priv->channel[direction]->max_bufsize = priv->buffer_size; 1599 + } 1600 + /* sysfs magic */ 1601 + SET_NETDEV_DEV(dev, &cgdev->dev); 1602 + 1603 + if (ctcm_netdev_register(dev) != 0) { 1604 + ctcm_free_netdevice(dev); 1605 + goto out; 1606 + } 1607 + 1608 + if (ctcm_add_attributes(&cgdev->dev)) { 1609 + ctcm_netdev_unregister(dev); 1610 + /* dev->priv = NULL; why that ???? */ 1611 + ctcm_free_netdevice(dev); 1612 + goto out; 1613 + } 1614 + 1615 + strlcpy(priv->fsm->name, dev->name, sizeof(priv->fsm->name)); 1616 + 1617 + CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, 1618 + "setup(%s) ok : r/w = %s / %s, proto : %d", 1619 + dev->name, priv->channel[READ]->id, 1620 + priv->channel[WRITE]->id, priv->protocol); 1621 + 1622 + return 0; 1623 + out: 1624 + ccw_device_set_offline(cgdev->cdev[1]); 1625 + ccw_device_set_offline(cgdev->cdev[0]); 1626 + 1627 + return -ENODEV; 1628 + } 1629 + 1630 + /** 1631 + * Shutdown an interface. 1632 + * 1633 + * cgdev Device to be shut down. 1634 + * 1635 + * returns 0 on success, !0 on failure. 1636 + */ 1637 + static int ctcm_shutdown_device(struct ccwgroup_device *cgdev) 1638 + { 1639 + struct ctcm_priv *priv; 1640 + struct net_device *dev; 1641 + 1642 + priv = dev_get_drvdata(&cgdev->dev); 1643 + if (!priv) 1644 + return -ENODEV; 1645 + 1646 + if (priv->channel[READ]) { 1647 + dev = priv->channel[READ]->netdev; 1648 + CTCM_DBF_DEV(SETUP, dev, ""); 1649 + /* Close the device */ 1650 + ctcm_close(dev); 1651 + dev->flags &= ~IFF_RUNNING; 1652 + ctcm_remove_attributes(&cgdev->dev); 1653 + channel_free(priv->channel[READ]); 1654 + } else 1655 + dev = NULL; 1656 + 1657 + if (priv->channel[WRITE]) 1658 + channel_free(priv->channel[WRITE]); 1659 + 1660 + if (dev) { 1661 + ctcm_netdev_unregister(dev); 1662 + /* dev->priv = NULL; why that ??? */ 1663 + ctcm_free_netdevice(dev); 1664 + } 1665 + 1666 + if (priv->fsm) 1667 + kfree_fsm(priv->fsm); 1668 + 1669 + ccw_device_set_offline(cgdev->cdev[1]); 1670 + ccw_device_set_offline(cgdev->cdev[0]); 1671 + 1672 + if (priv->channel[READ]) 1673 + channel_remove(priv->channel[READ]); 1674 + if (priv->channel[WRITE]) 1675 + channel_remove(priv->channel[WRITE]); 1676 + priv->channel[READ] = priv->channel[WRITE] = NULL; 1677 + 1678 + return 0; 1679 + 1680 + } 1681 + 1682 + 1683 + static void ctcm_remove_device(struct ccwgroup_device *cgdev) 1684 + { 1685 + struct ctcm_priv *priv; 1686 + 1687 + CTCM_DBF_TEXT(SETUP, CTC_DBF_ERROR, __FUNCTION__); 1688 + 1689 + priv = dev_get_drvdata(&cgdev->dev); 1690 + if (!priv) 1691 + return; 1692 + if (cgdev->state == CCWGROUP_ONLINE) 1693 + ctcm_shutdown_device(cgdev); 1694 + ctcm_remove_files(&cgdev->dev); 1695 + dev_set_drvdata(&cgdev->dev, NULL); 1696 + kfree(priv); 1697 + put_device(&cgdev->dev); 1698 + } 1699 + 1700 + static struct ccwgroup_driver ctcm_group_driver = { 1701 + .owner = THIS_MODULE, 1702 + .name = CTC_DRIVER_NAME, 1703 + .max_slaves = 2, 1704 + .driver_id = 0xC3E3C3D4, /* CTCM */ 1705 + .probe = ctcm_probe_device, 1706 + .remove = ctcm_remove_device, 1707 + .set_online = ctcm_new_device, 1708 + .set_offline = ctcm_shutdown_device, 1709 + }; 1710 + 1711 + 1712 + /* 1713 + * Module related routines 1714 + */ 1715 + 1716 + /* 1717 + * Prepare to be unloaded. Free IRQ's and release all resources. 1718 + * This is called just before this module is unloaded. It is 1719 + * not called, if the usage count is !0, so we don't need to check 1720 + * for that. 1721 + */ 1722 + static void __exit ctcm_exit(void) 1723 + { 1724 + unregister_cu3088_discipline(&ctcm_group_driver); 1725 + ctcm_unregister_dbf_views(); 1726 + ctcm_pr_info("CTCM driver unloaded\n"); 1727 + } 1728 + 1729 + /* 1730 + * Print Banner. 1731 + */ 1732 + static void print_banner(void) 1733 + { 1734 + printk(KERN_INFO "CTCM driver initialized\n"); 1735 + } 1736 + 1737 + /** 1738 + * Initialize module. 1739 + * This is called just after the module is loaded. 1740 + * 1741 + * returns 0 on success, !0 on error. 1742 + */ 1743 + static int __init ctcm_init(void) 1744 + { 1745 + int ret; 1746 + 1747 + channels = NULL; 1748 + 1749 + ret = ctcm_register_dbf_views(); 1750 + if (ret) { 1751 + ctcm_pr_crit("ctcm_init failed with ctcm_register_dbf_views " 1752 + "rc = %d\n", ret); 1753 + return ret; 1754 + } 1755 + ret = register_cu3088_discipline(&ctcm_group_driver); 1756 + if (ret) { 1757 + ctcm_unregister_dbf_views(); 1758 + ctcm_pr_crit("ctcm_init failed with register_cu3088_discipline " 1759 + "(rc = %d)\n", ret); 1760 + return ret; 1761 + } 1762 + print_banner(); 1763 + return ret; 1764 + } 1765 + 1766 + module_init(ctcm_init); 1767 + module_exit(ctcm_exit); 1768 + 1769 + MODULE_AUTHOR("Peter Tiedemann <ptiedem@de.ibm.com>"); 1770 + MODULE_DESCRIPTION("Network driver for S/390 CTC + CTCMPC (SNA)"); 1771 + MODULE_LICENSE("GPL"); 1772 +
+287
drivers/s390/net/ctcm_main.h
··· 1 + /* 2 + * drivers/s390/net/ctcm_main.h 3 + * 4 + * Copyright IBM Corp. 2001, 2007 5 + * Authors: Fritz Elfert (felfert@millenux.com) 6 + * Peter Tiedemann (ptiedem@de.ibm.com) 7 + */ 8 + 9 + #ifndef _CTCM_MAIN_H_ 10 + #define _CTCM_MAIN_H_ 11 + 12 + #include <asm/ccwdev.h> 13 + #include <asm/ccwgroup.h> 14 + 15 + #include <linux/skbuff.h> 16 + #include <linux/netdevice.h> 17 + 18 + #include "fsm.h" 19 + #include "cu3088.h" 20 + #include "ctcm_dbug.h" 21 + #include "ctcm_mpc.h" 22 + 23 + #define CTC_DRIVER_NAME "ctcm" 24 + #define CTC_DEVICE_NAME "ctc" 25 + #define CTC_DEVICE_GENE "ctc%d" 26 + #define MPC_DEVICE_NAME "mpc" 27 + #define MPC_DEVICE_GENE "mpc%d" 28 + 29 + #define CHANNEL_FLAGS_READ 0 30 + #define CHANNEL_FLAGS_WRITE 1 31 + #define CHANNEL_FLAGS_INUSE 2 32 + #define CHANNEL_FLAGS_BUFSIZE_CHANGED 4 33 + #define CHANNEL_FLAGS_FAILED 8 34 + #define CHANNEL_FLAGS_WAITIRQ 16 35 + #define CHANNEL_FLAGS_RWMASK 1 36 + #define CHANNEL_DIRECTION(f) (f & CHANNEL_FLAGS_RWMASK) 37 + 38 + #define LOG_FLAG_ILLEGALPKT 1 39 + #define LOG_FLAG_ILLEGALSIZE 2 40 + #define LOG_FLAG_OVERRUN 4 41 + #define LOG_FLAG_NOMEM 8 42 + 43 + #define ctcm_pr_debug(fmt, arg...) printk(KERN_DEBUG fmt, ##arg) 44 + #define ctcm_pr_info(fmt, arg...) printk(KERN_INFO fmt, ##arg) 45 + #define ctcm_pr_notice(fmt, arg...) printk(KERN_NOTICE fmt, ##arg) 46 + #define ctcm_pr_warn(fmt, arg...) printk(KERN_WARNING fmt, ##arg) 47 + #define ctcm_pr_emerg(fmt, arg...) printk(KERN_EMERG fmt, ##arg) 48 + #define ctcm_pr_err(fmt, arg...) printk(KERN_ERR fmt, ##arg) 49 + #define ctcm_pr_crit(fmt, arg...) printk(KERN_CRIT fmt, ##arg) 50 + 51 + /* 52 + * CCW commands, used in this driver. 53 + */ 54 + #define CCW_CMD_WRITE 0x01 55 + #define CCW_CMD_READ 0x02 56 + #define CCW_CMD_NOOP 0x03 57 + #define CCW_CMD_TIC 0x08 58 + #define CCW_CMD_SENSE_CMD 0x14 59 + #define CCW_CMD_WRITE_CTL 0x17 60 + #define CCW_CMD_SET_EXTENDED 0xc3 61 + #define CCW_CMD_PREPARE 0xe3 62 + 63 + #define CTCM_PROTO_S390 0 64 + #define CTCM_PROTO_LINUX 1 65 + #define CTCM_PROTO_LINUX_TTY 2 66 + #define CTCM_PROTO_OS390 3 67 + #define CTCM_PROTO_MPC 4 68 + #define CTCM_PROTO_MAX 4 69 + 70 + #define CTCM_BUFSIZE_LIMIT 65535 71 + #define CTCM_BUFSIZE_DEFAULT 32768 72 + #define MPC_BUFSIZE_DEFAULT CTCM_BUFSIZE_LIMIT 73 + 74 + #define CTCM_TIME_1_SEC 1000 75 + #define CTCM_TIME_5_SEC 5000 76 + #define CTCM_TIME_10_SEC 10000 77 + 78 + #define CTCM_INITIAL_BLOCKLEN 2 79 + 80 + #define READ 0 81 + #define WRITE 1 82 + 83 + #define CTCM_ID_SIZE BUS_ID_SIZE+3 84 + 85 + struct ctcm_profile { 86 + unsigned long maxmulti; 87 + unsigned long maxcqueue; 88 + unsigned long doios_single; 89 + unsigned long doios_multi; 90 + unsigned long txlen; 91 + unsigned long tx_time; 92 + struct timespec send_stamp; 93 + }; 94 + 95 + /* 96 + * Definition of one channel 97 + */ 98 + struct channel { 99 + struct channel *next; 100 + char id[CTCM_ID_SIZE]; 101 + struct ccw_device *cdev; 102 + /* 103 + * Type of this channel. 104 + * CTC/A or Escon for valid channels. 105 + */ 106 + enum channel_types type; 107 + /* 108 + * Misc. flags. See CHANNEL_FLAGS_... below 109 + */ 110 + __u32 flags; 111 + __u16 protocol; /* protocol of this channel (4 = MPC) */ 112 + /* 113 + * I/O and irq related stuff 114 + */ 115 + struct ccw1 *ccw; 116 + struct irb *irb; 117 + /* 118 + * RX/TX buffer size 119 + */ 120 + int max_bufsize; 121 + struct sk_buff *trans_skb; /* transmit/receive buffer */ 122 + struct sk_buff_head io_queue; /* universal I/O queue */ 123 + struct tasklet_struct ch_tasklet; /* MPC ONLY */ 124 + /* 125 + * TX queue for collecting skb's during busy. 126 + */ 127 + struct sk_buff_head collect_queue; 128 + /* 129 + * Amount of data in collect_queue. 130 + */ 131 + int collect_len; 132 + /* 133 + * spinlock for collect_queue and collect_len 134 + */ 135 + spinlock_t collect_lock; 136 + /* 137 + * Timer for detecting unresposive 138 + * I/O operations. 139 + */ 140 + fsm_timer timer; 141 + /* MPC ONLY section begin */ 142 + __u32 th_seq_num; /* SNA TH seq number */ 143 + __u8 th_seg; 144 + __u32 pdu_seq; 145 + struct sk_buff *xid_skb; 146 + char *xid_skb_data; 147 + struct th_header *xid_th; 148 + struct xid2 *xid; 149 + char *xid_id; 150 + struct th_header *rcvd_xid_th; 151 + struct xid2 *rcvd_xid; 152 + char *rcvd_xid_id; 153 + __u8 in_mpcgroup; 154 + fsm_timer sweep_timer; 155 + struct sk_buff_head sweep_queue; 156 + struct th_header *discontact_th; 157 + struct tasklet_struct ch_disc_tasklet; 158 + /* MPC ONLY section end */ 159 + 160 + int retry; /* retry counter for misc. operations */ 161 + fsm_instance *fsm; /* finite state machine of this channel */ 162 + struct net_device *netdev; /* corresponding net_device */ 163 + struct ctcm_profile prof; 164 + unsigned char *trans_skb_data; 165 + __u16 logflags; 166 + }; 167 + 168 + struct ctcm_priv { 169 + struct net_device_stats stats; 170 + unsigned long tbusy; 171 + 172 + /* The MPC group struct of this interface */ 173 + struct mpc_group *mpcg; /* MPC only */ 174 + struct xid2 *xid; /* MPC only */ 175 + 176 + /* The finite state machine of this interface */ 177 + fsm_instance *fsm; 178 + 179 + /* The protocol of this device */ 180 + __u16 protocol; 181 + 182 + /* Timer for restarting after I/O Errors */ 183 + fsm_timer restart_timer; 184 + 185 + int buffer_size; /* ctc only */ 186 + 187 + struct channel *channel[2]; 188 + }; 189 + 190 + int ctcm_open(struct net_device *dev); 191 + int ctcm_close(struct net_device *dev); 192 + 193 + /* 194 + * prototypes for non-static sysfs functions 195 + */ 196 + int ctcm_add_attributes(struct device *dev); 197 + void ctcm_remove_attributes(struct device *dev); 198 + int ctcm_add_files(struct device *dev); 199 + void ctcm_remove_files(struct device *dev); 200 + 201 + /* 202 + * Compatibility macros for busy handling 203 + * of network devices. 204 + */ 205 + static inline void ctcm_clear_busy_do(struct net_device *dev) 206 + { 207 + clear_bit(0, &(((struct ctcm_priv *)dev->priv)->tbusy)); 208 + netif_wake_queue(dev); 209 + } 210 + 211 + static inline void ctcm_clear_busy(struct net_device *dev) 212 + { 213 + struct mpc_group *grp; 214 + grp = ((struct ctcm_priv *)dev->priv)->mpcg; 215 + 216 + if (!(grp && grp->in_sweep)) 217 + ctcm_clear_busy_do(dev); 218 + } 219 + 220 + 221 + static inline int ctcm_test_and_set_busy(struct net_device *dev) 222 + { 223 + netif_stop_queue(dev); 224 + return test_and_set_bit(0, &(((struct ctcm_priv *)dev->priv)->tbusy)); 225 + } 226 + 227 + extern int loglevel; 228 + extern struct channel *channels; 229 + 230 + void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb); 231 + 232 + /* 233 + * Functions related to setup and device detection. 234 + */ 235 + 236 + static inline int ctcm_less_than(char *id1, char *id2) 237 + { 238 + unsigned long dev1, dev2; 239 + 240 + id1 = id1 + 5; 241 + id2 = id2 + 5; 242 + 243 + dev1 = simple_strtoul(id1, &id1, 16); 244 + dev2 = simple_strtoul(id2, &id2, 16); 245 + 246 + return (dev1 < dev2); 247 + } 248 + 249 + int ctcm_ch_alloc_buffer(struct channel *ch); 250 + 251 + static inline int ctcm_checkalloc_buffer(struct channel *ch) 252 + { 253 + if (ch->trans_skb == NULL) 254 + return ctcm_ch_alloc_buffer(ch); 255 + if (ch->flags & CHANNEL_FLAGS_BUFSIZE_CHANGED) { 256 + dev_kfree_skb(ch->trans_skb); 257 + return ctcm_ch_alloc_buffer(ch); 258 + } 259 + return 0; 260 + } 261 + 262 + struct mpc_group *ctcmpc_init_mpc_group(struct ctcm_priv *priv); 263 + 264 + /* test if protocol attribute (of struct ctcm_priv or struct channel) 265 + * has MPC protocol setting. Type is not checked 266 + */ 267 + #define IS_MPC(p) ((p)->protocol == CTCM_PROTO_MPC) 268 + 269 + /* test if struct ctcm_priv of struct net_device has MPC protocol setting */ 270 + #define IS_MPCDEV(d) IS_MPC((struct ctcm_priv *)d->priv) 271 + 272 + static inline gfp_t gfp_type(void) 273 + { 274 + return in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; 275 + } 276 + 277 + /* 278 + * Definition of our link level header. 279 + */ 280 + struct ll_header { 281 + __u16 length; 282 + __u16 type; 283 + __u16 unused; 284 + }; 285 + #define LL_HEADER_LENGTH (sizeof(struct ll_header)) 286 + 287 + #endif
+2472
drivers/s390/net/ctcm_mpc.c
··· 1 + /* 2 + * drivers/s390/net/ctcm_mpc.c 3 + * 4 + * Copyright IBM Corp. 2004, 2007 5 + * Authors: Belinda Thompson (belindat@us.ibm.com) 6 + * Andy Richter (richtera@us.ibm.com) 7 + * Peter Tiedemann (ptiedem@de.ibm.com) 8 + */ 9 + 10 + /* 11 + This module exports functions to be used by CCS: 12 + EXPORT_SYMBOL(ctc_mpc_alloc_channel); 13 + EXPORT_SYMBOL(ctc_mpc_establish_connectivity); 14 + EXPORT_SYMBOL(ctc_mpc_dealloc_ch); 15 + EXPORT_SYMBOL(ctc_mpc_flow_control); 16 + */ 17 + 18 + #undef DEBUG 19 + #undef DEBUGDATA 20 + #undef DEBUGCCW 21 + 22 + #include <linux/version.h> 23 + #include <linux/module.h> 24 + #include <linux/init.h> 25 + #include <linux/kernel.h> 26 + #include <linux/slab.h> 27 + #include <linux/errno.h> 28 + #include <linux/types.h> 29 + #include <linux/interrupt.h> 30 + #include <linux/timer.h> 31 + #include <linux/sched.h> 32 + 33 + #include <linux/signal.h> 34 + #include <linux/string.h> 35 + #include <linux/proc_fs.h> 36 + 37 + #include <linux/ip.h> 38 + #include <linux/if_arp.h> 39 + #include <linux/tcp.h> 40 + #include <linux/skbuff.h> 41 + #include <linux/ctype.h> 42 + #include <linux/netdevice.h> 43 + #include <net/dst.h> 44 + 45 + #include <linux/io.h> /* instead of <asm/io.h> ok ? */ 46 + #include <asm/ccwdev.h> 47 + #include <asm/ccwgroup.h> 48 + #include <linux/bitops.h> /* instead of <asm/bitops.h> ok ? */ 49 + #include <linux/uaccess.h> /* instead of <asm/uaccess.h> ok ? */ 50 + #include <linux/wait.h> 51 + #include <linux/moduleparam.h> 52 + #include <asm/idals.h> 53 + 54 + #include "cu3088.h" 55 + #include "ctcm_mpc.h" 56 + #include "ctcm_main.h" 57 + #include "ctcm_fsms.h" 58 + 59 + static const struct xid2 init_xid = { 60 + .xid2_type_id = XID_FM2, 61 + .xid2_len = 0x45, 62 + .xid2_adj_id = 0, 63 + .xid2_rlen = 0x31, 64 + .xid2_resv1 = 0, 65 + .xid2_flag1 = 0, 66 + .xid2_fmtt = 0, 67 + .xid2_flag4 = 0x80, 68 + .xid2_resv2 = 0, 69 + .xid2_tgnum = 0, 70 + .xid2_sender_id = 0, 71 + .xid2_flag2 = 0, 72 + .xid2_option = XID2_0, 73 + .xid2_resv3 = "\x00", 74 + .xid2_resv4 = 0, 75 + .xid2_dlc_type = XID2_READ_SIDE, 76 + .xid2_resv5 = 0, 77 + .xid2_mpc_flag = 0, 78 + .xid2_resv6 = 0, 79 + .xid2_buf_len = (MPC_BUFSIZE_DEFAULT - 35), 80 + }; 81 + 82 + static const struct th_header thnorm = { 83 + .th_seg = 0x00, 84 + .th_ch_flag = TH_IS_XID, 85 + .th_blk_flag = TH_DATA_IS_XID, 86 + .th_is_xid = 0x01, 87 + .th_seq_num = 0x00000000, 88 + }; 89 + 90 + static const struct th_header thdummy = { 91 + .th_seg = 0x00, 92 + .th_ch_flag = 0x00, 93 + .th_blk_flag = TH_DATA_IS_XID, 94 + .th_is_xid = 0x01, 95 + .th_seq_num = 0x00000000, 96 + }; 97 + 98 + /* 99 + * Definition of one MPC group 100 + */ 101 + 102 + /* 103 + * Compatibility macros for busy handling 104 + * of network devices. 105 + */ 106 + 107 + static void ctcmpc_unpack_skb(struct channel *ch, struct sk_buff *pskb); 108 + 109 + /* 110 + * MPC Group state machine actions (static prototypes) 111 + */ 112 + static void mpc_action_nop(fsm_instance *fsm, int event, void *arg); 113 + static void mpc_action_go_ready(fsm_instance *fsm, int event, void *arg); 114 + static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg); 115 + static void mpc_action_timeout(fsm_instance *fi, int event, void *arg); 116 + static int mpc_validate_xid(struct mpcg_info *mpcginfo); 117 + static void mpc_action_yside_xid(fsm_instance *fsm, int event, void *arg); 118 + static void mpc_action_doxid0(fsm_instance *fsm, int event, void *arg); 119 + static void mpc_action_doxid7(fsm_instance *fsm, int event, void *arg); 120 + static void mpc_action_xside_xid(fsm_instance *fsm, int event, void *arg); 121 + static void mpc_action_rcvd_xid0(fsm_instance *fsm, int event, void *arg); 122 + static void mpc_action_rcvd_xid7(fsm_instance *fsm, int event, void *arg); 123 + 124 + #ifdef DEBUGDATA 125 + /*-------------------------------------------------------------------* 126 + * Dump buffer format * 127 + * * 128 + *--------------------------------------------------------------------*/ 129 + void ctcmpc_dumpit(char *buf, int len) 130 + { 131 + __u32 ct, sw, rm, dup; 132 + char *ptr, *rptr; 133 + char tbuf[82], tdup[82]; 134 + #if (UTS_MACHINE == s390x) 135 + char addr[22]; 136 + #else 137 + char addr[12]; 138 + #endif 139 + char boff[12]; 140 + char bhex[82], duphex[82]; 141 + char basc[40]; 142 + 143 + sw = 0; 144 + rptr = ptr = buf; 145 + rm = 16; 146 + duphex[0] = 0x00; 147 + dup = 0; 148 + 149 + for (ct = 0; ct < len; ct++, ptr++, rptr++) { 150 + if (sw == 0) { 151 + #if (UTS_MACHINE == s390x) 152 + sprintf(addr, "%16.16lx", (unsigned long)rptr); 153 + #else 154 + sprintf(addr, "%8.8X", (__u32)rptr); 155 + #endif 156 + 157 + sprintf(boff, "%4.4X", (__u32)ct); 158 + bhex[0] = '\0'; 159 + basc[0] = '\0'; 160 + } 161 + if ((sw == 4) || (sw == 12)) 162 + strcat(bhex, " "); 163 + if (sw == 8) 164 + strcat(bhex, " "); 165 + 166 + #if (UTS_MACHINE == s390x) 167 + sprintf(tbuf, "%2.2lX", (unsigned long)*ptr); 168 + #else 169 + sprintf(tbuf, "%2.2X", (__u32)*ptr); 170 + #endif 171 + 172 + tbuf[2] = '\0'; 173 + strcat(bhex, tbuf); 174 + if ((0 != isprint(*ptr)) && (*ptr >= 0x20)) 175 + basc[sw] = *ptr; 176 + else 177 + basc[sw] = '.'; 178 + 179 + basc[sw+1] = '\0'; 180 + sw++; 181 + rm--; 182 + if (sw == 16) { 183 + if ((strcmp(duphex, bhex)) != 0) { 184 + if (dup != 0) { 185 + sprintf(tdup, "Duplicate as above " 186 + "to %s", addr); 187 + printk(KERN_INFO " " 188 + " --- %s ---\n", tdup); 189 + } 190 + printk(KERN_INFO " %s (+%s) : %s [%s]\n", 191 + addr, boff, bhex, basc); 192 + dup = 0; 193 + strcpy(duphex, bhex); 194 + } else 195 + dup++; 196 + 197 + sw = 0; 198 + rm = 16; 199 + } 200 + } /* endfor */ 201 + 202 + if (sw != 0) { 203 + for ( ; rm > 0; rm--, sw++) { 204 + if ((sw == 4) || (sw == 12)) 205 + strcat(bhex, " "); 206 + if (sw == 8) 207 + strcat(bhex, " "); 208 + strcat(bhex, " "); 209 + strcat(basc, " "); 210 + } 211 + if (dup != 0) { 212 + sprintf(tdup, "Duplicate as above to %s", addr); 213 + printk(KERN_INFO " " 214 + " --- %s ---\n", tdup); 215 + } 216 + printk(KERN_INFO " %s (+%s) : %s [%s]\n", 217 + addr, boff, bhex, basc); 218 + } else { 219 + if (dup >= 1) { 220 + sprintf(tdup, "Duplicate as above to %s", addr); 221 + printk(KERN_INFO " " 222 + " --- %s ---\n", tdup); 223 + } 224 + if (dup != 0) { 225 + printk(KERN_INFO " %s (+%s) : %s [%s]\n", 226 + addr, boff, bhex, basc); 227 + } 228 + } 229 + 230 + return; 231 + 232 + } /* end of ctcmpc_dumpit */ 233 + #endif 234 + 235 + #ifdef DEBUGDATA 236 + /* 237 + * Dump header and first 16 bytes of an sk_buff for debugging purposes. 238 + * 239 + * skb The sk_buff to dump. 240 + * offset Offset relative to skb-data, where to start the dump. 241 + */ 242 + void ctcmpc_dump_skb(struct sk_buff *skb, int offset) 243 + { 244 + unsigned char *p = skb->data; 245 + struct th_header *header; 246 + struct pdu *pheader; 247 + int bl = skb->len; 248 + int i; 249 + 250 + if (p == NULL) 251 + return; 252 + 253 + p += offset; 254 + header = (struct th_header *)p; 255 + 256 + printk(KERN_INFO "dump:\n"); 257 + printk(KERN_INFO "skb len=%d \n", skb->len); 258 + if (skb->len > 2) { 259 + switch (header->th_ch_flag) { 260 + case TH_HAS_PDU: 261 + break; 262 + case 0x00: 263 + case TH_IS_XID: 264 + if ((header->th_blk_flag == TH_DATA_IS_XID) && 265 + (header->th_is_xid == 0x01)) 266 + goto dumpth; 267 + case TH_SWEEP_REQ: 268 + goto dumpth; 269 + case TH_SWEEP_RESP: 270 + goto dumpth; 271 + default: 272 + break; 273 + } 274 + 275 + pheader = (struct pdu *)p; 276 + printk(KERN_INFO "pdu->offset: %d hex: %04x\n", 277 + pheader->pdu_offset, pheader->pdu_offset); 278 + printk(KERN_INFO "pdu->flag : %02x\n", pheader->pdu_flag); 279 + printk(KERN_INFO "pdu->proto : %02x\n", pheader->pdu_proto); 280 + printk(KERN_INFO "pdu->seq : %02x\n", pheader->pdu_seq); 281 + goto dumpdata; 282 + 283 + dumpth: 284 + printk(KERN_INFO "th->seg : %02x\n", header->th_seg); 285 + printk(KERN_INFO "th->ch : %02x\n", header->th_ch_flag); 286 + printk(KERN_INFO "th->blk_flag: %02x\n", header->th_blk_flag); 287 + printk(KERN_INFO "th->type : %s\n", 288 + (header->th_is_xid) ? "DATA" : "XID"); 289 + printk(KERN_INFO "th->seqnum : %04x\n", header->th_seq_num); 290 + 291 + } 292 + dumpdata: 293 + if (bl > 32) 294 + bl = 32; 295 + printk(KERN_INFO "data: "); 296 + for (i = 0; i < bl; i++) 297 + printk(KERN_INFO "%02x%s", *p++, (i % 16) ? " " : "\n<7>"); 298 + printk(KERN_INFO "\n"); 299 + } 300 + #endif 301 + 302 + /* 303 + * ctc_mpc_alloc_channel 304 + * (exported interface) 305 + * 306 + * Device Initialization : 307 + * ACTPATH driven IO operations 308 + */ 309 + int ctc_mpc_alloc_channel(int port_num, void (*callback)(int, int)) 310 + { 311 + char device[20]; 312 + struct net_device *dev; 313 + struct mpc_group *grp; 314 + struct ctcm_priv *priv; 315 + 316 + ctcm_pr_debug("ctcmpc enter: %s()\n", __FUNCTION__); 317 + 318 + sprintf(device, "%s%i", MPC_DEVICE_NAME, port_num); 319 + dev = __dev_get_by_name(&init_net, device); 320 + 321 + if (dev == NULL) { 322 + printk(KERN_INFO "ctc_mpc_alloc_channel %s dev=NULL\n", device); 323 + return 1; 324 + } 325 + 326 + priv = dev->priv; 327 + grp = priv->mpcg; 328 + if (!grp) 329 + return 1; 330 + 331 + grp->allochanfunc = callback; 332 + grp->port_num = port_num; 333 + grp->port_persist = 1; 334 + 335 + ctcm_pr_debug("ctcmpc: %s called for device %s state=%s\n", 336 + __FUNCTION__, 337 + dev->name, 338 + fsm_getstate_str(grp->fsm)); 339 + 340 + switch (fsm_getstate(grp->fsm)) { 341 + case MPCG_STATE_INOP: 342 + /* Group is in the process of terminating */ 343 + grp->alloc_called = 1; 344 + break; 345 + case MPCG_STATE_RESET: 346 + /* MPC Group will transition to state */ 347 + /* MPCG_STATE_XID2INITW iff the minimum number */ 348 + /* of 1 read and 1 write channel have successfully*/ 349 + /* activated */ 350 + /*fsm_newstate(grp->fsm, MPCG_STATE_XID2INITW);*/ 351 + if (callback) 352 + grp->send_qllc_disc = 1; 353 + case MPCG_STATE_XID0IOWAIT: 354 + fsm_deltimer(&grp->timer); 355 + grp->outstanding_xid2 = 0; 356 + grp->outstanding_xid7 = 0; 357 + grp->outstanding_xid7_p2 = 0; 358 + grp->saved_xid2 = NULL; 359 + if (callback) 360 + ctcm_open(dev); 361 + fsm_event(priv->fsm, DEV_EVENT_START, dev); 362 + break; 363 + case MPCG_STATE_READY: 364 + /* XID exchanges completed after PORT was activated */ 365 + /* Link station already active */ 366 + /* Maybe timing issue...retry callback */ 367 + grp->allocchan_callback_retries++; 368 + if (grp->allocchan_callback_retries < 4) { 369 + if (grp->allochanfunc) 370 + grp->allochanfunc(grp->port_num, 371 + grp->group_max_buflen); 372 + } else { 373 + /* there are problems...bail out */ 374 + /* there may be a state mismatch so restart */ 375 + grp->port_persist = 1; 376 + fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); 377 + grp->allocchan_callback_retries = 0; 378 + } 379 + break; 380 + default: 381 + return 0; 382 + 383 + } 384 + 385 + ctcm_pr_debug("ctcmpc exit: %s()\n", __FUNCTION__); 386 + return 0; 387 + } 388 + EXPORT_SYMBOL(ctc_mpc_alloc_channel); 389 + 390 + /* 391 + * ctc_mpc_establish_connectivity 392 + * (exported interface) 393 + */ 394 + void ctc_mpc_establish_connectivity(int port_num, 395 + void (*callback)(int, int, int)) 396 + { 397 + char device[20]; 398 + struct net_device *dev; 399 + struct mpc_group *grp; 400 + struct ctcm_priv *priv; 401 + struct channel *rch, *wch; 402 + 403 + ctcm_pr_debug("ctcmpc enter: %s()\n", __FUNCTION__); 404 + 405 + sprintf(device, "%s%i", MPC_DEVICE_NAME, port_num); 406 + dev = __dev_get_by_name(&init_net, device); 407 + 408 + if (dev == NULL) { 409 + printk(KERN_INFO "ctc_mpc_establish_connectivity " 410 + "%s dev=NULL\n", device); 411 + return; 412 + } 413 + priv = dev->priv; 414 + rch = priv->channel[READ]; 415 + wch = priv->channel[WRITE]; 416 + 417 + grp = priv->mpcg; 418 + 419 + ctcm_pr_debug("ctcmpc: %s() called for device %s state=%s\n", 420 + __FUNCTION__, dev->name, 421 + fsm_getstate_str(grp->fsm)); 422 + 423 + grp->estconnfunc = callback; 424 + grp->port_num = port_num; 425 + 426 + switch (fsm_getstate(grp->fsm)) { 427 + case MPCG_STATE_READY: 428 + /* XID exchanges completed after PORT was activated */ 429 + /* Link station already active */ 430 + /* Maybe timing issue...retry callback */ 431 + fsm_deltimer(&grp->timer); 432 + grp->estconn_callback_retries++; 433 + if (grp->estconn_callback_retries < 4) { 434 + if (grp->estconnfunc) { 435 + grp->estconnfunc(grp->port_num, 0, 436 + grp->group_max_buflen); 437 + grp->estconnfunc = NULL; 438 + } 439 + } else { 440 + /* there are problems...bail out */ 441 + fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); 442 + grp->estconn_callback_retries = 0; 443 + } 444 + break; 445 + case MPCG_STATE_INOP: 446 + case MPCG_STATE_RESET: 447 + /* MPC Group is not ready to start XID - min num of */ 448 + /* 1 read and 1 write channel have not been acquired*/ 449 + printk(KERN_WARNING "ctcmpc: %s() REJECTED ACTIVE XID Req" 450 + "uest - Channel Pair is not Active\n", __FUNCTION__); 451 + if (grp->estconnfunc) { 452 + grp->estconnfunc(grp->port_num, -1, 0); 453 + grp->estconnfunc = NULL; 454 + } 455 + break; 456 + case MPCG_STATE_XID2INITW: 457 + /* alloc channel was called but no XID exchange */ 458 + /* has occurred. initiate xside XID exchange */ 459 + /* make sure yside XID0 processing has not started */ 460 + if ((fsm_getstate(rch->fsm) > CH_XID0_PENDING) || 461 + (fsm_getstate(wch->fsm) > CH_XID0_PENDING)) { 462 + printk(KERN_WARNING "mpc: %s() ABORT ACTIVE XID" 463 + " Request- PASSIVE XID in process\n" 464 + , __FUNCTION__); 465 + break; 466 + } 467 + grp->send_qllc_disc = 1; 468 + fsm_newstate(grp->fsm, MPCG_STATE_XID0IOWAIT); 469 + fsm_deltimer(&grp->timer); 470 + fsm_addtimer(&grp->timer, MPC_XID_TIMEOUT_VALUE, 471 + MPCG_EVENT_TIMER, dev); 472 + grp->outstanding_xid7 = 0; 473 + grp->outstanding_xid7_p2 = 0; 474 + grp->saved_xid2 = NULL; 475 + if ((rch->in_mpcgroup) && 476 + (fsm_getstate(rch->fsm) == CH_XID0_PENDING)) 477 + fsm_event(grp->fsm, MPCG_EVENT_XID0DO, rch); 478 + else { 479 + printk(KERN_WARNING "mpc: %s() Unable to start" 480 + " ACTIVE XID0 on read channel\n", 481 + __FUNCTION__); 482 + if (grp->estconnfunc) { 483 + grp->estconnfunc(grp->port_num, -1, 0); 484 + grp->estconnfunc = NULL; 485 + } 486 + fsm_deltimer(&grp->timer); 487 + goto done; 488 + } 489 + if ((wch->in_mpcgroup) && 490 + (fsm_getstate(wch->fsm) == CH_XID0_PENDING)) 491 + fsm_event(grp->fsm, MPCG_EVENT_XID0DO, wch); 492 + else { 493 + printk(KERN_WARNING "mpc: %s() Unable to start" 494 + " ACTIVE XID0 on write channel\n", 495 + __FUNCTION__); 496 + if (grp->estconnfunc) { 497 + grp->estconnfunc(grp->port_num, -1, 0); 498 + grp->estconnfunc = NULL; 499 + } 500 + fsm_deltimer(&grp->timer); 501 + goto done; 502 + } 503 + break; 504 + case MPCG_STATE_XID0IOWAIT: 505 + /* already in active XID negotiations */ 506 + default: 507 + break; 508 + } 509 + 510 + done: 511 + ctcm_pr_debug("ctcmpc exit: %s()\n", __FUNCTION__); 512 + return; 513 + } 514 + EXPORT_SYMBOL(ctc_mpc_establish_connectivity); 515 + 516 + /* 517 + * ctc_mpc_dealloc_ch 518 + * (exported interface) 519 + */ 520 + void ctc_mpc_dealloc_ch(int port_num) 521 + { 522 + struct net_device *dev; 523 + char device[20]; 524 + struct ctcm_priv *priv; 525 + struct mpc_group *grp; 526 + 527 + ctcm_pr_debug("ctcmpc enter: %s()\n", __FUNCTION__); 528 + sprintf(device, "%s%i", MPC_DEVICE_NAME, port_num); 529 + dev = __dev_get_by_name(&init_net, device); 530 + 531 + if (dev == NULL) { 532 + printk(KERN_INFO "%s() %s dev=NULL\n", __FUNCTION__, device); 533 + goto done; 534 + } 535 + 536 + ctcm_pr_debug("ctcmpc:%s %s() called for device %s refcount=%d\n", 537 + dev->name, __FUNCTION__, 538 + dev->name, atomic_read(&dev->refcnt)); 539 + 540 + priv = dev->priv; 541 + if (priv == NULL) { 542 + printk(KERN_INFO "%s() %s priv=NULL\n", 543 + __FUNCTION__, device); 544 + goto done; 545 + } 546 + fsm_deltimer(&priv->restart_timer); 547 + 548 + grp = priv->mpcg; 549 + if (grp == NULL) { 550 + printk(KERN_INFO "%s() %s dev=NULL\n", __FUNCTION__, device); 551 + goto done; 552 + } 553 + grp->channels_terminating = 0; 554 + 555 + fsm_deltimer(&grp->timer); 556 + 557 + grp->allochanfunc = NULL; 558 + grp->estconnfunc = NULL; 559 + grp->port_persist = 0; 560 + grp->send_qllc_disc = 0; 561 + fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); 562 + 563 + ctcm_close(dev); 564 + done: 565 + ctcm_pr_debug("ctcmpc exit: %s()\n", __FUNCTION__); 566 + return; 567 + } 568 + EXPORT_SYMBOL(ctc_mpc_dealloc_ch); 569 + 570 + /* 571 + * ctc_mpc_flow_control 572 + * (exported interface) 573 + */ 574 + void ctc_mpc_flow_control(int port_num, int flowc) 575 + { 576 + char device[20]; 577 + struct ctcm_priv *priv; 578 + struct mpc_group *grp; 579 + struct net_device *dev; 580 + struct channel *rch; 581 + int mpcg_state; 582 + 583 + ctcm_pr_debug("ctcmpc enter: %s() %i\n", __FUNCTION__, flowc); 584 + 585 + sprintf(device, "%s%i", MPC_DEVICE_NAME, port_num); 586 + dev = __dev_get_by_name(&init_net, device); 587 + 588 + if (dev == NULL) { 589 + printk(KERN_INFO "ctc_mpc_flow_control %s dev=NULL\n", device); 590 + return; 591 + } 592 + 593 + ctcm_pr_debug("ctcmpc: %s %s called \n", dev->name, __FUNCTION__); 594 + 595 + priv = dev->priv; 596 + if (priv == NULL) { 597 + printk(KERN_INFO "ctcmpc:%s() %s priv=NULL\n", 598 + __FUNCTION__, device); 599 + return; 600 + } 601 + grp = priv->mpcg; 602 + rch = priv->channel[READ]; 603 + 604 + mpcg_state = fsm_getstate(grp->fsm); 605 + switch (flowc) { 606 + case 1: 607 + if (mpcg_state == MPCG_STATE_FLOWC) 608 + break; 609 + if (mpcg_state == MPCG_STATE_READY) { 610 + if (grp->flow_off_called == 1) 611 + grp->flow_off_called = 0; 612 + else 613 + fsm_newstate(grp->fsm, MPCG_STATE_FLOWC); 614 + break; 615 + } 616 + break; 617 + case 0: 618 + if (mpcg_state == MPCG_STATE_FLOWC) { 619 + fsm_newstate(grp->fsm, MPCG_STATE_READY); 620 + /* ensure any data that has accumulated */ 621 + /* on the io_queue will now be sen t */ 622 + tasklet_schedule(&rch->ch_tasklet); 623 + } 624 + /* possible race condition */ 625 + if (mpcg_state == MPCG_STATE_READY) { 626 + grp->flow_off_called = 1; 627 + break; 628 + } 629 + break; 630 + } 631 + 632 + ctcm_pr_debug("ctcmpc exit: %s() %i\n", __FUNCTION__, flowc); 633 + } 634 + EXPORT_SYMBOL(ctc_mpc_flow_control); 635 + 636 + static int mpc_send_qllc_discontact(struct net_device *); 637 + 638 + /* 639 + * helper function of ctcmpc_unpack_skb 640 + */ 641 + static void mpc_rcvd_sweep_resp(struct mpcg_info *mpcginfo) 642 + { 643 + struct channel *rch = mpcginfo->ch; 644 + struct net_device *dev = rch->netdev; 645 + struct ctcm_priv *priv = dev->priv; 646 + struct mpc_group *grp = priv->mpcg; 647 + struct channel *ch = priv->channel[WRITE]; 648 + 649 + if (do_debug) 650 + ctcm_pr_debug("ctcmpc enter: %s(): ch=0x%p id=%s\n", 651 + __FUNCTION__, ch, ch->id); 652 + 653 + if (do_debug_data) 654 + ctcmpc_dumpit((char *)mpcginfo->sweep, TH_SWEEP_LENGTH); 655 + 656 + grp->sweep_rsp_pend_num--; 657 + 658 + if ((grp->sweep_req_pend_num == 0) && 659 + (grp->sweep_rsp_pend_num == 0)) { 660 + fsm_deltimer(&ch->sweep_timer); 661 + grp->in_sweep = 0; 662 + rch->th_seq_num = 0x00; 663 + ch->th_seq_num = 0x00; 664 + ctcm_clear_busy_do(dev); 665 + } 666 + 667 + kfree(mpcginfo); 668 + 669 + return; 670 + 671 + } 672 + 673 + /* 674 + * helper function of mpc_rcvd_sweep_req 675 + * which is a helper of ctcmpc_unpack_skb 676 + */ 677 + static void ctcmpc_send_sweep_resp(struct channel *rch) 678 + { 679 + struct net_device *dev = rch->netdev; 680 + struct ctcm_priv *priv = dev->priv; 681 + struct mpc_group *grp = priv->mpcg; 682 + int rc = 0; 683 + struct th_sweep *header; 684 + struct sk_buff *sweep_skb; 685 + struct channel *ch = priv->channel[WRITE]; 686 + 687 + if (do_debug) 688 + ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n", 689 + __FUNCTION__, rch, rch->id); 690 + 691 + sweep_skb = __dev_alloc_skb(MPC_BUFSIZE_DEFAULT, 692 + GFP_ATOMIC|GFP_DMA); 693 + if (sweep_skb == NULL) { 694 + printk(KERN_INFO "Couldn't alloc sweep_skb\n"); 695 + rc = -ENOMEM; 696 + goto done; 697 + } 698 + 699 + header = (struct th_sweep *) 700 + kmalloc(sizeof(struct th_sweep), gfp_type()); 701 + 702 + if (!header) { 703 + dev_kfree_skb_any(sweep_skb); 704 + rc = -ENOMEM; 705 + goto done; 706 + } 707 + 708 + header->th.th_seg = 0x00 ; 709 + header->th.th_ch_flag = TH_SWEEP_RESP; 710 + header->th.th_blk_flag = 0x00; 711 + header->th.th_is_xid = 0x00; 712 + header->th.th_seq_num = 0x00; 713 + header->sw.th_last_seq = ch->th_seq_num; 714 + 715 + memcpy(skb_put(sweep_skb, TH_SWEEP_LENGTH), header, TH_SWEEP_LENGTH); 716 + 717 + kfree(header); 718 + 719 + dev->trans_start = jiffies; 720 + skb_queue_tail(&ch->sweep_queue, sweep_skb); 721 + 722 + fsm_addtimer(&ch->sweep_timer, 100, CTC_EVENT_RSWEEP_TIMER, ch); 723 + 724 + return; 725 + 726 + done: 727 + if (rc != 0) { 728 + grp->in_sweep = 0; 729 + ctcm_clear_busy_do(dev); 730 + fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); 731 + } 732 + 733 + return; 734 + } 735 + 736 + /* 737 + * helper function of ctcmpc_unpack_skb 738 + */ 739 + static void mpc_rcvd_sweep_req(struct mpcg_info *mpcginfo) 740 + { 741 + struct channel *rch = mpcginfo->ch; 742 + struct net_device *dev = rch->netdev; 743 + struct ctcm_priv *priv = dev->priv; 744 + struct mpc_group *grp = priv->mpcg; 745 + struct channel *ch = priv->channel[WRITE]; 746 + 747 + if (do_debug) 748 + CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_DEBUG, 749 + " %s(): ch=0x%p id=%s\n", __FUNCTION__, ch, ch->id); 750 + 751 + if (grp->in_sweep == 0) { 752 + grp->in_sweep = 1; 753 + ctcm_test_and_set_busy(dev); 754 + grp->sweep_req_pend_num = grp->active_channels[READ]; 755 + grp->sweep_rsp_pend_num = grp->active_channels[READ]; 756 + } 757 + 758 + if (do_debug_data) 759 + ctcmpc_dumpit((char *)mpcginfo->sweep, TH_SWEEP_LENGTH); 760 + 761 + grp->sweep_req_pend_num--; 762 + ctcmpc_send_sweep_resp(ch); 763 + kfree(mpcginfo); 764 + return; 765 + } 766 + 767 + /* 768 + * MPC Group Station FSM definitions 769 + */ 770 + static const char *mpcg_event_names[] = { 771 + [MPCG_EVENT_INOP] = "INOP Condition", 772 + [MPCG_EVENT_DISCONC] = "Discontact Received", 773 + [MPCG_EVENT_XID0DO] = "Channel Active - Start XID", 774 + [MPCG_EVENT_XID2] = "XID2 Received", 775 + [MPCG_EVENT_XID2DONE] = "XID0 Complete", 776 + [MPCG_EVENT_XID7DONE] = "XID7 Complete", 777 + [MPCG_EVENT_TIMER] = "XID Setup Timer", 778 + [MPCG_EVENT_DOIO] = "XID DoIO", 779 + }; 780 + 781 + static const char *mpcg_state_names[] = { 782 + [MPCG_STATE_RESET] = "Reset", 783 + [MPCG_STATE_INOP] = "INOP", 784 + [MPCG_STATE_XID2INITW] = "Passive XID- XID0 Pending Start", 785 + [MPCG_STATE_XID2INITX] = "Passive XID- XID0 Pending Complete", 786 + [MPCG_STATE_XID7INITW] = "Passive XID- XID7 Pending P1 Start", 787 + [MPCG_STATE_XID7INITX] = "Passive XID- XID7 Pending P2 Complete", 788 + [MPCG_STATE_XID0IOWAIT] = "Active XID- XID0 Pending Start", 789 + [MPCG_STATE_XID0IOWAIX] = "Active XID- XID0 Pending Complete", 790 + [MPCG_STATE_XID7INITI] = "Active XID- XID7 Pending Start", 791 + [MPCG_STATE_XID7INITZ] = "Active XID- XID7 Pending Complete ", 792 + [MPCG_STATE_XID7INITF] = "XID - XID7 Complete ", 793 + [MPCG_STATE_FLOWC] = "FLOW CONTROL ON", 794 + [MPCG_STATE_READY] = "READY", 795 + }; 796 + 797 + /* 798 + * The MPC Group Station FSM 799 + * 22 events 800 + */ 801 + static const fsm_node mpcg_fsm[] = { 802 + { MPCG_STATE_RESET, MPCG_EVENT_INOP, mpc_action_go_inop }, 803 + { MPCG_STATE_INOP, MPCG_EVENT_INOP, mpc_action_nop }, 804 + { MPCG_STATE_FLOWC, MPCG_EVENT_INOP, mpc_action_go_inop }, 805 + 806 + { MPCG_STATE_READY, MPCG_EVENT_DISCONC, mpc_action_discontact }, 807 + { MPCG_STATE_READY, MPCG_EVENT_INOP, mpc_action_go_inop }, 808 + 809 + { MPCG_STATE_XID2INITW, MPCG_EVENT_XID0DO, mpc_action_doxid0 }, 810 + { MPCG_STATE_XID2INITW, MPCG_EVENT_XID2, mpc_action_rcvd_xid0 }, 811 + { MPCG_STATE_XID2INITW, MPCG_EVENT_INOP, mpc_action_go_inop }, 812 + { MPCG_STATE_XID2INITW, MPCG_EVENT_TIMER, mpc_action_timeout }, 813 + { MPCG_STATE_XID2INITW, MPCG_EVENT_DOIO, mpc_action_yside_xid }, 814 + 815 + { MPCG_STATE_XID2INITX, MPCG_EVENT_XID0DO, mpc_action_doxid0 }, 816 + { MPCG_STATE_XID2INITX, MPCG_EVENT_XID2, mpc_action_rcvd_xid0 }, 817 + { MPCG_STATE_XID2INITX, MPCG_EVENT_INOP, mpc_action_go_inop }, 818 + { MPCG_STATE_XID2INITX, MPCG_EVENT_TIMER, mpc_action_timeout }, 819 + { MPCG_STATE_XID2INITX, MPCG_EVENT_DOIO, mpc_action_yside_xid }, 820 + 821 + { MPCG_STATE_XID7INITW, MPCG_EVENT_XID2DONE, mpc_action_doxid7 }, 822 + { MPCG_STATE_XID7INITW, MPCG_EVENT_DISCONC, mpc_action_discontact }, 823 + { MPCG_STATE_XID7INITW, MPCG_EVENT_XID2, mpc_action_rcvd_xid7 }, 824 + { MPCG_STATE_XID7INITW, MPCG_EVENT_INOP, mpc_action_go_inop }, 825 + { MPCG_STATE_XID7INITW, MPCG_EVENT_TIMER, mpc_action_timeout }, 826 + { MPCG_STATE_XID7INITW, MPCG_EVENT_XID7DONE, mpc_action_doxid7 }, 827 + { MPCG_STATE_XID7INITW, MPCG_EVENT_DOIO, mpc_action_yside_xid }, 828 + 829 + { MPCG_STATE_XID7INITX, MPCG_EVENT_DISCONC, mpc_action_discontact }, 830 + { MPCG_STATE_XID7INITX, MPCG_EVENT_XID2, mpc_action_rcvd_xid7 }, 831 + { MPCG_STATE_XID7INITX, MPCG_EVENT_INOP, mpc_action_go_inop }, 832 + { MPCG_STATE_XID7INITX, MPCG_EVENT_XID7DONE, mpc_action_doxid7 }, 833 + { MPCG_STATE_XID7INITX, MPCG_EVENT_TIMER, mpc_action_timeout }, 834 + { MPCG_STATE_XID7INITX, MPCG_EVENT_DOIO, mpc_action_yside_xid }, 835 + 836 + { MPCG_STATE_XID0IOWAIT, MPCG_EVENT_XID0DO, mpc_action_doxid0 }, 837 + { MPCG_STATE_XID0IOWAIT, MPCG_EVENT_DISCONC, mpc_action_discontact }, 838 + { MPCG_STATE_XID0IOWAIT, MPCG_EVENT_XID2, mpc_action_rcvd_xid0 }, 839 + { MPCG_STATE_XID0IOWAIT, MPCG_EVENT_INOP, mpc_action_go_inop }, 840 + { MPCG_STATE_XID0IOWAIT, MPCG_EVENT_TIMER, mpc_action_timeout }, 841 + { MPCG_STATE_XID0IOWAIT, MPCG_EVENT_DOIO, mpc_action_xside_xid }, 842 + 843 + { MPCG_STATE_XID0IOWAIX, MPCG_EVENT_XID0DO, mpc_action_doxid0 }, 844 + { MPCG_STATE_XID0IOWAIX, MPCG_EVENT_DISCONC, mpc_action_discontact }, 845 + { MPCG_STATE_XID0IOWAIX, MPCG_EVENT_XID2, mpc_action_rcvd_xid0 }, 846 + { MPCG_STATE_XID0IOWAIX, MPCG_EVENT_INOP, mpc_action_go_inop }, 847 + { MPCG_STATE_XID0IOWAIX, MPCG_EVENT_TIMER, mpc_action_timeout }, 848 + { MPCG_STATE_XID0IOWAIX, MPCG_EVENT_DOIO, mpc_action_xside_xid }, 849 + 850 + { MPCG_STATE_XID7INITI, MPCG_EVENT_XID2DONE, mpc_action_doxid7 }, 851 + { MPCG_STATE_XID7INITI, MPCG_EVENT_XID2, mpc_action_rcvd_xid7 }, 852 + { MPCG_STATE_XID7INITI, MPCG_EVENT_DISCONC, mpc_action_discontact }, 853 + { MPCG_STATE_XID7INITI, MPCG_EVENT_INOP, mpc_action_go_inop }, 854 + { MPCG_STATE_XID7INITI, MPCG_EVENT_TIMER, mpc_action_timeout }, 855 + { MPCG_STATE_XID7INITI, MPCG_EVENT_XID7DONE, mpc_action_doxid7 }, 856 + { MPCG_STATE_XID7INITI, MPCG_EVENT_DOIO, mpc_action_xside_xid }, 857 + 858 + { MPCG_STATE_XID7INITZ, MPCG_EVENT_XID2, mpc_action_rcvd_xid7 }, 859 + { MPCG_STATE_XID7INITZ, MPCG_EVENT_XID7DONE, mpc_action_doxid7 }, 860 + { MPCG_STATE_XID7INITZ, MPCG_EVENT_DISCONC, mpc_action_discontact }, 861 + { MPCG_STATE_XID7INITZ, MPCG_EVENT_INOP, mpc_action_go_inop }, 862 + { MPCG_STATE_XID7INITZ, MPCG_EVENT_TIMER, mpc_action_timeout }, 863 + { MPCG_STATE_XID7INITZ, MPCG_EVENT_DOIO, mpc_action_xside_xid }, 864 + 865 + { MPCG_STATE_XID7INITF, MPCG_EVENT_INOP, mpc_action_go_inop }, 866 + { MPCG_STATE_XID7INITF, MPCG_EVENT_XID7DONE, mpc_action_go_ready }, 867 + }; 868 + 869 + static int mpcg_fsm_len = ARRAY_SIZE(mpcg_fsm); 870 + 871 + /* 872 + * MPC Group Station FSM action 873 + * CTCM_PROTO_MPC only 874 + */ 875 + static void mpc_action_go_ready(fsm_instance *fsm, int event, void *arg) 876 + { 877 + struct net_device *dev = arg; 878 + struct ctcm_priv *priv = NULL; 879 + struct mpc_group *grp = NULL; 880 + 881 + if (dev == NULL) { 882 + printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__); 883 + return; 884 + } 885 + 886 + ctcm_pr_debug("ctcmpc enter: %s %s()\n", dev->name, __FUNCTION__); 887 + 888 + priv = dev->priv; 889 + if (priv == NULL) { 890 + printk(KERN_INFO "%s() priv=NULL\n", __FUNCTION__); 891 + return; 892 + } 893 + 894 + grp = priv->mpcg; 895 + if (grp == NULL) { 896 + printk(KERN_INFO "%s() grp=NULL\n", __FUNCTION__); 897 + return; 898 + } 899 + 900 + fsm_deltimer(&grp->timer); 901 + 902 + if (grp->saved_xid2->xid2_flag2 == 0x40) { 903 + priv->xid->xid2_flag2 = 0x00; 904 + if (grp->estconnfunc) { 905 + grp->estconnfunc(grp->port_num, 1, 906 + grp->group_max_buflen); 907 + grp->estconnfunc = NULL; 908 + } else if (grp->allochanfunc) 909 + grp->send_qllc_disc = 1; 910 + goto done; 911 + } 912 + 913 + grp->port_persist = 1; 914 + grp->out_of_sequence = 0; 915 + grp->estconn_called = 0; 916 + 917 + tasklet_hi_schedule(&grp->mpc_tasklet2); 918 + 919 + ctcm_pr_debug("ctcmpc exit: %s %s()\n", dev->name, __FUNCTION__); 920 + return; 921 + 922 + done: 923 + fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); 924 + 925 + 926 + ctcm_pr_info("ctcmpc: %s()failure occurred\n", __FUNCTION__); 927 + } 928 + 929 + /* 930 + * helper of ctcm_init_netdevice 931 + * CTCM_PROTO_MPC only 932 + */ 933 + void mpc_group_ready(unsigned long adev) 934 + { 935 + struct net_device *dev = (struct net_device *)adev; 936 + struct ctcm_priv *priv = NULL; 937 + struct mpc_group *grp = NULL; 938 + struct channel *ch = NULL; 939 + 940 + 941 + ctcm_pr_debug("ctcmpc enter: %s()\n", __FUNCTION__); 942 + 943 + if (dev == NULL) { 944 + printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__); 945 + return; 946 + } 947 + 948 + priv = dev->priv; 949 + if (priv == NULL) { 950 + printk(KERN_INFO "%s() priv=NULL\n", __FUNCTION__); 951 + return; 952 + } 953 + 954 + grp = priv->mpcg; 955 + if (grp == NULL) { 956 + printk(KERN_INFO "ctcmpc:%s() grp=NULL\n", __FUNCTION__); 957 + return; 958 + } 959 + 960 + printk(KERN_NOTICE "ctcmpc: %s GROUP TRANSITIONED TO READY" 961 + " maxbuf:%d\n", 962 + dev->name, grp->group_max_buflen); 963 + 964 + fsm_newstate(grp->fsm, MPCG_STATE_READY); 965 + 966 + /* Put up a read on the channel */ 967 + ch = priv->channel[READ]; 968 + ch->pdu_seq = 0; 969 + if (do_debug_data) 970 + ctcm_pr_debug("ctcmpc: %s() ToDCM_pdu_seq= %08x\n" , 971 + __FUNCTION__, ch->pdu_seq); 972 + 973 + ctcmpc_chx_rxidle(ch->fsm, CTC_EVENT_START, ch); 974 + /* Put the write channel in idle state */ 975 + ch = priv->channel[WRITE]; 976 + if (ch->collect_len > 0) { 977 + spin_lock(&ch->collect_lock); 978 + ctcm_purge_skb_queue(&ch->collect_queue); 979 + ch->collect_len = 0; 980 + spin_unlock(&ch->collect_lock); 981 + } 982 + ctcm_chx_txidle(ch->fsm, CTC_EVENT_START, ch); 983 + 984 + ctcm_clear_busy(dev); 985 + 986 + if (grp->estconnfunc) { 987 + grp->estconnfunc(grp->port_num, 0, 988 + grp->group_max_buflen); 989 + grp->estconnfunc = NULL; 990 + } else 991 + if (grp->allochanfunc) 992 + grp->allochanfunc(grp->port_num, 993 + grp->group_max_buflen); 994 + 995 + grp->send_qllc_disc = 1; 996 + grp->changed_side = 0; 997 + 998 + ctcm_pr_debug("ctcmpc exit: %s()\n", __FUNCTION__); 999 + return; 1000 + 1001 + } 1002 + 1003 + /* 1004 + * Increment the MPC Group Active Channel Counts 1005 + * helper of dev_action (called from channel fsm) 1006 + */ 1007 + int mpc_channel_action(struct channel *ch, int direction, int action) 1008 + { 1009 + struct net_device *dev = ch->netdev; 1010 + struct ctcm_priv *priv; 1011 + struct mpc_group *grp = NULL; 1012 + int rc = 0; 1013 + 1014 + if (do_debug) 1015 + ctcm_pr_debug("ctcmpc enter: %s(): ch=0x%p id=%s\n", 1016 + __FUNCTION__, ch, ch->id); 1017 + 1018 + if (dev == NULL) { 1019 + printk(KERN_INFO "ctcmpc_channel_action %i dev=NULL\n", 1020 + action); 1021 + rc = 1; 1022 + goto done; 1023 + } 1024 + 1025 + priv = dev->priv; 1026 + if (priv == NULL) { 1027 + printk(KERN_INFO 1028 + "ctcmpc_channel_action%i priv=NULL, dev=%s\n", 1029 + action, dev->name); 1030 + rc = 2; 1031 + goto done; 1032 + } 1033 + 1034 + grp = priv->mpcg; 1035 + 1036 + if (grp == NULL) { 1037 + printk(KERN_INFO "ctcmpc: %s()%i mpcgroup=NULL, dev=%s\n", 1038 + __FUNCTION__, action, dev->name); 1039 + rc = 3; 1040 + goto done; 1041 + } 1042 + 1043 + ctcm_pr_info( 1044 + "ctcmpc: %s() %i(): Grp:%s total_channel_paths=%i " 1045 + "active_channels read=%i, write=%i\n", 1046 + __FUNCTION__, 1047 + action, 1048 + fsm_getstate_str(grp->fsm), 1049 + grp->num_channel_paths, 1050 + grp->active_channels[READ], 1051 + grp->active_channels[WRITE]); 1052 + 1053 + if ((action == MPC_CHANNEL_ADD) && (ch->in_mpcgroup == 0)) { 1054 + grp->num_channel_paths++; 1055 + grp->active_channels[direction]++; 1056 + grp->outstanding_xid2++; 1057 + ch->in_mpcgroup = 1; 1058 + 1059 + if (ch->xid_skb != NULL) 1060 + dev_kfree_skb_any(ch->xid_skb); 1061 + 1062 + ch->xid_skb = __dev_alloc_skb(MPC_BUFSIZE_DEFAULT, 1063 + GFP_ATOMIC | GFP_DMA); 1064 + if (ch->xid_skb == NULL) { 1065 + printk(KERN_INFO "ctcmpc: %s()" 1066 + "Couldn't alloc ch xid_skb\n", __FUNCTION__); 1067 + fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); 1068 + return 1; 1069 + } 1070 + ch->xid_skb_data = ch->xid_skb->data; 1071 + ch->xid_th = (struct th_header *)ch->xid_skb->data; 1072 + skb_put(ch->xid_skb, TH_HEADER_LENGTH); 1073 + ch->xid = (struct xid2 *)skb_tail_pointer(ch->xid_skb); 1074 + skb_put(ch->xid_skb, XID2_LENGTH); 1075 + ch->xid_id = skb_tail_pointer(ch->xid_skb); 1076 + ch->xid_skb->data = ch->xid_skb_data; 1077 + skb_reset_tail_pointer(ch->xid_skb); 1078 + ch->xid_skb->len = 0; 1079 + 1080 + memcpy(skb_put(ch->xid_skb, grp->xid_skb->len), 1081 + grp->xid_skb->data, 1082 + grp->xid_skb->len); 1083 + 1084 + ch->xid->xid2_dlc_type = ((CHANNEL_DIRECTION(ch->flags) == READ) 1085 + ? XID2_READ_SIDE : XID2_WRITE_SIDE); 1086 + 1087 + if (CHANNEL_DIRECTION(ch->flags) == WRITE) 1088 + ch->xid->xid2_buf_len = 0x00; 1089 + 1090 + ch->xid_skb->data = ch->xid_skb_data; 1091 + skb_reset_tail_pointer(ch->xid_skb); 1092 + ch->xid_skb->len = 0; 1093 + 1094 + fsm_newstate(ch->fsm, CH_XID0_PENDING); 1095 + 1096 + if ((grp->active_channels[READ] > 0) && 1097 + (grp->active_channels[WRITE] > 0) && 1098 + (fsm_getstate(grp->fsm) < MPCG_STATE_XID2INITW)) { 1099 + fsm_newstate(grp->fsm, MPCG_STATE_XID2INITW); 1100 + printk(KERN_NOTICE "ctcmpc: %s MPC GROUP " 1101 + "CHANNELS ACTIVE\n", dev->name); 1102 + } 1103 + } else if ((action == MPC_CHANNEL_REMOVE) && 1104 + (ch->in_mpcgroup == 1)) { 1105 + ch->in_mpcgroup = 0; 1106 + grp->num_channel_paths--; 1107 + grp->active_channels[direction]--; 1108 + 1109 + if (ch->xid_skb != NULL) 1110 + dev_kfree_skb_any(ch->xid_skb); 1111 + ch->xid_skb = NULL; 1112 + 1113 + if (grp->channels_terminating) 1114 + goto done; 1115 + 1116 + if (((grp->active_channels[READ] == 0) && 1117 + (grp->active_channels[WRITE] > 0)) 1118 + || ((grp->active_channels[WRITE] == 0) && 1119 + (grp->active_channels[READ] > 0))) 1120 + fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); 1121 + } 1122 + 1123 + done: 1124 + 1125 + if (do_debug) { 1126 + ctcm_pr_debug( 1127 + "ctcmpc: %s() %i Grp:%s ttl_chan_paths=%i " 1128 + "active_chans read=%i, write=%i\n", 1129 + __FUNCTION__, 1130 + action, 1131 + fsm_getstate_str(grp->fsm), 1132 + grp->num_channel_paths, 1133 + grp->active_channels[READ], 1134 + grp->active_channels[WRITE]); 1135 + 1136 + ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n", 1137 + __FUNCTION__, ch, ch->id); 1138 + } 1139 + return rc; 1140 + 1141 + } 1142 + 1143 + /** 1144 + * Unpack a just received skb and hand it over to 1145 + * upper layers. 1146 + * special MPC version of unpack_skb. 1147 + * 1148 + * ch The channel where this skb has been received. 1149 + * pskb The received skb. 1150 + */ 1151 + static void ctcmpc_unpack_skb(struct channel *ch, struct sk_buff *pskb) 1152 + { 1153 + struct net_device *dev = ch->netdev; 1154 + struct ctcm_priv *priv = dev->priv; 1155 + struct mpc_group *grp = priv->mpcg; 1156 + struct pdu *curr_pdu; 1157 + struct mpcg_info *mpcginfo; 1158 + struct th_header *header = NULL; 1159 + struct th_sweep *sweep = NULL; 1160 + int pdu_last_seen = 0; 1161 + __u32 new_len; 1162 + struct sk_buff *skb; 1163 + int skblen; 1164 + int sendrc = 0; 1165 + 1166 + if (do_debug) 1167 + ctcm_pr_debug("ctcmpc enter: %s() %s cp:%i ch:%s\n", 1168 + __FUNCTION__, dev->name, smp_processor_id(), ch->id); 1169 + 1170 + header = (struct th_header *)pskb->data; 1171 + if ((header->th_seg == 0) && 1172 + (header->th_ch_flag == 0) && 1173 + (header->th_blk_flag == 0) && 1174 + (header->th_seq_num == 0)) 1175 + /* nothing for us */ goto done; 1176 + 1177 + if (do_debug_data) { 1178 + ctcm_pr_debug("ctcmpc: %s() th_header\n", __FUNCTION__); 1179 + ctcmpc_dumpit((char *)header, TH_HEADER_LENGTH); 1180 + ctcm_pr_debug("ctcmpc: %s() pskb len: %04x \n", 1181 + __FUNCTION__, pskb->len); 1182 + } 1183 + 1184 + pskb->dev = dev; 1185 + pskb->ip_summed = CHECKSUM_UNNECESSARY; 1186 + skb_pull(pskb, TH_HEADER_LENGTH); 1187 + 1188 + if (likely(header->th_ch_flag == TH_HAS_PDU)) { 1189 + if (do_debug_data) 1190 + ctcm_pr_debug("ctcmpc: %s() came into th_has_pdu\n", 1191 + __FUNCTION__); 1192 + if ((fsm_getstate(grp->fsm) == MPCG_STATE_FLOWC) || 1193 + ((fsm_getstate(grp->fsm) == MPCG_STATE_READY) && 1194 + (header->th_seq_num != ch->th_seq_num + 1) && 1195 + (ch->th_seq_num != 0))) { 1196 + /* This is NOT the next segment * 1197 + * we are not the correct race winner * 1198 + * go away and let someone else win * 1199 + * BUT..this only applies if xid negot * 1200 + * is done * 1201 + */ 1202 + grp->out_of_sequence += 1; 1203 + __skb_push(pskb, TH_HEADER_LENGTH); 1204 + skb_queue_tail(&ch->io_queue, pskb); 1205 + if (do_debug_data) 1206 + ctcm_pr_debug("ctcmpc: %s() th_seq_num " 1207 + "expect:%08x got:%08x\n", __FUNCTION__, 1208 + ch->th_seq_num + 1, header->th_seq_num); 1209 + 1210 + return; 1211 + } 1212 + grp->out_of_sequence = 0; 1213 + ch->th_seq_num = header->th_seq_num; 1214 + 1215 + if (do_debug_data) 1216 + ctcm_pr_debug("ctcmpc: %s() FromVTAM_th_seq=%08x\n", 1217 + __FUNCTION__, ch->th_seq_num); 1218 + 1219 + if (unlikely(fsm_getstate(grp->fsm) != MPCG_STATE_READY)) 1220 + goto done; 1221 + pdu_last_seen = 0; 1222 + while ((pskb->len > 0) && !pdu_last_seen) { 1223 + curr_pdu = (struct pdu *)pskb->data; 1224 + if (do_debug_data) { 1225 + ctcm_pr_debug("ctcm: %s() pdu_header\n", 1226 + __FUNCTION__); 1227 + ctcmpc_dumpit((char *)pskb->data, 1228 + PDU_HEADER_LENGTH); 1229 + ctcm_pr_debug("ctcm: %s() pskb len: %04x \n", 1230 + __FUNCTION__, pskb->len); 1231 + } 1232 + skb_pull(pskb, PDU_HEADER_LENGTH); 1233 + 1234 + if (curr_pdu->pdu_flag & PDU_LAST) 1235 + pdu_last_seen = 1; 1236 + if (curr_pdu->pdu_flag & PDU_CNTL) 1237 + pskb->protocol = htons(ETH_P_SNAP); 1238 + else 1239 + pskb->protocol = htons(ETH_P_SNA_DIX); 1240 + 1241 + if ((pskb->len <= 0) || (pskb->len > ch->max_bufsize)) { 1242 + printk(KERN_INFO 1243 + "%s Illegal packet size %d " 1244 + "received " 1245 + "dropping\n", dev->name, 1246 + pskb->len); 1247 + priv->stats.rx_dropped++; 1248 + priv->stats.rx_length_errors++; 1249 + goto done; 1250 + } 1251 + skb_reset_mac_header(pskb); 1252 + new_len = curr_pdu->pdu_offset; 1253 + if (do_debug_data) 1254 + ctcm_pr_debug("ctcmpc: %s() new_len: %04x \n", 1255 + __FUNCTION__, new_len); 1256 + if ((new_len == 0) || (new_len > pskb->len)) { 1257 + /* should never happen */ 1258 + /* pskb len must be hosed...bail out */ 1259 + printk(KERN_INFO 1260 + "ctcmpc: %s(): invalid pdu" 1261 + " offset of %04x - data may be" 1262 + "lost\n", __FUNCTION__, new_len); 1263 + goto done; 1264 + } 1265 + skb = __dev_alloc_skb(new_len+4, GFP_ATOMIC); 1266 + 1267 + if (!skb) { 1268 + printk(KERN_INFO 1269 + "ctcm: %s Out of memory in " 1270 + "%s()- request-len:%04x \n", 1271 + dev->name, 1272 + __FUNCTION__, 1273 + new_len+4); 1274 + priv->stats.rx_dropped++; 1275 + fsm_event(grp->fsm, 1276 + MPCG_EVENT_INOP, dev); 1277 + goto done; 1278 + } 1279 + 1280 + memcpy(skb_put(skb, new_len), 1281 + pskb->data, new_len); 1282 + 1283 + skb_reset_mac_header(skb); 1284 + skb->dev = pskb->dev; 1285 + skb->protocol = pskb->protocol; 1286 + skb->ip_summed = CHECKSUM_UNNECESSARY; 1287 + *((__u32 *) skb_push(skb, 4)) = ch->pdu_seq; 1288 + ch->pdu_seq++; 1289 + 1290 + if (do_debug_data) 1291 + ctcm_pr_debug("%s: ToDCM_pdu_seq= %08x\n", 1292 + __FUNCTION__, ch->pdu_seq); 1293 + 1294 + ctcm_pr_debug("ctcm: %s() skb:%0lx " 1295 + "skb len: %d \n", __FUNCTION__, 1296 + (unsigned long)skb, skb->len); 1297 + if (do_debug_data) { 1298 + ctcm_pr_debug("ctcmpc: %s() up to 32 bytes" 1299 + " of pdu_data sent\n", 1300 + __FUNCTION__); 1301 + ctcmpc_dump32((char *)skb->data, skb->len); 1302 + } 1303 + 1304 + skblen = skb->len; 1305 + sendrc = netif_rx(skb); 1306 + priv->stats.rx_packets++; 1307 + priv->stats.rx_bytes += skblen; 1308 + skb_pull(pskb, new_len); /* point to next PDU */ 1309 + } 1310 + } else { 1311 + mpcginfo = (struct mpcg_info *) 1312 + kmalloc(sizeof(struct mpcg_info), gfp_type()); 1313 + if (mpcginfo == NULL) 1314 + goto done; 1315 + 1316 + mpcginfo->ch = ch; 1317 + mpcginfo->th = header; 1318 + mpcginfo->skb = pskb; 1319 + ctcm_pr_debug("ctcmpc: %s() Not PDU - may be control pkt\n", 1320 + __FUNCTION__); 1321 + /* it's a sweep? */ 1322 + sweep = (struct th_sweep *)pskb->data; 1323 + mpcginfo->sweep = sweep; 1324 + if (header->th_ch_flag == TH_SWEEP_REQ) 1325 + mpc_rcvd_sweep_req(mpcginfo); 1326 + else if (header->th_ch_flag == TH_SWEEP_RESP) 1327 + mpc_rcvd_sweep_resp(mpcginfo); 1328 + else if (header->th_blk_flag == TH_DATA_IS_XID) { 1329 + struct xid2 *thisxid = (struct xid2 *)pskb->data; 1330 + skb_pull(pskb, XID2_LENGTH); 1331 + mpcginfo->xid = thisxid; 1332 + fsm_event(grp->fsm, MPCG_EVENT_XID2, mpcginfo); 1333 + } else if (header->th_blk_flag == TH_DISCONTACT) 1334 + fsm_event(grp->fsm, MPCG_EVENT_DISCONC, mpcginfo); 1335 + else if (header->th_seq_num != 0) { 1336 + printk(KERN_INFO "%s unexpected packet" 1337 + " expected control pkt\n", dev->name); 1338 + priv->stats.rx_dropped++; 1339 + /* mpcginfo only used for non-data transfers */ 1340 + kfree(mpcginfo); 1341 + if (do_debug_data) 1342 + ctcmpc_dump_skb(pskb, -8); 1343 + } 1344 + } 1345 + done: 1346 + 1347 + dev_kfree_skb_any(pskb); 1348 + if (sendrc == NET_RX_DROP) { 1349 + printk(KERN_WARNING "%s %s() NETWORK BACKLOG EXCEEDED" 1350 + " - PACKET DROPPED\n", dev->name, __FUNCTION__); 1351 + fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); 1352 + } 1353 + 1354 + if (do_debug) 1355 + ctcm_pr_debug("ctcmpc exit : %s %s(): ch=0x%p id=%s\n", 1356 + dev->name, __FUNCTION__, ch, ch->id); 1357 + } 1358 + 1359 + /** 1360 + * tasklet helper for mpc's skb unpacking. 1361 + * 1362 + * ch The channel to work on. 1363 + * Allow flow control back pressure to occur here. 1364 + * Throttling back channel can result in excessive 1365 + * channel inactivity and system deact of channel 1366 + */ 1367 + void ctcmpc_bh(unsigned long thischan) 1368 + { 1369 + struct channel *ch = (struct channel *)thischan; 1370 + struct sk_buff *skb; 1371 + struct net_device *dev = ch->netdev; 1372 + struct ctcm_priv *priv = dev->priv; 1373 + struct mpc_group *grp = priv->mpcg; 1374 + 1375 + if (do_debug) 1376 + ctcm_pr_debug("%s cp:%i enter: %s() %s\n", 1377 + dev->name, smp_processor_id(), __FUNCTION__, ch->id); 1378 + /* caller has requested driver to throttle back */ 1379 + while ((fsm_getstate(grp->fsm) != MPCG_STATE_FLOWC) && 1380 + (skb = skb_dequeue(&ch->io_queue))) { 1381 + ctcmpc_unpack_skb(ch, skb); 1382 + if (grp->out_of_sequence > 20) { 1383 + /* assume data loss has occurred if */ 1384 + /* missing seq_num for extended */ 1385 + /* period of time */ 1386 + grp->out_of_sequence = 0; 1387 + fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); 1388 + break; 1389 + } 1390 + if (skb == skb_peek(&ch->io_queue)) 1391 + break; 1392 + } 1393 + if (do_debug) 1394 + ctcm_pr_debug("ctcmpc exit : %s %s(): ch=0x%p id=%s\n", 1395 + dev->name, __FUNCTION__, ch, ch->id); 1396 + return; 1397 + } 1398 + 1399 + /* 1400 + * MPC Group Initializations 1401 + */ 1402 + struct mpc_group *ctcmpc_init_mpc_group(struct ctcm_priv *priv) 1403 + { 1404 + struct mpc_group *grp; 1405 + 1406 + CTCM_DBF_TEXT(MPC_SETUP, 3, __FUNCTION__); 1407 + 1408 + grp = kzalloc(sizeof(struct mpc_group), GFP_KERNEL); 1409 + if (grp == NULL) 1410 + return NULL; 1411 + 1412 + grp->fsm = 1413 + init_fsm("mpcg", mpcg_state_names, mpcg_event_names, 1414 + MPCG_NR_STATES, MPCG_NR_EVENTS, mpcg_fsm, 1415 + mpcg_fsm_len, GFP_KERNEL); 1416 + if (grp->fsm == NULL) { 1417 + kfree(grp); 1418 + return NULL; 1419 + } 1420 + 1421 + fsm_newstate(grp->fsm, MPCG_STATE_RESET); 1422 + fsm_settimer(grp->fsm, &grp->timer); 1423 + 1424 + grp->xid_skb = 1425 + __dev_alloc_skb(MPC_BUFSIZE_DEFAULT, GFP_ATOMIC | GFP_DMA); 1426 + if (grp->xid_skb == NULL) { 1427 + printk(KERN_INFO "Couldn't alloc MPCgroup xid_skb\n"); 1428 + kfree_fsm(grp->fsm); 1429 + kfree(grp); 1430 + return NULL; 1431 + } 1432 + /* base xid for all channels in group */ 1433 + grp->xid_skb_data = grp->xid_skb->data; 1434 + grp->xid_th = (struct th_header *)grp->xid_skb->data; 1435 + memcpy(skb_put(grp->xid_skb, TH_HEADER_LENGTH), 1436 + &thnorm, TH_HEADER_LENGTH); 1437 + 1438 + grp->xid = (struct xid2 *) skb_tail_pointer(grp->xid_skb); 1439 + memcpy(skb_put(grp->xid_skb, XID2_LENGTH), &init_xid, XID2_LENGTH); 1440 + grp->xid->xid2_adj_id = jiffies | 0xfff00000; 1441 + grp->xid->xid2_sender_id = jiffies; 1442 + 1443 + grp->xid_id = skb_tail_pointer(grp->xid_skb); 1444 + memcpy(skb_put(grp->xid_skb, 4), "VTAM", 4); 1445 + 1446 + grp->rcvd_xid_skb = 1447 + __dev_alloc_skb(MPC_BUFSIZE_DEFAULT, GFP_ATOMIC|GFP_DMA); 1448 + if (grp->rcvd_xid_skb == NULL) { 1449 + printk(KERN_INFO "Couldn't alloc MPCgroup rcvd_xid_skb\n"); 1450 + kfree_fsm(grp->fsm); 1451 + dev_kfree_skb(grp->xid_skb); 1452 + kfree(grp); 1453 + return NULL; 1454 + } 1455 + grp->rcvd_xid_data = grp->rcvd_xid_skb->data; 1456 + grp->rcvd_xid_th = (struct th_header *)grp->rcvd_xid_skb->data; 1457 + memcpy(skb_put(grp->rcvd_xid_skb, TH_HEADER_LENGTH), 1458 + &thnorm, TH_HEADER_LENGTH); 1459 + grp->saved_xid2 = NULL; 1460 + priv->xid = grp->xid; 1461 + priv->mpcg = grp; 1462 + return grp; 1463 + } 1464 + 1465 + /* 1466 + * The MPC Group Station FSM 1467 + */ 1468 + 1469 + /* 1470 + * MPC Group Station FSM actions 1471 + * CTCM_PROTO_MPC only 1472 + */ 1473 + 1474 + /** 1475 + * NOP action for statemachines 1476 + */ 1477 + static void mpc_action_nop(fsm_instance *fi, int event, void *arg) 1478 + { 1479 + } 1480 + 1481 + /* 1482 + * invoked when the device transitions to dev_stopped 1483 + * MPC will stop each individual channel if a single XID failure 1484 + * occurs, or will intitiate all channels be stopped if a GROUP 1485 + * level failure occurs. 1486 + */ 1487 + static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg) 1488 + { 1489 + struct net_device *dev = arg; 1490 + struct ctcm_priv *priv; 1491 + struct mpc_group *grp; 1492 + int rc = 0; 1493 + struct channel *wch, *rch; 1494 + 1495 + if (dev == NULL) { 1496 + printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__); 1497 + return; 1498 + } 1499 + 1500 + ctcm_pr_debug("ctcmpc enter: %s %s()\n", dev->name, __FUNCTION__); 1501 + 1502 + priv = dev->priv; 1503 + grp = priv->mpcg; 1504 + grp->flow_off_called = 0; 1505 + 1506 + fsm_deltimer(&grp->timer); 1507 + 1508 + if (grp->channels_terminating) 1509 + goto done; 1510 + 1511 + grp->channels_terminating = 1; 1512 + 1513 + grp->saved_state = fsm_getstate(grp->fsm); 1514 + fsm_newstate(grp->fsm, MPCG_STATE_INOP); 1515 + if (grp->saved_state > MPCG_STATE_XID7INITF) 1516 + printk(KERN_NOTICE "%s:MPC GROUP INOPERATIVE\n", dev->name); 1517 + if ((grp->saved_state != MPCG_STATE_RESET) || 1518 + /* dealloc_channel has been called */ 1519 + ((grp->saved_state == MPCG_STATE_RESET) && 1520 + (grp->port_persist == 0))) 1521 + fsm_deltimer(&priv->restart_timer); 1522 + 1523 + wch = priv->channel[WRITE]; 1524 + rch = priv->channel[READ]; 1525 + 1526 + switch (grp->saved_state) { 1527 + case MPCG_STATE_RESET: 1528 + case MPCG_STATE_INOP: 1529 + case MPCG_STATE_XID2INITW: 1530 + case MPCG_STATE_XID0IOWAIT: 1531 + case MPCG_STATE_XID2INITX: 1532 + case MPCG_STATE_XID7INITW: 1533 + case MPCG_STATE_XID7INITX: 1534 + case MPCG_STATE_XID0IOWAIX: 1535 + case MPCG_STATE_XID7INITI: 1536 + case MPCG_STATE_XID7INITZ: 1537 + case MPCG_STATE_XID7INITF: 1538 + break; 1539 + case MPCG_STATE_FLOWC: 1540 + case MPCG_STATE_READY: 1541 + default: 1542 + tasklet_hi_schedule(&wch->ch_disc_tasklet); 1543 + } 1544 + 1545 + grp->xid2_tgnum = 0; 1546 + grp->group_max_buflen = 0; /*min of all received */ 1547 + grp->outstanding_xid2 = 0; 1548 + grp->outstanding_xid7 = 0; 1549 + grp->outstanding_xid7_p2 = 0; 1550 + grp->saved_xid2 = NULL; 1551 + grp->xidnogood = 0; 1552 + grp->changed_side = 0; 1553 + 1554 + grp->rcvd_xid_skb->data = grp->rcvd_xid_data; 1555 + skb_reset_tail_pointer(grp->rcvd_xid_skb); 1556 + grp->rcvd_xid_skb->len = 0; 1557 + grp->rcvd_xid_th = (struct th_header *)grp->rcvd_xid_skb->data; 1558 + memcpy(skb_put(grp->rcvd_xid_skb, TH_HEADER_LENGTH), &thnorm, 1559 + TH_HEADER_LENGTH); 1560 + 1561 + if (grp->send_qllc_disc == 1) { 1562 + grp->send_qllc_disc = 0; 1563 + rc = mpc_send_qllc_discontact(dev); 1564 + } 1565 + 1566 + /* DO NOT issue DEV_EVENT_STOP directly out of this code */ 1567 + /* This can result in INOP of VTAM PU due to halting of */ 1568 + /* outstanding IO which causes a sense to be returned */ 1569 + /* Only about 3 senses are allowed and then IOS/VTAM will*/ 1570 + /* ebcome unreachable without manual intervention */ 1571 + if ((grp->port_persist == 1) || (grp->alloc_called)) { 1572 + grp->alloc_called = 0; 1573 + fsm_deltimer(&priv->restart_timer); 1574 + fsm_addtimer(&priv->restart_timer, 1575 + 500, 1576 + DEV_EVENT_RESTART, 1577 + dev); 1578 + fsm_newstate(grp->fsm, MPCG_STATE_RESET); 1579 + if (grp->saved_state > MPCG_STATE_XID7INITF) 1580 + printk(KERN_NOTICE "%s:MPC GROUP RECOVERY SCHEDULED\n", 1581 + dev->name); 1582 + } else { 1583 + fsm_deltimer(&priv->restart_timer); 1584 + fsm_addtimer(&priv->restart_timer, 500, DEV_EVENT_STOP, dev); 1585 + fsm_newstate(grp->fsm, MPCG_STATE_RESET); 1586 + printk(KERN_NOTICE "%s:MPC GROUP RECOVERY NOT ATTEMPTED\n", 1587 + dev->name); 1588 + } 1589 + 1590 + done: 1591 + ctcm_pr_debug("ctcmpc exit:%s %s()\n", dev->name, __FUNCTION__); 1592 + return; 1593 + } 1594 + 1595 + /** 1596 + * Handle mpc group action timeout. 1597 + * MPC Group Station FSM action 1598 + * CTCM_PROTO_MPC only 1599 + * 1600 + * fi An instance of an mpc_group fsm. 1601 + * event The event, just happened. 1602 + * arg Generic pointer, casted from net_device * upon call. 1603 + */ 1604 + static void mpc_action_timeout(fsm_instance *fi, int event, void *arg) 1605 + { 1606 + struct net_device *dev = arg; 1607 + struct ctcm_priv *priv; 1608 + struct mpc_group *grp; 1609 + struct channel *wch; 1610 + struct channel *rch; 1611 + 1612 + CTCM_DBF_TEXT(MPC_TRACE, 6, __FUNCTION__); 1613 + 1614 + if (dev == NULL) { 1615 + CTCM_DBF_TEXT_(MPC_ERROR, 4, "%s: dev=NULL\n", __FUNCTION__); 1616 + return; 1617 + } 1618 + 1619 + priv = dev->priv; 1620 + grp = priv->mpcg; 1621 + wch = priv->channel[WRITE]; 1622 + rch = priv->channel[READ]; 1623 + 1624 + switch (fsm_getstate(grp->fsm)) { 1625 + case MPCG_STATE_XID2INITW: 1626 + /* Unless there is outstanding IO on the */ 1627 + /* channel just return and wait for ATTN */ 1628 + /* interrupt to begin XID negotiations */ 1629 + if ((fsm_getstate(rch->fsm) == CH_XID0_PENDING) && 1630 + (fsm_getstate(wch->fsm) == CH_XID0_PENDING)) 1631 + break; 1632 + default: 1633 + fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); 1634 + } 1635 + 1636 + CTCM_DBF_TEXT_(MPC_TRACE, 6, "%s: dev=%s exit", 1637 + __FUNCTION__, dev->name); 1638 + return; 1639 + } 1640 + 1641 + /* 1642 + * MPC Group Station FSM action 1643 + * CTCM_PROTO_MPC only 1644 + */ 1645 + void mpc_action_discontact(fsm_instance *fi, int event, void *arg) 1646 + { 1647 + struct mpcg_info *mpcginfo = arg; 1648 + struct channel *ch = mpcginfo->ch; 1649 + struct net_device *dev = ch->netdev; 1650 + struct ctcm_priv *priv = dev->priv; 1651 + struct mpc_group *grp = priv->mpcg; 1652 + 1653 + if (ch == NULL) { 1654 + printk(KERN_INFO "%s() ch=NULL\n", __FUNCTION__); 1655 + return; 1656 + } 1657 + if (ch->netdev == NULL) { 1658 + printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__); 1659 + return; 1660 + } 1661 + 1662 + ctcm_pr_debug("ctcmpc enter: %s %s()\n", dev->name, __FUNCTION__); 1663 + 1664 + grp->send_qllc_disc = 1; 1665 + fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); 1666 + 1667 + ctcm_pr_debug("ctcmpc exit: %s %s()\n", dev->name, __FUNCTION__); 1668 + return; 1669 + } 1670 + 1671 + /* 1672 + * MPC Group Station - not part of FSM 1673 + * CTCM_PROTO_MPC only 1674 + * called from add_channel in ctcm_main.c 1675 + */ 1676 + void mpc_action_send_discontact(unsigned long thischan) 1677 + { 1678 + struct channel *ch; 1679 + struct net_device *dev; 1680 + struct ctcm_priv *priv; 1681 + struct mpc_group *grp; 1682 + int rc = 0; 1683 + unsigned long saveflags; 1684 + 1685 + ch = (struct channel *)thischan; 1686 + dev = ch->netdev; 1687 + priv = dev->priv; 1688 + grp = priv->mpcg; 1689 + 1690 + ctcm_pr_info("ctcmpc: %s cp:%i enter: %s() GrpState:%s ChState:%s\n", 1691 + dev->name, 1692 + smp_processor_id(), 1693 + __FUNCTION__, 1694 + fsm_getstate_str(grp->fsm), 1695 + fsm_getstate_str(ch->fsm)); 1696 + saveflags = 0; /* avoids compiler warning with 1697 + spin_unlock_irqrestore */ 1698 + 1699 + spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags); 1700 + rc = ccw_device_start(ch->cdev, &ch->ccw[15], 1701 + (unsigned long)ch, 0xff, 0); 1702 + spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags); 1703 + 1704 + if (rc != 0) { 1705 + ctcm_pr_info("ctcmpc: %s() ch:%s IO failed \n", 1706 + __FUNCTION__, 1707 + ch->id); 1708 + ctcm_ccw_check_rc(ch, rc, "send discontact"); 1709 + /* Not checking return code value here */ 1710 + /* Making best effort to notify partner*/ 1711 + /* that MPC Group is going down */ 1712 + } 1713 + 1714 + ctcm_pr_debug("ctcmpc exit: %s %s()\n", dev->name, __FUNCTION__); 1715 + return; 1716 + } 1717 + 1718 + 1719 + /* 1720 + * helper function of mpc FSM 1721 + * CTCM_PROTO_MPC only 1722 + * mpc_action_rcvd_xid7 1723 + */ 1724 + static int mpc_validate_xid(struct mpcg_info *mpcginfo) 1725 + { 1726 + struct channel *ch = mpcginfo->ch; 1727 + struct net_device *dev = ch->netdev; 1728 + struct ctcm_priv *priv = dev->priv; 1729 + struct mpc_group *grp = priv->mpcg; 1730 + struct xid2 *xid = mpcginfo->xid; 1731 + int failed = 0; 1732 + int rc = 0; 1733 + __u64 our_id, their_id = 0; 1734 + int len; 1735 + 1736 + len = TH_HEADER_LENGTH + PDU_HEADER_LENGTH; 1737 + 1738 + ctcm_pr_debug("ctcmpc enter: %s()\n", __FUNCTION__); 1739 + 1740 + if (mpcginfo->xid == NULL) { 1741 + printk(KERN_INFO "%s() xid=NULL\n", __FUNCTION__); 1742 + rc = 1; 1743 + goto done; 1744 + } 1745 + 1746 + ctcm_pr_debug("ctcmpc : %s xid received()\n", __FUNCTION__); 1747 + ctcmpc_dumpit((char *)mpcginfo->xid, XID2_LENGTH); 1748 + 1749 + /*the received direction should be the opposite of ours */ 1750 + if (((CHANNEL_DIRECTION(ch->flags) == READ) ? XID2_WRITE_SIDE : 1751 + XID2_READ_SIDE) != xid->xid2_dlc_type) { 1752 + failed = 1; 1753 + printk(KERN_INFO "ctcmpc:%s() XID REJECTED - READ-WRITE CH " 1754 + "Pairing Invalid \n", __FUNCTION__); 1755 + } 1756 + 1757 + if (xid->xid2_dlc_type == XID2_READ_SIDE) { 1758 + ctcm_pr_debug("ctcmpc: %s(): grpmaxbuf:%d xid2buflen:%d\n", 1759 + __FUNCTION__, grp->group_max_buflen, 1760 + xid->xid2_buf_len); 1761 + 1762 + if (grp->group_max_buflen == 0 || 1763 + grp->group_max_buflen > xid->xid2_buf_len - len) 1764 + grp->group_max_buflen = xid->xid2_buf_len - len; 1765 + } 1766 + 1767 + 1768 + if (grp->saved_xid2 == NULL) { 1769 + grp->saved_xid2 = 1770 + (struct xid2 *)skb_tail_pointer(grp->rcvd_xid_skb); 1771 + 1772 + memcpy(skb_put(grp->rcvd_xid_skb, 1773 + XID2_LENGTH), xid, XID2_LENGTH); 1774 + grp->rcvd_xid_skb->data = grp->rcvd_xid_data; 1775 + 1776 + skb_reset_tail_pointer(grp->rcvd_xid_skb); 1777 + grp->rcvd_xid_skb->len = 0; 1778 + 1779 + /* convert two 32 bit numbers into 1 64 bit for id compare */ 1780 + our_id = (__u64)priv->xid->xid2_adj_id; 1781 + our_id = our_id << 32; 1782 + our_id = our_id + priv->xid->xid2_sender_id; 1783 + their_id = (__u64)xid->xid2_adj_id; 1784 + their_id = their_id << 32; 1785 + their_id = their_id + xid->xid2_sender_id; 1786 + /* lower id assume the xside role */ 1787 + if (our_id < their_id) { 1788 + grp->roll = XSIDE; 1789 + ctcm_pr_debug("ctcmpc :%s() WE HAVE LOW ID-" 1790 + "TAKE XSIDE\n", __FUNCTION__); 1791 + } else { 1792 + grp->roll = YSIDE; 1793 + ctcm_pr_debug("ctcmpc :%s() WE HAVE HIGH ID-" 1794 + "TAKE YSIDE\n", __FUNCTION__); 1795 + } 1796 + 1797 + } else { 1798 + if (xid->xid2_flag4 != grp->saved_xid2->xid2_flag4) { 1799 + failed = 1; 1800 + printk(KERN_INFO "%s XID REJECTED - XID Flag Byte4\n", 1801 + __FUNCTION__); 1802 + } 1803 + if (xid->xid2_flag2 == 0x40) { 1804 + failed = 1; 1805 + printk(KERN_INFO "%s XID REJECTED - XID NOGOOD\n", 1806 + __FUNCTION__); 1807 + } 1808 + if (xid->xid2_adj_id != grp->saved_xid2->xid2_adj_id) { 1809 + failed = 1; 1810 + printk(KERN_INFO "%s XID REJECTED - " 1811 + "Adjacent Station ID Mismatch\n", 1812 + __FUNCTION__); 1813 + } 1814 + if (xid->xid2_sender_id != grp->saved_xid2->xid2_sender_id) { 1815 + failed = 1; 1816 + printk(KERN_INFO "%s XID REJECTED - " 1817 + "Sender Address Mismatch\n", __FUNCTION__); 1818 + 1819 + } 1820 + } 1821 + 1822 + if (failed) { 1823 + ctcm_pr_info("ctcmpc : %s() failed\n", __FUNCTION__); 1824 + priv->xid->xid2_flag2 = 0x40; 1825 + grp->saved_xid2->xid2_flag2 = 0x40; 1826 + rc = 1; 1827 + } 1828 + 1829 + done: 1830 + 1831 + ctcm_pr_debug("ctcmpc exit: %s()\n", __FUNCTION__); 1832 + return rc; 1833 + } 1834 + 1835 + /* 1836 + * MPC Group Station FSM action 1837 + * CTCM_PROTO_MPC only 1838 + */ 1839 + static void mpc_action_side_xid(fsm_instance *fsm, void *arg, int side) 1840 + { 1841 + struct channel *ch = arg; 1842 + struct ctcm_priv *priv; 1843 + struct mpc_group *grp = NULL; 1844 + struct net_device *dev = NULL; 1845 + int rc = 0; 1846 + int gotlock = 0; 1847 + unsigned long saveflags = 0; /* avoids compiler warning with 1848 + spin_unlock_irqrestore */ 1849 + 1850 + if (ch == NULL) { 1851 + printk(KERN_INFO "%s ch=NULL\n", __FUNCTION__); 1852 + goto done; 1853 + } 1854 + 1855 + if (do_debug) 1856 + ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n", 1857 + __FUNCTION__, smp_processor_id(), ch, ch->id); 1858 + 1859 + dev = ch->netdev; 1860 + if (dev == NULL) { 1861 + printk(KERN_INFO "%s dev=NULL\n", __FUNCTION__); 1862 + goto done; 1863 + } 1864 + 1865 + priv = dev->priv; 1866 + if (priv == NULL) { 1867 + printk(KERN_INFO "%s priv=NULL\n", __FUNCTION__); 1868 + goto done; 1869 + } 1870 + 1871 + grp = priv->mpcg; 1872 + if (grp == NULL) { 1873 + printk(KERN_INFO "%s grp=NULL\n", __FUNCTION__); 1874 + goto done; 1875 + } 1876 + 1877 + if (ctcm_checkalloc_buffer(ch)) 1878 + goto done; 1879 + 1880 + /* skb data-buffer referencing: */ 1881 + 1882 + ch->trans_skb->data = ch->trans_skb_data; 1883 + skb_reset_tail_pointer(ch->trans_skb); 1884 + ch->trans_skb->len = 0; 1885 + /* result of the previous 3 statements is NOT always 1886 + * already set after ctcm_checkalloc_buffer 1887 + * because of possible reuse of the trans_skb 1888 + */ 1889 + memset(ch->trans_skb->data, 0, 16); 1890 + ch->rcvd_xid_th = (struct th_header *)ch->trans_skb_data; 1891 + /* check is main purpose here: */ 1892 + skb_put(ch->trans_skb, TH_HEADER_LENGTH); 1893 + ch->rcvd_xid = (struct xid2 *)skb_tail_pointer(ch->trans_skb); 1894 + /* check is main purpose here: */ 1895 + skb_put(ch->trans_skb, XID2_LENGTH); 1896 + ch->rcvd_xid_id = skb_tail_pointer(ch->trans_skb); 1897 + /* cleanup back to startpoint */ 1898 + ch->trans_skb->data = ch->trans_skb_data; 1899 + skb_reset_tail_pointer(ch->trans_skb); 1900 + ch->trans_skb->len = 0; 1901 + 1902 + /* non-checking rewrite of above skb data-buffer referencing: */ 1903 + /* 1904 + memset(ch->trans_skb->data, 0, 16); 1905 + ch->rcvd_xid_th = (struct th_header *)ch->trans_skb_data; 1906 + ch->rcvd_xid = (struct xid2 *)(ch->trans_skb_data + TH_HEADER_LENGTH); 1907 + ch->rcvd_xid_id = ch->trans_skb_data + TH_HEADER_LENGTH + XID2_LENGTH; 1908 + */ 1909 + 1910 + ch->ccw[8].flags = CCW_FLAG_SLI | CCW_FLAG_CC; 1911 + ch->ccw[8].count = 0; 1912 + ch->ccw[8].cda = 0x00; 1913 + 1914 + if (side == XSIDE) { 1915 + /* mpc_action_xside_xid */ 1916 + if (ch->xid_th == NULL) { 1917 + printk(KERN_INFO "%s ch->xid_th=NULL\n", __FUNCTION__); 1918 + goto done; 1919 + } 1920 + ch->ccw[9].cmd_code = CCW_CMD_WRITE; 1921 + ch->ccw[9].flags = CCW_FLAG_SLI | CCW_FLAG_CC; 1922 + ch->ccw[9].count = TH_HEADER_LENGTH; 1923 + ch->ccw[9].cda = virt_to_phys(ch->xid_th); 1924 + 1925 + if (ch->xid == NULL) { 1926 + printk(KERN_INFO "%s ch->xid=NULL\n", __FUNCTION__); 1927 + goto done; 1928 + } 1929 + 1930 + ch->ccw[10].cmd_code = CCW_CMD_WRITE; 1931 + ch->ccw[10].flags = CCW_FLAG_SLI | CCW_FLAG_CC; 1932 + ch->ccw[10].count = XID2_LENGTH; 1933 + ch->ccw[10].cda = virt_to_phys(ch->xid); 1934 + 1935 + ch->ccw[11].cmd_code = CCW_CMD_READ; 1936 + ch->ccw[11].flags = CCW_FLAG_SLI | CCW_FLAG_CC; 1937 + ch->ccw[11].count = TH_HEADER_LENGTH; 1938 + ch->ccw[11].cda = virt_to_phys(ch->rcvd_xid_th); 1939 + 1940 + ch->ccw[12].cmd_code = CCW_CMD_READ; 1941 + ch->ccw[12].flags = CCW_FLAG_SLI | CCW_FLAG_CC; 1942 + ch->ccw[12].count = XID2_LENGTH; 1943 + ch->ccw[12].cda = virt_to_phys(ch->rcvd_xid); 1944 + 1945 + ch->ccw[13].cmd_code = CCW_CMD_READ; 1946 + ch->ccw[13].cda = virt_to_phys(ch->rcvd_xid_id); 1947 + 1948 + } else { /* side == YSIDE : mpc_action_yside_xid */ 1949 + ch->ccw[9].cmd_code = CCW_CMD_READ; 1950 + ch->ccw[9].flags = CCW_FLAG_SLI | CCW_FLAG_CC; 1951 + ch->ccw[9].count = TH_HEADER_LENGTH; 1952 + ch->ccw[9].cda = virt_to_phys(ch->rcvd_xid_th); 1953 + 1954 + ch->ccw[10].cmd_code = CCW_CMD_READ; 1955 + ch->ccw[10].flags = CCW_FLAG_SLI | CCW_FLAG_CC; 1956 + ch->ccw[10].count = XID2_LENGTH; 1957 + ch->ccw[10].cda = virt_to_phys(ch->rcvd_xid); 1958 + 1959 + if (ch->xid_th == NULL) { 1960 + printk(KERN_INFO "%s ch->xid_th=NULL\n", __FUNCTION__); 1961 + goto done; 1962 + } 1963 + ch->ccw[11].cmd_code = CCW_CMD_WRITE; 1964 + ch->ccw[11].flags = CCW_FLAG_SLI | CCW_FLAG_CC; 1965 + ch->ccw[11].count = TH_HEADER_LENGTH; 1966 + ch->ccw[11].cda = virt_to_phys(ch->xid_th); 1967 + 1968 + if (ch->xid == NULL) { 1969 + printk(KERN_INFO "%s ch->xid=NULL\n", __FUNCTION__); 1970 + goto done; 1971 + } 1972 + ch->ccw[12].cmd_code = CCW_CMD_WRITE; 1973 + ch->ccw[12].flags = CCW_FLAG_SLI | CCW_FLAG_CC; 1974 + ch->ccw[12].count = XID2_LENGTH; 1975 + ch->ccw[12].cda = virt_to_phys(ch->xid); 1976 + 1977 + if (ch->xid_id == NULL) { 1978 + printk(KERN_INFO "%s ch->xid_id=NULL\n", __FUNCTION__); 1979 + goto done; 1980 + } 1981 + ch->ccw[13].cmd_code = CCW_CMD_WRITE; 1982 + ch->ccw[13].cda = virt_to_phys(ch->xid_id); 1983 + 1984 + } 1985 + ch->ccw[13].flags = CCW_FLAG_SLI | CCW_FLAG_CC; 1986 + ch->ccw[13].count = 4; 1987 + 1988 + ch->ccw[14].cmd_code = CCW_CMD_NOOP; 1989 + ch->ccw[14].flags = CCW_FLAG_SLI; 1990 + ch->ccw[14].count = 0; 1991 + ch->ccw[14].cda = 0; 1992 + 1993 + if (do_debug_ccw) 1994 + ctcmpc_dumpit((char *)&ch->ccw[8], sizeof(struct ccw1) * 7); 1995 + 1996 + ctcmpc_dumpit((char *)ch->xid_th, TH_HEADER_LENGTH); 1997 + ctcmpc_dumpit((char *)ch->xid, XID2_LENGTH); 1998 + ctcmpc_dumpit((char *)ch->xid_id, 4); 1999 + if (!in_irq()) { 2000 + /* Such conditional locking is a known problem for 2001 + * sparse because its static undeterministic. 2002 + * Warnings should be ignored here. */ 2003 + spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags); 2004 + gotlock = 1; 2005 + } 2006 + 2007 + fsm_addtimer(&ch->timer, 5000 , CTC_EVENT_TIMER, ch); 2008 + rc = ccw_device_start(ch->cdev, &ch->ccw[8], 2009 + (unsigned long)ch, 0xff, 0); 2010 + 2011 + if (gotlock) /* see remark above about conditional locking */ 2012 + spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags); 2013 + 2014 + if (rc != 0) { 2015 + ctcm_pr_info("ctcmpc: %s() ch:%s IO failed \n", 2016 + __FUNCTION__, ch->id); 2017 + ctcm_ccw_check_rc(ch, rc, 2018 + (side == XSIDE) ? "x-side XID" : "y-side XID"); 2019 + } 2020 + 2021 + done: 2022 + if (do_debug) 2023 + ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n", 2024 + __FUNCTION__, ch, ch->id); 2025 + return; 2026 + 2027 + } 2028 + 2029 + /* 2030 + * MPC Group Station FSM action 2031 + * CTCM_PROTO_MPC only 2032 + */ 2033 + static void mpc_action_xside_xid(fsm_instance *fsm, int event, void *arg) 2034 + { 2035 + mpc_action_side_xid(fsm, arg, XSIDE); 2036 + } 2037 + 2038 + /* 2039 + * MPC Group Station FSM action 2040 + * CTCM_PROTO_MPC only 2041 + */ 2042 + static void mpc_action_yside_xid(fsm_instance *fsm, int event, void *arg) 2043 + { 2044 + mpc_action_side_xid(fsm, arg, YSIDE); 2045 + } 2046 + 2047 + /* 2048 + * MPC Group Station FSM action 2049 + * CTCM_PROTO_MPC only 2050 + */ 2051 + static void mpc_action_doxid0(fsm_instance *fsm, int event, void *arg) 2052 + { 2053 + struct channel *ch = arg; 2054 + struct ctcm_priv *priv; 2055 + struct mpc_group *grp = NULL; 2056 + struct net_device *dev = NULL; 2057 + 2058 + if (do_debug) 2059 + ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n", 2060 + __FUNCTION__, smp_processor_id(), ch, ch->id); 2061 + 2062 + if (ch == NULL) { 2063 + printk(KERN_WARNING "%s ch=NULL\n", __FUNCTION__); 2064 + goto done; 2065 + } 2066 + 2067 + dev = ch->netdev; 2068 + if (dev == NULL) { 2069 + printk(KERN_WARNING "%s dev=NULL\n", __FUNCTION__); 2070 + goto done; 2071 + } 2072 + 2073 + priv = dev->priv; 2074 + if (priv == NULL) { 2075 + printk(KERN_WARNING "%s priv=NULL\n", __FUNCTION__); 2076 + goto done; 2077 + } 2078 + 2079 + grp = priv->mpcg; 2080 + if (grp == NULL) { 2081 + printk(KERN_WARNING "%s grp=NULL\n", __FUNCTION__); 2082 + goto done; 2083 + } 2084 + 2085 + if (ch->xid == NULL) { 2086 + printk(KERN_WARNING "%s ch-xid=NULL\n", __FUNCTION__); 2087 + goto done; 2088 + } 2089 + 2090 + fsm_newstate(ch->fsm, CH_XID0_INPROGRESS); 2091 + 2092 + ch->xid->xid2_option = XID2_0; 2093 + 2094 + switch (fsm_getstate(grp->fsm)) { 2095 + case MPCG_STATE_XID2INITW: 2096 + case MPCG_STATE_XID2INITX: 2097 + ch->ccw[8].cmd_code = CCW_CMD_SENSE_CMD; 2098 + break; 2099 + case MPCG_STATE_XID0IOWAIT: 2100 + case MPCG_STATE_XID0IOWAIX: 2101 + ch->ccw[8].cmd_code = CCW_CMD_WRITE_CTL; 2102 + break; 2103 + } 2104 + 2105 + fsm_event(grp->fsm, MPCG_EVENT_DOIO, ch); 2106 + 2107 + done: 2108 + if (do_debug) 2109 + ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n", 2110 + __FUNCTION__, ch, ch->id); 2111 + return; 2112 + 2113 + } 2114 + 2115 + /* 2116 + * MPC Group Station FSM action 2117 + * CTCM_PROTO_MPC only 2118 + */ 2119 + static void mpc_action_doxid7(fsm_instance *fsm, int event, void *arg) 2120 + { 2121 + struct net_device *dev = arg; 2122 + struct ctcm_priv *priv = NULL; 2123 + struct mpc_group *grp = NULL; 2124 + int direction; 2125 + int rc = 0; 2126 + int send = 0; 2127 + 2128 + ctcm_pr_debug("ctcmpc enter: %s() \n", __FUNCTION__); 2129 + 2130 + if (dev == NULL) { 2131 + printk(KERN_INFO "%s dev=NULL \n", __FUNCTION__); 2132 + rc = 1; 2133 + goto done; 2134 + } 2135 + 2136 + priv = dev->priv; 2137 + if (priv == NULL) { 2138 + printk(KERN_INFO "%s priv=NULL \n", __FUNCTION__); 2139 + rc = 1; 2140 + goto done; 2141 + } 2142 + 2143 + grp = priv->mpcg; 2144 + if (grp == NULL) { 2145 + printk(KERN_INFO "%s grp=NULL \n", __FUNCTION__); 2146 + rc = 1; 2147 + goto done; 2148 + } 2149 + 2150 + for (direction = READ; direction <= WRITE; direction++) { 2151 + struct channel *ch = priv->channel[direction]; 2152 + struct xid2 *thisxid = ch->xid; 2153 + ch->xid_skb->data = ch->xid_skb_data; 2154 + skb_reset_tail_pointer(ch->xid_skb); 2155 + ch->xid_skb->len = 0; 2156 + thisxid->xid2_option = XID2_7; 2157 + send = 0; 2158 + 2159 + /* xid7 phase 1 */ 2160 + if (grp->outstanding_xid7_p2 > 0) { 2161 + if (grp->roll == YSIDE) { 2162 + if (fsm_getstate(ch->fsm) == CH_XID7_PENDING1) { 2163 + fsm_newstate(ch->fsm, CH_XID7_PENDING2); 2164 + ch->ccw[8].cmd_code = CCW_CMD_SENSE_CMD; 2165 + memcpy(skb_put(ch->xid_skb, 2166 + TH_HEADER_LENGTH), 2167 + &thdummy, TH_HEADER_LENGTH); 2168 + send = 1; 2169 + } 2170 + } else if (fsm_getstate(ch->fsm) < CH_XID7_PENDING2) { 2171 + fsm_newstate(ch->fsm, CH_XID7_PENDING2); 2172 + ch->ccw[8].cmd_code = CCW_CMD_WRITE_CTL; 2173 + memcpy(skb_put(ch->xid_skb, 2174 + TH_HEADER_LENGTH), 2175 + &thnorm, TH_HEADER_LENGTH); 2176 + send = 1; 2177 + } 2178 + } else { 2179 + /* xid7 phase 2 */ 2180 + if (grp->roll == YSIDE) { 2181 + if (fsm_getstate(ch->fsm) < CH_XID7_PENDING4) { 2182 + fsm_newstate(ch->fsm, CH_XID7_PENDING4); 2183 + memcpy(skb_put(ch->xid_skb, 2184 + TH_HEADER_LENGTH), 2185 + &thnorm, TH_HEADER_LENGTH); 2186 + ch->ccw[8].cmd_code = CCW_CMD_WRITE_CTL; 2187 + send = 1; 2188 + } 2189 + } else if (fsm_getstate(ch->fsm) == CH_XID7_PENDING3) { 2190 + fsm_newstate(ch->fsm, CH_XID7_PENDING4); 2191 + ch->ccw[8].cmd_code = CCW_CMD_SENSE_CMD; 2192 + memcpy(skb_put(ch->xid_skb, TH_HEADER_LENGTH), 2193 + &thdummy, TH_HEADER_LENGTH); 2194 + send = 1; 2195 + } 2196 + } 2197 + 2198 + if (send) 2199 + fsm_event(grp->fsm, MPCG_EVENT_DOIO, ch); 2200 + } 2201 + 2202 + done: 2203 + 2204 + if (rc != 0) 2205 + fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); 2206 + 2207 + return; 2208 + } 2209 + 2210 + /* 2211 + * MPC Group Station FSM action 2212 + * CTCM_PROTO_MPC only 2213 + */ 2214 + static void mpc_action_rcvd_xid0(fsm_instance *fsm, int event, void *arg) 2215 + { 2216 + 2217 + struct mpcg_info *mpcginfo = arg; 2218 + struct channel *ch = mpcginfo->ch; 2219 + struct net_device *dev = ch->netdev; 2220 + struct ctcm_priv *priv; 2221 + struct mpc_group *grp; 2222 + 2223 + if (do_debug) 2224 + ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n", 2225 + __FUNCTION__, smp_processor_id(), ch, ch->id); 2226 + 2227 + priv = dev->priv; 2228 + grp = priv->mpcg; 2229 + 2230 + ctcm_pr_debug("ctcmpc in:%s() %s xid2:%i xid7:%i xidt_p2:%i \n", 2231 + __FUNCTION__, ch->id, 2232 + grp->outstanding_xid2, 2233 + grp->outstanding_xid7, 2234 + grp->outstanding_xid7_p2); 2235 + 2236 + if (fsm_getstate(ch->fsm) < CH_XID7_PENDING) 2237 + fsm_newstate(ch->fsm, CH_XID7_PENDING); 2238 + 2239 + grp->outstanding_xid2--; 2240 + grp->outstanding_xid7++; 2241 + grp->outstanding_xid7_p2++; 2242 + 2243 + /* must change state before validating xid to */ 2244 + /* properly handle interim interrupts received*/ 2245 + switch (fsm_getstate(grp->fsm)) { 2246 + case MPCG_STATE_XID2INITW: 2247 + fsm_newstate(grp->fsm, MPCG_STATE_XID2INITX); 2248 + mpc_validate_xid(mpcginfo); 2249 + break; 2250 + case MPCG_STATE_XID0IOWAIT: 2251 + fsm_newstate(grp->fsm, MPCG_STATE_XID0IOWAIX); 2252 + mpc_validate_xid(mpcginfo); 2253 + break; 2254 + case MPCG_STATE_XID2INITX: 2255 + if (grp->outstanding_xid2 == 0) { 2256 + fsm_newstate(grp->fsm, MPCG_STATE_XID7INITW); 2257 + mpc_validate_xid(mpcginfo); 2258 + fsm_event(grp->fsm, MPCG_EVENT_XID2DONE, dev); 2259 + } 2260 + break; 2261 + case MPCG_STATE_XID0IOWAIX: 2262 + if (grp->outstanding_xid2 == 0) { 2263 + fsm_newstate(grp->fsm, MPCG_STATE_XID7INITI); 2264 + mpc_validate_xid(mpcginfo); 2265 + fsm_event(grp->fsm, MPCG_EVENT_XID2DONE, dev); 2266 + } 2267 + break; 2268 + } 2269 + kfree(mpcginfo); 2270 + 2271 + if (do_debug) { 2272 + ctcm_pr_debug("ctcmpc:%s() %s xid2:%i xid7:%i xidt_p2:%i \n", 2273 + __FUNCTION__, ch->id, 2274 + grp->outstanding_xid2, 2275 + grp->outstanding_xid7, 2276 + grp->outstanding_xid7_p2); 2277 + ctcm_pr_debug("ctcmpc:%s() %s grpstate: %s chanstate: %s \n", 2278 + __FUNCTION__, ch->id, 2279 + fsm_getstate_str(grp->fsm), 2280 + fsm_getstate_str(ch->fsm)); 2281 + } 2282 + return; 2283 + 2284 + } 2285 + 2286 + 2287 + /* 2288 + * MPC Group Station FSM action 2289 + * CTCM_PROTO_MPC only 2290 + */ 2291 + static void mpc_action_rcvd_xid7(fsm_instance *fsm, int event, void *arg) 2292 + { 2293 + struct mpcg_info *mpcginfo = arg; 2294 + struct channel *ch = mpcginfo->ch; 2295 + struct net_device *dev = ch->netdev; 2296 + struct ctcm_priv *priv = dev->priv; 2297 + struct mpc_group *grp = priv->mpcg; 2298 + 2299 + if (do_debug) { 2300 + ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n", 2301 + __FUNCTION__, smp_processor_id(), ch, ch->id); 2302 + 2303 + ctcm_pr_debug("ctcmpc: outstanding_xid7: %i, " 2304 + " outstanding_xid7_p2: %i\n", 2305 + grp->outstanding_xid7, 2306 + grp->outstanding_xid7_p2); 2307 + } 2308 + 2309 + grp->outstanding_xid7--; 2310 + ch->xid_skb->data = ch->xid_skb_data; 2311 + skb_reset_tail_pointer(ch->xid_skb); 2312 + ch->xid_skb->len = 0; 2313 + 2314 + switch (fsm_getstate(grp->fsm)) { 2315 + case MPCG_STATE_XID7INITI: 2316 + fsm_newstate(grp->fsm, MPCG_STATE_XID7INITZ); 2317 + mpc_validate_xid(mpcginfo); 2318 + break; 2319 + case MPCG_STATE_XID7INITW: 2320 + fsm_newstate(grp->fsm, MPCG_STATE_XID7INITX); 2321 + mpc_validate_xid(mpcginfo); 2322 + break; 2323 + case MPCG_STATE_XID7INITZ: 2324 + case MPCG_STATE_XID7INITX: 2325 + if (grp->outstanding_xid7 == 0) { 2326 + if (grp->outstanding_xid7_p2 > 0) { 2327 + grp->outstanding_xid7 = 2328 + grp->outstanding_xid7_p2; 2329 + grp->outstanding_xid7_p2 = 0; 2330 + } else 2331 + fsm_newstate(grp->fsm, MPCG_STATE_XID7INITF); 2332 + 2333 + mpc_validate_xid(mpcginfo); 2334 + fsm_event(grp->fsm, MPCG_EVENT_XID7DONE, dev); 2335 + break; 2336 + } 2337 + mpc_validate_xid(mpcginfo); 2338 + break; 2339 + } 2340 + 2341 + kfree(mpcginfo); 2342 + 2343 + if (do_debug) 2344 + ctcm_pr_debug("ctcmpc exit: %s(): cp=%i ch=0x%p id=%s\n", 2345 + __FUNCTION__, smp_processor_id(), ch, ch->id); 2346 + return; 2347 + 2348 + } 2349 + 2350 + /* 2351 + * mpc_action helper of an MPC Group Station FSM action 2352 + * CTCM_PROTO_MPC only 2353 + */ 2354 + static int mpc_send_qllc_discontact(struct net_device *dev) 2355 + { 2356 + int rc = 0; 2357 + __u32 new_len = 0; 2358 + struct sk_buff *skb; 2359 + struct qllc *qllcptr; 2360 + struct ctcm_priv *priv; 2361 + struct mpc_group *grp; 2362 + 2363 + ctcm_pr_debug("ctcmpc enter: %s()\n", __FUNCTION__); 2364 + 2365 + if (dev == NULL) { 2366 + printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__); 2367 + rc = 1; 2368 + goto done; 2369 + } 2370 + 2371 + priv = dev->priv; 2372 + if (priv == NULL) { 2373 + printk(KERN_INFO "%s() priv=NULL\n", __FUNCTION__); 2374 + rc = 1; 2375 + goto done; 2376 + } 2377 + 2378 + grp = priv->mpcg; 2379 + if (grp == NULL) { 2380 + printk(KERN_INFO "%s() grp=NULL\n", __FUNCTION__); 2381 + rc = 1; 2382 + goto done; 2383 + } 2384 + ctcm_pr_info("ctcmpc: %s() GROUP STATE: %s\n", __FUNCTION__, 2385 + mpcg_state_names[grp->saved_state]); 2386 + 2387 + switch (grp->saved_state) { 2388 + /* 2389 + * establish conn callback function is 2390 + * preferred method to report failure 2391 + */ 2392 + case MPCG_STATE_XID0IOWAIT: 2393 + case MPCG_STATE_XID0IOWAIX: 2394 + case MPCG_STATE_XID7INITI: 2395 + case MPCG_STATE_XID7INITZ: 2396 + case MPCG_STATE_XID2INITW: 2397 + case MPCG_STATE_XID2INITX: 2398 + case MPCG_STATE_XID7INITW: 2399 + case MPCG_STATE_XID7INITX: 2400 + if (grp->estconnfunc) { 2401 + grp->estconnfunc(grp->port_num, -1, 0); 2402 + grp->estconnfunc = NULL; 2403 + break; 2404 + } 2405 + case MPCG_STATE_FLOWC: 2406 + case MPCG_STATE_READY: 2407 + grp->send_qllc_disc = 2; 2408 + new_len = sizeof(struct qllc); 2409 + qllcptr = kzalloc(new_len, gfp_type() | GFP_DMA); 2410 + if (qllcptr == NULL) { 2411 + printk(KERN_INFO 2412 + "ctcmpc: Out of memory in %s()\n", 2413 + dev->name); 2414 + rc = 1; 2415 + goto done; 2416 + } 2417 + 2418 + qllcptr->qllc_address = 0xcc; 2419 + qllcptr->qllc_commands = 0x03; 2420 + 2421 + skb = __dev_alloc_skb(new_len, GFP_ATOMIC); 2422 + 2423 + if (skb == NULL) { 2424 + printk(KERN_INFO "%s Out of memory in mpc_send_qllc\n", 2425 + dev->name); 2426 + priv->stats.rx_dropped++; 2427 + rc = 1; 2428 + kfree(qllcptr); 2429 + goto done; 2430 + } 2431 + 2432 + memcpy(skb_put(skb, new_len), qllcptr, new_len); 2433 + kfree(qllcptr); 2434 + 2435 + if (skb_headroom(skb) < 4) { 2436 + printk(KERN_INFO "ctcmpc: %s() Unable to" 2437 + " build discontact for %s\n", 2438 + __FUNCTION__, dev->name); 2439 + rc = 1; 2440 + dev_kfree_skb_any(skb); 2441 + goto done; 2442 + } 2443 + 2444 + *((__u32 *)skb_push(skb, 4)) = priv->channel[READ]->pdu_seq; 2445 + priv->channel[READ]->pdu_seq++; 2446 + if (do_debug_data) 2447 + ctcm_pr_debug("ctcmpc: %s ToDCM_pdu_seq= %08x\n", 2448 + __FUNCTION__, priv->channel[READ]->pdu_seq); 2449 + 2450 + /* receipt of CC03 resets anticipated sequence number on 2451 + receiving side */ 2452 + priv->channel[READ]->pdu_seq = 0x00; 2453 + skb_reset_mac_header(skb); 2454 + skb->dev = dev; 2455 + skb->protocol = htons(ETH_P_SNAP); 2456 + skb->ip_summed = CHECKSUM_UNNECESSARY; 2457 + 2458 + ctcmpc_dumpit((char *)skb->data, (sizeof(struct qllc) + 4)); 2459 + 2460 + netif_rx(skb); 2461 + break; 2462 + default: 2463 + break; 2464 + 2465 + } 2466 + 2467 + done: 2468 + ctcm_pr_debug("ctcmpc exit: %s()\n", __FUNCTION__); 2469 + return rc; 2470 + } 2471 + /* --- This is the END my friend --- */ 2472 +
+239
drivers/s390/net/ctcm_mpc.h
··· 1 + /* 2 + * drivers/s390/net/ctcm_mpc.h 3 + * 4 + * Copyright IBM Corp. 2007 5 + * Authors: Peter Tiedemann (ptiedem@de.ibm.com) 6 + * 7 + * MPC additions: 8 + * Belinda Thompson (belindat@us.ibm.com) 9 + * Andy Richter (richtera@us.ibm.com) 10 + */ 11 + 12 + #ifndef _CTC_MPC_H_ 13 + #define _CTC_MPC_H_ 14 + 15 + #include <linux/skbuff.h> 16 + #include "fsm.h" 17 + 18 + /* 19 + * MPC external interface 20 + * Note that ctc_mpc_xyz are called with a lock on ................ 21 + */ 22 + 23 + /* port_number is the mpc device 0, 1, 2 etc mpc2 is port_number 2 */ 24 + 25 + /* passive open Just wait for XID2 exchange */ 26 + extern int ctc_mpc_alloc_channel(int port, 27 + void (*callback)(int port_num, int max_write_size)); 28 + /* active open Alloc then send XID2 */ 29 + extern void ctc_mpc_establish_connectivity(int port, 30 + void (*callback)(int port_num, int rc, int max_write_size)); 31 + 32 + extern void ctc_mpc_dealloc_ch(int port); 33 + extern void ctc_mpc_flow_control(int port, int flowc); 34 + 35 + /* 36 + * other MPC Group prototypes and structures 37 + */ 38 + 39 + #define ETH_P_SNA_DIX 0x80D5 40 + 41 + /* 42 + * Declaration of an XID2 43 + * 44 + */ 45 + #define ALLZEROS 0x0000000000000000 46 + 47 + #define XID_FM2 0x20 48 + #define XID2_0 0x00 49 + #define XID2_7 0x07 50 + #define XID2_WRITE_SIDE 0x04 51 + #define XID2_READ_SIDE 0x05 52 + 53 + struct xid2 { 54 + __u8 xid2_type_id; 55 + __u8 xid2_len; 56 + __u32 xid2_adj_id; 57 + __u8 xid2_rlen; 58 + __u8 xid2_resv1; 59 + __u8 xid2_flag1; 60 + __u8 xid2_fmtt; 61 + __u8 xid2_flag4; 62 + __u16 xid2_resv2; 63 + __u8 xid2_tgnum; 64 + __u32 xid2_sender_id; 65 + __u8 xid2_flag2; 66 + __u8 xid2_option; 67 + char xid2_resv3[8]; 68 + __u16 xid2_resv4; 69 + __u8 xid2_dlc_type; 70 + __u16 xid2_resv5; 71 + __u8 xid2_mpc_flag; 72 + __u8 xid2_resv6; 73 + __u16 xid2_buf_len; 74 + char xid2_buffer[255 - (13 * sizeof(__u8) + 75 + 2 * sizeof(__u32) + 76 + 4 * sizeof(__u16) + 77 + 8 * sizeof(char))]; 78 + } __attribute__ ((packed)); 79 + 80 + #define XID2_LENGTH (sizeof(struct xid2)) 81 + 82 + struct th_header { 83 + __u8 th_seg; 84 + __u8 th_ch_flag; 85 + #define TH_HAS_PDU 0xf0 86 + #define TH_IS_XID 0x01 87 + #define TH_SWEEP_REQ 0xfe 88 + #define TH_SWEEP_RESP 0xff 89 + __u8 th_blk_flag; 90 + #define TH_DATA_IS_XID 0x80 91 + #define TH_RETRY 0x40 92 + #define TH_DISCONTACT 0xc0 93 + #define TH_SEG_BLK 0x20 94 + #define TH_LAST_SEG 0x10 95 + #define TH_PDU_PART 0x08 96 + __u8 th_is_xid; /* is 0x01 if this is XID */ 97 + __u32 th_seq_num; 98 + } __attribute__ ((packed)); 99 + 100 + struct th_addon { 101 + __u32 th_last_seq; 102 + __u32 th_resvd; 103 + } __attribute__ ((packed)); 104 + 105 + struct th_sweep { 106 + struct th_header th; 107 + struct th_addon sw; 108 + } __attribute__ ((packed)); 109 + 110 + #define TH_HEADER_LENGTH (sizeof(struct th_header)) 111 + #define TH_SWEEP_LENGTH (sizeof(struct th_sweep)) 112 + 113 + #define PDU_LAST 0x80 114 + #define PDU_CNTL 0x40 115 + #define PDU_FIRST 0x20 116 + 117 + struct pdu { 118 + __u32 pdu_offset; 119 + __u8 pdu_flag; 120 + __u8 pdu_proto; /* 0x01 is APPN SNA */ 121 + __u16 pdu_seq; 122 + } __attribute__ ((packed)); 123 + 124 + #define PDU_HEADER_LENGTH (sizeof(struct pdu)) 125 + 126 + struct qllc { 127 + __u8 qllc_address; 128 + #define QLLC_REQ 0xFF 129 + #define QLLC_RESP 0x00 130 + __u8 qllc_commands; 131 + #define QLLC_DISCONNECT 0x53 132 + #define QLLC_UNSEQACK 0x73 133 + #define QLLC_SETMODE 0x93 134 + #define QLLC_EXCHID 0xBF 135 + } __attribute__ ((packed)); 136 + 137 + 138 + /* 139 + * Definition of one MPC group 140 + */ 141 + 142 + #define MAX_MPCGCHAN 10 143 + #define MPC_XID_TIMEOUT_VALUE 10000 144 + #define MPC_CHANNEL_ADD 0 145 + #define MPC_CHANNEL_REMOVE 1 146 + #define MPC_CHANNEL_ATTN 2 147 + #define XSIDE 1 148 + #define YSIDE 0 149 + 150 + struct mpcg_info { 151 + struct sk_buff *skb; 152 + struct channel *ch; 153 + struct xid2 *xid; 154 + struct th_sweep *sweep; 155 + struct th_header *th; 156 + }; 157 + 158 + struct mpc_group { 159 + struct tasklet_struct mpc_tasklet; 160 + struct tasklet_struct mpc_tasklet2; 161 + int changed_side; 162 + int saved_state; 163 + int channels_terminating; 164 + int out_of_sequence; 165 + int flow_off_called; 166 + int port_num; 167 + int port_persist; 168 + int alloc_called; 169 + __u32 xid2_adj_id; 170 + __u8 xid2_tgnum; 171 + __u32 xid2_sender_id; 172 + int num_channel_paths; 173 + int active_channels[2]; 174 + __u16 group_max_buflen; 175 + int outstanding_xid2; 176 + int outstanding_xid7; 177 + int outstanding_xid7_p2; 178 + int sweep_req_pend_num; 179 + int sweep_rsp_pend_num; 180 + struct sk_buff *xid_skb; 181 + char *xid_skb_data; 182 + struct th_header *xid_th; 183 + struct xid2 *xid; 184 + char *xid_id; 185 + struct th_header *rcvd_xid_th; 186 + struct sk_buff *rcvd_xid_skb; 187 + char *rcvd_xid_data; 188 + __u8 in_sweep; 189 + __u8 roll; 190 + struct xid2 *saved_xid2; 191 + void (*allochanfunc)(int, int); 192 + int allocchan_callback_retries; 193 + void (*estconnfunc)(int, int, int); 194 + int estconn_callback_retries; 195 + int estconn_called; 196 + int xidnogood; 197 + int send_qllc_disc; 198 + fsm_timer timer; 199 + fsm_instance *fsm; /* group xid fsm */ 200 + }; 201 + 202 + #ifdef DEBUGDATA 203 + void ctcmpc_dumpit(char *buf, int len); 204 + #else 205 + static inline void ctcmpc_dumpit(char *buf, int len) 206 + { 207 + } 208 + #endif 209 + 210 + #ifdef DEBUGDATA 211 + /* 212 + * Dump header and first 16 bytes of an sk_buff for debugging purposes. 213 + * 214 + * skb The struct sk_buff to dump. 215 + * offset Offset relative to skb-data, where to start the dump. 216 + */ 217 + void ctcmpc_dump_skb(struct sk_buff *skb, int offset); 218 + #else 219 + static inline void ctcmpc_dump_skb(struct sk_buff *skb, int offset) 220 + {} 221 + #endif 222 + 223 + static inline void ctcmpc_dump32(char *buf, int len) 224 + { 225 + if (len < 32) 226 + ctcmpc_dumpit(buf, len); 227 + else 228 + ctcmpc_dumpit(buf, 32); 229 + } 230 + 231 + int ctcmpc_open(struct net_device *); 232 + void ctcm_ccw_check_rc(struct channel *, int, char *); 233 + void mpc_group_ready(unsigned long adev); 234 + int mpc_channel_action(struct channel *ch, int direction, int action); 235 + void mpc_action_send_discontact(unsigned long thischan); 236 + void mpc_action_discontact(fsm_instance *fi, int event, void *arg); 237 + void ctcmpc_bh(unsigned long thischan); 238 + #endif 239 + /* --- This is the END my friend --- */
+210
drivers/s390/net/ctcm_sysfs.c
··· 1 + /* 2 + * drivers/s390/net/ctcm_sysfs.c 3 + * 4 + * Copyright IBM Corp. 2007, 2007 5 + * Authors: Peter Tiedemann (ptiedem@de.ibm.com) 6 + * 7 + */ 8 + 9 + #undef DEBUG 10 + #undef DEBUGDATA 11 + #undef DEBUGCCW 12 + 13 + #include <linux/sysfs.h> 14 + #include "ctcm_main.h" 15 + 16 + /* 17 + * sysfs attributes 18 + */ 19 + 20 + static ssize_t ctcm_buffer_show(struct device *dev, 21 + struct device_attribute *attr, char *buf) 22 + { 23 + struct ctcm_priv *priv = dev_get_drvdata(dev); 24 + 25 + if (!priv) 26 + return -ENODEV; 27 + return sprintf(buf, "%d\n", priv->buffer_size); 28 + } 29 + 30 + static ssize_t ctcm_buffer_write(struct device *dev, 31 + struct device_attribute *attr, const char *buf, size_t count) 32 + { 33 + struct net_device *ndev; 34 + int bs1; 35 + struct ctcm_priv *priv = dev_get_drvdata(dev); 36 + 37 + if (!(priv && priv->channel[READ] && 38 + (ndev = priv->channel[READ]->netdev))) { 39 + CTCM_DBF_TEXT(SETUP, CTC_DBF_ERROR, "bfnondev"); 40 + return -ENODEV; 41 + } 42 + 43 + sscanf(buf, "%u", &bs1); 44 + if (bs1 > CTCM_BUFSIZE_LIMIT) 45 + goto einval; 46 + if (bs1 < (576 + LL_HEADER_LENGTH + 2)) 47 + goto einval; 48 + priv->buffer_size = bs1; /* just to overwrite the default */ 49 + 50 + if ((ndev->flags & IFF_RUNNING) && 51 + (bs1 < (ndev->mtu + LL_HEADER_LENGTH + 2))) 52 + goto einval; 53 + 54 + priv->channel[READ]->max_bufsize = bs1; 55 + priv->channel[WRITE]->max_bufsize = bs1; 56 + if (!(ndev->flags & IFF_RUNNING)) 57 + ndev->mtu = bs1 - LL_HEADER_LENGTH - 2; 58 + priv->channel[READ]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED; 59 + priv->channel[WRITE]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED; 60 + 61 + CTCM_DBF_DEV(SETUP, ndev, buf); 62 + return count; 63 + 64 + einval: 65 + CTCM_DBF_DEV(SETUP, ndev, "buff_err"); 66 + return -EINVAL; 67 + } 68 + 69 + static void ctcm_print_statistics(struct ctcm_priv *priv) 70 + { 71 + char *sbuf; 72 + char *p; 73 + 74 + if (!priv) 75 + return; 76 + sbuf = kmalloc(2048, GFP_KERNEL); 77 + if (sbuf == NULL) 78 + return; 79 + p = sbuf; 80 + 81 + p += sprintf(p, " Device FSM state: %s\n", 82 + fsm_getstate_str(priv->fsm)); 83 + p += sprintf(p, " RX channel FSM state: %s\n", 84 + fsm_getstate_str(priv->channel[READ]->fsm)); 85 + p += sprintf(p, " TX channel FSM state: %s\n", 86 + fsm_getstate_str(priv->channel[WRITE]->fsm)); 87 + p += sprintf(p, " Max. TX buffer used: %ld\n", 88 + priv->channel[WRITE]->prof.maxmulti); 89 + p += sprintf(p, " Max. chained SKBs: %ld\n", 90 + priv->channel[WRITE]->prof.maxcqueue); 91 + p += sprintf(p, " TX single write ops: %ld\n", 92 + priv->channel[WRITE]->prof.doios_single); 93 + p += sprintf(p, " TX multi write ops: %ld\n", 94 + priv->channel[WRITE]->prof.doios_multi); 95 + p += sprintf(p, " Netto bytes written: %ld\n", 96 + priv->channel[WRITE]->prof.txlen); 97 + p += sprintf(p, " Max. TX IO-time: %ld\n", 98 + priv->channel[WRITE]->prof.tx_time); 99 + 100 + printk(KERN_INFO "Statistics for %s:\n%s", 101 + priv->channel[WRITE]->netdev->name, sbuf); 102 + kfree(sbuf); 103 + return; 104 + } 105 + 106 + static ssize_t stats_show(struct device *dev, 107 + struct device_attribute *attr, char *buf) 108 + { 109 + struct ctcm_priv *priv = dev_get_drvdata(dev); 110 + if (!priv) 111 + return -ENODEV; 112 + ctcm_print_statistics(priv); 113 + return sprintf(buf, "0\n"); 114 + } 115 + 116 + static ssize_t stats_write(struct device *dev, struct device_attribute *attr, 117 + const char *buf, size_t count) 118 + { 119 + struct ctcm_priv *priv = dev_get_drvdata(dev); 120 + if (!priv) 121 + return -ENODEV; 122 + /* Reset statistics */ 123 + memset(&priv->channel[WRITE]->prof, 0, 124 + sizeof(priv->channel[WRITE]->prof)); 125 + return count; 126 + } 127 + 128 + static ssize_t ctcm_proto_show(struct device *dev, 129 + struct device_attribute *attr, char *buf) 130 + { 131 + struct ctcm_priv *priv = dev_get_drvdata(dev); 132 + if (!priv) 133 + return -ENODEV; 134 + 135 + return sprintf(buf, "%d\n", priv->protocol); 136 + } 137 + 138 + static ssize_t ctcm_proto_store(struct device *dev, 139 + struct device_attribute *attr, const char *buf, size_t count) 140 + { 141 + int value; 142 + struct ctcm_priv *priv = dev_get_drvdata(dev); 143 + 144 + if (!priv) 145 + return -ENODEV; 146 + sscanf(buf, "%u", &value); 147 + if (!((value == CTCM_PROTO_S390) || 148 + (value == CTCM_PROTO_LINUX) || 149 + (value == CTCM_PROTO_MPC) || 150 + (value == CTCM_PROTO_OS390))) 151 + return -EINVAL; 152 + priv->protocol = value; 153 + CTCM_DBF_DEV(SETUP, dev, buf); 154 + 155 + return count; 156 + } 157 + 158 + static ssize_t ctcm_type_show(struct device *dev, 159 + struct device_attribute *attr, char *buf) 160 + { 161 + struct ccwgroup_device *cgdev; 162 + 163 + cgdev = to_ccwgroupdev(dev); 164 + if (!cgdev) 165 + return -ENODEV; 166 + 167 + return sprintf(buf, "%s\n", 168 + cu3088_type[cgdev->cdev[0]->id.driver_info]); 169 + } 170 + 171 + static DEVICE_ATTR(buffer, 0644, ctcm_buffer_show, ctcm_buffer_write); 172 + static DEVICE_ATTR(protocol, 0644, ctcm_proto_show, ctcm_proto_store); 173 + static DEVICE_ATTR(type, 0444, ctcm_type_show, NULL); 174 + static DEVICE_ATTR(stats, 0644, stats_show, stats_write); 175 + 176 + static struct attribute *ctcm_attr[] = { 177 + &dev_attr_protocol.attr, 178 + &dev_attr_type.attr, 179 + &dev_attr_buffer.attr, 180 + NULL, 181 + }; 182 + 183 + static struct attribute_group ctcm_attr_group = { 184 + .attrs = ctcm_attr, 185 + }; 186 + 187 + int ctcm_add_attributes(struct device *dev) 188 + { 189 + int rc; 190 + 191 + rc = device_create_file(dev, &dev_attr_stats); 192 + 193 + return rc; 194 + } 195 + 196 + void ctcm_remove_attributes(struct device *dev) 197 + { 198 + device_remove_file(dev, &dev_attr_stats); 199 + } 200 + 201 + int ctcm_add_files(struct device *dev) 202 + { 203 + return sysfs_create_group(&dev->kobj, &ctcm_attr_group); 204 + } 205 + 206 + void ctcm_remove_files(struct device *dev) 207 + { 208 + sysfs_remove_group(&dev->kobj, &ctcm_attr_group); 209 + } 210 +