How to access USB bus number from Linux device driver? - linux

I have two identical USB devices connected to different USB host controllers. Sometimes devices initialization order changes spontaneously breaking devices enumeration. Is there a way to get USB bus number in device driver (it would be enough for implementing of correct initialization) like it is done in user space with lsusb?

I found the decision. The task was to get USB bus number in kernel module, the similar task was found at this post. It was necessary to get a bus->busnum member of usb_device structure in the driver init function:
struct usb_device *usbdev;
struct usb_bus *mybus;
usbdev=interface_to_usbdev(pusb_intf);
mybus=usbdev->bus;
printk("USB Bus number is %d\n",mybus->busnum);

Related

Why platform device need to be registered as another device?

I'm a beginner in Linux driver development. I've been searched many references but i still didn't get this. That's why i ask here, sorry for that.
I found the codes in my project that the device is registered as a misc device via misc_register in platform driver's probe function. What make me confused is that, in my view, the physical device represented by platform_device has been matched with the platform_driver already, that means the device has been "driven" successfully. Then why we need another misc device? If these misc device and platform device is representing the same physical device, how they bind with each others?
misc_register() is mostly just a way of registering an individual character device (character special file) without using up a whole new major device number for a character device driver. It is accessible from user space using the file operation handlers specified by the struct file_operations referred to by the fops member of the struct miscdevice being registered by misc_register().

How existing kernel driver should be initialized as PCI memory-mapped?

Existing kernel drivers such as xilinx have specific way to be registered (as tty device), if they are mapped directly to cpu memory map as done here with device tree:
https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842249/Uartlite+Driver
But in other cases, there is a PCIe device (like FPGA which has the xilinx uart IPs) which is connected to and the cpu.
How should we make the uart get registered when using PCIe device ?
The device tree I try to register into PCIe is uartlite driver:
https://github.com/Xilinx/linux-xlnx/blob/master/drivers/tty/serial/uartlite.c
I think that what I probably need to do is:
Write a custom pci driver.
Need to prepare platform_device struct and then call the uart probe routine from pci driver:
ulite_probe(struct platform_device *pdev)
I've seen related question with others using FPGA with multiple device connected, but seems that there is no docuemnt, or tutorial which describes how to do this.
Any comment, example or document is appreciated.
So something like a ARM CPU connected to an Artix FPGA over PCIe right?
Yes, you would need a custom PCIe driver. The PCIe configuration and data spaces would have to be mapped. Have a look at pci_resource_{start, len} and pci_remap_bar functions. You can then use pci_get_device to get a pointer to the struct device and retrieve the virtual address of the PCIe configuration space. The UART driver can then use the struct device pointer and it's register map should be at some offset to the virtual address of the PCIe configuration space as per your design. You can invoke the probe call of UARTlite IP driver in your own driver.
"Existing kernel drivers such as xilinx have specific way to be registered (as tty device), if they are mapped directly to cpu memory map as done here with device tree". Note that this is true if we are only talking of tty devices. A GPIO peripheral IP won't be expose as tty but in /sys/class/gpio.

Interrupt driven SPI or I2C driver

I am working on a user application, which depends on I2C or SPI device connected with the beaglebone board.
My app is running in userspace. Now whenever an interrupt occurs from I2c device, My application should get the data from I2c device.
My question is how to sync all these. Do I need to write a device driver which gets the data from I2c device or trigger another device driver to read the data from I2c and how it can trigger my user app to get the data?
You'll need to know about three things: i2c drivers, spi drivers and input subsystem.
For i2c drivers, search kernel code for struct i2c_driver and module_i2c_driver helper macro for registering and unregistering the driver.
Similarly, struct spi_driver and module_spi_driver for spi.
For input subsystem, search for struct input_dev. Among other things, you'll need to "hook" into interesting events by setting relevant event bits and implement input_event event handler.
UPDATE: Forgot to mention, aim of input subsystem is to help take care of input events coming in from i2c or spi device.

Process of device driver detection in linux

Wanted to know how a device is detected in Linux? What exactly is the workflow of the device driver in device detection?
It is the Kernel's job to detect devices as it has the lowest level access to the available hardware. When the Kernel scans through all available addresses it maintains a list of Vendor and Device IDs.
To use PCI bus devices as an example, there is a Vendor ID and a Device ID associated with all PCI devices.
Device drivers are written in such a way as to identify to the Kernel what kinds of devices the driver is able to control. Drivers may advertise that they can handle more than one vendor and device type combination.
The Kernel will allocate a driver to each device based on these IDs. A similar process is in place for USB devices. Older technologies like legacy devices (serial ports, parallel, ps2 mice/keyboards) will have explicitly hardcoded methods of associating particular drivers with devices.
You can use the Linux commands lsusb and lspci to see the available devices and IDs on your system.
So in direct answer to your question - the device driver usually does nothing to detect the device, at least in the first instance. Once the driver is associated with a device (by the Kernel) the driver will likely do further interrogation of the device to ensure it contains the right firmware or is the right hardware revision, etc.

Is there a way to get the device node of a usb device using libusb APIs?

I am trying to get the device node (eg. /dev/sdb) of a usb device.
I was wondering if there is any libusb API that would give me the particular device node to which the USB device is associated with.
If there is no API, are there any other alternate means of achieving this? Any insight on this would prove REALLY helpful.
Thanks in advance.
On Linux, easiest method to explore attached USB devices and their properties is to simply scan directory /sys/bus/usb/devices. This virtual directory lists all attached devices. Each entry has very simple structure, and for every device that has slave connected (like device connected via hub) there is virtual subdirectory.
What is also nice that in general you do not need to be root to read a lot of device properties, like manufacturer or serial number.
Another very good property of this interface is that it is semi-stable. That is, every device has unique id like a-b.c.d.e:x.y (a - bus number, b,c - root hub, next hub, port, etc.., x,y - function, subfunction), and this device enumeration is not going to abruptly shift for all devices if one device is connected or disconnected.
You can also easily map these device ids into libusb-style bus/device numbers (but those are not stable).
Unfortunately, this is Linux specific, and does not seem to be available for other operating systems. I wish libusb had implemented something like this, but it does not.
Anyway, good luck!

Resources