Where the probe() function's argument comes from? - linux

I'm studying linux device driver. currently, I understand flows of device driver approximatively, but I dont know how probe() function gets its arguments.
For example, here is my code and this is based on kernel 3.10.
static int gpio_led_probe(struct platform_device *pdev) {
struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
struct gpio_leds_priv *priv;
....
priv = gpio_leds_create_of(pdev);
....
}
As like this, the argument 'pdev' is using for various point of source. I'm understading when probe() called and it's role, but I cannot find where the data 'pdev' comes from.
thanks for read my thread, and sorry that my english is not good.

platform device specific data while probing comes from the platform setup code or from device tree.
you can find the related code in arch/arm/borad/device files
struct platform_device embedded with platform_data structure where you will pass the platform related data to the drivers.
in modern kernels platform data is passed to device drivers through device tree. device tree can be found in /arch/arm/boot/dts/your_device

You can provide the platform device information by filling the platform_device structure or you have to provide your device information in device tree, during system bootup, platform_device structure gets populated based on the device tree information.In latest kernel usually we use device tree to get the device information.

Related

Need to find and open a USB serial device on linux

I'm writing a small C application to run on my (Linux) QNAP NAS that will talk to an Arduino (I have no difficulty with any of the USB code for the arduino). (The arduino has a trusted application on it that accepts text commands via USB serial.)
My wish was to find it using the USB vendor/product IDs (only half implemented at the moment). What I have so far (see below) works quite nicely in that it does find the device.
// runs on NAS
#include <stdio.h>
#include <usb.h>
main () {
struct usb_bus *bus;
struct usb_device *dev;
usb_init();
usb_find_busses();
usb_find_devices();
for (bus = usb_busses; bus; bus = bus->next) {
for (dev = bus->devices; dev; dev = dev->next) {
printf("Trying %s/%s\n", bus->dirname, dev->filename);
printf("\tVendor = 0x%04x\n", dev->descriptor.idVendor);
printf("\tBus = 0x%03x\n", bus->location);
printf("\tFile = %s\n", dev->filename);
if (dev->descriptor.idVendor==0x403) {
printf("\t HEY, THIS IS MINE!\n");
usb_dev_handle *handle = usb_open(dev);
printf("\t HANDLE 0x%08x\n", (int) handle);
//printf(handle, "1,5,62,75\n");
usb_close(handle);
}
}
}
}
The trouble is that now I want to send/receive a little bit of text with the device and I don't know how to do that.
I have expected I should be generating a device name from something in the usb_device struct and then open it like a file (like one would do on Windows).
If that's correct, I need to know the correct way to find out the device name...
I believe I'm using libusb.
I happen to know that -- as currently configured/connected -- it's ttyUSB0 but I'd like to know that using code.
thank you!
I suggest using libusbp. It is a C library with a C++ wrapper, and there is example code showing how to get the name of a serial port based on the vendor ID and product ID of the USB device:
https://github.com/pololu/libusbp/blob/master/examples/port_name/port_name.cpp
libusb is a library used for low level communication with USB devices. But when your communication is limited just to reading device's USB descriptor - libusb is not the best tool.
Linux systems use udev subsystem to manage hot-plug devices. udev reads descriptors of all plugged USB devices and stores them in its database. libudev is the library that you should use to get such info like device names of enumerated devices. In your case you need to remember that usb_device and usb_interface are separate things - only the latter would have the tty device file assigned to it.
Alternatively you could just use udev config to assign a constant device name to your specific device. So you would not have to be looking for it.

Linux PCIe Driver: What to use for private data structure?

I'm creating my first PCIe driver for Linux and have a question regarding which structure to use for the pci_set_drvdata() function.
The PCIe hardware is built in house and we will be using DMA to send data to and from the device. It is not a sound card or any other subsystem which needs to be plugged into the kernel.
When I look at examples there seems to be a specific struct to fill in and then send to pci_set_drvdata().
What do I fill in for this case? Do I simply ignore this and send in a blank structure? The line I am referring to in any PCIe driver is:
struct structure_in_question *my_struct;
my_struct = kzalloc( sizeof(*my_struct), GFP_KERNEL) );
This is usually found in the probe() function.
That function is used for associating with the device private data that cannot be supplied any other way. If there is no such data then the function should simply not be used.
It is a convenient way for example to save a pointer to a local dynamically allocated device context in the device probe callback and then retrieve it back with pci_get_drvdata in the device remove callback and do a proper cleanup of the context.

defining platform devices in - Linux kernel

