Question about IRPs skipping PDOs/FDOs

Hi folks

I am currently learning about Windows internals and driver development (mostly out of curiosity / for education) and reading “Programming the Windows Driver Model”. In the first chapter introducing PDOs and FDOs, I stumpled upon the following examples for an IRP flow and have questions about it.

Why can the FDO_dev talk directly to the HAL without passing the request through the bus drivers? Shouldn’t only the bus drivers know how to send data over the buses?
My only explanation is that this is a request which does not involve the actual hardware the FDO_dev driver was made for and the HAL request does not involve the bus but some other non-PnP hardware.

Here is the second example with a USB device:

First of all, what is considered the “USB hub” in this context? Is it the small external device you can buy at the electronics store that extends your PC’s USB ports or are the USB ports soldered to the motherboard already considered the first USB hub attached to the host controller?
Next question: why can the USB hub drivers be skipped in this IRP example? My explanation is that for a read request, no particular action is required by the USB hub driver, because the USB device driver already knows the hardware ID of the destination device and the USB hub hardware will make sure that the message goes to the right device. So from the OS’s perspective, it is the exact same operation regardless of the USB device being connected directly to the host controller or via an intermediate hub.
If this assumption is correct, the USB device driver would need to know how many hub layers to skip (since there could be more than one intermediate USB hub on the path to the host controller). How can it know that info? Does it scan the entire device stack until it reaches the host controller? Or are actually all of the layers traversed but the book author wanted to indicate in the figure that the USB hub layer does not perform any action?

Thanks and best regards
berlin

I’ll only address your first question, which is best illustrated by a pci bus device. The pci bus driver is basically only responsible for enumerating its bus, for identifying the devices attached to the pci bus(ses) on the system. Each enumerated pci device has its own independent pci resources, and communication with those resources is accomplished by reading/writing what appear to the host system as memory addresses. The pci bus driver is not responsible for IO operations between the host system and the attached devices. For this type of peripheral device bus, the FDO driver communicates directly with its device. This type of bus is generally referred to as a ‘parallel bus’.

In contrast a ‘serial bus’ has a single ‘controller’ device that is responsible for both enumeration and IO operations. In this case the FDO driver has to send all IO requests through the controller device, and in Windows it does that by sending the request to the PDO. Examples of serial busses are SCSI. SAS, and USB. Note that in general the controllers themselves are PCI devices. They function like any other PCI device, and send their IO requests directly to their hardware, not to their PDOs.

Yes, all usb ports are enumerated and belong to a hub, including the root hub which is the first in the hierarchy. Look in device manager and view by connection to see the topology. As for a usb request skipping directly to the usb controller, that is an internal implementation detail to the usb stack. The usb stack consists of the host controller, hub, and generic parent drivers. There are private interfaces between them to optimize operations, including skipping intermediate hubs and sending a device request directly to the controller. The usb device fdo never does this. As per the rules it sends the URB down its own stack where it eventually is processed by the usb stack pdo (enumerated either by the hub or generic parent driver). The pdo has logic to skip the remaining usb topology and send the request directly to the controller.

perhaps I can help too

consider that the Windows IO model adopts a ‘cut through’ model. Where the highest level driver that can communicate with the hardware does. If they can, bus drivers don’t send request over the bus that they control, but rather arbitrate the resources used by higher level drivers to make those communications directly. This is a direct legacy of PCI