How to get USB device details in kernel programming? - linux

I am new to kernel programming and I have dev_t value of a USB device.
I want to get the details of the device like vendor ID, product ID, or some other attribute which will vary from device to device. I want to do this in kernel space, and without loading my program as an external module.
I have came across a libusb library, however, as far as I know, it is used in user space. Is it possible to use libusb in kernel space also, like my requirement? If possible, how to import and set-up libusb so that I can compile kernel?

It is better to write a loadable kernel module for this task. Every time you find a bug you just have to compile your module against your kernel and load it. There is a defined framework in kernel for USB, use APIs that are provided by kernel to do things you are looking for.
Except That libusb is a user space library and there is no point of using it inside kernel.
In user space you can access USB related information using procfs/sysfs also.

Related

How are platform drivers managed in linux

Helo All,
I am trying to learn embedded linux.
Please provide clarity on below:
As DTB provides Board and SOC related information will it be sufficient to make sure correct drivers will be enabled?
How a correct driver will get selected and will it happen during build time or kernel runtime based on the DTB?
How are drivers for platform devices(UART, SPI, I2C etc) handled in Linux? I mean as different SOC's have different implementations(register and bit fields will be different) of these peripherals how a single driver will be able to handle both SOC's?
Is it sufficient to have well defined DTB about board and kernel to make Linux up and running on any platform.
Thanks,
Suraj

How set a module used by "something"

I need your advice.
I want to achieve transactions between my pc and fpga by pcie slot.
I try to install a driver to do that but the driver don't see the fpga.
I run on terminal $ lspci and I take this picture:
enter image description here
Is there any way to connect xdma module with my fpga manually...??
What you see in the "Used By" column of lsmod does not mean whether some user-space program is using the module, but only if it is being used by other kernel modules. For example if you check the usb_core line from the lsmod output, you will see that it is being used by a bunch of USB/HID related modules.
The kernel module (or device deriver) is only a way to enable your system to comunicate with the particular piece of hardware. It only exposes its interface so the rest of the kernel (or userspace programs) can interact with it.
You will need for sure some user level software or application that makes use of the interface exposed by the kernel module.
I don't know for your particular case, but the interface that the driver exposes depends on the type of the hardware and the module implementation itself. It may expose some files to /sysfs, or add a new syscall (this is very unlikely, but it's a possibility), or make special usage of ioctl.
So, you should check for the module documentation, or look for some user-space program that knows how to interface with the driver.

Linux Kernel device driver needs access to shared object in userspace

