Using different drivers by USB REV

We have an existing product that has our standard USB VID/PID. We haven’t set the USB REV to anything so it defaults to FFFF, but the .INF file for our driver doesn’t specify the REV so it works fine:
USB\VID_1234&PID_1234&MI_00

We now have to introduce a new version of the product that uses the same VID/PID, so we thought we could use the REV to make sure it uses the new driver. The new product sets its REV to 0008 (no particular reason it has to be this) so the .INF file looks like:
USB\VID_1234&PID_1234&REV_0008&MI_00
This seems to work fine - the new driver is used when the new device is connected.

The problem comes when the old driver is also installed. In order to get it to ignore the new device I changed the .INF file to:
USB\VID_1234&PID_1234&REV_FFFF&MI_00
but Windows refuses to recognise this as a valid driver for the old device. Since Device Manager shows the Hardware ID as “USB\VID_1234&PID_1234&REV_???&MI_00” (presumably because FFFF can’t be expressed as a valid BCD) I tried putting this in the .INF file:
USB\VID_1234&PID_1234&REV_???&MI_00
This driver is recognised for the old device. However, if I remove it and plug in the new device it then uses the old driver. I don’t understand how, because if I try and force the new device to upgrade to the old driver it says “The specified location does not contain information about your hardware”.

If I have the new device using the new driver, then unplug and insert the old device, it uses the new driver. I can’t understand why because the new driver should only accept a REV of 0008. Again, if I try to force it to upgrade to the new driver it gives the error above.

I can only assume that when a device is inserted if the VID and PID are the same then Windows doesn’t check the REV, but does if you try to upgrade the driver.

So what we can do? Since the old device has been shipping for a while it’s too late to set the REV to something other than FFFF. Are there any other ways round this, or are we screwed?

Thanks for any help.

how about just changing the PID, as in the *product* ID, since you are introducing a new version of the product?

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Thursday, January 07, 2010 10:15 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Using different drivers by USB REV

We have an existing product that has our standard USB VID/PID. We haven’t set the USB REV to anything so it defaults to FFFF, but the .INF file for our driver doesn’t specify the REV so it works fine:
USB\VID_1234&PID_1234&MI_00

We now have to introduce a new version of the product that uses the same VID/PID, so we thought we could use the REV to make sure it uses the new driver. The new product sets its REV to 0008 (no particular reason it has to be this) so the .INF file looks like:
USB\VID_1234&PID_1234&REV_0008&MI_00
This seems to work fine - the new driver is used when the new device is connected.

The problem comes when the old driver is also installed. In order to get it to ignore the new device I changed the .INF file to:
USB\VID_1234&PID_1234&REV_FFFF&MI_00
but Windows refuses to recognise this as a valid driver for the old device. Since Device Manager shows the Hardware ID as “USB\VID_1234&PID_1234&REV_???&MI_00” (presumably because FFFF can’t be expressed as a valid BCD) I tried putting this in the .INF file:
USB\VID_1234&PID_1234&REV_???&MI_00
This driver is recognised for the old device. However, if I remove it and plug in the new device it then uses the old driver. I don’t understand how, because if I try and force the new device to upgrade to the old driver it says “The specified location does not contain information about your hardware”.

If I have the new device using the new driver, then unplug and insert the old device, it uses the new driver. I can’t understand why because the new driver should only accept a REV of 0008. Again, if I try to force it to upgrade to the new driver it gives the error above.

I can only assume that when a device is inserted if the VID and PID are the same then Windows doesn’t check the REV, but does if you try to upgrade the driver.

So what we can do? Since the old device has been shipping for a while it’s too late to set the REV to something other than FFFF. Are there any other ways round this, or are we screwed?

Thanks for any help.


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

I wish it was that simple, but it’s not possible.

>

I wish it was that simple, but it’s not possible.

Hey! You can’t just say that without explaining why :slight_smile:

James

[USB driver selection based on REV_xxxx/bcdDevice fails with values
0xFFFF and 0x0008]

Doron: Does what the OP wants work correctly, if both bcdDevice values
are legal (e.g. 0x0000 instead of 0xFFFF)? Or are there more problems?

“Parsley72”:

On 1/8/2010 7:14 AM, xxxxx@gmail.com wrote:

