Skip to contentSkip to conversation

Driver Core patches for 2.6.6

PATCH New Greg KH 2 participants 21 messages May 14, 2004 – May 15, 2004

Subsystems (9)
lore
Share & tools
lore

Greg KH

author
#0 lore raw

PATCH 1/1 Driver Core patches for 2.6.6

Hi,

Here are lots of fun changes related to the driver core and sysfs for 2.6.6. They include adding the module param info to sysfs, more class_simple changes, a smbios driver, and some sysfs bug fixes.

All of these patches have been in the -mm tree for a number of releases.

Please pull from:

	bk://kernel.bkbits.net/gregkh/linux/driver-2.6

thanks,

greg k-h

p.s. I'll send these as patches in response to this email to lkml for those who want to see them.

 drivers/base/bus.c           |   32 +++-
 drivers/base/class.c         |    6 
 drivers/base/map.c           |    7 
 drivers/base/platform.c      |    5 
 drivers/base/sys.c           |    5 
 drivers/block/paride/pg.c    |   48 +++++-
 drivers/block/paride/pt.c    |   54 ++++++-
 drivers/char/ip2main.c       |   44 +++++-
 drivers/char/ppdev.c         |   45 +++++-
 drivers/char/tipar.c         |   49 +++++-
 drivers/firmware/Kconfig     |   16 ++
 drivers/firmware/Makefile    |    1 
 drivers/firmware/smbios.c    |  310 ++++++++++++++++++++++++++++++++++++++-----
 drivers/firmware/smbios.h    |   53 +++++++
 drivers/macintosh/adb.c      |   19 +-
 drivers/misc/Kconfig         |    8 -
 drivers/misc/ibmasm/module.c |    7 
 drivers/net/wan/cosa.c       |   41 ++++-
 fs/sysfs/bin.c               |    2 
 fs/sysfs/dir.c               |   19 +-
 fs/sysfs/file.c              |    2 
 fs/sysfs/sysfs.h             |   13 +
 include/linux/device.h       |    2 
 include/linux/kobject.h      |    2 
 include/linux/module.h       |   25 +++
 include/linux/moduleparam.h  |    4 
 include/linux/sysfs.h        |    2 
 kernel/module.c              |  194 ++++++++++++++++++++++++--
 kernel/params.c              |    2 
 lib/kobject.c                |   10 -
 net/core/dev.c               |   18 +-
 31 files changed, 917 insertions(+), 128 deletions(-)

-----

<kenn:linux.ie>:
o Re: Platform device matching

Daniele Bellucci:
o missing audit in bus_register()

Greg Kroah-Hartman:
o Module attributes: fix build error if CONFIG_MODULE_UNLOAD=n
o Add modules to sysfs
o Driver core: handle error if we run out of memory in kmap code
o My cleanups to the smbios driver

Hanna V. Linder:
o Add class support to drivers/net/wan/cosa.c
o add class support to drivers/char/tipar.c
o add class support to drivers/block/paride/pt.c
o add class support to drivers/block/paride/pg.c
o Add class support to drivers/char/ip2main.c

James Bottomley:
o fix dev_printk to work even in the absence of an attached driver

Maneesh Soni:
o sysfs_rename_dir-cleanup
o kobject/sysfs race fix
o kobject_set_name - error handling

Marcel Sebek:
o Class support for ppdev.c

Max Asbock:
o add ibmasm driver warning message

Michael E. Brown:
o add SMBIOS tables to sysfs -- UPDATED

Olaf Hering:
o add simple class for adb

author
#1 lore raw

PATCH 1/1 Driver Core patches for 2.6.6

ChangeSet 1.1587.5.11, 2004/04/28 11:50:29-07:00, [email protected]

[PATCH] add SMBIOS tables to sysfs -- UPDATED

 drivers/firmware/Kconfig  |    8 +
 drivers/firmware/Makefile |    1 
 drivers/firmware/smbios.c |  266 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/firmware/smbios.h |   53 +++++++++
 4 files changed, 328 insertions(+)
drivers/firmware/Kconfig +8 -0
diff -Nru a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
@@ -34,4 +34,12 @@
 	  Subsequent efibootmgr releases may be found at:
 	  http://linux.dell.com/efibootmgr
 
+config SMBIOS
+	tristate "BIOS SMBIOS table access driver."
+	help
+	  Say Y or M here if you want to enable access to the SMBIOS table
+	  via driverfs. It exposes /sys/firmware/smbios/ subdirectory tree
+	  containing a binary dump of the SMBIOS table header as well as the SMBIOS
+	  table.
+
 endmenu
drivers/firmware/Makefile +1 -0
diff -Nru a/drivers/firmware/Makefile b/drivers/firmware/Makefile
@@ -3,3 +3,4 @@
 #
 obj-$(CONFIG_EDD)             	+= edd.o
 obj-$(CONFIG_EFI_VARS)		+= efivars.o
+obj-$(CONFIG_SMBIOS)            += smbios.o
drivers/firmware/smbios.c new file +266 -0

266 lines not on this page · raw message

drivers/firmware/smbios.h new file +53 -0

53 lines not on this page · raw message

author
#2 lore raw

ChangeSet 1.1587.5.12, 2004/04/28 11:51:03-07:00, [email protected]

My cleanups to the smbios driver.

 drivers/firmware/smbios.c |   44 +++++++++++++-------------------------------
 1 files changed, 13 insertions(+), 31 deletions(-)
drivers/firmware/smbios.c +13 -31
diff -Nru a/drivers/firmware/smbios.c b/drivers/firmware/smbios.c
@@ -10,9 +10,9 @@
  *
  * This code takes information provided by SMBIOS tables
  * and presents it in sysfs as:
- *    /sys/firmware/smbios/smbios
- *				|--> /table_entry_point
- *				|--> /table
+ *    /sys/firmware/smbios
+ *			|--> /table_entry_point
+ *			|--> /table
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License v2.0 as published by
@@ -42,7 +42,6 @@
 struct smbios_device {
 	struct smbios_table_entry_point table_eps;
 	unsigned int smbios_table_real_length;
-	struct kobject kobj;
 };
 
 /* there shall be only one */
