Can two Identical devices be present on the same bus in any PCI Topology - pci

As per the PCI standard, devices are identified on the basis of Vendor Id, Device Id and the bus no. All devices of same type have identical vendor id and device id. If I put two such devices on the same bus say bus 0. How will the PCI Software Subsystem distinguish between the two?
If such a case is not possible in PCI, then can such thing be possible through PCI Express Switch?

Yes, it's perfectly fine. The host distinguishes identical devices by slot.

PCI and PCI Express devices are identified by Bus/Device/Function, which is necessarily unique per device in the system. Vendor and Device ID are just properties of a device found at a certain Bus/Device/Function.
When enumerating board, a driver will typically scan PCI configuration space (iterate through all the installed PCI devices), until it finds one or more devices that match the expected Vendor and Device ID, and possibly also the subsystem IDs. Once it finds a match, it should record the bus/device/function as a "handle" to the open device.
Properly written software should find all vendor/device matches, put them in a table, and let you pick which one you want to use (e.g. /dev/mydevice0, /dev/mydevice1, etc). However, I have seen lazy software that simply stops at the first match.

As I know, each PCI device can be uniquely described by (Bus,Device,Function). Consider your case(2 devices have identical VID and DID installed) and I think they must be located at different PCI bus ! If they must be in the same bus then please make their Device or Function number different

Related

Multiple I2C devices with the same address

Currently working on a project that requires me to use two I2C devices on the Raspberry Pi, but both devices use the same address. Does anyone have an easy fix to changing the address of 1 of the devices? :)
No, most devices don't allow changing the address. Those that do have a separate pin (or pins) that can be used to select the address. Very few devices allow changing the address by software. If you said which device you use, we could tell you which group it belongs.
However, there's a quite easy workaround: The Raspberry Pi has up to 6 I2C busses, so you can just use a second bus for the second device (like the one on GPIO0/1, which is already configured as I2C bus 0 by default and typically unused)

Single device driver for multiple devices

I'm writing a device driver for multiple devices, especially FPGA board.
I want a single driver to drive multiple devices.
In this case, how can I differentiate the devices in the code?
By minor number? PCIe address?
Thanks,

Why does the driver request the USB device to send the USB descriptors?

As far as I understand the USB devices introduce themselves by sending a device descriptor to the host which uses the information embedded in the descriptor to find and load the right driver/drivers. What I don't understand is why the drivers need the configuration, interface, endpoint and string descriptors from the device. I know the descriptors describe the device as a whole e.g. number of configurations, interfaces, endpoints, types, the size of the packets, the purpose of each byte in the packet etc. Why can't the drivers include this information from the start? Why does the USB device hold this information?
I guess the main reason is because it was designed that way. The designers could just as easily have gone the other way as you say.
Possibly more helpfully, I can think of a few reasons why they did decide on it this way:
Consider the context in which USB came about. PC peripheral connectivity was a mess. You had serial (UART) ports, PS/2 keyboard & mouse, parallel ports in various modes (e.g. ECP and EPP), game port & MIDI, the various SCSI variants, etc. Most of these did not allow for self-describing devices in a standardised way, demanding custom drivers for each type of device, and mostly manual driver loading. Device descriptors alone would mostly solve the problem of selecting the correct driver, but not necessarily the issue of needing a custom driver for each device.
Various standard device class specifications (e.g. HID, audio) define their own class-specific descriptors for communicating device variations to the standard driver. For this reason alone the generalised descriptor mechanism is useful.
Composite devices in their present form would effectively not be possible without standardised interface descriptors. You'd presumably have to make each composite device act as a hub with multiple devices attached.
Many (most?) standard device class specifications mandate a certain minimum number of endpoints where the standardised protocol is implemented, (e.g. bulk-only USB mass storage defines 1 bulk input and 1 bulk output endpoint) while devices are free to add more for vendor-specific extensions, or…
…future expansion of the standard device class or USB standard itself while maintaining backwards compatibility both ways (old driver/new device, new driver/old device). Think of UASP devices that fall back to regular bulk-only mass storage transport.
While not strictly necessary for making all those things happen, making devices self-describing in this way does seem to have been a success overall.

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.

Does any interrupt occur when a usb device is connected?

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"