mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Martin Schwidefsky <schwidefsky@de.ibm.com>
To: torvalds@osdl.org, linux-kernel@vger.kernel.org
Subject: [PATCH] s390 (7/8): static root object fix.
Date: Tue, 21 Oct 2003 17:10:08 +0200	[thread overview]
Message-ID: <20031021151008.GE1690@mschwid3.boeblingen.de.ibm.com> (raw)

Add s390_root_dev_{register,unregister} to fix reference counting
for the root objects of group device drivers.

diffstat:
 drivers/s390/cio/css.c     |   44 ++++++++++++++++++++++++++++++++++++++++++--
 drivers/s390/net/cu3088.c  |   25 +++++++++----------------
 drivers/s390/net/iucv.c    |   28 ++++++++++++----------------
 drivers/s390/net/iucv.h    |    2 +-
 drivers/s390/net/netiucv.c |    8 ++++----
 drivers/s390/net/qeth.c    |   25 +++++++++----------------
 include/asm-s390/ccwdev.h  |    3 +++
 7 files changed, 80 insertions(+), 55 deletions(-)

diff -urN linux-2.6/drivers/s390/cio/css.c linux-2.6-s390/drivers/s390/cio/css.c
--- linux-2.6/drivers/s390/cio/css.c	Fri Oct 17 23:42:55 2003
+++ linux-2.6-s390/drivers/s390/cio/css.c	Tue Oct 21 16:37:38 2003
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/css.c
  *  driver for channel subsystem
- *   $Revision: 1.49 $
+ *   $Revision: 1.51 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *			 IBM Corporation
@@ -236,6 +236,46 @@
 
 subsys_initcall(init_channel_subsystem);
 
+/*
+ * Register root devices for some drivers. The release function must not be
+ * in the device drivers, so we do it here.
+ */
+static void
+s390_root_dev_release(struct device *dev)
+{
+	kfree(dev);
+}
+
+struct device *
+s390_root_dev_register(const char *name)
+{
+	struct device *dev;
+	int ret;
+
+	if (!strlen(name))
+		return ERR_PTR(-EINVAL);
+	dev = kmalloc(sizeof(struct device), GFP_KERNEL);
+	if (!dev)
+		return ERR_PTR(-ENOMEM);
+	memset(dev, 0, sizeof(struct device));
+	strncpy(dev->bus_id, name, min(strlen(name), (size_t)BUS_ID_SIZE));
+	dev->release = s390_root_dev_release;
+	ret = device_register(dev);
+	if (ret) {
+		kfree(dev);
+		return ERR_PTR(ret);
+	}
+	return dev;
+}
+
+void
+s390_root_dev_unregister(struct device *dev)
+{
+	if (dev)
+		device_unregister(dev);
+}
+
 MODULE_LICENSE("GPL");
 EXPORT_SYMBOL(css_bus_type);
-
+EXPORT_SYMBOL(s390_root_dev_register);
+EXPORT_SYMBOL(s390_root_dev_unregister);
diff -urN linux-2.6/drivers/s390/net/cu3088.c linux-2.6-s390/drivers/s390/net/cu3088.c
--- linux-2.6/drivers/s390/net/cu3088.c	Fri Oct 17 23:43:00 2003
+++ linux-2.6-s390/drivers/s390/net/cu3088.c	Tue Oct 21 16:37:38 2003
@@ -1,5 +1,5 @@
 /*
- * $Id: cu3088.c,v 1.31 2003/09/29 15:24:27 cohuck Exp $
+ * $Id: cu3088.c,v 1.33 2003/10/14 12:10:19 cohuck Exp $
  *
  * CTC / LCS ccw_device driver
  *
@@ -25,6 +25,7 @@
 \f
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/err.h>
 
 #include <asm/ccwdev.h>
 #include <asm/ccwgroup.h>
@@ -55,15 +56,7 @@
 
 static struct ccw_driver cu3088_driver;
 
-static void
-cu3088_root_dev_release (struct device *dev)
-{
-}
-
-struct device cu3088_root_dev = {
-	.bus_id = "cu3088",
-	.release = cu3088_root_dev_release,
-};
+struct device *cu3088_root_dev;
 
 static ssize_t
 group_write(struct device_driver *drv, const char *buf, size_t count)
@@ -90,7 +83,7 @@
 		start = end + 1;
 	}
 
-	ret = ccwgroup_create(&cu3088_root_dev, cdrv->driver_id,
+	ret = ccwgroup_create(cu3088_root_dev, cdrv->driver_id,
 			      &cu3088_driver, 2, argv);
 
 	return (ret == 0) ? count : ret;
@@ -144,12 +137,12 @@
 {
 	int rc;
 	
-	rc = device_register(&cu3088_root_dev);
-	if (rc)
-		return rc;
+	cu3088_root_dev = s390_root_dev_register("cu3088");
+	if (IS_ERR(cu3088_root_dev))
+		return PTR_ERR(cu3088_root_dev);
 	rc = ccw_driver_register(&cu3088_driver);
 	if (rc)
-		device_unregister(&cu3088_root_dev);
+		s390_root_dev_unregister(cu3088_root_dev);
 
 	return rc;
 }
@@ -158,7 +151,7 @@
 cu3088_exit (void)
 {
 	ccw_driver_unregister(&cu3088_driver);
-	device_unregister(&cu3088_root_dev);
+	s390_root_dev_unregister(cu3088_root_dev);
 }
 
 MODULE_DEVICE_TABLE(ccw,cu3088_ids);
diff -urN linux-2.6/drivers/s390/net/iucv.c linux-2.6-s390/drivers/s390/net/iucv.c
--- linux-2.6/drivers/s390/net/iucv.c	Fri Oct 17 23:42:54 2003
+++ linux-2.6-s390/drivers/s390/net/iucv.c	Tue Oct 21 16:37:38 2003
@@ -1,5 +1,5 @@
 /* 
- * $Id: iucv.c,v 1.15 2003/10/01 09:25:15 mschwide Exp $
+ * $Id: iucv.c,v 1.17 2003/10/14 12:10:19 cohuck Exp $
  *
  * IUCV network driver
  *
@@ -29,7 +29,7 @@
  * 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.15 $
+ * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.17 $
  *
  */
 \f
