purpose of __devexit_p in driver files - c

Can anyone please tell me the purpose of __devexit_p part in driver files ?
I find __devexit_p is normally using with remove functions in the driver code
Example 1:
static struct i2c_driver lsm9ds0_driver = {
.driver = {
.owner = THIS_MODULE,
.name = LSM9DS0_DEV_NAME,
},
.probe = lsm9ds0_probe,
.remove = __devexit_p(lsm9ds0_remove),
.id_table = lsm9ds0_id,
};
Example 2:
static struct spi_driver light_driver = {
.driver = {
.name = "light",
.owner = THIS_MODULE,
},
.probe = light_probe,
.remove = __devexit_p(light_remove),
};
Is there any difference if I removed __devexit_p from above examples?
Will it affect the performance of the driver when __devexit_p removed?

Based on this LXR listing from 2.6.32:
/*
Functions marked as __devexit may be discarded at kernel link time,
depending on config options. Newer versions of binutils detect references
from retained sections to discarded sections and flag an error. Pointers to
__devexit functions must use __devexit_p(function_name), the wrapper will
insert either the function_name or NULL, depending on the config options.
*/
#if defined(MODULE) || defined(CONFIG_HOTPLUG)
#define __devexit_p(x) x
#else
#define __devexit_p(x) NULL
#endif
it seems to be used to conditionally expand it to the given parameter or NULL based on the code being compiled as part of a kernel module (MODULE) and on the CONFIG_HOTPLUG kernel option.

Related

What static struct in linux kernel code use for

Hi I am following the book Linux device driver development to write a driver in Linux. In an example code as below:
struct my_gpios {
int reset_gpio;
int led_gpio;
};
static struct my_gpiosneeded_gpios = {
.reset_gpio = 47;
.led_gpio = 41;
};
static struct resource needed_resources[] = {
[0] = { /* The first memory region */
.start = JZ4740_UDC_BASE_ADDR,
.end = JZ4740_UDC_BASE_ADDR + 0x10000 - 1,
.flags = IORESOURCE_MEM,
.name = "mem1",
},
[1] = {
.start = JZ4740_UDC_BASE_ADDR2,Platform Device Drivers
[ 126 ]
.end = JZ4740_UDC_BASE_ADDR2 + 0x10000 -1,
.flags = IORESOURCE_MEM,
.name = "mem2",
},
};
static struct platform_devicemy_device = {
.name = "my-platform-device",
.id = 0,
.dev = {
.platform_data = &needed_gpios,
},
.resource = needed_resources,
.num_resources = ARRY_SIZE(needed_resources),
};
platform_device_register(&my_device);
I do not understand the syntax static struct_gpiosneeded_gpios = {} meaning and why have a dot in .reset_gpio. And what is the meaning of the syntax static struct [] = {[0]={}, [1]={}}?
Could you please give me a reference link or keyword or example about static struct {.a = VALUE, .b = VALUE,};?
static struct something x = {
.field_one = 123,
.field_two = 456
};
This is a struct initialization syntax, standard from C99 (see here). This example creates a variable of type struct something named x, with fields field_one and field_two initialized to the specified values, and any other field initialized to 0. The static keyword is a storage duration specifier (see here).
static struct something x[] = {[0]={ ... }, [1]={ ... }};
This is a mix of both struct initialization and array initialization syntax, again standard from C99 (see here). This example creates an array x of variables of type struct something, the one at index 0 is initialized with the contents of the {...} initializer, and the same goes for the one at index 1. Since the greatest specified index is 1, the array size is 2.
I do not understand why they named the type is u32 or what is the purpose of __raw.
The u32 type is just a short alias for uint32_t.
I am not sure exactly where you saw __raw, since I don't seem to find anything like it in the kernel source. In any case, the Linux kernel as a series of compile-time annotations used for variables that have different purposes (__user, __rcu, etc). Those are not part of the C standard and frequently not even GCC extensions. They are mostly hints to be used by Sparse, the Linux kernel semantic checker.
Is there any standard or rule for naming the variable, macro, type,... in kernel?
Refer to the Linux kernel coding style documentation page for more information. I would suggest you to read it all before trying to do any kind of kernel programming. The more documentation pages you read, the better.
And what C standard i have to compliance when writing code in linux driver?
Use anything that is C99 or older and you will be fine. The Linux kernel code does not adhere to a single C standard, and various parts of the code aren't even standard compliant, but use GCC extensions. See here for more information.
You don't usually choose the standard when compiling, the kernel Makefile does this for you, and it should default to C90.
In any case, those are a lot of questions. If you have a specific question I would suggest you to ask it separately so that people are able to give you a focused and more extensive answer, since it's off topic to ask too broad or too many questions.

