How to find is an USB device is connected via hub

My crazy workarounds against Vista UHCI bug aren’t necessary when the device isn’t connected directly to HC. If there is an USB hub in the chain, everything works as expected. I’d like to not use workaround unless necessary so I’d need to find if our device is connected via USB hub or directly. No problem with 2.0 hubs because in this case I detect HC as EHCI and workarounds are disabled anyway. Only 1.1 hub has to be detected.

I already tried IOCTL_INTERNAL_USB_GET_HUB_COUNT but is is refused by usbhub.sys if sent from USB function driver down the stack. It checks some internal flags in its device extensions a passes it down only if one of them is set (probably only for hub PDOs). I tried IOCTL_USB_GET_NODE_INFORMATION but it is just completed with STATUS_SUCCESS (!) and no data change when sent this way – it should be probably sent to named interface.

Is there some easy way how to find it out? It is not so important to develop something complicated; USB 1.1 hubs aren’t common nowadays and we only need to solve a case when our fingerprint sensor is connected via internal 1.1 hub for some reasons.

Thanks.

Best regards,

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

Mike,
can’t offer much help but am looking at the exact same issue our product not only MUST connect to the root hub directly but must also be it’s only client as we intend to max-out the bandwidth at least intermittently. I work in the pre-press industry moving image data & we must shovel large files over USB since a printing plate can consume some thing like 12 megabyte per sq. inch multiply that by sq. inches per plate to get the # of pixels ( one bit ea. ) 2 gig per layer & AT LEAST 4 layers ( plates ) to make one image is a SMALL job by our standards plus we must hold at 0 defects per layer. Plz let me know what you find. DBB

I do know one really obvious way…
try to xfer a packet innie or outtie & remember to set time-out as low as you can if the pipe stalls there probably is a non 2.0 unit in the path :slight_smile:

It’d probably work if I can control HC directly but in Windows there are too many things which can influence timing. The problem is test could have false positive result (i.e. too long time even without a hub) which we can’t afford.

Best regards,

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


From: xxxxx@lists.osr.com[SMTP:xxxxx@lists.osr.com] on behalf of xxxxx@xitron.com[SMTP:xxxxx@xitron.com]
Reply To: Windows System Software Devs Interest List
Sent: Friday, February 23, 2007 10:49 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] How to find is an USB device is connected via hub

I do know one really obvious way…
try to xfer a packet innie or outtie & remember to set time-out as low as you can if the pipe stalls there probably is a non 2.0 unit in the path :slight_smile:


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

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

In your case I’d probably examine UsbView WDK sources and solve it from user mode. UsbView is able to discover complete USB topology.

The difference is in your case it seems as standard request whereas in our case it is just temporary workaround tied to one scenario which can be removed once MS gets it fixed.

Best regards,

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


From: xxxxx@lists.osr.com[SMTP:xxxxx@lists.osr.com] on behalf of xxxxx@xitron.com[SMTP:xxxxx@xitron.com]
Reply To: Windows System Software Devs Interest List
Sent: Friday, February 23, 2007 8:53 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] How to find is an USB device is connected via hub

Mike,
can’t offer much help but am looking at the exact same issue our product not only MUST connect to the root hub directly but must also be it’s only client as we intend to max-out the bandwidth at least intermittently. I work in the pre-press industry moving image data & we must shovel large files over USB since a printing plate can consume some thing like 12 megabyte per sq. inch multiply that by sq. inches per plate to get the # of pixels ( one bit ea. ) 2 gig per layer & AT LEAST 4 layers ( plates ) to make one image is a SMALL job by our standards plus we must hold at 0 defects per layer. Plz let me know what you find. DBB


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

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

I know I know it’s always something,
our own devices have had frequent run-ins with systems stress related problems like having to shut the dammed “file find” service off so it doesn’t scan hard drives while a job is running 'cuz it blocks access to the file being processed & so on. just wanted to throw that one out before I leave as one foot is out the door already - I know there is a way… I will try to throw you a bone monday - DBB

xxxxx@xitron.com wrote:

Mike,
can’t offer much help but am looking at the exact same issue our product not only MUST connect to the root hub directly but must also be it’s only client as we intend to max-out the bandwidth at least intermittently. I work in the pre-press industry moving image data & we must shovel large files over USB since a printing plate can consume some thing like 12 megabyte per sq. inch multiply that by sq. inches per plate to get the # of pixels ( one bit ea. ) 2 gig per layer & AT LEAST 4 layers ( plates ) to make one image is a SMALL job by our standards plus we must hold at 0 defects per layer. Plz let me know what you find. DBB

