Does any interrupt occur when a usb device is connected? - linux-device-driver

I am working on USB HIDs on linux platform. Keyboards, mouse etc., are examples of Human Interface Devices. Whenever a HID is inserted to a system, at first device enumeration occurs. Then an entry in the form of hidraw appears in the /dev directory.
In linux, "usbhid and hid" are the modules which are called when an HID device is inserted. When I disabled these modules (using rmmod and system restart), the devices were not enumerated and no hidraw entry appeared on /dev(as expected).
Now my question is there any way to know if any USB HID device is connected to a system with the above two modules being disabled i.e does any interrupt or signal generate upon hardware insertion.
I am planning to execute some code when such signal or interrupt occurs(in C). Any kind of help is appreciated.
Thanks,

Insertion of the device is detected through the voltage level changes occuring on the D+ and the D- lines. I do not think that insertion of USB device generates any interrupt. The voltage level changes are read by the hub(root or any hub further down on the line) and according reported to the core.
The USB core driver would be notified about the same. So may be you can write a user-space driver which targets a specific device (using Vendor and Product ID) and through this you can carry out your functionality.

If you are doing this in user mode, you get get a notification using udev (which use netlink internally).
You can match a device using the vendorId and productId field in the rulefile.
SUBSYSTEMS=="usb", ATTRS{idVendor}=="abcd", ATTRS{idProduct}=="1234"

Related

How to flash without STLINK

My STLINKV2 is not working anymore, not detected by Linux, it failed after the first successful flash. I ordered a new one but it will take 60+ days to arrive. Meanwhile I have heard on Youtube you can program Bluepills directly by connecting cut open USB cable to certain pins and then using a jumper. But I cannot get any precie information on this, is this really possible and how?
You should use the embedded bootloader. You can flash it through several interfaces. Look at AN2606, maybe you can find an already written flasher. Good luck STM32CubeProgrammer handle it.
If you intend to program it through usb, look also at AN3156 all protocols document are referred in chapter 2 of AN2606
THOSE AREN'T CUT OPEN USB CABLES they are USB to serial adapters for arduino's bootloader
They connect them like this:
The problem is that this requires the Arduino STM32 bootloader to be flashed in it.
Another option will be to use STM32CubeProg this program allows you to program your stm over
Serial
SPI
I2C
USB
You'll need to set the BOOT0 and BOOT1 pins to the correct value (HIGH slash LOW) to allow it to go in flash mode during boot.
Here is semi outdated tutorial which tells most of the steps to program a STM using serial. (the Flash Loader Demonstrator is outdated and you should use STM32CubeProg)

How to test the actual presence of platform i2c device in driver's probe() function

I am writing an I2C bus driver. I have tested it on one external module I have plugged in my system (video card module) and it works. I have specified the i2c device (frequency, registers etc.) in device tree.
I would like to specify the rest of devices which will be using the driver in device tree as well. However, if I do that and the device is currently not present in the system, kernel fails to initialize. I guess this happens because in my probe function, I am setting up the frequency (which gets set up by writing to I2C register of that device - FPGA) and since the device isn't there - it just fails.
How should I solve this issue. Is there a way to check the actual physical presence in probe function without kernel failing? Or should I move the code that sets up frequency in another function that happens after ".master_xfer" when I'm reading/writing. The second option just seems like waste of resources. Another thing I had in mind was after I use open() to access the device in user-space, I should set the frequency in user-space as well. But I would really like all of this to happen inside the driver if possible. I'd like the frequency to be set after open() happens in userspace but for the code to execute in device driver code because there I access the register range specified in device tree. Maybe I could find where open() happens, check the ID of I2C device, than get the registers and do it there?

How to configure libnfc to use a specific device?

