diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2006-04-24 15:34:09 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-04-24 15:34:09 -0700 |
commit | 4a076f7ffaae89e3f1c2ffecd147b79ae1e0bd9d (patch) | |
tree | 86bd89054c44670a82f2cfa1f7373cfc0898245c /driver | |
parent | 67c67eb735d985aadf3d63200ebb59147b9fa100 (diff) | |
download | patches-4a076f7ffaae89e3f1c2ffecd147b79ae1e0bd9d.tar.gz |
lotsa patches added
Diffstat (limited to 'driver')
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) |