@@ -143,7 +142,7 @@
 smbios_read_table_entry_point(struct kobject *kobj, char *buffer,
 				loff_t pos, size_t size)
 {
-	struct smbios_device *sdev = to_smbios_device(kobj);
+	struct smbios_device *sdev = &the_smbios_device;
 	const char *p = (const char *)&(sdev->table_eps);
 	unsigned int count =
 		size > sizeof(sdev->table_eps) ?
@@ -156,7 +155,7 @@
 smbios_read_table(struct kobject *kobj, char *buffer,
 				loff_t pos, size_t size)
 {
-	struct smbios_device *sdev = to_smbios_device(kobj);
+	struct smbios_device *sdev = &the_smbios_device;
 	u8 *buf;
 	unsigned int count = sdev->smbios_table_real_length - pos;
 	int i = 0;
@@ -204,30 +203,16 @@
 
 static decl_subsys(smbios,&ktype_smbios,NULL);
 
-static inline void
-smbios_device_unregister(struct smbios_device *sdev)
+static void smbios_device_unregister(void)
 {
-	sysfs_remove_bin_file(&sdev->kobj, &tep_attr );
-	sysfs_remove_bin_file(&sdev->kobj, &table_attr );
-	kobject_unregister(&sdev->kobj);
+	sysfs_remove_bin_file(&smbios_subsys.kset.kobj, &tep_attr );
+	sysfs_remove_bin_file(&smbios_subsys.kset.kobj, &table_attr );
 }
 
-static int
-smbios_device_register(struct smbios_device *sdev)
+static void __init smbios_device_register(void)
 {
-	int error;
-
-	if (!sdev)
-		return 1;
-
-	kobject_set_name(&sdev->kobj, "smbios");
-	kobj_set_kset_s(sdev,smbios_subsys);
-	error = kobject_register(&sdev->kobj);
-	if (!error){
-		sysfs_create_bin_file(&sdev->kobj, &tep_attr );
-		sysfs_create_bin_file(&sdev->kobj, &table_attr );
-	}
-	return error;
+	sysfs_create_bin_file(&smbios_subsys.kset.kobj, &tep_attr );
+	sysfs_create_bin_file(&smbios_subsys.kset.kobj, &table_attr );
 }
 
 static int __init
@@ -247,10 +232,7 @@
 	if (rc)
 		return rc;
 
-	rc = smbios_device_register(&the_smbios_device);
-
-	if (rc)
-		firmware_unregister(&smbios_subsys);
+	smbios_device_register();
 
 	return rc;
 }
@@ -258,7 +240,7 @@
 static void __exit
 smbios_exit(void)
 {
-	smbios_device_unregister(&the_smbios_device);
+	smbios_device_unregister();
 	firmware_unregister(&smbios_subsys);
 }
 
author
#3 lore raw

ChangeSet 1.1587.5.13, 2004/05/02 20:28:38-07:00, [email protected]

[PATCH] Class support for ppdev.c

 drivers/char/ppdev.c |   45 +++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 43 insertions(+), 2 deletions(-)
drivers/char/ppdev.c +43 -2
diff -Nru a/drivers/char/ppdev.c b/drivers/char/ppdev.c
@@ -59,6 +59,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/ioctl.h>
 #include <linux/parport.h>
@@ -739,6 +740,8 @@
 	return mask;
 }
 
+static struct class_simple *ppdev_class;
+
 static struct file_operations pp_fops = {
 	.owner		= THIS_MODULE,
 	.llseek		= no_llseek,
@@ -750,23 +753,59 @@
 	.release	= pp_release,
 };
 
+static void pp_attach(struct parport *port)
+{
+	class_simple_device_add(ppdev_class, MKDEV(PP_MAJOR, port->number),
+			NULL, "parport%d", port->number);
+}
+
+static void pp_detach(struct parport *port)
+{
+	class_simple_device_remove(MKDEV(PP_MAJOR, port->number));
+}
+
+static struct parport_driver pp_driver = {
+	.name		= CHRDEV,
+	.attach		= pp_attach,
+	.detach		= pp_detach,
+};
+
 static int __init ppdev_init (void)
 {
-	int i;
+	int i, err = 0;
 
 	if (register_chrdev (PP_MAJOR, CHRDEV, &pp_fops)) {
 		printk (KERN_WARNING CHRDEV ": unable to get major %d\n",
 			PP_MAJOR);
 		return -EIO;
 	}
+	ppdev_class = class_simple_create(THIS_MODULE, CHRDEV);
+	if (IS_ERR(ppdev_class)) {
+		err = PTR_ERR(ppdev_class);
+		goto out_chrdev;
+	}
 	devfs_mk_dir("parports");
 	for (i = 0; i < PARPORT_MAX; i++) {
 		devfs_mk_cdev(MKDEV(PP_MAJOR, i),
 				S_IFCHR | S_IRUGO | S_IWUGO, "parports/%d", i);
 	}
+	if (parport_register_driver(&pp_driver)) {
+		printk (KERN_WARNING CHRDEV ": unable to register with parport\n");
+		goto out_class;
+	}
 
 	printk (KERN_INFO PP_VERSION "\n");
-	return 0;
+	goto out;
+
+out_class:
+	for (i = 0; i < PARPORT_MAX; i++)
+		devfs_remove("parports/%d", i);
+	devfs_remove("parports");
+	class_simple_destroy(ppdev_class);
+out_chrdev:
+	unregister_chrdev(PP_MAJOR, CHRDEV);
+out:
+	return err;
 }
 
 static void __exit ppdev_cleanup (void)
@@ -775,7 +814,9 @@
 	/* Clean up all parport stuff */
 	for (i = 0; i < PARPORT_MAX; i++)
 		devfs_remove("parports/%d", i);
+	parport_unregister_driver(&pp_driver);
 	devfs_remove("parports");
+	class_simple_destroy(ppdev_class);
 	unregister_chrdev (PP_MAJOR, CHRDEV);
 }
 
author
#4 lore raw

ChangeSet 1.1587.5.14, 2004/05/02 20:28:58-07:00, [email protected]

[PATCH] Add class support to drivers/char/ip2main.c

 drivers/char/ip2main.c |   44 +++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 39 insertions(+), 5 deletions(-)
drivers/char/ip2main.c +39 -5
diff -Nru a/drivers/char/ip2main.c b/drivers/char/ip2main.c
@@ -99,6 +99,7 @@
 #include <linux/slab.h>
 #include <linux/major.h>
 #include <linux/wait.h>
+#include <linux/device.h>
 
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
@@ -301,6 +302,9 @@
 static char rirqs[IP2_MAX_BOARDS];
 static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};
 
+/* for sysfs class support */
+static struct class_simple *ip2_class;
+
 // Some functions to keep track of what irq's we have
 
 static int __init
@@ -411,7 +415,9 @@
 			iiResetDelay( i2BoardPtrTable[i] );
 			/* free io addresses and Tibet */
 			release_region( ip2config.addr[i], 8 );
+			class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 4 * i)); 
 			devfs_remove("ip2/ipl%d", i);
+			class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
 			devfs_remove("ip2/stat%d", i);
 		}
 		/* Disable and remove interrupt handler. */
@@ -420,6 +426,7 @@
 			clear_requested_irq( ip2config.irq[i]);
 		}
 	}
+	class_simple_destroy(ip2_class);
 	devfs_remove("ip2");
 	if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) {
 		printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err);
@@ -494,7 +501,7 @@
 ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) 
 {
 	int i, j, box;
-	int err;
+	int err = 0;
 	int status = 0;
 	static int loaded;
 	i2eBordStrPtr pB = NULL;
@@ -683,7 +690,14 @@
 	/* Register the IPL driver. */
 	if ( ( err = register_chrdev ( IP2_IPL_MAJOR, pcIpl, &ip2_ipl ) ) ) {
 		printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err );
-	} else
+	} else {
+		/* create the sysfs class */
+		ip2_class = class_simple_create(THIS_MODULE, "ip2");
+		if (IS_ERR(ip2_class)) {
+			err = PTR_ERR(ip2_class);
+			goto out_chrdev;	
+		}
+	}
 	/* Register the read_procmem thing */
 	if (!create_proc_info_entry("ip2mem",0,&proc_root,ip2_read_procmem)) {
 		printk(KERN_ERR "IP2: failed to register read_procmem\n");
@@ -700,13 +714,27 @@
 			}
 
 			if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
