How to dereference device_private in struct device - linux

I'm working on a driver in Linux. I'm working on getting some /sys file attributes in place that will make things nicer. In delivering what these attributes are to tell, the attribute functions must have access to some data that's stored by the driver. Because of how things appear to be made and stored, I thought I could use the device_private *p member of the struct device that comes from device_create(). Basically, it's like this:
for (i = 0; i < total; i++) {
pDevice = device_create(ahcip_class, NULL, /*no parent*/
MKDEV(AHCIP_MAJOR, AHCIP_MINOR + i), NULL, /*no additional info*/
DRIVER_NAME "%d", AHCIP_MINOR + i);
if (IS_ERR(pDevice)) {
ret = PTR_ERR(pDevice);
printk(KERN_ERR "%s:%d device_create failed AHCIP_MINOR %d\n",
__func__, __LINE__, (AHCIP_MINOR + i));
break;
}
mydevs[i].psysfs_dev = pDevice;
ret = sysfs_create_group(&pDevice->kobj, &attr_group);
if (!ret) {
pr_err("%s:%d failed in making the device attributes\n",
__func__, __LINE__);
goto build_udev_quick_out;
}
}
This doesn't yet show the assignment into the device_private pointer, but that's where I'm headed. Each new device made under this class will need the same attributes thus the group. Here's my single attribute that I'm starting with for "proof of concept"
static ahcip_dev *get_ahcip_dev(struct kobject *ko)
{
ahcip_dev *adev = NULL;
struct device *pdev = container_of(ko, struct device, kobj);
if (!pdev) {
pr_err("%s:%d unable to find device struct in kobject\n",
__func__, __LINE__);
return NULL;
}
/* **** problem dereferencing p **** */
adev = (ahcip_dev*)pdev->p->driver_data;
/* return the pointer anyway, but if it's null, print to klog */
if (!adev)
pr_err("%s:%d no ahcip_dev, private driver data is NULL\n",
__func__, __LINE__);
/* **** again problem dereferencing p **** */
return pdev->p->(ahcip_dev*)driver_data; // <--- problem here
}
static ssize_t pxis_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buff)
{
u32 pi = 0;
ahcip_dev *adev = get_ahcip_dev(kobj);
/* get_ahcip_dev() will print what happened, this needs to return
* error code
*/
if (!adev)
return -EIO;
pi = adev->port_index;
return sprintf(buff, "%08x\n", get_port_reg(adev->hba->ports[pi], 0x10));
}
I figured that, since device_create() returns a struct device* and I'm using that to make the device group, the struct kobject* that is coming into pxis_show is the member of the device structure made by device_create. If this is true, then I should be able to stuff some private data into that object and use it when the /sys files are accessed. However, when the lines of code marked above dereference the p member I get dereferencing pointer of incomplete type from gcc. I've determined that it's the struct device_private member of struct device that is incomplete but why? Is there a different structure I should be using? This seems to be something truly internally by the kernel.

For assign private data for device, you need to use void *drvdata parameter to device_create(). After creation, data can be accessed via dev_get_drvdata(pdev).
struct device_private is internal for device implementation. From description of this structure (drivers/base/base.h):
Nothing outside of the driver core should ever touch these fields.

Related

container_of isn't returning expected address

