Relation between USB and PCI - hardware

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?

Related

Can a non-enumerated device conduct DMA operations?

PCIe devices can read or write to memory, i.e. can do DMA without requiring a device driver.
If I remember correctly, if you flash a device's firmware (let's say an FPGA device) and input 0xFFFF as device and vendor ID, the device won't be enumerated by BIOS.
I am wondering, if a PCIe device can conduct DMA operations (memory read and write) by bus mastering even when it is not enumerated by BIOS.
A PCIe device can only do DMA if Bus Master Enable (BME) is set in the command register. BME will only be set when a driver is active.

Why is the max number of PCI lanes possible in your system set by your CPU? Even with DMA being widespread

There are a few scenarios I'm curious about:
a transfer from GPU1 memory to GPU2 memory over the PCI bus
a transfer from GPU1 to main memory with DMA
a transfer from GPU1 to main memory without DMA
Will all these scenarios be limited to the total number of PCIe lanes supported by the CPU? For Intel systems, ARM systems?
Will all these scenarios be limited to the total number of PCIe lanes supported by the CPU?
PCIe is not precisely a bus -- certainly not in the way that PCI or ISA were, for instance. It's a set of point-to-point connections between peripherals and the PCIe root complex (which is usually the CPU itself). Any given root complex will support some fixed number of PCIe lanes, each of which is connected to one device. (Often in sets. For instance, it's typical to connect 16 PCIe lanes to most GPUs.)
So, yes. Any communications between PCIe devices, or between devices and memory, must pass through the CPU, and will be limited by the number of PCIe lanes the device (or devices) have connecting them to the bus master.

USB interface between two microcontroller

I have been tasked to write a device driver for an embedded system which has two microcontroller interfaced via USB. The data transfer between two controller will take place across USB.
I am facing difficulty in reading USB specification.
Which USB class is suitable for communicating between two controllers?
USB is an asymmetric protocol where there is a host and a device, and the host is the one who initiates all communication. The device can conform to a USB Device Class, or your device can just have a vendor-defined interface that doesn't conform to any particular class.
Without knowing anything about the data you are sending between the microcontrollers, I would suggest just using a vendor-defined interface (USB device class code 0xFF). The host can initiate custom control transfers on endpoint 0 that transfer arbitrary data between the host and device. You can also use bulk/interrupt/isochronous endpoints to transfer data.
The USB CDC ACM class is used for virtual serial ports, and it provides a way to send bytes back and forth between the host and device; many devices use it for a generic communication mechanism.
The HID (Human Interface Device) class is another one that is designed for things like keyboards, but it can also be used for generic communication.
The main point of using a USB Device Class is that it allows you to take advantage of built-in drivers that different operating systems have for these types of devices without having to write your own driver. You might look to see if your host microcontroller has special USB drivers for one of those device classes. If it doesn't then there is not much point in using a USB Device Class. It sounds like you will be writing the code on both ends of the USB cable and you don't intend to take your device and plug it into any other type of USB host, so there is no point in forcing your protocol to conform to a USB class.

Raspberry Pi stream USB through to ethernet?

I am looking into ways to stream a usb camera over long distances. The plan is to plug the USB into a raspberry pi2, then send it over wifi via TCP. Is this a viable plan?
I have found a few approaches like this:
https://www.virtualhere.com/
But They seem to be for printers and other 'static' devices. Will a streaming data connection work with this type of approach?
Thanks.
Yes, a USB camera uses the "isochronous" transfer mode of the USB protocol.
VirtualHere and most other usb/ip software support this mode.
The main issue is network latency. The lower the webcam resolution, the less latency will be a problem. Also, the pi2 has a fast CPU however the USB bus is shared with the Ethernet so by definition throughput is cut in half, perhaps looking at a embedded board that doesn't share the USB bus like a beaglebone or odroid-c1 or other board would provide better performance for the same price.
(I am the author of VirtualHere)

PCI function number for SATA AHCI controller

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.