-				devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i),
+				class_simple_device_add(ip2_class, MKDEV(IP2_IPL_MAJOR, 
+						4 * i), NULL, "ipl%d", i);
+				err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i),
 						S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
 						"ip2/ipl%d", i);
+				if (err) {
+					class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 
+						4 * i));
+					goto out_class;
+				}
 
-				devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
+				class_simple_device_add(ip2_class, MKDEV(IP2_IPL_MAJOR, 
+						4 * i + 1), NULL, "stat%d", i);
+				err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
 						S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
 						"ip2/stat%d", i);
+				if (err) {
+					class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 
+						4 * i + 1));
+					goto out_class;
+				}
 
 			    for ( box = 0; box < ABS_MAX_BOXES; ++box )
 			    {
@@ -759,8 +787,14 @@
 		}
 	}
 	ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0 );
+	goto out;
 
-	return 0;
+out_class:
+	class_simple_destroy(ip2_class);
+out_chrdev:
+	unregister_chrdev(IP2_IPL_MAJOR, "ip2");
+out:
+	return err;
 }
 
 EXPORT_SYMBOL(ip2_loadmain);
author
#5 lore raw

ChangeSet 1.1587.5.15, 2004/05/02 20:29:22-07:00, [email protected]

[PATCH] add class support to drivers/block/paride/pg.c

This patch adds class support to pg.c, the parallel port generic ATAPI device driver.

I have verified it compiles but do not have the hardware. If someone does and could test that would be helpful.

 drivers/block/paride/pg.c |   48 ++++++++++++++++++++++++++++++++++++----------
 1 files changed, 38 insertions(+), 10 deletions(-)
drivers/block/paride/pg.c +38 -10
diff -Nru a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
@@ -161,6 +161,7 @@
 #include <linux/slab.h>
 #include <linux/mtio.h>
 #include <linux/pg.h>
+#include <linux/device.h>
 
 #include <asm/uaccess.h>
 
@@ -240,6 +241,8 @@
 
 static char pg_scratch[512];	/* scratch block buffer */
 
+static struct class_simple *pg_class;
+
 /* kernel glue structures */
 
 static struct file_operations pg_fops = {
@@ -658,15 +661,19 @@
 
 static int __init pg_init(void)
 {
-	int unit;
+	int unit, err = 0;
 
-	if (disable)
-		return -1;
+	if (disable){
+		err = -1;
+		goto out;
+	}
 
 	pg_init_units();
 
-	if (pg_detect())
-		return -1;
+	if (pg_detect()) {
+		err = -1;
+		goto out;
+	}
 
 	if (register_chrdev(major, name, &pg_fops)) {
 		printk("pg_init: unable to get major number %d\n", major);
@@ -675,18 +682,37 @@
 			if (dev->present)
 				pi_release(dev->pi);
 		}
-		return -1;
+		err = -1;
+		goto out;
+	}
+	pg_class = class_simple_create(THIS_MODULE, "pg");
+	if (IS_ERR(pg_class)) {
+		err = PTR_ERR(pg_class);
+		goto out_chrdev;
 	}
 	devfs_mk_dir("pg");
 	for (unit = 0; unit < PG_UNITS; unit++) {
 		struct pg *dev = &devices[unit];
 		if (dev->present) {
-			devfs_mk_cdev(MKDEV(major, unit),
+			class_simple_device_add(pg_class, MKDEV(major, unit), 
+					NULL, "pg%u", unit);
+			err = devfs_mk_cdev(MKDEV(major, unit),
 				      S_IFCHR | S_IRUSR | S_IWUSR, "pg/%u",
 				      unit);
+			if (err) 
+				goto out_class;
 		}
 	}
-	return 0;
+	err = 0;
+	goto out;
+
+out_class:
+	class_simple_device_remove(MKDEV(major, unit));
+	class_simple_destroy(pg_class);
+out_chrdev:
+	unregister_chrdev(major, "pg");
+out:
+	return err;
 }
 
 static void __exit pg_exit(void)
@@ -695,10 +721,12 @@
 
 	for (unit = 0; unit < PG_UNITS; unit++) {
 		struct pg *dev = &devices[unit];
-		if (dev->present)
+		if (dev->present) {
+			class_simple_device_remove(MKDEV(major, unit));
 			devfs_remove("pg/%u", unit);
+		}
 	}
-
+	class_simple_destroy(pg_class);
 	devfs_remove("pg");
 	unregister_chrdev(major, name);
 
author
#6 lore raw

ChangeSet 1.1587.5.16, 2004/05/02 20:29:41-07:00, [email protected]

[PATCH] add class support to drivers/block/paride/pt.c

This patch adds class support to pt.c which "the high-level driver for parallel port ATAPI tape drives based on chips supported by the paride module." Which I dont have in order to test.

I have verified it compiles but can not test it. If someone who has the hardware could I would appreciate it.

 drivers/block/paride/pt.c |   54 ++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 45 insertions(+), 9 deletions(-)
drivers/block/paride/pt.c +45 -9
diff -Nru a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
@@ -145,6 +145,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/mtio.h>
+#include <linux/device.h>
 
 #include <asm/uaccess.h>
 
@@ -260,6 +261,9 @@
 	.release = pt_release,
 };
 