I don’t see why you MUST connect to the root hub. It’s going to take 3
or 4 minutes to transfer 8 gigabytes over a bulk pipe; adding an
inefficient hub in the middle increases that somewhat, but since it’s a
bulk pipe the data will still get there. As long as you put a note to
that effect in the release notes, isn’t it your clients’ job to decide
whether they’re willing to trade performance for convenience?


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

Hi Michal,

I’ve been able to use IOCTL_INTERNAL_USB_GET_HUB_COUNT in a lower filter of
hidusb.sys. It is issued synchronously in the completion routine for start
device. I prepare the Irp using a technique like CallUSBD() but instead of
setting Argument1 to PURB, it is initialized to &HubCount (a ULONG). Also,
HubCount is cleared to 0 before sending the Irp to the next lower driver.

The returned HubCount is equal to the number of usbhub FDO’s which see the
Irp (as it is forwarded) before it is completed by the roothub FDO. When HID
device is connected to a roothub the returned count is 1; if connected to a
single external hub, the returned count is 2; it increments for each level
of hub nesting.

When I saw your posting, I thought this might be a change with Vista. But I
verified the filter driver works on this platform too.

What is the NTSTATUS code you get when it “is refused by usbhub.sys” ?

Stan Mitchell
SourceQuest, Inc.

Mike,
I see stan has a good lead on this looks promising also look at the Usbview.exe example in DDK we will probably Use some variant of that method since we have no filters in our datastream anything that goes thru a lower filter will need a re-write to function.
AND
Tim,
with all due respect NO!
while it PROBABLY will work we absolutely do not support any such thing the problem is not the data-rate itself it’s also because these print jobs can take nearly 30 minutes to complete if anything gobs-up the OS & it’s timing or slows down our status requests to/from hardware it risks damaging our timing even just one data overrun/underrun will blow the whole job ruin the media & waste valuable time. The machines our stuff runs on are configured to support our device & local area network & NOTHING ELSE we really do not share a platform with other tasks so demanding a hub to ourselves is not a big deal.

> since we have no filters in our datastream anything that goes thru a lower

filter will need a re-write to function.

No, I’m not suggesting that a lower filter is required. I used the lower
filter example only to illustrate that a client at the function level in the
stack could issue this IoControlCode. In the test case, hidusb is the
function driver and the filter driver is at the lower edge of it, but above
usbhub’s PDO.

Stan Mitchell
SourceQuest, Inc.

Stan,

that’s interesting. If it works from low hidusb filter, it should work in my case, too. I’ll have to check it again.

I prepare URB exactly as you and the call returns STATUS_INVALID_PARAMETER. When I manually change the result of test usbhub.sys uses to check the device extension, it continues but the result count is 2 if my device is connected directly to root hub. So I guess I sent it to the wrong device, it should be probably one level lower.

BTW, how can you use synchronous call in the completion routine? Can’t it be called at raised IRQL?

Best regards,

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


From: xxxxx@lists.osr.com[SMTP:xxxxx@lists.osr.com] on behalf of xxxxx@yahoo.com[SMTP:xxxxx@yahoo.com]
Reply To: Windows System Software Devs Interest List
Sent: Sunday, February 25, 2007 4:58 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] How to find is an USB device is connected via hub

Hi Michal,

I’ve been able to use IOCTL_INTERNAL_USB_GET_HUB_COUNT in a lower filter of
hidusb.sys. It is issued synchronously in the completion routine for start
device. I prepare the Irp using a technique like CallUSBD() but instead of
setting Argument1 to PURB, it is initialized to &HubCount (a ULONG). Also,
HubCount is cleared to 0 before sending the Irp to the next lower driver.

The returned HubCount is equal to the number of usbhub FDO’s which see the
Irp (as it is forwarded) before it is completed by the roothub FDO. When HID
device is connected to a roothub the returned count is 1; if connected to a
single external hub, the returned count is 2; it increments for each level
of hub nesting.

When I saw your posting, I thought this might be a change with Vista. But I
verified the filter driver works on this platform too.

What is the NTSTATUS code you get when it “is refused by usbhub.sys” ?

Stan Mitchell
SourceQuest, Inc.


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

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

>> the call returns STATUS_INVALID_PARAMETER
Sounds like it is complaining about Argument1?

> BTW, how can you use synchronous call in the completion routine? Can’t it
be called at raised IRQL?