I'm not sure what I'm doing incorrectly but it's time for some extra eyes. I make a device with device_create() providing some "extra data" as follows:
pDevice = device_create(ahcip_class, NULL, /*no parent*/
MKDEV(AHCIP_MAJOR, AHCIP_MINOR + i), &mydevs[i],
DRIVER_NAME "%d", AHCIP_MINOR + i);
Expecting that my sysfs attribute function is going to take a pointer to the struct kobject member of struct device I do the following with my attribute function
static ahcip_dev *get_ahcip_dev(struct kobject *ko)
{
ahcip_dev *adev = NULL;
struct device *pdev = container_of(ko, struct device, kobj);
if (!pdev) {
pr_err("%s:%d unable to find device struct in kobject\n",
__func__, __LINE__);
return NULL;
}
/* some debugging stuff */
pr_info("%s:%d mydevs[0] %p\n", __func__, __LINE__, mydevs);
pr_info("%s:%d mydevs[1] %p\n", __func__, __LINE__, mydevs+1);
pr_info("%s:%d mydevs[0].psysfs_dev %p\n", __func__, __LINE__,
mydevs->psysfs_dev);
pr_info("%s:%d mydevs[1].psysfs_dev %p\n", __func__, __LINE__,
(mydevs + 1)->psysfs_dev);
pr_info("%s:%d pdev %p\n", __func__, __LINE__, pdev);
adev = (ahcip_dev*)dev_get_drvdata(pdev);
/* return the pointer anyway, but if it's null, print to klog */
if (!adev)
pr_err("%s:%d no ahcip_dev, private driver data is NULL\n",
__func__, __LINE__);
return adev;
}
static ssize_t pxis_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buff)
{
u32 pi = 0;
ahcip_dev *adev = get_ahcip_dev(kobj);
/* get_ahcip_dev() will print what happened, this needs to return
* error code
*/
if (!adev)
return -EIO;
pi = adev->port_index;
return sprintf(buff, "%08x\n", get_port_reg(adev->hba->ports[pi], 0x10));
}
The output (condensed) from the above function shows:
get_ahcip_dev:175 mydevs[1].psysfs_dev ffff88011b2b4800
get_ahcip_dev:176 pdev ffff88011b2b47f0
pdev in this case should point to the same memory location as mydevs[1].psysfs_dev but it's 16 bytes "earlier". What am I doing wrong?
I don't like to answer my own questions but this seems appropriate in this case. The root of the problem was a faulty assumption of what the attribute function needed to process. Attribute functions have this prototype you can view in context here
ssize_t (*show)(struct kobject *, struct attribute *,char *);
ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
Since the device_create() function returns a struct device object defined as follows (excerpt only, see full def here)
struct device {
struct device *parent;
struct device_private *p;
struct kobject kobj;
...
}
I assumed that it was this pointer that my attribute function must process. Reading through the description of the problem shows that when I used the container_of macro to get what I thought was the address of the containing struct device I was 16 bytes "to early." Notice, the first two fields of this structure are pointers. On a 64 bit system, which mine is, this is 16 bytes.
Because the function prototypes are defined as shown above, I assumed I was getting a reference to the kobj field. Instead, I was getting the actual struct device object. In other words, I was getting the address I wanted upon function entry and was still trying to find it.
Something about this may be documented in the labyrinth of Linux kernel documentation. If anyone knows of it, please put a link here. I read much but didn't see this one coming. I hope this question and answer helps some other kernel newbie.
Your example did not show how you created the sysfs attribute nor how your pxis_show() function was associated with it. Since you're trying to connect this attribute to a struct device, might you happen to be calling device_create_file() to create the sysfs node? If so, examining the callback prototypes of struct device_attribute might make more sense. You will see that the show/store callbacks look like:
ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf);
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
In which case that might better explain your extra offset issue--the first parameter is actually already pointing to your struct device, and not the embedded kobj member, so that performing a container_of() will take you back an additional 16 bytes.
You might be confusing the device_attribute callbacks with the struct sysfs_ops format, as they look similar, but notice the parameter types are different. In fact, there is a mapping from sysfs_ops to struct device_attribute as can be seen with the wrapper functions dev_attr_show and dev_attr_store as can be found here

how to get struct i2c_client *client structure inside the ioctl?

I am moving userspace sysfs interaction to the "/dev" using miscregister using ioctl method.
Can we resolve client structure(struct i2c_client) from Inode of please somebody tell how to get client structure inside ioctl. I need to do i2c transfer inside ioctl.
I referred this link :
http://stackoverflow.com/questions/2635038/inode-to-device-information
but coudln get any answer.
please someone give solution.
while you open your device in kernel using your open function. (this part of code is copied from one of the mainline drivers (drivers/i2c/i2c-dev.c) to make things easy for you)
my_i2c_device_open(struct inode *inode, struct file *file)
{
unsigned int minor = iminor(inode);
struct i2c_client *client;
struct i2c_adapter *adap;
struct i2c_dev *i2c_dev;
i2c_dev = i2c_dev_get_by_minor(minor);
if (!i2c_dev)
return -ENODEV;
adap = i2c_get_adapter(i2c_dev->adap->nr);
if (!adap)
return -ENODEV;
client = kzalloc(sizeof(*client), GFP_KERNEL);
if (!client) {
i2c_put_adapter(adap);
return -ENOMEM;
}
snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr);
client->adapter = adap;
file->private_data = client;
return 0;
}
when you call ioctl you can retrieve the i2c_client from the file pointer of your device:
static long my_i2c_device_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct i2c_client *client = file->private_data;
}
Hope this makes your life easy.'
This reference might help:
Reason to pass data using struct inode and struct file in Linux device driver programming
You build yourself a structure equivalent with "struct scull_dev" in the example above and you store there a reference to the i2c_client structure. In the IOCTL function you can retrieve later on the main control structure and the reference to the i2c_client through container_of.