What is the use of of_device_id and i2c_device_id?

I was understanding an I2C driver for adxl34x sensor.
If I only keep of_device_id, my probe does not gets called, but if I include i2c_device_id probe gets called.
I checked for some explanation but I get to know that i2c_device_id is used for legacy purpose or board file matching.
Here I am using device tree.
How is it possible that i2c_device_id is making the device recognised?
Is there a dependency in I2C drivers to use both i2c_Device_id and of_device_id??
here is my understanding on this top
id_table is used for legacy i2c devices. See in this code
static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
const struct i2c_client *client)
{
while (id->name[0]) {
if (strcmp(client->name, id->name) == 0)
return id;
id++;
}
return NULL;
}
There is no device id table reference, while of_device_id
/**
* of_match_device - Tell if a struct device matches an of_device_id list
* #ids: array of of device match structures to search in
* #dev: the of device structure to match against
*
* Used by a driver to check whether an platform_device present in the
* system is in its list of supported devices.
*/
const struct of_device_id *of_match_device(const struct of_device_id *matches,
const struct device *dev)
{
if ((!matches) || (!dev->of_node))
return NULL;
return of_match_node(matches, dev->of_node);
}
Uses dev->of_node
So its safe to say both mechanism are isolated and does not depend on each other.
Then why my driver is not getting probed by only using this,
/*
static const struct i2c_device_id adxl34x_id[] = {
{ "adxl345", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adxl34x_id);
*/
#ifdef CONFIG_OF
static const struct of_device_id adxl34x_of_id[] = {
/*
* The ADXL346 is backward-compatible with the ADXL345. Differences are
* handled by runtime detection of the device model, there's thus no
* need for listing the "adi,adxl346" compatible value explicitly.
*/
{ .compatible = "adi,adxl345", },
/*
* Deprecated, DT nodes should use one or more of the device-specific
* compatible values "adi,adxl345" and "adi,adxl346".
*/
{ .compatible = "adi,adxl34x", },
{ }
};
MODULE_DEVICE_TABLE(of, adxl34x_of_id);
#endif
static struct i2c_driver adxl34x_driver = {
.driver = {
.name = "adxl34x",
//.pm = &adxl34x_i2c_pm,
.of_match_table = of_match_ptr(adxl34x_of_id),
},
.probe = adxl34x_i2c_probe,
.remove = adxl34x_i2c_remove,
//.id_table = adxl34x_id, /*commented i2c_device_id*/
};
Here are some links that I have gone through in order to get some understanding
https://patches.linaro.org/patch/16873/
https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-July/131965.html
https://i2c.wiki.kernel.org/index.php/OF_Modalias
I understood that first of_* style match will happen, then i2c_device_id type match.
In my case, then how of_* is not able to bind then?
Why i2c_device_table is needed if its legacy thing?
You are right. It is true that you need to pass id_table along with the driver structure for I2C if you are using probe callback.
This is because the earlier I2C driver framework used older style of probe function signature that required i2c_device_id to be passed as the second parameter. However, this has now been replaced with i2c_probe_new callback whose function signature shows that it no more needs i2c_device_id parameter anymore.
Here is a link to this code change for reference:
https://elixir.bootlin.com/linux/v5.16.9/source/include/linux/i2c.h#L281

Function pointer inside a constant struct

I'm using a driver written by someone else.
To access the driver functions, I have to use a function access struct like the one below: (defined in a header file, say, driver.h)
typedef struct _driver {
void (*init) (void); // init is supposed to point to _init
} const driver; // problem here with **const**
----------------------------------------------------------------------
void _init (void) { // defined in another file, say, driver.c
// init code
}
How can I make init point to _init ?
The following code works if the driver is not const:
driver dr;
dr.init = &_init; // modifying directly
((driver*)(&dr))->init = &_init; // modifying through a pointer
According to the documentation, the driver is supposed to be used as follows:
driver dr;
driver *pdr = &dr;
pdr->init();
In order for this code to work, dr.init must point _init, but I can't find it anywhere in the code.
Any input is greatly appreciated.
Best regards,
Sergey
Use an initializer, e.g.
driver dr = { _init };
rmartinjak's answer is right, but if you have gcc extensions enabled or using C99 and above, you can use designated initializers. Since your driver struct will probably have more members, this way will probably end up being cleaner looking.
driver dr = {
.init = _init,
/* .member = value, */
};