@@ -44,12 +44,14 @@
 #include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/device.h>
 #include <asm/atomic.h>
 #include "iucv.h"
 #include <asm/io.h>
 #include <asm/s390_ext.h>
 #include <asm/ebcdic.h>
+#include <asm/ccwdev.h> //for root device stuff
 
 #define DEBUG
 
@@ -79,20 +81,12 @@
 	return 0;
 }
 
-static void
-iucv_root_release (struct device *dev)
-{
-}
-
 struct bus_type iucv_bus = {
 	.name = "iucv",
 	.match = iucv_bus_match,
 };	
 
-struct device iucv_root = {
-	.bus_id = "iucv",
-	.release = iucv_root_release,
-};
+struct device *iucv_root;
 
 /* General IUCV interrupt structure */
 typedef struct {
@@ -355,7 +349,7 @@
 static void
 iucv_banner(void)
 {
-	char vbuf[] = "$Revision: 1.15 $";
+	char vbuf[] = "$Revision: 1.17 $";
 	char *version = vbuf;
 
 	if ((version = strchr(version, ':'))) {
@@ -387,11 +381,11 @@
 		return ret;
 	}
 
-	ret = device_register(&iucv_root);
-	if (ret != 0) {
+	iucv_root = s390_root_dev_register("iucv");
+	if (IS_ERR(iucv_root)) {
 		printk(KERN_ERR "IUCV: failed to register iucv root.\n");
 		bus_unregister(&iucv_bus);
-		return ret;
+		return PTR_ERR(iucv_root);
 	}
 
 	/* Note: GFP_DMA used used to get memory below 2G */
@@ -401,6 +395,7 @@
 		printk(KERN_WARNING
 		       "%s: Could not allocate external interrupt buffer\n",
 		       __FUNCTION__);
+		s390_root_dev_unregister(iucv_root);
 		return -ENOMEM;
 	}
 	memset(iucv_external_int_buffer, 0, sizeof(iucv_GeneralInterrupt));
@@ -413,6 +408,7 @@
 		       __FUNCTION__);
 		kfree(iucv_external_int_buffer);
 		iucv_external_int_buffer = NULL;
+		s390_root_dev_unregister(iucv_root);
 		return -ENOMEM;
 	}
 	memset(iucv_param_pool, 0, sizeof(iucv_param) * PARAM_POOL_SIZE);
@@ -439,7 +435,7 @@
 		kfree(iucv_external_int_buffer);
 	if (iucv_param_pool)
 		kfree(iucv_param_pool);
-	device_unregister(&iucv_root);
+	s390_root_dev_unregister(iucv_root);
 	bus_unregister(&iucv_bus);
 	printk(KERN_INFO "IUCV lowlevel driver unloaded\n");
 }
diff -urN linux-2.6/drivers/s390/net/iucv.h linux-2.6-s390/drivers/s390/net/iucv.h
--- linux-2.6/drivers/s390/net/iucv.h	Fri Oct 17 23:43:36 2003
+++ linux-2.6-s390/drivers/s390/net/iucv.h	Tue Oct 21 16:37:38 2003
@@ -203,7 +203,7 @@
 } iucv_array_t __attribute__ ((aligned (8)));
 
 extern struct bus_type iucv_bus;
