]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] s390: iucv driver.
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Fri, 26 Sep 2003 01:02:56 +0000 (18:02 -0700)
committerLinus Torvalds <torvalds@home.osdl.org>
Fri, 26 Sep 2003 01:02:56 +0000 (18:02 -0700)
 - 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
drivers/s390/net/iucv.h
drivers/s390/net/netiucv.c

index 2b52bb46dddbb7b1a0779af2ae5bde0554f06e9b..9326ee644fa2ba4ff422ba3fa1c4abbd3daf04b5 100644 (file)
@@ -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
  *
  * 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 $
  *
  */
 \f
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/config.h>
 
 #include <linux/spinlock.h>
@@ -43,6 +44,7 @@
 #include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/errno.h>
+#include <linux/device.h>
 #include <asm/atomic.h>
 #include "iucv.h"
 #include <asm/io.h>
 #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
index a882449aa8e30d8dd8ae55d157dfc3de66a42539..7bd3617fa03b143eb5935249ab1d16c5a11fde27 100644 (file)
@@ -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                                    
index 4546f67b01a8b1faec333aa990b26c6348b36233..61198556d46504d9b87e12dc295fc9168b30451e 100644 (file)
@@ -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
  *
  * 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 $
  *
  */
 \f
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -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;
 }