Replacing deprecated "dev_attrs" attribute with "dev_groups"

I'm trying to compile a Linux device driver (kernel module), however the module was last updated in April 2013 and of course it doesn't compile anymore on a recent (3.13) kernel, here's the error :
als_sys.c:99:2: error: unknown field ‘dev_attrs’ specified in initializer
I've searched already but all that I found were patches, there is no clear "tutorial" about updating an old module, the only thing I understood was that I need to use dev_groups instead, but it doesn't accept the same value as dev_attrs and I don't know how to adapt the existing code for that.
The code (some of it, the entire code can be found here) :
# als_sys.c
static ssize_t
illuminance_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct als_device *als = to_als_device(dev);
int illuminance;
int result;
result = als->ops->get_illuminance(als, &illuminance);
if (result)
return result;
if (!illuminance)
return sprintf(buf, "0\n");
else if (illuminance == -1)
return sprintf(buf, "-1\n");
else if (illuminance < -1)
return -ERANGE;
else
return sprintf(buf, "%d\n", illuminance);
}
# truncated - also "adjustment_show" is similar to this function so
# I didn't copy/paste it to save some space in the question
static struct device_attribute als_attrs[] = { # that's what I need to modify, but
__ATTR(illuminance, 0444, illuminance_show, NULL), # I have no clue what to
__ATTR(display_adjustment, 0444, adjustment_show, NULL), # put here instead
__ATTR_NULL,
};
# truncated
static struct class als_class = {
.name = "als",
.dev_release = als_release,
.dev_attrs = als_attrs, # line 99, that's where it fails
};
EDIT
As mentioned in the answer below, I changed the code like this :
static struct device_attribute als_attrs[] = {
__ATTR(illuminance, 0444, illuminance_show, NULL),
__ATTR(display_adjustment, 0444, adjustment_show, NULL),
__ATTR_NULL,
};
static const struct attribute_group als_attr_group = {
.attrs = als_attrs,
};
static struct class als_class = {
.name = "als",
.dev_release = als_release,
.dev_groups = als_attr_group, # line 103 - it fails here again
};
But I still get another error :
als_sys.c:103:2: error: initializer element is not constant
I've found this question which is about the same error however its answer is about a single attribute and I don't know how to adapt it for multiple ones.
Thanks for your help and have a nice day.
Indeed, dev_attrs was replaced with dev_groups in 3.13. In 3.12 they were both presented in struct. Look at 3.12 version and 3.13 version.
Anyway, there should not be a problem, because simple search for attribute_group gives you a lot of examples.
Simply put, you have to embed your dev_attrs inside dev_group:
static const struct attribute_group als_attr_group = {
.attrs = als_attrs,
};
And then use that attribute group in struct class.
There is also a handy macro ATTRIBUTE_GROUPS. See example usage https://lkml.org/lkml/2013/10/23/218.
EDIT:
Remove const declaration from attribute group like this:
static struct attribute_group als_attr_group = {
.attrs = als_attrs,
};
Because you can't initialize const struct with something that is not literal like 0xff or 'c'. See more detailes here.

EXT3 file operations

I am trying to follow how Linux deals with EXT3 files.
I am looking at fs/ext3/file.c where there are file operations that deal with the files are present:
const struct file_operations ext3_file_operations = {
.llseek = generic_file_llseek,
.read = do_sync_read,
.write = do_sync_write,
.aio_read = generic_file_aio_read,
.aio_write = generic_file_aio_write,
.unlocked_ioctl = ext3_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = ext3_compat_ioctl,
#endif
.mmap = generic_file_mmap,
.open = dquot_file_open,
.release = ext3_release_file,
.fsync = ext3_sync_file,
.splice_read = generic_file_splice_read,
.splice_write = generic_file_splice_write,
};
How can I find when does .open is replaced by the function "dquot_file_open" for example?
Should I follow the system call defined in fs/open.c:
SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
Or should I be looking at other functions?
I am working on Linux 3.7.6 for User-Mode-Linux
The Linux kernel is organized in an OOP manner (though written in C). The struct file_operations is really a class, the members (function pointers) are the function members ("methods" for Java heads) of the class. The code you quote serves to set up the ext3 object by filling in the function pointers. This is done at compile/link time.
The open(2) system call calls this indirectly, by finding out the struct file_operations relevant for the file system at hand, and calling its open member.
I'd suggest you take a look at the kernelnewbies page for an overall view and more detailed help.

Resources