From: Martin Schwidefsky Network driver changes: - ctc: move kfree of driver structure after the last use of it. - netiucv: stay in state startwait if peer is down. - lcs: initialize ipm_list and unregister netdev only if it is present. --- 25-akpm/drivers/s390/net/ctctty.c | 4 - 25-akpm/drivers/s390/net/lcs.c | 10 ++-- 25-akpm/drivers/s390/net/netiucv.c | 88 +++++++++++-------------------------- 3 files changed, 37 insertions(+), 65 deletions(-) diff -puN drivers/s390/net/ctctty.c~s390-5-12-network-driver-fixes drivers/s390/net/ctctty.c --- 25/drivers/s390/net/ctctty.c~s390-5-12-network-driver-fixes 2004-04-08 13:55:07.198929768 -0700 +++ 25-akpm/drivers/s390/net/ctctty.c 2004-04-08 13:55:07.205928704 -0700 @@ -1,5 +1,5 @@ /* - * $Id: ctctty.c,v 1.16 2004/02/05 12:39:55 felfert Exp $ + * $Id: ctctty.c,v 1.17 2004/03/31 17:06:34 ptiedem Exp $ * * CTC / ESCON network driver, tty interface. * @@ -1232,7 +1232,7 @@ ctc_tty_cleanup(void) { ctc_tty_shuttingdown = 1; spin_unlock_irqrestore(&ctc_tty_lock, saveflags); tty_unregister_driver(driver->ctc_tty_device); - kfree(driver); put_tty_driver(driver->ctc_tty_device); + kfree(driver); driver = NULL; } diff -puN drivers/s390/net/lcs.c~s390-5-12-network-driver-fixes drivers/s390/net/lcs.c --- 25/drivers/s390/net/lcs.c~s390-5-12-network-driver-fixes 2004-04-08 13:55:07.200929464 -0700 +++ 25-akpm/drivers/s390/net/lcs.c 2004-04-08 13:55:07.207928400 -0700 @@ -11,7 +11,7 @@ * Frank Pavlic (pavlic@de.ibm.com) and * Martin Schwidefsky * - * $Revision: 1.72 $ $Date: 2004/03/22 09:34:27 $ + * $Revision: 1.74 $ $Date: 2004/04/05 00:01:04 $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -58,7 +58,7 @@ /** * initialization string for output */ -#define VERSION_LCS_C "$Revision: 1.72 $" +#define VERSION_LCS_C "$Revision: 1.74 $" static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")"; static char debug_buffer[255]; @@ -206,6 +206,9 @@ lcs_alloc_card(void) return NULL; } +#ifdef CONFIG_IP_MULTICAST + INIT_LIST_HEAD(&card->ipm_list); +#endif LCS_DBF_HEX(2, setup, &card, sizeof(void*)); return card; } @@ -1967,7 +1970,8 @@ lcs_remove_device(struct ccwgroup_device if (ccwgdev->state == CCWGROUP_ONLINE) { lcs_shutdown_device(ccwgdev); } - unregister_netdev(card->dev); + if (card->dev) + unregister_netdev(card->dev); sysfs_remove_group(&ccwgdev->dev.kobj, &lcs_attr_group); lcs_cleanup_card(card); lcs_free_card(card); diff -puN drivers/s390/net/netiucv.c~s390-5-12-network-driver-fixes drivers/s390/net/netiucv.c --- 25/drivers/s390/net/netiucv.c~s390-5-12-network-driver-fixes 2004-04-08 13:55:07.201929312 -0700 +++ 25-akpm/drivers/s390/net/netiucv.c 2004-04-08 13:55:07.209928096 -0700 @@ -1,5 +1,5 @@ /* - * $Id: netiucv.c,v 1.47 2004/03/22 07:41:42 braunu Exp $ + * $Id: netiucv.c,v 1.48 2004/04/01 13:42:09 braunu Exp $ * * IUCV network driver * @@ -30,7 +30,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * RELEASE-TAG: IUCV network driver $Revision: 1.47 $ + * RELEASE-TAG: IUCV network driver $Revision: 1.48 $ * */ @@ -100,7 +100,6 @@ struct iucv_connection { int max_buffsize; int flags; fsm_timer timer; - int retry; fsm_instance *fsm; struct net_device *netdev; struct connection_profile prof; @@ -169,8 +168,6 @@ static __inline__ int netiucv_test_and_s return test_and_set_bit(0, &((struct netiucv_priv *)dev->priv)->tbusy); } -#define SET_DEVICE_START(device, value) - static __u8 iucv_host[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static __u8 iucvMagic[16] = { 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, @@ -217,7 +214,6 @@ enum dev_states { DEV_STATE_STARTWAIT, DEV_STATE_STOPWAIT, DEV_STATE_RUNNING, - DEV_STATE_STARTRETRY, /** * MUST be always the last element!! */ @@ -229,7 +225,6 @@ static const char *dev_state_names[] = { "StartWait", "StopWait", "Running", - "StartRetry", }; /** @@ -599,7 +594,6 @@ conn_action_txdone(fsm_instance *fi, int pr_debug("%s() called\n", __FUNCTION__); - fsm_deltimer(&conn->timer); if (conn && conn->netdev && conn->netdev->priv) privptr = (struct netiucv_priv *)conn->netdev->priv; conn->prof.tx_pending--; @@ -639,8 +633,6 @@ conn_action_txdone(fsm_instance *fi, int memcpy(skb_put(conn->tx_buff, NETIUCV_HDRLEN), &header, NETIUCV_HDRLEN); - fsm_addtimer(&conn->timer, NETIUCV_TIMEOUT_5SEC, - CONN_EVENT_TIMER, conn); conn->prof.send_stamp = xtime; rc = iucv_send(conn->pathid, NULL, 0, 0, 0, 0, conn->tx_buff->data, conn->tx_buff->len); @@ -650,7 +642,6 @@ conn_action_txdone(fsm_instance *fi, int if (conn->prof.tx_pending > conn->prof.tx_max_pending) conn->prof.tx_max_pending = conn->prof.tx_pending; if (rc != 0) { - fsm_deltimer(&conn->timer); conn->prof.tx_pending--; fsm_newstate(fi, CONN_STATE_IDLE); if (privptr) @@ -721,6 +712,7 @@ conn_action_connack(fsm_instance *fi, in pr_debug("%s() called\n", __FUNCTION__); + fsm_deltimer(&conn->timer); fsm_newstate(fi, CONN_STATE_IDLE); conn->pathid = eib->ippathid; netdev->tx_queue_len = eib->ipmsglim; @@ -728,35 +720,35 @@ conn_action_connack(fsm_instance *fi, in } static void +conn_action_conntimsev(fsm_instance *fi, int event, void *arg) +{ + struct iucv_connection *conn = (struct iucv_connection *)arg; + __u8 udata[16]; + + pr_debug("%s() called\n", __FUNCTION__); + + fsm_deltimer(&conn->timer); + iucv_sever(conn->pathid, udata); + fsm_newstate(fi, CONN_STATE_STARTWAIT); +} + +static void conn_action_connsever(fsm_instance *fi, int event, void *arg) { struct iucv_event *ev = (struct iucv_event *)arg; struct iucv_connection *conn = ev->conn; - // iucv_ConnectionSevered *eib = (iucv_ConnectionSevered *)ev->data; struct net_device *netdev = conn->netdev; struct netiucv_priv *privptr = (struct netiucv_priv *)netdev->priv; - int state = fsm_getstate(fi); + __u8 udata[16]; pr_debug("%s() called\n", __FUNCTION__); - switch (state) { - case CONN_STATE_SETUPWAIT: - printk(KERN_INFO "%s: Remote dropped connection\n", - netdev->name); - fsm_newstate(fi, CONN_STATE_STOPPED); - fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev); - break; - case CONN_STATE_IDLE: - case CONN_STATE_TX: - printk(KERN_INFO "%s: Remote dropped connection\n", - netdev->name); - if (conn->handle) - iucv_unregister_program(conn->handle); - conn->handle = 0; - fsm_newstate(fi, CONN_STATE_STOPPED); - fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev); - break; - } + fsm_deltimer(&conn->timer); + iucv_sever(conn->pathid, udata); + printk(KERN_INFO "%s: Remote dropped connection\n", + netdev->name); + fsm_newstate(fi, CONN_STATE_STARTWAIT); + fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev); } static void @@ -798,6 +790,8 @@ conn_action_start(fsm_instance *fi, int switch (rc) { case 0: conn->netdev->tx_queue_len = msglimit; + fsm_addtimer(&conn->timer, NETIUCV_TIMEOUT_5SEC, + CONN_EVENT_TIMER, conn); return; case 11: printk(KERN_NOTICE @@ -864,6 +858,7 @@ conn_action_stop(fsm_instance *fi, int e pr_debug("%s() called\n", __FUNCTION__); + fsm_deltimer(&conn->timer); fsm_newstate(fi, CONN_STATE_STOPPED); netiucv_purge_skb_queue(&conn->collect_queue); if (conn->handle) @@ -888,7 +883,6 @@ conn_action_inval(fsm_instance *fi, int static const fsm_node conn_fsm[] = { { CONN_STATE_INVALID, CONN_EVENT_START, conn_action_inval }, { CONN_STATE_STOPPED, CONN_EVENT_START, conn_action_start }, - { CONN_STATE_STARTWAIT, CONN_EVENT_START, conn_action_start }, { CONN_STATE_STOPPED, CONN_EVENT_STOP, conn_action_stop }, { CONN_STATE_STARTWAIT, CONN_EVENT_STOP, conn_action_stop }, @@ -905,6 +899,7 @@ static const fsm_node conn_fsm[] = { { CONN_STATE_TX, CONN_EVENT_CONN_REQ, conn_action_connreject }, { CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_ACK, conn_action_connack }, + { CONN_STATE_SETUPWAIT, CONN_EVENT_TIMER, conn_action_conntimsev }, { CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_REJ, conn_action_connsever }, { CONN_STATE_IDLE, CONN_EVENT_CONN_REJ, conn_action_connsever }, @@ -940,7 +935,6 @@ dev_action_start(fsm_instance *fi, int e pr_debug("%s() called\n", __FUNCTION__); - fsm_deltimer(&privptr->timer); ev.conn = privptr->conn; fsm_newstate(fi, DEV_STATE_STARTWAIT); fsm_event(privptr->conn->fsm, CONN_EVENT_START, &ev); @@ -964,7 +958,6 @@ dev_action_stop(fsm_instance *fi, int ev ev.conn = privptr->conn; - fsm_deltimer(&privptr->timer); fsm_newstate(fi, DEV_STATE_STOPWAIT); fsm_event(privptr->conn->fsm, CONN_EVENT_STOP, &ev); } @@ -981,13 +974,10 @@ static void dev_action_connup(fsm_instance *fi, int event, void *arg) { struct net_device *dev = (struct net_device *)arg; - struct netiucv_priv *privptr = dev->priv; pr_debug("%s() called\n", __FUNCTION__); switch (fsm_getstate(fi)) { - case DEV_STATE_STARTRETRY: - fsm_deltimer(&privptr->timer); case DEV_STATE_STARTWAIT: fsm_newstate(fi, DEV_STATE_RUNNING); printk(KERN_INFO @@ -1013,22 +1003,11 @@ dev_action_connup(fsm_instance *fi, int static void dev_action_conndown(fsm_instance *fi, int event, void *arg) { - struct net_device *dev = (struct net_device *)arg; - struct netiucv_priv *privptr = dev->priv; - struct iucv_event ev; - pr_debug("%s() called\n", __FUNCTION__); switch (fsm_getstate(fi)) { case DEV_STATE_RUNNING: fsm_newstate(fi, DEV_STATE_STARTWAIT); - ev.conn = privptr->conn; - fsm_event(privptr->conn->fsm, CONN_EVENT_START, &ev); - break; - case DEV_STATE_STARTWAIT: - fsm_addtimer(&privptr->timer, NETIUCV_TIMEOUT_5SEC, - DEV_EVENT_TIMER, dev); - fsm_newstate(fi, DEV_STATE_STARTRETRY); break; case DEV_STATE_STOPWAIT: fsm_newstate(fi, DEV_STATE_STOPPED); @@ -1044,11 +1023,6 @@ static const fsm_node dev_fsm[] = { { DEV_STATE_STARTWAIT, DEV_EVENT_STOP, dev_action_stop }, { DEV_STATE_STARTWAIT, DEV_EVENT_CONUP, dev_action_connup }, - { DEV_STATE_STARTWAIT, DEV_EVENT_CONDOWN, dev_action_conndown }, - - { DEV_STATE_STARTRETRY, DEV_EVENT_TIMER, dev_action_start }, - { DEV_STATE_STARTRETRY, DEV_EVENT_CONUP, dev_action_connup }, - { DEV_STATE_STARTRETRY, DEV_EVENT_STOP, dev_action_stop }, { DEV_STATE_RUNNING, DEV_EVENT_STOP, dev_action_stop }, { DEV_STATE_RUNNING, DEV_EVENT_CONDOWN, dev_action_conndown }, @@ -1119,10 +1093,7 @@ netiucv_transmit_skb(struct iucv_connect header.next = 0; memcpy(skb_put(nskb, NETIUCV_HDRLEN), &header, NETIUCV_HDRLEN); - conn->retry = 0; fsm_newstate(conn->fsm, CONN_STATE_TX); - fsm_addtimer(&conn->timer, NETIUCV_TIMEOUT_5SEC, - CONN_EVENT_TIMER, conn); conn->prof.send_stamp = xtime; rc = iucv_send(conn->pathid, NULL, 0, 0, 1 /* single_flag */, @@ -1135,7 +1106,6 @@ netiucv_transmit_skb(struct iucv_connect conn->prof.tx_max_pending = conn->prof.tx_pending; if (rc != 0) { struct netiucv_priv *privptr; - fsm_deltimer(&conn->timer); fsm_newstate(conn->fsm, CONN_STATE_IDLE); conn->prof.tx_pending--; privptr = (struct netiucv_priv *)conn->netdev->priv; @@ -1178,7 +1148,6 @@ netiucv_transmit_skb(struct iucv_connect */ static int netiucv_open(struct net_device *dev) { - SET_DEVICE_START(dev, 1); fsm_event(((struct netiucv_priv *)dev->priv)->fsm, DEV_EVENT_START, dev); return 0; } @@ -1193,7 +1162,6 @@ netiucv_open(struct net_device *dev) { */ static int netiucv_close(struct net_device *dev) { - SET_DEVICE_START(dev, 0); fsm_event(((struct netiucv_priv *)dev->priv)->fsm, DEV_EVENT_STOP, dev); return 0; } @@ -1912,7 +1880,7 @@ static struct device_driver netiucv_driv static void netiucv_banner(void) { - char vbuf[] = "$Revision: 1.47 $"; + char vbuf[] = "$Revision: 1.48 $"; char *version = vbuf; if ((version = strchr(version, ':'))) { _