Enumerating multiport devices?

I’ve got a PCI device that implements 8 serial ports.

I’m using mf.sys by creating an inf of class=MultiportSerial to enumerate the 8 devices with new hardware IDS like “MF\myserial1001”, “MF\myserial1002”, etc…

That works just fine. My question is, what happens when I stuff more than one of these PCI devices into the system? My multiportserial inf is going to want to create another set of “MF\myserial1001”, “MF\myserial1002”, etc…

Ideally I’d like to be able to plug in the 1st card and enumerate ports 1-8, plug in a second and get 9-16… You get the idea.

As a side note in order to get the COM ports ordered properly I had to write a coinstaller to that interrogates the hardware id (myserialXXXX), and reassigns the COM port number appropriately.

You’ve misunderstood the way INFs work. All your serial ports run the same
child-level driver, right? Then all the IDs should be the same. You only
need one entry in your INF. I suggest, given your pattern,
“MF\myserialmycompanyname”.

Jake Oshins
Windows Kernel Team

This message offers no warranties and confers no rights.

wrote in message news:xxxxx@ntdev…

I’ve got a PCI device that implements 8 serial ports.

I’m using mf.sys by creating an inf of class=MultiportSerial to enumerate
the 8 devices with new hardware IDS like “MF\myserial1001”,
“MF\myserial1002”, etc…

That works just fine. My question is, what happens when I stuff more than
one of these PCI devices into the system? My multiportserial inf is going
to want to create another set of “MF\myserial1001”, “MF\myserial1002”,
etc…

Ideally I’d like to be able to plug in the 1st card and enumerate ports 1-8,
plug in a second and get 9-16… You get the idea.

As a side note in order to get the COM ports ordered properly I had to write
a coinstaller to that interrogates the hardware id (myserialXXXX), and
reassigns the COM port number appropriately.

Thanks for responding Jake.

The reason I had to give them unique IDs is because the order in which each MF device was enumerated was incorrect.

Specifically lets say each serial port has 8 1-byte wide registers. I have 8 of these implemented in contiguous memory in the same BAR. If I assign the IDs the same, Windows will enumerated the COMs in an order like 1,8,2,7,3,6,4,5. To get around this I gave them unique IDs that my coinstaller parses and then reassigns the COM# appropriately. So if myserial1002 is assigned COM8 by default, the coinstaller sees that it should have been 2 and then renames it.

If I silkscreen the DB9 connectors with the respective COM port number in Windows I want to make sure they are correct.

Where I need help is that this approach won’t work when if I plug more than one card in. If I could get Windows to enumerate the devices in the order in which they are defined in the INF file life would be good.

Do you have any suggestions that I might try?

You can’t guarantee that you get any particular COM port number under
Windows. Any machine into which you plug this may have COM ports which
conflict with yours. Attempts to silkscreen these numbers usually fail.

Jake Oshins
Windows Kernel Team

This message offers no warranties and confers no rights.

wrote in message news:xxxxx@ntdev…

Thanks for responding Jake.

The reason I had to give them unique IDs is because the order in which each
MF device was enumerated was incorrect.

Specifically lets say each serial port has 8 1-byte wide registers. I have
8 of these implemented in contiguous memory in the same BAR. If I assign
the IDs the same, Windows will enumerated the COMs in an order like
1,8,2,7,3,6,4,5. To get around this I gave them unique IDs that my
coinstaller parses and then reassigns the COM# appropriately. So if
myserial1002 is assigned COM8 by default, the coinstaller sees that it
should have been 2 and then renames it.

If I silkscreen the DB9 connectors with the respective COM port number in
Windows I want to make sure they are correct.

Where I need help is that this approach won’t work when if I plug more than
one card in. If I could get Windows to enumerate the devices in the order
in which they are defined in the INF file life would be good.

Do you have any suggestions that I might try?

I don’t need fixed COM port numbers. I DO need them sequentially. Maybe I’m not communicating very clearly. I’ve included the section of my multiportserial inf. I would expect Windows to start with the next available COM port number. Let’s say it’s 12 (just for fun). In that case I would want MF\myserial1001 to get COM12, MF\myserial1002 to get COM13, and so on. That is NOT what happens. MF\myserial1001 gets COM12, then MF\myserial1008 gets COM13, MF\myserial1002 gets COM14.