We have an existing product that has our standard USB VID/PID. We
haven’t set the USB REV to anything so it defaults to FFFF […]

Assuming “USB REV” is actually “bcdDevice”, the USB 2.0 specification
states that this is the “Device release number in binary-coded decimal”.

Commmon “default values” for bcdDevice are 0x0000 or 0x0100.
For binary-coded decimal, 0xFFFF is an “illegal value”.

=> You are lucky that your USB device works at all. With any OS.

So what we can do?

On 1/8/2010 7:54 AM, Doron Holan wrote:

how about just changing the PID, as in the *product* ID, since you
are introducing a new version of the product?

Probably this is the only working solution.

On 1/8/2010 10:43 AM, xxxxx@gmail.com wrote:

I wish it was that simple, but it’s not possible.

Ooookaaaay… let me summarize:

  • You have USB devices “in the wild” with an illegal “bcdDevice” entry
    in their USB configuration descriptor.

  • Windows does not reject the USB device, but now you found out it does
    cannot use bcdDevice for driver selection.

  • Management does not allow you to change the “idProduct” field for the
    new USB device revision (which would solve the driver problem).

Are there any other ways round this, or are we screwed?

Well, you could re-write the OS. Probably, yes, you are.

Hagen Patzke wrote:

Doron: Does what the OP wants work correctly, if both bcdDevice
values are legal (e.g. 0x0000 instead of 0xFFFF)? Or are there
more problems?

I just posted about this in another thread. bcdDevice is not part of the device ID when the devnode gets set up. (Go look in HKLM\System\CCS\Enum\USB – &REV isn’t in there anywhere.) Therefore, changing it and plugging in your device again doesn’t do anything. Don’t know what values of REV are valid or not because they are pretty useless, so I don’t use them. Best advice: use a new PID, just like Doron said.

On 1/8/2010 4:00 PM, xxxxx@gmail.com wrote:

[…] bcdDevice is not part of the device ID when the devnode gets
set up. (Go look in HKLM\System\CCS\Enum\USB – &REV isn’t in there
anywhere.) Therefore, changing it and plugging in your device again
doesn’t do anything. […]

Many thanks, Chris, for the clarification!

Best advice: use a new PID, just like Doron said.

Yup, making a note of it here.

xxxxx@gmail.com wrote:

We have an existing product that has our standard USB VID/PID. We haven’t set the USB REV to anything so it defaults to FFFF, but the .INF file for our driver doesn’t specify the REV so it works fine:
USB\VID_1234&PID_1234&MI_00

I’m wondering where you came up with the idea that FFFF was a legal
value for the bcdDevice field. There is no notion of a “default”
revision number. The revision must always be specified in the device
descriptor, and it’s supposed to be a BCD value. Thus, a value of FFFF
violates the USB specification.

So what we can do? Since the old device has been shipping for a while it’s too late to set the REV to something other than FFFF. Are there any other ways round this, or are we screwed?

As I you have already been told, you are screwed. You’re going to need
to change the PID. That shouldn’t be any more difficult than changing
the revision.

And this time, set the bcdDevice field to 0100 (1.0) to begin with…


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

> -----Original Message-----

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Friday, January 08, 2010 4:00 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Using different drivers by USB REV

I just posted about this in another thread. bcdDevice is not
part of the device ID when the devnode gets set up. (Go look
in HKLM\System\CCS\Enum\USB – &REV isn’t in there anywhere.)
Therefore, changing it and plugging in your device again
doesn’t do anything. Don’t know what values of REV are valid
or not because they are pretty useless, so I don’t use them.

They aren’t useless, they can be used exactly as intended i.e. to
disinguigh device revision. Inside the driver or software. This info is
part of the device descriptor so driver has it during initialization and
can distinguish device revisions. It is helpful in some cases; we use
it.

From OS point of view the situation is a bit schizophrenic. REV is part
of HW ID and can be specified in the INF but it isn’t part of Device
Instance ID so devices with different revision share the same device
node (as you wrote). It leads to confusion as OP demonstrated. I’d like
to know intention behind it, it seems as a design mistake or omission.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]

> -----Original Message-----

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Friday, January 08, 2010 7:05 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Using different drivers by USB REV

