aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/net/netiucv.c1314
1 files changed, 652 insertions, 662 deletions
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index 3346088f47e0..6387b483f2bf 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * IUCV network driver 2 * IUCV network driver
3 * 3 *
4 * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation 4 * Copyright 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
5 * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com) 5 * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
6 * 6 *
7 * Sysfs integration and all bugs therein by Cornelia Huck 7 * Sysfs integration and all bugs therein by Cornelia Huck
@@ -58,13 +58,94 @@
58#include <asm/io.h> 58#include <asm/io.h>
59#include <asm/uaccess.h> 59#include <asm/uaccess.h>
60 60
61#include "iucv.h" 61#include <net/iucv/iucv.h>
62#include "fsm.h" 62#include "fsm.h"
63 63
64MODULE_AUTHOR 64MODULE_AUTHOR
65 ("(C) 2001 IBM Corporation by Fritz Elfert (felfert@millenux.com)"); 65 ("(C) 2001 IBM Corporation by Fritz Elfert (felfert@millenux.com)");
66MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver"); 66MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver");
67 67
68/**
69 * Debug Facility stuff
70 */
71#define IUCV_DBF_SETUP_NAME "iucv_setup"
72#define IUCV_DBF_SETUP_LEN 32
73#define IUCV_DBF_SETUP_PAGES 2
74#define IUCV_DBF_SETUP_NR_AREAS 1
75#define IUCV_DBF_SETUP_LEVEL 3
76
77#define IUCV_DBF_DATA_NAME "iucv_data"
78#define IUCV_DBF_DATA_LEN 128
79#define IUCV_DBF_DATA_PAGES 2
80#define IUCV_DBF_DATA_NR_AREAS 1
81#define IUCV_DBF_DATA_LEVEL 2
82
83#define IUCV_DBF_TRACE_NAME "iucv_trace"
84#define IUCV_DBF_TRACE_LEN 16
85#define IUCV_DBF_TRACE_PAGES 4
86#define IUCV_DBF_TRACE_NR_AREAS 1
87#define IUCV_DBF_TRACE_LEVEL 3
88
89#define IUCV_DBF_TEXT(name,level,text) \
90 do { \
91 debug_text_event(iucv_dbf_##name,level,text); \
92 } while (0)
93
94#define IUCV_DBF_HEX(name,level,addr,len) \
95 do { \
96 debug_event(iucv_dbf_##name,level,(void*)(addr),len); \
97 } while (0)
98
99DECLARE_PER_CPU(char[256], iucv_dbf_txt_buf);
100
101#define IUCV_DBF_TEXT_(name,level,text...) \
102 do { \
103 char* iucv_dbf_txt_buf = get_cpu_var(iucv_dbf_txt_buf); \
104 sprintf(iucv_dbf_txt_buf, text); \
105 debug_text_event(iucv_dbf_##name,level,iucv_dbf_txt_buf); \
106 put_cpu_var(iucv_dbf_txt_buf); \
107 } while (0)
108
109#define IUCV_DBF_SPRINTF(name,level,text...) \
110 do { \
111 debug_sprintf_event(iucv_dbf_trace, level, ##text ); \
112 debug_sprintf_event(iucv_dbf_trace, level, text ); \
113 } while (0)
114
115/**
116 * some more debug stuff
117 */
118#define IUCV_HEXDUMP16(importance,header,ptr) \
119PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
120 "%02x %02x %02x %02x %02x %02x %02x %02x\n", \
121 *(((char*)ptr)),*(((char*)ptr)+1),*(((char*)ptr)+2), \
122 *(((char*)ptr)+3),*(((char*)ptr)+4),*(((char*)ptr)+5), \
123 *(((char*)ptr)+6),*(((char*)ptr)+7),*(((char*)ptr)+8), \
124 *(((char*)ptr)+9),*(((char*)ptr)+10),*(((char*)ptr)+11), \
125 *(((char*)ptr)+12),*(((char*)ptr)+13), \
126 *(((char*)ptr)+14),*(((char*)ptr)+15)); \
127PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
128 "%02x %02x %02x %02x %02x %02x %02x %02x\n", \
129 *(((char*)ptr)+16),*(((char*)ptr)+17), \
130 *(((char*)ptr)+18),*(((char*)ptr)+19), \
131 *(((char*)ptr)+20),*(((char*)ptr)+21), \
132 *(((char*)ptr)+22),*(((char*)ptr)+23), \
133 *(((char*)ptr)+24),*(((char*)ptr)+25), \
134 *(((char*)ptr)+26),*(((char*)ptr)+27), \
135 *(((char*)ptr)+28),*(((char*)ptr)+29), \
136 *(((char*)ptr)+30),*(((char*)ptr)+31));
137
138static inline void iucv_hex_dump(unsigned char *buf, size_t len)
139{
140 size_t i;
141
142 for (i = 0; i < len; i++) {
143 if (i && !(i % 16))
144 printk("\n");
145 printk("%02x ", *(buf + i));
146 }
147 printk("\n");
148}
68 149
69#define PRINTK_HEADER " iucv: " /* for debugging */ 150#define PRINTK_HEADER " iucv: " /* for debugging */
70 151
@@ -73,6 +154,25 @@ static struct device_driver netiucv_driver = {
73 .bus = &iucv_bus, 154 .bus = &iucv_bus,
74}; 155};
75 156
157static int netiucv_callback_connreq(struct iucv_path *,
158 u8 ipvmid[8], u8 ipuser[16]);
159static void netiucv_callback_connack(struct iucv_path *, u8 ipuser[16]);
160static void netiucv_callback_connrej(struct iucv_path *, u8 ipuser[16]);
161static void netiucv_callback_connsusp(struct iucv_path *, u8 ipuser[16]);
162static void netiucv_callback_connres(struct iucv_path *, u8 ipuser[16]);
163static void netiucv_callback_rx(struct iucv_path *, struct iucv_message *);
164static void netiucv_callback_txdone(struct iucv_path *, struct iucv_message *);
165
166static struct iucv_handler netiucv_handler = {
167 .path_pending = netiucv_callback_connreq,
168 .path_complete = netiucv_callback_connack,
169 .path_severed = netiucv_callback_connrej,
170 .path_quiesced = netiucv_callback_connsusp,
171 .path_resumed = netiucv_callback_connres,
172 .message_pending = netiucv_callback_rx,
173 .message_complete = netiucv_callback_txdone
174};
175
76/** 176/**
77 * Per connection profiling data 177 * Per connection profiling data
78 */ 178 */
@@ -92,9 +192,8 @@ struct connection_profile {
92 * Representation of one iucv connection 192 * Representation of one iucv connection
93 */ 193 */
94struct iucv_connection { 194struct iucv_connection {
95 struct iucv_connection *next; 195 struct list_head list;
96 iucv_handle_t handle; 196 struct iucv_path *path;
97 __u16 pathid;
98 struct sk_buff *rx_buff; 197 struct sk_buff *rx_buff;
99 struct sk_buff *tx_buff; 198 struct sk_buff *tx_buff;
100 struct sk_buff_head collect_queue; 199 struct sk_buff_head collect_queue;
@@ -112,12 +211,9 @@ struct iucv_connection {
112/** 211/**
113 * Linked list of all connection structs. 212 * Linked list of all connection structs.
114 */ 213 */
115struct iucv_connection_struct { 214static struct list_head iucv_connection_list =
116 struct iucv_connection *iucv_connections; 215 LIST_HEAD_INIT(iucv_connection_list);
117 rwlock_t iucv_rwlock; 216static rwlock_t iucv_connection_rwlock = RW_LOCK_UNLOCKED;
118};
119
120static struct iucv_connection_struct iucv_conns;
121 217
122/** 218/**
123 * Representation of event-data for the 219 * Representation of event-data for the
@@ -142,11 +238,11 @@ struct netiucv_priv {
142/** 238/**
143 * Link level header for a packet. 239 * Link level header for a packet.
144 */ 240 */
145typedef struct ll_header_t { 241struct ll_header {
146 __u16 next; 242 u16 next;
147} ll_header; 243};
148 244
149#define NETIUCV_HDRLEN (sizeof(ll_header)) 245#define NETIUCV_HDRLEN (sizeof(struct ll_header))
150#define NETIUCV_BUFSIZE_MAX 32768 246#define NETIUCV_BUFSIZE_MAX 32768
151#define NETIUCV_BUFSIZE_DEFAULT NETIUCV_BUFSIZE_MAX 247#define NETIUCV_BUFSIZE_DEFAULT NETIUCV_BUFSIZE_MAX
152#define NETIUCV_MTU_MAX (NETIUCV_BUFSIZE_MAX - NETIUCV_HDRLEN) 248#define NETIUCV_MTU_MAX (NETIUCV_BUFSIZE_MAX - NETIUCV_HDRLEN)
@@ -158,36 +254,26 @@ typedef struct ll_header_t {
158 * Compatibility macros for busy handling 254 * Compatibility macros for busy handling
159 * of network devices. 255 * of network devices.
160 */ 256 */
161static __inline__ void netiucv_clear_busy(struct net_device *dev) 257static inline void netiucv_clear_busy(struct net_device *dev)
162{ 258{
163 clear_bit(0, &(((struct netiucv_priv *)dev->priv)->tbusy)); 259 struct netiucv_priv *priv = netdev_priv(dev);
260 clear_bit(0, &priv->tbusy);
164 netif_wake_queue(dev); 261 netif_wake_queue(dev);
165} 262}
166 263
167static __inline__ int netiucv_test_and_set_busy(struct net_device *dev) 264static inline int netiucv_test_and_set_busy(struct net_device *dev)
168{ 265{
266 struct netiucv_priv *priv = netdev_priv(dev);
169 netif_stop_queue(dev); 267 netif_stop_queue(dev);
170 return test_and_set_bit(0, &((struct netiucv_priv *)dev->priv)->tbusy); 268 return test_and_set_bit(0, &priv->tbusy);
171} 269}
172 270
173static __u8 iucv_host[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 271static u8 iucvMagic[16] = {
174static __u8 iucvMagic[16] = {
175 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 272 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
176 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 273 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
177}; 274};
178 275
179/** 276/**
180 * This mask means the 16-byte IUCV "magic" and the origin userid must
181 * match exactly as specified in order to give connection_pending()
182 * control.
183 */
184static __u8 netiucv_mask[] = {
185 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
186 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
187 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
188};
189
190/**
191 * Convert an iucv userId to its printable 277 * Convert an iucv userId to its printable
192 * form (strip whitespace at end). 278 * form (strip whitespace at end).
193 * 279 *
@@ -195,8 +281,7 @@ static __u8 netiucv_mask[] = {
195 * 281 *
196 * @returns The printable string (static data!!) 282 * @returns The printable string (static data!!)
197 */ 283 */
198static __inline__ char * 284static inline char *netiucv_printname(char *name)
199netiucv_printname(char *name)
200{ 285{
201 static char tmp[9]; 286 static char tmp[9];
202 char *p = tmp; 287 char *p = tmp;
@@ -379,8 +464,7 @@ static debug_info_t *iucv_dbf_trace = NULL;
379 464
380DEFINE_PER_CPU(char[256], iucv_dbf_txt_buf); 465DEFINE_PER_CPU(char[256], iucv_dbf_txt_buf);
381 466
382static void 467static void iucv_unregister_dbf_views(void)
383iucv_unregister_dbf_views(void)
384{ 468{
385 if (iucv_dbf_setup) 469 if (iucv_dbf_setup)
386 debug_unregister(iucv_dbf_setup); 470 debug_unregister(iucv_dbf_setup);
@@ -389,8 +473,7 @@ iucv_unregister_dbf_views(void)
389 if (iucv_dbf_trace) 473 if (iucv_dbf_trace)
390 debug_unregister(iucv_dbf_trace); 474 debug_unregister(iucv_dbf_trace);
391} 475}
392static int 476static int iucv_register_dbf_views(void)
393iucv_register_dbf_views(void)
394{ 477{
395 iucv_dbf_setup = debug_register(IUCV_DBF_SETUP_NAME, 478 iucv_dbf_setup = debug_register(IUCV_DBF_SETUP_NAME,
396 IUCV_DBF_SETUP_PAGES, 479 IUCV_DBF_SETUP_PAGES,
@@ -422,125 +505,111 @@ iucv_register_dbf_views(void)
422 return 0; 505 return 0;
423} 506}
424 507
425/** 508/*
426 * Callback-wrappers, called from lowlevel iucv layer. 509 * Callback-wrappers, called from lowlevel iucv layer.
427 *****************************************************************************/ 510 */
428 511
429static void 512static void netiucv_callback_rx(struct iucv_path *path,
430netiucv_callback_rx(iucv_MessagePending *eib, void *pgm_data) 513 struct iucv_message *msg)
431{ 514{
432 struct iucv_connection *conn = (struct iucv_connection *)pgm_data; 515 struct iucv_connection *conn = path->private;
433 struct iucv_event ev; 516 struct iucv_event ev;
434 517
435 ev.conn = conn; 518 ev.conn = conn;
436 ev.data = (void *)eib; 519 ev.data = msg;
437
438 fsm_event(conn->fsm, CONN_EVENT_RX, &ev); 520 fsm_event(conn->fsm, CONN_EVENT_RX, &ev);
439} 521}
440 522
441static void 523static void netiucv_callback_txdone(struct iucv_path *path,
442netiucv_callback_txdone(iucv_MessageComplete *eib, void *pgm_data) 524 struct iucv_message *msg)
443{ 525{
444 struct iucv_connection *conn = (struct iucv_connection *)pgm_data; 526 struct iucv_connection *conn = path->private;
445 struct iucv_event ev; 527 struct iucv_event ev;
446 528
447 ev.conn = conn; 529 ev.conn = conn;
448 ev.data = (void *)eib; 530 ev.data = msg;
449 fsm_event(conn->fsm, CONN_EVENT_TXDONE, &ev); 531 fsm_event(conn->fsm, CONN_EVENT_TXDONE, &ev);
450} 532}
451 533
452static void 534static void netiucv_callback_connack(struct iucv_path *path, u8 ipuser[16])
453netiucv_callback_connack(iucv_ConnectionComplete *eib, void *pgm_data)
454{ 535{
455 struct iucv_connection *conn = (struct iucv_connection *)pgm_data; 536 struct iucv_connection *conn = path->private;
456 struct iucv_event ev;
457 537
458 ev.conn = conn; 538 fsm_event(conn->fsm, CONN_EVENT_CONN_ACK, conn);
459 ev.data = (void *)eib;
460 fsm_event(conn->fsm, CONN_EVENT_CONN_ACK, &ev);
461} 539}
462 540
463static void 541static int netiucv_callback_connreq(struct iucv_path *path,
464netiucv_callback_connreq(iucv_ConnectionPending *eib, void *pgm_data) 542 u8 ipvmid[8], u8 ipuser[16])
465{ 543{
466 struct iucv_connection *conn = (struct iucv_connection *)pgm_data; 544 struct iucv_connection *conn = path->private;
467 struct iucv_event ev; 545 struct iucv_event ev;
546 int rc;
468 547
469 ev.conn = conn; 548 if (memcmp(iucvMagic, ipuser, sizeof(ipuser)))
470 ev.data = (void *)eib; 549 /* ipuser must match iucvMagic. */
471 fsm_event(conn->fsm, CONN_EVENT_CONN_REQ, &ev); 550 return -EINVAL;
551 rc = -EINVAL;
552 read_lock_bh(&iucv_connection_rwlock);
553 list_for_each_entry(conn, &iucv_connection_list, list) {
554 if (strncmp(ipvmid, conn->userid, 8))
555 continue;
556 /* Found a matching connection for this path. */
557 conn->path = path;
558 ev.conn = conn;
559 ev.data = path;
560 fsm_event(conn->fsm, CONN_EVENT_CONN_REQ, &ev);
561 rc = 0;
562 }
563 read_unlock_bh(&iucv_connection_rwlock);
564 return rc;
472} 565}
473 566
474static void 567static void netiucv_callback_connrej(struct iucv_path *path, u8 ipuser[16])
475netiucv_callback_connrej(iucv_ConnectionSevered *eib, void *pgm_data)
476{ 568{
477 struct iucv_connection *conn = (struct iucv_connection *)pgm_data; 569 struct iucv_connection *conn = path->private;
478 struct iucv_event ev;
479 570
480 ev.conn = conn; 571 fsm_event(conn->fsm, CONN_EVENT_CONN_REJ, conn);
481 ev.data = (void *)eib;
482 fsm_event(conn->fsm, CONN_EVENT_CONN_REJ, &ev);
483} 572}
484 573
485static void 574static void netiucv_callback_connsusp(struct iucv_path *path, u8 ipuser[16])
486netiucv_callback_connsusp(iucv_ConnectionQuiesced *eib, void *pgm_data)
487{ 575{
488 struct iucv_connection *conn = (struct iucv_connection *)pgm_data; 576 struct iucv_connection *conn = path->private;
489 struct iucv_event ev;
490 577
491 ev.conn = conn; 578 fsm_event(conn->fsm, CONN_EVENT_CONN_SUS, conn);
492 ev.data = (void *)eib;
493 fsm_event(conn->fsm, CONN_EVENT_CONN_SUS, &ev);
494} 579}
495 580
496static void 581static void netiucv_callback_connres(struct iucv_path *path, u8 ipuser[16])
497netiucv_callback_connres(iucv_ConnectionResumed *eib, void *pgm_data)
498{ 582{
499 struct iucv_connection *conn = (struct iucv_connection *)pgm_data; 583 struct iucv_connection *conn = path->private;
500 struct iucv_event ev;
501 584
502 ev.conn = conn; 585 fsm_event(conn->fsm, CONN_EVENT_CONN_RES, conn);
503 ev.data = (void *)eib; 586}
504 fsm_event(conn->fsm, CONN_EVENT_CONN_RES, &ev);
505}
506
507static iucv_interrupt_ops_t netiucv_ops = {
508 .ConnectionPending = netiucv_callback_connreq,
509 .ConnectionComplete = netiucv_callback_connack,
510 .ConnectionSevered = netiucv_callback_connrej,
511 .ConnectionQuiesced = netiucv_callback_connsusp,
512 .ConnectionResumed = netiucv_callback_connres,
513 .MessagePending = netiucv_callback_rx,
514 .MessageComplete = netiucv_callback_txdone
515};
516 587
517/** 588/**
518 * Dummy NOP action for all statemachines 589 * Dummy NOP action for all statemachines
519 */ 590 */
520static void 591static void fsm_action_nop(fsm_instance *fi, int event, void *arg)
521fsm_action_nop(fsm_instance *fi, int event, void *arg)
522{ 592{
523} 593}
524 594
525/** 595/*
526 * Actions of the connection statemachine 596 * Actions of the connection statemachine
527 *****************************************************************************/ 597 */
528 598
529/** 599/**
530 * Helper function for conn_action_rx() 600 * netiucv_unpack_skb
531 * Unpack a just received skb and hand it over to 601 * @conn: The connection where this skb has been received.
532 * upper layers. 602 * @pskb: The received skb.
533 * 603 *
534 * @param conn The connection where this skb has been received. 604 * Unpack a just received skb and hand it over to upper layers.
535 * @param pskb The received skb. 605 * Helper function for conn_action_rx.
536 */ 606 */
537//static __inline__ void 607static void netiucv_unpack_skb(struct iucv_connection *conn,
538static void 608 struct sk_buff *pskb)
539netiucv_unpack_skb(struct iucv_connection *conn, struct sk_buff *pskb)
540{ 609{
541 struct net_device *dev = conn->netdev; 610 struct net_device *dev = conn->netdev;
542 struct netiucv_priv *privptr = dev->priv; 611 struct netiucv_priv *privptr = netdev_priv(dev);
543 __u16 offset = 0; 612 u16 offset = 0;
544 613
545 skb_put(pskb, NETIUCV_HDRLEN); 614 skb_put(pskb, NETIUCV_HDRLEN);
546 pskb->dev = dev; 615 pskb->dev = dev;
@@ -549,7 +618,7 @@ netiucv_unpack_skb(struct iucv_connection *conn, struct sk_buff *pskb)
549 618
550 while (1) { 619 while (1) {
551 struct sk_buff *skb; 620 struct sk_buff *skb;
552 ll_header *header = (ll_header *)pskb->data; 621 struct ll_header *header = (struct ll_header *) pskb->data;
553 622
554 if (!header->next) 623 if (!header->next)
555 break; 624 break;
@@ -595,40 +664,37 @@ netiucv_unpack_skb(struct iucv_connection *conn, struct sk_buff *pskb)
595 } 664 }
596} 665}
597 666
598static void 667static void conn_action_rx(fsm_instance *fi, int event, void *arg)
599conn_action_rx(fsm_instance *fi, int event, void *arg)
600{ 668{
601 struct iucv_event *ev = (struct iucv_event *)arg; 669 struct iucv_event *ev = arg;
602 struct iucv_connection *conn = ev->conn; 670 struct iucv_connection *conn = ev->conn;
603 iucv_MessagePending *eib = (iucv_MessagePending *)ev->data; 671 struct iucv_message *msg = ev->data;
604 struct netiucv_priv *privptr =(struct netiucv_priv *)conn->netdev->priv; 672 struct netiucv_priv *privptr = netdev_priv(conn->netdev);
605
606 __u32 msglen = eib->ln1msg2.ipbfln1f;
607 int rc; 673 int rc;
608 674
609 IUCV_DBF_TEXT(trace, 4, __FUNCTION__); 675 IUCV_DBF_TEXT(trace, 4, __FUNCTION__);
610 676
611 if (!conn->netdev) { 677 if (!conn->netdev) {
612 /* FRITZ: How to tell iucv LL to drop the msg? */ 678 iucv_message_reject(conn->path, msg);
613 PRINT_WARN("Received data for unlinked connection\n"); 679 PRINT_WARN("Received data for unlinked connection\n");
614 IUCV_DBF_TEXT(data, 2, 680 IUCV_DBF_TEXT(data, 2,
615 "Received data for unlinked connection\n"); 681 "Received data for unlinked connection\n");
616 return; 682 return;
617 } 683 }
618 if (msglen > conn->max_buffsize) { 684 if (msg->length > conn->max_buffsize) {
619 /* FRITZ: How to tell iucv LL to drop the msg? */ 685 iucv_message_reject(conn->path, msg);
620 privptr->stats.rx_dropped++; 686 privptr->stats.rx_dropped++;
621 PRINT_WARN("msglen %d > max_buffsize %d\n", 687 PRINT_WARN("msglen %d > max_buffsize %d\n",
622 msglen, conn->max_buffsize); 688 msg->length, conn->max_buffsize);
623 IUCV_DBF_TEXT_(data, 2, "msglen %d > max_buffsize %d\n", 689 IUCV_DBF_TEXT_(data, 2, "msglen %d > max_buffsize %d\n",
624 msglen, conn->max_buffsize); 690 msg->length, conn->max_buffsize);
625 return; 691 return;
626 } 692 }
627 conn->rx_buff->data = conn->rx_buff->tail = conn->rx_buff->head; 693 conn->rx_buff->data = conn->rx_buff->tail = conn->rx_buff->head;
628 conn->rx_buff->len = 0; 694 conn->rx_buff->len = 0;
629 rc = iucv_receive(conn->pathid, eib->ipmsgid, eib->iptrgcls, 695 rc = iucv_message_receive(conn->path, msg, 0, conn->rx_buff->data,
630 conn->rx_buff->data, msglen, NULL, NULL, NULL); 696 msg->length, NULL);
631 if (rc || msglen < 5) { 697 if (rc || msg->length < 5) {
632 privptr->stats.rx_errors++; 698 privptr->stats.rx_errors++;
633 PRINT_WARN("iucv_receive returned %08x\n", rc); 699 PRINT_WARN("iucv_receive returned %08x\n", rc);
634 IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_receive\n", rc); 700 IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_receive\n", rc);
@@ -637,26 +703,26 @@ conn_action_rx(fsm_instance *fi, int event, void *arg)
637 netiucv_unpack_skb(conn, conn->rx_buff); 703 netiucv_unpack_skb(conn, conn->rx_buff);
638} 704}
639 705
640static void 706static void conn_action_txdone(fsm_instance *fi, int event, void *arg)
641conn_action_txdone(fsm_instance *fi, int event, void *arg)
642{ 707{
643 struct iucv_event *ev = (struct iucv_event *)arg; 708 struct iucv_event *ev = arg;
644 struct iucv_connection *conn = ev->conn; 709 struct iucv_connection *conn = ev->conn;
645 iucv_MessageComplete *eib = (iucv_MessageComplete *)ev->data; 710 struct iucv_message *msg = ev->data;
711 struct iucv_message txmsg;
646 struct netiucv_priv *privptr = NULL; 712 struct netiucv_priv *privptr = NULL;
647 /* Shut up, gcc! skb is always below 2G. */ 713 u32 single_flag = msg->tag;
648 __u32 single_flag = eib->ipmsgtag; 714 u32 txbytes = 0;
649 __u32 txbytes = 0; 715 u32 txpackets = 0;
650 __u32 txpackets = 0; 716 u32 stat_maxcq = 0;
651 __u32 stat_maxcq = 0;
652 struct sk_buff *skb; 717 struct sk_buff *skb;
653 unsigned long saveflags; 718 unsigned long saveflags;
654 ll_header header; 719 struct ll_header header;
720 int rc;
655 721
656 IUCV_DBF_TEXT(trace, 4, __FUNCTION__); 722 IUCV_DBF_TEXT(trace, 4, __FUNCTION__);
657 723
658 if (conn && conn->netdev && conn->netdev->priv) 724 if (conn && conn->netdev)
659 privptr = (struct netiucv_priv *)conn->netdev->priv; 725 privptr = netdev_priv(conn->netdev);
660 conn->prof.tx_pending--; 726 conn->prof.tx_pending--;
661 if (single_flag) { 727 if (single_flag) {
662 if ((skb = skb_dequeue(&conn->commit_queue))) { 728 if ((skb = skb_dequeue(&conn->commit_queue))) {
@@ -688,56 +754,55 @@ conn_action_txdone(fsm_instance *fi, int event, void *arg)
688 conn->prof.maxmulti = conn->collect_len; 754 conn->prof.maxmulti = conn->collect_len;
689 conn->collect_len = 0; 755 conn->collect_len = 0;
690 spin_unlock_irqrestore(&conn->collect_lock, saveflags); 756 spin_unlock_irqrestore(&conn->collect_lock, saveflags);
691 if (conn->tx_buff->len) { 757 if (conn->tx_buff->len == 0) {
692 int rc; 758 fsm_newstate(fi, CONN_STATE_IDLE);
693 759 return;
694 header.next = 0; 760 }
695 memcpy(skb_put(conn->tx_buff, NETIUCV_HDRLEN), &header,
696 NETIUCV_HDRLEN);
697 761
698 conn->prof.send_stamp = xtime; 762 header.next = 0;
699 rc = iucv_send(conn->pathid, NULL, 0, 0, 0, 0, 763 memcpy(skb_put(conn->tx_buff, NETIUCV_HDRLEN), &header, NETIUCV_HDRLEN);
764 conn->prof.send_stamp = xtime;
765 txmsg.class = 0;
766 txmsg.tag = 0;
767 rc = iucv_message_send(conn->path, &txmsg, 0, 0,
700 conn->tx_buff->data, conn->tx_buff->len); 768 conn->tx_buff->data, conn->tx_buff->len);
701 conn->prof.doios_multi++; 769 conn->prof.doios_multi++;
702 conn->prof.txlen += conn->tx_buff->len; 770 conn->prof.txlen += conn->tx_buff->len;
703 conn->prof.tx_pending++; 771 conn->prof.tx_pending++;
704 if (conn->prof.tx_pending > conn->prof.tx_max_pending) 772 if (conn->prof.tx_pending > conn->prof.tx_max_pending)
705 conn->prof.tx_max_pending = conn->prof.tx_pending; 773 conn->prof.tx_max_pending = conn->prof.tx_pending;
706 if (rc) { 774 if (rc) {
707 conn->prof.tx_pending--; 775 conn->prof.tx_pending--;
708 fsm_newstate(fi, CONN_STATE_IDLE);
709 if (privptr)
710 privptr->stats.tx_errors += txpackets;
711 PRINT_WARN("iucv_send returned %08x\n", rc);
712 IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_send\n", rc);
713 } else {
714 if (privptr) {
715 privptr->stats.tx_packets += txpackets;
716 privptr->stats.tx_bytes += txbytes;
717 }
718 if (stat_maxcq > conn->prof.maxcqueue)
719 conn->prof.maxcqueue = stat_maxcq;
720 }
721 } else
722 fsm_newstate(fi, CONN_STATE_IDLE); 776 fsm_newstate(fi, CONN_STATE_IDLE);
777 if (privptr)
778 privptr->stats.tx_errors += txpackets;
779 PRINT_WARN("iucv_send returned %08x\n", rc);
780 IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_send\n", rc);
781 } else {
782 if (privptr) {
783 privptr->stats.tx_packets += txpackets;
784 privptr->stats.tx_bytes += txbytes;
785 }
786 if (stat_maxcq > conn->prof.maxcqueue)
787 conn->prof.maxcqueue = stat_maxcq;
788 }
723} 789}
724 790
725static void 791static void conn_action_connaccept(fsm_instance *fi, int event, void *arg)
726conn_action_connaccept(fsm_instance *fi, int event, void *arg)
727{ 792{
728 struct iucv_event *ev = (struct iucv_event *)arg; 793 struct iucv_event *ev = arg;
729 struct iucv_connection *conn = ev->conn; 794 struct iucv_connection *conn = ev->conn;
730 iucv_ConnectionPending *eib = (iucv_ConnectionPending *)ev->data; 795 struct iucv_path *path = ev->data;
731 struct net_device *netdev = conn->netdev; 796 struct net_device *netdev = conn->netdev;
732 struct netiucv_priv *privptr = (struct netiucv_priv *)netdev->priv; 797 struct netiucv_priv *privptr = netdev_priv(netdev);
733 int rc; 798 int rc;
734 __u16 msglimit;
735 __u8 udata[16];
736 799
737 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 800 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
738 801
739 rc = iucv_accept(eib->ippathid, NETIUCV_QUEUELEN_DEFAULT, udata, 0, 802 conn->path = path;
740 conn->handle, conn, NULL, &msglimit); 803 path->msglim = NETIUCV_QUEUELEN_DEFAULT;
804 path->flags = 0;
805 rc = iucv_path_accept(path, &netiucv_handler, NULL, conn);
741 if (rc) { 806 if (rc) {
742 PRINT_WARN("%s: IUCV accept failed with error %d\n", 807 PRINT_WARN("%s: IUCV accept failed with error %d\n",
743 netdev->name, rc); 808 netdev->name, rc);
@@ -745,183 +810,126 @@ conn_action_connaccept(fsm_instance *fi, int event, void *arg)
745 return; 810 return;
746 } 811 }
747 fsm_newstate(fi, CONN_STATE_IDLE); 812 fsm_newstate(fi, CONN_STATE_IDLE);
748 conn->pathid = eib->ippathid; 813 netdev->tx_queue_len = conn->path->msglim;
749 netdev->tx_queue_len = msglimit;
750 fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev); 814 fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev);
751} 815}
752 816
753static void 817static void conn_action_connreject(fsm_instance *fi, int event, void *arg)
754conn_action_connreject(fsm_instance *fi, int event, void *arg)
755{ 818{
756 struct iucv_event *ev = (struct iucv_event *)arg; 819 struct iucv_event *ev = arg;
757 struct iucv_connection *conn = ev->conn; 820 struct iucv_path *path = ev->data;
758 struct net_device *netdev = conn->netdev;
759 iucv_ConnectionPending *eib = (iucv_ConnectionPending *)ev->data;
760 __u8 udata[16];
761 821
762 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 822 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
763 823 iucv_path_sever(path, NULL);
764 iucv_sever(eib->ippathid, udata);
765 if (eib->ippathid != conn->pathid) {
766 PRINT_INFO("%s: IR Connection Pending; "
767 "pathid %d does not match original pathid %d\n",
768 netdev->name, eib->ippathid, conn->pathid);
769 IUCV_DBF_TEXT_(data, 2,
770 "connreject: IR pathid %d, conn. pathid %d\n",
771 eib->ippathid, conn->pathid);
772 iucv_sever(conn->pathid, udata);
773 }
774} 824}
775 825
776static void 826static void conn_action_connack(fsm_instance *fi, int event, void *arg)
777conn_action_connack(fsm_instance *fi, int event, void *arg)
778{ 827{
779 struct iucv_event *ev = (struct iucv_event *)arg; 828 struct iucv_connection *conn = arg;
780 struct iucv_connection *conn = ev->conn;
781 iucv_ConnectionComplete *eib = (iucv_ConnectionComplete *)ev->data;
782 struct net_device *netdev = conn->netdev; 829 struct net_device *netdev = conn->netdev;
783 struct netiucv_priv *privptr = (struct netiucv_priv *)netdev->priv; 830 struct netiucv_priv *privptr = netdev_priv(netdev);
784 831
785 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 832 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
786
787 fsm_deltimer(&conn->timer); 833 fsm_deltimer(&conn->timer);
788 fsm_newstate(fi, CONN_STATE_IDLE); 834 fsm_newstate(fi, CONN_STATE_IDLE);
789 if (eib->ippathid != conn->pathid) { 835 netdev->tx_queue_len = conn->path->msglim;
790 PRINT_INFO("%s: IR Connection Complete; "
791 "pathid %d does not match original pathid %d\n",
792 netdev->name, eib->ippathid, conn->pathid);
793 IUCV_DBF_TEXT_(data, 2,
794 "connack: IR pathid %d, conn. pathid %d\n",
795 eib->ippathid, conn->pathid);
796 conn->pathid = eib->ippathid;
797 }
798 netdev->tx_queue_len = eib->ipmsglim;
799 fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev); 836 fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev);
800} 837}
801 838
802static void 839static void conn_action_conntimsev(fsm_instance *fi, int event, void *arg)
803conn_action_conntimsev(fsm_instance *fi, int event, void *arg)
804{ 840{
805 struct iucv_connection *conn = (struct iucv_connection *)arg; 841 struct iucv_connection *conn = arg;
806 __u8 udata[16];
807 842
808 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 843 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
809
810 fsm_deltimer(&conn->timer); 844 fsm_deltimer(&conn->timer);
811 iucv_sever(conn->pathid, udata); 845 iucv_path_sever(conn->path, NULL);
812 fsm_newstate(fi, CONN_STATE_STARTWAIT); 846 fsm_newstate(fi, CONN_STATE_STARTWAIT);
813} 847}
814 848
815static void 849static void conn_action_connsever(fsm_instance *fi, int event, void *arg)
816conn_action_connsever(fsm_instance *fi, int event, void *arg)
817{ 850{
818 struct iucv_event *ev = (struct iucv_event *)arg; 851 struct iucv_connection *conn = arg;
819 struct iucv_connection *conn = ev->conn;
820 struct net_device *netdev = conn->netdev; 852 struct net_device *netdev = conn->netdev;
821 struct netiucv_priv *privptr = (struct netiucv_priv *)netdev->priv; 853 struct netiucv_priv *privptr = netdev_priv(netdev);
822 __u8 udata[16];
823 854
824 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 855 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
825 856
826 fsm_deltimer(&conn->timer); 857 fsm_deltimer(&conn->timer);
827 iucv_sever(conn->pathid, udata); 858 iucv_path_sever(conn->path, NULL);
828 PRINT_INFO("%s: Remote dropped connection\n", netdev->name); 859 PRINT_INFO("%s: Remote dropped connection\n", netdev->name);
829 IUCV_DBF_TEXT(data, 2, 860 IUCV_DBF_TEXT(data, 2,
830 "conn_action_connsever: Remote dropped connection\n"); 861 "conn_action_connsever: Remote dropped connection\n");
831 fsm_newstate(fi, CONN_STATE_STARTWAIT); 862 fsm_newstate(fi, CONN_STATE_STARTWAIT);
832 fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev); 863 fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev);
833} 864}
834 865
835static void 866static void conn_action_start(fsm_instance *fi, int event, void *arg)
836conn_action_start(fsm_instance *fi, int event, void *arg)
837{ 867{
838 struct iucv_event *ev = (struct iucv_event *)arg; 868 struct iucv_connection *conn = arg;
839 struct iucv_connection *conn = ev->conn;
840 __u16 msglimit;
841 int rc; 869 int rc;
842 870
843 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 871 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
844 872
845 if (!conn->handle) { 873 fsm_newstate(fi, CONN_STATE_STARTWAIT);
846 IUCV_DBF_TEXT(trace, 5, "calling iucv_register_program\n");
847 conn->handle =
848 iucv_register_program(iucvMagic, conn->userid,
849 netiucv_mask,
850 &netiucv_ops, conn);
851 fsm_newstate(fi, CONN_STATE_STARTWAIT);
852 if (!conn->handle) {
853 fsm_newstate(fi, CONN_STATE_REGERR);
854 conn->handle = NULL;
855 IUCV_DBF_TEXT(setup, 2,
856 "NULL from iucv_register_program\n");
857 return;
858 }
859
860 PRINT_DEBUG("%s('%s'): registered successfully\n",
861 conn->netdev->name, conn->userid);
862 }
863
864 PRINT_DEBUG("%s('%s'): connecting ...\n", 874 PRINT_DEBUG("%s('%s'): connecting ...\n",
865 conn->netdev->name, conn->userid); 875 conn->netdev->name, conn->userid);
866 876
867 /* We must set the state before calling iucv_connect because the callback 877 /*
868 * handler could be called at any point after the connection request is 878 * We must set the state before calling iucv_connect because the
869 * sent */ 879 * callback handler could be called at any point after the connection
880 * request is sent
881 */
870 882
871 fsm_newstate(fi, CONN_STATE_SETUPWAIT); 883 fsm_newstate(fi, CONN_STATE_SETUPWAIT);
872 rc = iucv_connect(&(conn->pathid), NETIUCV_QUEUELEN_DEFAULT, iucvMagic, 884 conn->path = iucv_path_alloc(NETIUCV_QUEUELEN_DEFAULT, 0, GFP_KERNEL);
873 conn->userid, iucv_host, 0, NULL, &msglimit, 885 rc = iucv_path_connect(conn->path, &netiucv_handler, conn->userid,
874 conn->handle, conn); 886 NULL, iucvMagic, conn);
875 switch (rc) { 887 switch (rc) {
876 case 0: 888 case 0:
877 conn->netdev->tx_queue_len = msglimit; 889 conn->netdev->tx_queue_len = conn->path->msglim;
878 fsm_addtimer(&conn->timer, NETIUCV_TIMEOUT_5SEC, 890 fsm_addtimer(&conn->timer, NETIUCV_TIMEOUT_5SEC,
879 CONN_EVENT_TIMER, conn); 891 CONN_EVENT_TIMER, conn);
880 return; 892 return;
881 case 11: 893 case 11:
882 PRINT_INFO("%s: User %s is currently not available.\n", 894 PRINT_INFO("%s: User %s is currently not available.\n",
883 conn->netdev->name, 895 conn->netdev->name,
884 netiucv_printname(conn->userid)); 896 netiucv_printname(conn->userid));
885 fsm_newstate(fi, CONN_STATE_STARTWAIT); 897 fsm_newstate(fi, CONN_STATE_STARTWAIT);
886 return; 898 break;
887 case 12: 899 case 12:
888 PRINT_INFO("%s: User %s is currently not ready.\n", 900 PRINT_INFO("%s: User %s is currently not ready.\n",
889 conn->netdev->name, 901 conn->netdev->name,
890 netiucv_printname(conn->userid)); 902 netiucv_printname(conn->userid));
891 fsm_newstate(fi, CONN_STATE_STARTWAIT); 903 fsm_newstate(fi, CONN_STATE_STARTWAIT);
892 return; 904 break;
893 case 13: 905 case 13:
894 PRINT_WARN("%s: Too many IUCV connections.\n", 906 PRINT_WARN("%s: Too many IUCV connections.\n",
895 conn->netdev->name); 907 conn->netdev->name);
896 fsm_newstate(fi, CONN_STATE_CONNERR); 908 fsm_newstate(fi, CONN_STATE_CONNERR);
897 break; 909 break;
898 case 14: 910 case 14:
899 PRINT_WARN( 911 PRINT_WARN("%s: User %s has too many IUCV connections.\n",
900 "%s: User %s has too many IUCV connections.\n", 912 conn->netdev->name,
901 conn->netdev->name, 913 netiucv_printname(conn->userid));
902 netiucv_printname(conn->userid)); 914 fsm_newstate(fi, CONN_STATE_CONNERR);
903 fsm_newstate(fi, CONN_STATE_CONNERR); 915 break;
904 break; 916 case 15:
905 case 15: 917 PRINT_WARN("%s: No IUCV authorization in CP directory.\n",
906 PRINT_WARN( 918 conn->netdev->name);
907 "%s: No IUCV authorization in CP directory.\n", 919 fsm_newstate(fi, CONN_STATE_CONNERR);
908 conn->netdev->name); 920 break;
909 fsm_newstate(fi, CONN_STATE_CONNERR); 921 default:
910 break; 922 PRINT_WARN("%s: iucv_connect returned error %d\n",
911 default: 923 conn->netdev->name, rc);
912 PRINT_WARN("%s: iucv_connect returned error %d\n", 924 fsm_newstate(fi, CONN_STATE_CONNERR);
913 conn->netdev->name, rc); 925 break;
914 fsm_newstate(fi, CONN_STATE_CONNERR);
915 break;
916 } 926 }
917 IUCV_DBF_TEXT_(setup, 5, "iucv_connect rc is %d\n", rc); 927 IUCV_DBF_TEXT_(setup, 5, "iucv_connect rc is %d\n", rc);
918 IUCV_DBF_TEXT(trace, 5, "calling iucv_unregister_program\n"); 928 kfree(conn->path);
919 iucv_unregister_program(conn->handle); 929 conn->path = NULL;
920 conn->handle = NULL;
921} 930}
922 931
923static void 932static void netiucv_purge_skb_queue(struct sk_buff_head *q)
924netiucv_purge_skb_queue(struct sk_buff_head *q)
925{ 933{
926 struct sk_buff *skb; 934 struct sk_buff *skb;
927 935
@@ -931,36 +939,34 @@ netiucv_purge_skb_queue(struct sk_buff_head *q)
931 } 939 }
932} 940}
933 941
934static void 942static void conn_action_stop(fsm_instance *fi, int event, void *arg)
935conn_action_stop(fsm_instance *fi, int event, void *arg)
936{ 943{
937 struct iucv_event *ev = (struct iucv_event *)arg; 944 struct iucv_event *ev = arg;
938 struct iucv_connection *conn = ev->conn; 945 struct iucv_connection *conn = ev->conn;
939 struct net_device *netdev = conn->netdev; 946 struct net_device *netdev = conn->netdev;
940 struct netiucv_priv *privptr = (struct netiucv_priv *)netdev->priv; 947 struct netiucv_priv *privptr = netdev_priv(netdev);
941 948
942 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 949 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
943 950
944 fsm_deltimer(&conn->timer); 951 fsm_deltimer(&conn->timer);
945 fsm_newstate(fi, CONN_STATE_STOPPED); 952 fsm_newstate(fi, CONN_STATE_STOPPED);
946 netiucv_purge_skb_queue(&conn->collect_queue); 953 netiucv_purge_skb_queue(&conn->collect_queue);
947 if (conn->handle) 954 if (conn->path) {
948 IUCV_DBF_TEXT(trace, 5, "calling iucv_unregister_program\n"); 955 IUCV_DBF_TEXT(trace, 5, "calling iucv_path_sever\n");
949 iucv_unregister_program(conn->handle); 956 iucv_path_sever(conn->path, iucvMagic);
950 conn->handle = NULL; 957 kfree(conn->path);
958 conn->path = NULL;
959 }
951 netiucv_purge_skb_queue(&conn->commit_queue); 960 netiucv_purge_skb_queue(&conn->commit_queue);
952 fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev); 961 fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev);
953} 962}
954 963
955static void 964static void conn_action_inval(fsm_instance *fi, int event, void *arg)
956conn_action_inval(fsm_instance *fi, int event, void *arg)
957{ 965{
958 struct iucv_event *ev = (struct iucv_event *)arg; 966 struct iucv_connection *conn = arg;
959 struct iucv_connection *conn = ev->conn;
960 struct net_device *netdev = conn->netdev; 967 struct net_device *netdev = conn->netdev;
961 968
962 PRINT_WARN("%s: Cannot connect without username\n", 969 PRINT_WARN("%s: Cannot connect without username\n", netdev->name);
963 netdev->name);
964 IUCV_DBF_TEXT(data, 2, "conn_action_inval called\n"); 970 IUCV_DBF_TEXT(data, 2, "conn_action_inval called\n");
965} 971}
966 972
@@ -999,29 +1005,27 @@ static const fsm_node conn_fsm[] = {
999static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node); 1005static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node);
1000 1006
1001 1007
1002/** 1008/*
1003 * Actions for interface - statemachine. 1009 * Actions for interface - statemachine.
1004 *****************************************************************************/ 1010 */
1005 1011
1006/** 1012/**
1007 * Startup connection by sending CONN_EVENT_START to it. 1013 * dev_action_start
1014 * @fi: An instance of an interface statemachine.
1015 * @event: The event, just happened.
1016 * @arg: Generic pointer, casted from struct net_device * upon call.
1008 * 1017 *
1009 * @param fi An instance of an interface statemachine. 1018 * Startup connection by sending CONN_EVENT_START to it.
1010 * @param event The event, just happened.
1011 * @param arg Generic pointer, casted from struct net_device * upon call.
1012 */ 1019 */
1013static void 1020static void dev_action_start(fsm_instance *fi, int event, void *arg)
1014dev_action_start(fsm_instance *fi, int event, void *arg)
1015{ 1021{
1016 struct net_device *dev = (struct net_device *)arg; 1022 struct net_device *dev = arg;
1017 struct netiucv_priv *privptr = dev->priv; 1023 struct netiucv_priv *privptr = netdev_priv(dev);
1018 struct iucv_event ev;
1019 1024
1020 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 1025 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1021 1026
1022 ev.conn = privptr->conn;
1023 fsm_newstate(fi, DEV_STATE_STARTWAIT); 1027 fsm_newstate(fi, DEV_STATE_STARTWAIT);
1024 fsm_event(privptr->conn->fsm, CONN_EVENT_START, &ev); 1028 fsm_event(privptr->conn->fsm, CONN_EVENT_START, privptr->conn);
1025} 1029}
1026 1030
1027/** 1031/**
@@ -1034,8 +1038,8 @@ dev_action_start(fsm_instance *fi, int event, void *arg)
1034static void 1038static void
1035dev_action_stop(fsm_instance *fi, int event, void *arg) 1039dev_action_stop(fsm_instance *fi, int event, void *arg)
1036{ 1040{
1037 struct net_device *dev = (struct net_device *)arg; 1041 struct net_device *dev = arg;
1038 struct netiucv_priv *privptr = dev->priv; 1042 struct netiucv_priv *privptr = netdev_priv(dev);
1039 struct iucv_event ev; 1043 struct iucv_event ev;
1040 1044
1041 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 1045 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
@@ -1057,8 +1061,8 @@ dev_action_stop(fsm_instance *fi, int event, void *arg)
1057static void 1061static void
1058dev_action_connup(fsm_instance *fi, int event, void *arg) 1062dev_action_connup(fsm_instance *fi, int event, void *arg)
1059{ 1063{
1060 struct net_device *dev = (struct net_device *)arg; 1064 struct net_device *dev = arg;
1061 struct netiucv_priv *privptr = dev->priv; 1065 struct netiucv_priv *privptr = netdev_priv(dev);
1062 1066
1063 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 1067 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1064 1068
@@ -1131,11 +1135,13 @@ static const int DEV_FSM_LEN = sizeof(dev_fsm) / sizeof(fsm_node);
1131 * 1135 *
1132 * @return 0 on success, -ERRNO on failure. (Never fails.) 1136 * @return 0 on success, -ERRNO on failure. (Never fails.)
1133 */ 1137 */
1134static int 1138static int netiucv_transmit_skb(struct iucv_connection *conn,
1135netiucv_transmit_skb(struct iucv_connection *conn, struct sk_buff *skb) { 1139 struct sk_buff *skb)
1140{
1141 struct iucv_message msg;
1136 unsigned long saveflags; 1142 unsigned long saveflags;
1137 ll_header header; 1143 struct ll_header header;
1138 int rc = 0; 1144 int rc;
1139 1145
1140 if (fsm_getstate(conn->fsm) != CONN_STATE_IDLE) { 1146 if (fsm_getstate(conn->fsm) != CONN_STATE_IDLE) {
1141 int l = skb->len + NETIUCV_HDRLEN; 1147 int l = skb->len + NETIUCV_HDRLEN;
@@ -1145,11 +1151,12 @@ netiucv_transmit_skb(struct iucv_connection *conn, struct sk_buff *skb) {
1145 (conn->max_buffsize - NETIUCV_HDRLEN)) { 1151 (conn->max_buffsize - NETIUCV_HDRLEN)) {
1146 rc = -EBUSY; 1152 rc = -EBUSY;
1147 IUCV_DBF_TEXT(data, 2, 1153 IUCV_DBF_TEXT(data, 2,
1148 "EBUSY from netiucv_transmit_skb\n"); 1154 "EBUSY from netiucv_transmit_skb\n");
1149 } else { 1155 } else {
1150 atomic_inc(&skb->users); 1156 atomic_inc(&skb->users);
1151 skb_queue_tail(&conn->collect_queue, skb); 1157 skb_queue_tail(&conn->collect_queue, skb);
1152 conn->collect_len += l; 1158 conn->collect_len += l;
1159 rc = 0;
1153 } 1160 }
1154 spin_unlock_irqrestore(&conn->collect_lock, saveflags); 1161 spin_unlock_irqrestore(&conn->collect_lock, saveflags);
1155 } else { 1162 } else {
@@ -1188,9 +1195,10 @@ netiucv_transmit_skb(struct iucv_connection *conn, struct sk_buff *skb) {
1188 fsm_newstate(conn->fsm, CONN_STATE_TX); 1195 fsm_newstate(conn->fsm, CONN_STATE_TX);
1189 conn->prof.send_stamp = xtime; 1196 conn->prof.send_stamp = xtime;
1190 1197
1191 rc = iucv_send(conn->pathid, NULL, 0, 0, 1 /* single_flag */, 1198 msg.tag = 1;
1192 0, nskb->data, nskb->len); 1199 msg.class = 0;
1193 /* Shut up, gcc! nskb is always below 2G. */ 1200 rc = iucv_message_send(conn->path, &msg, 0, 0,
1201 nskb->data, nskb->len);
1194 conn->prof.doios_single++; 1202 conn->prof.doios_single++;
1195 conn->prof.txlen += skb->len; 1203 conn->prof.txlen += skb->len;
1196 conn->prof.tx_pending++; 1204 conn->prof.tx_pending++;
@@ -1200,7 +1208,7 @@ netiucv_transmit_skb(struct iucv_connection *conn, struct sk_buff *skb) {
1200 struct netiucv_priv *privptr; 1208 struct netiucv_priv *privptr;
1201 fsm_newstate(conn->fsm, CONN_STATE_IDLE); 1209 fsm_newstate(conn->fsm, CONN_STATE_IDLE);
1202 conn->prof.tx_pending--; 1210 conn->prof.tx_pending--;
1203 privptr = (struct netiucv_priv *)conn->netdev->priv; 1211 privptr = netdev_priv(conn->netdev);
1204 if (privptr) 1212 if (privptr)
1205 privptr->stats.tx_errors++; 1213 privptr->stats.tx_errors++;
1206 if (copied) 1214 if (copied)
@@ -1226,9 +1234,9 @@ netiucv_transmit_skb(struct iucv_connection *conn, struct sk_buff *skb) {
1226 return rc; 1234 return rc;
1227} 1235}
1228 1236
1229/** 1237/*
1230 * Interface API for upper network layers 1238 * Interface API for upper network layers
1231 *****************************************************************************/ 1239 */
1232 1240
1233/** 1241/**
1234 * Open an interface. 1242 * Open an interface.
@@ -1238,9 +1246,11 @@ netiucv_transmit_skb(struct iucv_connection *conn, struct sk_buff *skb) {
1238 * 1246 *
1239 * @return 0 on success, -ERRNO on failure. (Never fails.) 1247 * @return 0 on success, -ERRNO on failure. (Never fails.)
1240 */ 1248 */
1241static int 1249static int netiucv_open(struct net_device *dev)
1242netiucv_open(struct net_device *dev) { 1250{
1243 fsm_event(((struct netiucv_priv *)dev->priv)->fsm, DEV_EVENT_START,dev); 1251 struct netiucv_priv *priv = netdev_priv(dev);
1252
1253 fsm_event(priv->fsm, DEV_EVENT_START, dev);
1244 return 0; 1254 return 0;
1245} 1255}
1246 1256
@@ -1252,9 +1262,11 @@ netiucv_open(struct net_device *dev) {
1252 * 1262 *
1253 * @return 0 on success, -ERRNO on failure. (Never fails.) 1263 * @return 0 on success, -ERRNO on failure. (Never fails.)
1254 */ 1264 */
1255static int 1265static int netiucv_close(struct net_device *dev)
1256netiucv_close(struct net_device *dev) { 1266{
1257 fsm_event(((struct netiucv_priv *)dev->priv)->fsm, DEV_EVENT_STOP, dev); 1267 struct netiucv_priv *priv = netdev_priv(dev);
1268
1269 fsm_event(priv->fsm, DEV_EVENT_STOP, dev);
1258 return 0; 1270 return 0;
1259} 1271}
1260 1272
@@ -1271,8 +1283,8 @@ netiucv_close(struct net_device *dev) {
1271 */ 1283 */
1272static int netiucv_tx(struct sk_buff *skb, struct net_device *dev) 1284static int netiucv_tx(struct sk_buff *skb, struct net_device *dev)
1273{ 1285{
1274 int rc = 0; 1286 struct netiucv_priv *privptr = netdev_priv(dev);
1275 struct netiucv_priv *privptr = dev->priv; 1287 int rc;
1276 1288
1277 IUCV_DBF_TEXT(trace, 4, __FUNCTION__); 1289 IUCV_DBF_TEXT(trace, 4, __FUNCTION__);
1278 /** 1290 /**
@@ -1312,40 +1324,41 @@ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev)
1312 return -EBUSY; 1324 return -EBUSY;
1313 } 1325 }
1314 dev->trans_start = jiffies; 1326 dev->trans_start = jiffies;
1315 if (netiucv_transmit_skb(privptr->conn, skb)) 1327 rc = netiucv_transmit_skb(privptr->conn, skb) != 0;
1316 rc = 1;
1317 netiucv_clear_busy(dev); 1328 netiucv_clear_busy(dev);
1318 return rc; 1329 return rc;
1319} 1330}
1320 1331
1321/** 1332/**
1322 * Returns interface statistics of a device. 1333 * netiucv_stats
1334 * @dev: Pointer to interface struct.
1323 * 1335 *
1324 * @param dev Pointer to interface struct. 1336 * Returns interface statistics of a device.
1325 * 1337 *
1326 * @return Pointer to stats struct of this interface. 1338 * Returns pointer to stats struct of this interface.
1327 */ 1339 */
1328static struct net_device_stats * 1340static struct net_device_stats *netiucv_stats (struct net_device * dev)
1329netiucv_stats (struct net_device * dev)
1330{ 1341{
1342 struct netiucv_priv *priv = netdev_priv(dev);
1343
1331 IUCV_DBF_TEXT(trace, 5, __FUNCTION__); 1344 IUCV_DBF_TEXT(trace, 5, __FUNCTION__);
1332 return &((struct netiucv_priv *)dev->priv)->stats; 1345 return &priv->stats;
1333} 1346}
1334 1347
1335/** 1348/**
1336 * Sets MTU of an interface. 1349 * netiucv_change_mtu
1350 * @dev: Pointer to interface struct.
1351 * @new_mtu: The new MTU to use for this interface.
1337 * 1352 *
1338 * @param dev Pointer to interface struct. 1353 * Sets MTU of an interface.
1339 * @param new_mtu The new MTU to use for this interface.
1340 * 1354 *
1341 * @return 0 on success, -EINVAL if MTU is out of valid range. 1355 * Returns 0 on success, -EINVAL if MTU is out of valid range.
1342 * (valid range is 576 .. NETIUCV_MTU_MAX). 1356 * (valid range is 576 .. NETIUCV_MTU_MAX).
1343 */ 1357 */
1344static int 1358static int netiucv_change_mtu(struct net_device * dev, int new_mtu)
1345netiucv_change_mtu (struct net_device * dev, int new_mtu)
1346{ 1359{
1347 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 1360 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1348 if ((new_mtu < 576) || (new_mtu > NETIUCV_MTU_MAX)) { 1361 if (new_mtu < 576 || new_mtu > NETIUCV_MTU_MAX) {
1349 IUCV_DBF_TEXT(setup, 2, "given MTU out of valid range\n"); 1362 IUCV_DBF_TEXT(setup, 2, "given MTU out of valid range\n");
1350 return -EINVAL; 1363 return -EINVAL;
1351 } 1364 }
@@ -1353,12 +1366,12 @@ netiucv_change_mtu (struct net_device * dev, int new_mtu)
1353 return 0; 1366 return 0;
1354} 1367}
1355 1368
1356/** 1369/*
1357 * attributes in sysfs 1370 * attributes in sysfs
1358 *****************************************************************************/ 1371 */
1359 1372
1360static ssize_t 1373static ssize_t user_show(struct device *dev, struct device_attribute *attr,
1361user_show (struct device *dev, struct device_attribute *attr, char *buf) 1374 char *buf)
1362{ 1375{
1363 struct netiucv_priv *priv = dev->driver_data; 1376 struct netiucv_priv *priv = dev->driver_data;
1364 1377
@@ -1366,8 +1379,8 @@ user_show (struct device *dev, struct device_attribute *attr, char *buf)
1366 return sprintf(buf, "%s\n", netiucv_printname(priv->conn->userid)); 1379 return sprintf(buf, "%s\n", netiucv_printname(priv->conn->userid));
1367} 1380}
1368 1381
1369static ssize_t 1382static ssize_t user_write(struct device *dev, struct device_attribute *attr,
1370user_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1383 const char *buf, size_t count)
1371{ 1384{
1372 struct netiucv_priv *priv = dev->driver_data; 1385 struct netiucv_priv *priv = dev->driver_data;
1373 struct net_device *ndev = priv->conn->netdev; 1386 struct net_device *ndev = priv->conn->netdev;
@@ -1375,80 +1388,70 @@ user_write (struct device *dev, struct device_attribute *attr, const char *buf,
1375 char *tmp; 1388 char *tmp;
1376 char username[9]; 1389 char username[9];
1377 int i; 1390 int i;
1378 struct iucv_connection **clist = &iucv_conns.iucv_connections; 1391 struct iucv_connection *cp;
1379 unsigned long flags;
1380 1392
1381 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 1393 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1382 if (count>9) { 1394 if (count > 9) {
1383 PRINT_WARN("netiucv: username too long (%d)!\n", (int)count); 1395 PRINT_WARN("netiucv: username too long (%d)!\n", (int) count);
1384 IUCV_DBF_TEXT_(setup, 2, 1396 IUCV_DBF_TEXT_(setup, 2,
1385 "%d is length of username\n", (int)count); 1397 "%d is length of username\n", (int) count);
1386 return -EINVAL; 1398 return -EINVAL;
1387 } 1399 }
1388 1400
1389 tmp = strsep((char **) &buf, "\n"); 1401 tmp = strsep((char **) &buf, "\n");
1390 for (i=0, p=tmp; i<8 && *p; i++, p++) { 1402 for (i = 0, p = tmp; i < 8 && *p; i++, p++) {
1391 if (isalnum(*p) || (*p == '$')) 1403 if (isalnum(*p) || (*p == '$')) {
1392 username[i]= toupper(*p); 1404 username[i]= toupper(*p);
1393 else if (*p == '\n') { 1405 continue;
1406 }
1407 if (*p == '\n') {
1394 /* trailing lf, grr */ 1408 /* trailing lf, grr */
1395 break; 1409 break;
1396 } else {
1397 PRINT_WARN("netiucv: Invalid char %c in username!\n",
1398 *p);
1399 IUCV_DBF_TEXT_(setup, 2,
1400 "username: invalid character %c\n",
1401 *p);
1402 return -EINVAL;
1403 } 1410 }
1411 PRINT_WARN("netiucv: Invalid char %c in username!\n", *p);
1412 IUCV_DBF_TEXT_(setup, 2,
1413 "username: invalid character %c\n", *p);
1414 return -EINVAL;
1404 } 1415 }
1405 while (i<8) 1416 while (i < 8)
1406 username[i++] = ' '; 1417 username[i++] = ' ';
1407 username[8] = '\0'; 1418 username[8] = '\0';
1408 1419
1409 if (memcmp(username, priv->conn->userid, 9)) { 1420 if (memcmp(username, priv->conn->userid, 9) &&
1410 /* username changed */ 1421 (ndev->flags & (IFF_UP | IFF_RUNNING))) {
1411 if (ndev->flags & (IFF_UP | IFF_RUNNING)) { 1422 /* username changed while the interface is active. */
1412 PRINT_WARN( 1423 PRINT_WARN("netiucv: device %s active, connected to %s\n",
1413 "netiucv: device %s active, connected to %s\n", 1424 dev->bus_id, priv->conn->userid);
1414 dev->bus_id, priv->conn->userid); 1425 PRINT_WARN("netiucv: user cannot be updated\n");
1415 PRINT_WARN("netiucv: user cannot be updated\n"); 1426 IUCV_DBF_TEXT(setup, 2, "user_write: device active\n");
1416 IUCV_DBF_TEXT(setup, 2, "user_write: device active\n"); 1427 return -EBUSY;
1417 return -EBUSY; 1428 }
1429 read_lock_bh(&iucv_connection_rwlock);
1430 list_for_each_entry(cp, &iucv_connection_list, list) {
1431 if (!strncmp(username, cp->userid, 9) && cp->netdev != ndev) {
1432 read_unlock_bh(&iucv_connection_rwlock);
1433 PRINT_WARN("netiucv: Connection to %s already "
1434 "exists\n", username);
1435 return -EEXIST;
1418 } 1436 }
1419 } 1437 }
1420 read_lock_irqsave(&iucv_conns.iucv_rwlock, flags); 1438 read_unlock_bh(&iucv_connection_rwlock);
1421 while (*clist) {
1422 if (!strncmp(username, (*clist)->userid, 9) ||
1423 ((*clist)->netdev != ndev))
1424 break;
1425 clist = &((*clist)->next);
1426 }
1427 read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags);
1428 if (*clist) {
1429 PRINT_WARN("netiucv: Connection to %s already exists\n",
1430 username);
1431 return -EEXIST;
1432 }
1433 memcpy(priv->conn->userid, username, 9); 1439 memcpy(priv->conn->userid, username, 9);
1434
1435 return count; 1440 return count;
1436
1437} 1441}
1438 1442
1439static DEVICE_ATTR(user, 0644, user_show, user_write); 1443static DEVICE_ATTR(user, 0644, user_show, user_write);
1440 1444
1441static ssize_t 1445static ssize_t buffer_show (struct device *dev, struct device_attribute *attr,
1442buffer_show (struct device *dev, struct device_attribute *attr, char *buf) 1446 char *buf)
1443{ 1447{ struct netiucv_priv *priv = dev->driver_data;
1444 struct netiucv_priv *priv = dev->driver_data;
1445 1448
1446 IUCV_DBF_TEXT(trace, 5, __FUNCTION__); 1449 IUCV_DBF_TEXT(trace, 5, __FUNCTION__);
1447 return sprintf(buf, "%d\n", priv->conn->max_buffsize); 1450 return sprintf(buf, "%d\n", priv->conn->max_buffsize);
1448} 1451}
1449 1452
1450static ssize_t 1453static ssize_t buffer_write (struct device *dev, struct device_attribute *attr,
1451buffer_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1454 const char *buf, size_t count)
1452{ 1455{
1453 struct netiucv_priv *priv = dev->driver_data; 1456 struct netiucv_priv *priv = dev->driver_data;
1454 struct net_device *ndev = priv->conn->netdev; 1457 struct net_device *ndev = priv->conn->netdev;
@@ -1502,8 +1505,8 @@ buffer_write (struct device *dev, struct device_attribute *attr, const char *buf
1502 1505
1503static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write); 1506static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write);
1504 1507
1505static ssize_t 1508static ssize_t dev_fsm_show (struct device *dev, struct device_attribute *attr,
1506dev_fsm_show (struct device *dev, struct device_attribute *attr, char *buf) 1509 char *buf)
1507{ 1510{
1508 struct netiucv_priv *priv = dev->driver_data; 1511 struct netiucv_priv *priv = dev->driver_data;
1509 1512
@@ -1513,8 +1516,8 @@ dev_fsm_show (struct device *dev, struct device_attribute *attr, char *buf)
1513 1516
1514static DEVICE_ATTR(device_fsm_state, 0444, dev_fsm_show, NULL); 1517static DEVICE_ATTR(device_fsm_state, 0444, dev_fsm_show, NULL);
1515 1518
1516static ssize_t 1519static ssize_t conn_fsm_show (struct device *dev,
1517conn_fsm_show (struct device *dev, struct device_attribute *attr, char *buf) 1520 struct device_attribute *attr, char *buf)
1518{ 1521{
1519 struct netiucv_priv *priv = dev->driver_data; 1522 struct netiucv_priv *priv = dev->driver_data;
1520 1523
@@ -1524,8 +1527,8 @@ conn_fsm_show (struct device *dev, struct device_attribute *attr, char *buf)
1524 1527
1525static DEVICE_ATTR(connection_fsm_state, 0444, conn_fsm_show, NULL); 1528static DEVICE_ATTR(connection_fsm_state, 0444, conn_fsm_show, NULL);
1526 1529
1527static ssize_t 1530static ssize_t maxmulti_show (struct device *dev,
1528maxmulti_show (struct device *dev, struct device_attribute *attr, char *buf) 1531 struct device_attribute *attr, char *buf)
1529{ 1532{
1530 struct netiucv_priv *priv = dev->driver_data; 1533 struct netiucv_priv *priv = dev->driver_data;
1531 1534
@@ -1533,8 +1536,9 @@ maxmulti_show (struct device *dev, struct device_attribute *attr, char *buf)
1533 return sprintf(buf, "%ld\n", priv->conn->prof.maxmulti); 1536 return sprintf(buf, "%ld\n", priv->conn->prof.maxmulti);
1534} 1537}
1535 1538
1536static ssize_t 1539static ssize_t maxmulti_write (struct device *dev,
1537maxmulti_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1540 struct device_attribute *attr,
1541 const char *buf, size_t count)
1538{ 1542{
1539 struct netiucv_priv *priv = dev->driver_data; 1543 struct netiucv_priv *priv = dev->driver_data;
1540 1544
@@ -1545,8 +1549,8 @@ maxmulti_write (struct device *dev, struct device_attribute *attr, const char *b
1545 1549
1546static DEVICE_ATTR(max_tx_buffer_used, 0644, maxmulti_show, maxmulti_write); 1550static DEVICE_ATTR(max_tx_buffer_used, 0644, maxmulti_show, maxmulti_write);
1547 1551
1548static ssize_t 1552static ssize_t maxcq_show (struct device *dev, struct device_attribute *attr,
1549maxcq_show (struct device *dev, struct device_attribute *attr, char *buf) 1553 char *buf)
1550{ 1554{
1551 struct netiucv_priv *priv = dev->driver_data; 1555 struct netiucv_priv *priv = dev->driver_data;
1552 1556
@@ -1554,8 +1558,8 @@ maxcq_show (struct device *dev, struct device_attribute *attr, char *buf)
1554 return sprintf(buf, "%ld\n", priv->conn->prof.maxcqueue); 1558 return sprintf(buf, "%ld\n", priv->conn->prof.maxcqueue);
1555} 1559}
1556 1560
1557static ssize_t 1561static ssize_t maxcq_write (struct device *dev, struct device_attribute *attr,
1558maxcq_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1562 const char *buf, size_t count)
1559{ 1563{
1560 struct netiucv_priv *priv = dev->driver_data; 1564 struct netiucv_priv *priv = dev->driver_data;
1561 1565
@@ -1566,8 +1570,8 @@ maxcq_write (struct device *dev, struct device_attribute *attr, const char *buf,
1566 1570
1567static DEVICE_ATTR(max_chained_skbs, 0644, maxcq_show, maxcq_write); 1571static DEVICE_ATTR(max_chained_skbs, 0644, maxcq_show, maxcq_write);
1568 1572
1569static ssize_t 1573static ssize_t sdoio_show (struct device *dev, struct device_attribute *attr,
1570sdoio_show (struct device *dev, struct device_attribute *attr, char *buf) 1574 char *buf)
1571{ 1575{
1572 struct netiucv_priv *priv = dev->driver_data; 1576 struct netiucv_priv *priv = dev->driver_data;
1573 1577
@@ -1575,8 +1579,8 @@ sdoio_show (struct device *dev, struct device_attribute *attr, char *buf)
1575 return sprintf(buf, "%ld\n", priv->conn->prof.doios_single); 1579 return sprintf(buf, "%ld\n", priv->conn->prof.doios_single);
1576} 1580}
1577 1581
1578static ssize_t 1582static ssize_t sdoio_write (struct device *dev, struct device_attribute *attr,
1579sdoio_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1583 const char *buf, size_t count)
1580{ 1584{
1581 struct netiucv_priv *priv = dev->driver_data; 1585 struct netiucv_priv *priv = dev->driver_data;
1582 1586
@@ -1587,8 +1591,8 @@ sdoio_write (struct device *dev, struct device_attribute *attr, const char *buf,
1587 1591
1588static DEVICE_ATTR(tx_single_write_ops, 0644, sdoio_show, sdoio_write); 1592static DEVICE_ATTR(tx_single_write_ops, 0644, sdoio_show, sdoio_write);
1589 1593
1590static ssize_t 1594static ssize_t mdoio_show (struct device *dev, struct device_attribute *attr,
1591mdoio_show (struct device *dev, struct device_attribute *attr, char *buf) 1595 char *buf)
1592{ 1596{
1593 struct netiucv_priv *priv = dev->driver_data; 1597 struct netiucv_priv *priv = dev->driver_data;
1594 1598
@@ -1596,8 +1600,8 @@ mdoio_show (struct device *dev, struct device_attribute *attr, char *buf)
1596 return sprintf(buf, "%ld\n", priv->conn->prof.doios_multi); 1600 return sprintf(buf, "%ld\n", priv->conn->prof.doios_multi);
1597} 1601}
1598 1602
1599static ssize_t 1603static ssize_t mdoio_write (struct device *dev, struct device_attribute *attr,
1600mdoio_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1604 const char *buf, size_t count)
1601{ 1605{
1602 struct netiucv_priv *priv = dev->driver_data; 1606 struct netiucv_priv *priv = dev->driver_data;
1603 1607
@@ -1608,8 +1612,8 @@ mdoio_write (struct device *dev, struct device_attribute *attr, const char *buf,
1608 1612
1609static DEVICE_ATTR(tx_multi_write_ops, 0644, mdoio_show, mdoio_write); 1613static DEVICE_ATTR(tx_multi_write_ops, 0644, mdoio_show, mdoio_write);
1610 1614
1611static ssize_t 1615static ssize_t txlen_show (struct device *dev, struct device_attribute *attr,
1612txlen_show (struct device *dev, struct device_attribute *attr, char *buf) 1616 char *buf)
1613{ 1617{
1614 struct netiucv_priv *priv = dev->driver_data; 1618 struct netiucv_priv *priv = dev->driver_data;
1615 1619
@@ -1617,8 +1621,8 @@ txlen_show (struct device *dev, struct device_attribute *attr, char *buf)
1617 return sprintf(buf, "%ld\n", priv->conn->prof.txlen); 1621 return sprintf(buf, "%ld\n", priv->conn->prof.txlen);
1618} 1622}
1619 1623
1620static ssize_t 1624static ssize_t txlen_write (struct device *dev, struct device_attribute *attr,
1621txlen_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1625 const char *buf, size_t count)
1622{ 1626{
1623 struct netiucv_priv *priv = dev->driver_data; 1627 struct netiucv_priv *priv = dev->driver_data;
1624 1628
@@ -1629,8 +1633,8 @@ txlen_write (struct device *dev, struct device_attribute *attr, const char *buf,
1629 1633
1630static DEVICE_ATTR(netto_bytes, 0644, txlen_show, txlen_write); 1634static DEVICE_ATTR(netto_bytes, 0644, txlen_show, txlen_write);
1631 1635
1632static ssize_t 1636static ssize_t txtime_show (struct device *dev, struct device_attribute *attr,
1633txtime_show (struct device *dev, struct device_attribute *attr, char *buf) 1637 char *buf)
1634{ 1638{
1635 struct netiucv_priv *priv = dev->driver_data; 1639 struct netiucv_priv *priv = dev->driver_data;
1636 1640
@@ -1638,8 +1642,8 @@ txtime_show (struct device *dev, struct device_attribute *attr, char *buf)
1638 return sprintf(buf, "%ld\n", priv->conn->prof.tx_time); 1642 return sprintf(buf, "%ld\n", priv->conn->prof.tx_time);
1639} 1643}
1640 1644
1641static ssize_t 1645static ssize_t txtime_write (struct device *dev, struct device_attribute *attr,
1642txtime_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1646 const char *buf, size_t count)
1643{ 1647{
1644 struct netiucv_priv *priv = dev->driver_data; 1648 struct netiucv_priv *priv = dev->driver_data;
1645 1649
@@ -1650,8 +1654,8 @@ txtime_write (struct device *dev, struct device_attribute *attr, const char *buf
1650 1654
1651static DEVICE_ATTR(max_tx_io_time, 0644, txtime_show, txtime_write); 1655static DEVICE_ATTR(max_tx_io_time, 0644, txtime_show, txtime_write);
1652 1656
1653static ssize_t 1657static ssize_t txpend_show (struct device *dev, struct device_attribute *attr,
1654txpend_show (struct device *dev, struct device_attribute *attr, char *buf) 1658 char *buf)
1655{ 1659{
1656 struct netiucv_priv *priv = dev->driver_data; 1660 struct netiucv_priv *priv = dev->driver_data;
1657 1661
@@ -1659,8 +1663,8 @@ txpend_show (struct device *dev, struct device_attribute *attr, char *buf)
1659 return sprintf(buf, "%ld\n", priv->conn->prof.tx_pending); 1663 return sprintf(buf, "%ld\n", priv->conn->prof.tx_pending);
1660} 1664}
1661 1665
1662static ssize_t 1666static ssize_t txpend_write (struct device *dev, struct device_attribute *attr,
1663txpend_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1667 const char *buf, size_t count)
1664{ 1668{
1665 struct netiucv_priv *priv = dev->driver_data; 1669 struct netiucv_priv *priv = dev->driver_data;
1666 1670
@@ -1671,8 +1675,8 @@ txpend_write (struct device *dev, struct device_attribute *attr, const char *buf
1671 1675
1672static DEVICE_ATTR(tx_pending, 0644, txpend_show, txpend_write); 1676static DEVICE_ATTR(tx_pending, 0644, txpend_show, txpend_write);
1673 1677
1674static ssize_t 1678static ssize_t txmpnd_show (struct device *dev, struct device_attribute *attr,
1675txmpnd_show (struct device *dev, struct device_attribute *attr, char *buf) 1679 char *buf)
1676{ 1680{
1677 struct netiucv_priv *priv = dev->driver_data; 1681 struct netiucv_priv *priv = dev->driver_data;
1678 1682
@@ -1680,8 +1684,8 @@ txmpnd_show (struct device *dev, struct device_attribute *attr, char *buf)
1680 return sprintf(buf, "%ld\n", priv->conn->prof.tx_max_pending); 1684 return sprintf(buf, "%ld\n", priv->conn->prof.tx_max_pending);
1681} 1685}
1682 1686
1683static ssize_t 1687static ssize_t txmpnd_write (struct device *dev, struct device_attribute *attr,
1684txmpnd_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1688 const char *buf, size_t count)
1685{ 1689{
1686 struct netiucv_priv *priv = dev->driver_data; 1690 struct netiucv_priv *priv = dev->driver_data;
1687 1691
@@ -1721,8 +1725,7 @@ static struct attribute_group netiucv_stat_attr_group = {
1721 .attrs = netiucv_stat_attrs, 1725 .attrs = netiucv_stat_attrs,
1722}; 1726};
1723 1727
1724static inline int 1728static inline int netiucv_add_files(struct device *dev)
1725netiucv_add_files(struct device *dev)
1726{ 1729{
1727 int ret; 1730 int ret;
1728 1731
@@ -1736,18 +1739,16 @@ netiucv_add_files(struct device *dev)
1736 return ret; 1739 return ret;
1737} 1740}
1738 1741
1739static inline void 1742static inline void netiucv_remove_files(struct device *dev)
1740netiucv_remove_files(struct device *dev)
1741{ 1743{
1742 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 1744 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1743 sysfs_remove_group(&dev->kobj, &netiucv_stat_attr_group); 1745 sysfs_remove_group(&dev->kobj, &netiucv_stat_attr_group);
1744 sysfs_remove_group(&dev->kobj, &netiucv_attr_group); 1746 sysfs_remove_group(&dev->kobj, &netiucv_attr_group);
1745} 1747}
1746 1748
1747static int 1749static int netiucv_register_device(struct net_device *ndev)
1748netiucv_register_device(struct net_device *ndev)
1749{ 1750{
1750 struct netiucv_priv *priv = ndev->priv; 1751 struct netiucv_priv *priv = netdev_priv(ndev);
1751 struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL); 1752 struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL);
1752 int ret; 1753 int ret;
1753 1754
@@ -1786,8 +1787,7 @@ out_unreg:
1786 return ret; 1787 return ret;
1787} 1788}
1788 1789
1789static void 1790static void netiucv_unregister_device(struct device *dev)
1790netiucv_unregister_device(struct device *dev)
1791{ 1791{
1792 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 1792 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1793 netiucv_remove_files(dev); 1793 netiucv_remove_files(dev);
@@ -1798,107 +1798,89 @@ netiucv_unregister_device(struct device *dev)
1798 * Allocate and initialize a new connection structure. 1798 * Allocate and initialize a new connection structure.
1799 * Add it to the list of netiucv connections; 1799 * Add it to the list of netiucv connections;
1800 */ 1800 */
1801static struct iucv_connection * 1801static struct iucv_connection *netiucv_new_connection(struct net_device *dev,
1802netiucv_new_connection(struct net_device *dev, char *username) 1802 char *username)
1803{ 1803{
1804 unsigned long flags; 1804 struct iucv_connection *conn;
1805 struct iucv_connection **clist = &iucv_conns.iucv_connections;
1806 struct iucv_connection *conn =
1807 kzalloc(sizeof(struct iucv_connection), GFP_KERNEL);
1808
1809 if (conn) {
1810 skb_queue_head_init(&conn->collect_queue);
1811 skb_queue_head_init(&conn->commit_queue);
1812 spin_lock_init(&conn->collect_lock);
1813 conn->max_buffsize = NETIUCV_BUFSIZE_DEFAULT;
1814 conn->netdev = dev;
1815
1816 conn->rx_buff = alloc_skb(NETIUCV_BUFSIZE_DEFAULT,
1817 GFP_KERNEL | GFP_DMA);
1818 if (!conn->rx_buff) {
1819 kfree(conn);
1820 return NULL;
1821 }
1822 conn->tx_buff = alloc_skb(NETIUCV_BUFSIZE_DEFAULT,
1823 GFP_KERNEL | GFP_DMA);
1824 if (!conn->tx_buff) {
1825 kfree_skb(conn->rx_buff);
1826 kfree(conn);
1827 return NULL;
1828 }
1829 conn->fsm = init_fsm("netiucvconn", conn_state_names,
1830 conn_event_names, NR_CONN_STATES,
1831 NR_CONN_EVENTS, conn_fsm, CONN_FSM_LEN,
1832 GFP_KERNEL);
1833 if (!conn->fsm) {
1834 kfree_skb(conn->tx_buff);
1835 kfree_skb(conn->rx_buff);
1836 kfree(conn);
1837 return NULL;
1838 }
1839 fsm_settimer(conn->fsm, &conn->timer);
1840 fsm_newstate(conn->fsm, CONN_STATE_INVALID);
1841
1842 if (username) {
1843 memcpy(conn->userid, username, 9);
1844 fsm_newstate(conn->fsm, CONN_STATE_STOPPED);
1845 }
1846 1805
1847 write_lock_irqsave(&iucv_conns.iucv_rwlock, flags); 1806 conn = kzalloc(sizeof(*conn), GFP_KERNEL);
1848 conn->next = *clist; 1807 if (!conn)
1849 *clist = conn; 1808 goto out;
1850 write_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); 1809 skb_queue_head_init(&conn->collect_queue);
1810 skb_queue_head_init(&conn->commit_queue);
1811 spin_lock_init(&conn->collect_lock);
1812 conn->max_buffsize = NETIUCV_BUFSIZE_DEFAULT;
1813 conn->netdev = dev;
1814
1815 conn->rx_buff = alloc_skb(conn->max_buffsize, GFP_KERNEL | GFP_DMA);
1816 if (!conn->rx_buff)
1817 goto out_conn;
1818 conn->tx_buff = alloc_skb(conn->max_buffsize, GFP_KERNEL | GFP_DMA);
1819 if (!conn->tx_buff)
1820 goto out_rx;
1821 conn->fsm = init_fsm("netiucvconn", conn_state_names,
1822 conn_event_names, NR_CONN_STATES,
1823 NR_CONN_EVENTS, conn_fsm, CONN_FSM_LEN,
1824 GFP_KERNEL);
1825 if (!conn->fsm)
1826 goto out_tx;
1827
1828 fsm_settimer(conn->fsm, &conn->timer);
1829 fsm_newstate(conn->fsm, CONN_STATE_INVALID);
1830
1831 if (username) {
1832 memcpy(conn->userid, username, 9);
1833 fsm_newstate(conn->fsm, CONN_STATE_STOPPED);
1851 } 1834 }
1835
1836 write_lock_bh(&iucv_connection_rwlock);
1837 list_add_tail(&conn->list, &iucv_connection_list);
1838 write_unlock_bh(&iucv_connection_rwlock);
1852 return conn; 1839 return conn;
1840
1841out_tx:
1842 kfree_skb(conn->tx_buff);
1843out_rx:
1844 kfree_skb(conn->rx_buff);
1845out_conn:
1846 kfree(conn);
1847out:
1848 return NULL;
1853} 1849}
1854 1850
1855/** 1851/**
1856 * Release a connection structure and remove it from the 1852 * Release a connection structure and remove it from the
1857 * list of netiucv connections. 1853 * list of netiucv connections.
1858 */ 1854 */
1859static void 1855static void netiucv_remove_connection(struct iucv_connection *conn)
1860netiucv_remove_connection(struct iucv_connection *conn)
1861{ 1856{
1862 struct iucv_connection **clist = &iucv_conns.iucv_connections;
1863 unsigned long flags;
1864
1865 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 1857 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1866 if (conn == NULL) 1858 write_lock_bh(&iucv_connection_rwlock);
1867 return; 1859 list_del_init(&conn->list);
1868 write_lock_irqsave(&iucv_conns.iucv_rwlock, flags); 1860 write_unlock_bh(&iucv_connection_rwlock);
1869 while (*clist) { 1861 if (conn->path) {
1870 if (*clist == conn) { 1862 iucv_path_sever(conn->path, iucvMagic);
1871 *clist = conn->next; 1863 kfree(conn->path);
1872 write_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); 1864 conn->path = NULL;
1873 if (conn->handle) {
1874 iucv_unregister_program(conn->handle);
1875 conn->handle = NULL;
1876 }
1877 fsm_deltimer(&conn->timer);
1878 kfree_fsm(conn->fsm);
1879 kfree_skb(conn->rx_buff);
1880 kfree_skb(conn->tx_buff);
1881 return;
1882 }
1883 clist = &((*clist)->next);
1884 } 1865 }
1885 write_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); 1866 fsm_deltimer(&conn->timer);
1867 kfree_fsm(conn->fsm);
1868 kfree_skb(conn->rx_buff);
1869 kfree_skb(conn->tx_buff);
1886} 1870}
1887 1871
1888/** 1872/**
1889 * Release everything of a net device. 1873 * Release everything of a net device.
1890 */ 1874 */
1891static void 1875static void netiucv_free_netdevice(struct net_device *dev)
1892netiucv_free_netdevice(struct net_device *dev)
1893{ 1876{
1894 struct netiucv_priv *privptr; 1877 struct netiucv_priv *privptr = netdev_priv(dev);
1895 1878
1896 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 1879 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1897 1880
1898 if (!dev) 1881 if (!dev)
1899 return; 1882 return;
1900 1883
1901 privptr = (struct netiucv_priv *)dev->priv;
1902 if (privptr) { 1884 if (privptr) {
1903 if (privptr->conn) 1885 if (privptr->conn)
1904 netiucv_remove_connection(privptr->conn); 1886 netiucv_remove_connection(privptr->conn);
@@ -1913,11 +1895,8 @@ netiucv_free_netdevice(struct net_device *dev)
1913/** 1895/**
1914 * Initialize a net device. (Called from kernel in alloc_netdev()) 1896 * Initialize a net device. (Called from kernel in alloc_netdev())
1915 */ 1897 */
1916static void 1898static void netiucv_setup_netdevice(struct net_device *dev)
1917netiucv_setup_netdevice(struct net_device *dev)
1918{ 1899{
1919 memset(dev->priv, 0, sizeof(struct netiucv_priv));
1920
1921 dev->mtu = NETIUCV_MTU_DEFAULT; 1900 dev->mtu = NETIUCV_MTU_DEFAULT;
1922 dev->hard_start_xmit = netiucv_tx; 1901 dev->hard_start_xmit = netiucv_tx;
1923 dev->open = netiucv_open; 1902 dev->open = netiucv_open;
@@ -1936,8 +1915,7 @@ netiucv_setup_netdevice(struct net_device *dev)
1936/** 1915/**
1937 * Allocate and initialize everything of a net device. 1916 * Allocate and initialize everything of a net device.
1938 */ 1917 */
1939static struct net_device * 1918static struct net_device *netiucv_init_netdevice(char *username)
1940netiucv_init_netdevice(char *username)
1941{ 1919{
1942 struct netiucv_priv *privptr; 1920 struct netiucv_priv *privptr;
1943 struct net_device *dev; 1921 struct net_device *dev;
@@ -1946,40 +1924,40 @@ netiucv_init_netdevice(char *username)
1946 netiucv_setup_netdevice); 1924 netiucv_setup_netdevice);
1947 if (!dev) 1925 if (!dev)
1948 return NULL; 1926 return NULL;
1949 if (dev_alloc_name(dev, dev->name) < 0) { 1927 if (dev_alloc_name(dev, dev->name) < 0)
1950 free_netdev(dev); 1928 goto out_netdev;
1951 return NULL;
1952 }
1953 1929
1954 privptr = (struct netiucv_priv *)dev->priv; 1930 privptr = netdev_priv(dev);
1955 privptr->fsm = init_fsm("netiucvdev", dev_state_names, 1931 privptr->fsm = init_fsm("netiucvdev", dev_state_names,
1956 dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS, 1932 dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS,
1957 dev_fsm, DEV_FSM_LEN, GFP_KERNEL); 1933 dev_fsm, DEV_FSM_LEN, GFP_KERNEL);
1958 if (!privptr->fsm) { 1934 if (!privptr->fsm)
1959 free_netdev(dev); 1935 goto out_netdev;
1960 return NULL; 1936
1961 }
1962 privptr->conn = netiucv_new_connection(dev, username); 1937 privptr->conn = netiucv_new_connection(dev, username);
1963 if (!privptr->conn) { 1938 if (!privptr->conn) {
1964 kfree_fsm(privptr->fsm);
1965 free_netdev(dev);
1966 IUCV_DBF_TEXT(setup, 2, "NULL from netiucv_new_connection\n"); 1939 IUCV_DBF_TEXT(setup, 2, "NULL from netiucv_new_connection\n");
1967 return NULL; 1940 goto out_fsm;
1968 } 1941 }
1969 fsm_newstate(privptr->fsm, DEV_STATE_STOPPED); 1942 fsm_newstate(privptr->fsm, DEV_STATE_STOPPED);
1970
1971 return dev; 1943 return dev;
1944
1945out_fsm:
1946 kfree_fsm(privptr->fsm);
1947out_netdev:
1948 free_netdev(dev);
1949 return NULL;
1972} 1950}
1973 1951
1974static ssize_t 1952static ssize_t conn_write(struct device_driver *drv,
1975conn_write(struct device_driver *drv, const char *buf, size_t count) 1953 const char *buf, size_t count)
1976{ 1954{
1977 char *p; 1955 const char *p;
1978 char username[9]; 1956 char username[9];
1979 int i, ret; 1957 int i, rc;
1980 struct net_device *dev; 1958 struct net_device *dev;
1981 struct iucv_connection **clist = &iucv_conns.iucv_connections; 1959 struct netiucv_priv *priv;
1982 unsigned long flags; 1960 struct iucv_connection *cp;
1983 1961
1984 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 1962 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
1985 if (count>9) { 1963 if (count>9) {
@@ -1988,83 +1966,82 @@ conn_write(struct device_driver *drv, const char *buf, size_t count)
1988 return -EINVAL; 1966 return -EINVAL;
1989 } 1967 }
1990 1968
1991 for (i=0, p=(char *)buf; i<8 && *p; i++, p++) { 1969 for (i = 0, p = buf; i < 8 && *p; i++, p++) {
1992 if (isalnum(*p) || (*p == '$')) 1970 if (isalnum(*p) || *p == '$') {
1993 username[i]= toupper(*p); 1971 username[i] = toupper(*p);
1994 else if (*p == '\n') { 1972 continue;
1973 }
1974 if (*p == '\n')
1995 /* trailing lf, grr */ 1975 /* trailing lf, grr */
1996 break; 1976 break;
1997 } else { 1977 PRINT_WARN("netiucv: Invalid character in username!\n");
1998 PRINT_WARN("netiucv: Invalid character in username!\n"); 1978 IUCV_DBF_TEXT_(setup, 2,
1999 IUCV_DBF_TEXT_(setup, 2, 1979 "conn_write: invalid character %c\n", *p);
2000 "conn_write: invalid character %c\n", *p); 1980 return -EINVAL;
2001 return -EINVAL;
2002 }
2003 } 1981 }
2004 while (i<8) 1982 while (i < 8)
2005 username[i++] = ' '; 1983 username[i++] = ' ';
2006 username[8] = '\0'; 1984 username[8] = '\0';
2007 1985
2008 read_lock_irqsave(&iucv_conns.iucv_rwlock, flags); 1986 read_lock_bh(&iucv_connection_rwlock);
2009 while (*clist) { 1987 list_for_each_entry(cp, &iucv_connection_list, list) {
2010 if (!strncmp(username, (*clist)->userid, 9)) 1988 if (!strncmp(username, cp->userid, 9)) {
2011 break; 1989 read_unlock_bh(&iucv_connection_rwlock);
2012 clist = &((*clist)->next); 1990 PRINT_WARN("netiucv: Connection to %s already "
2013 } 1991 "exists\n", username);
2014 read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); 1992 return -EEXIST;
2015 if (*clist) { 1993 }
2016 PRINT_WARN("netiucv: Connection to %s already exists\n",
2017 username);
2018 return -EEXIST;
2019 } 1994 }
1995 read_unlock_bh(&iucv_connection_rwlock);
1996
2020 dev = netiucv_init_netdevice(username); 1997 dev = netiucv_init_netdevice(username);
2021 if (!dev) { 1998 if (!dev) {
2022 PRINT_WARN( 1999 PRINT_WARN("netiucv: Could not allocate network device "
2023 "netiucv: Could not allocate network device structure " 2000 "structure for user '%s'\n",
2024 "for user '%s'\n", netiucv_printname(username)); 2001 netiucv_printname(username));
2025 IUCV_DBF_TEXT(setup, 2, "NULL from netiucv_init_netdevice\n"); 2002 IUCV_DBF_TEXT(setup, 2, "NULL from netiucv_init_netdevice\n");
2026 return -ENODEV; 2003 return -ENODEV;
2027 } 2004 }
2028 2005
2029 if ((ret = netiucv_register_device(dev))) { 2006 rc = netiucv_register_device(dev);
2007 if (rc) {
2030 IUCV_DBF_TEXT_(setup, 2, 2008 IUCV_DBF_TEXT_(setup, 2,
2031 "ret %d from netiucv_register_device\n", ret); 2009 "ret %d from netiucv_register_device\n", rc);
2032 goto out_free_ndev; 2010 goto out_free_ndev;
2033 } 2011 }
2034 2012
2035 /* sysfs magic */ 2013 /* sysfs magic */
2036 SET_NETDEV_DEV(dev, 2014 priv = netdev_priv(dev);
2037 (struct device*)((struct netiucv_priv*)dev->priv)->dev); 2015 SET_NETDEV_DEV(dev, priv->dev);
2038 2016
2039 if ((ret = register_netdev(dev))) { 2017 rc = register_netdev(dev);
2040 netiucv_unregister_device((struct device*) 2018 if (rc)
2041 ((struct netiucv_priv*)dev->priv)->dev); 2019 goto out_unreg;
2042 goto out_free_ndev;
2043 }
2044 2020
2045 PRINT_INFO("%s: '%s'\n", dev->name, netiucv_printname(username)); 2021 PRINT_INFO("%s: '%s'\n", dev->name, netiucv_printname(username));
2046 2022
2047 return count; 2023 return count;
2048 2024
2025out_unreg:
2026 netiucv_unregister_device(priv->dev);
2049out_free_ndev: 2027out_free_ndev:
2050 PRINT_WARN("netiucv: Could not register '%s'\n", dev->name); 2028 PRINT_WARN("netiucv: Could not register '%s'\n", dev->name);
2051 IUCV_DBF_TEXT(setup, 2, "conn_write: could not register\n"); 2029 IUCV_DBF_TEXT(setup, 2, "conn_write: could not register\n");
2052 netiucv_free_netdevice(dev); 2030 netiucv_free_netdevice(dev);
2053 return ret; 2031 return rc;
2054} 2032}
2055 2033
2056static DRIVER_ATTR(connection, 0200, NULL, conn_write); 2034static DRIVER_ATTR(connection, 0200, NULL, conn_write);
2057 2035
2058static ssize_t 2036static ssize_t remove_write (struct device_driver *drv,
2059remove_write (struct device_driver *drv, const char *buf, size_t count) 2037 const char *buf, size_t count)
2060{ 2038{
2061 struct iucv_connection **clist = &iucv_conns.iucv_connections; 2039 struct iucv_connection *cp;
2062 unsigned long flags;
2063 struct net_device *ndev; 2040 struct net_device *ndev;
2064 struct netiucv_priv *priv; 2041 struct netiucv_priv *priv;
2065 struct device *dev; 2042 struct device *dev;
2066 char name[IFNAMSIZ]; 2043 char name[IFNAMSIZ];
2067 char *p; 2044 const char *p;
2068 int i; 2045 int i;
2069 2046
2070 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 2047 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
@@ -2072,33 +2049,27 @@ remove_write (struct device_driver *drv, const char *buf, size_t count)
2072 if (count >= IFNAMSIZ) 2049 if (count >= IFNAMSIZ)
2073 count = IFNAMSIZ - 1;; 2050 count = IFNAMSIZ - 1;;
2074 2051
2075 for (i=0, p=(char *)buf; i<count && *p; i++, p++) { 2052 for (i = 0, p = buf; i < count && *p; i++, p++) {
2076 if ((*p == '\n') || (*p == ' ')) { 2053 if (*p == '\n' || *p == ' ')
2077 /* trailing lf, grr */ 2054 /* trailing lf, grr */
2078 break; 2055 break;
2079 } else { 2056 name[i] = *p;
2080 name[i]=*p;
2081 }
2082 } 2057 }
2083 name[i] = '\0'; 2058 name[i] = '\0';
2084 2059
2085 read_lock_irqsave(&iucv_conns.iucv_rwlock, flags); 2060 read_lock_bh(&iucv_connection_rwlock);
2086 while (*clist) { 2061 list_for_each_entry(cp, &iucv_connection_list, list) {
2087 ndev = (*clist)->netdev; 2062 ndev = cp->netdev;
2088 priv = (struct netiucv_priv*)ndev->priv; 2063 priv = netdev_priv(ndev);
2089 dev = priv->dev; 2064 dev = priv->dev;
2090 2065 if (strncmp(name, ndev->name, count))
2091 if (strncmp(name, ndev->name, count)) { 2066 continue;
2092 clist = &((*clist)->next); 2067 read_unlock_bh(&iucv_connection_rwlock);
2093 continue;
2094 }
2095 read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags);
2096 if (ndev->flags & (IFF_UP | IFF_RUNNING)) { 2068 if (ndev->flags & (IFF_UP | IFF_RUNNING)) {
2097 PRINT_WARN( 2069 PRINT_WARN("netiucv: net device %s active with peer "
2098 "netiucv: net device %s active with peer %s\n", 2070 "%s\n", ndev->name, priv->conn->userid);
2099 ndev->name, priv->conn->userid);
2100 PRINT_WARN("netiucv: %s cannot be removed\n", 2071 PRINT_WARN("netiucv: %s cannot be removed\n",
2101 ndev->name); 2072 ndev->name);
2102 IUCV_DBF_TEXT(data, 2, "remove_write: still active\n"); 2073 IUCV_DBF_TEXT(data, 2, "remove_write: still active\n");
2103 return -EBUSY; 2074 return -EBUSY;
2104 } 2075 }
@@ -2106,7 +2077,7 @@ remove_write (struct device_driver *drv, const char *buf, size_t count)
2106 netiucv_unregister_device(dev); 2077 netiucv_unregister_device(dev);
2107 return count; 2078 return count;
2108 } 2079 }
2109 read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); 2080 read_unlock_bh(&iucv_connection_rwlock);
2110 PRINT_WARN("netiucv: net device %s unknown\n", name); 2081 PRINT_WARN("netiucv: net device %s unknown\n", name);
2111 IUCV_DBF_TEXT(data, 2, "remove_write: unknown device\n"); 2082 IUCV_DBF_TEXT(data, 2, "remove_write: unknown device\n");
2112 return -EINVAL; 2083 return -EINVAL;
@@ -2114,67 +2085,86 @@ remove_write (struct device_driver *drv, const char *buf, size_t count)
2114 2085
2115static DRIVER_ATTR(remove, 0200, NULL, remove_write); 2086static DRIVER_ATTR(remove, 0200, NULL, remove_write);
2116 2087
2117static void 2088static struct attribute * netiucv_drv_attrs[] = {
2118netiucv_banner(void) 2089 &driver_attr_connection.attr,
2090 &driver_attr_remove.attr,
2091 NULL,
2092};
2093
2094static struct attribute_group netiucv_drv_attr_group = {
2095 .attrs = netiucv_drv_attrs,
2096};
2097
2098static void netiucv_banner(void)
2119{ 2099{
2120 PRINT_INFO("NETIUCV driver initialized\n"); 2100 PRINT_INFO("NETIUCV driver initialized\n");
2121} 2101}
2122 2102
2123static void __exit 2103static void __exit netiucv_exit(void)
2124netiucv_exit(void)
2125{ 2104{
2105 struct iucv_connection *cp;
2106 struct net_device *ndev;
2107 struct netiucv_priv *priv;
2108 struct device *dev;
2109
2126 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 2110 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
2127 while (iucv_conns.iucv_connections) { 2111 while (!list_empty(&iucv_connection_list)) {
2128 struct net_device *ndev = iucv_conns.iucv_connections->netdev; 2112 cp = list_entry(iucv_connection_list.next,
2129 struct netiucv_priv *priv = (struct netiucv_priv*)ndev->priv; 2113 struct iucv_connection, list);
2130 struct device *dev = priv->dev; 2114 list_del(&cp->list);
2115 ndev = cp->netdev;
2116 priv = netdev_priv(ndev);
2117 dev = priv->dev;
2131 2118
2132 unregister_netdev(ndev); 2119 unregister_netdev(ndev);
2133 netiucv_unregister_device(dev); 2120 netiucv_unregister_device(dev);
2134 } 2121 }
2135 2122
2136 driver_remove_file(&netiucv_driver, &driver_attr_connection); 2123 sysfs_remove_group(&netiucv_driver.kobj, &netiucv_drv_attr_group);
2137 driver_remove_file(&netiucv_driver, &driver_attr_remove);
2138 driver_unregister(&netiucv_driver); 2124 driver_unregister(&netiucv_driver);
2125 iucv_unregister(&netiucv_handler, 1);
2139 iucv_unregister_dbf_views(); 2126 iucv_unregister_dbf_views();
2140 2127
2141 PRINT_INFO("NETIUCV driver unloaded\n"); 2128 PRINT_INFO("NETIUCV driver unloaded\n");
2142 return; 2129 return;
2143} 2130}
2144 2131
2145static int __init 2132static int __init netiucv_init(void)
2146netiucv_init(void)
2147{ 2133{
2148 int ret; 2134 int rc;
2149 2135
2150 ret = iucv_register_dbf_views(); 2136 rc = iucv_register_dbf_views();
2151 if (ret) { 2137 if (rc)
2152 PRINT_WARN("netiucv_init failed, " 2138 goto out;
2153 "iucv_register_dbf_views rc = %d\n", ret); 2139 rc = iucv_register(&netiucv_handler, 1);
2154 return ret; 2140 if (rc)
2155 } 2141 goto out_dbf;
2156 IUCV_DBF_TEXT(trace, 3, __FUNCTION__); 2142 IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
2157 ret = driver_register(&netiucv_driver); 2143 rc = driver_register(&netiucv_driver);
2158 if (ret) { 2144 if (rc) {
2159 PRINT_ERR("NETIUCV: failed to register driver.\n"); 2145 PRINT_ERR("NETIUCV: failed to register driver.\n");
2160 IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_register\n", ret); 2146 IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_register\n", rc);
2161 iucv_unregister_dbf_views(); 2147 goto out_iucv;
2162 return ret;
2163 } 2148 }
2164 2149
2165 /* Add entry for specifying connections. */ 2150 rc = sysfs_create_group(&netiucv_driver.kobj, &netiucv_drv_attr_group);
2166 ret = driver_create_file(&netiucv_driver, &driver_attr_connection); 2151 if (rc) {
2167 if (!ret) { 2152 PRINT_ERR("NETIUCV: failed to add driver attributes.\n");
2168 ret = driver_create_file(&netiucv_driver, &driver_attr_remove); 2153 IUCV_DBF_TEXT_(setup, 2,
2169 netiucv_banner(); 2154 "ret %d - netiucv_drv_attr_group\n", rc);
2170 rwlock_init(&iucv_conns.iucv_rwlock); 2155 goto out_driver;
2171 } else {
2172 PRINT_ERR("NETIUCV: failed to add driver attribute.\n");
2173 IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_create_file\n", ret);
2174 driver_unregister(&netiucv_driver);
2175 iucv_unregister_dbf_views();
2176 } 2156 }
2177 return ret; 2157 netiucv_banner();
2158 return rc;
2159
2160out_driver:
2161 driver_unregister(&netiucv_driver);
2162out_iucv:
2163 iucv_unregister(&netiucv_handler, 1);
2164out_dbf:
2165 iucv_unregister_dbf_views();
2166out:
2167 return rc;
2178} 2168}
2179 2169
2180module_init(netiucv_init); 2170module_init(netiucv_init);