+/* sysfs class support */
+static struct class_simple *pt_class;
+
 static inline int status_reg(struct pi_adapter *pi)
 {
 	return pi_read_regr(pi, 1, 6);
@@ -959,33 +963,62 @@
 
 static int __init pt_init(void)
 {
-	int unit;
+	int unit, err = 0;
 
-	if (disable)
-		return -1;
+	if (disable) {
+		err = -1;
+		goto out;
+	}
 
-	if (pt_detect())
-		return -1;
+	if (pt_detect()) {
+		err = -1;
+		goto out;
+	}
 
 	if (register_chrdev(major, name, &pt_fops)) {
 		printk("pt_init: unable to get major number %d\n", major);
 		for (unit = 0; unit < PT_UNITS; unit++)
 			if (pt[unit].present)
 				pi_release(pt[unit].pi);
-		return -1;
+		err = -1;
+		goto out;
+	}
+	pt_class = class_simple_create(THIS_MODULE, "pt");
+	if (IS_ERR(pt_class)) {
+		err = PTR_ERR(pt_class);
+		goto out_chrdev;
 	}
 
 	devfs_mk_dir("pt");
 	for (unit = 0; unit < PT_UNITS; unit++)
 		if (pt[unit].present) {
-			devfs_mk_cdev(MKDEV(major, unit),
+			class_simple_device_add(pt_class, MKDEV(major, unit), 
+					NULL, "pt%d", unit);
+			err = devfs_mk_cdev(MKDEV(major, unit),
 				      S_IFCHR | S_IRUSR | S_IWUSR,
 				      "pt/%d", unit);
-			devfs_mk_cdev(MKDEV(major, unit + 128),
+			if (err) {
+				class_simple_device_remove(MKDEV(major, unit));
+				goto out_class;
+			}
+			class_simple_device_add(pt_class, MKDEV(major, unit + 128),
+					NULL, "pt%dn", unit);
+			err = devfs_mk_cdev(MKDEV(major, unit + 128),
 				      S_IFCHR | S_IRUSR | S_IWUSR,
 				      "pt/%dn", unit);
+			if (err) {
+				class_simple_device_remove(MKDEV(major, unit + 128));
+				goto out_class;
+			}
 		}
-	return 0;
+	goto out;
+
+out_class:
+	class_simple_destroy(pt_class);
+out_chrdev:
+	unregister_chrdev(major, "pt");
+out:
+	return err;
 }
 
 static void __exit pt_exit(void)
@@ -993,9 +1026,12 @@
 	int unit;
 	for (unit = 0; unit < PT_UNITS; unit++)
 		if (pt[unit].present) {
+			class_simple_device_remove(MKDEV(major, unit));
 			devfs_remove("pt/%d", unit);
+			class_simple_device_remove(MKDEV(major, unit + 128));
 			devfs_remove("pt/%dn", unit);
 		}
+	class_simple_destroy(pt_class);
 	devfs_remove("pt");
 	unregister_chrdev(major, name);
 	for (unit = 0; unit < PT_UNITS; unit++)
author
#7 lore raw

ChangeSet 1.1587.5.17, 2004/05/02 20:29:59-07:00, [email protected]

[PATCH] add class support to drivers/char/tipar.c

This patch adds class support to the Texas Instruments graphing calculators with a parallel link cable.

I have verified it compiles. If someone has the hardware please verify it works.

 drivers/char/tipar.c |   49 ++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 42 insertions(+), 7 deletions(-)
drivers/char/tipar.c +42 -7
diff -Nru a/drivers/char/tipar.c b/drivers/char/tipar.c
@@ -58,6 +58,7 @@
 #include <asm/bitops.h>
 #include <linux/devfs_fs_kernel.h>	/* DevFs support */
 #include <linux/parport.h>	/* Our code depend on parport */
+#include <linux/device.h>
 
 /*
  * TI definitions
@@ -92,6 +93,8 @@
 static unsigned int tp_count;	/* tipar count */
 static unsigned long opened;	/* opened devices */
 
+static struct class_simple *tipar_class;
+
 /* --- macros for parport access -------------------------------------- */
 
 #define r_dtr(x)        (parport_read_data(table[(x)].dev->port))
@@ -424,18 +427,26 @@
 static int
 tipar_register(int nr, struct parport *port)
 {
+	int err = 0;
+
 	/* Register our module into parport */
 	table[nr].dev = parport_register_device(port, "tipar",
 						NULL, NULL, NULL, 0,
 						(void *) &table[nr]);
 
-	if (table[nr].dev == NULL)
-		return 1;
+	if (table[nr].dev == NULL) {
+		err = 1;
+		goto out;
+	}
 
+	class_simple_device_add(tipar_class, MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr),
+			NULL, "par%d", nr);
 	/* Use devfs, tree: /dev/ticables/par/[0..2] */
-	devfs_mk_cdev(MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr),
+	err = devfs_mk_cdev(MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr),
 			S_IFCHR | S_IRUGO | S_IWUGO,
 			"ticables/par/%d", nr);
+	if (err)
+		goto out_class;
 
 	/* Display informations */
 	printk(KERN_INFO "tipar%d: using %s (%s).\n", nr, port->name,
@@ -447,7 +458,14 @@
 	else
 		printk("tipar%d: link cable not found.\n", nr);
 
-	return 0;
+	err = 0;
+	goto out;
+
+out_class:
+	class_simple_device_remove(MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr));
+	class_simple_destroy(tipar_class);
+out:
+	return err;
 }
 
 static void
@@ -477,23 +495,38 @@
 int __init
 tipar_init_module(void)
 {
+	int err = 0;
+
 	printk("tipar: parallel link cable driver, version %s\n",
 	       DRIVER_VERSION);
 
 	if (register_chrdev(TIPAR_MAJOR, "tipar", &tipar_fops)) {
 		printk("tipar: unable to get major %d\n", TIPAR_MAJOR);
-		return -EIO;
+		err = -EIO;
+		goto out;
 	}
 
 	/* Use devfs with tree: /dev/ticables/par/[0..2] */
 	devfs_mk_dir("ticables/par");
 
+	tipar_class = class_simple_create(THIS_MODULE, "ticables");
+	if (IS_ERR(tipar_class)) {
+		err = PTR_ERR(tipar_class);
+		goto out_chrdev;
+	}
 	if (parport_register_driver(&tipar_driver)) {
 		printk("tipar: unable to register with parport\n");
-		return -EIO;
+		err = -EIO;
+		goto out;
 	}
 
-	return 0;
+	err = 0;
+	goto out;
+
+out_chrdev:
+	unregister_chrdev(TIPAR_MAJOR, "tipar");
+out:
+	return err;	
 }
 
 void __exit
@@ -510,8 +543,10 @@
 		if (table[i].dev == NULL)
 			continue;
 		parport_unregister_device(table[i].dev);
+		class_simple_device_remove(MKDEV(TIPAR_MAJOR, i));
 		devfs_remove("ticables/par/%d", i);
 	}
+	class_simple_destroy(tipar_class);
 	devfs_remove("ticables/par");
 
 	printk("tipar: module unloaded !\n");
author
#8 lore raw

ChangeSet 1.1587.5.18, 2004/05/02 20:30:19-07:00, [email protected]

[PATCH] Re: Platform device matching

Quoted 4 lines · Russell King

So, this comment needs updating:

* So, extract the <name> from the device, and compare it against
* the name of the driver. Return whether they match or not.

Want a patch?

 drivers/base/platform.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)
drivers/base/platform.c +3 -2
diff -Nru a/drivers/base/platform.c b/drivers/base/platform.c
@@ -57,8 +57,9 @@
  *	type of device, like "pci" or "floppy", and <instance> is the 
  *	enumerated instance of the device, like '0' or '42'.
  *	Driver IDs are simply "<name>". 
- *	So, extract the <name> from the device, and compare it against 
- *	the name of the driver. Return whether they match or not.
+ *	So, extract the <name> from the platform_device structure, 
+ *	and compare it against the name of the driver. Return whether 
+ *	they match or not.
  */
 
 static int platform_match(struct device * dev, struct device_driver * drv)
author
#9 lore raw

ChangeSet 1.1587.5.19, 2004/05/04 14:16:58-07:00, [email protected]

[PATCH] add simple class for adb

This adds /sys/class/adb/, removes unused devfs lines and updates a comment to match reality.

 drivers/macintosh/adb.c |   19 +++++++++++++------
 1 files changed, 13 insertions(+), 6 deletions(-)
drivers/macintosh/adb.c +13 -6
diff -Nru a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
@@ -10,7 +10,7 @@
  *
  * To do:
  *