This is a problem because my hardware has 8 physical ports that are pinned out such that BAR0+0 is the 1st. BAR0+8 is the 2nd, etc. Ideally I wouldn’t need to use a different ID for each port and Windows would load the driver for each device in the order I have specified below. How do I work around this? I’ve been fighting this for a very long time and know there has got to be a better way to handle this issue. I need help understanding how Windows does what it does though.

HKR, Child0000, HardwareID, MF\myserial1001
HKR, Child0000, VaryingResourceMap,1,00, 00,00,00,00, 08,00,00,00
HKR, Child0000, ResourceMap,1,02

HKR, Child0001, HardwareID, MF\myserial1002
HKR, Child0001, VaryingResourceMap,1,00, 08,00,00,00, 08,00,00,00
HKR, Child0001, ResourceMap,1,02

HKR, Child0002, HardwareID, MF\myserial1003
HKR, Child0002, VaryingResourceMap,1,00, 10,00,00,00, 08,00,00,00
HKR, Child0002, ResourceMap,1,02

HKR, Child0003, HardwareID, MF\SELserial1004
HKR, Child0003, VaryingResourceMap,1,00, 18,00,00,00, 08,00,00,00
HKR, Child0003, ResourceMap,1,02

HKR, Child0004, HardwareID, MF\SELserial1005
HKR, Child0004, VaryingResourceMap,1,00, 20,00,00,00, 08,00,00,00
HKR, Child0004, ResourceMap,1,02

HKR, Child0005, HardwareID, MF\myserial1006
HKR, Child0005, VaryingResourceMap,1,00, 28,00,00,00, 08,00,00,00
HKR, Child0005, ResourceMap,1,02

HKR, Child0006, HardwareID, MF\SELserial1007
HKR, Child0006, VaryingResourceMap,1,00, 30,00,00,00, 08,00,00,00
HKR, Child0006, ResourceMap,1,02

HKR, Child0007, HardwareID, MF\myserial1008
HKR, Child0007, VaryingResourceMap,1,00, 38,00,00,00, 08,00,00,00
HKR, Child0007, ResourceMap,1,02

You have one set of BARs. Why not just write your driver so that one device instance handles ALL those bars and exports ALL your comports… name that whatever you want, in whatever sequence you want. Windows supplies a COM Port Database for this purpose.

Peter
OSR

Peter,

I’m not sure I’m understanding your suggestion very well. Are you suggesting I change my model from using a multiport serial adapter to enumerate each COM port and instead load my serial driver for the device directly. Then re-write my serial driver such that it splits it’s resources (BAR0+0 -> COM1, BAR0+1 -> COM2, etc) in a way that it exports each resource independently using the COM Port Database?

If so, I’m not really sure how to go about that. If I completely missed the mark, could you clarify what you meant?

Shane

Yes. Precisely.

When I hear “one set of bars” I think “that’s one device” hence “there’s one driver needed here.” I haven’t done a many-to-one serial port driver, and interfacing with the COM Port Database presents a complexity here that I’m not personally familiar with… but I *do* know the interfaces to that database are documented.

In terms of possible approaches, assuming you’re writing this in KMDF then ONE approach could be to write a simple bus driver and create one PDO for each com port. Set the PDOs in RAW mode (see WdfPdoInitAssignRawDevice).

KMDF *might* make the naming issue tricky… again, that needs a bit of exploration before you get too far down that path (KMDF raw PDOs want to have auto-generated names, for example, and I don’t know off-hand if this can be changed).

An alternative design might be one with multiple FDOs as “control devices”… This is less sensible architecturally (you wind-up with one PDO, one FDO, and a bunch of rogue “control devices” which is kinda yucky), but probably tenable.

But, whatever… if you want to be in control of your com port numbers, that’s an approach you might want to explore.

One final note to amplify Jake’s comment about “silk screened numbers” generally not making sense… Note that the standard interface for serial ports allows the user to change serial port numbers at will. Thereby defying whatever silk-screened numbering scheme you might devise.