I have a Raspberry PI with two NFC readers attached. Problem is that the readers get different device numbers each time the system reboots or a reader is detached and attached again.
I therefore created udev rules that create a fixed device name depending on the physical port a device is attached to. E.g. plug in NFC reader in the upper left port leads always to /dev/nfc_a and plugged into the upper right port leads always to /dev/nfc_b.
How can I now configure libnfc to use these devices and report the device names such as /dev/nfc_a as a part of the reading? I am using Node-RED with node-red-contrib-nfc (https://github.com/hardillb/node-red-contrib-nfc) on top of libnfc. My ultimate goal is to safely distinguish the two readers within my Node-RED flow to act differently upon the readings.
I already found the "connstring" configuration but I don't know how to correctly set it for using /dev/nfc_a.
It's been a LONG time since I wrote this node, but looking back at the nodejs library it's based on (nfc) the output message should contain a field called deviceID which should indicate which NFC reader triggered the input.
When I run on my machine I get:
deviceID: 'pn53x_usb:001:005'
Where 001 is the USB bus id and 005 is the device ID, which matches up with the output from lsusb. These should stay static as long as the readers are always plugged into the same USB sockets.

At boot time how OS determines all the hardware?

I have these related questions:
Does anybody know how an OS gets to know all hardware connected on the motherboard? (I guess this is called "Hardware Enumeration").
How does it determine what kind of hardware is residing at an specific IO address (i.e.: serial or parallel or whatever controller)?
How to code a system module which will do this job? (Assuming no OS loaded yet, just BIOS).
I know BIOS is just a validation and an user friendly interface to configure hardware at boot time with no real use after that for most modern OS's (win, Linux, etc). Besides I know that for the BIOS it should not be difficult to find all hardware because it is specifically tuned by the board manufacturer (who knows everything about it!). But for an OS or an application above BIOS that is a complete different story. Right?
Pre-PCI this was much more difficult, you needed a trick for each product, and even with that it was difficult to figure everything out. With usb and pci you can scan the busses to find a vendor and product id, from that you go into a product specific discovery (like the old days this can be difficult). Sometimes the details for that board are protected by NDA or worse you just dont get to know unless you work there on the right team.
The general approach is either based on detection (usb, pcie, etc vendor/product ids) you load a driver or write a driver for that family of product based on the documentation for that family of product. Since you mentioned BIOS, win, linux that implies X86 or a PC, and that pretty much covers the autodetectable. Beyond that you rely on the user who knows what hardware was installed in the system and a driver that came with it. or in some way you ask them what is installed (the specific printer at the end of a cable or out on the network if not auto detectable is an easy to understand example).
In short you take decades of experience in trying to succeed at this and apply it, and still fail from time to time since you are not in 100% control of all the hardware in the system, there are hundreds of vendors out there each doing their own thing.
BIOS enumerates the pci(e) for an x86 pc, for other platforms the OS might do it. The enumeration includes allocating address space for the device based on pci compliant rules. but within that address space you have to know how to program that specific board from vendor documentation if available.
Sorry my English is not very good.
Responding questions 1 and 2:
During the boot process, only the hardware modules strictly necessary to find and start the OS are loaded.
These hardware modules are: motherboard, hard drive, RAM, graphics card, keyboard, mouse, screen (that is detected by the graphics card), network card, CD / DVD, and a few extra peripherals such as USB units.
Each hardware module you connect to a computer has a controller that is like a small BIOS with all the information of the stored device: manufacturer, device type, protocols, etc
The detection process is very simple: the BIOS has hardcoded all the information about the motherboard, with all communication ports. At startup, the BIOS sends a signal to all system ports asking the questions "Who are you? What are you? How do you function?" and all attached devices answers by sending their information. In this way the computer knows how much RAM you have, if there is present a keyboard or a mouse, which storage devices are available, screen resolution, etc ...
Obviously, this process only works with the basic modules needed to boot the system, and does not work with complex peripherals that require specific drivers: printers, scanners, webcams ... all these complex peripherals are loaded by software once the OS has been charged.
Responding question 3:
If you wants to load a specific module during the boot, you must:
- Create a controller for this module.
- If the peripheral is too complex to load everything from the controller, you must to write all the proccess to control that module directly in the BIOS module, or reprogram the IPL to manage that specific module.
I hope I've helped
Actually, when you turn on your system, the BIOS starts the IPL (Initial program load) from ROM. For check the all connected devices are working good and also check the mandatory devices such as keyboard, CMOS, Hard disk and so on. If it is not success, it gives an error flag to the BIOS. The BIOS shows us the error through video devices.
If it is success, the control of boot is transferred to BIOS for further process.
The above all process are called POST (Power On Self Test).
Now the BIOS have the control. It checks all secondary memory devices for boot loader of the OS. If it hit, the bootloader's memory address is transferred to RAM.
The Ram started to execute the bootloader. Here only the os starts to run.
If the bootloader not hit, the bios shows us the boot failure error.
I hope your doubt clarified...

Mouse Detect, OS Boot

I was just wondering how the mouse, keyboard works during the boot process. Let us say that I have a USB mouse and a USB keyboard. When I switch on my computer, POST is done just to check whether all the hardware connected to my system are working. But to get a USB hardware working, we need to have a USB driver which ultimately is a process. But if OS is not loaded yet(I mean init and swapper processes), how this process comes into existence? One thing striking my mind is BIOS. But I think, BIOS can't identify the different drivers needed to detect different mouse, keyboards. Please help.
The BIOS is able to enumerate and control a certain subset of USB devices. In particular, mice and keyboards belong to a common class of devices (Human Interface Devices, HID) that are have a common, defined interface and which is fairly to drive. So, the BIOS just has drivers for that class of devices baked in.
Modern BIOSes emulate the PS/2 ports 0x60 and 0x64 using SMM/SMI with a feature often called "USB Legacy Support" (see the EHCI specification for more info.)
When the OS itself loads and initializes the USB controller there is a controller ownership transition from BIOS-owned to OS-owned.