- * - /proc/adb to list the devices and infos
+ * - /sys/bus/adb to list the devices and infos
  * - more /dev/adb to allow userland to receive the
  *   flow of auto-polling datas from a given device.
  * - move bus probe to a kernel thread
@@ -23,7 +23,6 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/fs.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
@@ -36,6 +35,7 @@
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include <linux/completion.h>
+#include <linux/device.h>
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
 #ifdef CONFIG_PPC
@@ -75,6 +75,8 @@
 	NULL
 };
 
+static struct class_simple *adb_dev_class;
+
 struct adb_driver *adb_controller;
 struct notifier_block *adb_client_list = NULL;
 static int adb_got_sleep;
@@ -883,6 +885,7 @@
 }
 
 static struct file_operations adb_fops = {
+	.owner		= THIS_MODULE,
 	.llseek		= no_llseek,
 	.read		= adb_read,
 	.write		= adb_write,
@@ -893,9 +896,13 @@
 static void
 adbdev_init(void)
 {
-	if (register_chrdev(ADB_MAJOR, "adb", &adb_fops))
+	if (register_chrdev(ADB_MAJOR, "adb", &adb_fops)) {
 		printk(KERN_ERR "adb: unable to get major %d\n", ADB_MAJOR);
-	else
-		devfs_mk_cdev(MKDEV(ADB_MAJOR, 0),
-				S_IFCHR | S_IRUSR | S_IWUSR, "adb");
+		return;
+	}
+	adb_dev_class = class_simple_create(THIS_MODULE, "adb");
+	if (IS_ERR(adb_dev_class)) {
+		return;
+	}
+	class_simple_device_add(adb_dev_class, MKDEV(ADB_MAJOR, 0), NULL, "adb");
 }
author
#10 lore raw

ChangeSet 1.1587.5.20, 2004/05/05 14:40:43-07:00, [email protected]

Driver core: handle error if we run out of memory in kmap code

 drivers/base/map.c |    7 +++++++
 1 files changed, 7 insertions(+)
drivers/base/map.c +7 -0
diff -Nru a/drivers/base/map.c b/drivers/base/map.c
@@ -138,6 +138,13 @@
 	struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL);
 	struct probe *base = kmalloc(sizeof(struct probe), GFP_KERNEL);
 	int i;
+
+	if ((p == NULL) || (base == NULL)) {
+		kfree(p);
+		kfree(base);
+		return NULL;
+	}
+
 	memset(base, 0, sizeof(struct probe));
 	base->dev = 1;
 	base->range = ~0;
author
#11 lore raw

ChangeSet 1.1587.5.21, 2004/05/05 15:10:00-07:00, [email protected]

[PATCH] missing audit in bus_register()

|How about using a goto on the error path to clean up properly |instead of the different return sections.

.. here goes Take 2:

 drivers/base/bus.c |   21 ++++++++++++++++++---
 1 files changed, 18 insertions(+), 3 deletions(-)
drivers/base/bus.c +18 -3
diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c
@@ -555,21 +555,36 @@
  */
 int bus_register(struct bus_type * bus)
 {
+	int retval;
+
 	kobject_set_name(&bus->subsys.kset.kobj,bus->name);
 	subsys_set_kset(bus,bus_subsys);
-	subsystem_register(&bus->subsys);
+	retval = subsystem_register(&bus->subsys);
+	if (retval) 
+		goto out;
 
 	kobject_set_name(&bus->devices.kobj, "devices");
 	bus->devices.subsys = &bus->subsys;
-	kset_register(&bus->devices);
+	retval = kset_register(&bus->devices);
+	if (retval)
+		goto bus_devices_fail;
 
 	kobject_set_name(&bus->drivers.kobj, "drivers");
 	bus->drivers.subsys = &bus->subsys;
 	bus->drivers.ktype = &ktype_driver;
-	kset_register(&bus->drivers);
+	retval = kset_register(&bus->drivers);
+	if (retval)
+		goto bus_drivers_fail;
 
 	pr_debug("bus type '%s' registered\n",bus->name);
 	return 0;
+
+bus_drivers_fail:
+	kset_unregister(&bus->devices);
+bus_devices_fail:
+	subsystem_unregister(&bus->subsys);
+out:
+	return retval;
 }
 
 
author
#12 lore raw

ChangeSet 1.1587.5.22, 2004/05/07 14:22:49-07:00, [email protected]

Add modules to sysfs

This patch adds basic kobject support to struct module, and it creates a /sys/module directory which contains all of the individual modules. Each module currently exports the refcount (if they are unloadable) and any module paramaters that are marked exportable in sysfs.

Was written by me and Rusty over and over many times during the past 6 months.

 include/linux/module.h      |   25 ++++++
 include/linux/moduleparam.h |    4 -
 kernel/module.c             |  160 ++++++++++++++++++++++++++++++++++++++++++++
 kernel/params.c             |    2 
 4 files changed, 188 insertions(+), 3 deletions(-)
include/linux/module.h +25 -0
diff -Nru a/include/linux/module.h b/include/linux/module.h
@@ -16,6 +16,8 @@
 #include <linux/kmod.h>
 #include <linux/elf.h>
 #include <linux/stringify.h>
+#include <linux/kobject.h>
+#include <linux/moduleparam.h>
 #include <asm/local.h>
 
 #include <asm/module.h>
@@ -207,6 +209,23 @@
 	MODULE_STATE_GOING,
 };
 