Peter
OSR

Kmdf has auto generated names for pdos as a default, if you want to use specific names, go right ahead

d

debt from my phone


From: xxxxx@osr.com
Sent: 9/25/2012 2:26 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Enumerating multiport devices?

Yes. Precisely.

When I hear “one set of bars” I think “that’s one device” hence “there’s one driver needed here.” I haven’t done a many-to-one serial port driver, and interfacing with the COM Port Database presents a complexity here that I’m not personally familiar with… but I *do* know the interfaces to that database are documented.

In terms of possible approaches, assuming you’re writing this in KMDF then ONE approach could be to write a simple bus driver and create one PDO for each com port. Set the PDOs in RAW mode (see WdfPdoInitAssignRawDevice).

KMDF *might* make the naming issue tricky… again, that needs a bit of exploration before you get too far down that path (KMDF raw PDOs want to have auto-generated names, for example, and I don’t know off-hand if this can be changed).

An alternative design might be one with multiple FDOs as “control devices”… This is less sensible architecturally (you wind-up with one PDO, one FDO, and a bunch of rogue “control devices” which is kinda yucky), but probably tenable.

But, whatever… if you want to be in control of your com port numbers, that’s an approach you might want to explore.

One final note to amplify Jake’s comment about “silk screened numbers” generally not making sense… Note that the standard interface for serial ports allows the user to change serial port numbers at will. Thereby defying whatever silk-screened numbering scheme you might devise.

Peter
OSR


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Doron,

How does one go about using specific names rather than the auto generated ones?

-Shane

So, the autogenerated name is just a DEFAULT. You assign a specific name to a WDFDEVICE using WdfDeviceInitAssignName.

Peter
OSR

why do you care? As long as unique names (COM12, COM14, etc.) are assigned
to each port, what difference does it make to you what they are? Users have
long had the ability to rename com ports in Windows and most high-end multi
port serial solutions I have seen have some kind of helper app that allows
the user to physically identify which port a name maps to

If your hardware cannot be accesses independently for each port, then MF
will not work and you need another solution, but this has nothing to do with
how the ports are named to the user

wrote in message news:xxxxx@ntdev…

I don’t need fixed COM port numbers. I DO need them sequentially. Maybe
I’m not communicating very clearly. I’ve included the section of my
multiportserial inf. I would expect Windows to start with the next
available COM port number. Let’s say it’s 12 (just for fun). In that case
I would want MF\myserial1001 to get COM12, MF\myserial1002 to get COM13, and
so on. That is NOT what happens. MF\myserial1001 gets COM12, then
MF\myserial1008 gets COM13, MF\myserial1002 gets COM14.

This is a problem because my hardware has 8 physical ports that are pinned
out such that BAR0+0 is the 1st. BAR0+8 is the 2nd, etc. Ideally I
wouldn’t need to use a different ID for each port and Windows would load the
driver for each device in the order I have specified below. How do I work
around this? I’ve been fighting this for a very long time and know there
has got to be a better way to handle this issue. I need help understanding
how Windows does what it does though.

HKR, Child0000, HardwareID, MF\myserial1001
HKR, Child0000, VaryingResourceMap,1,00, 00,00,00,00, 08,00,00,00
HKR, Child0000, ResourceMap,1,02

HKR, Child0001, HardwareID, MF\myserial1002
HKR, Child0001, VaryingResourceMap,1,00, 08,00,00,00, 08,00,00,00
HKR, Child0001, ResourceMap,1,02

HKR, Child0002, HardwareID, MF\myserial1003
HKR, Child0002, VaryingResourceMap,1,00, 10,00,00,00, 08,00,00,00
HKR, Child0002, ResourceMap,1,02

HKR, Child0003, HardwareID, MF\SELserial1004
HKR, Child0003, VaryingResourceMap,1,00, 18,00,00,00, 08,00,00,00
HKR, Child0003, ResourceMap,1,02