IOCTL Method - Linux

I have an exam question and I can't quite see how to solve it.
A driver that needs the ioctl method to be implemented and tested.
I have to write the ioctl() method, the associated test program as well as the common IOCTL definitions.
The ioctl() method should only handle one command. In this command, I need to transmit a data structure from user space to kernel space.
Below is the structure shown:
struct data
{
     char label [10];
     int value;
}
The driver must print the IOCTL command data, using printk();
Device name is "/dev/mydevice"
The test program must validate driver mode using an initialized data structure.
Hope there are some that can help
thanks in advance
My suggestion:
static int f_on_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
int ret;
switch (cmd)
{
case PASS_STRUCT:
struct data pass_data;
ret = copy_from_user(&pass_data, arg, sizeof(*pass_data));
if(ret < 0)
{
printk("PASS_STRUCT\n");
return -1;
}
printk(KERN ALERT "Message PASS_STRUCT : %d and %c\n",pass_data.value, pass_data.label);
break;
default:
return ENOTTY;
}
return 0;
}
Definitions:
Common.h
#define SYSLED_IOC_MAGIC 'k'
#define PASS_STRUCT _IOW(SYSLED_IOC_MAGIC, 1, struct data)
The test program:
int main()
{
int fd = open("/dev/mydevice", O_RDWR);
data data_pass;
data_pass.value = 2;
data_pass.label = "hej";
ioctl(fd, PASS_STRUCT, &data_pass);
close(fd);
return 0;
}
Is this completely wrong??

Call to ioctl() on a usb device using usbfs does not work

I am trying to create my own driver for my Gamepad right now, I found out the original reason why I wanted to create it does not exist but I still want to do it for the experience. So please don't tell me there is a better way to do this than writing my own driver.
The part in kernelspace with the ioctl function that should be called is:
static int xpad_ioctl (struct usb_interface *intf, unsigned int code,void *buf) {
//struct usb_xpad *xpad = usb_get_intfdata(intf);
printk(KERN_INFO"(Ongy)IOCTL called\n");
//if (_IOC_TYPE(code) != XPAD_IOMAGIC) return -ENOTTY;
//if (_IOC_NR(code) > XPAD_IOMAX) return -ENOTTY;
switch(code){
case XPAD_IORMAP:
printk(KERN_INFO"(Ongy)IORMAP called\n");
break;
default:
return -EINVAL;
}
return 0;
}
static struct usb_driver xpad_driver =
{
.name = "Cyborg-V5-driver",
.probe = xpad_probe,
.disconnect = xpad_disconnect,
.unlocked_ioctl = xpad_ioctl,
.id_table = xpad_table,
};
The part in userspace to call it is (this is part of a Qt-application):
int openfile() {
char *device = "/dev/bus/usb/005/009";
printf("Opening device %s\n", device);
return open(device, /*O_RDONLY*/O_WRONLY | O_NONBLOCK );
}
[...] the closefile(int file_desc) is missing here, this and the openfile functions exist because of me not knowing one can call "::open()" when Qt overrides function calls.
void MainContainer::callioctl() {
int file_desc, ret_val;
errno = 0;
file_desc = openfile();
if (file_desc==-1){
printf("Ioctl notcalled because of: error %s\n", strerror(errno));
}
else
{
errno = 0;
//struct usbdevfs_getdriver* driver = (usbdevfs_getdriver*)malloc(sizeof(struct usbdevfs_getdriver));
struct mappingpair* pair = (mappingpair*)malloc(sizeof(struct mappingpair));
ret_val = ioctl(file_desc, XPAD_IORMAP, pair);
//printf("Drivername %s\n", driver->driver);
closefile(file_desc);
if (ret_val==-1) printf("Ioctl failed with error %s\n", strerror(errno));
else printf("Ioctl call successfull\n");
}
}
ok, the string to the file I open I get with a call to lsusb and change it by hand in the code, this is only for debugging and until I get the ioctl calls working
When I call the callioctl() it prints:
Ioctl failed with error Unpassender IOCTL (I/O-Control) für das Gerät
The German part means "wrong ioctl (I/O-Control) for the device" and nothing appears in dmesg, that is why I think my ioctl function in the driver is not called.
If you look at http://www.hep.by/gnu/kernel/usb/usbfs.html it says that to send an ioctl to the usb_driver device you need to do:
struct usbdevfs_ioctl {
int ifno;
int ioctl_code;
void *data;
};
/* user mode call looks like this.
* 'request' becomes the driver->ioctl() 'code' parameter.
* the size of 'param' is encoded in 'request', and that data
* is copied to or from the driver->ioctl() 'buf' parameter.
*/
static int
usbdev_ioctl (int fd, int ifno, unsigned request, void *param)
{
struct usbdevfs_ioctl wrapper;
wrapper.ifno = ifno;
wrapper.ioctl_code = request;
wrapper.data = param;
return ioctl (fd, USBDEVFS_IOCTL, &wrapper);
}
The documentation is listing usb device under /proc/bus so admittedly this may have changed.

