request_firmware() hotplug interface, third round and a halve
Subsystems (3)
Hi,
There is some new stuff:
-----------------------
- 'struct device *device' is used instead of 'char *device'. So we now have the device symlink :)
- request_firmware_nowait is implemented, please comment on it.
- It doesn't abuse the stack any more, or at least not that much :)
- There is a timeout, changeable from userspace. Feedback on a reasonable default value appreciated.
- Extended 'loading' semantics:
echo 1 > loading:
start a new load, and flush any data from a previous partial load.
echo 0 > loading:
finish load.
echo -1 > loading:
cancel load and give an error to the driver.
- adapted to new sysfs interface.
- it is now a patch against current bk-cvs gateway.
- There is a *working* sample on how to use the firmware class without using request_firmware(). It is not clean, but it works, if it is found to be interesting it should be further polished.
Some random notes:
-----------------
- request_firmware_cancel is not needed, request_firmware_nowait will lock the client module into memory until after triggering the callback.
The only other problem that I can think of is the device getting unplugged while waiting for firmware, so the driver callback should first make sure that the device is still there.
- firmware-class.diff adds both samples to the kernel tree, that doesn't mean that I want them there, it is just for easier testing.
Patches:
-------
- firmware-class.diff:
firmware_class code and the two samples.
- sysfs-bin-flexible-size.diff:
Make dynamically sized files possible. And return the right value on successful write.
- sysfs-bin-lost-dget.diff:
I was having trouble when calling request_firmware() from a work queue, and after a little investigations it seams that this dget got lost along the way. Adding it back fixed the issue. Or am I causing a dentry leak now?
PS: If you guys consider this abusive CC:ing, please complain.
Signature · 6 lines
--- Manuel Estrada Sainz <[email protected]> <[email protected]> <[email protected]> ------------------------ <[email protected]> ------------------- Let us have the serenity to accept the things we cannot change, courage to change the things we can, and wisdom to know the difference.
drivers/base/Makefile +2 -0
@@ -3,4 +3,6 @@ obj-y := core.o sys.o interface.o power.o bus.o \ driver.o class.o platform.o \ cpu.o firmware.o init.o +obj-m := firmware_class.o firmware_sample_driver.o \ + firmware_sample_firmware_class.o obj-$(CONFIG_NUMA) += node.o memblk.o
drivers/base/firmware_class.c +425 -0
425 lines not on this page · raw message
drivers/base/firmware_sample_driver.c +115 -0
115 lines not on this page · raw message
drivers/base/firmware_sample_firmware_class.c +200 -0
200 lines not on this page · raw message
include/linux/firmware.h +20 -0
@@ -0,0 +1,20 @@ +#ifndef _LINUX_FIRMWARE_H +#define _LINUX_FIRMWARE_H +#include <linux/module.h> +#include <linux/types.h> +#define FIRMWARE_NAME_MAX 30 +struct firmware { +size_t size; +u8 *data; +}; +int request_firmware (const struct firmware **fw,const char *name, +struct device *device); +int request_firmware_nowait ( +struct module *module, +const char *name,struct device *device,void *context, +void (*cont)(const struct firmware *fw,void *context)); +/* Maybe 'device' should be 'struct device *' */ + +void release_firmware (const struct firmware *fw); +void register_firmware (const char *name,const u8 *data,size_t size); +#endif
fs/sysfs/bin.c +19 -10
@@ -30,10 +30,15 @@loff_t offs = *off;int ret; -if (offs > size) -return 0 ; -if (offs + count > size) - count = size - offs; +if (count >PAGE_SIZE ) + count =PAGE_SIZE ; + +if (size){ +if (offs > size) +return 0 ; +if (offs + count > size) + count = size - offs; + } ret =fill_read (dentry, buffer, offs, count);if (ret <0 )
@@ -69,10 +74,14 @@loff_t offs = *off;int ret; -if (offs > size) -return 0 ; -if (offs + count > size) - count = size - offs; +if (count >PAGE_SIZE ) + count =PAGE_SIZE ; +if (size) { +if (offs > size) +return 0 ; +if (offs + count > size) + count = size - offs; + } ret = -EFAULT ;if (copy_from_user (buffer + offs, userbuf, count))
@@ -81,7 +90,7 @@ count =flush_write (dentry, buffer, offs, count);if (count >0 ) *off = offs + count; - ret =0 ; + ret = count; Done:return ret; }
@@ -102,7 +111,7 @@ goto Done; error = -ENOMEM ; - file->private_data =kmalloc (attr->size,GFP_KERNEL ); + file->private_data =kmalloc (PAGE_SIZE ,GFP_KERNEL );if (!file->private_data) goto Done;
fs/sysfs/inode.c +3 -2
@@ -60,9 +60,10 @@ Proceed:if (init) error =init (inode); -if (!error) +if (!error){d_instantiate (dentry, inode); -else +dget (dentry);/* Extra count - pin the dentry in core */ + }else iput (inode); Done:return error;
Oops, forgot to respond to this, sorry...
Quoted 7 lines · Manuel Estrada Sainz
Hi,
There is some new stuff:
------------------------ 'struct device *device' is used instead of 'char *device'. So we now have the device symlink :)
Nice.
Quoted 1 line
-
request_firmware_nowaitis implemented, please comment on it.
Looks sane.
Quoted 1 line
- It doesn't abuse the stack any more, or at least not that much :)
Thanks.
Quoted 2 lines
- There is a timeout, changeable from userspace. Feedback on a reasonable default value appreciated.
Is this really needed? Especially as you now have:
Quoted 8 lines
- Extended 'loading' semantics:
echo 1 > loading:
start a new load, and flush any data from a previous partial load.
echo 0 > loading:
finish load.
echo -1 > loading:
cancel load and give an error to the driver.
Looks good.
I'd recommend sending the sysfs patches to Pat Mochel. He's the one to take those.
Some minor comments about the code:
drivers/base/Makefile line 7
Quoted 9 lines
diff --exclude=CVS -urN linux-2.5.orig/drivers/base/Makefile linux-2.5.mine/drivers/base/Makefile
drivers/base/Makefile +2
-0@@ -3,4 +3,6 @@ obj-y := core.o sys.o interface.o power.o bus.o \ driver.o class.o platform.o \ cpu.o firmware.o init.o +obj-m := firmware_class.o firmware_sample_driver.o \ + firmware_sample_firmware_class.o
Why make the firmware_class.o always a module? Shouldn't it only be included in the core, if a driver that uses it is selected?
drivers/base/Makefile
Quoted 9 lines
drivers/base/Makefile +9
-0+static inline struct class_device *to_class_dev(struct kobject *obj) +{ + return container_of(obj,struct class_device,kobj); +} +static inline +struct class_device_attribute *to_class_dev_attr(struct attribute *_attr) +{ + return container_of(_attr,struct class_device_attribute,attr); +}
Move these two to drivers/base/base.h as they shouldn't be defined in two different files.
drivers/base/Makefile
Quoted 2 lines
drivers/base/Makefile +2
-0+int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr); +int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr);
If you need these, add them to include/linux/sysfs.h.
drivers/base/Makefile
Quoted 7 lines
drivers/base/Makefile +7
-0+struct firmware_priv { + char fw_id[FIRMWARE_NAME_MAX]; + struct completion completion; + struct bin_attribute attr_data; + struct firmware *fw; + s32 loading:2; + u32 abort:1;
Why s32 and u32? Why not just ints for both of them?
drivers/base/Makefile
Quoted 4 lines
drivers/base/Makefile +4
-0+struct class firmware_class = { + .name = "firmware", + .hotplug = firmware_class_hotplug, +};
Oops, forgot tabs there...
drivers/base/Makefile
Quoted 1 line
drivers/base/Makefile +1
-0+ switch(fw_priv->loading){
Please add a space before the '{'.
drivers/base/Makefile
Quoted 2 lines
drivers/base/Makefile +2
-0+ case 0: + if(prev_loading==1)
And a space after the if. You do this in lots of places.
Other than those very minor things, this looks quite good.
thanks,
greg k-h
Quoted 9 lines · Greg Kroah-Hartman
drivers/base/firmware_class.c line 41
Quoted 7 lines
drivers/base/firmware_class.c +7
-0+struct firmware_priv { +char fw_id[FIRMWARE_NAME_MAX ]; +struct completion completion; +struct bin_attribute attr_data; +struct firmware *fw; +s32 loading:2 ; +u32 abort:1 ;Why s32 and u32? Why not just ints for both of them?
And for that matter, I don't think there's any point using bitfields, 61 bits is not worth it.
Signature · 4 lines
David Gibson | For every complex problem there is a [email protected] | solution which is simple, neat and | wrong. http://www.ozlabs.org/people/dgibson
Quoted 11 lines · David Gibson
Quoted 9 lines · Greg Kroah-Hartman
drivers/base/firmware_class.c line 41
Quoted 7 lines
drivers/base/firmware_class.c +7
-0+struct firmware_priv { +char fw_id[FIRMWARE_NAME_MAX ]; +struct completion completion; +struct bin_attribute attr_data; +struct firmware *fw; +s32 loading:2 ; +u32 abort:1 ;Why s32 and u32? Why not just ints for both of them?
Quoted 2 lines
And for that matter, I don't think there's any point using bitfields, 61 bits is not worth it.
Done, I just sent updated patches.
Thanks
Manuel
Signature · 6 lines
--- Manuel Estrada Sainz <[email protected]> <[email protected]> <[email protected]> ------------------------ <[email protected]> ------------------- Let us have the serenity to accept the things we cannot change, courage to change the things we can, and wisdom to know the difference.
Quoted 3 lines · Greg KH
Oops, forgot to respond to this, sorry...
On Sun, May 18, 2003 at 12:19:22AM +0200, Manuel Estrada Sainz wrote:
[snip]
Quoted 4 lines
Quoted 2 lines
- There is a timeout, changeable from userspace. Feedback on a reasonable default value appreciated.
Is this really needed? Especially as you now have:
There is currently no way to know if hotplug couldn't be called at all or if it failed because it didn't have firmware load support.
If that happens, we would be waiting for ever. And I'd rather make that a countable number of seconds :)
I'll make '0' mean no timeout at all.
Quoted 9 lines
Quoted 8 lines
- Extended 'loading' semantics:
echo 1 > loading:
start a new load, and flush any data from a previous partial load.
echo 0 > loading:
finish load.
echo -1 > loading:
cancel load and give an error to the driver.
Quoted 4 lines
Looks good.
I'd recommend sending the sysfs patches to Pat Mochel. He's the one to take those.
Done.
Quoted 14 lines
Some minor comments about the code:
drivers/base/Makefile line 7
Quoted 9 lines
diff --exclude=CVS -urN linux-2.5.orig/drivers/base/Makefile linux-2.5.mine/drivers/base/Makefile
drivers/base/Makefile +2
-0@@ -3,4 +3,6 @@ obj-y := core.o sys.o interface.o power.o bus.o \ driver.o class.o platform.o \ cpu.o firmware.o init.o +obj-m := firmware_class.o firmware_sample_driver.o \ + firmware_sample_firmware_class.oWhy make the firmware_class.o always a module? Shouldn't it only be included in the core, if a driver that uses it is selected?
That was the quickest way to get modules to play with :-)
I am not sure on how to implement "if a driver that uses it is selected" and not sure on where to add the Kconfig entries to make it available to out-of-kernel modules.
If the approach in the attached patches is still not right, please complain.
Maybe kbuild could allow forcing one option from another, a companion for 'depends', lets call it 'hard_depends'
depends FOO
If FOO is not there the entry won't even be shown in the menu.
hard_depends FOO
FOO gets set to satisfy the dependency.
When trying to deselect an item that is hard_depended upon, the system could complain and tell you which options should be deselected or even offer to do it automatically.
This would also simplify the selection of crc32 and compression/decompression code. And allow removal of all those comments like "Video4Linux support is needed for USB Multimedia device support".
Quoted 4 lines
Quoted 4 lines
drivers/base/Makefile +4
-0+static inline struct class_device *to_class_dev(struct kobject *obj) +{ + return container_of(obj,struct class_device,kobj); +}
Quoted 8 lines
drivers/base/Makefile
Quoted 5 lines
drivers/base/Makefile +5
-0+static inline +struct class_device_attribute *to_class_dev_attr(struct attribute *_attr) +{ + return container_of(_attr,struct class_device_attribute,attr); +}Move these two to
drivers/base/base.has they shouldn't be defined in two different files.
OK, I also removed equivalent macros from class.c
Quoted 5 lines
drivers/base/Makefile
Quoted 2 lines
drivers/base/Makefile +2
-0+int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr); +int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr);If you need these, add them to
include/linux/sysfs.h.
Quoted 9 lines
drivers/base/Makefile
Quoted 7 lines
drivers/base/Makefile +7
-0+struct firmware_priv { + char fw_id[FIRMWARE_NAME_MAX]; + struct completion completion; + struct bin_attribute attr_data; + struct firmware *fw; + s32 loading:2; + u32 abort:1;Why s32 and u32? Why not just ints for both of them?
Since they are bit fields, I wanted to have more control over them and a single bit bit-field should be unsigned, but I guess that David is right, it is not worth it. Both are full int's now.
Quoted 7 lines
drivers/base/Makefile
Quoted 4 lines
drivers/base/Makefile +4
-0+struct class firmware_class = { + .name = "firmware", + .hotplug = firmware_class_hotplug, +};Oops, forgot tabs there...
Quoted 8 lines
drivers/base/Makefile
Quoted 1 line
drivers/base/Makefile +1
-0+ switch(fw_priv->loading){Please add a space before the '{'.
drivers/base/Makefile
Quoted 2 lines
drivers/base/Makefile +2
-0+ case 0: + if(prev_loading==1)And a space after the if. You do this in lots of places.
Fixed, and just in case, I put it through Lindent which BTW is a little evil :-) so I hand removed the evilness I could not take.
Quoted 1 line
Other than those very minor things, this looks quite good.
Great.
Patches:
firmware-class.diff:
The code itself against bk-cvs.
class-casts.diff:
to_class_dev/to_class_dev_attr changes against bk-cvs.
sysfs-bin-header.diff
sysfs-bin-lost-dget.diff sysfs-bin-flexible-size.diff:
Just for completeness, since the above will not work without them, but I already send them to Pat Mochel in a separate mail.
incremental.diff:
Incremental patch for easier reading, although there are lots of formating changes.
Thanks
Manuel
Signature · 6 lines
--- Manuel Estrada Sainz <[email protected]> <[email protected]> <[email protected]> ------------------------ <[email protected]> ------------------- Let us have the serenity to accept the things we cannot change, courage to change the things we can, and wisdom to know the difference.
Quoted 3 lines · Manuel Estrada Sainz
If the approach in the attached patches is still not right, please complain.
-ENOPATCHES :)
Quoted 3 lines · Greg KH
Oops, forgot to respond to this, sorry...
On Sun, May 18, 2003 at 12:19:22AM +0200, Manuel Estrada Sainz wrote:
[snip]
Quoted 4 lines
Quoted 2 lines
- There is a timeout, changeable from userspace. Feedback on a reasonable default value appreciated.
Is this really needed? Especially as you now have:
There is currently no way to know if hotplug couldn't be called at all or if it failed because it didn't have firmware load support.
If that happens, we would be waiting for ever. And I'd rather make that a countable number of seconds :)
I'll make '0' mean no timeout at all.
Quoted 9 lines
Quoted 8 lines
- Extended 'loading' semantics:
echo 1 > loading:
start a new load, and flush any data from a previous partial load.
echo 0 > loading:
finish load.
echo -1 > loading:
cancel load and give an error to the driver.
Quoted 4 lines
Looks good.
I'd recommend sending the sysfs patches to Pat Mochel. He's the one to take those.
Done.
Quoted 14 lines
Some minor comments about the code:
drivers/base/Makefile line 7
Quoted 9 lines
diff --exclude=CVS -urN linux-2.5.orig/drivers/base/Makefile linux-2.5.mine/drivers/base/Makefile
drivers/base/Makefile +2
-0@@ -3,4 +3,6 @@ obj-y := core.o sys.o interface.o power.o bus.o \ driver.o class.o platform.o \ cpu.o firmware.o init.o +obj-m := firmware_class.o firmware_sample_driver.o \ + firmware_sample_firmware_class.oWhy make the firmware_class.o always a module? Shouldn't it only be included in the core, if a driver that uses it is selected?
That was the quickest way to get modules to play with :-)
I am not sure on how to implement "if a driver that uses it is selected" and not sure on where to add the Kconfig entries to make it available to out-of-kernel modules.
If the approach in the attached patches is still not right, please complain.
Maybe kbuild could allow forcing one option from another, a companion for 'depends', lets call it 'hard_depends'
depends FOO
If FOO is not there the entry won't even be shown in the menu.
hard_depends FOO
FOO gets set to satisfy the dependency.
When trying to deselect an item that is hard_depended upon, the system could complain and tell you which options should be deselected or even offer to do it automatically.
This would also simplify the selection of crc32 and compression/decompression code. And allow removal of all those comments like "Video4Linux support is needed for USB Multimedia device support".
Quoted 4 lines
Quoted 4 lines
drivers/base/Makefile +4
-0+static inline struct class_device *to_class_dev(struct kobject *obj) +{ + return container_of(obj,struct class_device,kobj); +}
Quoted 8 lines
drivers/base/Makefile
Quoted 5 lines
drivers/base/Makefile +5
-0+static inline +struct class_device_attribute *to_class_dev_attr(struct attribute *_attr) +{ + return container_of(_attr,struct class_device_attribute,attr); +}Move these two to
drivers/base/base.has they shouldn't be defined in two different files.
OK, I also removed equivalent macros from class.c
Quoted 5 lines
drivers/base/Makefile
Quoted 2 lines
drivers/base/Makefile +2
-0+int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr); +int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr);If you need these, add them to
include/linux/sysfs.h.
Quoted 9 lines
drivers/base/Makefile
Quoted 7 lines
drivers/base/Makefile +7
-0+struct firmware_priv { + char fw_id[FIRMWARE_NAME_MAX]; + struct completion completion; + struct bin_attribute attr_data; + struct firmware *fw; + s32 loading:2; + u32 abort:1;Why s32 and u32? Why not just ints for both of them?
Since they are bit fields, I wanted to have more control over them and a single bit bit-field should be unsigned, but I guess that David is right, it is not worth it. Both are full int's now.
Quoted 7 lines
drivers/base/Makefile
Quoted 4 lines
drivers/base/Makefile +4
-0+struct class firmware_class = { + .name = "firmware", + .hotplug = firmware_class_hotplug, +};Oops, forgot tabs there...
Quoted 8 lines
drivers/base/Makefile
Quoted 1 line
drivers/base/Makefile +1
-0+ switch(fw_priv->loading){Please add a space before the '{'.
drivers/base/Makefile
Quoted 2 lines
drivers/base/Makefile +2
-0+ case 0: + if(prev_loading==1)And a space after the if. You do this in lots of places.
Fixed, and just in case, I put it through Lindent which BTW is a little evil :-) so I hand removed the evilness I could not take.
Quoted 1 line
Other than those very minor things, this looks quite good.
Great.
Patches:
firmware-class.diff:
The code itself against bk-cvs.
class-casts.diff:
to_class_dev/to_class_dev_attr changes against bk-cvs.
sysfs-bin-header.diff
sysfs-bin-lost-dget.diff sysfs-bin-flexible-size.diff:
Just for completeness, since the above will not work without them, but I already send them to Pat Mochel in a separate mail.
incremental.diff:
Incremental patch for easier reading, although there are lots of formating changes.
Thanks
Manuel
PS: Sorry, I forgot the patches last time :(
PS2: Now that I really include the patches I realized their size, and compressed some.
Signature · 6 lines
--- Manuel Estrada Sainz <[email protected]> <[email protected]> <[email protected]> ------------------------ <[email protected]> ------------------- Let us have the serenity to accept the things we cannot change, courage to change the things we can, and wisdom to know the difference.
drivers/base/Makefile +8 -2
@@ -5,4 +5,10 @@ cpu.o firmware.o init.o -obj-m := firmware_class.o firmware_sample_driver.o \ - firmware_sample_firmware_class.o +obj-$(CONFIG_FW_LOADER) += firmware_class.o + +#The next three lines are just to make testing easier and should not get into +#the kernel +obj-$(CONFIG_FW_LOADER_SAMPLE) += firmware_class.o +obj-$(CONFIG_FW_LOADER_SAMPLE) += firmware_sample_driver.o \ + firmware_sample_firmware_class.o + obj-$(CONFIG_NUMA) += node.o memblk.o
reverted:
linux/sysfs.h +0 -3
@@ -23,9 +23,6 @@ssize_t (*write)(struct kobject *,char *,loff_t ,size_t ); }; -int sysfs_create_bin_file (struct kobject * kobj,struct bin_attribute * attr); -int sysfs_remove_bin_file (struct kobject * kobj,struct bin_attribute * attr); -struct sysfs_ops {ssize_t (*show)(struct kobject *,struct attribute *,char *);ssize_t (*store)(struct kobject *,struct attribute *,const char *,size_t );
only in patch2:
unchanged:
drivers/base/base.h +9 -0
@@ -4,3 +4,12 @@extern int bus_add_driver (struct device_driver *);extern void bus_remove_driver (struct device_driver *); +static inline struct class_device *to_class_dev (struct kobject *obj) +{ + return container_of(obj,struct class_device,kobj); +} +static inline +struct class_device_attribute *to_class_dev_attr (struct attribute *_attr) +{ + return container_of(_attr,struct class_device_attribute,attr); +}
only in patch2:
unchanged:
drivers/base/class.c +0 -3
@@ -148,9 +148,6 @@ } -#define to_class_dev (obj) container_of(obj,struct class_device,kobj) -#define to_class_dev_attr (_attr) container_of(_attr,struct class_device_attribute,attr) -static ssize_t class_device_attr_show (struct kobject * kobj,struct attribute * attr,char * buf)
only in patch2:
unchanged:
drivers/base/Kconfig.lib +17 -0
@@ -0,0 +1,17 @@ +# +# To be sourced from lib/Kconfig +# + +config FW_LOADER + tristate "Hotplug firmware loading support" + ---help--- + This option is provided for the case where no in-kernel-tree modules + require hotplug firmware loading support, but a module built outside + the kernel tree does. + +config FW_LOADER_SAMPLE + tristate "Hotplug firmware loading samples" + ---help--- + This should not get in the kernel, it is just here to make playing + with firmware loading easier. +
only in patch2:
unchanged:
lib/Kconfig +2 -1
@@ -26,5 +26,6 @@ (PPP_DEFLATE=m || JFFS2_FS=m || CRYPTO_DEFLATE=m) default y if PPP_DEFLATE=y || JFFS2_FS=y || CRYPTO_DEFLATE=y -endmenu +source "drivers/base/Kconfig.lib" +endmenu
only in patch2:
unchanged:
include/linux/sysfs.h +3 -0
@@ -23,6 +23,9 @@ssize_t (*write)(struct kobject *,char *,loff_t ,size_t ); }; +int sysfs_create_bin_file (struct kobject * kobj,struct bin_attribute * attr); +int sysfs_remove_bin_file (struct kobject * kobj,struct bin_attribute * attr); +struct sysfs_ops {ssize_t (*show)(struct kobject *,struct attribute *,char *);ssize_t (*store)(struct kobject *,struct attribute *,const char *,size_t );
drivers/base/firmware_class.c +115 -110
478 lines not on this page · raw message
drivers/base/firmware_sample_firmware_class.c +4 -4
@@ -32,8 +32,8 @@struct firmware_priv {char fw_id[FIRMWARE_NAME_MAX ]; -s32 loading:2 ; -u32 abort:1 ; +int loading; +int abort; };extern struct class firmware_class;
@@ -68,8 +68,8 @@return count; } -CLASS_DEVICE_ATTR (loading,0644 , - firmware_loading_show, firmware_loading_store); +static CLASS_DEVICE_ATTR(loading, 0644, + firmware_loading_show, firmware_loading_store);static ssize_t firmware_data_read (struct kobject *kobj,char *buffer,loff_t offset,size_t count)
Quoted 10 lines · Manuel Estrada Sainz
Quoted 3 lines · Greg KH
Oops, forgot to respond to this, sorry...
On Sun, May 18, 2003 at 12:19:22AM +0200, Manuel Estrada Sainz wrote:
[snip]
Quoted 4 lines
Quoted 2 lines
- There is a timeout, changeable from userspace. Feedback on a reasonable default value appreciated.
Is this really needed? Especially as you now have:
Quoted 7 lines
There is currently no way to know if hotplug couldn't be called at all or if it failed because it didn't have firmware load support.
If that happens, we would be waiting for ever. And I'd rather make that a countable number of seconds :)
I'll make '0' mean no timeout at all.
Ok, that's fine with me. A bit of documentation for all of this might be nice. Just add some kerneldoc comments to your public functions, and you should be fine.
Quoted 3 lines
I am not sure on how to implement "if a driver that uses it is selected" and not sure on where to add the
Kconfigentries to make it available to out-of-kernel modules.
You could do something like what has been done for the mii module. Look at lib/Makefile and drivers/usb/net/Makefile.mii for an example.
I'm not saying that this is the best way, but it could be one solution. Ideally, the user would never have to select the firmware core option, it would just get automatically built if a driver that needs it is also selected.
Quoted 1 line
Patches:
The patches look great. Add a bit of documentation, and some build integration, and I'd think you are finished. Unless anyone else has any objections?
Very nice job, thanks again for doing this.
greg k-h
Quoted 14 lines · Greg KH
Quoted 13 lines · Manuel Estrada Sainz
Quoted 3 lines · Greg KH
Oops, forgot to respond to this, sorry...
On Sun, May 18, 2003 at 12:19:22AM +0200, Manuel Estrada Sainz wrote:
[snip]
Quoted 4 lines
Quoted 2 lines
- There is a timeout, changeable from userspace. Feedback on a reasonable default value appreciated.
Is this really needed? Especially as you now have:
There is currently no way to know if hotplug couldn't be called at all or if it failed because it didn't have firmware load support.
Quoted 8 lines
Quoted 4 lines
If that happens, we would be waiting for ever. And I'd rather make that a countable number of seconds :)
I'll make '0' mean no timeout at all.
Ok, that's fine with me. A bit of documentation for all of this might be nice. Just add some kerneldoc comments to your public functions, and you should be fine.
Done. I am not a good documentation writer, but the attached patches should include enough documentation to understand how things work.
Quoted 11 lines
Quoted 3 lines
I am not sure on how to implement "if a driver that uses it is selected" and not sure on where to add the
Kconfigentries to make it available to out-of-kernel modules.You could do something like what has been done for the mii module. Look at lib/Makefile and
drivers/usb/net/Makefile.miifor an example.I'm not saying that this is the best way, but it could be one solution. Ideally, the user would never have to select the firmware core option, it would just get automatically built if a driver that needs it is also selected.
But if a driver not in the kernel tree needs it, the user should be able to enable it unconditionally, like the CRC32 stuff.
And currently there is no in-kernel driver that uses it, so the only way to enable it is manually.
Once Atmel PCMCIA driver (which will use it) gets in, the new 'enable' kconfig keyword should be already available and no makefile tricks will be needed.
[snip]
Quoted 1 line
Add a bit of documentation, and some build integration,
Until drivers start using it, there is not much build integration to do.
Quoted 2 lines
and I'd think you are finished. Unless anyone else has any objections?
Simon Kelley had an objection, it was badly corrupting kernel memory :-/.
It was a bug in the sysfs pieces which is now fixed.
So I am finished :-) What do I do now? Should I send it to Linus or you take care of that?
Quoted 1 line
Very nice job, thanks again for doing this.
No problem.
News:
- Fixed the sysfs corruption problem.
- Use refcounting with class_device instances.
- I had to add support for 'release forwarding' to the class subsystem.
- Removed firmware_sample_firmware_class.c
- It is ugly, if found interesting, it should get polished first.
- Removed FW_LOADER_SAMPLE Kconfig/Makefile stuff.
- Some more formatting changes.
Patches:
incremental.diff:
For easier reading as usual.
firmware-class.diff.bz2:
The code itself
firmware-class-sample-driver.diff.bz2:
The sample driver, for easier ignoring :)
class-casts+release.diff.bz2:
to_class_dev/to_class_dev_attr and 'release forwarding' changes.
sysfs-bin-header.diff.bz2
sysfs-bin-lost-dget.diff.bz2 sysfs-bin-flexible-size.diff.bz2:
sysfs bits. This time, they don't corrupt kernel memory :-/ (I'll send them to Patrick Mochel in a few moments.)
Have a nice day
Manuel
Signature · 6 lines
--- Manuel Estrada Sainz <[email protected]> <[email protected]> <[email protected]> ------------------------ <[email protected]> ------------------- Let us have the serenity to accept the things we cannot change, courage to change the things we can, and wisdom to know the difference.
drivers/base/class.c +8 -0
@@ -179,7 +179,15 @@ .store = class_device_attr_store, }; +static void class_dev_release (struct kobject * kobj) +{ +struct class_device *class_dev =to_class_dev (kobj); +if (class_dev->release) + class_dev->release (class_dev); +} +static struct kobj_type ktype_class_device = { + .release = &class_dev_release, .sysfs_ops = &class_dev_sysfs_ops, };
only in patch2:
unchanged:
include/linux/device.h +1 -0
@@ -204,6 +204,7 @@void * class_data;/* class-specific data */ char class_id[BUS_ID_SIZE ];/* unique to this class */ +void (*release)(struct class_device * class_dev); }; static inline void *
drivers/base/Kconfig.lib +0 -6
@@ -12,6 +11,0 @@ -config FW_LOADER_SAMPLE - tristate "Hotplug firmware loading samples" - ---help--- - This should not get in the kernel, it is just here to make playing - with firmware loading easier. -
drivers/base/Makefile +0 -7
@@ -6,9 +6,2 @@ obj-$(CONFIG_FW_LOADER) += firmware_class.o - -#The next three lines are just to make testing easier and should not get into -#the kernel -obj-$(CONFIG_FW_LOADER_SAMPLE) += firmware_class.o -obj-$(CONFIG_FW_LOADER_SAMPLE) += firmware_sample_driver.o \ - firmware_sample_firmware_class.o - obj-$(CONFIG_NUMA) += node.o memblk.o
drivers/base/firmware_class.c +106 -18
235 lines not on this page · raw message
include/linux/firmware.h +5 -5
@@ -9,12 +9,12 @@ }; -int request_firmware (const struct firmware **fw,const char *name, -struct device *device); -int request_firmware_nowait ( +int request_firmware (const struct firmware **fw,const char *name, +struct device *device); +int request_firmware_nowait (struct module *module,const char *name,struct device *device,void *context,void (*cont)(const struct firmware *fw,void *context));/* Maybe 'device' should be 'struct device *' */ -void release_firmware (const struct firmware *fw); -void register_firmware (const char *name,const u8 *data,size_t size); +void release_firmware (const struct firmware *fw); +void register_firmware (const char *name,const u8 *data,size_t size);#endif
fs/sysfs/bin.c +3 -3
@@ -33,7 +33,7 @@if (count >PAGE_SIZE ) count =PAGE_SIZE ; -if (size){ +if (size) {if (offs > size)return 0 ;if (offs + count > size)
@@ -46,7 +46,7 @@ count = ret; ret = -EFAULT ; -if (copy_to_user (userbuf, buffer + offs, count) !=0 ) +if (copy_to_user (userbuf, buffer, count) !=0 ) goto Done; *off = offs + count;
@@ -84,7 +84,7 @@ } ret = -EFAULT ; -if (copy_from_user (buffer + offs, userbuf, count)) +if (copy_from_user (buffer, userbuf, count)) goto Done; count =flush_write (dentry, buffer, offs, count);
fs/sysfs/inode.c +1 -1
@@ -60,7 +60,7 @@ Proceed:if (init) error =init (inode); -if (!error){ +if (!error) {d_instantiate (dentry, inode);dget (dentry);/* Extra count - pin the dentry in core */ }else
BZh91AY&SYV†³N ¿ß€0`ÿ¿o¯ß¿ïßú@¼ æÄÐa2dÉ‘„Á4Ó# C Ôˆ@ æÄÐa2dÉ‘„Á4Ó# C T’@ÑO*x™=Iä›PÉ“&!�&jiéMLš)©‚ââË•w±e”U÷Ü]kªK—)K®RZÖ¸«4Ï \µsE–œ×Nꪌ�ʲ¦4j¸´bXá}õ‘&jSÝ!ÎìNÆç>šèê3ï4O_M�?5©âÓôÚ¦ÚN¦µ‘z”ÁÓùqö6ÖÅŽ%¬¢¸t{/dÃ2°/½¾Æq™àpÖñÖ·Òs|m"ç…Ÿ¿˜ô.¾â¶¬§²•ø´2ˆ¤û©V²hÇÀû2ár–•âóóùß®Dá°«[¡]b;Óe¦5›Ls˜›OïB¬w�šC€ã@[áCP¶˜JeE¡©Z�Mb€@€J;Êm”<ëÄ"