V4L/DVB (6715): ivtv: Remove unnecessary register update
[linux-2.6/verdex.git] / drivers / s390 / net / netiucv.c
blobd6e93f15440ea1721b243b889a9be1006da2f983
1 /*
2 * IUCV network driver
4 * Copyright 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
5 * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
7 * Sysfs integration and all bugs therein by Cornelia Huck
8 * (cornelia.huck@de.ibm.com)
10 * Documentation used:
11 * the source of the original IUCV driver by:
12 * Stefan Hegewald <hegewald@de.ibm.com>
13 * Hartmut Penner <hpenner@de.ibm.com>
14 * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
15 * Martin Schwidefsky (schwidefsky@de.ibm.com)
16 * Alan Altmark (Alan_Altmark@us.ibm.com) Sept. 2000
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2, or (at your option)
21 * any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34 #undef DEBUG
36 #include <linux/module.h>
37 #include <linux/init.h>
38 #include <linux/kernel.h>
39 #include <linux/slab.h>
40 #include <linux/errno.h>
41 #include <linux/types.h>
42 #include <linux/interrupt.h>
43 #include <linux/timer.h>
44 #include <linux/bitops.h>
46 #include <linux/signal.h>
47 #include <linux/string.h>
48 #include <linux/device.h>
50 #include <linux/ip.h>
51 #include <linux/if_arp.h>
52 #include <linux/tcp.h>
53 #include <linux/skbuff.h>
54 #include <linux/ctype.h>
55 #include <net/dst.h>
57 #include <asm/io.h>
58 #include <asm/uaccess.h>
60 #include <net/iucv/iucv.h>
61 #include "fsm.h"
63 MODULE_AUTHOR
64 ("(C) 2001 IBM Corporation by Fritz Elfert (felfert@millenux.com)");
65 MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver");
67 /**
68 * Debug Facility stuff
70 #define IUCV_DBF_SETUP_NAME "iucv_setup"
71 #define IUCV_DBF_SETUP_LEN 32
72 #define IUCV_DBF_SETUP_PAGES 2
73 #define IUCV_DBF_SETUP_NR_AREAS 1
74 #define IUCV_DBF_SETUP_LEVEL 3
76 #define IUCV_DBF_DATA_NAME "iucv_data"
77 #define IUCV_DBF_DATA_LEN 128
78 #define IUCV_DBF_DATA_PAGES 2
79 #define IUCV_DBF_DATA_NR_AREAS 1
80 #define IUCV_DBF_DATA_LEVEL 2
82 #define IUCV_DBF_TRACE_NAME "iucv_trace"
83 #define IUCV_DBF_TRACE_LEN 16
84 #define IUCV_DBF_TRACE_PAGES 4
85 #define IUCV_DBF_TRACE_NR_AREAS 1
86 #define IUCV_DBF_TRACE_LEVEL 3
88 #define IUCV_DBF_TEXT(name,level,text) \
89 do { \
90 debug_text_event(iucv_dbf_##name,level,text); \
91 } while (0)
93 #define IUCV_DBF_HEX(name,level,addr,len) \
94 do { \
95 debug_event(iucv_dbf_##name,level,(void*)(addr),len); \
96 } while (0)
98 DECLARE_PER_CPU(char[256], iucv_dbf_txt_buf);
100 #define IUCV_DBF_TEXT_(name,level,text...) \
101 do { \
102 char* iucv_dbf_txt_buf = get_cpu_var(iucv_dbf_txt_buf); \
103 sprintf(iucv_dbf_txt_buf, text); \
104 debug_text_event(iucv_dbf_##name,level,iucv_dbf_txt_buf); \
105 put_cpu_var(iucv_dbf_txt_buf); \
106 } while (0)
108 #define IUCV_DBF_SPRINTF(name,level,text...) \
109 do { \
110 debug_sprintf_event(iucv_dbf_trace, level, ##text ); \
111 debug_sprintf_event(iucv_dbf_trace, level, text ); \
112 } while (0)
115 * some more debug stuff
117 #define IUCV_HEXDUMP16(importance,header,ptr) \
118 PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
119 "%02x %02x %02x %02x %02x %02x %02x %02x\n", \
120 *(((char*)ptr)),*(((char*)ptr)+1),*(((char*)ptr)+2), \
121 *(((char*)ptr)+3),*(((char*)ptr)+4),*(((char*)ptr)+5), \
122 *(((char*)ptr)+6),*(((char*)ptr)+7),*(((char*)ptr)+8), \
123 *(((char*)ptr)+9),*(((char*)ptr)+10),*(((char*)ptr)+11), \
124 *(((char*)ptr)+12),*(((char*)ptr)+13), \
125 *(((char*)ptr)+14),*(((char*)ptr)+15)); \
126 PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
127 "%02x %02x %02x %02x %02x %02x %02x %02x\n", \
128 *(((char*)ptr)+16),*(((char*)ptr)+17), \
129 *(((char*)ptr)+18),*(((char*)ptr)+19), \
130 *(((char*)ptr)+20),*(((char*)ptr)+21), \
131 *(((char*)ptr)+22),*(((char*)ptr)+23), \
132 *(((char*)ptr)+24),*(((char*)ptr)+25), \
133 *(((char*)ptr)+26),*(((char*)ptr)+27), \
134 *(((char*)ptr)+28),*(((char*)ptr)+29), \
135 *(((char*)ptr)+30),*(((char*)ptr)+31));
137 #define PRINTK_HEADER " iucv: " /* for debugging */
139 static struct device_driver netiucv_driver = {
140 .name = "netiucv",
141 .bus = &iucv_bus,
144 static int netiucv_callback_connreq(struct iucv_path *,
145 u8 ipvmid[8], u8 ipuser[16]);
146 static void netiucv_callback_connack(struct iucv_path *, u8 ipuser[16]);
147 static void netiucv_callback_connrej(struct iucv_path *, u8 ipuser[16]);
148 static void netiucv_callback_connsusp(struct iucv_path *, u8 ipuser[16]);
149 static void netiucv_callback_connres(struct iucv_path *, u8 ipuser[16]);
150 static void netiucv_callback_rx(struct iucv_path *, struct iucv_message *);
151 static void netiucv_callback_txdone(struct iucv_path *, struct iucv_message *);
153 static struct iucv_handler netiucv_handler = {
154 .path_pending = netiucv_callback_connreq,
155 .path_complete = netiucv_callback_connack,
156 .path_severed = netiucv_callback_connrej,
157 .path_quiesced = netiucv_callback_connsusp,
158 .path_resumed = netiucv_callback_connres,
159 .message_pending = netiucv_callback_rx,
160 .message_complete = netiucv_callback_txdone
164 * Per connection profiling data
166 struct connection_profile {
167 unsigned long maxmulti;
168 unsigned long maxcqueue;
169 unsigned long doios_single;
170 unsigned long doios_multi;
171 unsigned long txlen;
172 unsigned long tx_time;
173 struct timespec send_stamp;
174 unsigned long tx_pending;
175 unsigned long tx_max_pending;
179 * Representation of one iucv connection
181 struct iucv_connection {
182 struct list_head list;
183 struct iucv_path *path;
184 struct sk_buff *rx_buff;
185 struct sk_buff *tx_buff;
186 struct sk_buff_head collect_queue;
187 struct sk_buff_head commit_queue;
188 spinlock_t collect_lock;
189 int collect_len;
190 int max_buffsize;
191 fsm_timer timer;
192 fsm_instance *fsm;
193 struct net_device *netdev;
194 struct connection_profile prof;
195 char userid[9];
199 * Linked list of all connection structs.
201 static struct list_head iucv_connection_list =
202 LIST_HEAD_INIT(iucv_connection_list);
203 static DEFINE_RWLOCK(iucv_connection_rwlock);
206 * Representation of event-data for the
207 * connection state machine.
209 struct iucv_event {
210 struct iucv_connection *conn;
211 void *data;
215 * Private part of the network device structure
217 struct netiucv_priv {
218 struct net_device_stats stats;
219 unsigned long tbusy;
220 fsm_instance *fsm;
221 struct iucv_connection *conn;
222 struct device *dev;
226 * Link level header for a packet.
228 struct ll_header {
229 u16 next;
232 #define NETIUCV_HDRLEN (sizeof(struct ll_header))
233 #define NETIUCV_BUFSIZE_MAX 32768
234 #define NETIUCV_BUFSIZE_DEFAULT NETIUCV_BUFSIZE_MAX
235 #define NETIUCV_MTU_MAX (NETIUCV_BUFSIZE_MAX - NETIUCV_HDRLEN)
236 #define NETIUCV_MTU_DEFAULT 9216
237 #define NETIUCV_QUEUELEN_DEFAULT 50
238 #define NETIUCV_TIMEOUT_5SEC 5000
241 * Compatibility macros for busy handling
242 * of network devices.
244 static inline void netiucv_clear_busy(struct net_device *dev)
246 struct netiucv_priv *priv = netdev_priv(dev);
247 clear_bit(0, &priv->tbusy);
248 netif_wake_queue(dev);
251 static inline int netiucv_test_and_set_busy(struct net_device *dev)
253 struct netiucv_priv *priv = netdev_priv(dev);
254 netif_stop_queue(dev);
255 return test_and_set_bit(0, &priv->tbusy);
258 static u8 iucvMagic[16] = {
259 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
260 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
264 * Convert an iucv userId to its printable
265 * form (strip whitespace at end).
267 * @param An iucv userId
269 * @returns The printable string (static data!!)
271 static char *netiucv_printname(char *name)
273 static char tmp[9];
274 char *p = tmp;
275 memcpy(tmp, name, 8);
276 tmp[8] = '\0';
277 while (*p && (!isspace(*p)))
278 p++;
279 *p = '\0';
280 return tmp;
284 * States of the interface statemachine.
286 enum dev_states {
287 DEV_STATE_STOPPED,
288 DEV_STATE_STARTWAIT,
289 DEV_STATE_STOPWAIT,
290 DEV_STATE_RUNNING,
292 * MUST be always the last element!!
294 NR_DEV_STATES
297 static const char *dev_state_names[] = {
298 "Stopped",
299 "StartWait",
300 "StopWait",
301 "Running",
305 * Events of the interface statemachine.
307 enum dev_events {
308 DEV_EVENT_START,
309 DEV_EVENT_STOP,
310 DEV_EVENT_CONUP,
311 DEV_EVENT_CONDOWN,
313 * MUST be always the last element!!
315 NR_DEV_EVENTS
318 static const char *dev_event_names[] = {
319 "Start",
320 "Stop",
321 "Connection up",
322 "Connection down",
326 * Events of the connection statemachine
328 enum conn_events {
330 * Events, representing callbacks from
331 * lowlevel iucv layer)
333 CONN_EVENT_CONN_REQ,
334 CONN_EVENT_CONN_ACK,
335 CONN_EVENT_CONN_REJ,
336 CONN_EVENT_CONN_SUS,
337 CONN_EVENT_CONN_RES,
338 CONN_EVENT_RX,
339 CONN_EVENT_TXDONE,
342 * Events, representing errors return codes from
343 * calls to lowlevel iucv layer
347 * Event, representing timer expiry.
349 CONN_EVENT_TIMER,
352 * Events, representing commands from upper levels.
354 CONN_EVENT_START,
355 CONN_EVENT_STOP,
358 * MUST be always the last element!!
360 NR_CONN_EVENTS,
363 static const char *conn_event_names[] = {
364 "Remote connection request",
365 "Remote connection acknowledge",
366 "Remote connection reject",
367 "Connection suspended",
368 "Connection resumed",
369 "Data received",
370 "Data sent",
372 "Timer",
374 "Start",
375 "Stop",
379 * States of the connection statemachine.
381 enum conn_states {
383 * Connection not assigned to any device,
384 * initial state, invalid
386 CONN_STATE_INVALID,
389 * Userid assigned but not operating
391 CONN_STATE_STOPPED,
394 * Connection registered,
395 * no connection request sent yet,
396 * no connection request received
398 CONN_STATE_STARTWAIT,
401 * Connection registered and connection request sent,
402 * no acknowledge and no connection request received yet.
404 CONN_STATE_SETUPWAIT,
407 * Connection up and running idle
409 CONN_STATE_IDLE,
412 * Data sent, awaiting CONN_EVENT_TXDONE
414 CONN_STATE_TX,
417 * Error during registration.
419 CONN_STATE_REGERR,
422 * Error during registration.
424 CONN_STATE_CONNERR,
427 * MUST be always the last element!!
429 NR_CONN_STATES,
432 static const char *conn_state_names[] = {
433 "Invalid",
434 "Stopped",
435 "StartWait",
436 "SetupWait",
437 "Idle",
438 "TX",
439 "Terminating",
440 "Registration error",
441 "Connect error",
446 * Debug Facility Stuff
448 static debug_info_t *iucv_dbf_setup = NULL;
449 static debug_info_t *iucv_dbf_data = NULL;
450 static debug_info_t *iucv_dbf_trace = NULL;
452 DEFINE_PER_CPU(char[256], iucv_dbf_txt_buf);
454 static void iucv_unregister_dbf_views(void)
456 if (iucv_dbf_setup)
457 debug_unregister(iucv_dbf_setup);
458 if (iucv_dbf_data)
459 debug_unregister(iucv_dbf_data);
460 if (iucv_dbf_trace)
461 debug_unregister(iucv_dbf_trace);
463 static int iucv_register_dbf_views(void)
465 iucv_dbf_setup = debug_register(IUCV_DBF_SETUP_NAME,
466 IUCV_DBF_SETUP_PAGES,
467 IUCV_DBF_SETUP_NR_AREAS,
468 IUCV_DBF_SETUP_LEN);
469 iucv_dbf_data = debug_register(IUCV_DBF_DATA_NAME,
470 IUCV_DBF_DATA_PAGES,
471 IUCV_DBF_DATA_NR_AREAS,
472 IUCV_DBF_DATA_LEN);
473 iucv_dbf_trace = debug_register(IUCV_DBF_TRACE_NAME,
474 IUCV_DBF_TRACE_PAGES,
475 IUCV_DBF_TRACE_NR_AREAS,
476 IUCV_DBF_TRACE_LEN);
478 if ((iucv_dbf_setup == NULL) || (iucv_dbf_data == NULL) ||
479 (iucv_dbf_trace == NULL)) {
480 iucv_unregister_dbf_views();
481 return -ENOMEM;
483 debug_register_view(iucv_dbf_setup, &debug_hex_ascii_view);
484 debug_set_level(iucv_dbf_setup, IUCV_DBF_SETUP_LEVEL);
486 debug_register_view(iucv_dbf_data, &debug_hex_ascii_view);
487 debug_set_level(iucv_dbf_data, IUCV_DBF_DATA_LEVEL);
489 debug_register_view(iucv_dbf_trace, &debug_hex_ascii_view);
490 debug_set_level(iucv_dbf_trace, IUCV_DBF_TRACE_LEVEL);
492 return 0;
496 * Callback-wrappers, called from lowlevel iucv layer.
499 static void netiucv_callback_rx(struct iucv_path *path,
500 struct iucv_message *msg)
502 struct iucv_connection *conn = path->private;
503 struct iucv_event ev;
505 ev.conn = conn;
506 ev.data = msg;
507 fsm_event(conn->fsm, CONN_EVENT_RX, &ev);
510 static void netiucv_callback_txdone(struct iucv_path *path,
511 struct iucv_message *msg)
513 struct iucv_connection *conn = path->private;
514 struct iucv_event ev;
516 ev.conn = conn;
517 ev.data = msg;
518 fsm_event(conn->fsm, CONN_EVENT_TXDONE, &ev);
521 static void netiucv_callback_connack(struct iucv_path *path, u8 ipuser[16])
523 struct iucv_connection *conn = path->private;
525 fsm_event(conn->fsm, CONN_EVENT_CONN_ACK, conn);
528 static int netiucv_callback_connreq(struct iucv_path *path,
529 u8 ipvmid[8], u8 ipuser[16])
531 struct iucv_connection *conn = path->private;
532 struct iucv_event ev;
533 int rc;
535 if (memcmp(iucvMagic, ipuser, sizeof(ipuser)))
536 /* ipuser must match iucvMagic. */
537 return -EINVAL;
538 rc = -EINVAL;
539 read_lock_bh(&iucv_connection_rwlock);
540 list_for_each_entry(conn, &iucv_connection_list, list) {
541 if (strncmp(ipvmid, conn->userid, 8))
542 continue;
543 /* Found a matching connection for this path. */
544 conn->path = path;
545 ev.conn = conn;
546 ev.data = path;
547 fsm_event(conn->fsm, CONN_EVENT_CONN_REQ, &ev);
548 rc = 0;
550 read_unlock_bh(&iucv_connection_rwlock);
551 return rc;
554 static void netiucv_callback_connrej(struct iucv_path *path, u8 ipuser[16])
556 struct iucv_connection *conn = path->private;
558 fsm_event(conn->fsm, CONN_EVENT_CONN_REJ, conn);
561 static void netiucv_callback_connsusp(struct iucv_path *path, u8 ipuser[16])
563 struct iucv_connection *conn = path->private;
565 fsm_event(conn->fsm, CONN_EVENT_CONN_SUS, conn);
568 static void netiucv_callback_connres(struct iucv_path *path, u8 ipuser[16])
570 struct iucv_connection *conn = path->private;
572 fsm_event(conn->fsm, CONN_EVENT_CONN_RES, conn);
576 * Dummy NOP action for all statemachines
578 static void fsm_action_nop(fsm_instance *fi, int event, void *arg)
583 * Actions of the connection statemachine
587 * netiucv_unpack_skb
588 * @conn: The connection where this skb has been received.
589 * @pskb: The received skb.
591 * Unpack a just received skb and hand it over to upper layers.
592 * Helper function for conn_action_rx.
594 static void netiucv_unpack_skb(struct iucv_connection *conn,
595 struct sk_buff *pskb)
597 struct net_device *dev = conn->netdev;
598 struct netiucv_priv *privptr = netdev_priv(dev);
599 u16 offset = 0;
601 skb_put(pskb, NETIUCV_HDRLEN);
602 pskb->dev = dev;
603 pskb->ip_summed = CHECKSUM_NONE;
604 pskb->protocol = ntohs(ETH_P_IP);
606 while (1) {
607 struct sk_buff *skb;
608 struct ll_header *header = (struct ll_header *) pskb->data;
610 if (!header->next)
611 break;
613 skb_pull(pskb, NETIUCV_HDRLEN);
614 header->next -= offset;
615 offset += header->next;
616 header->next -= NETIUCV_HDRLEN;
617 if (skb_tailroom(pskb) < header->next) {
618 PRINT_WARN("%s: Illegal next field in iucv header: "
619 "%d > %d\n",
620 dev->name, header->next, skb_tailroom(pskb));
621 IUCV_DBF_TEXT_(data, 2, "Illegal next field: %d > %d\n",
622 header->next, skb_tailroom(pskb));
623 return;
625 skb_put(pskb, header->next);
626 skb_reset_mac_header(pskb);
627 skb = dev_alloc_skb(pskb->len);
628 if (!skb) {
629 PRINT_WARN("%s Out of memory in netiucv_unpack_skb\n",
630 dev->name);
631 IUCV_DBF_TEXT(data, 2,
632 "Out of memory in netiucv_unpack_skb\n");
633 privptr->stats.rx_dropped++;
634 return;
636 skb_copy_from_linear_data(pskb, skb_put(skb, pskb->len),
637 pskb->len);
638 skb_reset_mac_header(skb);
639 skb->dev = pskb->dev;
640 skb->protocol = pskb->protocol;
641 pskb->ip_summed = CHECKSUM_UNNECESSARY;
642 privptr->stats.rx_packets++;
643 privptr->stats.rx_bytes += skb->len;
645 * Since receiving is always initiated from a tasklet (in iucv.c),
646 * we must use netif_rx_ni() instead of netif_rx()
648 netif_rx_ni(skb);
649 dev->last_rx = jiffies;
650 skb_pull(pskb, header->next);
651 skb_put(pskb, NETIUCV_HDRLEN);
655 static void conn_action_rx(fsm_instance *fi, int event, void *arg)
657 struct iucv_event *ev = arg;
658 struct iucv_connection *conn = ev->conn;
659 struct iucv_message *msg = ev->data;
660 struct netiucv_priv *privptr = netdev_priv(conn->netdev);
661 int rc;
663 IUCV_DBF_TEXT(trace, 4, __FUNCTION__);
665 if (!conn->netdev) {
666 iucv_message_reject(conn->path, msg);
667 PRINT_WARN("Received data for unlinked connection\n");
668 IUCV_DBF_TEXT(data, 2,
669 "Received data for unlinked connection\n");
670 return;
672 if (msg->length > conn->max_buffsize) {
673 iucv_message_reject(conn->path, msg);
674 privptr->stats.rx_dropped++;
675 PRINT_WARN("msglen %d > max_buffsize %d\n",
676 msg->length, conn->max_buffsize);
677 IUCV_DBF_TEXT_(data, 2, "msglen %d > max_buffsize %d\n",
678 msg->length, conn->max_buffsize);
679 return;
681 conn->rx_buff->data = conn->rx_buff->head;
682 skb_reset_tail_pointer(conn->rx_buff);
683 conn->rx_buff->len = 0;
684 rc = iucv_message_receive(conn->path, msg, 0, conn->rx_buff->data,
685 msg->length, NULL);
686 if (rc || msg->length < 5) {
687 privptr->stats.rx_errors++;
688 PRINT_WARN("iucv_receive returned %08x\n", rc);
689 IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_receive\n", rc);
690 return;
692 netiucv_unpack_skb(conn, conn->rx_buff);
695 static void conn_action_txdone(fsm_instance *fi, int event, void *arg)
697 struct iucv_event *ev = arg;
698 struct iucv_connection *conn = ev->conn;
699 struct iucv_message *msg = ev->data;
700 struct iucv_message txmsg;
701 struct netiucv_priv *privptr = NULL;
702 u32 single_flag = msg->tag;
703 u32 txbytes = 0;
704 u32 txpackets = 0;
705 u32 stat_maxcq = 0;
706 struct sk_buff *skb;
707 unsigned long saveflags;
708 struct ll_header header;
709 int rc;
711 IUCV_DBF_TEXT(trace, 4, __FUNCTION__);
713 if (conn && conn->netdev)
714 privptr = netdev_priv(conn->netdev);
715 conn->prof.tx_pending--;
716 if (single_flag) {
717 if ((skb = skb_dequeue(&conn->commit_queue))) {
718 atomic_dec(&skb->users);
719 dev_kfree_skb_any(skb);
720 if (privptr) {
721 privptr->stats.tx_packets++;
722 privptr->stats.tx_bytes +=
723 (skb->len - NETIUCV_HDRLEN
724 - NETIUCV_HDRLEN);
728 conn->tx_buff->data = conn->tx_buff->head;
729 skb_reset_tail_pointer(conn->tx_buff);
730 conn->tx_buff->len = 0;
731 spin_lock_irqsave(&conn->collect_lock, saveflags);
732 while ((skb = skb_dequeue(&conn->collect_queue))) {
733 header.next = conn->tx_buff->len + skb->len + NETIUCV_HDRLEN;
734 memcpy(skb_put(conn->tx_buff, NETIUCV_HDRLEN), &header,
735 NETIUCV_HDRLEN);
736 skb_copy_from_linear_data(skb,
737 skb_put(conn->tx_buff, skb->len),
738 skb->len);
739 txbytes += skb->len;
740 txpackets++;
741 stat_maxcq++;
742 atomic_dec(&skb->users);
743 dev_kfree_skb_any(skb);
745 if (conn->collect_len > conn->prof.maxmulti)
746 conn->prof.maxmulti = conn->collect_len;
747 conn->collect_len = 0;
748 spin_unlock_irqrestore(&conn->collect_lock, saveflags);
749 if (conn->tx_buff->len == 0) {
750 fsm_newstate(fi, CONN_STATE_IDLE);
751 return;
754 header.next = 0;
755 memcpy(skb_put(conn->tx_buff, NETIUCV_HDRLEN), &header, NETIUCV_HDRLEN);
756 conn->prof.send_stamp = current_kernel_time();
757 txmsg.class = 0;
758 txmsg.tag = 0;
759 rc = iucv_message_send(conn->path, &txmsg, 0, 0,
760 conn->tx_buff->data, conn->tx_buff->len);
761 conn->prof.doios_multi++;
762 conn->prof.txlen += conn->tx_buff->len;
763 conn->prof.tx_pending++;
764 if (conn->prof.tx_pending > conn->prof.tx_max_pending)
765 conn->prof.tx_max_pending = conn->prof.tx_pending;
766 if (rc) {
767 conn->prof.tx_pending--;
768 fsm_newstate(fi, CONN_STATE_IDLE);
769 if (privptr)
770 privptr->stats.tx_errors += txpackets;
771 PRINT_WARN("iucv_send returned %08x\n", rc);
772 IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_send\n", rc);
773 } else {
774 if (privptr) {
775 privptr->stats.tx_packets += txpackets;
776 privptr->stats.tx_bytes += txbytes;
778 if (stat_maxcq > conn->prof.maxcqueue)
779 conn->prof.maxcqueue = stat_maxcq;
783 static void conn_action_connaccept(fsm_instance *fi, int event, void *arg)
785 struct iucv_event *ev = arg;
786 struct iucv_connection *conn = ev->conn;
787 struct iucv_path *path = ev->data;
788 struct net_device *netdev = conn->netdev;
789 struct netiucv_priv *privptr = netdev_priv(netdev);
790 int rc;
792 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
794 conn->path = path;
795 path->msglim = NETIUCV_QUEUELEN_DEFAULT;
796 path->flags = 0;
797 rc = iucv_path_accept(path, &netiucv_handler, NULL, conn);
798 if (rc) {
799 PRINT_WARN("%s: IUCV accept failed with error %d\n",
800 netdev->name, rc);
801 IUCV_DBF_TEXT_(setup, 2, "rc %d from iucv_accept", rc);
802 return;
804 fsm_newstate(fi, CONN_STATE_IDLE);
805 netdev->tx_queue_len = conn->path->msglim;
806 fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev);
809 static void conn_action_connreject(fsm_instance *fi, int event, void *arg)
811 struct iucv_event *ev = arg;
812 struct iucv_path *path = ev->data;
814 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
815 iucv_path_sever(path, NULL);
818 static void conn_action_connack(fsm_instance *fi, int event, void *arg)
820 struct iucv_connection *conn = arg;
821 struct net_device *netdev = conn->netdev;
822 struct netiucv_priv *privptr = netdev_priv(netdev);
824 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
825 fsm_deltimer(&conn->timer);
826 fsm_newstate(fi, CONN_STATE_IDLE);
827 netdev->tx_queue_len = conn->path->msglim;
828 fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev);
831 static void conn_action_conntimsev(fsm_instance *fi, int event, void *arg)
833 struct iucv_connection *conn = arg;
835 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
836 fsm_deltimer(&conn->timer);
837 iucv_path_sever(conn->path, NULL);
838 fsm_newstate(fi, CONN_STATE_STARTWAIT);
841 static void conn_action_connsever(fsm_instance *fi, int event, void *arg)
843 struct iucv_connection *conn = arg;
844 struct net_device *netdev = conn->netdev;
845 struct netiucv_priv *privptr = netdev_priv(netdev);
847 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
849 fsm_deltimer(&conn->timer);
850 iucv_path_sever(conn->path, NULL);
851 PRINT_INFO("%s: Remote dropped connection\n", netdev->name);
852 IUCV_DBF_TEXT(data, 2,
853 "conn_action_connsever: Remote dropped connection\n");
854 fsm_newstate(fi, CONN_STATE_STARTWAIT);
855 fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev);
858 static void conn_action_start(fsm_instance *fi, int event, void *arg)
860 struct iucv_connection *conn = arg;
861 int rc;
863 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
865 fsm_newstate(fi, CONN_STATE_STARTWAIT);
866 PRINT_DEBUG("%s('%s'): connecting ...\n",
867 conn->netdev->name, conn->userid);
870 * We must set the state before calling iucv_connect because the
871 * callback handler could be called at any point after the connection
872 * request is sent
875 fsm_newstate(fi, CONN_STATE_SETUPWAIT);
876 conn->path = iucv_path_alloc(NETIUCV_QUEUELEN_DEFAULT, 0, GFP_KERNEL);
877 rc = iucv_path_connect(conn->path, &netiucv_handler, conn->userid,
878 NULL, iucvMagic, conn);
879 switch (rc) {
880 case 0:
881 conn->netdev->tx_queue_len = conn->path->msglim;
882 fsm_addtimer(&conn->timer, NETIUCV_TIMEOUT_5SEC,
883 CONN_EVENT_TIMER, conn);
884 return;
885 case 11:
886 PRINT_INFO("%s: User %s is currently not available.\n",
887 conn->netdev->name,
888 netiucv_printname(conn->userid));
889 fsm_newstate(fi, CONN_STATE_STARTWAIT);
890 break;
891 case 12:
892 PRINT_INFO("%s: User %s is currently not ready.\n",
893 conn->netdev->name,
894 netiucv_printname(conn->userid));
895 fsm_newstate(fi, CONN_STATE_STARTWAIT);
896 break;
897 case 13:
898 PRINT_WARN("%s: Too many IUCV connections.\n",
899 conn->netdev->name);
900 fsm_newstate(fi, CONN_STATE_CONNERR);
901 break;
902 case 14:
903 PRINT_WARN("%s: User %s has too many IUCV connections.\n",
904 conn->netdev->name,
905 netiucv_printname(conn->userid));
906 fsm_newstate(fi, CONN_STATE_CONNERR);
907 break;
908 case 15:
909 PRINT_WARN("%s: No IUCV authorization in CP directory.\n",
910 conn->netdev->name);
911 fsm_newstate(fi, CONN_STATE_CONNERR);
912 break;
913 default:
914 PRINT_WARN("%s: iucv_connect returned error %d\n",
915 conn->netdev->name, rc);
916 fsm_newstate(fi, CONN_STATE_CONNERR);
917 break;
919 IUCV_DBF_TEXT_(setup, 5, "iucv_connect rc is %d\n", rc);
920 kfree(conn->path);
921 conn->path = NULL;
924 static void netiucv_purge_skb_queue(struct sk_buff_head *q)
926 struct sk_buff *skb;
928 while ((skb = skb_dequeue(q))) {
929 atomic_dec(&skb->users);
930 dev_kfree_skb_any(skb);
934 static void conn_action_stop(fsm_instance *fi, int event, void *arg)
936 struct iucv_event *ev = arg;
937 struct iucv_connection *conn = ev->conn;
938 struct net_device *netdev = conn->netdev;
939 struct netiucv_priv *privptr = netdev_priv(netdev);
941 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
943 fsm_deltimer(&conn->timer);
944 fsm_newstate(fi, CONN_STATE_STOPPED);
945 netiucv_purge_skb_queue(&conn->collect_queue);
946 if (conn->path) {
947 IUCV_DBF_TEXT(trace, 5, "calling iucv_path_sever\n");
948 iucv_path_sever(conn->path, iucvMagic);
949 kfree(conn->path);
950 conn->path = NULL;
952 netiucv_purge_skb_queue(&conn->commit_queue);
953 fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev);
956 static void conn_action_inval(fsm_instance *fi, int event, void *arg)
958 struct iucv_connection *conn = arg;
959 struct net_device *netdev = conn->netdev;
961 PRINT_WARN("%s: Cannot connect without username\n", netdev->name);
962 IUCV_DBF_TEXT(data, 2, "conn_action_inval called\n");
965 static const fsm_node conn_fsm[] = {
966 { CONN_STATE_INVALID, CONN_EVENT_START, conn_action_inval },
967 { CONN_STATE_STOPPED, CONN_EVENT_START, conn_action_start },
969 { CONN_STATE_STOPPED, CONN_EVENT_STOP, conn_action_stop },
970 { CONN_STATE_STARTWAIT, CONN_EVENT_STOP, conn_action_stop },
971 { CONN_STATE_SETUPWAIT, CONN_EVENT_STOP, conn_action_stop },
972 { CONN_STATE_IDLE, CONN_EVENT_STOP, conn_action_stop },
973 { CONN_STATE_TX, CONN_EVENT_STOP, conn_action_stop },
974 { CONN_STATE_REGERR, CONN_EVENT_STOP, conn_action_stop },
975 { CONN_STATE_CONNERR, CONN_EVENT_STOP, conn_action_stop },
977 { CONN_STATE_STOPPED, CONN_EVENT_CONN_REQ, conn_action_connreject },
978 { CONN_STATE_STARTWAIT, CONN_EVENT_CONN_REQ, conn_action_connaccept },
979 { CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_REQ, conn_action_connaccept },
980 { CONN_STATE_IDLE, CONN_EVENT_CONN_REQ, conn_action_connreject },
981 { CONN_STATE_TX, CONN_EVENT_CONN_REQ, conn_action_connreject },
983 { CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_ACK, conn_action_connack },
984 { CONN_STATE_SETUPWAIT, CONN_EVENT_TIMER, conn_action_conntimsev },
986 { CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_REJ, conn_action_connsever },
987 { CONN_STATE_IDLE, CONN_EVENT_CONN_REJ, conn_action_connsever },
988 { CONN_STATE_TX, CONN_EVENT_CONN_REJ, conn_action_connsever },
990 { CONN_STATE_IDLE, CONN_EVENT_RX, conn_action_rx },
991 { CONN_STATE_TX, CONN_EVENT_RX, conn_action_rx },
993 { CONN_STATE_TX, CONN_EVENT_TXDONE, conn_action_txdone },
994 { CONN_STATE_IDLE, CONN_EVENT_TXDONE, conn_action_txdone },
997 static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node);
1001 * Actions for interface - statemachine.
1005 * dev_action_start
1006 * @fi: An instance of an interface statemachine.
1007 * @event: The event, just happened.
1008 * @arg: Generic pointer, casted from struct net_device * upon call.
1010 * Startup connection by sending CONN_EVENT_START to it.
1012 static void dev_action_start(fsm_instance *fi, int event, void *arg)
1014 struct net_device *dev = arg;
1015 struct netiucv_priv *privptr = netdev_priv(dev);
1017 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1019 fsm_newstate(fi, DEV_STATE_STARTWAIT);
1020 fsm_event(privptr->conn->fsm, CONN_EVENT_START, privptr->conn);
1024 * Shutdown connection by sending CONN_EVENT_STOP to it.
1026 * @param fi An instance of an interface statemachine.
1027 * @param event The event, just happened.
1028 * @param arg Generic pointer, casted from struct net_device * upon call.
1030 static void
1031 dev_action_stop(fsm_instance *fi, int event, void *arg)
1033 struct net_device *dev = arg;
1034 struct netiucv_priv *privptr = netdev_priv(dev);
1035 struct iucv_event ev;
1037 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1039 ev.conn = privptr->conn;
1041 fsm_newstate(fi, DEV_STATE_STOPWAIT);
1042 fsm_event(privptr->conn->fsm, CONN_EVENT_STOP, &ev);
1046 * Called from connection statemachine
1047 * when a connection is up and running.
1049 * @param fi An instance of an interface statemachine.
1050 * @param event The event, just happened.
1051 * @param arg Generic pointer, casted from struct net_device * upon call.
1053 static void
1054 dev_action_connup(fsm_instance *fi, int event, void *arg)
1056 struct net_device *dev = arg;
1057 struct netiucv_priv *privptr = netdev_priv(dev);
1059 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1061 switch (fsm_getstate(fi)) {
1062 case DEV_STATE_STARTWAIT:
1063 fsm_newstate(fi, DEV_STATE_RUNNING);
1064 PRINT_INFO("%s: connected with remote side %s\n",
1065 dev->name, privptr->conn->userid);
1066 IUCV_DBF_TEXT(setup, 3,
1067 "connection is up and running\n");
1068 break;
1069 case DEV_STATE_STOPWAIT:
1070 PRINT_INFO(
1071 "%s: got connection UP event during shutdown!\n",
1072 dev->name);
1073 IUCV_DBF_TEXT(data, 2,
1074 "dev_action_connup: in DEV_STATE_STOPWAIT\n");
1075 break;
1080 * Called from connection statemachine
1081 * when a connection has been shutdown.
1083 * @param fi An instance of an interface statemachine.
1084 * @param event The event, just happened.
1085 * @param arg Generic pointer, casted from struct net_device * upon call.
1087 static void
1088 dev_action_conndown(fsm_instance *fi, int event, void *arg)
1090 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1092 switch (fsm_getstate(fi)) {
1093 case DEV_STATE_RUNNING:
1094 fsm_newstate(fi, DEV_STATE_STARTWAIT);
1095 break;
1096 case DEV_STATE_STOPWAIT:
1097 fsm_newstate(fi, DEV_STATE_STOPPED);
1098 IUCV_DBF_TEXT(setup, 3, "connection is down\n");
1099 break;
1103 static const fsm_node dev_fsm[] = {
1104 { DEV_STATE_STOPPED, DEV_EVENT_START, dev_action_start },
1106 { DEV_STATE_STOPWAIT, DEV_EVENT_START, dev_action_start },
1107 { DEV_STATE_STOPWAIT, DEV_EVENT_CONDOWN, dev_action_conndown },
1109 { DEV_STATE_STARTWAIT, DEV_EVENT_STOP, dev_action_stop },
1110 { DEV_STATE_STARTWAIT, DEV_EVENT_CONUP, dev_action_connup },
1112 { DEV_STATE_RUNNING, DEV_EVENT_STOP, dev_action_stop },
1113 { DEV_STATE_RUNNING, DEV_EVENT_CONDOWN, dev_action_conndown },
1114 { DEV_STATE_RUNNING, DEV_EVENT_CONUP, fsm_action_nop },
1117 static const int DEV_FSM_LEN = sizeof(dev_fsm) / sizeof(fsm_node);
1120 * Transmit a packet.
1121 * This is a helper function for netiucv_tx().
1123 * @param conn Connection to be used for sending.
1124 * @param skb Pointer to struct sk_buff of packet to send.
1125 * The linklevel header has already been set up
1126 * by netiucv_tx().
1128 * @return 0 on success, -ERRNO on failure. (Never fails.)
1130 static int netiucv_transmit_skb(struct iucv_connection *conn,
1131 struct sk_buff *skb)
1133 struct iucv_message msg;
1134 unsigned long saveflags;
1135 struct ll_header header;
1136 int rc;
1138 if (fsm_getstate(conn->fsm) != CONN_STATE_IDLE) {
1139 int l = skb->len + NETIUCV_HDRLEN;
1141 spin_lock_irqsave(&conn->collect_lock, saveflags);
1142 if (conn->collect_len + l >
1143 (conn->max_buffsize - NETIUCV_HDRLEN)) {
1144 rc = -EBUSY;
1145 IUCV_DBF_TEXT(data, 2,
1146 "EBUSY from netiucv_transmit_skb\n");
1147 } else {
1148 atomic_inc(&skb->users);
1149 skb_queue_tail(&conn->collect_queue, skb);
1150 conn->collect_len += l;
1151 rc = 0;
1153 spin_unlock_irqrestore(&conn->collect_lock, saveflags);
1154 } else {
1155 struct sk_buff *nskb = skb;
1157 * Copy the skb to a new allocated skb in lowmem only if the
1158 * data is located above 2G in memory or tailroom is < 2.
1160 unsigned long hi = ((unsigned long)(skb_tail_pointer(skb) +
1161 NETIUCV_HDRLEN)) >> 31;
1162 int copied = 0;
1163 if (hi || (skb_tailroom(skb) < 2)) {
1164 nskb = alloc_skb(skb->len + NETIUCV_HDRLEN +
1165 NETIUCV_HDRLEN, GFP_ATOMIC | GFP_DMA);
1166 if (!nskb) {
1167 PRINT_WARN("%s: Could not allocate tx_skb\n",
1168 conn->netdev->name);
1169 IUCV_DBF_TEXT(data, 2, "alloc_skb failed\n");
1170 rc = -ENOMEM;
1171 return rc;
1172 } else {
1173 skb_reserve(nskb, NETIUCV_HDRLEN);
1174 memcpy(skb_put(nskb, skb->len),
1175 skb->data, skb->len);
1177 copied = 1;
1180 * skb now is below 2G and has enough room. Add headers.
1182 header.next = nskb->len + NETIUCV_HDRLEN;
1183 memcpy(skb_push(nskb, NETIUCV_HDRLEN), &header, NETIUCV_HDRLEN);
1184 header.next = 0;
1185 memcpy(skb_put(nskb, NETIUCV_HDRLEN), &header, NETIUCV_HDRLEN);
1187 fsm_newstate(conn->fsm, CONN_STATE_TX);
1188 conn->prof.send_stamp = current_kernel_time();
1190 msg.tag = 1;
1191 msg.class = 0;
1192 rc = iucv_message_send(conn->path, &msg, 0, 0,
1193 nskb->data, nskb->len);
1194 conn->prof.doios_single++;
1195 conn->prof.txlen += skb->len;
1196 conn->prof.tx_pending++;
1197 if (conn->prof.tx_pending > conn->prof.tx_max_pending)
1198 conn->prof.tx_max_pending = conn->prof.tx_pending;
1199 if (rc) {
1200 struct netiucv_priv *privptr;
1201 fsm_newstate(conn->fsm, CONN_STATE_IDLE);
1202 conn->prof.tx_pending--;
1203 privptr = netdev_priv(conn->netdev);
1204 if (privptr)
1205 privptr->stats.tx_errors++;
1206 if (copied)
1207 dev_kfree_skb(nskb);
1208 else {
1210 * Remove our headers. They get added
1211 * again on retransmit.
1213 skb_pull(skb, NETIUCV_HDRLEN);
1214 skb_trim(skb, skb->len - NETIUCV_HDRLEN);
1216 PRINT_WARN("iucv_send returned %08x\n", rc);
1217 IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_send\n", rc);
1218 } else {
1219 if (copied)
1220 dev_kfree_skb(skb);
1221 atomic_inc(&nskb->users);
1222 skb_queue_tail(&conn->commit_queue, nskb);
1226 return rc;
1230 * Interface API for upper network layers
1234 * Open an interface.
1235 * Called from generic network layer when ifconfig up is run.
1237 * @param dev Pointer to interface struct.
1239 * @return 0 on success, -ERRNO on failure. (Never fails.)
1241 static int netiucv_open(struct net_device *dev)
1243 struct netiucv_priv *priv = netdev_priv(dev);
1245 fsm_event(priv->fsm, DEV_EVENT_START, dev);
1246 return 0;
1250 * Close an interface.
1251 * Called from generic network layer when ifconfig down is run.
1253 * @param dev Pointer to interface struct.
1255 * @return 0 on success, -ERRNO on failure. (Never fails.)
1257 static int netiucv_close(struct net_device *dev)
1259 struct netiucv_priv *priv = netdev_priv(dev);
1261 fsm_event(priv->fsm, DEV_EVENT_STOP, dev);
1262 return 0;
1266 * Start transmission of a packet.
1267 * Called from generic network device layer.
1269 * @param skb Pointer to buffer containing the packet.
1270 * @param dev Pointer to interface struct.
1272 * @return 0 if packet consumed, !0 if packet rejected.
1273 * Note: If we return !0, then the packet is free'd by
1274 * the generic network layer.
1276 static int netiucv_tx(struct sk_buff *skb, struct net_device *dev)
1278 struct netiucv_priv *privptr = netdev_priv(dev);
1279 int rc;
1281 IUCV_DBF_TEXT(trace, 4, __FUNCTION__);
1283 * Some sanity checks ...
1285 if (skb == NULL) {
1286 PRINT_WARN("%s: NULL sk_buff passed\n", dev->name);
1287 IUCV_DBF_TEXT(data, 2, "netiucv_tx: skb is NULL\n");
1288 privptr->stats.tx_dropped++;
1289 return 0;
1291 if (skb_headroom(skb) < NETIUCV_HDRLEN) {
1292 PRINT_WARN("%s: Got sk_buff with head room < %ld bytes\n",
1293 dev->name, NETIUCV_HDRLEN);
1294 IUCV_DBF_TEXT(data, 2,
1295 "netiucv_tx: skb_headroom < NETIUCV_HDRLEN\n");
1296 dev_kfree_skb(skb);
1297 privptr->stats.tx_dropped++;
1298 return 0;
1302 * If connection is not running, try to restart it
1303 * and throw away packet.
1305 if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) {
1306 if (!in_atomic())
1307 fsm_event(privptr->fsm, DEV_EVENT_START, dev);
1308 dev_kfree_skb(skb);
1309 privptr->stats.tx_dropped++;
1310 privptr->stats.tx_errors++;
1311 privptr->stats.tx_carrier_errors++;
1312 return 0;
1315 if (netiucv_test_and_set_busy(dev)) {
1316 IUCV_DBF_TEXT(data, 2, "EBUSY from netiucv_tx\n");
1317 return -EBUSY;
1319 dev->trans_start = jiffies;
1320 rc = netiucv_transmit_skb(privptr->conn, skb) != 0;
1321 netiucv_clear_busy(dev);
1322 return rc;
1326 * netiucv_stats
1327 * @dev: Pointer to interface struct.
1329 * Returns interface statistics of a device.
1331 * Returns pointer to stats struct of this interface.
1333 static struct net_device_stats *netiucv_stats (struct net_device * dev)
1335 struct netiucv_priv *priv = netdev_priv(dev);
1337 IUCV_DBF_TEXT(trace, 5, __FUNCTION__);
1338 return &priv->stats;
1342 * netiucv_change_mtu
1343 * @dev: Pointer to interface struct.
1344 * @new_mtu: The new MTU to use for this interface.
1346 * Sets MTU of an interface.
1348 * Returns 0 on success, -EINVAL if MTU is out of valid range.
1349 * (valid range is 576 .. NETIUCV_MTU_MAX).
1351 static int netiucv_change_mtu(struct net_device * dev, int new_mtu)
1353 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1354 if (new_mtu < 576 || new_mtu > NETIUCV_MTU_MAX) {
1355 IUCV_DBF_TEXT(setup, 2, "given MTU out of valid range\n");
1356 return -EINVAL;
1358 dev->mtu = new_mtu;
1359 return 0;
1363 * attributes in sysfs
1366 static ssize_t user_show(struct device *dev, struct device_attribute *attr,
1367 char *buf)
1369 struct netiucv_priv *priv = dev->driver_data;
1371 IUCV_DBF_TEXT(trace, 5, __FUNCTION__);
1372 return sprintf(buf, "%s\n", netiucv_printname(priv->conn->userid));
1375 static ssize_t user_write(struct device *dev, struct device_attribute *attr,
1376 const char *buf, size_t count)
1378 struct netiucv_priv *priv = dev->driver_data;
1379 struct net_device *ndev = priv->conn->netdev;
1380 char *p;
1381 char *tmp;
1382 char username[9];
1383 int i;
1384 struct iucv_connection *cp;
1386 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1387 if (count > 9) {
1388 PRINT_WARN("netiucv: username too long (%d)!\n", (int) count);
1389 IUCV_DBF_TEXT_(setup, 2,
1390 "%d is length of username\n", (int) count);
1391 return -EINVAL;
1394 tmp = strsep((char **) &buf, "\n");
1395 for (i = 0, p = tmp; i < 8 && *p; i++, p++) {
1396 if (isalnum(*p) || (*p == '$')) {
1397 username[i]= toupper(*p);
1398 continue;
1400 if (*p == '\n') {
1401 /* trailing lf, grr */
1402 break;
1404 PRINT_WARN("netiucv: Invalid char %c in username!\n", *p);
1405 IUCV_DBF_TEXT_(setup, 2,
1406 "username: invalid character %c\n", *p);
1407 return -EINVAL;
1409 while (i < 8)
1410 username[i++] = ' ';
1411 username[8] = '\0';
1413 if (memcmp(username, priv->conn->userid, 9) &&
1414 (ndev->flags & (IFF_UP | IFF_RUNNING))) {
1415 /* username changed while the interface is active. */
1416 PRINT_WARN("netiucv: device %s active, connected to %s\n",
1417 dev->bus_id, priv->conn->userid);
1418 PRINT_WARN("netiucv: user cannot be updated\n");
1419 IUCV_DBF_TEXT(setup, 2, "user_write: device active\n");
1420 return -EBUSY;
1422 read_lock_bh(&iucv_connection_rwlock);
1423 list_for_each_entry(cp, &iucv_connection_list, list) {
1424 if (!strncmp(username, cp->userid, 9) && cp->netdev != ndev) {
1425 read_unlock_bh(&iucv_connection_rwlock);
1426 PRINT_WARN("netiucv: Connection to %s already "
1427 "exists\n", username);
1428 return -EEXIST;
1431 read_unlock_bh(&iucv_connection_rwlock);
1432 memcpy(priv->conn->userid, username, 9);
1433 return count;
1436 static DEVICE_ATTR(user, 0644, user_show, user_write);
1438 static ssize_t buffer_show (struct device *dev, struct device_attribute *attr,
1439 char *buf)
1440 { struct netiucv_priv *priv = dev->driver_data;
1442 IUCV_DBF_TEXT(trace, 5, __FUNCTION__);
1443 return sprintf(buf, "%d\n", priv->conn->max_buffsize);
1446 static ssize_t buffer_write (struct device *dev, struct device_attribute *attr,
1447 const char *buf, size_t count)
1449 struct netiucv_priv *priv = dev->driver_data;
1450 struct net_device *ndev = priv->conn->netdev;
1451 char *e;
1452 int bs1;
1454 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1455 if (count >= 39)
1456 return -EINVAL;
1458 bs1 = simple_strtoul(buf, &e, 0);
1460 if (e && (!isspace(*e))) {
1461 PRINT_WARN("netiucv: Invalid character in buffer!\n");
1462 IUCV_DBF_TEXT_(setup, 2, "buffer_write: invalid char %c\n", *e);
1463 return -EINVAL;
1465 if (bs1 > NETIUCV_BUFSIZE_MAX) {
1466 PRINT_WARN("netiucv: Given buffer size %d too large.\n",
1467 bs1);
1468 IUCV_DBF_TEXT_(setup, 2,
1469 "buffer_write: buffer size %d too large\n",
1470 bs1);
1471 return -EINVAL;
1473 if ((ndev->flags & IFF_RUNNING) &&
1474 (bs1 < (ndev->mtu + NETIUCV_HDRLEN + 2))) {
1475 PRINT_WARN("netiucv: Given buffer size %d too small.\n",
1476 bs1);
1477 IUCV_DBF_TEXT_(setup, 2,
1478 "buffer_write: buffer size %d too small\n",
1479 bs1);
1480 return -EINVAL;
1482 if (bs1 < (576 + NETIUCV_HDRLEN + NETIUCV_HDRLEN)) {
1483 PRINT_WARN("netiucv: Given buffer size %d too small.\n",
1484 bs1);
1485 IUCV_DBF_TEXT_(setup, 2,
1486 "buffer_write: buffer size %d too small\n",
1487 bs1);
1488 return -EINVAL;
1491 priv->conn->max_buffsize = bs1;
1492 if (!(ndev->flags & IFF_RUNNING))
1493 ndev->mtu = bs1 - NETIUCV_HDRLEN - NETIUCV_HDRLEN;
1495 return count;
1499 static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write);
1501 static ssize_t dev_fsm_show (struct device *dev, struct device_attribute *attr,
1502 char *buf)
1504 struct netiucv_priv *priv = dev->driver_data;
1506 IUCV_DBF_TEXT(trace, 5, __FUNCTION__);
1507 return sprintf(buf, "%s\n", fsm_getstate_str(priv->fsm));
1510 static DEVICE_ATTR(device_fsm_state, 0444, dev_fsm_show, NULL);
1512 static ssize_t conn_fsm_show (struct device *dev,
1513 struct device_attribute *attr, char *buf)
1515 struct netiucv_priv *priv = dev->driver_data;
1517 IUCV_DBF_TEXT(trace, 5, __FUNCTION__);
1518 return sprintf(buf, "%s\n", fsm_getstate_str(priv->conn->fsm));
1521 static DEVICE_ATTR(connection_fsm_state, 0444, conn_fsm_show, NULL);
1523 static ssize_t maxmulti_show (struct device *dev,
1524 struct device_attribute *attr, char *buf)
1526 struct netiucv_priv *priv = dev->driver_data;
1528 IUCV_DBF_TEXT(trace, 5, __FUNCTION__);
1529 return sprintf(buf, "%ld\n", priv->conn->prof.maxmulti);
1532 static ssize_t maxmulti_write (struct device *dev,
1533 struct device_attribute *attr,
1534 const char *buf, size_t count)
1536 struct netiucv_priv *priv = dev->driver_data;
1538 IUCV_DBF_TEXT(trace, 4, __FUNCTION__);
1539 priv->conn->prof.maxmulti = 0;
1540 return count;
1543 static DEVICE_ATTR(max_tx_buffer_used, 0644, maxmulti_show, maxmulti_write);
1545 static ssize_t maxcq_show (struct device *dev, struct device_attribute *attr,
1546 char *buf)
1548 struct netiucv_priv *priv = dev->driver_data;
1550 IUCV_DBF_TEXT(trace, 5, __FUNCTION__);
1551 return sprintf(buf, "%ld\n", priv->conn->prof.maxcqueue);
1554 static ssize_t maxcq_write (struct device *dev, struct device_attribute *attr,
1555 const char *buf, size_t count)
1557 struct netiucv_priv *priv = dev->driver_data;
1559 IUCV_DBF_TEXT(trace, 4, __FUNCTION__);
1560 priv->conn->prof.maxcqueue = 0;
1561 return count;
1564 static DEVICE_ATTR(max_chained_skbs, 0644, maxcq_show, maxcq_write);
1566 static ssize_t sdoio_show (struct device *dev, struct device_attribute *attr,
1567 char *buf)
1569 struct netiucv_priv *priv = dev->driver_data;
1571 IUCV_DBF_TEXT(trace, 5, __FUNCTION__);
1572 return sprintf(buf, "%ld\n", priv->conn->prof.doios_single);
1575 static ssize_t sdoio_write (struct device *dev, struct device_attribute *attr,
1576 const char *buf, size_t count)
1578 struct netiucv_priv *priv = dev->driver_data;
1580 IUCV_DBF_TEXT(trace, 4, __FUNCTION__);
1581 priv->conn->prof.doios_single = 0;
1582 return count;
1585 static DEVICE_ATTR(tx_single_write_ops, 0644, sdoio_show, sdoio_write);
1587 static ssize_t mdoio_show (struct device *dev, struct device_attribute *attr,
1588 char *buf)
1590 struct netiucv_priv *priv = dev->driver_data;
1592 IUCV_DBF_TEXT(trace, 5, __FUNCTION__);
1593 return sprintf(buf, "%ld\n", priv->conn->prof.doios_multi);
1596 static ssize_t mdoio_write (struct device *dev, struct device_attribute *attr,
1597 const char *buf, size_t count)
1599 struct netiucv_priv *priv = dev->driver_data;
1601 IUCV_DBF_TEXT(trace, 5, __FUNCTION__);
1602 priv->conn->prof.doios_multi = 0;
1603 return count;
1606 static DEVICE_ATTR(tx_multi_write_ops, 0644, mdoio_show, mdoio_write);
1608 static ssize_t txlen_show (struct device *dev, struct device_attribute *attr,
1609 char *buf)
1611 struct netiucv_priv *priv = dev->driver_data;
1613 IUCV_DBF_TEXT(trace, 5, __FUNCTION__);
1614 return sprintf(buf, "%ld\n", priv->conn->prof.txlen);
1617 static ssize_t txlen_write (struct device *dev, struct device_attribute *attr,
1618 const char *buf, size_t count)
1620 struct netiucv_priv *priv = dev->driver_data;
1622 IUCV_DBF_TEXT(trace, 4, __FUNCTION__);
1623 priv->conn->prof.txlen = 0;
1624 return count;
1627 static DEVICE_ATTR(netto_bytes, 0644, txlen_show, txlen_write);
1629 static ssize_t txtime_show (struct device *dev, struct device_attribute *attr,
1630 char *buf)
1632 struct netiucv_priv *priv = dev->driver_data;
1634 IUCV_DBF_TEXT(trace, 5, __FUNCTION__);
1635 return sprintf(buf, "%ld\n", priv->conn->prof.tx_time);
1638 static ssize_t txtime_write (struct device *dev, struct device_attribute *attr,
1639 const char *buf, size_t count)
1641 struct netiucv_priv *priv = dev->driver_data;
1643 IUCV_DBF_TEXT(trace, 4, __FUNCTION__);
1644 priv->conn->prof.tx_time = 0;
1645 return count;
1648 static DEVICE_ATTR(max_tx_io_time, 0644, txtime_show, txtime_write);
1650 static ssize_t txpend_show (struct device *dev, struct device_attribute *attr,
1651 char *buf)
1653 struct netiucv_priv *priv = dev->driver_data;
1655 IUCV_DBF_TEXT(trace, 5, __FUNCTION__);
1656 return sprintf(buf, "%ld\n", priv->conn->prof.tx_pending);
1659 static ssize_t txpend_write (struct device *dev, struct device_attribute *attr,
1660 const char *buf, size_t count)
1662 struct netiucv_priv *priv = dev->driver_data;
1664 IUCV_DBF_TEXT(trace, 4, __FUNCTION__);
1665 priv->conn->prof.tx_pending = 0;
1666 return count;
1669 static DEVICE_ATTR(tx_pending, 0644, txpend_show, txpend_write);
1671 static ssize_t txmpnd_show (struct device *dev, struct device_attribute *attr,
1672 char *buf)
1674 struct netiucv_priv *priv = dev->driver_data;
1676 IUCV_DBF_TEXT(trace, 5, __FUNCTION__);
1677 return sprintf(buf, "%ld\n", priv->conn->prof.tx_max_pending);
1680 static ssize_t txmpnd_write (struct device *dev, struct device_attribute *attr,
1681 const char *buf, size_t count)
1683 struct netiucv_priv *priv = dev->driver_data;
1685 IUCV_DBF_TEXT(trace, 4, __FUNCTION__);
1686 priv->conn->prof.tx_max_pending = 0;
1687 return count;
1690 static DEVICE_ATTR(tx_max_pending, 0644, txmpnd_show, txmpnd_write);
1692 static struct attribute *netiucv_attrs[] = {
1693 &dev_attr_buffer.attr,
1694 &dev_attr_user.attr,
1695 NULL,
1698 static struct attribute_group netiucv_attr_group = {
1699 .attrs = netiucv_attrs,
1702 static struct attribute *netiucv_stat_attrs[] = {
1703 &dev_attr_device_fsm_state.attr,
1704 &dev_attr_connection_fsm_state.attr,
1705 &dev_attr_max_tx_buffer_used.attr,
1706 &dev_attr_max_chained_skbs.attr,
1707 &dev_attr_tx_single_write_ops.attr,
1708 &dev_attr_tx_multi_write_ops.attr,
1709 &dev_attr_netto_bytes.attr,
1710 &dev_attr_max_tx_io_time.attr,
1711 &dev_attr_tx_pending.attr,
1712 &dev_attr_tx_max_pending.attr,
1713 NULL,
1716 static struct attribute_group netiucv_stat_attr_group = {
1717 .name = "stats",
1718 .attrs = netiucv_stat_attrs,
1721 static int netiucv_add_files(struct device *dev)
1723 int ret;
1725 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1726 ret = sysfs_create_group(&dev->kobj, &netiucv_attr_group);
1727 if (ret)
1728 return ret;
1729 ret = sysfs_create_group(&dev->kobj, &netiucv_stat_attr_group);
1730 if (ret)
1731 sysfs_remove_group(&dev->kobj, &netiucv_attr_group);
1732 return ret;
1735 static void netiucv_remove_files(struct device *dev)
1737 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1738 sysfs_remove_group(&dev->kobj, &netiucv_stat_attr_group);
1739 sysfs_remove_group(&dev->kobj, &netiucv_attr_group);
1742 static int netiucv_register_device(struct net_device *ndev)
1744 struct netiucv_priv *priv = netdev_priv(ndev);
1745 struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL);
1746 int ret;
1749 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1751 if (dev) {
1752 snprintf(dev->bus_id, BUS_ID_SIZE, "net%s", ndev->name);
1753 dev->bus = &iucv_bus;
1754 dev->parent = iucv_root;
1756 * The release function could be called after the
1757 * module has been unloaded. It's _only_ task is to
1758 * free the struct. Therefore, we specify kfree()
1759 * directly here. (Probably a little bit obfuscating
1760 * but legitime ...).
1762 dev->release = (void (*)(struct device *))kfree;
1763 dev->driver = &netiucv_driver;
1764 } else
1765 return -ENOMEM;
1767 ret = device_register(dev);
1769 if (ret)
1770 return ret;
1771 ret = netiucv_add_files(dev);
1772 if (ret)
1773 goto out_unreg;
1774 priv->dev = dev;
1775 dev->driver_data = priv;
1776 return 0;
1778 out_unreg:
1779 device_unregister(dev);
1780 return ret;
1783 static void netiucv_unregister_device(struct device *dev)
1785 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1786 netiucv_remove_files(dev);
1787 device_unregister(dev);
1791 * Allocate and initialize a new connection structure.
1792 * Add it to the list of netiucv connections;
1794 static struct iucv_connection *netiucv_new_connection(struct net_device *dev,
1795 char *username)
1797 struct iucv_connection *conn;
1799 conn = kzalloc(sizeof(*conn), GFP_KERNEL);
1800 if (!conn)
1801 goto out;
1802 skb_queue_head_init(&conn->collect_queue);
1803 skb_queue_head_init(&conn->commit_queue);
1804 spin_lock_init(&conn->collect_lock);
1805 conn->max_buffsize = NETIUCV_BUFSIZE_DEFAULT;
1806 conn->netdev = dev;
1808 conn->rx_buff = alloc_skb(conn->max_buffsize, GFP_KERNEL | GFP_DMA);
1809 if (!conn->rx_buff)
1810 goto out_conn;
1811 conn->tx_buff = alloc_skb(conn->max_buffsize, GFP_KERNEL | GFP_DMA);
1812 if (!conn->tx_buff)
1813 goto out_rx;
1814 conn->fsm = init_fsm("netiucvconn", conn_state_names,
1815 conn_event_names, NR_CONN_STATES,
1816 NR_CONN_EVENTS, conn_fsm, CONN_FSM_LEN,
1817 GFP_KERNEL);
1818 if (!conn->fsm)
1819 goto out_tx;
1821 fsm_settimer(conn->fsm, &conn->timer);
1822 fsm_newstate(conn->fsm, CONN_STATE_INVALID);
1824 if (username) {
1825 memcpy(conn->userid, username, 9);
1826 fsm_newstate(conn->fsm, CONN_STATE_STOPPED);
1829 write_lock_bh(&iucv_connection_rwlock);
1830 list_add_tail(&conn->list, &iucv_connection_list);
1831 write_unlock_bh(&iucv_connection_rwlock);
1832 return conn;
1834 out_tx:
1835 kfree_skb(conn->tx_buff);
1836 out_rx:
1837 kfree_skb(conn->rx_buff);
1838 out_conn:
1839 kfree(conn);
1840 out:
1841 return NULL;
1845 * Release a connection structure and remove it from the
1846 * list of netiucv connections.
1848 static void netiucv_remove_connection(struct iucv_connection *conn)
1850 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1851 write_lock_bh(&iucv_connection_rwlock);
1852 list_del_init(&conn->list);
1853 write_unlock_bh(&iucv_connection_rwlock);
1854 fsm_deltimer(&conn->timer);
1855 netiucv_purge_skb_queue(&conn->collect_queue);
1856 if (conn->path) {
1857 iucv_path_sever(conn->path, iucvMagic);
1858 kfree(conn->path);
1859 conn->path = NULL;
1861 netiucv_purge_skb_queue(&conn->commit_queue);
1862 kfree_fsm(conn->fsm);
1863 kfree_skb(conn->rx_buff);
1864 kfree_skb(conn->tx_buff);
1868 * Release everything of a net device.
1870 static void netiucv_free_netdevice(struct net_device *dev)
1872 struct netiucv_priv *privptr = netdev_priv(dev);
1874 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1876 if (!dev)
1877 return;
1879 if (privptr) {
1880 if (privptr->conn)
1881 netiucv_remove_connection(privptr->conn);
1882 if (privptr->fsm)
1883 kfree_fsm(privptr->fsm);
1884 privptr->conn = NULL; privptr->fsm = NULL;
1885 /* privptr gets freed by free_netdev() */
1887 free_netdev(dev);
1891 * Initialize a net device. (Called from kernel in alloc_netdev())
1893 static void netiucv_setup_netdevice(struct net_device *dev)
1895 dev->mtu = NETIUCV_MTU_DEFAULT;
1896 dev->hard_start_xmit = netiucv_tx;
1897 dev->open = netiucv_open;
1898 dev->stop = netiucv_close;
1899 dev->get_stats = netiucv_stats;
1900 dev->change_mtu = netiucv_change_mtu;
1901 dev->destructor = netiucv_free_netdevice;
1902 dev->hard_header_len = NETIUCV_HDRLEN;
1903 dev->addr_len = 0;
1904 dev->type = ARPHRD_SLIP;
1905 dev->tx_queue_len = NETIUCV_QUEUELEN_DEFAULT;
1906 dev->flags = IFF_POINTOPOINT | IFF_NOARP;
1910 * Allocate and initialize everything of a net device.
1912 static struct net_device *netiucv_init_netdevice(char *username)
1914 struct netiucv_priv *privptr;
1915 struct net_device *dev;
1917 dev = alloc_netdev(sizeof(struct netiucv_priv), "iucv%d",
1918 netiucv_setup_netdevice);
1919 if (!dev)
1920 return NULL;
1921 if (dev_alloc_name(dev, dev->name) < 0)
1922 goto out_netdev;
1924 privptr = netdev_priv(dev);
1925 privptr->fsm = init_fsm("netiucvdev", dev_state_names,
1926 dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS,
1927 dev_fsm, DEV_FSM_LEN, GFP_KERNEL);
1928 if (!privptr->fsm)
1929 goto out_netdev;
1931 privptr->conn = netiucv_new_connection(dev, username);
1932 if (!privptr->conn) {
1933 IUCV_DBF_TEXT(setup, 2, "NULL from netiucv_new_connection\n");
1934 goto out_fsm;
1936 fsm_newstate(privptr->fsm, DEV_STATE_STOPPED);
1937 return dev;
1939 out_fsm:
1940 kfree_fsm(privptr->fsm);
1941 out_netdev:
1942 free_netdev(dev);
1943 return NULL;
1946 static ssize_t conn_write(struct device_driver *drv,
1947 const char *buf, size_t count)
1949 const char *p;
1950 char username[9];
1951 int i, rc;
1952 struct net_device *dev;
1953 struct netiucv_priv *priv;
1954 struct iucv_connection *cp;
1956 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1957 if (count>9) {
1958 PRINT_WARN("netiucv: username too long (%d)!\n", (int)count);
1959 IUCV_DBF_TEXT(setup, 2, "conn_write: too long\n");
1960 return -EINVAL;
1963 for (i = 0, p = buf; i < 8 && *p; i++, p++) {
1964 if (isalnum(*p) || *p == '$') {
1965 username[i] = toupper(*p);
1966 continue;
1968 if (*p == '\n')
1969 /* trailing lf, grr */
1970 break;
1971 PRINT_WARN("netiucv: Invalid character in username!\n");
1972 IUCV_DBF_TEXT_(setup, 2,
1973 "conn_write: invalid character %c\n", *p);
1974 return -EINVAL;
1976 while (i < 8)
1977 username[i++] = ' ';
1978 username[8] = '\0';
1980 read_lock_bh(&iucv_connection_rwlock);
1981 list_for_each_entry(cp, &iucv_connection_list, list) {
1982 if (!strncmp(username, cp->userid, 9)) {
1983 read_unlock_bh(&iucv_connection_rwlock);
1984 PRINT_WARN("netiucv: Connection to %s already "
1985 "exists\n", username);
1986 return -EEXIST;
1989 read_unlock_bh(&iucv_connection_rwlock);
1991 dev = netiucv_init_netdevice(username);
1992 if (!dev) {
1993 PRINT_WARN("netiucv: Could not allocate network device "
1994 "structure for user '%s'\n",
1995 netiucv_printname(username));
1996 IUCV_DBF_TEXT(setup, 2, "NULL from netiucv_init_netdevice\n");
1997 return -ENODEV;
2000 rc = netiucv_register_device(dev);
2001 if (rc) {
2002 IUCV_DBF_TEXT_(setup, 2,
2003 "ret %d from netiucv_register_device\n", rc);
2004 goto out_free_ndev;
2007 /* sysfs magic */
2008 priv = netdev_priv(dev);
2009 SET_NETDEV_DEV(dev, priv->dev);
2011 rc = register_netdev(dev);
2012 if (rc)
2013 goto out_unreg;
2015 PRINT_INFO("%s: '%s'\n", dev->name, netiucv_printname(username));
2017 return count;
2019 out_unreg:
2020 netiucv_unregister_device(priv->dev);
2021 out_free_ndev:
2022 PRINT_WARN("netiucv: Could not register '%s'\n", dev->name);
2023 IUCV_DBF_TEXT(setup, 2, "conn_write: could not register\n");
2024 netiucv_free_netdevice(dev);
2025 return rc;
2028 static DRIVER_ATTR(connection, 0200, NULL, conn_write);
2030 static ssize_t remove_write (struct device_driver *drv,
2031 const char *buf, size_t count)
2033 struct iucv_connection *cp;
2034 struct net_device *ndev;
2035 struct netiucv_priv *priv;
2036 struct device *dev;
2037 char name[IFNAMSIZ];
2038 const char *p;
2039 int i;
2041 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
2043 if (count >= IFNAMSIZ)
2044 count = IFNAMSIZ - 1;;
2046 for (i = 0, p = buf; i < count && *p; i++, p++) {
2047 if (*p == '\n' || *p == ' ')
2048 /* trailing lf, grr */
2049 break;
2050 name[i] = *p;
2052 name[i] = '\0';
2054 read_lock_bh(&iucv_connection_rwlock);
2055 list_for_each_entry(cp, &iucv_connection_list, list) {
2056 ndev = cp->netdev;
2057 priv = netdev_priv(ndev);
2058 dev = priv->dev;
2059 if (strncmp(name, ndev->name, count))
2060 continue;
2061 read_unlock_bh(&iucv_connection_rwlock);
2062 if (ndev->flags & (IFF_UP | IFF_RUNNING)) {
2063 PRINT_WARN("netiucv: net device %s active with peer "
2064 "%s\n", ndev->name, priv->conn->userid);
2065 PRINT_WARN("netiucv: %s cannot be removed\n",
2066 ndev->name);
2067 IUCV_DBF_TEXT(data, 2, "remove_write: still active\n");
2068 return -EBUSY;
2070 unregister_netdev(ndev);
2071 netiucv_unregister_device(dev);
2072 return count;
2074 read_unlock_bh(&iucv_connection_rwlock);
2075 PRINT_WARN("netiucv: net device %s unknown\n", name);
2076 IUCV_DBF_TEXT(data, 2, "remove_write: unknown device\n");
2077 return -EINVAL;
2080 static DRIVER_ATTR(remove, 0200, NULL, remove_write);
2082 static struct attribute * netiucv_drv_attrs[] = {
2083 &driver_attr_connection.attr,
2084 &driver_attr_remove.attr,
2085 NULL,
2088 static struct attribute_group netiucv_drv_attr_group = {
2089 .attrs = netiucv_drv_attrs,
2092 static struct attribute_group *netiucv_drv_attr_groups[] = {
2093 &netiucv_drv_attr_group,
2094 NULL,
2097 static void netiucv_banner(void)
2099 PRINT_INFO("NETIUCV driver initialized\n");
2102 static void __exit netiucv_exit(void)
2104 struct iucv_connection *cp;
2105 struct net_device *ndev;
2106 struct netiucv_priv *priv;
2107 struct device *dev;
2109 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
2110 while (!list_empty(&iucv_connection_list)) {
2111 cp = list_entry(iucv_connection_list.next,
2112 struct iucv_connection, list);
2113 ndev = cp->netdev;
2114 priv = netdev_priv(ndev);
2115 dev = priv->dev;
2117 unregister_netdev(ndev);
2118 netiucv_unregister_device(dev);
2121 driver_unregister(&netiucv_driver);
2122 iucv_unregister(&netiucv_handler, 1);
2123 iucv_unregister_dbf_views();
2125 PRINT_INFO("NETIUCV driver unloaded\n");
2126 return;
2129 static int __init netiucv_init(void)
2131 int rc;
2133 rc = iucv_register_dbf_views();
2134 if (rc)
2135 goto out;
2136 rc = iucv_register(&netiucv_handler, 1);
2137 if (rc)
2138 goto out_dbf;
2139 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
2140 netiucv_driver.groups = netiucv_drv_attr_groups;
2141 rc = driver_register(&netiucv_driver);
2142 if (rc) {
2143 PRINT_ERR("NETIUCV: failed to register driver.\n");
2144 IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_register\n", rc);
2145 goto out_iucv;
2148 netiucv_banner();
2149 return rc;
2151 out_iucv:
2152 iucv_unregister(&netiucv_handler, 1);
2153 out_dbf:
2154 iucv_unregister_dbf_views();
2155 out:
2156 return rc;
2159 module_init(netiucv_init);
2160 module_exit(netiucv_exit);
2161 MODULE_LICENSE("GPL");