If the completion routine is called at passive level, just make the
synchronous call, otherwise make it from a work item.

Stan Mitchell
SourceQuest, Inc.

> ----------

From: xxxxx@lists.osr.com[SMTP:xxxxx@lists.osr.com] on behalf of Stan Mitchell[SMTP:xxxxx@yahoo.com]
Reply To: Windows System Software Devs Interest List
Sent: Monday, February 26, 2007 8:36 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] How to find is an USB device is connected via hub

>> the call returns STATUS_INVALID_PARAMETER
Sounds like it is complaining about Argument1?

No. I stepped through the usbhub code. The relevant part looks like this:

if ((DeviceOrPortExtension->Something & 1) == 0) {
return(STATUS_INVALID_PARAMETER);
}
SendIrpDown();

I don’t remember it exactly but in principle it was as above. When I changed the test result of above condition in the debugger it worked and only count was greater by one.

Best regards,

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

I traced into this call with windbg and I’m seeing something similar (but
different) in usbhub.sys (6.0.6000.16386) on Vista. When the device is
connected to a roothub, it executes the first section of the “if” clause;
when behind an external hub, it takes the “else” path.

PULONG pArg1 = irpStack->Parameters.Others.Argument1;
if (devext->SomeFlags & 0x1)
{
// roothub
if (pArg1 == NULL)
{
… complete Irp with STATUS_INVALID_PARAMETER
}
else
{
(*pArg1)++;
… complete Irp with success
}
}
else
{
// external hub
if (pArg1!= NULL) (*pArg1)++;
… pass irp down stack
}

Stan Mitchell
SourceQuest, Inc.

I examined only XP SP2, maybe things changed at Vista. I’ll look at it again, thanks.

Best regards,

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


From: xxxxx@lists.osr.com[SMTP:xxxxx@lists.osr.com] on behalf of Stan Mitchell[SMTP:xxxxx@yahoo.com]
Reply To: Windows System Software Devs Interest List
Sent: Monday, February 26, 2007 9:55 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] How to find is an USB device is connected via hub

I traced into this call with windbg and I’m seeing something similar (but
different) in usbhub.sys (6.0.6000.16386) on Vista. When the device is
connected to a roothub, it executes the first section of the “if” clause;
when behind an external hub, it takes the “else” path.

PULONG pArg1 = irpStack->Parameters.Others.Argument1;
if (devext->SomeFlags & 0x1)
{
// roothub
if (pArg1 == NULL)
{
… complete Irp with STATUS_INVALID_PARAMETER
}
else
{
(*pArg1)++;
… complete Irp with success
}
}
else
{
// external hub
if (pArg1!= NULL) (*pArg1)++;
… pass irp down stack
}

Stan Mitchell
SourceQuest, Inc.


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

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

Stan,

I finally tried it at Vista and now it works as expected. Which is great because I need it at Vista only. Thanks for the tip, I presumed it works the same way at XP SP2 and was too lazy to boot Vista which is not only ugly but also half of my tools don’t work there.

Now I’m surprised apart from all the bugs something useful was added to Vista USB :wink: Ironically, I wouldn’t ever need it if I don’t have to solve these bugs…

Best regards,

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


From: xxxxx@lists.osr.com[SMTP:xxxxx@lists.osr.com] on behalf of Stan Mitchell[SMTP:xxxxx@yahoo.com]
Reply To: Windows System Software Devs Interest List
Sent: Monday, February 26, 2007 9:55 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] How to find is an USB device is connected via hub

I traced into this call with windbg and I’m seeing something similar (but
different) in usbhub.sys (6.0.6000.16386) on Vista. When the device is
connected to a roothub, it executes the first section of the “if” clause;
when behind an external hub, it takes the “else” path.

PULONG pArg1 = irpStack->Parameters.Others.Argument1;
if (devext->SomeFlags & 0x1)
{
// roothub
if (pArg1 == NULL)
{
… complete Irp with STATUS_INVALID_PARAMETER
}
else
{
(*pArg1)++;
… complete Irp with success
}
}
else
{
// external hub
if (pArg1!= NULL) (*pArg1)++;
… pass irp down stack
}

Stan Mitchell
SourceQuest, Inc.


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

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

Hi Michal,
Glad you got it working. I had assumed you were testing on Vista not XP.
I’m the same way, my development is still done on XP and Vista only runs on
a test machine.
Regards,
Stan Mitchell
SourceQuest, Inc.