What is the use of 'i2c_get_clientdata" and "i2c_set_clientdata" - linux-kernel

I have been studying I2C driver (client) code for a while.
I have seen this function "i2c_get_clientdata" and "i2c_set_clientdata" every where.
I have seen the this question here .
Use of pointer to structure instead of creating static local copy
Some times i think like it is like "container_of" macro to get a pointer to the structure.
But still i didn't understood properly why to use it and when to use it.
Below i am posting a sample code where I see its usage.
If any one could help me understand why it is used there and when we shall use it when we write our own drivers.
struct max6875_data {
struct i2c_client *fake_client;
struct mutex update_lock;
u32 valid;
u8 data[USER_EEPROM_SIZE];
unsigned long last_updated[USER_EEPROM_SLICES];
};
static ssize_t max6875_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
struct i2c_client *client = kobj_to_i2c_client(kobj);
struct max6875_data *data = i2c_get_clientdata(client);
int slice, max_slice;
if (off > USER_EEPROM_SIZE)
return 0;
if (off + count > USER_EEPROM_SIZE)
count = USER_EEPROM_SIZE - off;
/* refresh slices which contain requested bytes */
max_slice = (off + count - 1) >> SLICE_BITS;
for (slice = (off >> SLICE_BITS); slice <= max_slice; slice++)
max6875_update_slice(client, slice);
memcpy(buf, &data->data[off], count);
return count;
}

Those functions are used to get/set the void *driver_data pointer that is part of the struct device, itself part of struct i2c_client.
This is a void pointer that is for the driver to use. One would use this pointer mainly to pass driver related data around.
That is what is happening in your example. The max6875_read is a callback getting a structu kobject. That kobject is an i2c_client which is enough to communicate with the underlying device using the driver_data pointer here allows to get back the driver related data (instead of using global variables for example).

Related

Another void* topic; I just have to ask because I am confused