I am trying to write a network device driver for Linux. The device that I have has an API available that allows me to access all of the features I need through a shared object that exists in userspace.
I want to write a network driver such that I can make the device show up as a CAN interface. However, in order to interact with the device I need to use a specific shared object that exists in userspace.
The reason that I need a network device driver is to expose a CAN Interface that can be interacted with via the SocketCAN utilities.
Is there a way that I can write a network device driver in userspace? Or what would the best way for me to architect a solution?
Tl;Dr
Need to write a device driver for a device which can only be interacted with from userspace via a supplied shared object which exposes the API. I need the device to show up as a network interface in order to utilize the SocketCAN utilities and other applications that communicate with CAN interfaces in Linux.
What are my options here? What can I do?
Thanks!
So you are saying that there is no driver for your network device in kernel at all, and it can be only accessed via some user-space library? In that case shared library you mentioned should be communicating with your network device by memory mapping your /dev/mem file, in order to be able to read/write to hardware registers. Or perhaps by using some UIO.
So your driver should be also developed in user-space then... Then the actual question you should ask is how to use kernel CAN API from user-space? And is it possible at all in the first place? For answers I guess you should look at Documentation/networking/can.txt. And if the answer is "no" (means you can't expose CAN interface from user-space), then you should develop also some kernel driver which would interact with your user-space part, exposing CAN interface.
In ideal world the whole driver architecture would look like this:
But you need to use some (proprietary, if I understand correctly) shared library API to interact with your device. So I propose you to use next driver architecture, which depicted on the image below:
blue color stands for parts that need to be developed
magenta is for already existing code
In a nutshell, your app and driver both make a shim between SocketCAN API and shared library API.
So you need to develop 2 components:
Driver (on kernel side). It's in charge of:
talking to SocketCAN utilities
talking to your user-space application
Application (in user-space); it's probably should be a daemon, as it's gonna be running constantly. It's in charge of:
talking to shared library
talking to your driver
The last question remains is which kernel API to use to interact between your kernel space driver and user-space application (marked as IPC on picture). It strictly depends on which kind of data you are going to send between two, and how much of data you will want to send, and which way of sending is most appropriate for your task. It may also depend on your shared library API: you probably don't want to spend much of CPU time to convert messages format (as you already have triple context switching with this driver architecture, which is not really nice for performance). So it's probably should be something packet-oriented, like Netlink.
Next reading can be useful to figure out which IPC to use:
Kernel Space - User Space Interfaces
Linux kernel interfaces

questions about embedded linux device driver by linux newbie

I have been studying linux driver recently,
as those articles I read said, the device driver modules are likely to be automatically loaded on demand by kernel, I am therefore wondering about the recipe how kernel figures out which module to load for a specific device(sound card, I2C/spi device, etc), I also cannot thoroughly imagine how the kernel detects each hardware device while boot-time .
answers relevant to embedded linux are prefered , PC linux are also welcome !
3Q
I think you are mixing two different things, which is hardware detection, and on demand module loading.
In some cases, the kernel is explicitely doing a module request. However, in most cases, the kernel itself does not do any "on demand loading".
But wait, you must be mistaken, if I plug my shiny new webcam, isn't
the module automagically loaded ?
Yes it is, but not by the kernel. All the kernel does is calling a userspace program with so called "hotplug event" or "uevent" as arguments. On Linux PC, this userspace program is usually udev, but on embedded system, you can use for example mdev. You can find a more detailed explanation here and here
Regarding the second part of your question, the kernel is doing hardware discovery only if the hardware is discoverable. Example of discoverable hardware is USB and PCI. Example of non discoverable harwdare busses is SPI or I2C.
In the latter cases, the presence of a particular device on a given bus is either encoded directly in the kernel, or given to him by the booloader. Google for "device tree" for an example of the latter.
To sum things up : Hardware detection is done by the kernel, and module loading is done by userspace, with information provided by the kernel.

Is there a way to ask the Linux Kernel to re-run its PCI initialization code?

I'm looking for either a kernel mode call that I can make from a driver, a userland utility, or a system call that will ask the Kernel to look at the PCI bus and either completely re-run its initialization, or initialize a specific device. Specifically, I need the Kernel to recognize a device that was added to the bus after boot and then configure its address space, interrupt, and other configuration parameters, and finally enable the device so that I can load the driver for it (unless this all happens as part of the driver load).
I'm stuck on the 2.4.x series Kernel for this, and am currently working with 2.4.20, but will be moving to 2.4.37 if it matters. The distro is a stripped down Red Hat 7.3 running in a ram disk, but I can add in whatever tools are needed to get this working (as long as they play nice with 2.4 series).
If some background would help clarify what I'm trying to do: From a cold boot, once in Linux I use GPIO to program an FPGA. Part of the FPGA, once programmed, implements a simple PCI device. Currently, after programming the FPGA, I reboot the system and Linux recognizes the device after coming up and loads the driver for it.
Instead of needing that reboot, I'd like to simply ask the Kernel to do whatever it does during boot up to find PCI devices (I have the Kernel configured to find PCI devices on its own, instead of asking the BIOS for that information, so the BIOS won't need to know about this device (I hope)).
I believe that Linux is capable of seeing the device after it is programmed but before a reboot, because scanpci will show the device after I program it, as will lspci -H 1. I just need a way to get it into /proc/pci, configured and enabled.
This below command will help the user to rescan it complete root hub.
echo "1" > /sys/class/pci_bus/0000\:00/rescan
You could speed up the reboot with kexec, if you don't figure out how to get the PCI scan redone. You could ask this on the LKML, if you haven't already.
unloading/reloading the module doesn't help, does it?
http://www.linuxjournal.com/article/5633 suggests you should be able to do it with 2.4 kernels using pcihpfs.
If that isn't working, maybe the driver doesn't support hotplug?
It would probably crash the system if you reconfigured the addresses of other PCI devices while they are in use.
A better way would be to just configure the new card. If your kernel has support for Cardus devices, it already knows how to configure a newly-inserted PCI device (which is what Cardbus is). You just need to figure out how to get the kernel to do it...
It should be possible for a kernel module to do this. Even if you can't get built-in hotplug code, you should be able to set the pci resources using calls to pci_bus_write_config_dword() and friends. There is probably some IRQ routing setup to do as well.

Resources