Driver Core patches for 2.6.8-rc1
Subsystems (8)
PATCH 1/1 Driver Core patches for 2.6.8-rc1
Hi,
Here are a some driver core and assorted patches for 2.6.8-rc1. They contain:
- some driver core fixes.
- a raw.c fix
- a root_plug.c fix
- add a new attribute for block devices.
Most of these have all been in the last few -mm tree 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/Kconfig | 2 - drivers/base/bus.c | 39 ++++++++++++++++++++- drivers/base/core.c | 10 +++++ drivers/base/driver.c | 19 ++++++++++ drivers/base/platform.c | 72 +++++++++++++++++++++++++++++++++++++-- drivers/block/genhd.c | 11 +++++ drivers/char/raw.c | 15 ++++---- drivers/pci/hotplug/rpaphp_vio.c | 9 ++++ include/linux/device.h | 4 ++ lib/kobject.c | 7 ++- security/root_plug.c | 6 +-- 11 files changed, 175 insertions(+), 19 deletions(-)
-----
<mika:osdl.org>:
o Upgrade security/root_plug.c to new module parameter syntax
Andrew Morton:
o raw.c cleanups
Dmitry Torokhov:
o Driver core: Fix OOPS in device_platform_unregister
o Driver core: add driver_find helper to find a driver by its name
o Driver core: kset_find_obj should increment refcount of the found object
o Driver core: add default driver attributes to struct bus_type
o Driver core: add platform_device_register_simple to register platform
Greg Kroah-Hartman:
o Driver Core: remove extra space in Kconfig file
Olaf Hering:
o add removeable sysfs block device attribute
PATCH 1/1 Driver Core patches for 2.6.8-rc1
ChangeSet 1.1757.22.6, 2004/06/22 16:24:54-07:00, [email protected]
[PATCH] raw.c cleanups
- pass the raw_config_request by reference, not by value.
- fix whitespace drainbamage
drivers/char/raw.c | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-)
drivers/char/raw.c +8 -7
@@ -125,11 +125,11 @@return ioctl_by_bdev (bdev, command, arg); } -static void bind_device (struct raw_config_request rq) +static void bind_device (struct raw_config_request *rq) { -class_simple_device_remove (MKDEV (RAW_MAJOR , rq.raw_minor)); -class_simple_device_add (raw_class,MKDEV (RAW_MAJOR , rq.raw_minor), -NULL ,"raw%d" , rq.raw_minor); +class_simple_device_remove (MKDEV (RAW_MAJOR , rq->raw_minor)); +class_simple_device_add (raw_class,MKDEV (RAW_MAJOR , rq->raw_minor), +NULL ,"raw%d" , rq->raw_minor); }/*
@@ -200,15 +200,16 @@if (rq.block_major ==0 && rq.block_minor ==0 ) {/* unbind */ rawdev->binding =NULL ; -class_simple_device_remove (MKDEV (RAW_MAJOR , rq.raw_minor)); +class_simple_device_remove (MKDEV (RAW_MAJOR , + rq.raw_minor)); }else { rawdev->binding =bdget (dev);if (rawdev->binding ==NULL ) err = -ENOMEM ;else {__module_get (THIS_MODULE ); -bind_device (rq); - } +bind_device (&rq); + } }up (&raw_mutex); }else {
ChangeSet 1.1757.22.7, 2004/06/30 09:59:10-07:00, [email protected]
Driver Core: remove extra space in Kconfig file.
drivers/base/Kconfig | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-)
drivers/base/Kconfig +1 -1
@@ -18,7 +18,7 @@ the kernel tree does. config DEBUG_DRIVER - bool "Driver Core verbose debug messages" + bool "Driver Core verbose debug messages" depends on DEBUG_KERNEL help Say Y here if you want the Driver core to produce a bunch of
ChangeSet 1.1784.12.2, 2004/07/08 16:40:09-07:00, [email protected]
[PATCH] Driver core: add platform_device_register_simple to register platform
Add platform_device_register_simple to register platform devices requiring minimal resource and memory management. The device will have standard release function that just frees memory occupied by the platform device. By having release function in the driver core modules using such devices can be unloaded without waiting for the last reference to the device to be dropped.
drivers/base/platform.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/device.h | 2 + 2 files changed, 70 insertions(+)
drivers/base/platform.c +68 -0
@@ -15,6 +15,7 @@#include <linux/init.h> #include <linux/dma-mapping.h> #include <linux/bootmem.h> +#include <linux/err.h> struct device platform_bus = { .bus_id ="platform" ,
@@ -133,6 +134,13 @@return ret; } +/** +* platform_device_unregister - remove a platform-level device +* @dev: platform device we're removing +* +* Note that this function will also release all memory- and port-based +* resources owned by the device (@dev->resource). +*/ void platform_device_unregister (struct platform_device * pdev) {int i;
@@ -148,6 +156,65 @@ } } +struct platform_object { +struct platform_device pdev; +struct resource resources[0 ]; +}; + +static void platform_device_release_simple (struct device *dev) +{ +struct platform_device *pdev =to_platform_device (dev); + +kfree (container_of(pdev ,struct platform_object ,pdev )); +} + +/** +* platform_device_register_simple +* @name: base name of the device we're adding +* @id: instance id +* @res: set of resources that needs to be allocated for the device +* @num: number of resources +* +* This function creates a simple platform device that requires minimal +* resource and memory management. Canned release function freeing +* memory allocated for the device allows drivers using such devices +* to be unloaded iwithout waiting for the last reference to the device +* to be dropped. +*/ +struct platform_device *platform_device_register_simple (char *name,unsigned int id, +struct resource *res,unsigned int num) +{ +struct platform_object *pobj; +int retval; + + pobj =kmalloc (sizeof (struct platform_object ) +sizeof (struct resource ) * num,GFP_KERNEL ); +if (!pobj) { + retval = -ENOMEM ; + goto error; + } + +memset (pobj,0 ,sizeof (*pobj)); + pobj->pdev.name = name; + pobj->pdev.id = id; + pobj->pdev.dev.release = platform_device_release_simple; + +if (num) { +memcpy (pobj->resources, res,sizeof (struct resource ) * num); + pobj->pdev.resource = pobj->resources; + pobj->pdev.num_resources = num; + } + + retval =platform_device_register (&pobj->pdev); +if (retval) + goto error; + +return &pobj->pdev; + +error: +kfree (pobj); +return ERR_PTR (retval); +} +/** * platform_match - bind platform device to platform driver.
@@ -237,6 +304,7 @@EXPORT_SYMBOL (platform_bus);EXPORT_SYMBOL (platform_bus_type);EXPORT_SYMBOL (platform_device_register); +EXPORT_SYMBOL (platform_device_register_simple);EXPORT_SYMBOL (platform_device_unregister);EXPORT_SYMBOL (platform_get_irq);EXPORT_SYMBOL (platform_get_resource);
include/linux/device.h +2 -0
@@ -381,6 +381,8 @@extern int platform_get_irq (struct platform_device *,unsigned int );extern int platform_add_devices (struct platform_device **,int ); +extern struct platform_device *platform_device_register_simple (char *,unsigned int ,struct resource *,unsigned int ); +/* drivers/base/power.c */ extern void device_shutdown (void );
ChangeSet 1.1784.12.3, 2004/07/08 16:41:56-07:00, [email protected]
[PATCH] Driver core: add default driver attributes to struct bus_type
drivers/base/bus.c | 37 +++++++++++++++++++++++++++++++++++-- include/linux/device.h | 1 + 2 files changed, 36 insertions(+), 2 deletions(-)
drivers/base/bus.c +35 -2
@@ -415,7 +415,7 @@static void device_remove_attrs (struct bus_type * bus,struct device * dev) {int i; - +if (bus->dev_attrs) {for (i =0 ;attr_name (bus->dev_attrs[i]); i++)device_remove_file (dev,&bus->dev_attrs[i]);
@@ -471,6 +471,37 @@ } } +static int driver_add_attrs (struct bus_type * bus,struct device_driver * drv) +{ +int error =0 ; +int i; + +if (bus->drv_attrs) { +for (i =0 ;attr_name (bus->drv_attrs[i]); i++) { + error =driver_create_file (drv, &bus->drv_attrs[i]); +if (error) + goto Err; + } + } + Done: +return error; + Err: +while (--i >=0 ) +driver_remove_file (drv, &bus->drv_attrs[i]); + goto Done; +} + + +static void driver_remove_attrs (struct bus_type * bus,struct device_driver * drv) +{ +int i; + +if (bus->drv_attrs) { +for (i =0 ;attr_name (bus->drv_attrs[i]); i++) +driver_remove_file (drv, &bus->drv_attrs[i]); + } +} +/** * bus_add_driver - Add a driver to the bus.
@@ -499,6 +530,7 @@driver_attach (drv);up_write (&bus->subsys.rwsem); +driver_add_attrs (bus, drv); }return error; }
@@ -516,6 +548,7 @@void bus_remove_driver (struct device_driver * drv) {if (drv->bus) { +driver_remove_attrs (drv->bus, drv);down_write (&drv->bus->subsys.rwsem);pr_debug ("bus %s: remove driver %s\n" , drv->bus->name, drv->name);driver_detach (drv);
@@ -610,7 +643,7 @@static void bus_remove_attrs (struct bus_type * bus) {int i; - +if (bus->bus_attrs) {for (i =0 ;attr_name (bus->bus_attrs[i]); i++)bus_remove_file (bus,&bus->bus_attrs[i]);
include/linux/device.h +1 -0
@@ -56,6 +56,7 @@struct bus_attribute * bus_attrs;struct device_attribute * dev_attrs; +struct driver_attribute * drv_attrs;int (*match)(struct device * dev,struct device_driver * drv);struct device * (*add) (struct device * parent,char * bus_id);
ChangeSet 1.1784.12.4, 2004/07/08 16:46:10-07:00, [email protected]
[PATCH] Driver core: kset_find_obj should increment refcount of the found object
kset_find_obj should increment refcount of the found object so users of the function can safely use returned object
drivers/base/bus.c | 2 ++ drivers/base/core.c | 10 ++++++++++ drivers/pci/hotplug/rpaphp_vio.c | 9 ++++++++- lib/kobject.c | 7 ++++--- 4 files changed, 24 insertions(+), 4 deletions(-)
drivers/base/bus.c +2 -0
@@ -607,6 +607,8 @@* * Call kset_find_obj() to iterate over list of buses to * find a bus by name. Return bus if found. +* +* Note that kset_find_obj increments bus' reference count. */ struct bus_type *find_bus (char * name)
drivers/base/core.c +10 -0
@@ -378,6 +378,16 @@return error; } +/** +* device_find - locate device on a bus by name. +* @name: name of the device. +* @bus: bus to scan for the device. +* +* Call kset_find_obj() to iterate over list of devices on +* a bus to find device by name. Return device if found. +* +* Note that kset_find_obj increments device's reference count. +*/ struct device *device_find (const char *name,struct bus_type *bus) {struct kobject *k =kset_find_obj (&bus->devices, name);
drivers/pci/hotplug/rpaphp_vio.c +8 -1
@@ -86,7 +86,14 @@ } slot->dev_type =VIO_DEV ; slot->dev.vio_dev =vio_find_node (dn); -if (!slot->dev.vio_dev) +if (slot->dev.vio_dev) { +/* +* rpaphp is the only owner of vio devices and +* does not need extra reference taken by +* vio_find_node +*/ +put_device (&slot->dev.vio_dev->dev); + }else slot->dev.vio_dev =vio_register_device_node (dn);if (slot->dev.vio_dev) slot->state =CONFIGURED ;
lib/kobject.c +4 -3
@@ -537,7 +537,8 @@* @name: object's name. * * Lock kset via @kset->subsys, and iterate over @kset->list, -* looking for a matching kobject. Return object if found. +* looking for a matching kobject. If matching object is found +* take a reference and return the object. */ struct kobject *kset_find_obj (struct kset * kset,const char * name)
@@ -548,8 +549,8 @@down_read (&kset->subsys->rwsem);list_for_each (entry,&kset->list) {struct kobject * k =to_kobj (entry); -if (kobject_name (k) && (!strcmp (kobject_name (k),name))) { - ret = k; +if (kobject_name (k) && !strcmp (kobject_name (k),name)) { + ret =kobject_get (k);break ; } }
ChangeSet 1.1784.12.5, 2004/07/08 16:46:47-07:00, [email protected]
[PATCH] Driver core: add driver_find helper to find a driver by its name
drivers/base/driver.c | 19 +++++++++++++++++++ include/linux/device.h | 1 + 2 files changed, 20 insertions(+)
drivers/base/driver.c +19 -0
@@ -111,10 +111,29 @@up (&drv->unload_sem); } +/** +* driver_find - locate driver on a bus by its name. +* @name: name of the driver. +* @bus: bus to scan for the driver. +* +* Call kset_find_obj() to iterate over list of drivers on +* a bus to find driver by name. Return driver if found. +* +* Note that kset_find_obj increments driver's reference count. +*/ +struct device_driver *driver_find (const char *name,struct bus_type *bus) +{ +struct kobject *k =kset_find_obj (&bus->drivers, name); +if (k) +return to_drv (k); +return NULL ; +} +EXPORT_SYMBOL (driver_register);EXPORT_SYMBOL (driver_unregister);EXPORT_SYMBOL (get_driver);EXPORT_SYMBOL (put_driver); +EXPORT_SYMBOL (driver_find);EXPORT_SYMBOL (driver_create_file);EXPORT_SYMBOL (driver_remove_file);
include/linux/device.h +1 -0
@@ -120,6 +120,7 @@extern struct device_driver *get_driver (struct device_driver * drv);extern void put_driver (struct device_driver * drv); +extern struct device_driver *driver_find (const char *name,struct bus_type *bus);/* driverfs interface for exporting driver attributes */
ChangeSet 1.1784.12.6, 2004/07/14 16:09:44-07:00, [email protected]
[PATCH] Driver core: Fix OOPS in device_platform_unregister
Driver core: platform_device_unregister should release resources first
and only then call device_unregister, otherwise if there are no more references to the device it will be freed and the fucntion will try to access freed memory.
drivers/base/platform.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/base/platform.c +2 -2
@@ -146,13 +146,13 @@int i;if (pdev) { -device_unregister (&pdev->dev); -for (i =0 ; i < pdev->num_resources; i++) {struct resource *r = &pdev->resource[i];if (r->flags & (IORESOURCE_MEM |IORESOURCE_IO ))release_resource (r); } + +device_unregister (&pdev->dev); } }
ChangeSet 1.1784.12.7, 2004/07/14 16:19:51-07:00, [email protected]
[PATCH] Upgrade security/root_plug.c to new module parameter syntax
Hi again,
Still doing my compile, and got this:
CC [M] security/root_plug.osecurity/root_plug.c:39: warning: missing initializer security/root_plug.c:39: warning: (near initialization for __parm_vendor_id.addr') security/root_plug.c:42: warning: missing initializer security/root_plug.c:42: warning: (near initialization for __parm_product_id.addr') security/root_plug.c:48: warning: missing initializer security/root_plug.c:48: warning: (near initialization for `__parm_debug.addr')
Simply upgrading root_plug to use the new module parameter syntax seemed to do the trick. I made the debug writable, the others just readable to root.
security/root_plug.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
security/root_plug.c +3 -3
@@ -36,16 +36,16 @@static int vendor_id =0x0557 ;static int product_id =0x2008 ; -MODULE_PARM (vendor_id,"h" ); +module_param (vendor_id, uint,0400 );MODULE_PARM_DESC (vendor_id,"USB Vendor ID of device to look for" ); -MODULE_PARM (product_id,"h" ); +module_param (product_id, uint,0400 );MODULE_PARM_DESC (product_id,"USB Product ID of device to look for" );/* should we print out debug messages */ static int debug =0 ; -MODULE_PARM (debug,"i" ); +module_param (debug, bool,0600 );MODULE_PARM_DESC (debug,"Debug enabled or not" );#if defined(CONFIG_SECURITY_ROOTPLUG_MODULE )
ChangeSet 1.1784.12.8, 2004/07/14 16:20:29-07:00, [email protected]
[PATCH] add removeable sysfs block device attribute
This patch adds a /block/*/removeable sysfs attribute. A value of 1 indicates the media can change anytime. This is a hint for userland to poll such devices for possible media changes, and leave all others alone. There is currently no way to see if a connected usb-storage device is a disk or a card reader. It will also show 1 for CD and ZIP drives.
It was done by Patrick Mansfield a while ago. I can probably not sigh-off his work. ;)
drivers/block/genhd.c | 11 +++++++++++ 1 files changed, 11 insertions(+)
drivers/block/genhd.c +11 -0
@@ -352,6 +352,12 @@ {return sprintf (page,"%d\n" , disk->minors); } +static ssize_t disk_removable_read (struct gendisk * disk,char *page) +{ +return sprintf (page,"%d\n" , + (disk->flags &GENHD_FL_REMOVABLE ?1 :0 )); + +}static ssize_t disk_size_read (struct gendisk * disk,char *page) {return sprintf (page,"%llu\n" , (unsigned long long )get_capacity (disk));
@@ -384,6 +390,10 @@ .attr = {.name = "range", .mode = S_IRUGO }, .show = disk_range_read }; +static struct disk_attribute disk_attr_removable = { + .attr = {.name ="removable" , .mode =S_IRUGO }, + .show = disk_removable_read +};static struct disk_attribute disk_attr_size = { .attr = {.name ="size" , .mode =S_IRUGO }, .show = disk_size_read
@@ -396,6 +406,7 @@static struct attribute * default_attrs[] = { &disk_attr_dev.attr, &disk_attr_range.attr, + &disk_attr_removable.attr, &disk_attr_size.attr, &disk_attr_stat.attr,NULL ,