I’m wondering where you came up with the idea that FFFF was a legal
value for the bcdDevice field. There is no notion of a “default”
revision number. The revision must always be specified in the device
descriptor, and it’s supposed to be a BCD value. Thus, a
value of FFFF
violates the USB specification.

You’re rigth. Recently I noticed this problem with a prototype of our
new device where revision used hex value from A - F range. OS created
strange HW ID for it and USB analyser marked this field in the decriptor
as invalid. We fixed it but tried USB-IF tests before to see if it
passes. Susprisingly, it did. It doesn’t mean anything, thought, tests
can be improved in the future and devices with invalid revision may not
pass. Better play safe and use only 0 - 9 digits for bcdDevice.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]

I appreciate all the responses. I was trying to simplify the description of our problem but I can see a more complete explanation is required.

I’m actually talking about a problem we have in production. We make a variety of products with different VID/PIDs using the same hardware, so when the board is first programmed it’s VID:PID:REV is FFFF:FFFF:FFFF. I don’t write the firmware, but I’m told this is because we can only change a 1 to a 0 but not vice-versa. So we leave it as all 1’s to give us the maximum possible range of VID/PIDs. We have a special version of the driver for production that recognises a VID:PID of FFFF:FFFF - obviously this is never released outside the factory.

During the calibration of the device the VID:PID is set according to the model number. At the moment the REV is always set to 1. So the product as the end user sees it has a valid REV of 1, not an ‘illegal’ value of FFFF’.

The problem is that we’re introducing a new hardware board that uses a different driver but also needs to have a large possible range of VID/PIDs (not the same ones, obviously). The problem is that the same PCs in production need to tell the difference between the old and new hardware. Our solution was to set the REV to 0008 in the firmware of the new boards then change the .INF files of both drivers to distinguish between them, but as explained previously this doesn’t work.

The obvious solution is to change the firmware of the old hardware as well to set the VID:PID:REV to FFFF:FFFF:0001 (so the REV matches the finished product). Unfortunately this is difficult because our products are actually manufactured by many companies (over 20) at different locations round the world. If we change the firmware then they all have to retest, recertify, relogo or whatever is required for their product, so the Product Manager is strongly against this solution. I’m trying to figure out a different way of resolving this.

So to answer your question - we can’t change the PID before we plug into a PC and set the model. Defaulting it to anything other than FFFF restricts what it can be set to later on.

I find this comment particularly interesting:

bcdDevice is not part of the device ID when the devnode gets set up. (Go look in
HKLM\System\CCS\Enum\USB – &REV isn’t in there anywhere.) Therefore, changing it and
plugging in your device again doesn’t do anything. Don’t know what values of REV are valid or not
because they are pretty useless, so I don’t use them.
This implies that even if we do change the old firmware to default the REV to 0001 (and change the .INF files to match) we still can’t guarantee that Windows will use the correct driver. Am I correct? I should be able to test this next week if nobody’s sure.

Anyway, thanks for all the help and apologies for trying to simplify the explanation!

> -----Original Message-----

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Saturday, January 09, 2010 7:27 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Using different drivers by USB REV

This implies that even if we do change the old firmware to
default the REV to 0001 (and change the .INF files to match)
we still can’t guarantee that Windows will use the correct
driver. Am I correct?

Yes. OS will load only one driver for all revisions of your device. The
device node is created for VID/PID/USB port and revision doesn’t play
role.

What exactly is your production PC doing? Isn’t is possible to have one
driver (possible 3rd one) for both devices initialization which changes
VID/PID/REV and after change continue with standard driver? The
‘initial’ driver can distinguigh between devices using revisions because
it knows device descriptor.

If not, you can sacrifice one bit of PID to distinguigh devices.
Similarly as you did with REV but now it would work. REV is really meant
to distinguigh revisions of one device and not different devices. In
other words, if devices are so different they can’t use one driver, you
misused REV field and have to use something else.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]

The one thing I don’t understand is why Windows sometimes uses the wrong driver when the device is connected, but won’t allow me to force an upgrade to the wrong driver. It seems like in that situation it does check the REV.

Yeah, the third driver option did occur to me. I’ll have to talk to the driver team…

Thanks for the advice.

Does anyone know of a Windows function call that replicates the Device Manager functionality of forcing an upgrade to a driver of my choice? I might be able to sort this out from our calibration application.