+/* sysfs stuff */
+struct module_attribute
+{
+	struct attribute attr;
+	struct kernel_param *param;
+};
+
+struct module_kobject
+{
+	/* Everyone should have one of these. */
+	struct kobject kobj;
+
+	/* We always have refcnt, we may have others from module_param(). */
+	unsigned int num_attributes;
+	struct module_attribute attr[0];
+};
+
 struct module
 {
 	enum module_state state;
@@ -217,6 +236,9 @@
 	/* Unique handle for this module */
 	char name[MODULE_NAME_LEN];
 
+	/* Sysfs stuff. */
+	struct module_kobject *mkobj;
+
 	/* Exported symbols */
 	const struct kernel_symbol *syms;
 	unsigned int num_syms;
@@ -267,6 +289,9 @@
 
 	/* Destruction function. */
 	void (*exit)(void);
+
+	/* Fake kernel param for refcnt. */
+	struct kernel_param refcnt_param;
 #endif
 
 #ifdef CONFIG_KALLSYMS
include/linux/moduleparam.h +2 -2
diff -Nru a/include/linux/moduleparam.h b/include/linux/moduleparam.h
@@ -50,7 +50,7 @@
    not there, read bits mean it's readable, write bits mean it's
    writable. */
 #define __module_param_call(prefix, name, set, get, arg, perm)		\
-	static char __param_str_##name[] __initdata = prefix #name;	\
+	static char __param_str_##name[] = prefix #name;		\
 	static struct kernel_param const __param_##name			\
 	__attribute_used__						\
     __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
@@ -71,7 +71,7 @@
 
 /* Actually copy string: maxlen param is usually sizeof(string). */
 #define module_param_string(name, string, len, perm)			\
-	static struct kparam_string __param_string_##name __initdata	\
+	static struct kparam_string __param_string_##name		\
 		= { len, string };					\
 	module_param_call(name, param_set_copystring, param_get_charp,	\
 		   &__param_string_##name, perm)
kernel/module.c +160 -0

199 lines not on this page · raw message

kernel/params.c +1 -1
diff -Nru a/kernel/params.c b/kernel/params.c
@@ -161,7 +161,7 @@
 									\
 		if (!val) return -EINVAL;				\
 		l = strtolfn(val, &endp, 0);				\
-		if (endp == val || *endp || ((type)l != l))		\
+		if (endp == val || ((type)l != l))			\
 			return -EINVAL;					\
 		*((type *)kp->arg) = l;					\
 		return 0;						\
author
#13 lore raw

ChangeSet 1.1587.5.23, 2004/05/11 13:32:24-07:00, [email protected]

Module attributes: fix build error if CONFIG_MODULE_UNLOAD=n

Thanks to Andrew Morton for pointing this out to me.

 kernel/module.c |   32 ++++++++++++++++----------------
 1 files changed, 16 insertions(+), 16 deletions(-)
kernel/module.c +16 -16
diff -Nru a/kernel/module.c b/kernel/module.c
@@ -379,6 +379,22 @@
 }
 #endif /* CONFIG_SMP */
 
+static int add_attribute(struct module *mod, struct kernel_param *kp)
+{
+	struct module_attribute *a;
+	int retval;
+
+	a = &mod->mkobj->attr[mod->mkobj->num_attributes];
+	a->attr.name = (char *)kp->name;
+	a->attr.owner = mod;
+	a->attr.mode = kp->perm;
+	a->param = kp;
+	retval = sysfs_create_file(&mod->mkobj->kobj, &a->attr);
+	if (!retval)
+		mod->mkobj->num_attributes++;
+	return retval;
+}
+
 #ifdef CONFIG_MODULE_UNLOAD
 /* Init the unload section of the module. */
 static void module_unload_init(struct module *mod)
@@ -502,22 +518,6 @@
 	struct stopref sref = { mod, flags, forced };
 
 	return stop_machine_run(__try_stop_module, &sref, NR_CPUS);
-}
-
-static int add_attribute(struct module *mod, struct kernel_param *kp)
-{
-	struct module_attribute *a;
-	int retval;
-
-	a = &mod->mkobj->attr[mod->mkobj->num_attributes];
-	a->attr.name = (char *)kp->name;
-	a->attr.owner = mod;
-	a->attr.mode = kp->perm;
-	a->param = kp;
-	retval = sysfs_create_file(&mod->mkobj->kobj, &a->attr);
-	if (!retval)
-		mod->mkobj->num_attributes++;
-	return retval;
 }
 
 unsigned int module_refcount(struct module *mod)
author
#14 lore raw

ChangeSet 1.1587.5.24, 2004/05/11 14:31:21-07:00, [email protected]

[PATCH] Add class support to drivers/net/wan/cosa.c

This patch adds sysfs class support to the Cosa driver. I have verified it compiles but do not have the hardware to test it. If someone could that would be helpful.

 drivers/net/wan/cosa.c |   41 ++++++++++++++++++++++++++++++++++-------
 1 files changed, 34 insertions(+), 7 deletions(-)
drivers/net/wan/cosa.c +34 -7
diff -Nru a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
@@ -93,6 +93,7 @@
 #include <linux/netdevice.h>
 #include <linux/spinlock.h>
 #include <linux/smp_lock.h>
+#include <linux/device.h>
 
 #undef COSA_SLOW_IO	/* for testing purposes only */
 #undef REALLY_SLOW_IO
@@ -233,6 +234,9 @@
 /* IRQ can be safely autoprobed */
 static int irq[MAX_CARDS+1] = { -1, -1, -1, -1, -1, -1, 0, };
 
+/* for class stuff*/
+static struct class_simple *cosa_class;
+
 #ifdef MODULE
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_CARDS) "i");
 MODULE_PARM_DESC(io, "The I/O bases of the COSA or SRP cards");
@@ -359,7 +363,7 @@
 
 static int __init cosa_init(void)
 {
-	int i;
+	int i, err = 0;
 
 	printk(KERN_INFO "cosa v1.08 (c) 1997-2000 Jan Kasprzak <[email protected]>\n");
 #ifdef CONFIG_SMP
@@ -369,12 +373,14 @@
 		if (register_chrdev(cosa_major, "cosa", &cosa_fops)) {
 			printk(KERN_WARNING "cosa: unable to get major %d\n",
 				cosa_major);
-			return -EIO;
+			err = -EIO;
+			goto out;
 		}
 	} else {
 		if (!(cosa_major=register_chrdev(0, "cosa", &cosa_fops))) {
 			printk(KERN_WARNING "cosa: unable to register chardev\n");
-			return -EIO;
+			err = -EIO;
+			goto out;
 		}
 	}
 	for (i=0; i<MAX_CARDS; i++)
@@ -384,15 +390,33 @@
 	if (!nr_cards) {
 		printk(KERN_WARNING "cosa: no devices found.\n");
 		unregister_chrdev(cosa_major, "cosa");
-		return -ENODEV;
+		err = -ENODEV;
+		goto out;
 	}
 	devfs_mk_dir("cosa");
+	cosa_class = class_simple_create(THIS_MODULE, "cosa");
+	if (IS_ERR(cosa_class)) {
+		err = PTR_ERR(cosa_class);
+		goto out_chrdev;
+	}
 	for (i=0; i<nr_cards; i++) {
-		devfs_mk_cdev(MKDEV(cosa_major, i),
+		class_simple_device_add(cosa_class, MKDEV(cosa_major, i),
+				NULL, "cosa%d", i);
+		err = devfs_mk_cdev(MKDEV(cosa_major, i),
 				S_IFCHR|S_IRUSR|S_IWUSR,
 				"cosa/%d", i);
+		if (err) {
+			class_simple_device_remove(MKDEV(cosa_major, i));
+			goto out_chrdev;		
+		}
 	}
-	return 0;
+	err = 0;
+	goto out;
+	
+out_chrdev:
+	unregister_chrdev(cosa_major, "cosa");
+out:
+	return err;
 }
 module_init(cosa_init);
 
@@ -402,8 +426,11 @@
 	int i;
 	printk(KERN_INFO "Unloading the cosa module\n");
 
-	for (i=0; i<nr_cards; i++)
+	for (i=0; i<nr_cards; i++) {
+		class_simple_device_remove(MKDEV(cosa_major, i));
 		devfs_remove("cosa/%d", i);
+	}
+	class_simple_destroy(cosa_class);
 	devfs_remove("cosa");
 	for (cosa=cosa_cards; nr_cards--; cosa++) {
 		/* Clean up the per-channel data */
author
#15 lore raw

ChangeSet 1.1587.5.25, 2004/05/11 16:31:46-07:00, [email protected]

[PATCH] kobject_set_name - error handling

1) kobject_set_name-cleanup-01.patch

This patch corrects the following by checking the reutrn code from kobject_set_name().

bus_add_driver()
bus_register()
sys_dev_register()

