I'm debugging a second stage boot loader for a PC with SATA AHCI controller. I'm able to enumerate the PCI bus and find the hard disk. So far, so good. Now, lspci in my notebook (Dell Inspiron 1525) show me:
-[0000:00]-+-1f.0 Intel Corporation 82801HEM (ICH8M) LPC Interface Controller
+-1f.1 Intel Corporation 82801HBM/HEM (ICH8M/ICH8M-E) IDE Controller
+-1f.2 Intel Corporation 82801HBM/HEM (ICH8M/ICH8M-E) SATA AHCI Controller
\-1f.3 Intel Corporation 82801H (ICH8 Family) SMBus Controller
My question: Is SATA AHCI Controller always function 2 in any PC? If not, how I found?
I don't pretend to be general; booting my notebook will be good enough, without compromise further refinements.
Compliant SATA AHCI controllers should always have Device class 1 (storage controller) subclass 6 (Serial ATA) and interface 1 (AHCI). So the correct strategy is to enumerate all the PCI devices and compare their class, subclass and interface to identify those which implements AHCI. Note that there may be more than one, depending on the mainboard and whether any other AHCI cards are plugged into it.
You may want to also allow your code to match an AHCI controller by the vendor and device ID, because some early AHCI controllers don't have the appropriate class/subclass/interface set.
Related
The Microsoft article "USB serial driver (Usbser.sys)" tells that:
If you want to load Usbser.sys automatically, set the class code to 02
and subclass code to 02 in the Device Descriptor.
If I program a STM32 MCU with a CDC example with 02 class code (CDC) and 02 subclass code (ACM), the usbser.sys loads. And this makeshift USB-UART bridge detected as "Ports (COM and LPT)/COM5". If I use some USB-UART bridge IC (like FT232), commonly it's class is "Vendor specific" and they need a vendors driver. If the vendor driver has install this devices are also detected as "Ports (COM and LPT)/COMx"
The Cypress USB-UART bridge CY7C65213 has 02/02 class/subclass in the descriptor. But without the Cypress driver, this IC detected as "Other devices/Virtual Serial Port Device 00".
Actually, I can install the Cypress driver, this IC will detected as COMx and my soft will work well.
But I want to understand why the usbser.sys driver is not loading with this device? How can the Windows understand that some USB CDC-ACM devices need the usbser.sys and the other don't need this driver? Is the difference in the descriptor or somwehere else? What instruments shall I use to spot the difference and to tell one devices from other?
If you open C:\Windows\inf\usbser.inf in a text editor you can see what kinds of devices it matches:
[Standard.NTamd64]
%UsbSerial.DeviceDesc% = UsbSerial_Install, USB\Class_02&SubClass_02&Prot_01
%UsbSerial.DeviceDesc% = UsbSerial_Install, USB\Class_02&SubClass_02
This part tells us that it only matches devices that have a compatible ID equal to "USB\Class_02&SubClass_02&Prot_01" or "USB\Class_02&SubClass_02&Prot_01". I am guessing your Cypress device either doesn't have those compatible IDs, or it has some other driver that is matching that device using more specific IDs.
You can see the compatible IDs of your device by double-clicking on it in the Device Manager and going to the Details tab. It also helps to view devices by connection so you can know whether you are clicking on an actual USB device or just one of its child devices.
Question: Why the usbser.sys is not used with a USB CDC-ACM device?
Answer: usbser.sys is for USB CDC-ACM devices but your device isn't a USB CDC-ACM device.
Question: But I want to understand why the usbser.sys driver is not loading with this device?
Answer: see above
Question: What instruments shall I use to spot the difference and to tell one devices from other?
Answer: Use any tool or software that can read the USB device descriptor and configuration descriptor.
Question: How can the Windows understand that some USB CDC-ACM devices need the usbser.sys and the other don't need this driver?
Answer: It reads the device descriptor and configuration descriptor. If it contains a USB CDC-ACM compatible device, it will load usbser.sys. The requirements for USB CDC-ACM are described in the associated USB specification. In short, it requires two USB interface in a particular order, linked by an interface association descriptor and with the correct class code / subclass code (in the interface association descriptor).
Question: Is the difference in the descriptor or somwehere else?
Answer: Yes, the difference is in the descriptors (device and configuration).
Note: On Windows 8 and earlier, usbser.sys is not automatically loaded as mandated by the USB standard. A manual installation (possibly in conjunction with an INF-file) is needed.
For USB Host Controllers there are the UHCI/OHCI/EHCI/XHCI specification that define how to program a driver. Is there an equivalent specification for USB Device Controllers?
No. Generally, every USB-capable microcontroller has a USB block that you can control by writing to some registers in your code, but those registers are pretty different on the different microcontrollers and I have not heard of any attempt to standardize them.
I have an ASIC that has a PCI interface that I need to use in an embedded project I'm working on. The microprocessor I am considering right now is a Freescale MPC5668G, which has I2C, SPI, DMA, Media Local Bus interfaces. The MPC5668G is necessary because the project requires multiple CAN buses.
The issue is that I don't have any experience with PCI and I'm not sure what the best way to interface between the ASIC and the microprocessor.
Can anyone provide some insight on where to start?
Thank you,
Andy
I am trying to access a PCI BAR (#5) for a PCIe SATA bridge from userspace, but whenever I mmap() from the BAR via the /sys/bus/pci/devices/.../resource5, I get 0xFF at every offset in the file. Other devices such as an Intel SATA controller respond with sensible data.
The BAR is shown in lspci -vv just the same as for the Intel controller (only the address is different).
Region 5: Memory at f7b10000 (32-bit, non-prefetchable) [size=2K]
Both devices are are matched by the ahci driver, and the SATA controller works otherwise - I can access the attached disks.
I am trying to access from user space because I just want to poke at the registers experimentally for now. To do this, I am using a modified form of pcimem, changed to access the registers I care about. However, any offset returns 0xFF, so even with plain pcimem:
pcimem /sys/bus/pci/devices/0000\:01\:00.0/resource5 0 w
returns 0xFFFFFFFF ("w" indicates a "word" read, hence the 4 bytes).
What is it that is preventing the BAR5 for this device being accessible, when other devices are? Does it even make sense to make this kind of userspace access to PCI BARs?
Not certain how helpful this is going to be, but I saw the same thing when I was writing a driver for a new PCIe FPGA device.
The MMAP-ed PCI BAR memory space would return 0xFFFFFFFF (-1) when there was an error on the device. The only way I was able to resolve this was to reset the card by a full power reset of the computer.
I've encountered the same issue debugging NVMe hdds hotplug.
If before GRUB prompt there was a hdd in PCIe slot, you can hotplug other drives in that slot, and if not, pci_ioremap_bar() returns memory region reading all 0xffffffff.
Strange shit.
I m bit confused by the following statement in linux device drivers book.
http://www.linuxdriver.co.il/ldd3/
13.2. USB and Sysfs To help understand what this long device path means, we
describe how the kernel labels the USB
devices. The first USB device is a
root hub. This is the USB controller,
usually contained in a PCI device. The
controller is so named because it
controls the whole USB bus connected
to it. The controller is a bridge
between the PCI bus and the USB bus,
as well as being the first USB device
on that bus.
Especially the statement "The controller is a bridge between the PCI bus and the USB bus"
Is it so? I m under the impression that PCI and USB are both distinct Buses.
Please clarify.
They are indeed distinct busses, which is why you need a bridge between them so the CPU can, over PCI, through the bridge, communicate with stuff on the USB bus.
CPU ---(front-side bus)---- PCI controller ----(PCI-bus)-+-- USB controller ----(USB-bus)--+-- USB mouse
| +--- USB printer
+-- SATA controller
The "Controller" refer to above is a piece of Hardware. It houses functionality to "bridge" communications between a USB interface and a PCI interface.
By "bridging" it is meant that USB protocol packets are transferred to/from the CPU / USB ports but usually through a PCI "bus".
The reasons a hop through a PCI bus is used probably comes down to 2:
1 interface is better than two (cost & complexity wise)
USB is much slower speed than PCI (certainly PCI-Express): it is easy just to "encapsulate" USB protocol packets onto PCI for shuttling those around the motherboard.
Note: there is often confusion when it comes to naming hardware chips. For efficient (read $$) reasons, it is quite common to have chips that house multiple functions. It is not because the main function of a chip is "PCI bridge" that it must be limited to perform "PCI bridging".
The USB controller communicates both USB and PCI. USB does not directly talk to the CPU, but rather across the PCI bus first.
Two very simple flow diagrams:
Userspace -> Kernel -> PCI -> USB Controller -> USB Device
USB Device -> USB Controller -> PCI -> Kernel -> Userspace
Or, better put:
Userspace -> Kernel -> [CARD_ARCHITECTURE] -> USB Controller -> USB Device
USB Device -> USB Controller -> [CARD_ARCHITECTURE] -> Kernel -> Userspace
... as you see, PCI is rather incidental. Are you writing a device driver?