How to obtain the PDO from a FDO

My problem is that I need to obtain the PCI bus address (bus number & PCI
slot number) of a FDO which my driver has opened. My driver is layered on
top of several different kinds of devices and needs to know their physical
locations. I could add a private IOCTL for obtaining the bus address (that
is actually what I will have to do tonight) but it bugs me that the
information is available somewhere and I shouldn’t need an IOCTL to get
it.

My first idea was to use IoGetDeviceProperty from the top-level driver;
alas it needs an PDO. So, unless there is some other way to obtain the bus
address of a device by its FDO(I don’t think so), I need a wat to find the
PDO of a FDO, or even a way to walk the device stack.

Is this possible ? Am I missing something simple ?

-tzvetan

There is a KB article that documents the complete procedure.
http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q253232

=====================
Mark Roddy
Windows XP/2000/NT Consultant, Microsoft MVP
Hollis Technology Solutions 603-321-1032
www.hollistech.com
xxxxx@hollistech.com
For Windows Device Driver Training: see www.azius.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@jupiter.com
Sent: Sunday, April 07, 2002 1:06 AM
To: NT Developers Interest List
Subject: [ntdev] How to obtain the PDO from a FDO

My problem is that I need to obtain the PCI bus address (bus
number & PCI slot number) of a FDO which my driver has
opened. My driver is layered on top of several different
kinds of devices and needs to know their physical locations.
I could add a private IOCTL for obtaining the bus address
(that is actually what I will have to do tonight) but it bugs
me that the information is available somewhere and I
shouldn’t need an IOCTL to get it.

My first idea was to use IoGetDeviceProperty from the
top-level driver; alas it needs an PDO. So, unless there is
some other way to obtain the bus address of a device by its
FDO(I don’t think so), I need a wat to find the PDO of a FDO,
or even a way to walk the device stack.

Is this possible ? Am I missing something simple ?

-tzvetan


You are currently subscribed to ntdev as:
xxxxx@hollistech.com To unsubscribe send a blank email to
%%email.unsub%%

I am afraid that is not it. The KB article just explains how to obtain the
bus address using IoGetDeviceProperty, which, as I already mentioned in my
initial post, doesn’t work because IoGetDeviceProperty requires a PDO.
Which in turn leads back to my initial question: how to get the PDO from
an FDO ?? :slight_smile:

In the meantime I accidentally found another way to determine device’s
physical location on the PCI bus. It turns out that the PCI bus driver
handles IRP_MN_QUERY_ID(BusQueryInstanceID) by returning a string with the
Device+Function IDs of the device and all its parent bridges. This is the
most complete information anybody could want. The problem is that it could
break any time since newer versions of the PCI bus driver may change the
format of the Device Instance ID.

The search continues!

-tzvetan

You can send an IRP_MN_QUERY_DEVICE_RELATIONS type TargetDeviceRelation
down the stack to get a referenced pointer to the PDO.

=====================
Mark Roddy
Windows XP/2000/NT Consultant, Microsoft MVP
Hollis Technology Solutions 603-321-1032
www.hollistech.com
xxxxx@hollistech.com
For Windows Device Driver Training: see www.azius.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tzvetan Mikov
Sent: Sunday, April 07, 2002 6:24 PM
To: NT Developers Interest List
Subject: [ntdev] Re: How to obtain the PDO from a FDO

I am afraid that is not it. The KB article just explains how
to obtain the bus address using IoGetDeviceProperty, which,
as I already mentioned in my initial post, doesn’t work
because IoGetDeviceProperty requires a PDO. Which in turn
leads back to my initial question: how to get the PDO from an
FDO ?? :slight_smile:

In the meantime I accidentally found another way to determine
device’s physical location on the PCI bus. It turns out that
the PCI bus driver handles
IRP_MN_QUERY_ID(BusQueryInstanceID) by returning a string with the
Device+Function IDs of the device and all its parent bridges. This is
Device+the
most complete information anybody could want. The problem is
that it could break any time since newer versions of the PCI
bus driver may change the format of the Device Instance ID.

The search continues!

-tzvetan


You are currently subscribed to ntdev as:
xxxxx@hollistech.com To unsubscribe send a blank email to
%%email.unsub%%

> You can send an IRP_MN_QUERY_DEVICE_RELATIONS type TargetDeviceRelation

down the stack to get a referenced pointer to the PDO.

=====================
Mark Roddy

Thanks a lot! This answers my question and solves the first part of my
problem. Below I have tried to describe the second part.

I am trying to build a “slot path” for a PCI device. A “slot path” is the
sequence of PCI device/function numbers, starting from the device itself,
and going through the chain of bridges up the PCI tree to bus 0. The slot
path uniquely identifies the actual physical location of the PCI board.
Why do I need it ? - I need to address devices geographically and our
system has a very complex PCI tree.