o The following patch cleansup the kobject_set_name() users. Basically checking return code from kobject_set_name(). There can be error returns like -ENOMEM or -EFAULT from kobject_set_name() if the name length exceeds KOBJ_NAME_LEN.

 drivers/base/bus.c |   11 +++++++++--
 drivers/base/sys.c |    5 ++++-
 2 files changed, 13 insertions(+), 3 deletions(-)
drivers/base/bus.c +9 -2
diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c
@@ -451,7 +451,11 @@
 
 	if (bus) {
 		pr_debug("bus %s: add driver %s\n",bus->name,drv->name);
-		kobject_set_name(&drv->kobj,drv->name);
+		error = kobject_set_name(&drv->kobj,drv->name);
+		if (error) {
+			put_bus(bus);
+			return error;
+		}
 		drv->kobj.kset = &bus->drivers;
 		if ((error = kobject_register(&drv->kobj))) {
 			put_bus(bus);
@@ -557,7 +561,10 @@
 {
 	int retval;
 
-	kobject_set_name(&bus->subsys.kset.kobj,bus->name);
+	retval = kobject_set_name(&bus->subsys.kset.kobj,bus->name);
+	if (retval)
+		goto out;
+
 	subsys_set_kset(bus,bus_subsys);
 	retval = subsystem_register(&bus->subsys);
 	if (retval) 
drivers/base/sys.c +4 -1
diff -Nru a/drivers/base/sys.c b/drivers/base/sys.c
@@ -180,8 +180,11 @@
 
 	/* But make sure we point to the right type for sysfs translation */
 	sysdev->kobj.ktype = &ktype_sysdev;
-	kobject_set_name(&sysdev->kobj,"%s%d",
+	error = kobject_set_name(&sysdev->kobj,"%s%d",
 			 kobject_name(&cls->kset.kobj),sysdev->id);
+	if (error)
+		return error;
+
 	pr_debug("Registering sys device '%s'\n",kobject_name(&sysdev->kobj));
 
 	/* Register the object */
author
#16 lore raw

ChangeSet 1.1587.5.26, 2004/05/11 16:35:42-07:00, [email protected]

[PATCH] fix dev_printk to work even in the absence of an attached driver

 include/linux/device.h |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)
include/linux/device.h +1 -1
diff -Nru a/include/linux/device.h b/include/linux/device.h
@@ -400,7 +400,7 @@
 
 /* debugging and troubleshooting/diagnostic helpers. */
 #define dev_printk(level, dev, format, arg...)	\
-	printk(level "%s %s: " format , (dev)->driver->name , (dev)->bus_id , ## arg)
+	printk(level "%s %s: " format , (dev)->driver ? (dev)->driver->name : "" , (dev)->bus_id , ## arg)
 
 #ifdef DEBUG
 #define dev_dbg(dev, format, arg...)		\
author
#17 lore raw

ChangeSet 1.1587.5.27, 2004/05/11 16:43:50-07:00, [email protected]

[PATCH] kobject/sysfs race fix

The following patch fixes the race involved between unregistering a kobject and simultaneously opeing a corresponding attribute file in sysfs.

Ideally sysfs should take a ref. to the kobject as long as it has dentries referring to the kobjects, but because of current limitations in module/kobject ref counting, sysfs's pinning of kobject leads to hang/delays in rmmod of certain modules. The patch checks for unhashed dentries in check_perm() while opening a sysfs file. If the dentry is still hashed then it goes ahead and takes the ref to kobject. This done under the per dentry lock. It does this in the inline routine sysfs_get_kobject(dentry).

 fs/sysfs/bin.c   |    2 +-
 fs/sysfs/file.c  |    2 +-
 fs/sysfs/sysfs.h |   13 +++++++++++++
 3 files changed, 15 insertions(+), 2 deletions(-)
fs/sysfs/bin.c +1 -1
diff -Nru a/fs/sysfs/bin.c b/fs/sysfs/bin.c
@@ -94,7 +94,7 @@
 
 static int open(struct inode * inode, struct file * file)
 {
-	struct kobject * kobj = kobject_get(file->f_dentry->d_parent->d_fsdata);
+	struct kobject *kobj = sysfs_get_kobject(file->f_dentry->d_parent);
 	struct bin_attribute * attr = file->f_dentry->d_fsdata;
 	int error = -EINVAL;
 
fs/sysfs/file.c +1 -1
diff -Nru a/fs/sysfs/file.c b/fs/sysfs/file.c
@@ -238,7 +238,7 @@
 
 static int check_perm(struct inode * inode, struct file * file)
 {
-	struct kobject * kobj = kobject_get(file->f_dentry->d_parent->d_fsdata);
+	struct kobject *kobj = sysfs_get_kobject(file->f_dentry->d_parent);
 	struct attribute * attr = file->f_dentry->d_fsdata;
 	struct sysfs_buffer * buffer;
 	struct sysfs_ops * ops = NULL;
fs/sysfs/sysfs.h +13 -0
diff -Nru a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
@@ -11,3 +11,16 @@
 
 extern int sysfs_create_subdir(struct kobject *, const char *, struct dentry **);
 extern void sysfs_remove_subdir(struct dentry *);
+
+
+static inline struct kobject *sysfs_get_kobject(struct dentry *dentry)
+{
+	struct kobject * kobj = NULL;
+
+	spin_lock(&dentry->d_lock);
+	if (!d_unhashed(dentry))
+		kobj = kobject_get(dentry->d_fsdata);
+	spin_unlock(&dentry->d_lock);
+
+	return kobj;
+}
author
#18 lore raw

ChangeSet 1.1587.5.28, 2004/05/14 12:12:11-07:00, [email protected]

[PATCH] add ibmasm driver warning message

[note, I changed this a bit to be nicer on the system log, greg k-h]

 drivers/misc/Kconfig         |    8 +++++++-
 drivers/misc/ibmasm/module.c |    7 +++++++
 2 files changed, 14 insertions(+), 1 deletion(-)
drivers/misc/Kconfig +7 -1
diff -Nru a/drivers/misc/Kconfig b/drivers/misc/Kconfig
@@ -6,7 +6,7 @@
 
 config IBM_ASM
 	tristate "Device driver for IBM RSA service processor"
-	depends on X86
+	depends on X86 && EXPERIMENTAL
 	default n
 	---help---
 	  This option enables device driver support for in-band access to the
@@ -20,6 +20,12 @@
 	  this feature serial driver support (CONFIG_SERIAL_8250) must be
 	  enabled.
 	  
+	  WARNING: This software may not be supported or function
+	  correctly on your IBM server. Please consult the IBM ServerProven
+	  website http://www.pc.ibm/ww/eserver/xseries/serverproven for
+	  information on the specific driver level and support statement
+	  for your IBM server.
+
 
 	  If unsure, say N.
 
drivers/misc/ibmasm/module.c +7 -0
diff -Nru a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c
@@ -126,6 +126,13 @@
 
 	ibmasm_register_uart(sp);
 
+	dev_printk(KERN_DEBUG, &pdev->dev, "WARNING: This software may not be supported or function\n");
+	dev_printk(KERN_DEBUG, &pdev->dev, "correctly on your IBM server. Please consult the IBM\n");
+	dev_printk(KERN_DEBUG, &pdev->dev, "ServerProven website\n");
+	dev_printk(KERN_DEBUG, &pdev->dev, "http://www.pc.ibm.com/ww/eserver/xseries/serverproven\n");
+	dev_printk(KERN_DEBUG, &pdev->dev, "for information on the specific driver level and support\n");
+	dev_printk(KERN_DEBUG, &pdev->dev, "statement for your IBM server.\n");
+
 	return 0;
 
 error_send_message:
author
#19 lore raw

ChangeSet 1.1587.5.29, 2004/05/14 12:13:00-07:00, [email protected]

[PATCH] sysfs_rename_dir-cleanup

o The following patch cleans up sysfs_rename_dir(). It now checks the return code of kobject_set_name() and propagates the error code to its callers. Because of this there are changes in the following two APIs. Both return int instead of void.

int sysfs_rename_dir(struct kobject * kobj, const char *new_name) int kobject_rename(struct kobject * kobj, char *new_name)

 drivers/base/class.c    |    6 ++++--
 fs/sysfs/dir.c          |   19 ++++++++++++++-----
 include/linux/kobject.h |    2 +-
 include/linux/sysfs.h   |    2 +-
 lib/kobject.c           |   10 +++++++---
 net/core/dev.c          |   16 ++++++++++------
 6 files changed, 37 insertions(+), 18 deletions(-)
drivers/base/class.c +4 -2
diff -Nru a/drivers/base/class.c b/drivers/base/class.c
@@ -361,6 +361,8 @@
 
 int class_device_rename(struct class_device *class_dev, char *new_name)
 {
+	int error = 0;
+
 	class_dev = class_device_get(class_dev);
 	if (!class_dev)
 		return -EINVAL;
@@ -370,11 +372,11 @@
 
 	strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN);
 
-	kobject_rename(&class_dev->kobj, new_name);
+	error = kobject_rename(&class_dev->kobj, new_name);
 
 	class_device_put(class_dev);
 
-	return 0;
+	return error;
 }
 
 struct class_device * class_device_get(struct class_device *class_dev)
fs/sysfs/dir.c +14 -5
diff -Nru a/fs/sysfs/dir.c b/fs/sysfs/dir.c
@@ -154,24 +154,33 @@
 	dput(dentry);
 }
 
-void sysfs_rename_dir(struct kobject * kobj, const char *new_name)
+int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
 {
+	int error = 0;
 	struct dentry * new_dentry, * parent;
 
 	if (!strcmp(kobject_name(kobj), new_name))
-		return;
+		return -EINVAL;
 
 	if (!kobj->parent)
-		return;
+		return -EINVAL;
 
 	parent = kobj->parent->dentry;
 
 	down(&parent->d_inode->i_sem);
 
 	new_dentry = sysfs_get_dentry(parent, new_name);
-	d_move(kobj->dentry, new_dentry);
-	kobject_set_name(kobj,new_name);
+	if (!IS_ERR(new_dentry)) {
+  		if (!new_dentry->d_inode) {
+			error = kobject_set_name(kobj,new_name);
+			if (!error)
+				d_move(kobj->dentry, new_dentry);
+		}
+		dput(new_dentry);
+	}
 	up(&parent->d_inode->i_sem);	
+
+	return error;
 }
 
 EXPORT_SYMBOL(sysfs_create_dir);
include/linux/kobject.h +1 -1
diff -Nru a/include/linux/kobject.h b/include/linux/kobject.h
@@ -48,7 +48,7 @@
 extern int kobject_add(struct kobject *);
 extern void kobject_del(struct kobject *);
 
-extern void kobject_rename(struct kobject *, char *new_name);
+extern int kobject_rename(struct kobject *, char *new_name);
 
 extern int kobject_register(struct kobject *);
 extern void kobject_unregister(struct kobject *);
include/linux/sysfs.h +1 -1
diff -Nru a/include/linux/sysfs.h b/include/linux/sysfs.h
@@ -44,7 +44,7 @@
 extern void
 sysfs_remove_dir(struct kobject *);
 
-extern void
+extern int
 sysfs_rename_dir(struct kobject *, const char *new_name);
 
 extern int
lib/kobject.c +7 -3
diff -Nru a/lib/kobject.c b/lib/kobject.c
@@ -385,13 +385,17 @@
  *	@new_name: object's new name
  */
 
-void kobject_rename(struct kobject * kobj, char *new_name)
+int kobject_rename(struct kobject * kobj, char *new_name)
 {
+	int error = 0;
+
 	kobj = kobject_get(kobj);
 	if (!kobj)
-		return;
-	sysfs_rename_dir(kobj, new_name);
+		return -EINVAL;
+	error = sysfs_rename_dir(kobj, new_name);
 	kobject_put(kobj);
+
+	return error;
 }
 
 /**
net/core/dev.c +10 -6
diff -Nru a/net/core/dev.c b/net/core/dev.c
@@ -792,6 +792,8 @@
  */
 int dev_change_name(struct net_device *dev, char *newname)
 {
+	int err = 0;
+
 	ASSERT_RTNL();
 
 	if (dev->flags & IFF_UP)
@@ -801,7 +803,7 @@
 		return -EINVAL;
 
 	if (strchr(newname, '%')) {
-		int err = dev_alloc_name(dev, newname);
+		err = dev_alloc_name(dev, newname);
 		if (err < 0)
 			return err;
 		strcpy(newname, dev->name);
@@ -811,12 +813,14 @@
 	else
 		strlcpy(dev->name, newname, IFNAMSIZ);
 
-	hlist_del(&dev->name_hlist);
-	hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name));
+	err = class_device_rename(&dev->class_dev, dev->name);
+	if (!err) {
+		hlist_del(&dev->name_hlist);
+		hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name));
+		notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev);
+	}
 
-	class_device_rename(&dev->class_dev, dev->name);
-	notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev);
-	return 0;
+	return err;
 }
 
 /**
#20 lore raw

zombies with AMD64 and 32 bit userspace with 2.6

In reply to Greg KH

I have a box I am testing in my lab which is a dual opteron with a complete 32 bit userspace (debian based) with a 64 bit kernel. when running a stress test with a highly forking workload I am running into a situation where it generates a lot of zombies

the test is a simple forking proxy that receives connections from one machine (running apache benchmark) and forwards them to anothr machine (running apache). for <~30,000 requests the machine keeps up with no problem (apache is the bottlneck here at ~3500 requests/sec), but if I try to do a test with more then about 30,000 requests in it the box starts to generate zombie processes (eventually running into the max processes limit and stopping)

the smaller tests leave no zombies at all and can be run multiple times without a problem (although I have not run them back to back, so there is a substantial bit of time between tests)

I have been able to duplicate this with the 2.6.4 and 2.6.6 kernels.

running the exact same test (same binaries except for the kernel) on a dual athlon box has no problems (the dual athlon box becomes the bottleneck at ~2500 connections/sec) and has survived 10,000,000 connection tests.

David Lang

Signature · 3 lines
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it." - Brian W. Kernighan