From 63c85307be57491455881761490b1ec814464575 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 25 Sep 2003 18:02:56 -0700 Subject: [PATCH] [PATCH] s390: iucv driver. - Move iucv bus and root device initialization from netiucv to iucv. - Fix race condition in iucv_connect. - Add 'user' attribute to netiucv driver. --- drivers/s390/net/iucv.c | 72 ++++++++++++++++++++++++++++++-------- drivers/s390/net/iucv.h | 3 ++ drivers/s390/net/netiucv.c | 55 ++++++++--------------------- 3 files changed, 74 insertions(+), 56 deletions(-) diff --git a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c index 2b52bb46dddb..9326ee644fa2 100644 --- a/drivers/s390/net/iucv.c +++ b/drivers/s390/net/iucv.c @@ -1,5 +1,5 @@ /* - * $Id: iucv.c,v 1.11 2003/04/15 16:45:37 aberg Exp $ + * $Id: iucv.c,v 1.14 2003/09/23 16:48:17 mschwide Exp $ * * IUCV network driver * @@ -29,11 +29,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.11 $ + * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.14 $ * */ #include +#include #include #include @@ -43,6 +44,7 @@ #include #include #include +#include #include #include "iucv.h" #include @@ -71,6 +73,21 @@ #define IPANSLST 0x08 #define IPBUFLST 0x40 +static int +iucv_bus_match (struct device *dev, struct device_driver *drv) +{ + return 0; +} + +struct bus_type iucv_bus = { + .name = "iucv", + .match = iucv_bus_match, +}; + +struct device iucv_root = { + .bus_id = "iucv", +}; + /* General IUCV interrupt structure */ typedef struct { __u16 ippathid; @@ -283,7 +300,7 @@ MODULE_LICENSE("GPL"); #ifdef DEBUG static int debuglevel = 0; -MODULE_PARM(debuglevel, "i"); +module_param(debuglevel, int, 0); MODULE_PARM_DESC(debuglevel, "Specifies the debug level (0=off ... 3=all)"); @@ -332,7 +349,7 @@ do { \ static void iucv_banner(void) { - char vbuf[] = "$Revision: 1.11 $"; + char vbuf[] = "$Revision: 1.14 $"; char *version = vbuf; if ((version = strchr(version, ':'))) { @@ -353,9 +370,24 @@ iucv_banner(void) static int iucv_init(void) { + int ret; + if (iucv_external_int_buffer) return 0; + ret = bus_register(&iucv_bus); + if (ret != 0) { + printk(KERN_ERR "IUCV: failed to register bus.\n"); + return ret; + } + + ret = device_register(&iucv_root); + if (ret != 0) { + printk(KERN_ERR "IUCV: failed to register iucv root.\n"); + bus_unregister(&iucv_bus); + return ret; + } + /* Note: GFP_DMA used used to get memory below 2G */ iucv_external_int_buffer = kmalloc(sizeof(iucv_GeneralInterrupt), GFP_KERNEL|GFP_DMA); @@ -401,6 +433,8 @@ iucv_exit(void) kfree(iucv_external_int_buffer); if (iucv_param_pool) kfree(iucv_param_pool); + device_unregister(&iucv_root); + bus_unregister(&iucv_bus); printk(KERN_INFO "IUCV lowlevel driver unloaded\n"); } @@ -528,9 +562,8 @@ b2f0(__u32 code, void *parm) * - ENOMEM - storage allocation for a new pathid table failed */ static int -iucv_add_pathid(__u16 pathid, handler *handler) +__iucv_add_pathid(__u16 pathid, handler *handler) { - ulong flags; iucv_debug(1, "entering"); @@ -539,21 +572,30 @@ iucv_add_pathid(__u16 pathid, handler *handler) if (pathid > (max_connections - 1)) return -EINVAL; - spin_lock_irqsave (&iucv_lock, flags); if (iucv_pathid_table[pathid]) { - spin_unlock_irqrestore (&iucv_lock, flags); iucv_debug(1, "pathid entry is %p", iucv_pathid_table[pathid]); printk(KERN_WARNING "%s: Pathid being used, error.\n", __FUNCTION__); return -EINVAL; } iucv_pathid_table[pathid] = handler; - spin_unlock_irqrestore (&iucv_lock, flags); iucv_debug(1, "exiting"); return 0; } /* end of add_pathid function */ +static int +iucv_add_pathid(__u16 pathid, handler *handler) +{ + ulong flags; + int rc; + + spin_lock_irqsave (&iucv_lock, flags); + rc = __iucv_add_pathid(pathid, handler); + spin_unlock_irqrestore (&iucv_lock, flags); + return rc; +} + static void iucv_remove_pathid(__u16 pathid) { @@ -1090,15 +1132,18 @@ iucv_connect (__u16 *pathid, __u16 msglim_reqstd, EBC_TOUPPER(parm->iptarget, sizeof(parm->iptarget)); } + spin_lock_irqsave (&iucv_lock, flags); parm->ipflags1 = (__u8)flags1; b2f0_result = b2f0(CONNECT, parm); + if (b2f0_result == 0) + add_pathid_result = __iucv_add_pathid(parm->ippathid, h); + spin_unlock_irqrestore (&iucv_lock, flags); if (b2f0_result) { release_param(parm); return b2f0_result; } - add_pathid_result = iucv_add_pathid(parm->ippathid, h); *pathid = parm->ippathid; if (msglim) @@ -2171,8 +2216,6 @@ iucv_irq_handler(struct pt_regs *regs, __u16 code) { iucv_irqdata *irqdata; - irq_enter(); - irqdata = kmalloc(sizeof(iucv_irqdata), GFP_ATOMIC); if (!irqdata) { printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__); @@ -2188,9 +2231,6 @@ iucv_irq_handler(struct pt_regs *regs, __u16 code) spin_unlock(&iucv_irq_queue_lock); tasklet_schedule(&iucv_tasklet); - - irq_exit(); - return; } /** @@ -2407,6 +2447,8 @@ module_exit(iucv_exit); * using them or should some of them be made * static / removed? pls review. Arnd */ +EXPORT_SYMBOL (iucv_bus); +EXPORT_SYMBOL (iucv_root); EXPORT_SYMBOL (iucv_accept); EXPORT_SYMBOL (iucv_connect); #if 0 diff --git a/drivers/s390/net/iucv.h b/drivers/s390/net/iucv.h index a882449aa8e3..7bd3617fa03b 100644 --- a/drivers/s390/net/iucv.h +++ b/drivers/s390/net/iucv.h @@ -202,6 +202,9 @@ typedef struct { u32 length; } iucv_array_t __attribute__ ((aligned (8))); +extern struct bus_type iucv_bus; +extern struct device iucv_root; + /* -prototypes- */ /* * Name: iucv_register_program diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 4546f67b01a8..61198556d465 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -1,5 +1,5 @@ /* - * $Id: netiucv.c,v 1.20 2003/05/27 11:34:24 mschwide Exp $ + * $Id: netiucv.c,v 1.26 2003/09/23 16:48:17 mschwide Exp $ * * IUCV network driver * @@ -30,11 +30,10 @@ * 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.20 $ + * RELEASE-TAG: IUCV network driver $Revision: 1.26 $ * */ -#include #include #include #include @@ -115,23 +114,6 @@ static struct iucv_connection *connections; /* Keep track of interfaces. */ static int ifno; -static int -iucv_bus_match (struct device *dev, struct device_driver *drv) -{ - return 0; -} - -/* Hm - move to iucv.c and export? - CH */ -static struct bus_type iucv_bus = { - .name = "iucv", - .match = iucv_bus_match, -}; - -static struct device iucv_root = { - .name = "IUCV", - .bus_id = "iucv", -}; - /** * Representation of event-data for the * connection state machine. @@ -1254,6 +1236,16 @@ netiucv_change_mtu (struct net_device * dev, int new_mtu) *****************************************************************************/ #define CTRL_BUFSIZE 40 +static ssize_t +user_show (struct device *dev, char *buf) +{ + struct netiucv_priv *priv = dev->driver_data; + + return sprintf(buf, "%s\n", netiucv_printname(priv->conn->userid)); +} + +static DEVICE_ATTR(user, 0444, user_show, NULL); + static ssize_t buffer_show (struct device *dev, char *buf) { @@ -1437,6 +1429,7 @@ static DEVICE_ATTR(max_tx_io_time, 0644, txtime_show, txtime_write); static struct attribute *netiucv_attrs[] = { &dev_attr_buffer.attr, + &dev_attr_user.attr, NULL, }; @@ -1490,7 +1483,6 @@ netiucv_register_device(struct net_device *ndev, int ifno) int ret; char *str = "netiucv"; - snprintf(dev->name, DEVICE_NAME_SIZE, "%s", priv->conn->userid); snprintf(dev->bus_id, BUS_ID_SIZE, "%s%x", str, ifno); dev->bus = &iucv_bus; dev->parent = &iucv_root; @@ -1739,7 +1731,7 @@ static struct device_driver netiucv_driver = { static void netiucv_banner(void) { - char vbuf[] = "$Revision: 1.20 $"; + char vbuf[] = "$Revision: 1.26 $"; char *version = vbuf; if ((version = strchr(version, ':'))) { @@ -1763,7 +1755,6 @@ netiucv_exit(void) driver_remove_file(&netiucv_driver, &driver_attr_connection); driver_unregister(&netiucv_driver); - bus_unregister(&iucv_bus); printk(KERN_INFO "NETIUCV driver unloaded\n"); return; @@ -1774,25 +1765,9 @@ netiucv_init(void) { int ret; - /* Move the bus stuff to iucv.c? - CH */ - ret = bus_register(&iucv_bus); - if (ret != 0) { - printk(KERN_ERR "NETIUCV: failed to register bus.\n"); - return ret; - } - ret = driver_register(&netiucv_driver); if (ret != 0) { printk(KERN_ERR "NETIUCV: failed to register driver.\n"); - bus_unregister(&iucv_bus); - return ret; - } - - ret = device_register(&iucv_root); - if (ret != 0) { - printk(KERN_ERR "NETIUCV: failed to register iucv root.\n"); - driver_unregister(&netiucv_driver); - bus_unregister(&iucv_bus); return ret; } @@ -1803,9 +1778,7 @@ netiucv_init(void) netiucv_banner(); else { printk(KERN_ERR "NETIUCV: failed to add driver attribute.\n"); - device_unregister(&iucv_root); driver_unregister(&netiucv_driver); - bus_unregister(&iucv_bus); } return ret; } -- 2.39.5