Ok, muddling though Stack on the particulars about void*, books like The C Programming Language (K&R) and The C++ Programming Language (Stroustrup). What have I learned? That void* is a generic pointer with no type inferred. It requires a cast to any defined type and printing void* just yields the address.
What else do I know? void* can't be dereferenced and thus far remains the one item in C/C++ from which I have discovered much written about but little understanding imparted.
I understand that it must be cast such as *(char*)void* but what makes no sense to me for a generic pointer is that I must somehow already know what type I need in order to grab a value. I'm a Java programmer; I understand generic types but this is something I struggle with.
So I wrote some code
typedef struct node
{
void* data;
node* link;
}Node;
typedef struct list
{
Node* head;
}List;
Node* add_new(void* data, Node* link);
void show(Node* head);
Node* add_new(void* data, Node* link)
{
Node* newNode = new Node();
newNode->data = data;
newNode->link = link;
return newNode;
}
void show(Node* head)
{
while (head != nullptr)
{
std::cout << head->data;
head = head->link;
}
}
int main()
{
List list;
list.head = nullptr;
list.head = add_new("My Name", list.head);
list.head = add_new("Your Name", list.head);
list.head = add_new("Our Name", list.head);
show(list.head);
fgetc(stdin);
return 0;
}
I'll handle the memory deallocation later. Assuming I have no understanding of the type stored in void*, how do I get the value out? This implies I already need to know the type, and this reveals nothing about the generic nature of void* while I follow what is here although still no understanding.
Why am I expecting void* to cooperate and the compiler to automatically cast out the type that is hidden internally in some register on the heap or stack?
I'll handle the memory deallocation later. Assuming I have no understanding of the type stored in void*, how do I get the value out?
You can't. You must know the valid types that the pointer can be cast to before you can dereference it.
Here are couple of options for using a generic type:
If you are able to use a C++17 compiler, you may use std::any.
If you are able to use the boost libraries, you may use boost::any.
Unlike Java, you are working with memory pointers in C/C++. There is no encapsulation whatsoever. The void * type means the variable is an address in memory. Anything can be stored there. With a type like int * you tell the compiler what you are referring to. Besides the compiler knows the size of the type (say 4 bytes for int) and the address will be a multiple of 4 in that case (granularity/memory alignment). On top, if you give the compiler the type it will perform consistency checks at compilation time. Not after. This is not happening with void *.
In a nutshell, you are working bare metal. The types are compiler directives and do not hold runtime information. Nor does it track the objects you are dynamically creating. It is merely a segment in memory that is allocated where you can eventually store anything.
The main reason to use void* is that different things may be pointed at. Thus, I may pass in an int* or Node* or anything else. But unless you know either the type or the length, you can't do anything with it.
But if you know the length, you can handle the memory pointed at without knowing the type. Casting it as a char* is used because it is a single byte, so if I have a void* and a number of bytes, I can copy the memory somewhere else, or zero it out.
Additionally, if it is a pointer to a class, but you don't know if it is a parent or inherited class, you may be able to assume one and find out a flag inside the data which tells you which one. But no matter what, when you want to do much beyond passing it to another function, you need to cast it as something. char* is just the easiest single byte value to use.
Your confusion derived from habit to deal with Java programs. Java code is set of instruction for a virtual machine, where function of RAM is given to a sort of database, which stores name, type, size and data of each object. Programming language you're learning now is meant to be compiled into instruction for CPU, with same organization of memory as underlying OS have. Existing model used by C and C++ languages is some abstract built on top of most of popular OSes in way that code would work effectively after being compiled for that platform and OS. Naturally that organization doesn't involve string data about type, except for famous RTTI in C++.
For your case RTTI cannot be used directly, unless you would create a wrapper around your naked pointer, which would store the data.
In fact C++ library contains a vast collection of container class templates that are useable and portable, if they are defined by ISO standard. 3/4 of standard is just description of library often referred as STL. Use of them is preferable over working with naked pointers, unless you mean to create own container for some reason. For particular task only C++17 standard offered std::any class, previously present in boost library. Naturally, it is possible to reimplement it, or, in some cases, to replace by std::variant.
Assuming I have no understanding of the type stored in void*, how do I get the value out
You don't.
What you can do is record the type stored in the void*.
In c, void* is used to pass around a binary chunk of data that points at something through one layer of abstraction, and recieve it at the other end, casting it back to the type that the code knows it will be passed.
void do_callback( void(*pfun)(void*), void* pdata ) {
pfun(pdata);
}
void print_int( void* pint ) {
printf( "%d", *(int*)pint );
}
int main() {
int x = 7;
do_callback( print_int, &x );
}
here, we forget thet ype of &x, pass it through do_callback.
It is later passed to code inside do_callback or elsewhere that knows that the void* is actually an int*. So it casts it back and uses it as an int.
The void* and the consumer void(*)(void*) are coupled. The above code is "provably correct", but the proof does not lie in the type system; instead, it depends on the fact we only use that void* in a context that knows it is an int*.
In C++ you can use void* similarly. But you can also get fancy.
Suppose you want a pointer to anything printable. Something is printable if it can be << to a std::ostream.
struct printable {
void const* ptr = 0;
void(*print_f)(std::ostream&, void const*) = 0;
printable() {}
printable(printable&&)=default;
printable(printable const&)=default;
printable& operator=(printable&&)=default;
printable& operator=(printable const&)=default;
template<class T,std::size_t N>
printable( T(&t)[N] ):
ptr( t ),
print_f( []( std::ostream& os, void const* pt) {
T* ptr = (T*)pt;
for (std::size_t i = 0; i < N; ++i)
os << ptr[i];
})
{}
template<std::size_t N>
printable( char(&t)[N] ):
ptr( t ),
print_f( []( std::ostream& os, void const* pt) {
os << (char const*)pt;
})
{}
template<class T,
std::enable_if_t<!std::is_same<std::decay_t<T>, printable>{}, int> =0
>
printable( T&& t ):
ptr( std::addressof(t) ),
print_f( []( std::ostream& os, void const* pt) {
os << *(std::remove_reference_t<T>*)pt;
})
{}
friend
std::ostream& operator<<( std::ostream& os, printable self ) {
self.print_f( os, self.ptr );
return os;
}
explicit operator bool()const{ return print_f; }
};
what I just did is a technique called "type erasure" in C++ (vaguely similar to Java type erasure).
void send_to_log( printable p ) {
std::cerr << p;
}
Live example.
Here we created an ad-hoc "virtual" interface to the concept of printing on a type.
The type need not support any actual interface (no binary layout requirements), it just has to support a certain syntax.
We create our own virtual dispatch table system for an arbitrary type.
This is used in the C++ standard library. In c++11 there is std::function<Signature>, and in c++17 there is std::any.
std::any is void* that knows how to destroy and copy its contents, and if you know the type you can cast it back to the original type. You can also query it and ask it if it a specific type.
Mixing std::any with the above type-erasure techinque lets you create regular types (that behave like values, not references) with arbitrary duck-typed interfaces.