HKR, Child0004, HardwareID, MF\SELserial1005
HKR, Child0004, VaryingResourceMap,1,00, 20,00,00,00, 08,00,00,00
HKR, Child0004, ResourceMap,1,02

HKR, Child0005, HardwareID, MF\myserial1006
HKR, Child0005, VaryingResourceMap,1,00, 28,00,00,00, 08,00,00,00
HKR, Child0005, ResourceMap,1,02

HKR, Child0006, HardwareID, MF\SELserial1007
HKR, Child0006, VaryingResourceMap,1,00, 30,00,00,00, 08,00,00,00
HKR, Child0006, ResourceMap,1,02

HKR, Child0007, HardwareID, MF\myserial1008
HKR, Child0007, VaryingResourceMap,1,00, 38,00,00,00, 08,00,00,00
HKR, Child0007, ResourceMap,1,02

m wrote:

why do you care? As long as unique names (COM12, COM14, etc.) are
assigned to each port, what difference does it make to you what they
are? Users have long had the ability to rename com ports in Windows and
most high-end multi port serial solutions I have seen have some kind of
helper app that allows the user to physically identify which port a name
maps to

Such an helper app sounds like a very good idea.

Regarding your initial problem, how to prevent random ordering of the
assigned COMx names: The class installer for serial ports will always
pick the lowest available number, so you “only” have to make sure that
the ports are installed in the correct order.

To do this, you might write your own version of MF.sys that creates one
PDO for each serial port. Now create them not only in the correct order,
but always wait until one PDO’s driver has been installed (*) before
creating the next. And if YourMF.sys has been loaded for more than one
PCI card, make sure that no card starts enumerating its ports while
another is still in the process of doing so.

*: “Driver has been installed” is easy to determine from user mode, by
looking at the state of the device nodes. For your bus driver it is
trickier. One possible approach: When a PDO has reached power level D0,
you can be sure that its driver has been installed and loaded. The
opposite is not true, however. Be prepared for scenarios such as one COM
port disabled in the device manager and therefore never reaching D0. A
naive implementation would stumble and create no more serial ports after
that one.

So, you want him to write a SEPARATE bus driver just to do the enumeration AND a driver for the serial port card?

That seems like rather a lot of work to end-up with an architecture which isn’t even a good one.

As I said, he could just write ONE driver, the bus driver, and be done with it. To repeat: He’s got ONE card, with ONE set of resources (BARs). That means ONE power state, etc…
Peter
OSR

I think that if I were trying to meet the goals set forth in this thread
(and I don’t think I would actually agree with them, but I’ll put that aside
for the moment) I think I would write DLL that provided a property page in
device manager that displayed the silkscreen’s value. Tell the user: If you
want to know which COM port it is, look in Device Manager and match up with
the silkscreen. Let the COM port number be what it is.

Jake Oshins
Windows Kernel Team

This message offers no warranties and confers no rights.

“Wilhelm Nöker” wrote in message news:xxxxx@ntdev…

m wrote:

why do you care? As long as unique names (COM12, COM14, etc.) are
assigned to each port, what difference does it make to you what they
are? Users have long had the ability to rename com ports in Windows and
most high-end multi port serial solutions I have seen have some kind of
helper app that allows the user to physically identify which port a name
maps to

Such an helper app sounds like a very good idea.

Regarding your initial problem, how to prevent random ordering of the
assigned COMx names: The class installer for serial ports will always
pick the lowest available number, so you “only” have to make sure that
the ports are installed in the correct order.

To do this, you might write your own version of MF.sys that creates one
PDO for each serial port. Now create them not only in the correct order,
but always wait until one PDO’s driver has been installed (*) before
creating the next. And if YourMF.sys has been loaded for more than one
PCI card, make sure that no card starts enumerating its ports while
another is still in the process of doing so.

*: “Driver has been installed” is easy to determine from user mode, by
looking at the state of the device nodes. For your bus driver it is
trickier. One possible approach: When a PDO has reached power level D0,
you can be sure that its driver has been installed and loaded. The
opposite is not true, however. Be prepared for scenarios such as one COM
port disabled in the device manager and therefore never reaching D0. A
naive implementation would stumble and create no more serial ports after
that one.