i am quiet new at writing kernel drivers and there is something bothering me a lot. It would be great if you could kcik me into the right direction.
I am writing a module for a device, that has to be powered via putting a GPIO to HIGH-State.
In Documentation/gpio/* are texts, which say i should use the new descriptor-based interface of the GPIO Framework. But how to use it?
When i make an include like #include
it compiles and i can run the driver. But using gpiod_get(...) just returns fffffffffffffffe. It makes sense somehow, as the implentation of that function within linux/gpio/consumer.h is
static inline struct gpio_desc *__must_check gpiod_get(struct device
*dev, const char *con_id,enum gpiod_flags flags){
return ERR_PTR(-ENOSYS);
}
The implementation of the function exists in drivers/gpio/devres.c as well. How can i use that one?
It looks to me as i am not supposed to use that implementation.
I hope you can help me as it is getting really irritating.
As it turned out it was just necessary to include the file gpio/gpiolib as well which delivers additional definitions.
Related
I'm trying to import a COM interface into VC++. The COM object is from a application called IDEA, but as that is not very easy to get a hold of for others to help me. So I figure that if someone could give me instructions as to how I would do this for Word, it would be equivalent.
IDEA does have a .tlb file, but it would appear that it is incomplete. I can access the COM API using python with an example being something like this:
if __name__ == "__main__":
dbName = "Sample-Employees.IMD"
idea = win32ComClient.Dispatch(dispatch="Idea.IdeaClient")
db = idea.OpenDatabase(dbName) # open db
table_def = db.TableDef() # get table definition
Using the .tbl file, I can get as far as this:
#import "D:\Program Files (x86)\CaseWare IDEA\IDEA\Idea.tlb"
#include "x64\Debug\idea.tlh"
#include "x64\Debug\idea.tli"
void fn()
{
Idea::IIdeaClientPtr client;
auto db = client->OpenDatabase("Sample-Employees.IMD");
db-> // interface not defined
}
Intellisense will complete after the db-> with the following: AddRef, GetIdOfNames, GetTypeInfo, GetTypeInfoCount, Invoke, QueryInterface and Release. Thus, what I mean by an incomplete interface definition.
Now, since the python example states Idea.IdeaClient, and I've seen this with word as well (i.e. word.application), I was thinking that it might be possible to use that. Looking around though, I can't seem to find reference to that using #import. I have seen it being used with CLSIDFromProgID, but that is very manual mechanism. COM SMARTPTRs would be far more preferable.
Is this even possible to do with VC++?
Maybe OpenDatabase returns IDispatch, but interface containing TableDef is still defined in TLB.
In this case you'll need to downcast IDispatch to I-something-containing-TableDef-method.
Use QueryInterface call to get derived interface from IDispatch, not C or C++ casts, such as static_cast.
Otherwise, you'll need to use IDispatch::Invoke. The best help you have is CComPtr<IDispatch> from ATL, this template specialization have Invoke helpers, so that you can do something like this:
CComPtr<IDispatch> p;
p = db;
CComVairant result;
p.Invoke("TableDef", &result);
Or use IDispatch::Invoke as is.
Python aways relies on IDispatch::Invoke and does not use static interfaces, that's why it does not encounter this problem.
I work on Ubuntu kernel-mode netfilter module and need information about all network interfaces and their properties in module code.
Inside of init_module() I use register_netdevice_notifier() for that purpose. When callback function is called I can see correct event codes like up/down and other, but it seems that third parameter void* casted to net_device* provides object with invalid properties. ->name is empty string, ->if index is some nonsense number etc.
I tried debug version of module on kernel 3.19 and rebuild also on 4.2. Result is the same, I cannot read properties of net_device relating to event.
What can be problem ?
From what I can see from LXR, you need to call netdev_notifier_info_to_dev on the last parameter to get your net_device * (see here)
I'm writing drivers for several pieces of custom hardware. All of the devices are attached via PCIe to a host computer. For convenience I would like to group all of these custom devices together into a sysfs class (which I believe is an acceptable thing to do?). Unfortunately the information in LDD3 is way out of date and I'm having trouble finding current documentation that discusses what I'm attempting to do.
Creating my custom class is easy enough:
struct class MY_CLASS = class_create(THIS_MODULE, "myclass")
And inside of my probe calls I've got access to the struct dev:
static int probe(struct pci_dev *pcidev, const struct pci_device_id *id)
{
...
struct dev *my_dev = &pcidev->dev;
...
}
My question is this: now that I've got the class and the dev, how do I create a link between the two?
The device_create() basically does what I want, but since I've already got a struct dev my understanding is that I shouldn't call device_create (i.e. create a new device) again.
I've done a little more tracing and found that device_add() which is called by device_create(), calls device_add_class_symlinks() (not exported unfortunately) which does something like this:
...
sysfs_create_link(&dev->class->p->subsys.kobj,&dev->kobj, dev_name(dev));
...
I tried something like this directly in my drivers to create the links I want but I can't get it to compile because struct subsys_private (the "p" member in the class struct) is not exposed anywhere?
Any help is greatly appreciated!
Are your drivers sitting on the specific bus? If no, what purpose of the specific class?
Anyway, for starter
struct class devclass = {…}
probe()
{
struct device *dev = …
dev->class = &devclass;
}
init()
{
class_register(&devclass);
}
I've encountered the same issue.
if i called device_register with my class pointer assigned to the device class member. it will create a subsystem in my device directory, which is what device_add_class_symlinks do. but in my device directory there is already subsystem directory which is the link to the bus my device is attached to.
don't know if you got a method
Im trying to intercept the __do_page_fault() method in linux kernel. The normal way to register kprobes , i.e. defining kp.addr as
kp.addr = (kprobe_opcode_t *) kallsyms_lookup_name("__do_page_fault");
is not working. What's the proper way to do this?
Edit:
Any other method of intercepting do_page_fault will also work for me.
This error usually comes when GPL licenses are not used in the module. Adding the following lines in your module should remove this error :
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
I am trying to set up a devfreq driver for a peripheral on Linux. My init method for the driver looks as follows:
static struct platform_driver zynq_csortfreq_driver = {
.probe = zynq_csortfreq_probe,
.driver = {
.name = "ZYNQ_CSORT_DEVFREQ",
.owner = THIS_MODULE,
},
};
static int __init zynq_csortfreq_init(void)
{
return platform_driver_register(&zynq_csortfreq_driver);
}
late_initcall(zynq_csortfreq_init);
However, the probe function (zynq_csortfreq_probe) in my driver never seems to get called. I've read that in order for the probe call to work correctly, the .name value of the driver must match the name of the device - where can I find the name of the device?
In order for the probe function to be called, you must add a device from a machine file or via the device tree. This is typically done with platform_device_register() or platform_add_devices() in machine files. Alternatively, of_platform_populate() is used for the device tree model, but code does not use this directly. The platform device documentation has information for your Linux kernel version. It seems that your Linux uses the device tree model. The documentation in the cpufree devicetree will have some helpful information on activating your driver for this board with device trees.
The dtsi file needs something like,
soc {
zyncfreq#addr {
compatible="xxxx"
/* Other platform data */
Which will define the device for your machine. I would suggest that first you modify your machine files init_machine entry and use platform_device_register() to associate your driver with a device. Then you can later attempt to get the device tree mechanism working if you wish.
If you can view this closed question, my answer might be helpful if the Linux device-model documentation is not completely clear. However, I think for your case the Linux docs are sufficient.
SOLVED:
Problem is in the makefile system. A "dummy" object file must be created and the two "real" files must be combined into the "dummy" object file.
So, new makefile:
#
# Makefile for the mcp3202 driver.
#
obj-$(CONFIG_MCP3202) := mcp3202.o
mcp3202-objs := mcp3202_core.o mcp3202_pru.o
The original "mcp3202.c" was renamed to "mcp3202_core.c". The listed "mcp3202.o" does not need a corresponding .c file since it is created "out of thin air" by the make system by combining mcp3202_core.o and mcp3202_pru.o.
Not very elegant but explains why there's a lot of "_core.c" files strung through out the KERNEL build system. Sounds like an value-added opportunity for a Kernel guru to work on...