Linux Module - I/O Memory Register read/write hangs the system - linux-device-driver

I am trying to read/write to a I/O Memory Register of a platform device but the system hangs as soon as it goes to the line where read/write is performed.
I was able to check the following:
request_mem_region returns OK
the correct physical addr was requested (ioremap is OK)
a valid logical address is returned; used this to read the
register; ioread32(logical_addr)
I am quite new to the linux kernel, is there a way that the I/O registers are disabled?
I checked /proc/iomem, and the memory region that I wish to access appears in the list.
Where to go from here?

I found the answer. Thank you for your response Longfield.
I forgot to check the name used by the driver. It didn't match the device name being registered. They should match.

Related

Cache configuration for DMA device access on ARM Cortex-A72

I am writing an operating system for the raspberry pi.
I have a problem with the sdcard driver for the custom sdhost controller (emmc2)
of the raspberry-pi 4 (Cortex-A72, ARMv8-A, bcm2711 chipset).
Without using sdma everything works. With sdma, read works, but after writing sectors, the data on the sdcard sometimes contains invalid data.
For the sdma data transfer, I use a transfer buffer with a device type memory attribute (nGnRnE). When I use a fresh data buffer for the dma write transfer, the data on the sdcard is correct. But when I reuse the same buffer for the next write, then the sector on the sdcard partially contains data from the previous buffer content.
Maybe this is a cache coherency problem. I have enabled all caches (I and D). In the ARM manuals there is a talk of the SCU (snoop control unit) and I don't know whether I have do bother about the SCU.
My questions are:
Is it necessary to enable the SCU on a Cortex-A72 and how can this be done ?
What other things have to be kept in mind when using dma for device access ?
I found the solution for my problem:
On the raspberry pi 4 (bcm2711 chip), the physical addresses that are written into the registers of a dma engine must be legacy master addresses. The legacy master addresses are in the range 0xC0000000-0xFFFFFFFF. So I have to add 0xC0000000 to the values of the physical addresses that are written into the registers of the sdhci controller.
The documentation can be found here:
https://datasheets.raspberrypi.org/bcm2711/bcm2711-peripherals.pdf
1.2. Address map
1.2.4. Legacy master addresses
The answer to the other SCU question is: it is not necessary to enable the SCU on the Raspberry Pi 4 when the caches are enabled.

MINIX: sys_call: ipc mask denied SENDREC from 1 to 1

In MINIX 3.2.1, I want to create a new system call in VFS server which will be given a filename as a parameter and will print this certain file's inode number.
So in order to retrieve the inode of the file by its name I want to use the default system call:
int stat(char *name,struct stat *buffer)
http://minix1.woodhull.com/manpages/man2/stat.2.html
in the body of my new system call handler which is
int mycall_1(void);
inside `/usr/src/servers/vfs/misc.c
But when I test the new system call, at the point where the stat system call should be invoked, it actually won't and instead it's printing the message:
sys_call: ipc mask denied SENDREC from 1 to 1
After some research, I found that this possibly happens because the VFS server tries to send a message to itself, as stat is actually implemented inside VFS server, and so ipc mask denied this sendrec() call. So I have to edit some configuration file in order to give the right permission for this communication to happen.
But I'm not sure if what I have understood is right and also do not know which file should Ι edit to give the appropriate permissions. So, if someone could enlighten me on this issue, I would be grateful.
Thanks in advance.
You understood it correctly. But the solution is not to continue "fixing the permissions" which are here just to prevent to shot yourself in the foot: it would only allow the system to more badly brocken.
Rather, you need to perform the steps that VFS do when it services a STAT request, starting after it cracked the message.

Simple Char device driver

I have written a simple char driver code. I am trying to register my device. I can see my device name in /proc/devices file with major number. But after registration I am unable to see my device in /dev directory..I used register_chrdev() call,it is returning non negative value..I also tried using cdev_init() and cdev_add() calls but still the same thing is happening.
udev creates the /dev entry. To trigger udev, the driver needs to call device_create() which creates an entry under /sys/dev along with the device name.

writing device driver in linux -- interupt handler

I am trying to write a loadable device driver.. which is capable to act on external event. please clarify following points.
1> modprob command is used to add remove modules to kernel. Does it applies to static modules ?
can modprobe or rmmod --- remove static module of linux kernel.
2> If interrupt comes i will save data & schedule the bottom half. Now when the bottom half completes its task how shall i inform application at user space that data is available.
3> I am thinking to use entry in debugfs to transfer data between application & driver. So is it feasible that my device driver & my user space application -- by using MAP() system call map same area of an file in debufs & exchange data between each other ?
modprob command is used to add remove modules to kernel. Does it applies to static modules ? can modprobe or rmmod --- remove static module of linux kernel.
If you mean by static module = a module that is compiled as part of the linux kernel (and not as a separate loadable module) then the answer is; no you cannot.
If interrupt comes i will save data & schedule the bottom half. Now when the bottom half completes its task how shall i inform application at user space that data is available.
If the user space app runs in polling mode, you can notify it by ioctl, or sysfs/procfs file. but if the user space app need to be notified in event-driver manner, then use netlink socket.
I am thinking to use entry in debugfs to transfer data between application & driver. So is it feasible that my device driver & my user space application -- by using MAP() system call map same area of an file in debufs & exchange data between each other ?
the way a user space app read/writes debugfs is by simply reading/writing the debugfs file (it's under /proc/.. or /sys/.., so you can "open" the file, get the file descriptor, then read/write - as if it was a regular file).

Getting the IO count

I am using xen hypervisor. I am trying to get the IO count of the VMs running on top of the xen hypervisor. Can someone suggest me some way or tool to get the IO count ? I tried using xenmon and virt-top. Virt-top doesnt give any value and xenmon always shows 0. Any suggestions to get the number of read or write calls made by a VM or the read and write(Block IO) bandwidth of a particular VM. Thanks !
Regards,
Sethu
You can read this directly from sysfs on most systems. You want to open the following directory:
/sys/devices/xen-backend
And look for directories starting with vbd-
The nomenclature is:
vbd-{domain_id}-{vbd_id}/statistics
Inside, you'll find what you need, which is:
br_req - Number of block read requests
oo_req - Number of 'out of' requests (no room left in list to service any given request)
rd_req - Number of read requests
rd_sect - Number of sectors read
wr_sect - Number of sectors written
The br_req will be an aggregate count of things like write barriers, aborts, etc.
Note, for this to work, The kernel has to be told to export Xen attributes via sysfs, but most Xen packages have this enabled. Additionally, the location in sysfs might be different with earlier versions of Xen.
have you tried xentop?
There is also bwm-ng (check your distro). It shows block utilization per disk (real/virtual). If you know the name of the virtual disk attached to the VM, then you can use bwm-ng to get those stats.