I've successfully added a device attribute to my device driver, but in all the examples that I found the attribute is used to inject data to the kernel, while my goal would be to export some data from kernel to make it visible in user space. Which is the right way to write to that file from kernel-space? So that data can be retrieved from user-space?
To read data from the kernel, just return it in the show handler:
static ssize_t show_myvalue(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct my_device *mydev = ...dev...;
return sprintf(buf, "%d\n", mydev->myvalue);
}
static DEVICE_ATTR(myvalue, S_IRUGO, show_myvalue, NULL);
If you must notify user space of changes, use sysfs_notify.
Related
I am developing a module which works as a layer between mac80211 module and ath9k device driver (I have done that by exporting ath9k_ops, then accessing it in my module and changing the callback functions in order to point to functions in my module).
For now, my module just intercepts mac80211 callback operations (by struct ieee80211_ops) and forward them to the device driver.
Part of struct ieee80211_ops is:
struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb);
/* other callback functions ... */
}
This way, when module 80211 calls callback function (*tx) I can access members of the structs ieee80211_hw, ieee80211_tx_control, sk_buff, except the pointer pointing to private data of the device:
struct ath_softc *sc = hw->priv;
What I am not following is that the original callback function of the ath9k device driver (which I call at the end of my callback function) does exactly the same thing:
static void ath9k_tx(struct ieee80211_hw *hw,
struct ieee80211_tx_control *control,
struct sk_buff *skb)
{
struct ath_softc *sc = hw->priv;
/* other code accessing members of struct ath_softc normally */
}
So, why can't my module access the private data and ath9k module can? hw->
I think I provided enough information regarding the problem because the issue is probably related to the way private data is protected from other modules accessing it, and it's my fault in not understanding how memory fully works in linux kernel.
Thank you very much. Let me know if it's worth to provide more information on the question.
looking fs/ext4/super.c, I see this function
static void ext4_handle_error(struct super_block *sb)
I need have a kobj if I want to send an uevent inside ext4_handle_error function using
int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, char *envp_ext[])
Question: is there a way to get *kobj from super_block *sb?
struct ext4_sb_info *sbi = EXT4_SB(sb); sbi->s_kobj; is this good?
I'm writing a kernel module that need to ask an hid raw device periodically.
I tried hrtimer and a simple timer and each time I call hid_hw_raw_request I got a "BUG: scheduling while atomic".
If I try the same function outside my timer function (eg in the init), it works fine (no bug).
How could periodically call this function without generating any bug ?
You need to use a work queue to issue your hid_hw_raw_request as deferred work. This can be done as in the following example module:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/workqueue.h>
static void hid_work_handler(struct work_struct *hid_work);
static struct workqueue_struct *hid_workqueue;
static DECLARE_WORK(hid_work, hid_work_handler);
static void hid_work_handler(struct work_struct *hid_work)
{
...
hid_hw_raw_request(...);
...
}
static int __init hid_work_init(void)
{
if (!hid_workqueue)
hid_workqueue = create_singlethread_workqueue("hid_workqueue");
if (hid_workqueue)
queue_work(hid_workqueue, &hid_work);
return 0;
}
static void __exit hid_work_exit(void)
{
if (hid_workqueue) {
flush_workqueue(hid_workqueue);
destroy_workqueue(hid_workqueue);
}
}
module_init(hid_work_init);
module_exit(hid_work_exit);
MODULE_DESCRIPTION("hid_work_test");
MODULE_LICENSE("GPL");
Note that for the real implementation you'll need to create your own data struct with an included struct work_struct to be queued. This data struct will likely contain the hiddev, buffer, etc. that the hid_work_handler needs to do the actual transfer. See LDD3 Chapter 7 for more details (albeit syntax of calls is outdated, the basic explanation still applies).
I have read and almost gone through all the linux kernel documentation on the device tree and device tree overlays.I am not able to understand if we have to create a new entree in the device tree of the platform or to create a new overlay for the device for a new driver based on device tree.
I am looking for a simple led glowing driver example where led is connected to GPIO pin and its configuration is mentioned in the device tree overlay or device tree fragment on the board's platform.How can it be build/pushed and tested using the user space application.
I created a custom device in my device tree:
my_device#ffdf0000 {
compatible = "my_driver";
reg = <0xffdf0000 0x1000>
/*
* reg = address of device and size
* (Minimum is System's Pagesize = 0x1000 Byte in my case
*/
}
I wrote a Kernel stub for this Device:
(Here I took kernel_src/drivers/uio/uio_pdrv_genirq.c and Hans J. Koch: Userspace I/O drivers in a realtime context (device driver tutorial) as basis.)
This stub has following two structs:
The of_device_id struct:
static struct of_device_id my_match_table[] = {
{
.compatible = "my_driver",
},
{0}
};
MODULE_DEVICE_TABLE(of, my_match_table);
and the driver struct itself:
static struct platform_driver my_platform_driver = {
.probe = my_probe,
.remove = my_remove,
.driver = {
.name = "my_driver",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(my_match_table),
},
};
Now I have access to the properties of the device tree in my probe function:
static int my_probe(struct platform_device *dev)
{
struct uio_info *uioinfo;
struct resource *r = &dev->resource[0];
[...]
uioinfo->name = dev->dev.of_node->name /* name from device tree: "my_device" */
uioinfo->mem[0].addr = r->start; /* device address from device tree */
uioinfo->mem[0].size = resource_size(r); /* size from device tree */
[...]
}
When there is a match in compatible with both the kernel stub's entry and the device tree, the probe function is called.
Use QEMU with a minimal custom hardware device
I recommend you code up your own minimal platform device, to also control the hardware and have a full understanding.
I have provided a full runnable Buildroot QEMU example with source code on GitHub as detailed on this answer: How to program Linux .dts device tree files?
The example is also documented on the GitHub repository.
I have successfully implemented a GPIO based driver for my custom protocol using platform device model.
I want to upgrade it using device tree approach. So for starters I have a beaglebone black, and I have cross compiled the kernel using the device tree config enabled and verified during uboot console messages showing
Verifying Checksum ... OK
Flattened Device Tree blob at 80f80000
Booting using the fdt blob at 0x80f80000
XIP Kernel Image ... OK
OK
Using Device Tree in place at 80f80000, end 80f899de
I added my entry into the board common file node name my_gpio {compatible = "my_gpio" }
Then I build the usual process make uImages dtbs LOADADDR....
Finally i get my uImage with dtb.
In my driver i have used the same string "my_gpio" as .name property.
but my probe method is not getting called, which AFAIK is because it is not finding any compatible devices.
Any help suggestions would be great.
In my driver:
static struct platform_driver d_driver = {
.driver = {
.name = "d_gpio",
.of_match_table = d_of_match,
},
.probe = D_probe,
.remove = D_remove
};
Thanks
You need to prepare a structure of type struct of_device_id and use the compatible property on that.
Try in the following manner :
static struct of_device_id my_devs[] = {
{ .compatible = "my_gpio" }, /* This should be the name given in the device tree */
{ }
};
MODULE_DEVICE_TABLE(of, my_devs);
Now build the platform_driver structure, and pass the above table into it :
static struct platform_driver my_plat_driver = {
.probe = my_probe,
.remove = my_remove,
.driver = {
.name = "my_gpio_driver", /* This name is for sysfs, not for matching */
.of_match_table = my_devs /* This turns out as the matching logic */
}
};
May be your board support doesn't understand this protocol, so a node is needed to put in a place where the platform code actually processes it. Please go through below discussion and add a "virtual-devices" node in dtb , hope it would help.
http://web.archiveorange.com/archive/v/9IQA2s6aeZUFXdm6P87Z