I am refering following li k to decribe all the drivers used in my embedded Arm linux board as platform devices, need few points to be clarified. Please suggest on these.
http://thomas.enix.org/pub/conf/rmll2010/kernel-architecture-for-drivers.pdf
=============== Defining platform driver ==================
static struct platform_driver serial_imx_driver = {
.probe = serial_imx_probe,
.remove = serial_imx_remove,
.driver = {
.name = "imx-uart",
.owner = THIS_MODULE,
},
};
================= Defining a platform device ================
static struct platform_device imx_uart1_device = {
.name = "imx-uart",
.id = 0,
.num_resources = ARRAY_SIZE(imx_uart1_resources),
.resource = imx_uart1_resources,
.dev = {
.platform_data = &uart_pdata,
}
};
======== Kernel start up code location - /arch/arm/mach-imx/mx1ads.c ===========
static struct platform_device *devices[] __initdata = {
&cs89x0_device,
&imx_uart1_device,
&imx_uart2_device,
};
static void __init mx1ads_init(void)
{
[...]
platform_add_devices(devices, ARRAY_SIZE(devices));
[...]
}
MACHINE_START(MX1ADS, "Freescale MX1ADS")
[...]
.init_machine = mx1ads_init,
MACHINE_END
===============================
In linux /drivers/ folder if i have 10 folders for 10 different platform drivers. And i want only 6 drivers to be included in kernel source ?
So how will my kernel come to know which driver to include ?
Are platform drivers compiled as modules or statically compiled in the kernel ?
Also what happens when we call platform_add_devices() system call ?
Does all the platform drivers which are included in kernel are loaded into ram before call to platform_add_devices() system call is made ?
At Which path/file in kernel source i can define all platform devices used in my embedded linux system (means where all platform devices used on board are described) ?
Basically platform drivers are registered in the board files (for example /arch/arm/mach-imx/eukrea_mbimx27-baseboard.c). Modern systems use Device Tree approach.
In order to compile a driver it must be first selected (for example via make menuconfig). So if you select 6 drivers, then 6 drivers will be compiled.
platform_add_devices() registers platform drivers (adds them to a list, see drivers/base/platform.c), so that kernel know, which of them to initialize during the boot stage.
Platform drivers are part of the kernel, so they are in RAM as soon as the kernel image itself is loaded.
See this article for more details.
Platform devices (not drivers, like is stated above) are declared in a board file like /arch/arm/mach-*
and made known to the kernel with platform_add_devices().
This board file is statically compiled and linked to the kernel.
platform_add_devices() is not a system call. it is the part of a kernel API platform_device_register() call for registering devices so they can be
later binded with drivers.
Platform drivers are usually statically linked with kernel and when platform_driver_register() is called, kernel tries to bind driver to the device by matching platform_device and platform_driver name property.
If match is made, driver is registered and probe() function of the driver is called.
Obviously devices has to be registered first, before drivers are loaded.
Nowadays device tree files are used instead board files.
Devices from separate device tree blob file are registered by kernel, and matched to driver with compatible string property.
So this property has to be declared within device_driver structure and
device node in device tree file.
Goal is, when you change devices or their properties, you have to recompile just device tree file, and not the kernel itself.

How to get a device file name using major and minor number

I am trying add some debug messages in block io to track the io operation in linux kernel.
IO could happen to multiple block device, I have dev_t value with me.
I can get major and minor number from dev_t.
I want to know is there any way to get the device file name from /dev/ dir using these major and minor number?
Of course, I need kernel APIs.
It's simple:
Use bdget function to find the block_device by dev_t.
Use bdevname to get the device name.
Use bdput to put the device reference.
Have fun.
You can also use libudev. Since you already have the dev_t id this way is aesier.
#include <libudev.h>
// Create the udev context.
struct udev *udev = udev_new();
// Create de udev_device from the dev_t.
struct udev_device *dev = udev_device_new_from_devnum(udev, 'b', sb.st_dev);
// Finally obtain the node.
const char* node = udev_device_get_devnode(dev);
udev_unref(udev);
In general, you cannot do such simple reverse mapping. This is because knowing some major and major numbers, one can always use mknod to create valid device file anywhere, not necessarily under /dev.
At the end of the day, kernel does not care much how did any particular device node with certain major/minor came about - such a node is simply entry point into the kernel device driver that can handle this hardware or software device.
Granted, in practice on most modern Linux systems most device nodes are located in /dev and maintained by udev - but it is user-space daemon, which your kernel driver cannot talk to. Also note that udev can be configured to create new device nodes with any name.

What is the sequence followed by the Linux kernel to configure a device?

As I understood after reading the chapter related to The Linux Device Model in the Linux Device Drivers 3rd Edition, when a new device is configured, the kernel (2.6) follows more or less this sequence:
The Device is registered in the driver core (device_register(), what includes device initialization)
A kobject is registered in the device model
It creates an entry in sysfs and provokes a hotplug event
Bus and drivers are checked to see which one matches with the device
Probe
Device is binded to the driver
My main doubt is, in step 1, when is device_register() called and what fields should already be set in the device struct?
Is it called by the bus to which the device is connected? Any example in the code?
Have I misunderstood anything? :)
PCI hotplug code is going to call pci_do_scan_bus() to go through all slots, see if we find a device/bridge and add them to our device tree :
unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus) {
max = pci_scan_child_bus(bus) //scan bus for all slots and devices in them
pci_bus_add_devices(bus); //add what we find
...
}
The fields in struct device are actually filled up as part of call to pci_scan_child_bus(). Here's the call graph (sort of :)):
pci_scan_child_bus > pci_scan_slot (scan for slots on the bus) > pci_scan_single_device > pci_device_add > device_initialize.
Note that device_initialize() is the first part of device_register(). You will see that the fields of struct device are filled up in pci_device_add after the call to device_initialize(). You can find it under drivers/pci/probe.c in the kernel sources. The struct pci_dev will also be filled up which will later be used by the device specific driver.
The actual addition of the kobject to the device hierarchy happens in pci_bus_add_devices. Here's the call graph :
pci_bus_add_devices > pci_bus_add_device > device_add.
As you can see, this call flow completes the second part of the device_register() function.
So, in short, device_register() consists of : 1. Initialize device and 2. Add device.
pci_device_add does step 1 and pci_bus_add_device does step 2.
Files of interest are : drivers/pci/{pci.c,bus.c,probe.c}
In struct bus type there is pointer to function match, whose job is to match the driver associated with device. So when the device is associated with a bus, then as soon as the device is connected to bus then it is responsiblity of bus to search for the device.
Pls correct me if that is not the case.

Resources