-extern struct device iucv_root;
+extern struct device *iucv_root;
 
 /*   -prototypes-    */
 /*                                                                
diff -urN linux-2.6/drivers/s390/net/netiucv.c linux-2.6-s390/drivers/s390/net/netiucv.c
--- linux-2.6/drivers/s390/net/netiucv.c	Tue Oct 21 16:37:36 2003
+++ linux-2.6-s390/drivers/s390/net/netiucv.c	Tue Oct 21 16:37:38 2003
@@ -1,5 +1,5 @@
 /*
- * $Id: netiucv.c,v 1.27 2003/10/06 18:35:24 mschwide Exp $
+ * $Id: netiucv.c,v 1.28 2003/10/14 11:48:04 cohuck 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.27 $
+ * RELEASE-TAG: IUCV network driver $Revision: 1.28 $
  *
  */
 \f
@@ -1483,7 +1483,7 @@
 
 	snprintf(dev->bus_id, BUS_ID_SIZE, "%s%x", str, ifno);
 	dev->bus = &iucv_bus;
-	dev->parent = &iucv_root;
+	dev->parent = iucv_root;
 
 	ret = device_register(dev);
 
@@ -1729,7 +1729,7 @@
 static void
 netiucv_banner(void)
 {
-	char vbuf[] = "$Revision: 1.27 $";
+	char vbuf[] = "$Revision: 1.28 $";
 	char *version = vbuf;
 
 	if ((version = strchr(version, ':'))) {
diff -urN linux-2.6/drivers/s390/net/qeth.c linux-2.6-s390/drivers/s390/net/qeth.c
--- linux-2.6/drivers/s390/net/qeth.c	Tue Oct 21 16:37:38 2003
+++ linux-2.6-s390/drivers/s390/net/qeth.c	Tue Oct 21 16:37:38 2003
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/qeth.c ($Revision: 1.163 $)
+ * linux/drivers/s390/net/qeth.c ($Revision: 1.165 $)
  *
  * Linux on zSeries OSA Express and HiperSockets support
  *
@@ -165,7 +165,7 @@
 		 "reserved for low memory situations");
 
 /****************** MODULE STUFF **********************************/
-#define VERSION_QETH_C "$Revision: 1.163 $"
+#define VERSION_QETH_C "$Revision: 1.165 $"
 static const char *version = "qeth S/390 OSA-Express driver ("
     VERSION_QETH_C "/" VERSION_QETH_H "/" VERSION_QETH_MPC_H
     QETH_VERSION_IPV6 QETH_VERSION_VLAN ")";
@@ -9798,15 +9798,7 @@
 	.remove = ccwgroup_remove_ccwdev,
 };
 
-static void
-qeth_root_dev_release (struct device *dev)
-{
-}
-
-static struct device qeth_root_dev = {
-	.bus_id = "qeth",
-	.release = qeth_root_dev_release,
-};
+static struct device *qeth_root_dev;
 
 static struct ccwgroup_driver qeth_ccwgroup_driver;
 static ssize_t
@@ -9832,7 +9824,7 @@
 	}
 	pr_debug("creating qeth group device from '%s', '%s' and '%s'\n",
 		 bus_ids[0], bus_ids[1], bus_ids[2]);
-	ccwgroup_create(&qeth_root_dev, qeth_ccwgroup_driver.driver_id,
+	ccwgroup_create(qeth_root_dev, qeth_ccwgroup_driver.driver_id,
 			&qeth_ccw_driver, 3, argv);
 	return count;
 }
@@ -10792,10 +10784,11 @@
 	if (result)
 		goto out_cdrv;
 
-	result = device_register(&qeth_root_dev);
-	if (result)
+	qeth_root_dev = s390_root_dev_register("qeth");
+	if (IS_ERR(qeth_root_dev)) {
+		result = PTR_ERR(qeth_root_dev);
 		goto out_file;
-
+	}
 	qeth_register_notifiers();
 	qeth_add_procfs_entries();
 
@@ -10834,7 +10827,7 @@
 	driver_remove_file(&qeth_ccwgroup_driver.driver, &driver_attr_group);
 	ccw_driver_unregister(&qeth_ccw_driver);
 	ccwgroup_driver_unregister(&qeth_ccwgroup_driver);
-	device_unregister(&qeth_root_dev);
+	s390_root_dev_unregister(qeth_root_dev);
 
 	while (firstcard) {
 		struct qeth_card *card = firstcard;
diff -urN linux-2.6/include/asm-s390/ccwdev.h linux-2.6-s390/include/asm-s390/ccwdev.h
--- linux-2.6/include/asm-s390/ccwdev.h	Fri Oct 17 23:43:28 2003
+++ linux-2.6-s390/include/asm-s390/ccwdev.h	Tue Oct 21 16:37:38 2003
@@ -167,4 +167,7 @@
 extern int _ccw_device_get_device_number(struct ccw_device *);
 extern int _ccw_device_get_subchannel_number(struct ccw_device *);
 
+extern struct device *s390_root_dev_register(const char *);
+extern void s390_root_dev_unregister(struct device *);
+
 #endif /* _S390_CCWDEV_H_ */

                 reply	other threads:[~2003-10-21 15:12 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20031021151008.GE1690@mschwid3.boeblingen.de.ibm.com \
    --to=schwidefsky@de.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@osdl.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®