brintos

brintos / linux-shallow public Read only

0
0
Text · 52.0 KiB · 039e18d Raw
2084 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * IUCV network driver4 *5 * Copyright IBM Corp. 2001, 20096 *7 * Author(s):8 *	Original netiucv driver:9 *		Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)10 *	Sysfs integration and all bugs therein:11 *		Cornelia Huck (cornelia.huck@de.ibm.com)12 *	PM functions:13 *		Ursula Braun (ursula.braun@de.ibm.com)14 *15 * Documentation used:16 *  the source of the original IUCV driver by:17 *    Stefan Hegewald <hegewald@de.ibm.com>18 *    Hartmut Penner <hpenner@de.ibm.com>19 *    Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)20 *    Martin Schwidefsky (schwidefsky@de.ibm.com)21 *    Alan Altmark (Alan_Altmark@us.ibm.com)  Sept. 200022 */23 24#define KMSG_COMPONENT "netiucv"25#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt26 27#undef DEBUG28 29#include <linux/module.h>30#include <linux/init.h>31#include <linux/kernel.h>32#include <linux/slab.h>33#include <linux/errno.h>34#include <linux/types.h>35#include <linux/interrupt.h>36#include <linux/timer.h>37#include <linux/bitops.h>38 39#include <linux/signal.h>40#include <linux/string.h>41#include <linux/device.h>42 43#include <linux/ip.h>44#include <linux/if_arp.h>45#include <linux/tcp.h>46#include <linux/skbuff.h>47#include <linux/ctype.h>48#include <net/dst.h>49 50#include <linux/io.h>51#include <linux/uaccess.h>52#include <asm/ebcdic.h>53 54#include <net/iucv/iucv.h>55#include "fsm.h"56 57MODULE_AUTHOR58    ("(C) 2001 IBM Corporation by Fritz Elfert (felfert@millenux.com)");59MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver");60 61/*62 * Debug Facility stuff63 */64#define IUCV_DBF_SETUP_NAME "iucv_setup"65#define IUCV_DBF_SETUP_LEN 6466#define IUCV_DBF_SETUP_PAGES 267#define IUCV_DBF_SETUP_NR_AREAS 168#define IUCV_DBF_SETUP_LEVEL 369 70#define IUCV_DBF_DATA_NAME "iucv_data"71#define IUCV_DBF_DATA_LEN 12872#define IUCV_DBF_DATA_PAGES 273#define IUCV_DBF_DATA_NR_AREAS 174#define IUCV_DBF_DATA_LEVEL 275 76#define IUCV_DBF_TRACE_NAME "iucv_trace"77#define IUCV_DBF_TRACE_LEN 1678#define IUCV_DBF_TRACE_PAGES 479#define IUCV_DBF_TRACE_NR_AREAS 180#define IUCV_DBF_TRACE_LEVEL 381 82#define IUCV_DBF_TEXT(name,level,text) \83	do { \84		debug_text_event(iucv_dbf_##name,level,text); \85	} while (0)86 87#define IUCV_DBF_HEX(name,level,addr,len) \88	do { \89		debug_event(iucv_dbf_##name,level,(void*)(addr),len); \90	} while (0)91 92DECLARE_PER_CPU(char[256], iucv_dbf_txt_buf);93 94#define IUCV_DBF_TEXT_(name, level, text...) \95	do { \96		if (debug_level_enabled(iucv_dbf_##name, level)) { \97			char* __buf = get_cpu_var(iucv_dbf_txt_buf); \98			sprintf(__buf, text); \99			debug_text_event(iucv_dbf_##name, level, __buf); \100			put_cpu_var(iucv_dbf_txt_buf); \101		} \102	} while (0)103 104#define IUCV_DBF_SPRINTF(name,level,text...) \105	do { \106		debug_sprintf_event(iucv_dbf_trace, level, ##text ); \107		debug_sprintf_event(iucv_dbf_trace, level, text ); \108	} while (0)109 110/*111 * some more debug stuff112 */113#define PRINTK_HEADER " iucv: "       /* for debugging */114 115static struct device_driver netiucv_driver = {116	.owner = THIS_MODULE,117	.name = "netiucv",118	.bus  = &iucv_bus,119};120 121/*122 * Per connection profiling data123 */124struct connection_profile {125	unsigned long maxmulti;126	unsigned long maxcqueue;127	unsigned long doios_single;128	unsigned long doios_multi;129	unsigned long txlen;130	unsigned long tx_time;131	unsigned long send_stamp;132	unsigned long tx_pending;133	unsigned long tx_max_pending;134};135 136/*137 * Representation of one iucv connection138 */139struct iucv_connection {140	struct list_head	  list;141	struct iucv_path	  *path;142	struct sk_buff            *rx_buff;143	struct sk_buff            *tx_buff;144	struct sk_buff_head       collect_queue;145	struct sk_buff_head	  commit_queue;146	spinlock_t                collect_lock;147	int                       collect_len;148	int                       max_buffsize;149	fsm_timer                 timer;150	fsm_instance              *fsm;151	struct net_device         *netdev;152	struct connection_profile prof;153	char                      userid[9];154	char			  userdata[17];155};156 157/*158 * Linked list of all connection structs.159 */160static LIST_HEAD(iucv_connection_list);161static DEFINE_RWLOCK(iucv_connection_rwlock);162 163/*164 * Representation of event-data for the165 * connection state machine.166 */167struct iucv_event {168	struct iucv_connection *conn;169	void                   *data;170};171 172/*173 * Private part of the network device structure174 */175struct netiucv_priv {176	struct net_device_stats stats;177	unsigned long           tbusy;178	fsm_instance            *fsm;179        struct iucv_connection  *conn;180	struct device           *dev;181};182 183/*184 * Link level header for a packet.185 */186struct ll_header {187	u16 next;188};189 190#define NETIUCV_HDRLEN		 (sizeof(struct ll_header))191#define NETIUCV_BUFSIZE_MAX	 65537192#define NETIUCV_BUFSIZE_DEFAULT  NETIUCV_BUFSIZE_MAX193#define NETIUCV_MTU_MAX          (NETIUCV_BUFSIZE_MAX - NETIUCV_HDRLEN)194#define NETIUCV_MTU_DEFAULT      9216195#define NETIUCV_QUEUELEN_DEFAULT 50196#define NETIUCV_TIMEOUT_5SEC     5000197 198/*199 * Compatibility macros for busy handling200 * of network devices.201 */202static void netiucv_clear_busy(struct net_device *dev)203{204	struct netiucv_priv *priv = netdev_priv(dev);205	clear_bit(0, &priv->tbusy);206	netif_wake_queue(dev);207}208 209static int netiucv_test_and_set_busy(struct net_device *dev)210{211	struct netiucv_priv *priv = netdev_priv(dev);212	netif_stop_queue(dev);213	return test_and_set_bit(0, &priv->tbusy);214}215 216static u8 iucvMagic_ascii[16] = {217	0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,218	0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20219};220 221static u8 iucvMagic_ebcdic[16] = {222	0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,223	0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40224};225 226/*227 * Convert an iucv userId to its printable228 * form (strip whitespace at end).229 *230 * @param An iucv userId231 *232 * @returns The printable string (static data!!)233 */234static char *netiucv_printname(char *name, int len)235{236	static char tmp[17];237	char *p = tmp;238	memcpy(tmp, name, len);239	tmp[len] = '\0';240	while (*p && ((p - tmp) < len) && (!isspace(*p)))241		p++;242	*p = '\0';243	return tmp;244}245 246static char *netiucv_printuser(struct iucv_connection *conn)247{248	static char tmp_uid[9];249	static char tmp_udat[17];250	static char buf[100];251 252	if (memcmp(conn->userdata, iucvMagic_ebcdic, 16)) {253		tmp_uid[8] = '\0';254		tmp_udat[16] = '\0';255		memcpy(tmp_uid, netiucv_printname(conn->userid, 8), 8);256		memcpy(tmp_udat, conn->userdata, 16);257		EBCASC(tmp_udat, 16);258		memcpy(tmp_udat, netiucv_printname(tmp_udat, 16), 16);259		sprintf(buf, "%s.%s", tmp_uid, tmp_udat);260		return buf;261	} else262		return netiucv_printname(conn->userid, 8);263}264 265/*266 * States of the interface statemachine.267 */268enum dev_states {269	DEV_STATE_STOPPED,270	DEV_STATE_STARTWAIT,271	DEV_STATE_STOPWAIT,272	DEV_STATE_RUNNING,273	/*274	 * MUST be always the last element!!275	 */276	NR_DEV_STATES277};278 279static const char *dev_state_names[] = {280	"Stopped",281	"StartWait",282	"StopWait",283	"Running",284};285 286/*287 * Events of the interface statemachine.288 */289enum dev_events {290	DEV_EVENT_START,291	DEV_EVENT_STOP,292	DEV_EVENT_CONUP,293	DEV_EVENT_CONDOWN,294	/*295	 * MUST be always the last element!!296	 */297	NR_DEV_EVENTS298};299 300static const char *dev_event_names[] = {301	"Start",302	"Stop",303	"Connection up",304	"Connection down",305};306 307/*308 * Events of the connection statemachine309 */310enum conn_events {311	/*312	 * Events, representing callbacks from313	 * lowlevel iucv layer)314	 */315	CONN_EVENT_CONN_REQ,316	CONN_EVENT_CONN_ACK,317	CONN_EVENT_CONN_REJ,318	CONN_EVENT_CONN_SUS,319	CONN_EVENT_CONN_RES,320	CONN_EVENT_RX,321	CONN_EVENT_TXDONE,322 323	/*324	 * Events, representing errors return codes from325	 * calls to lowlevel iucv layer326	 */327 328	/*329	 * Event, representing timer expiry.330	 */331	CONN_EVENT_TIMER,332 333	/*334	 * Events, representing commands from upper levels.335	 */336	CONN_EVENT_START,337	CONN_EVENT_STOP,338 339	/*340	 * MUST be always the last element!!341	 */342	NR_CONN_EVENTS,343};344 345static const char *conn_event_names[] = {346	"Remote connection request",347	"Remote connection acknowledge",348	"Remote connection reject",349	"Connection suspended",350	"Connection resumed",351	"Data received",352	"Data sent",353 354	"Timer",355 356	"Start",357	"Stop",358};359 360/*361 * States of the connection statemachine.362 */363enum conn_states {364	/*365	 * Connection not assigned to any device,366	 * initial state, invalid367	 */368	CONN_STATE_INVALID,369 370	/*371	 * Userid assigned but not operating372	 */373	CONN_STATE_STOPPED,374 375	/*376	 * Connection registered,377	 * no connection request sent yet,378	 * no connection request received379	 */380	CONN_STATE_STARTWAIT,381 382	/*383	 * Connection registered and connection request sent,384	 * no acknowledge and no connection request received yet.385	 */386	CONN_STATE_SETUPWAIT,387 388	/*389	 * Connection up and running idle390	 */391	CONN_STATE_IDLE,392 393	/*394	 * Data sent, awaiting CONN_EVENT_TXDONE395	 */396	CONN_STATE_TX,397 398	/*399	 * Error during registration.400	 */401	CONN_STATE_REGERR,402 403	/*404	 * Error during registration.405	 */406	CONN_STATE_CONNERR,407 408	/*409	 * MUST be always the last element!!410	 */411	NR_CONN_STATES,412};413 414static const char *conn_state_names[] = {415	"Invalid",416	"Stopped",417	"StartWait",418	"SetupWait",419	"Idle",420	"TX",421	"Terminating",422	"Registration error",423	"Connect error",424};425 426 427/*428 * Debug Facility Stuff429 */430static debug_info_t *iucv_dbf_setup = NULL;431static debug_info_t *iucv_dbf_data = NULL;432static debug_info_t *iucv_dbf_trace = NULL;433 434DEFINE_PER_CPU(char[256], iucv_dbf_txt_buf);435 436static void iucv_unregister_dbf_views(void)437{438	debug_unregister(iucv_dbf_setup);439	debug_unregister(iucv_dbf_data);440	debug_unregister(iucv_dbf_trace);441}442static int iucv_register_dbf_views(void)443{444	iucv_dbf_setup = debug_register(IUCV_DBF_SETUP_NAME,445					IUCV_DBF_SETUP_PAGES,446					IUCV_DBF_SETUP_NR_AREAS,447					IUCV_DBF_SETUP_LEN);448	iucv_dbf_data = debug_register(IUCV_DBF_DATA_NAME,449				       IUCV_DBF_DATA_PAGES,450				       IUCV_DBF_DATA_NR_AREAS,451				       IUCV_DBF_DATA_LEN);452	iucv_dbf_trace = debug_register(IUCV_DBF_TRACE_NAME,453					IUCV_DBF_TRACE_PAGES,454					IUCV_DBF_TRACE_NR_AREAS,455					IUCV_DBF_TRACE_LEN);456 457	if ((iucv_dbf_setup == NULL) || (iucv_dbf_data == NULL) ||458	    (iucv_dbf_trace == NULL)) {459		iucv_unregister_dbf_views();460		return -ENOMEM;461	}462	debug_register_view(iucv_dbf_setup, &debug_hex_ascii_view);463	debug_set_level(iucv_dbf_setup, IUCV_DBF_SETUP_LEVEL);464 465	debug_register_view(iucv_dbf_data, &debug_hex_ascii_view);466	debug_set_level(iucv_dbf_data, IUCV_DBF_DATA_LEVEL);467 468	debug_register_view(iucv_dbf_trace, &debug_hex_ascii_view);469	debug_set_level(iucv_dbf_trace, IUCV_DBF_TRACE_LEVEL);470 471	return 0;472}473 474/*475 * Callback-wrappers, called from lowlevel iucv layer.476 */477 478static void netiucv_callback_rx(struct iucv_path *path,479				struct iucv_message *msg)480{481	struct iucv_connection *conn = path->private;482	struct iucv_event ev;483 484	ev.conn = conn;485	ev.data = msg;486	fsm_event(conn->fsm, CONN_EVENT_RX, &ev);487}488 489static void netiucv_callback_txdone(struct iucv_path *path,490				    struct iucv_message *msg)491{492	struct iucv_connection *conn = path->private;493	struct iucv_event ev;494 495	ev.conn = conn;496	ev.data = msg;497	fsm_event(conn->fsm, CONN_EVENT_TXDONE, &ev);498}499 500static void netiucv_callback_connack(struct iucv_path *path, u8 ipuser[16])501{502	struct iucv_connection *conn = path->private;503 504	fsm_event(conn->fsm, CONN_EVENT_CONN_ACK, conn);505}506 507static int netiucv_callback_connreq(struct iucv_path *path, u8 *ipvmid,508				    u8 *ipuser)509{510	struct iucv_connection *conn = path->private;511	struct iucv_event ev;512	static char tmp_user[9];513	static char tmp_udat[17];514	int rc;515 516	rc = -EINVAL;517	memcpy(tmp_user, netiucv_printname(ipvmid, 8), 8);518	memcpy(tmp_udat, ipuser, 16);519	EBCASC(tmp_udat, 16);520	read_lock_bh(&iucv_connection_rwlock);521	list_for_each_entry(conn, &iucv_connection_list, list) {522		if (strncmp(ipvmid, conn->userid, 8) ||523		    strncmp(ipuser, conn->userdata, 16))524			continue;525		/* Found a matching connection for this path. */526		conn->path = path;527		ev.conn = conn;528		ev.data = path;529		fsm_event(conn->fsm, CONN_EVENT_CONN_REQ, &ev);530		rc = 0;531	}532	IUCV_DBF_TEXT_(setup, 2, "Connection requested for %s.%s\n",533		       tmp_user, netiucv_printname(tmp_udat, 16));534	read_unlock_bh(&iucv_connection_rwlock);535	return rc;536}537 538static void netiucv_callback_connrej(struct iucv_path *path, u8 *ipuser)539{540	struct iucv_connection *conn = path->private;541 542	fsm_event(conn->fsm, CONN_EVENT_CONN_REJ, conn);543}544 545static void netiucv_callback_connsusp(struct iucv_path *path, u8 *ipuser)546{547	struct iucv_connection *conn = path->private;548 549	fsm_event(conn->fsm, CONN_EVENT_CONN_SUS, conn);550}551 552static void netiucv_callback_connres(struct iucv_path *path, u8 *ipuser)553{554	struct iucv_connection *conn = path->private;555 556	fsm_event(conn->fsm, CONN_EVENT_CONN_RES, conn);557}558 559/*560 * NOP action for statemachines561 */562static void netiucv_action_nop(fsm_instance *fi, int event, void *arg)563{564}565 566/*567 * Actions of the connection statemachine568 */569 570/*571 * netiucv_unpack_skb572 * @conn: The connection where this skb has been received.573 * @pskb: The received skb.574 *575 * Unpack a just received skb and hand it over to upper layers.576 * Helper function for conn_action_rx.577 */578static void netiucv_unpack_skb(struct iucv_connection *conn,579			       struct sk_buff *pskb)580{581	struct net_device     *dev = conn->netdev;582	struct netiucv_priv   *privptr = netdev_priv(dev);583	u16 offset = 0;584 585	skb_put(pskb, NETIUCV_HDRLEN);586	pskb->dev = dev;587	pskb->ip_summed = CHECKSUM_NONE;588	pskb->protocol = cpu_to_be16(ETH_P_IP);589 590	while (1) {591		struct sk_buff *skb;592		struct ll_header *header = (struct ll_header *) pskb->data;593 594		if (!header->next)595			break;596 597		skb_pull(pskb, NETIUCV_HDRLEN);598		header->next -= offset;599		offset += header->next;600		header->next -= NETIUCV_HDRLEN;601		if (skb_tailroom(pskb) < header->next) {602			IUCV_DBF_TEXT_(data, 2, "Illegal next field: %d > %d\n",603				header->next, skb_tailroom(pskb));604			return;605		}606		skb_put(pskb, header->next);607		skb_reset_mac_header(pskb);608		skb = dev_alloc_skb(pskb->len);609		if (!skb) {610			IUCV_DBF_TEXT(data, 2,611				"Out of memory in netiucv_unpack_skb\n");612			privptr->stats.rx_dropped++;613			return;614		}615		skb_copy_from_linear_data(pskb, skb_put(skb, pskb->len),616					  pskb->len);617		skb_reset_mac_header(skb);618		skb->dev = pskb->dev;619		skb->protocol = pskb->protocol;620		pskb->ip_summed = CHECKSUM_UNNECESSARY;621		privptr->stats.rx_packets++;622		privptr->stats.rx_bytes += skb->len;623		netif_rx(skb);624		skb_pull(pskb, header->next);625		skb_put(pskb, NETIUCV_HDRLEN);626	}627}628 629static void conn_action_rx(fsm_instance *fi, int event, void *arg)630{631	struct iucv_event *ev = arg;632	struct iucv_connection *conn = ev->conn;633	struct iucv_message *msg = ev->data;634	struct netiucv_priv *privptr = netdev_priv(conn->netdev);635	int rc;636 637	IUCV_DBF_TEXT(trace, 4, __func__);638 639	if (!conn->netdev) {640		iucv_message_reject(conn->path, msg);641		IUCV_DBF_TEXT(data, 2,642			      "Received data for unlinked connection\n");643		return;644	}645	if (msg->length > conn->max_buffsize) {646		iucv_message_reject(conn->path, msg);647		privptr->stats.rx_dropped++;648		IUCV_DBF_TEXT_(data, 2, "msglen %d > max_buffsize %d\n",649			       msg->length, conn->max_buffsize);650		return;651	}652	conn->rx_buff->data = conn->rx_buff->head;653	skb_reset_tail_pointer(conn->rx_buff);654	conn->rx_buff->len = 0;655	rc = iucv_message_receive(conn->path, msg, 0, conn->rx_buff->data,656				  msg->length, NULL);657	if (rc || msg->length < 5) {658		privptr->stats.rx_errors++;659		IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_receive\n", rc);660		return;661	}662	netiucv_unpack_skb(conn, conn->rx_buff);663}664 665static void conn_action_txdone(fsm_instance *fi, int event, void *arg)666{667	struct iucv_event *ev = arg;668	struct iucv_connection *conn = ev->conn;669	struct iucv_message *msg = ev->data;670	struct iucv_message txmsg;671	struct netiucv_priv *privptr = NULL;672	u32 single_flag = msg->tag;673	u32 txbytes = 0;674	u32 txpackets = 0;675	u32 stat_maxcq = 0;676	struct sk_buff *skb;677	unsigned long saveflags;678	struct ll_header header;679	int rc;680 681	IUCV_DBF_TEXT(trace, 4, __func__);682 683	if (!conn || !conn->netdev) {684		IUCV_DBF_TEXT(data, 2,685			      "Send confirmation for unlinked connection\n");686		return;687	}688	privptr = netdev_priv(conn->netdev);689	conn->prof.tx_pending--;690	if (single_flag) {691		if ((skb = skb_dequeue(&conn->commit_queue))) {692			refcount_dec(&skb->users);693			if (privptr) {694				privptr->stats.tx_packets++;695				privptr->stats.tx_bytes +=696					(skb->len - NETIUCV_HDRLEN697						  - NETIUCV_HDRLEN);698			}699			dev_kfree_skb_any(skb);700		}701	}702	conn->tx_buff->data = conn->tx_buff->head;703	skb_reset_tail_pointer(conn->tx_buff);704	conn->tx_buff->len = 0;705	spin_lock_irqsave(&conn->collect_lock, saveflags);706	while ((skb = skb_dequeue(&conn->collect_queue))) {707		header.next = conn->tx_buff->len + skb->len + NETIUCV_HDRLEN;708		skb_put_data(conn->tx_buff, &header, NETIUCV_HDRLEN);709		skb_copy_from_linear_data(skb,710					  skb_put(conn->tx_buff, skb->len),711					  skb->len);712		txbytes += skb->len;713		txpackets++;714		stat_maxcq++;715		refcount_dec(&skb->users);716		dev_kfree_skb_any(skb);717	}718	if (conn->collect_len > conn->prof.maxmulti)719		conn->prof.maxmulti = conn->collect_len;720	conn->collect_len = 0;721	spin_unlock_irqrestore(&conn->collect_lock, saveflags);722	if (conn->tx_buff->len == 0) {723		fsm_newstate(fi, CONN_STATE_IDLE);724		return;725	}726 727	header.next = 0;728	skb_put_data(conn->tx_buff, &header, NETIUCV_HDRLEN);729	conn->prof.send_stamp = jiffies;730	txmsg.class = 0;731	txmsg.tag = 0;732	rc = iucv_message_send(conn->path, &txmsg, 0, 0,733			       conn->tx_buff->data, conn->tx_buff->len);734	conn->prof.doios_multi++;735	conn->prof.txlen += conn->tx_buff->len;736	conn->prof.tx_pending++;737	if (conn->prof.tx_pending > conn->prof.tx_max_pending)738		conn->prof.tx_max_pending = conn->prof.tx_pending;739	if (rc) {740		conn->prof.tx_pending--;741		fsm_newstate(fi, CONN_STATE_IDLE);742		if (privptr)743			privptr->stats.tx_errors += txpackets;744		IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_send\n", rc);745	} else {746		if (privptr) {747			privptr->stats.tx_packets += txpackets;748			privptr->stats.tx_bytes += txbytes;749		}750		if (stat_maxcq > conn->prof.maxcqueue)751			conn->prof.maxcqueue = stat_maxcq;752	}753}754 755static struct iucv_handler netiucv_handler = {756	.path_pending	  = netiucv_callback_connreq,757	.path_complete	  = netiucv_callback_connack,758	.path_severed	  = netiucv_callback_connrej,759	.path_quiesced	  = netiucv_callback_connsusp,760	.path_resumed	  = netiucv_callback_connres,761	.message_pending  = netiucv_callback_rx,762	.message_complete = netiucv_callback_txdone,763};764 765static void conn_action_connaccept(fsm_instance *fi, int event, void *arg)766{767	struct iucv_event *ev = arg;768	struct iucv_connection *conn = ev->conn;769	struct iucv_path *path = ev->data;770	struct net_device *netdev = conn->netdev;771	struct netiucv_priv *privptr = netdev_priv(netdev);772	int rc;773 774	IUCV_DBF_TEXT(trace, 3, __func__);775 776	conn->path = path;777	path->msglim = NETIUCV_QUEUELEN_DEFAULT;778	path->flags = 0;779	rc = iucv_path_accept(path, &netiucv_handler, conn->userdata , conn);780	if (rc) {781		IUCV_DBF_TEXT_(setup, 2, "rc %d from iucv_accept", rc);782		return;783	}784	fsm_newstate(fi, CONN_STATE_IDLE);785	netdev->tx_queue_len = conn->path->msglim;786	fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev);787}788 789static void conn_action_connreject(fsm_instance *fi, int event, void *arg)790{791	struct iucv_event *ev = arg;792	struct iucv_path *path = ev->data;793 794	IUCV_DBF_TEXT(trace, 3, __func__);795	iucv_path_sever(path, NULL);796}797 798static void conn_action_connack(fsm_instance *fi, int event, void *arg)799{800	struct iucv_connection *conn = arg;801	struct net_device *netdev = conn->netdev;802	struct netiucv_priv *privptr = netdev_priv(netdev);803 804	IUCV_DBF_TEXT(trace, 3, __func__);805	fsm_deltimer(&conn->timer);806	fsm_newstate(fi, CONN_STATE_IDLE);807	netdev->tx_queue_len = conn->path->msglim;808	fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev);809}810 811static void conn_action_conntimsev(fsm_instance *fi, int event, void *arg)812{813	struct iucv_connection *conn = arg;814 815	IUCV_DBF_TEXT(trace, 3, __func__);816	fsm_deltimer(&conn->timer);817	iucv_path_sever(conn->path, conn->userdata);818	fsm_newstate(fi, CONN_STATE_STARTWAIT);819}820 821static void conn_action_connsever(fsm_instance *fi, int event, void *arg)822{823	struct iucv_connection *conn = arg;824	struct net_device *netdev = conn->netdev;825	struct netiucv_priv *privptr = netdev_priv(netdev);826 827	IUCV_DBF_TEXT(trace, 3, __func__);828 829	fsm_deltimer(&conn->timer);830	iucv_path_sever(conn->path, conn->userdata);831	dev_info(privptr->dev, "The peer z/VM guest %s has closed the "832			       "connection\n", netiucv_printuser(conn));833	IUCV_DBF_TEXT(data, 2,834		      "conn_action_connsever: Remote dropped connection\n");835	fsm_newstate(fi, CONN_STATE_STARTWAIT);836	fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev);837}838 839static void conn_action_start(fsm_instance *fi, int event, void *arg)840{841	struct iucv_connection *conn = arg;842	struct net_device *netdev = conn->netdev;843	struct netiucv_priv *privptr = netdev_priv(netdev);844	int rc;845 846	IUCV_DBF_TEXT(trace, 3, __func__);847 848	fsm_newstate(fi, CONN_STATE_STARTWAIT);849 850	/*851	 * We must set the state before calling iucv_connect because the852	 * callback handler could be called at any point after the connection853	 * request is sent854	 */855 856	fsm_newstate(fi, CONN_STATE_SETUPWAIT);857	conn->path = iucv_path_alloc(NETIUCV_QUEUELEN_DEFAULT, 0, GFP_KERNEL);858	IUCV_DBF_TEXT_(setup, 2, "%s: connecting to %s ...\n",859		netdev->name, netiucv_printuser(conn));860 861	rc = iucv_path_connect(conn->path, &netiucv_handler, conn->userid,862			       NULL, conn->userdata, conn);863	switch (rc) {864	case 0:865		netdev->tx_queue_len = conn->path->msglim;866		fsm_addtimer(&conn->timer, NETIUCV_TIMEOUT_5SEC,867			     CONN_EVENT_TIMER, conn);868		return;869	case 11:870		dev_warn(privptr->dev,871			"The IUCV device failed to connect to z/VM guest %s\n",872			netiucv_printname(conn->userid, 8));873		fsm_newstate(fi, CONN_STATE_STARTWAIT);874		break;875	case 12:876		dev_warn(privptr->dev,877			"The IUCV device failed to connect to the peer on z/VM"878			" guest %s\n", netiucv_printname(conn->userid, 8));879		fsm_newstate(fi, CONN_STATE_STARTWAIT);880		break;881	case 13:882		dev_err(privptr->dev,883			"Connecting the IUCV device would exceed the maximum"884			" number of IUCV connections\n");885		fsm_newstate(fi, CONN_STATE_CONNERR);886		break;887	case 14:888		dev_err(privptr->dev,889			"z/VM guest %s has too many IUCV connections"890			" to connect with the IUCV device\n",891			netiucv_printname(conn->userid, 8));892		fsm_newstate(fi, CONN_STATE_CONNERR);893		break;894	case 15:895		dev_err(privptr->dev,896			"The IUCV device cannot connect to a z/VM guest with no"897			" IUCV authorization\n");898		fsm_newstate(fi, CONN_STATE_CONNERR);899		break;900	default:901		dev_err(privptr->dev,902			"Connecting the IUCV device failed with error %d\n",903			rc);904		fsm_newstate(fi, CONN_STATE_CONNERR);905		break;906	}907	IUCV_DBF_TEXT_(setup, 5, "iucv_connect rc is %d\n", rc);908	kfree(conn->path);909	conn->path = NULL;910}911 912static void netiucv_purge_skb_queue(struct sk_buff_head *q)913{914	struct sk_buff *skb;915 916	while ((skb = skb_dequeue(q))) {917		refcount_dec(&skb->users);918		dev_kfree_skb_any(skb);919	}920}921 922static void conn_action_stop(fsm_instance *fi, int event, void *arg)923{924	struct iucv_event *ev = arg;925	struct iucv_connection *conn = ev->conn;926	struct net_device *netdev = conn->netdev;927	struct netiucv_priv *privptr = netdev_priv(netdev);928 929	IUCV_DBF_TEXT(trace, 3, __func__);930 931	fsm_deltimer(&conn->timer);932	fsm_newstate(fi, CONN_STATE_STOPPED);933	netiucv_purge_skb_queue(&conn->collect_queue);934	if (conn->path) {935		IUCV_DBF_TEXT(trace, 5, "calling iucv_path_sever\n");936		iucv_path_sever(conn->path, conn->userdata);937		kfree(conn->path);938		conn->path = NULL;939	}940	netiucv_purge_skb_queue(&conn->commit_queue);941	fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev);942}943 944static void conn_action_inval(fsm_instance *fi, int event, void *arg)945{946	struct iucv_connection *conn = arg;947	struct net_device *netdev = conn->netdev;948 949	IUCV_DBF_TEXT_(data, 2, "%s('%s'): conn_action_inval called\n",950		netdev->name, conn->userid);951}952 953static const fsm_node conn_fsm[] = {954	{ CONN_STATE_INVALID,   CONN_EVENT_START,    conn_action_inval      },955	{ CONN_STATE_STOPPED,   CONN_EVENT_START,    conn_action_start      },956 957	{ CONN_STATE_STOPPED,   CONN_EVENT_STOP,     conn_action_stop       },958	{ CONN_STATE_STARTWAIT, CONN_EVENT_STOP,     conn_action_stop       },959	{ CONN_STATE_SETUPWAIT, CONN_EVENT_STOP,     conn_action_stop       },960	{ CONN_STATE_IDLE,      CONN_EVENT_STOP,     conn_action_stop       },961	{ CONN_STATE_TX,        CONN_EVENT_STOP,     conn_action_stop       },962	{ CONN_STATE_REGERR,    CONN_EVENT_STOP,     conn_action_stop       },963	{ CONN_STATE_CONNERR,   CONN_EVENT_STOP,     conn_action_stop       },964 965	{ CONN_STATE_STOPPED,   CONN_EVENT_CONN_REQ, conn_action_connreject },966        { CONN_STATE_STARTWAIT, CONN_EVENT_CONN_REQ, conn_action_connaccept },967	{ CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_REQ, conn_action_connaccept },968	{ CONN_STATE_IDLE,      CONN_EVENT_CONN_REQ, conn_action_connreject },969	{ CONN_STATE_TX,        CONN_EVENT_CONN_REQ, conn_action_connreject },970 971	{ CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_ACK, conn_action_connack    },972	{ CONN_STATE_SETUPWAIT, CONN_EVENT_TIMER,    conn_action_conntimsev },973 974	{ CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_REJ, conn_action_connsever  },975	{ CONN_STATE_IDLE,      CONN_EVENT_CONN_REJ, conn_action_connsever  },976	{ CONN_STATE_TX,        CONN_EVENT_CONN_REJ, conn_action_connsever  },977 978	{ CONN_STATE_IDLE,      CONN_EVENT_RX,       conn_action_rx         },979	{ CONN_STATE_TX,        CONN_EVENT_RX,       conn_action_rx         },980 981	{ CONN_STATE_TX,        CONN_EVENT_TXDONE,   conn_action_txdone     },982	{ CONN_STATE_IDLE,      CONN_EVENT_TXDONE,   conn_action_txdone     },983};984 985static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node);986 987 988/*989 * Actions for interface - statemachine.990 */991 992/*993 * dev_action_start994 * @fi: An instance of an interface statemachine.995 * @event: The event, just happened.996 * @arg: Generic pointer, casted from struct net_device * upon call.997 *998 * Startup connection by sending CONN_EVENT_START to it.999 */1000static void dev_action_start(fsm_instance *fi, int event, void *arg)1001{1002	struct net_device   *dev = arg;1003	struct netiucv_priv *privptr = netdev_priv(dev);1004 1005	IUCV_DBF_TEXT(trace, 3, __func__);1006 1007	fsm_newstate(fi, DEV_STATE_STARTWAIT);1008	fsm_event(privptr->conn->fsm, CONN_EVENT_START, privptr->conn);1009}1010 1011/*1012 * Shutdown connection by sending CONN_EVENT_STOP to it.1013 *1014 * @param fi    An instance of an interface statemachine.1015 * @param event The event, just happened.1016 * @param arg   Generic pointer, casted from struct net_device * upon call.1017 */1018static void1019dev_action_stop(fsm_instance *fi, int event, void *arg)1020{1021	struct net_device   *dev = arg;1022	struct netiucv_priv *privptr = netdev_priv(dev);1023	struct iucv_event   ev;1024 1025	IUCV_DBF_TEXT(trace, 3, __func__);1026 1027	ev.conn = privptr->conn;1028 1029	fsm_newstate(fi, DEV_STATE_STOPWAIT);1030	fsm_event(privptr->conn->fsm, CONN_EVENT_STOP, &ev);1031}1032 1033/*1034 * Called from connection statemachine1035 * when a connection is up and running.1036 *1037 * @param fi    An instance of an interface statemachine.1038 * @param event The event, just happened.1039 * @param arg   Generic pointer, casted from struct net_device * upon call.1040 */1041static void1042dev_action_connup(fsm_instance *fi, int event, void *arg)1043{1044	struct net_device   *dev = arg;1045	struct netiucv_priv *privptr = netdev_priv(dev);1046 1047	IUCV_DBF_TEXT(trace, 3, __func__);1048 1049	switch (fsm_getstate(fi)) {1050		case DEV_STATE_STARTWAIT:1051			fsm_newstate(fi, DEV_STATE_RUNNING);1052			dev_info(privptr->dev,1053				"The IUCV device has been connected"1054				" successfully to %s\n",1055				netiucv_printuser(privptr->conn));1056			IUCV_DBF_TEXT(setup, 3,1057				"connection is up and running\n");1058			break;1059		case DEV_STATE_STOPWAIT:1060			IUCV_DBF_TEXT(data, 2,1061				"dev_action_connup: in DEV_STATE_STOPWAIT\n");1062			break;1063	}1064}1065 1066/*1067 * Called from connection statemachine1068 * when a connection has been shutdown.1069 *1070 * @param fi    An instance of an interface statemachine.1071 * @param event The event, just happened.1072 * @param arg   Generic pointer, casted from struct net_device * upon call.1073 */1074static void1075dev_action_conndown(fsm_instance *fi, int event, void *arg)1076{1077	IUCV_DBF_TEXT(trace, 3, __func__);1078 1079	switch (fsm_getstate(fi)) {1080		case DEV_STATE_RUNNING:1081			fsm_newstate(fi, DEV_STATE_STARTWAIT);1082			break;1083		case DEV_STATE_STOPWAIT:1084			fsm_newstate(fi, DEV_STATE_STOPPED);1085			IUCV_DBF_TEXT(setup, 3, "connection is down\n");1086			break;1087	}1088}1089 1090static const fsm_node dev_fsm[] = {1091	{ DEV_STATE_STOPPED,    DEV_EVENT_START,   dev_action_start    },1092 1093	{ DEV_STATE_STOPWAIT,   DEV_EVENT_START,   dev_action_start    },1094	{ DEV_STATE_STOPWAIT,   DEV_EVENT_CONDOWN, dev_action_conndown },1095 1096	{ DEV_STATE_STARTWAIT,  DEV_EVENT_STOP,    dev_action_stop     },1097	{ DEV_STATE_STARTWAIT,  DEV_EVENT_CONUP,   dev_action_connup   },1098 1099	{ DEV_STATE_RUNNING,    DEV_EVENT_STOP,    dev_action_stop     },1100	{ DEV_STATE_RUNNING,    DEV_EVENT_CONDOWN, dev_action_conndown },1101	{ DEV_STATE_RUNNING,    DEV_EVENT_CONUP,   netiucv_action_nop  },1102};1103 1104static const int DEV_FSM_LEN = sizeof(dev_fsm) / sizeof(fsm_node);1105 1106/*1107 * Transmit a packet.1108 * This is a helper function for netiucv_tx().1109 *1110 * @param conn Connection to be used for sending.1111 * @param skb Pointer to struct sk_buff of packet to send.1112 *            The linklevel header has already been set up1113 *            by netiucv_tx().1114 *1115 * @return 0 on success, -ERRNO on failure. (Never fails.)1116 */1117static int netiucv_transmit_skb(struct iucv_connection *conn,1118				struct sk_buff *skb)1119{1120	struct iucv_message msg;1121	unsigned long saveflags;1122	struct ll_header header;1123	int rc;1124 1125	if (fsm_getstate(conn->fsm) != CONN_STATE_IDLE) {1126		int l = skb->len + NETIUCV_HDRLEN;1127 1128		spin_lock_irqsave(&conn->collect_lock, saveflags);1129		if (conn->collect_len + l >1130		    (conn->max_buffsize - NETIUCV_HDRLEN)) {1131			rc = -EBUSY;1132			IUCV_DBF_TEXT(data, 2,1133				      "EBUSY from netiucv_transmit_skb\n");1134		} else {1135			refcount_inc(&skb->users);1136			skb_queue_tail(&conn->collect_queue, skb);1137			conn->collect_len += l;1138			rc = 0;1139		}1140		spin_unlock_irqrestore(&conn->collect_lock, saveflags);1141	} else {1142		struct sk_buff *nskb = skb;1143		/*1144		 * Copy the skb to a new allocated skb in lowmem only if the1145		 * data is located above 2G in memory or tailroom is < 2.1146		 */1147		unsigned long hi = ((unsigned long)(skb_tail_pointer(skb) +1148				    NETIUCV_HDRLEN)) >> 31;1149		int copied = 0;1150		if (hi || (skb_tailroom(skb) < 2)) {1151			nskb = alloc_skb(skb->len + NETIUCV_HDRLEN +1152					 NETIUCV_HDRLEN, GFP_ATOMIC | GFP_DMA);1153			if (!nskb) {1154				IUCV_DBF_TEXT(data, 2, "alloc_skb failed\n");1155				rc = -ENOMEM;1156				return rc;1157			} else {1158				skb_reserve(nskb, NETIUCV_HDRLEN);1159				skb_put_data(nskb, skb->data, skb->len);1160			}1161			copied = 1;1162		}1163		/*1164		 * skb now is below 2G and has enough room. Add headers.1165		 */1166		header.next = nskb->len + NETIUCV_HDRLEN;1167		memcpy(skb_push(nskb, NETIUCV_HDRLEN), &header, NETIUCV_HDRLEN);1168		header.next = 0;1169		skb_put_data(nskb, &header, NETIUCV_HDRLEN);1170 1171		fsm_newstate(conn->fsm, CONN_STATE_TX);1172		conn->prof.send_stamp = jiffies;1173 1174		msg.tag = 1;1175		msg.class = 0;1176		rc = iucv_message_send(conn->path, &msg, 0, 0,1177				       nskb->data, nskb->len);1178		conn->prof.doios_single++;1179		conn->prof.txlen += skb->len;1180		conn->prof.tx_pending++;1181		if (conn->prof.tx_pending > conn->prof.tx_max_pending)1182			conn->prof.tx_max_pending = conn->prof.tx_pending;1183		if (rc) {1184			struct netiucv_priv *privptr;1185			fsm_newstate(conn->fsm, CONN_STATE_IDLE);1186			conn->prof.tx_pending--;1187			privptr = netdev_priv(conn->netdev);1188			if (privptr)1189				privptr->stats.tx_errors++;1190			if (copied)1191				dev_kfree_skb(nskb);1192			else {1193				/*1194				 * Remove our headers. They get added1195				 * again on retransmit.1196				 */1197				skb_pull(skb, NETIUCV_HDRLEN);1198				skb_trim(skb, skb->len - NETIUCV_HDRLEN);1199			}1200			IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_send\n", rc);1201		} else {1202			if (copied)1203				dev_kfree_skb(skb);1204			refcount_inc(&nskb->users);1205			skb_queue_tail(&conn->commit_queue, nskb);1206		}1207	}1208 1209	return rc;1210}1211 1212/*1213 * Interface API for upper network layers1214 */1215 1216/*1217 * Open an interface.1218 * Called from generic network layer when ifconfig up is run.1219 *1220 * @param dev Pointer to interface struct.1221 *1222 * @return 0 on success, -ERRNO on failure. (Never fails.)1223 */1224static int netiucv_open(struct net_device *dev)1225{1226	struct netiucv_priv *priv = netdev_priv(dev);1227 1228	fsm_event(priv->fsm, DEV_EVENT_START, dev);1229	return 0;1230}1231 1232/*1233 * Close an interface.1234 * Called from generic network layer when ifconfig down is run.1235 *1236 * @param dev Pointer to interface struct.1237 *1238 * @return 0 on success, -ERRNO on failure. (Never fails.)1239 */1240static int netiucv_close(struct net_device *dev)1241{1242	struct netiucv_priv *priv = netdev_priv(dev);1243 1244	fsm_event(priv->fsm, DEV_EVENT_STOP, dev);1245	return 0;1246}1247 1248/*1249 * Start transmission of a packet.1250 * Called from generic network device layer.1251 */1252static netdev_tx_t netiucv_tx(struct sk_buff *skb, struct net_device *dev)1253{1254	struct netiucv_priv *privptr = netdev_priv(dev);1255	int rc;1256 1257	IUCV_DBF_TEXT(trace, 4, __func__);1258	/*1259	 * Some sanity checks ...1260	 */1261	if (skb == NULL) {1262		IUCV_DBF_TEXT(data, 2, "netiucv_tx: skb is NULL\n");1263		privptr->stats.tx_dropped++;1264		return NETDEV_TX_OK;1265	}1266	if (skb_headroom(skb) < NETIUCV_HDRLEN) {1267		IUCV_DBF_TEXT(data, 2,1268			"netiucv_tx: skb_headroom < NETIUCV_HDRLEN\n");1269		dev_kfree_skb(skb);1270		privptr->stats.tx_dropped++;1271		return NETDEV_TX_OK;1272	}1273 1274	/*1275	 * If connection is not running, try to restart it1276	 * and throw away packet.1277	 */1278	if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) {1279		dev_kfree_skb(skb);1280		privptr->stats.tx_dropped++;1281		privptr->stats.tx_errors++;1282		privptr->stats.tx_carrier_errors++;1283		return NETDEV_TX_OK;1284	}1285 1286	if (netiucv_test_and_set_busy(dev)) {1287		IUCV_DBF_TEXT(data, 2, "EBUSY from netiucv_tx\n");1288		return NETDEV_TX_BUSY;1289	}1290	netif_trans_update(dev);1291	rc = netiucv_transmit_skb(privptr->conn, skb);1292	netiucv_clear_busy(dev);1293	return rc ? NETDEV_TX_BUSY : NETDEV_TX_OK;1294}1295 1296/*1297 * netiucv_stats1298 * @dev: Pointer to interface struct.1299 *1300 * Returns interface statistics of a device.1301 *1302 * Returns pointer to stats struct of this interface.1303 */1304static struct net_device_stats *netiucv_stats (struct net_device * dev)1305{1306	struct netiucv_priv *priv = netdev_priv(dev);1307 1308	IUCV_DBF_TEXT(trace, 5, __func__);1309	return &priv->stats;1310}1311 1312/*1313 * attributes in sysfs1314 */1315 1316static ssize_t user_show(struct device *dev, struct device_attribute *attr,1317			 char *buf)1318{1319	struct netiucv_priv *priv = dev_get_drvdata(dev);1320 1321	IUCV_DBF_TEXT(trace, 5, __func__);1322	return sprintf(buf, "%s\n", netiucv_printuser(priv->conn));1323}1324 1325static int netiucv_check_user(const char *buf, size_t count, char *username,1326			      char *userdata)1327{1328	const char *p;1329	int i;1330 1331	p = strchr(buf, '.');1332	if ((p && ((count > 26) ||1333		   ((p - buf) > 8) ||1334		   (buf + count - p > 18))) ||1335	    (!p && (count > 9))) {1336		IUCV_DBF_TEXT(setup, 2, "conn_write: too long\n");1337		return -EINVAL;1338	}1339 1340	for (i = 0, p = buf; i < 8 && *p && *p != '.'; i++, p++) {1341		if (isalnum(*p) || *p == '$') {1342			username[i] = toupper(*p);1343			continue;1344		}1345		if (*p == '\n')1346			/* trailing lf, grr */1347			break;1348		IUCV_DBF_TEXT_(setup, 2,1349			       "conn_write: invalid character %02x\n", *p);1350		return -EINVAL;1351	}1352	while (i < 8)1353		username[i++] = ' ';1354	username[8] = '\0';1355 1356	if (*p == '.') {1357		p++;1358		for (i = 0; i < 16 && *p; i++, p++) {1359			if (*p == '\n')1360				break;1361			userdata[i] = toupper(*p);1362		}1363		while (i > 0 && i < 16)1364			userdata[i++] = ' ';1365	} else1366		memcpy(userdata, iucvMagic_ascii, 16);1367	userdata[16] = '\0';1368	ASCEBC(userdata, 16);1369 1370	return 0;1371}1372 1373static ssize_t user_write(struct device *dev, struct device_attribute *attr,1374			  const char *buf, size_t count)1375{1376	struct netiucv_priv *priv = dev_get_drvdata(dev);1377	struct net_device *ndev = priv->conn->netdev;1378	char	username[9];1379	char	userdata[17];1380	int	rc;1381	struct iucv_connection *cp;1382 1383	IUCV_DBF_TEXT(trace, 3, __func__);1384	rc = netiucv_check_user(buf, count, username, userdata);1385	if (rc)1386		return rc;1387 1388	if (memcmp(username, priv->conn->userid, 9) &&1389	    (ndev->flags & (IFF_UP | IFF_RUNNING))) {1390		/* username changed while the interface is active. */1391		IUCV_DBF_TEXT(setup, 2, "user_write: device active\n");1392		return -EPERM;1393	}1394	read_lock_bh(&iucv_connection_rwlock);1395	list_for_each_entry(cp, &iucv_connection_list, list) {1396		if (!strncmp(username, cp->userid, 9) &&1397		   !strncmp(userdata, cp->userdata, 17) && cp->netdev != ndev) {1398			read_unlock_bh(&iucv_connection_rwlock);1399			IUCV_DBF_TEXT_(setup, 2, "user_write: Connection to %s "1400				"already exists\n", netiucv_printuser(cp));1401			return -EEXIST;1402		}1403	}1404	read_unlock_bh(&iucv_connection_rwlock);1405	memcpy(priv->conn->userid, username, 9);1406	memcpy(priv->conn->userdata, userdata, 17);1407	return count;1408}1409 1410static DEVICE_ATTR(user, 0644, user_show, user_write);1411 1412static ssize_t buffer_show (struct device *dev, struct device_attribute *attr,1413			    char *buf)1414{1415	struct netiucv_priv *priv = dev_get_drvdata(dev);1416 1417	IUCV_DBF_TEXT(trace, 5, __func__);1418	return sprintf(buf, "%d\n", priv->conn->max_buffsize);1419}1420 1421static ssize_t buffer_write (struct device *dev, struct device_attribute *attr,1422			     const char *buf, size_t count)1423{1424	struct netiucv_priv *priv = dev_get_drvdata(dev);1425	struct net_device *ndev = priv->conn->netdev;1426	unsigned int bs1;1427	int rc;1428 1429	IUCV_DBF_TEXT(trace, 3, __func__);1430	if (count >= 39)1431		return -EINVAL;1432 1433	rc = kstrtouint(buf, 0, &bs1);1434 1435	if (rc == -EINVAL) {1436		IUCV_DBF_TEXT_(setup, 2, "buffer_write: invalid char %s\n",1437			buf);1438		return -EINVAL;1439	}1440	if ((rc == -ERANGE) || (bs1 > NETIUCV_BUFSIZE_MAX)) {1441		IUCV_DBF_TEXT_(setup, 2,1442			"buffer_write: buffer size %d too large\n",1443			bs1);1444		return -EINVAL;1445	}1446	if ((ndev->flags & IFF_RUNNING) &&1447	    (bs1 < (ndev->mtu + NETIUCV_HDRLEN + 2))) {1448		IUCV_DBF_TEXT_(setup, 2,1449			"buffer_write: buffer size %d too small\n",1450			bs1);1451		return -EINVAL;1452	}1453	if (bs1 < (576 + NETIUCV_HDRLEN + NETIUCV_HDRLEN)) {1454		IUCV_DBF_TEXT_(setup, 2,1455			"buffer_write: buffer size %d too small\n",1456			bs1);1457		return -EINVAL;1458	}1459 1460	priv->conn->max_buffsize = bs1;1461	if (!(ndev->flags & IFF_RUNNING))1462		ndev->mtu = bs1 - NETIUCV_HDRLEN - NETIUCV_HDRLEN;1463 1464	return count;1465 1466}1467 1468static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write);1469 1470static ssize_t dev_fsm_show (struct device *dev, struct device_attribute *attr,1471			     char *buf)1472{1473	struct netiucv_priv *priv = dev_get_drvdata(dev);1474 1475	IUCV_DBF_TEXT(trace, 5, __func__);1476	return sprintf(buf, "%s\n", fsm_getstate_str(priv->fsm));1477}1478 1479static DEVICE_ATTR(device_fsm_state, 0444, dev_fsm_show, NULL);1480 1481static ssize_t conn_fsm_show (struct device *dev,1482			      struct device_attribute *attr, char *buf)1483{1484	struct netiucv_priv *priv = dev_get_drvdata(dev);1485 1486	IUCV_DBF_TEXT(trace, 5, __func__);1487	return sprintf(buf, "%s\n", fsm_getstate_str(priv->conn->fsm));1488}1489 1490static DEVICE_ATTR(connection_fsm_state, 0444, conn_fsm_show, NULL);1491 1492static ssize_t maxmulti_show (struct device *dev,1493			      struct device_attribute *attr, char *buf)1494{1495	struct netiucv_priv *priv = dev_get_drvdata(dev);1496 1497	IUCV_DBF_TEXT(trace, 5, __func__);1498	return sprintf(buf, "%ld\n", priv->conn->prof.maxmulti);1499}1500 1501static ssize_t maxmulti_write (struct device *dev,1502			       struct device_attribute *attr,1503			       const char *buf, size_t count)1504{1505	struct netiucv_priv *priv = dev_get_drvdata(dev);1506 1507	IUCV_DBF_TEXT(trace, 4, __func__);1508	priv->conn->prof.maxmulti = 0;1509	return count;1510}1511 1512static DEVICE_ATTR(max_tx_buffer_used, 0644, maxmulti_show, maxmulti_write);1513 1514static ssize_t maxcq_show (struct device *dev, struct device_attribute *attr,1515			   char *buf)1516{1517	struct netiucv_priv *priv = dev_get_drvdata(dev);1518 1519	IUCV_DBF_TEXT(trace, 5, __func__);1520	return sprintf(buf, "%ld\n", priv->conn->prof.maxcqueue);1521}1522 1523static ssize_t maxcq_write (struct device *dev, struct device_attribute *attr,1524			    const char *buf, size_t count)1525{1526	struct netiucv_priv *priv = dev_get_drvdata(dev);1527 1528	IUCV_DBF_TEXT(trace, 4, __func__);1529	priv->conn->prof.maxcqueue = 0;1530	return count;1531}1532 1533static DEVICE_ATTR(max_chained_skbs, 0644, maxcq_show, maxcq_write);1534 1535static ssize_t sdoio_show (struct device *dev, struct device_attribute *attr,1536			   char *buf)1537{1538	struct netiucv_priv *priv = dev_get_drvdata(dev);1539 1540	IUCV_DBF_TEXT(trace, 5, __func__);1541	return sprintf(buf, "%ld\n", priv->conn->prof.doios_single);1542}1543 1544static ssize_t sdoio_write (struct device *dev, struct device_attribute *attr,1545			    const char *buf, size_t count)1546{1547	struct netiucv_priv *priv = dev_get_drvdata(dev);1548 1549	IUCV_DBF_TEXT(trace, 4, __func__);1550	priv->conn->prof.doios_single = 0;1551	return count;1552}1553 1554static DEVICE_ATTR(tx_single_write_ops, 0644, sdoio_show, sdoio_write);1555 1556static ssize_t mdoio_show (struct device *dev, struct device_attribute *attr,1557			   char *buf)1558{1559	struct netiucv_priv *priv = dev_get_drvdata(dev);1560 1561	IUCV_DBF_TEXT(trace, 5, __func__);1562	return sprintf(buf, "%ld\n", priv->conn->prof.doios_multi);1563}1564 1565static ssize_t mdoio_write (struct device *dev, struct device_attribute *attr,1566			    const char *buf, size_t count)1567{1568	struct netiucv_priv *priv = dev_get_drvdata(dev);1569 1570	IUCV_DBF_TEXT(trace, 5, __func__);1571	priv->conn->prof.doios_multi = 0;1572	return count;1573}1574 1575static DEVICE_ATTR(tx_multi_write_ops, 0644, mdoio_show, mdoio_write);1576 1577static ssize_t txlen_show (struct device *dev, struct device_attribute *attr,1578			   char *buf)1579{1580	struct netiucv_priv *priv = dev_get_drvdata(dev);1581 1582	IUCV_DBF_TEXT(trace, 5, __func__);1583	return sprintf(buf, "%ld\n", priv->conn->prof.txlen);1584}1585 1586static ssize_t txlen_write (struct device *dev, struct device_attribute *attr,1587			    const char *buf, size_t count)1588{1589	struct netiucv_priv *priv = dev_get_drvdata(dev);1590 1591	IUCV_DBF_TEXT(trace, 4, __func__);1592	priv->conn->prof.txlen = 0;1593	return count;1594}1595 1596static DEVICE_ATTR(netto_bytes, 0644, txlen_show, txlen_write);1597 1598static ssize_t txtime_show (struct device *dev, struct device_attribute *attr,1599			    char *buf)1600{1601	struct netiucv_priv *priv = dev_get_drvdata(dev);1602 1603	IUCV_DBF_TEXT(trace, 5, __func__);1604	return sprintf(buf, "%ld\n", priv->conn->prof.tx_time);1605}1606 1607static ssize_t txtime_write (struct device *dev, struct device_attribute *attr,1608			     const char *buf, size_t count)1609{1610	struct netiucv_priv *priv = dev_get_drvdata(dev);1611 1612	IUCV_DBF_TEXT(trace, 4, __func__);1613	priv->conn->prof.tx_time = 0;1614	return count;1615}1616 1617static DEVICE_ATTR(max_tx_io_time, 0644, txtime_show, txtime_write);1618 1619static ssize_t txpend_show (struct device *dev, struct device_attribute *attr,1620			    char *buf)1621{1622	struct netiucv_priv *priv = dev_get_drvdata(dev);1623 1624	IUCV_DBF_TEXT(trace, 5, __func__);1625	return sprintf(buf, "%ld\n", priv->conn->prof.tx_pending);1626}1627 1628static ssize_t txpend_write (struct device *dev, struct device_attribute *attr,1629			     const char *buf, size_t count)1630{1631	struct netiucv_priv *priv = dev_get_drvdata(dev);1632 1633	IUCV_DBF_TEXT(trace, 4, __func__);1634	priv->conn->prof.tx_pending = 0;1635	return count;1636}1637 1638static DEVICE_ATTR(tx_pending, 0644, txpend_show, txpend_write);1639 1640static ssize_t txmpnd_show (struct device *dev, struct device_attribute *attr,1641			    char *buf)1642{1643	struct netiucv_priv *priv = dev_get_drvdata(dev);1644 1645	IUCV_DBF_TEXT(trace, 5, __func__);1646	return sprintf(buf, "%ld\n", priv->conn->prof.tx_max_pending);1647}1648 1649static ssize_t txmpnd_write (struct device *dev, struct device_attribute *attr,1650			     const char *buf, size_t count)1651{1652	struct netiucv_priv *priv = dev_get_drvdata(dev);1653 1654	IUCV_DBF_TEXT(trace, 4, __func__);1655	priv->conn->prof.tx_max_pending = 0;1656	return count;1657}1658 1659static DEVICE_ATTR(tx_max_pending, 0644, txmpnd_show, txmpnd_write);1660 1661static struct attribute *netiucv_attrs[] = {1662	&dev_attr_buffer.attr,1663	&dev_attr_user.attr,1664	NULL,1665};1666 1667static struct attribute_group netiucv_attr_group = {1668	.attrs = netiucv_attrs,1669};1670 1671static struct attribute *netiucv_stat_attrs[] = {1672	&dev_attr_device_fsm_state.attr,1673	&dev_attr_connection_fsm_state.attr,1674	&dev_attr_max_tx_buffer_used.attr,1675	&dev_attr_max_chained_skbs.attr,1676	&dev_attr_tx_single_write_ops.attr,1677	&dev_attr_tx_multi_write_ops.attr,1678	&dev_attr_netto_bytes.attr,1679	&dev_attr_max_tx_io_time.attr,1680	&dev_attr_tx_pending.attr,1681	&dev_attr_tx_max_pending.attr,1682	NULL,1683};1684 1685static struct attribute_group netiucv_stat_attr_group = {1686	.name  = "stats",1687	.attrs = netiucv_stat_attrs,1688};1689 1690static const struct attribute_group *netiucv_attr_groups[] = {1691	&netiucv_stat_attr_group,1692	&netiucv_attr_group,1693	NULL,1694};1695 1696static int netiucv_register_device(struct net_device *ndev)1697{1698	struct netiucv_priv *priv = netdev_priv(ndev);1699	struct device *dev;1700	int ret;1701 1702	IUCV_DBF_TEXT(trace, 3, __func__);1703 1704	dev = iucv_alloc_device(netiucv_attr_groups, &netiucv_driver, NULL,1705				"net%s", ndev->name);1706	if (!dev)1707		return -ENOMEM;1708 1709	ret = device_register(dev);1710	if (ret) {1711		put_device(dev);1712		return ret;1713	}1714	priv->dev = dev;1715	dev_set_drvdata(dev, priv);1716	return 0;1717}1718 1719static void netiucv_unregister_device(struct device *dev)1720{1721	IUCV_DBF_TEXT(trace, 3, __func__);1722	device_unregister(dev);1723}1724 1725/*1726 * Allocate and initialize a new connection structure.1727 * Add it to the list of netiucv connections;1728 */1729static struct iucv_connection *netiucv_new_connection(struct net_device *dev,1730						      char *username,1731						      char *userdata)1732{1733	struct iucv_connection *conn;1734 1735	conn = kzalloc(sizeof(*conn), GFP_KERNEL);1736	if (!conn)1737		goto out;1738	skb_queue_head_init(&conn->collect_queue);1739	skb_queue_head_init(&conn->commit_queue);1740	spin_lock_init(&conn->collect_lock);1741	conn->max_buffsize = NETIUCV_BUFSIZE_DEFAULT;1742	conn->netdev = dev;1743 1744	conn->rx_buff = alloc_skb(conn->max_buffsize, GFP_KERNEL | GFP_DMA);1745	if (!conn->rx_buff)1746		goto out_conn;1747	conn->tx_buff = alloc_skb(conn->max_buffsize, GFP_KERNEL | GFP_DMA);1748	if (!conn->tx_buff)1749		goto out_rx;1750	conn->fsm = init_fsm("netiucvconn", conn_state_names,1751			     conn_event_names, NR_CONN_STATES,1752			     NR_CONN_EVENTS, conn_fsm, CONN_FSM_LEN,1753			     GFP_KERNEL);1754	if (!conn->fsm)1755		goto out_tx;1756 1757	fsm_settimer(conn->fsm, &conn->timer);1758	fsm_newstate(conn->fsm, CONN_STATE_INVALID);1759 1760	if (userdata)1761		memcpy(conn->userdata, userdata, 17);1762	if (username) {1763		memcpy(conn->userid, username, 9);1764		fsm_newstate(conn->fsm, CONN_STATE_STOPPED);1765	}1766 1767	write_lock_bh(&iucv_connection_rwlock);1768	list_add_tail(&conn->list, &iucv_connection_list);1769	write_unlock_bh(&iucv_connection_rwlock);1770	return conn;1771 1772out_tx:1773	kfree_skb(conn->tx_buff);1774out_rx:1775	kfree_skb(conn->rx_buff);1776out_conn:1777	kfree(conn);1778out:1779	return NULL;1780}1781 1782/*1783 * Release a connection structure and remove it from the1784 * list of netiucv connections.1785 */1786static void netiucv_remove_connection(struct iucv_connection *conn)1787{1788 1789	IUCV_DBF_TEXT(trace, 3, __func__);1790	write_lock_bh(&iucv_connection_rwlock);1791	list_del_init(&conn->list);1792	write_unlock_bh(&iucv_connection_rwlock);1793	fsm_deltimer(&conn->timer);1794	netiucv_purge_skb_queue(&conn->collect_queue);1795	if (conn->path) {1796		iucv_path_sever(conn->path, conn->userdata);1797		kfree(conn->path);1798		conn->path = NULL;1799	}1800	netiucv_purge_skb_queue(&conn->commit_queue);1801	kfree_fsm(conn->fsm);1802	kfree_skb(conn->rx_buff);1803	kfree_skb(conn->tx_buff);1804}1805 1806/*1807 * Release everything of a net device.1808 */1809static void netiucv_free_netdevice(struct net_device *dev)1810{1811	struct netiucv_priv *privptr = netdev_priv(dev);1812 1813	IUCV_DBF_TEXT(trace, 3, __func__);1814 1815	if (!dev)1816		return;1817 1818	if (privptr) {1819		if (privptr->conn)1820			netiucv_remove_connection(privptr->conn);1821		if (privptr->fsm)1822			kfree_fsm(privptr->fsm);1823		privptr->conn = NULL; privptr->fsm = NULL;1824		/* privptr gets freed by free_netdev() */1825	}1826}1827 1828/*1829 * Initialize a net device. (Called from kernel in alloc_netdev())1830 */1831static const struct net_device_ops netiucv_netdev_ops = {1832	.ndo_open		= netiucv_open,1833	.ndo_stop		= netiucv_close,1834	.ndo_get_stats		= netiucv_stats,1835	.ndo_start_xmit		= netiucv_tx,1836};1837 1838static void netiucv_setup_netdevice(struct net_device *dev)1839{1840	dev->mtu	         = NETIUCV_MTU_DEFAULT;1841	dev->min_mtu		 = 576;1842	dev->max_mtu		 = NETIUCV_MTU_MAX;1843	dev->needs_free_netdev   = true;1844	dev->priv_destructor     = netiucv_free_netdevice;1845	dev->hard_header_len     = NETIUCV_HDRLEN;1846	dev->addr_len            = 0;1847	dev->type                = ARPHRD_SLIP;1848	dev->tx_queue_len        = NETIUCV_QUEUELEN_DEFAULT;1849	dev->flags	         = IFF_POINTOPOINT | IFF_NOARP;1850	dev->netdev_ops		 = &netiucv_netdev_ops;1851}1852 1853/*1854 * Allocate and initialize everything of a net device.1855 */1856static struct net_device *netiucv_init_netdevice(char *username, char *userdata)1857{1858	struct netiucv_priv *privptr;1859	struct net_device *dev;1860 1861	dev = alloc_netdev(sizeof(struct netiucv_priv), "iucv%d",1862			   NET_NAME_UNKNOWN, netiucv_setup_netdevice);1863	if (!dev)1864		return NULL;1865	rtnl_lock();1866	if (dev_alloc_name(dev, dev->name) < 0)1867		goto out_netdev;1868 1869	privptr = netdev_priv(dev);1870	privptr->fsm = init_fsm("netiucvdev", dev_state_names,1871				dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS,1872				dev_fsm, DEV_FSM_LEN, GFP_KERNEL);1873	if (!privptr->fsm)1874		goto out_netdev;1875 1876	privptr->conn = netiucv_new_connection(dev, username, userdata);1877	if (!privptr->conn) {1878		IUCV_DBF_TEXT(setup, 2, "NULL from netiucv_new_connection\n");1879		goto out_fsm;1880	}1881	fsm_newstate(privptr->fsm, DEV_STATE_STOPPED);1882	return dev;1883 1884out_fsm:1885	kfree_fsm(privptr->fsm);1886out_netdev:1887	rtnl_unlock();1888	free_netdev(dev);1889	return NULL;1890}1891 1892static ssize_t connection_store(struct device_driver *drv, const char *buf,1893				size_t count)1894{1895	char username[9];1896	char userdata[17];1897	int rc;1898	struct net_device *dev;1899	struct netiucv_priv *priv;1900	struct iucv_connection *cp;1901 1902	IUCV_DBF_TEXT(trace, 3, __func__);1903	rc = netiucv_check_user(buf, count, username, userdata);1904	if (rc)1905		return rc;1906 1907	read_lock_bh(&iucv_connection_rwlock);1908	list_for_each_entry(cp, &iucv_connection_list, list) {1909		if (!strncmp(username, cp->userid, 9) &&1910		    !strncmp(userdata, cp->userdata, 17)) {1911			read_unlock_bh(&iucv_connection_rwlock);1912			IUCV_DBF_TEXT_(setup, 2, "conn_write: Connection to %s "1913				"already exists\n", netiucv_printuser(cp));1914			return -EEXIST;1915		}1916	}1917	read_unlock_bh(&iucv_connection_rwlock);1918 1919	dev = netiucv_init_netdevice(username, userdata);1920	if (!dev) {1921		IUCV_DBF_TEXT(setup, 2, "NULL from netiucv_init_netdevice\n");1922		return -ENODEV;1923	}1924 1925	rc = netiucv_register_device(dev);1926	if (rc) {1927		rtnl_unlock();1928		IUCV_DBF_TEXT_(setup, 2,1929			"ret %d from netiucv_register_device\n", rc);1930		goto out_free_ndev;1931	}1932 1933	/* sysfs magic */1934	priv = netdev_priv(dev);1935	SET_NETDEV_DEV(dev, priv->dev);1936 1937	rc = register_netdevice(dev);1938	rtnl_unlock();1939	if (rc)1940		goto out_unreg;1941 1942	dev_info(priv->dev, "The IUCV interface to %s has been established "1943			    "successfully\n",1944		netiucv_printuser(priv->conn));1945 1946	return count;1947 1948out_unreg:1949	netiucv_unregister_device(priv->dev);1950out_free_ndev:1951	netiucv_free_netdevice(dev);1952	return rc;1953}1954static DRIVER_ATTR_WO(connection);1955 1956static ssize_t remove_store(struct device_driver *drv, const char *buf,1957			    size_t count)1958{1959	struct iucv_connection *cp;1960        struct net_device *ndev;1961        struct netiucv_priv *priv;1962        struct device *dev;1963        char name[IFNAMSIZ];1964	const char *p;1965        int i;1966 1967	IUCV_DBF_TEXT(trace, 3, __func__);1968 1969        if (count >= IFNAMSIZ)1970                count = IFNAMSIZ - 1;1971 1972	for (i = 0, p = buf; i < count && *p; i++, p++) {1973		if (*p == '\n' || *p == ' ')1974                        /* trailing lf, grr */1975                        break;1976		name[i] = *p;1977        }1978        name[i] = '\0';1979 1980	read_lock_bh(&iucv_connection_rwlock);1981	list_for_each_entry(cp, &iucv_connection_list, list) {1982		ndev = cp->netdev;1983		priv = netdev_priv(ndev);1984                dev = priv->dev;1985		if (strncmp(name, ndev->name, count))1986			continue;1987		read_unlock_bh(&iucv_connection_rwlock);1988                if (ndev->flags & (IFF_UP | IFF_RUNNING)) {1989			dev_warn(dev, "The IUCV device is connected"1990				" to %s and cannot be removed\n",1991				priv->conn->userid);1992			IUCV_DBF_TEXT(data, 2, "remove_write: still active\n");1993			return -EPERM;1994                }1995                unregister_netdev(ndev);1996                netiucv_unregister_device(dev);1997                return count;1998        }1999	read_unlock_bh(&iucv_connection_rwlock);2000	IUCV_DBF_TEXT(data, 2, "remove_write: unknown device\n");2001        return -EINVAL;2002}2003static DRIVER_ATTR_WO(remove);2004 2005static struct attribute * netiucv_drv_attrs[] = {2006	&driver_attr_connection.attr,2007	&driver_attr_remove.attr,2008	NULL,2009};2010 2011static struct attribute_group netiucv_drv_attr_group = {2012	.attrs = netiucv_drv_attrs,2013};2014 2015static const struct attribute_group *netiucv_drv_attr_groups[] = {2016	&netiucv_drv_attr_group,2017	NULL,2018};2019 2020static void netiucv_banner(void)2021{2022	pr_info("driver initialized\n");2023}2024 2025static void __exit netiucv_exit(void)2026{2027	struct iucv_connection *cp;2028	struct net_device *ndev;2029	struct netiucv_priv *priv;2030	struct device *dev;2031 2032	IUCV_DBF_TEXT(trace, 3, __func__);2033	while (!list_empty(&iucv_connection_list)) {2034		cp = list_entry(iucv_connection_list.next,2035				struct iucv_connection, list);2036		ndev = cp->netdev;2037		priv = netdev_priv(ndev);2038		dev = priv->dev;2039 2040		unregister_netdev(ndev);2041		netiucv_unregister_device(dev);2042	}2043 2044	driver_unregister(&netiucv_driver);2045	iucv_unregister(&netiucv_handler, 1);2046	iucv_unregister_dbf_views();2047 2048	pr_info("driver unloaded\n");2049	return;2050}2051 2052static int __init netiucv_init(void)2053{2054	int rc;2055 2056	rc = iucv_register_dbf_views();2057	if (rc)2058		goto out;2059	rc = iucv_register(&netiucv_handler, 1);2060	if (rc)2061		goto out_dbf;2062	IUCV_DBF_TEXT(trace, 3, __func__);2063	netiucv_driver.groups = netiucv_drv_attr_groups;2064	rc = driver_register(&netiucv_driver);2065	if (rc) {2066		IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_register\n", rc);2067		goto out_iucv;2068	}2069 2070	netiucv_banner();2071	return rc;2072 2073out_iucv:2074	iucv_unregister(&netiucv_handler, 1);2075out_dbf:2076	iucv_unregister_dbf_views();2077out:2078	return rc;2079}2080 2081module_init(netiucv_init);2082module_exit(netiucv_exit);2083MODULE_LICENSE("GPL");2084