> -----Original Message-----

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Saturday, January 09, 2010 10:17 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Using different drivers by USB REV

The one thing I don’t understand is why Windows sometimes
uses the wrong driver when the device is connected, but won’t
allow me to force an upgrade to the wrong driver. It seems
like in that situation it does check the REV.

Sure. Once devnode is created, installed driver is used for connected
device with given VID/PID regardless of revision. But if you specify REV
in the INF, it is checked and the device has to match exactly. Check
Setup API logs to see what exactly happens.

Does anyone know of a Windows function call that replicates
the Device Manager functionality of forcing an upgrade to a
driver of my choice? I might be able to sort this out from
our calibration application.

You can use Setup API and/or DIFx. The first is pretty convoluted and
creating the app you need is possible but rather complicated (have done
something like this). Note force upgrade isn’t sufficient in your case.
You have to completely remove old driver at first which isn’t completely
documented and maybe even supported scenario (but possible). DIFx can be
better choice but I’d leave this part on others as I don’t have enough
experience there.

What do you want to do? Exchange drivers according to device connected?
Bad idea which would lead to more problems than it should solve. One for
all – you may need to reboot and maybe twice.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]

If the device connects using the wrong driver, I can use Device Manager to force an upgrade to the correct driver and this doesn’t require a reboot. If I can do this manually I assume there’s a way to do it programatically. I can add code to our app (or write a new one) to check the driver matches the REV, and force a driver change if it doesn’t.

Seems as really bad idea for production to me. Possible but slow and
fragile. Production machines should be as stable as possible and the
process as simple as possible. Otherwise it can lead to nightmare for
you. We’re doing mass production and I wouldn’t afford something like
this.

And I don’t see a reason for it. If wrong driver can be loaded, it isn’t
so wrong and should be usable for VID/PID/REV change. Then device should
be reconnected (manually or programatically) and new driver will be
loaded, now correct one. You can finish device configuration with it.

If you really want to do crazy things, the simplest way is to exchange
driver binaries without reinstallation. It is simple and relatively
safe. Two renames and one driver reload if you detect wrong driver. In
presumes drivers can share devnode registry area. But in ugrade scenario
there is the same problem as the devnode isn’t deleted, just updated.
Can lead to quite interesting things. That’s one reason why I mentioned
complete driver remove before.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Saturday, January 09, 2010 10:35 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Using different drivers by USB REV

If the device connects using the wrong driver, I can use
Device Manager to force an upgrade to the correct driver and
this doesn’t require a reboot. If I can do this manually I
assume there’s a way to do it programatically. I can add code
to our app (or write a new one) to check the driver matches
the REV, and force a driver change if it doesn’t.


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

xxxxx@gmail.com wrote:

The one thing I don’t understand is why Windows sometimes uses the
wrong driver when the device is connected, but won’t allow me to
force an upgrade to the wrong driver. It seems like in that situation
it does check the REV.

Can it be WIndows uses sometimes the wrong driver when you use a
different USB port?

There might by another possibility to solve your production problem, at
least as a workaround until a better solution is found (in my opinion
it’s a Windows “Quirk”, but in your case it may be actually beneficial):

As long as your devices don’t have a USB serial number set, you can have
two different drivers for the same device type (VID/PID) for two
different USB ports.

Only the driver class GUID and name must be different (NOT the Device
GUID!) for this to work.

We used this to speed-test a WUDF version of our USB bulk device driver
against the WDM version. If you connected the device to USB port one,
Windows used the WDM driver, when you connected the device to USB port
two, Windows used the WUDF driver. (Tested on XP, in 2006.)

>> If the device connects using the wrong driver, I can use

> Device Manager to force an upgrade to the correct driver and
> this doesn’t require a reboot. If I can do this manually I
> assume there’s a way to do it programatically. I can add code
> to our app (or write a new one) to check the driver matches
> the REV, and force a driver change if it doesn’t.

Assuming the new driver shall really replace the old one,
check out DPinst.

AFAIK, this not only pre-installs a driver, but also replaces all
instances of the old driver with the new one.

Plus, it is refreshingly simple to use, you need it for Windows7 anyway
(unless you prefer to re-create the functionality using the API), and
you don’t need to worry what driver to install if you connect a device
to another USB port.