Getting list of network devices inside the Linux kernel

I've been looking through net/core/dev.c and other files to try to find out how to get the list of network devices that are currently configured and it's proving to be a little difficult to find.
The end goal is to be able to get network device statistics using dev_get_stats in dev.c, but I need to know the current interfaces so I can grab the net_device struct to pass in. I'm having to do this inside the kernel as I'm writing a module which adds in a new /proc/ entry which relates to some statistics from the current network devices so from what I can gather this must be done inside the kernel.
If someone could point me to how to get the interfaces it would be much appreciated.
This ought to do the trick:
#include <linux/netdevice.h>
struct net_device *dev;
read_lock(&dev_base_lock);
dev = first_net_device(&init_net);
while (dev) {
printk(KERN_INFO "found [%s]\n", dev->name);
dev = next_net_device(dev);
}
read_unlock(&dev_base_lock);
Given a struct net *net identifying the net namespace that you are interested in, you should grab the dev_base_lock and use for_each_netdev():
read_lock(&dev_base_lock);
for_each_netdev(net, dev) {
/* Inspect dev */
}
read_unlock(&dev_base_lock);
(In newer kernels, you can use RCU instead, but that is probably an overcomplication in this case).
To obtain the net namespace to use, you should be registering your proc file with register_pernet_subsys():
static const struct file_operations foostats_seq_fops = {
.owner = THIS_MODULE,
.open = foostats_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = foostats_seq_release,
};
static int foo_proc_init_net(struct net *net)
{
if (!proc_net_fops_create(net, "foostats", S_IRUGO,
&foostats_seq_fops))
return -ENOMEM;
return 0;
}
static void foo_proc_exit_net(struct net *net)
{
proc_net_remove(net, "foostats");
}
static struct pernet_operations foo_proc_ops = {
.init = foo_proc_init_net,
.exit = foo_proc_exit_net,
};
register_pernet_subsys(&foo_proc_ops)
In your foostats_seq_open() function, you take a reference on the net namespace, and drop it in the release function:
static int foostats_seq_open(struct inode *inode, struct file *file)
{
int err;
struct net *net;
err = -ENXIO;
net = get_proc_net(inode);
if (net == NULL)
goto err_net;
err = single_open(file, foostats_seq_show, net);
if (err < 0)
goto err_open;
return 0;
err_open:
put_net(net);
err_net:
return err;
}
static int foostats_seq_release(struct inode *inode, struct file *file)
{
struct net *net = ((struct seq_file *)file->private_data)->private;
put_net(net);
return single_release(inode, file);
}
The foostats_seq_show() function can then obtain the net, walk the devices, gather the statistics and produce the output:
static int sockstat6_seq_show(struct seq_file *seq, void *v)
{
struct net *net = seq->private;
struct net_device *dev;
int foostat, barstat;
read_lock(&dev_base_lock);
for_each_netdev(net, dev) {
/* Inspect dev */
}
read_unlock(&dev_base_lock);
seq_printf(seq, "Foo: %d\n", foostat);
seq_printf(seq, "Bar: %d\n", barstat);
return 0;
}

Resources