Pcd driver with multiple devices code implementation part-7
In this article, let’s include a check_permission functionality to our driver. First of all, whenever the user application tries to open your device file, it actually uses open system call.
If you just closely observe this open system call(as shown in Figure 1), you can see that there is a field to indicate flag. What are these flags?
These flags could be, as this man page says here, the argument flags must include one of the following access modes.
That means the user application is going to indicate the access modes in the flags field, the access modes could be read-only, write-only, or read-write.
When this system call is issued, your driver’s open method gets called. And this access mode is supplied to your open method through the file pointer. That means if you check the struct file, a data structure. Because, as you know, that your drivers open method gets a pointer to this a struct file kernel object.
Here is a field f_mode. So, this access mode is actually stored in the field f_mode in the struct file kernel object.
That means, in your drivers open method, you should check this field.
Let’s understand how to decode this field. Remember that this is one of the fields of struct file defined in linux/fs.h.
You can check this field in your driver to understand access mode requested from the user space application. f_mode has bit fields to indicate access modes read or write. In order to decode that bit fields, you have to use these macros. FMODE_READ and FMODE_WRITE.
These macros actually defined here, as shown in Figure 4. You have to use these macros. FMODE_READ and FMODE_WRITE.
Now, let’s see how to decode this field.
Suppose, in your driver, you access the file pointer, and then you get the f_mode field. You have to do a bitwise & here. If you do bitwise & with this macro, then if it is true, if the result is true, then that means the file is opened for just read or read-write. This macro checks whether the read bit is set or not in this access mode field.
And similarly, if you do this if you use the macro WRITE, and if you do bitwise & operation with this value, then if this is true, then the file is opened for just write or read-write.
If you want to check exclusively for read-only, then you should be doing something like this. First, check whether it is opened for read. If this is true and you have to use here logical && and it shouldn’t be open for WRITE. That’s why this field must be false.
So, if this is false and the negation of false becomes true. Then only you can conclude that the file is opened for read-only.
I hope you get this logic. The same logic we are going to use in our check_permission function. Let’s get back to our editor, and let’s start coding. Now, let’s implement this check_permission. For this function.
I’m going to pass two arguments. One is device permission_field. So, that I can get by pcdev_data->perm field. And after that, I’m going to pass another argument that is the f_mode field of the file pointer.
Let’s go to the check_permission, which is right here. And let’s create some receiving variables, I call it as dev_perm, and I would call it as mode, or access mode, or something. acc _mode. What are our device permissions? Read-only, write-only, and read-write. Let’s create some macros to define that. #define, let me create one macro RDONLY, and the value is 0x1. Just assumed values, you can give whatever you want. WRONLY 0x10. And #define RDWR 0x11
Let me cut this code, and I would paste here. We would have created these macros when we initialized this structure. Here, in the permission field, let’s use those macros. RDONLY, this is WRONLY, and this is RDWR.
Let’s get back to the function. First, you have to check. If the device permission is, if it is read-write, then you need not to check the access mode. Just return 0.
if(dev_perm == RDONLY), then you have to check the access mode. Let me write like this. if(dev_perm== RDONLY) and logical &&. So, you have to use the access mode, acc_mode, decode it. Decode with a FMODE_READ. If this is true, and you have to use one more logical &&. The write bit field should be 0. You should confirm that. Because this is only for read-only. And acc_mode. Check for write field, FMODE_WRITE. This becomes a complex comparison.
So, let’s do one thing. Let’s put this in a separate parenthesis.
Let me explain once again. if(dev_perm == RDONLY) && if the file is opened for read and if the file is not opened for write. That you should confirm. That’s why I should use Negation. So, if the file is not opened for write, then negation of that would become true, then we can confirm that this is the read-only access. If this whole statement is true, then we just return 0.
And similarly, you have to do it for write-only. Let me copy these two. Let’s do for write-only. If the device permission is write-only, and access mode compare with write and make sure that it is not opened for read. So, this ensures read-only access. Otherwise, just return -EPERM.
This would be our check_permission function, and with this change, we are ready to test now. First of all, let’s confirm whether this builds or not. Complete up to here and in the next article, let’s test it. I’ll see you in the next article.
FastBit Embedded Brain Academy Courses
Click here: https://fastbitlab.com/course1