aboutsummaryrefslogtreecommitdiffstats
path: root/driver
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-04-24 15:34:09 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2006-04-24 15:34:09 -0700
commit4a076f7ffaae89e3f1c2ffecd147b79ae1e0bd9d (patch)
tree86bd89054c44670a82f2cfa1f7373cfc0898245c /driver
parent67c67eb735d985aadf3d63200ebb59147b9fa100 (diff)
downloadpatches-4a076f7ffaae89e3f1c2ffecd147b79ae1e0bd9d.tar.gz
lotsa patches added
Diffstat (limited to 'driver')
-rw-r--r--driver/class-device-add-attribute_group-creation.patch97
-rw-r--r--driver/frame-buffer-remove-cmap-sysfs-interface.patch126
-rw-r--r--driver/netdev-create-attribute_groups-with-class_device_add.patch128
3 files changed, 351 insertions, 0 deletions
diff --git a/driver/class-device-add-attribute_group-creation.patch b/driver/class-device-add-attribute_group-creation.patch
new file mode 100644
index 0000000000000..4bf2a0d9523f1
--- /dev/null
+++ b/driver/class-device-add-attribute_group-creation.patch
@@ -0,0 +1,97 @@
+From shemminger@osdl.org Fri Apr 21 13:03:59 2006
+Date: Fri, 21 Apr 2006 12:52:55 -0700
+From: Stephen Hemminger <shemminger@osdl.org>
+To: Greg KH <greg@kroah.com>, "David S. Miller" <davem@davemloft.net>
+Subject: class device: add attribute_group creation
+Message-ID: <20060421125255.3451959f@localhost.localdomain>
+
+Extend the support of attribute groups in class_device's to allow groups
+to be created as part of the registration process. This allows network device's
+to avoid race between registration and creating groups.
+
+Note that unlike attributes that are a property of the class object, the groups
+are a property of the class_device object. This is done because there are different
+types of network devices (wireless for example).
+
+Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/base/class.c | 32 ++++++++++++++++++++++++++++++++
+ include/linux/device.h | 2 ++
+ 2 files changed, 34 insertions(+)
+
+--- gregkh-2.6.orig/drivers/base/class.c
++++ gregkh-2.6/drivers/base/class.c
+@@ -456,6 +456,35 @@ static void class_device_remove_attrs(st
+ }
+ }
+
++static int class_device_add_groups(struct class_device * cd)
++{
++ int i;
++ int error = 0;
++
++ if (cd->groups) {
++ for (i = 0; cd->groups[i]; i++) {
++ error = sysfs_create_group(&cd->kobj, cd->groups[i]);
++ if (error) {
++ while (--i >= 0)
++ sysfs_remove_group(&cd->kobj, cd->groups[i]);
++ goto out;
++ }
++ }
++ }
++out:
++ return error;
++}
++
++static void class_device_remove_groups(struct class_device * cd)
++{
++ int i;
++ if (cd->groups) {
++ for (i = 0; cd->groups[i]; i++) {
++ sysfs_remove_group(&cd->kobj, cd->groups[i]);
++ }
++ }
++}
++
+ static ssize_t show_dev(struct class_device *class_dev, char *buf)
+ {
+ return print_dev_t(buf, class_dev->devt);
+@@ -559,6 +588,8 @@ int class_device_add(struct class_device
+ class_name);
+ }
+
++ class_device_add_groups(class_dev);
++
+ kobject_uevent(&class_dev->kobj, KOBJ_ADD);
+
+ /* notify any interfaces this device is now here */
+@@ -672,6 +703,7 @@ void class_device_del(struct class_devic
+ if (class_dev->devt_attr)
+ class_device_remove_file(class_dev, class_dev->devt_attr);
+ class_device_remove_attrs(class_dev);
++ class_device_remove_groups(class_dev);
+
+ kobject_uevent(&class_dev->kobj, KOBJ_REMOVE);
+ kobject_del(&class_dev->kobj);
+--- gregkh-2.6.orig/include/linux/device.h
++++ gregkh-2.6/include/linux/device.h
+@@ -200,6 +200,7 @@ extern int class_device_create_file(stru
+ * @node: for internal use by the driver core only.
+ * @kobj: for internal use by the driver core only.
+ * @devt_attr: for internal use by the driver core only.
++ * @groups: optional additional groups to be created
+ * @dev: if set, a symlink to the struct device is created in the sysfs
+ * directory for this struct class device.
+ * @class_data: pointer to whatever you want to store here for this struct
+@@ -228,6 +229,7 @@ struct class_device {
+ struct device * dev; /* not necessary, but nice to have */
+ void * class_data; /* class-specific data */
+ struct class_device *parent; /* parent of this child device, if there is one */
++ struct attribute_group ** groups; /* optional groups */
+
+ void (*release)(struct class_device *dev);
+ int (*uevent)(struct class_device *dev, char **envp,
diff --git a/driver/frame-buffer-remove-cmap-sysfs-interface.patch b/driver/frame-buffer-remove-cmap-sysfs-interface.patch
new file mode 100644
index 0000000000000..1df44994d6b8d
--- /dev/null
+++ b/driver/frame-buffer-remove-cmap-sysfs-interface.patch
@@ -0,0 +1,126 @@
+From jonsmirl@gmail.com Wed Apr 12 16:43:38 2006
+Message-ID: <9e4733910604121643u3cf7449dubac79e0869fe8712@mail.gmail.com>
+Date: Wed, 12 Apr 2006 19:43:35 -0400
+From: "Jon Smirl" <jonsmirl@gmail.com>
+To: "Greg KH" <gregkh@suse.de>
+Subject: Frame buffer: remove cmap sysfs interface
+
+Remove it as it does not work properly due to sysfs core changes.
+
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/video/fbsysfs.c | 92 +-----------------------------------------------
+ 1 file changed, 3 insertions(+), 89 deletions(-)
+
+--- gregkh-2.6.orig/drivers/video/fbsysfs.c
++++ gregkh-2.6/drivers/video/fbsysfs.c
+@@ -305,94 +305,6 @@ static ssize_t show_stride(struct class_
+ return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->fix.line_length);
+ }
+
+-/* Format for cmap is "%02x%c%4x%4x%4x\n" */
+-/* %02x entry %c transp %4x red %4x blue %4x green \n */
+-/* 256 rows at 16 chars equals 4096, the normal page size */
+-/* the code will automatically adjust for different page sizes */
+-static ssize_t store_cmap(struct class_device *class_device, const char *buf,
+- size_t count)
+-{
+- struct fb_info *fb_info = class_get_devdata(class_device);
+- int rc, i, start, length, transp = 0;
+-
+- if ((count > PAGE_SIZE) || ((count % 16) != 0))
+- return -EINVAL;
+-
+- if (!fb_info->fbops->fb_setcolreg && !fb_info->fbops->fb_setcmap)
+- return -EINVAL;
+-
+- sscanf(buf, "%02x", &start);
+- length = count / 16;
+-
+- for (i = 0; i < length; i++)
+- if (buf[i * 16 + 2] != ' ')
+- transp = 1;
+-
+- /* If we can batch, do it */
+- if (fb_info->fbops->fb_setcmap && length > 1) {
+- struct fb_cmap umap;
+-
+- memset(&umap, 0, sizeof(umap));
+- if ((rc = fb_alloc_cmap(&umap, length, transp)))
+- return rc;
+-
+- umap.start = start;
+- for (i = 0; i < length; i++) {
+- sscanf(&buf[i * 16 + 3], "%4hx", &umap.red[i]);
+- sscanf(&buf[i * 16 + 7], "%4hx", &umap.blue[i]);
+- sscanf(&buf[i * 16 + 11], "%4hx", &umap.green[i]);
+- if (transp)
+- umap.transp[i] = (buf[i * 16 + 2] != ' ');
+- }
+- rc = fb_info->fbops->fb_setcmap(&umap, fb_info);
+- fb_copy_cmap(&umap, &fb_info->cmap);
+- fb_dealloc_cmap(&umap);
+-
+- return rc ?: count;
+- }
+- for (i = 0; i < length; i++) {
+- u16 red, blue, green, tsp;
+-
+- sscanf(&buf[i * 16 + 3], "%4hx", &red);
+- sscanf(&buf[i * 16 + 7], "%4hx", &blue);
+- sscanf(&buf[i * 16 + 11], "%4hx", &green);
+- tsp = (buf[i * 16 + 2] != ' ');
+- if ((rc = fb_info->fbops->fb_setcolreg(start++,
+- red, green, blue, tsp, fb_info)))
+- return rc;
+-
+- fb_info->cmap.red[i] = red;
+- fb_info->cmap.blue[i] = blue;
+- fb_info->cmap.green[i] = green;
+- if (transp)
+- fb_info->cmap.transp[i] = tsp;
+- }
+- return count;
+-}
+-
+-static ssize_t show_cmap(struct class_device *class_device, char *buf)
+-{
+- struct fb_info *fb_info = class_get_devdata(class_device);
+- unsigned int i;
+-
+- if (!fb_info->cmap.red || !fb_info->cmap.blue ||
+- !fb_info->cmap.green)
+- return -EINVAL;
+-
+- if (fb_info->cmap.len > PAGE_SIZE / 16)
+- return -EINVAL;
+-
+- /* don't mess with the format, the buffer is PAGE_SIZE */
+- /* 256 entries at 16 chars per line equals 4096 = PAGE_SIZE */
+- for (i = 0; i < fb_info->cmap.len; i++) {
+- snprintf(&buf[ i * 16], PAGE_SIZE - i * 16, "%02x%c%4x%4x%4x\n", i + fb_info->cmap.start,
+- ((fb_info->cmap.transp && fb_info->cmap.transp[i]) ? '*' : ' '),
+- fb_info->cmap.red[i], fb_info->cmap.blue[i],
+- fb_info->cmap.green[i]);
+- }
+- return 16 * fb_info->cmap.len;
+-}
+-
+ static ssize_t store_blank(struct class_device *class_device, const char * buf,
+ size_t count)
+ {
+@@ -502,10 +414,12 @@ static ssize_t show_fbstate(struct class
+ return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->state);
+ }
+
++/* When cmap is added back in it should be a binary attribute
++ * not a text one. Consideration should also be given to converting
++ * fbdev to use configfs instead of sysfs */
+ static struct class_device_attribute class_device_attrs[] = {
+ __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp),
+ __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank),
+- __ATTR(color_map, S_IRUGO|S_IWUSR, show_cmap, store_cmap),
+ __ATTR(console, S_IRUGO|S_IWUSR, show_console, store_console),
+ __ATTR(cursor, S_IRUGO|S_IWUSR, show_cursor, store_cursor),
+ __ATTR(mode, S_IRUGO|S_IWUSR, show_mode, store_mode),
diff --git a/driver/netdev-create-attribute_groups-with-class_device_add.patch b/driver/netdev-create-attribute_groups-with-class_device_add.patch
new file mode 100644
index 0000000000000..2e03ee7bca403
--- /dev/null
+++ b/driver/netdev-create-attribute_groups-with-class_device_add.patch
@@ -0,0 +1,128 @@
+From shemminger@osdl.org Fri Apr 21 13:03:59 2006
+Date: Fri, 21 Apr 2006 12:54:38 -0700
+From: Stephen Hemminger <shemminger@osdl.org>
+To: Greg KH <greg@kroah.com>, "David S. Miller" <davem@davemloft.net>
+Subject: netdev: create attribute_groups with class_device_add
+Message-ID: <20060421125438.50f93a34@localhost.localdomain>
+
+Atomically create attributes when class device is added. This avoids the
+race between registering class_device (which generates hotplug event),
+and the creation of attribute groups.
+
+Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ include/linux/netdevice.h | 2 +
+ net/core/dev.c | 2 -
+ net/core/net-sysfs.c | 49 +++++++++++-----------------------------------
+ 3 files changed, 15 insertions(+), 38 deletions(-)
+
+--- gregkh-2.6.orig/include/linux/netdevice.h
++++ gregkh-2.6/include/linux/netdevice.h
+@@ -506,6 +506,8 @@ struct net_device
+
+ /* class/net/name entry */
+ struct class_device class_dev;
++ /* space for optional statistics and wireless sysfs groups */
++ struct attribute_group *sysfs_groups[3];
+ };
+
+ #define NETDEV_ALIGN 32
+--- gregkh-2.6.orig/net/core/dev.c
++++ gregkh-2.6/net/core/dev.c
+@@ -3043,11 +3043,11 @@ void netdev_run_todo(void)
+
+ switch(dev->reg_state) {
+ case NETREG_REGISTERING:
+- dev->reg_state = NETREG_REGISTERED;
+ err = netdev_register_sysfs(dev);
+ if (err)
+ printk(KERN_ERR "%s: failed sysfs registration (%d)\n",
+ dev->name, err);
++ dev->reg_state = NETREG_REGISTERED;
+ break;
+
+ case NETREG_UNREGISTERING:
+--- gregkh-2.6.orig/net/core/net-sysfs.c
++++ gregkh-2.6/net/core/net-sysfs.c
+@@ -29,7 +29,7 @@ static const char fmt_ulong[] = "%lu\n";
+
+ static inline int dev_isalive(const struct net_device *dev)
+ {
+- return dev->reg_state == NETREG_REGISTERED;
++ return dev->reg_state <= NETREG_REGISTERED;
+ }
+
+ /* use same locking rules as GIF* ioctl's */
+@@ -445,58 +445,33 @@ static struct class net_class = {
+
+ void netdev_unregister_sysfs(struct net_device * net)
+ {
+- struct class_device * class_dev = &(net->class_dev);
+-
+- if (net->get_stats)
+- sysfs_remove_group(&class_dev->kobj, &netstat_group);
+-
+-#ifdef WIRELESS_EXT
+- if (net->get_wireless_stats || (net->wireless_handlers &&
+- net->wireless_handlers->get_wireless_stats))
+- sysfs_remove_group(&class_dev->kobj, &wireless_group);
+-#endif
+- class_device_del(class_dev);
+-
++ class_device_del(&(net->class_dev));
+ }
+
+ /* Create sysfs entries for network device. */
+ int netdev_register_sysfs(struct net_device *net)
+ {
+ struct class_device *class_dev = &(net->class_dev);
+- int ret;
++ struct attribute_group **groups = net->sysfs_groups;
+
++ class_device_initialize(class_dev);
+ class_dev->class = &net_class;
+ class_dev->class_data = net;
++ class_dev->groups = groups;
+
++ BUILD_BUG_ON(BUS_ID_SIZE < IFNAMSIZ);
+ strlcpy(class_dev->class_id, net->name, BUS_ID_SIZE);
+- if ((ret = class_device_register(class_dev)))
+- goto out;
+
+- if (net->get_stats &&
+- (ret = sysfs_create_group(&class_dev->kobj, &netstat_group)))
+- goto out_unreg;
++ if (net->get_stats)
++ *groups++ = &netstat_group;
+
+ #ifdef WIRELESS_EXT
+- if (net->get_wireless_stats || (net->wireless_handlers &&
+- net->wireless_handlers->get_wireless_stats)) {
+- ret = sysfs_create_group(&class_dev->kobj, &wireless_group);
+- if (ret)
+- goto out_cleanup;
+- }
+- return 0;
+-out_cleanup:
+- if (net->get_stats)
+- sysfs_remove_group(&class_dev->kobj, &netstat_group);
+-#else
+- return 0;
++ if (net->get_wireless_stats
++ || (net->wireless_handlers && net->wireless_handlers->get_wireless_stats))
++ *groups++ = &wireless_group;
+ #endif
+
+-out_unreg:
+- printk(KERN_WARNING "%s: sysfs attribute registration failed %d\n",
+- net->name, ret);
+- class_device_unregister(class_dev);
+-out:
+- return ret;
++ return class_device_add(class_dev);
+ }
+
+ int netdev_sysfs_init(void)