copy_from_user is fetching unexpected data

I want to use the write sycall for copying a struct
from userspace to kernel.
In both user and kernel space, the struct is defined as
struct packet{
unsigned char packet[256];
int length;
}__attribute__ ((packed));
User space uses a local variable of type struct packet and passes it to the write syscall.
struct packet p;
/* ... (fill in data) */
printf("packet.length: %d\n",packet.length); /* looks correct */
result = write(uartFD, &p, sizeof(struct packet));
The kernel side looks like this, checking for correct length is done, just removed from example.
/* write syscall */
ssize_t packet_write(
struct file *file_ptr,
const char __user *user_buffer,
size_t count, loff_t *position)
{
struct packet p;
int retval;
if (copy_from_user((void*)&p, user_buffer, sizeof(struct packet))){
retval = -EACCES;
goto err;
}
/* looks wrong - different numbers like 96373062 or 96373958 */
printk("packet length: %d\n",p.length);
The opposite direction using read sycall is working as expected:
/* read syscall */
struct packet p;
/* ... (fill in data) */
copy_to_user(user_buffer, (void*)&p, sizeof(struct packet));
/* userspace */
read(uartFD, (void*)&packet, sizeof(struct packet));
What am I doing wrong with write syscall?
(Posted on behalf of the OP).
This is solved - it was my own silly. Both copying an integer and an unsigned char buffer separately was working, so it had to be something about the struct.
One site was packed, the other was not... reusing old code...

how to define a struct msghdr to send UDP packet in linux kernel without copying data from user space

I'm trying to send a Hello message from linux kernel after a UDP connect (which calls the function ip4_datagram_connect). Since the protocol number in this message needs to be different than UDP (This is a custom protocol which I'm building with UDP as the base code), I can't use the netpoll API.
So I'm trying to use the functions (picked up from udp_sendmsg())-
ip_make_skb(struct sock *sk,
struct flowi4 *fl4,
int getfrag(void *from, char *to, int offset,
int len, int odd, struct sk_buff *skb),
void *from, int length, int transhdrlen,
struct ipcm_cookie *ipc, struct rtable **rtp,
unsigned int flags)
to generate the sk_buff and
int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4)
to send out the generated sk_buff.
My problem is, the function ip_make_skb requires the pointers *from and length which in the udp_sendmsg function are the pointer to and the length of the data in the user space(+ length of udphdr) and then ip_make_skb() copies the data from the userspace. Since I'm just sending a Hello message from the kernel, this is a wasteful step for me (I don't need any data from the user space).
So can I just set the *from pointer to some dummy location and length to zero(+sizeof(struct udphdr))? If yes, what kind of value for *from will be appropriate?
Or is this completely wrong and I should do something else?
Edit 1: For now, I'm doing this
void *from = "Hello";
This will give me a valid pointer in the memory, but I feel it's a dirty way to do this. Tt works though.

How to know the buffer size passed from user space?