So, here is my question: Is there a way to get to the device’s parent PCI
bridges, so I can obtain their Device/function numbers as well?

(There is one solution that will work but I don’t like it at all: Having
obtained a device’s bus number using IoGetDeviceProperty(), I can
enumerate the entire bus with HalGetBusData() until I reach the device’s
parent bridge)

-tzvetan

> alas it needs an PDO. So, unless there is some other way to obtain the bus

address of a device by its FDO(I don’t think so), I need a wat to find the
PDO of a FDO, or even a way to walk the device stack.

Finding a PDO is trivial. It is reported to your AddDevice routine, regardless of where in the stack you are. Just store it
somewhere for subsequent PnP function calls.
In the worst case, you can send MN_QUERY_DEVICE_RELATIONS/TargetDeviceRelation down the stack. This will return a PDO.

Max

> most complete information anybody could want. The problem is that it could

break any time since newer versions of the PCI bus driver may change the
format of the Device Instance ID.

Doubts. This will break all existing INF files for PCI cards.

Max

> Finding a PDO is trivial. It is reported to your AddDevice routine, regardless of where in the stack you are. Just store it

somewhere for subsequent PnP function calls.

This doesn’t work for me because I am not on the device stack. My driver
opens devices and uses them; it is not a filter driver.

In the worst case, you can send MN_QUERY_DEVICE_RELATIONS/TargetDeviceRelation down the stack. This will return a PDO.

Yes, that is the solution.

-tzvetan

> > most complete information anybody could want. The problem is that it could

> break any time since newer versions of the PCI bus driver may change the
> format of the Device Instance ID.

Doubts. This will break all existing INF files for PCI cards.

No. The INF files specify Device IDs. I am talking about Device Instance
IDs, which identify a particluar instance of a device in the system.

-tzvetan

“Tzvetan Mikov” wrote in message news:xxxxx@ntdev…
>
> (There is one solution that will work but I don’t like it at all: Having
> obtained a device’s bus number using IoGetDeviceProperty(), I can
> enumerate the entire bus with HalGetBusData() until I reach the device’s
> parent bridge)
>

Actually, that may NOT work. Consider that bus/slot numbers can change
dynamically (with the addition/removal of devices). HalGetBusData(…) won’t
properly handle this. Or at least so I’ve been told.

Peter
OSR

> > (There is one solution that will work but I don’t like it at all: Having

> obtained a device’s bus number using IoGetDeviceProperty(), I can
> enumerate the entire bus with HalGetBusData() until I reach the device’s
> parent bridge)
>

Actually, that may NOT work. Consider that bus/slot numbers can change
dynamically (with the addition/removal of devices). HalGetBusData(…) won’t
properly handle this. Or at least so I’ve been told.

If that is the case, is there another correct (or even recommended)
approach to enumerate the PCI bus tree ?

If HalGetBusData() doesn’t work, and there isn’t any other way to
enumerate the PCI tree, I will have to write my own routines to read PCI
space. No need to say, it would be extremely messy and non-portable (have
to grab and keep all CPUs since the PCI spin lock is not available, etc.).

I can’t believe such a seamingly easy problem has no solution. There was a
tool in the W2K DDK called pcitool.exe (it is missing in the XP DDK). It
seems to be doing what I need. Does anyone knows how it works ?

-tzvetan

It calls HalGetBusData.

=====================
Mark Roddy
Windows XP/2000/NT Consultant, Microsoft MVP
Hollis Technology Solutions 603-321-1032
www.hollistech.com
xxxxx@hollistech.com
For Windows Device Driver Training: see www.azius.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tzvetan Mikov
Sent: Wednesday, April 10, 2002 12:57 AM
To: NT Developers Interest List
Subject: [ntdev] Re: How to obtain the PDO from a FDO

> > (There is one solution that will work but I don’t like it at all:
> > Having obtained a device’s bus number using
IoGetDeviceProperty(), I
> > can enumerate the entire bus with HalGetBusData() until I
reach the
> > device’s parent bridge)
> >
>
> Actually, that may NOT work. Consider that bus/slot numbers can
> change dynamically (with the addition/removal of devices).
> HalGetBusData(…) won’t properly handle this. Or at least so I’ve
> been told.

If that is the case, is there another correct (or even
recommended) approach to enumerate the PCI bus tree ?

If HalGetBusData() doesn’t work, and there isn’t any other
way to enumerate the PCI tree, I will have to write my own
routines to read PCI space. No need to say, it would be
extremely messy and non-portable (have to grab and keep all
CPUs since the PCI spin lock is not available, etc.).

I can’t believe such a seamingly easy problem has no
solution. There was a tool in the W2K DDK called pcitool.exe
(it is missing in the XP DDK). It seems to be doing what I
need. Does anyone knows how it works ?

-tzvetan


You are currently subscribed to ntdev as:
xxxxx@hollistech.com To unsubscribe send a blank email to
%%email.unsub%%