I'm trying to develop a new syscall for the linux kernel. This syscall will write info on the user buffer that is taken as argument, e.g.:
asmlinkage int new_syscall(..., char *buffer,...){...}
In user space this buffer is statically allocated as:
char buffer[10000];
There's a way (as sizeof() in the user level) to know the whole buffer size (10000 in this case)?
I have tried strlen_user(buffer) but it returns me the length of the string that is currently into the buffer, so if the buffer is empty it returns 0.
You can try passing structure which will contain the buffer pointer & the size of the buffer. But the same structure should also be defined in both user-space application & inside your system-call's code in kernel.
struct new_struct
{
void *p; //set this pointer to your buffer...
int size;
};
//from user-application...
int main()
{
....
struct new_struct req_kernel;
your_system_call_function(...,(void *)&req_kernel,...);
}
........................................................................................
//this is inside your kernel...
your_system_call(...,char __user optval,...)
{
.....
struct new_struct req;
if (copy_from_user(&req, optval, sizeof(req)))
return -EFAULT;
//now you have the address or pointer & size of the buffer
//which you want in kernel with struct req...
}

Using struct causes kernel panic?

I'm taking my first crack at writing some linux kernel code, and I'm hitting a weird kernel panic.
I have a linked list I am maintaining with the kernel's built-in macros (include/linux/list.h). If the list is empty, I allocate an instance of the following structure:
struct time_span
{
struct timeval start;
struct timeval end;
};
and point to it with a pointer called "tmp". I add tmp to the list I'm maintaining with list_add_tail().
Later, if the list is not empty (I'm trying to test with one list item to simplify debugging), I point to the first item in the list with tmp and try to print out the contents of tmp->end.tv_sec. Unfortunately, this causes a kernel panic.
tmp is not NULL (I check at run-time) and neither is "tmp->end" (I am able to print both). It's only when I try to access one of the fields in "end" that I get a kernel panic. I've never seen something like this before -- does anyone have any ideas?
Thanks for any assistance!
-------EDIT------
Code example (this lives in a function that will be called repeatedly):
// .........
struct timeval now_tv;
do_gettimeofday(&now_tv);
if(!list_empty(&(my_list.time_list)))
{
tmp = list_first_entry(&(my_list.time_list), struct time_span, time_list);
if(tmp != NULL)
{
tmp->end.tv_sec = now_tv.tv_sec; // THIS BREAKS
// Attempting to print "tmp->end.tv_sec" also breaks.
tmp->end.tv_usec = now_tv.tv_usec;
}
}
// .........
if(list_empty(&(my_list.time_list)))
{
new_time_span = (struct time_span *) kmalloc(sizeof(struct time_span), GFP_KERNEL);
INIT_LIST_HEAD(&(new_time_span->time_list));
list_add_tail(&(new_time_span->time_list), &(my_list.time_list));
do_gettimeofday(&(new_time_span->start));
}
// ........
You're missing some fundamentals about Linux linked lists.
The following should change:
struct time_span
{
struct timeval start;
struct timeval end;
};
To:
struct time_span
{
struct timeval start;
struct timeval end;
struct list_head time_list;
}
When using Linux linked lists you should put the struct list_head inside your struct that you want a list of.
In the code below, you're allocating a type struct time_span and referencing a variable named time_list inside the allocated variable new_time_span... but you haven't added that to your struct above.
// .........
struct timeval now_tv;
do_gettimeofday(&now_tv);
if(!list_empty(&(my_list.time_list)))
{
tmp = list_first_entry(&(my_list.time_list), struct time_span, time_list);
if(tmp != NULL)
{
tmp->end.tv_sec = now_tv.tv_sec; // THIS BREAKS
// Attempting to print "tmp->end.tv_sec" also breaks.
tmp->end.tv_usec = now_tv.tv_usec;
}
}
Based on the information you've provided, I don't know why the above breaks. Maybe it's just that tmp is a pointer pointing to garbage and that's why it crashes? If you have a kernel debugger setup it's easy to verify.
// .........
if(list_empty(&(my_list.time_list)))
{
new_time_span = (struct time_span *) kmalloc(sizeof(struct time_span), GFP_KERNEL);
INIT_LIST_HEAD(&(new_time_span->time_list));
list_add_tail(&(new_time_span->time_list), &(my_list.time_list));
do_gettimeofday(&(new_time_span->start));
}
// ........
Here are some good articles that should help:
http://kernelnewbies.org/FAQ/LinkedLists
http://sumanadak.blogspot.com/2006/09/linux-kernel-linked-list.html

Resources