Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTDEV

Before Posting...

Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


WinUSB: WinUsb_UnregisterIsochBuffer(): "Element not found" [0x490]

HagenHagen Member Posts: 61

Hi,

we are using WinUSB successfully for bulk and interrupt transfers for years now.
One of our older USB2 devices has additional isoc streams (OUT: 0x1; IN: 0x82)

Now, while for the OUT pipe we can successfully generate an isoc buffer via WinUsb_RegisterIsochBuffer(), same seems not work for our IN pipe. While WinUsb_RegisterIsochBuffer() returns without an error successive WinUsb_ReadIsochPipe(): requests do fail with "The parameter is incorrect" [0x57].

I have thoroughly validaded the parameters given to WinUsb_ReadIsochPipe().

What struck me is, that WinUsb_UnregisterIsochBuffer() fails with "Element not found" [0x490] on the buffer created for the IN pipe.
Since WinUsb_RegisterIsochBuffer awkwardly assigns the buffer with only the lower 4bit of the endpoint address could it be that WinUsb_RegisterIsochBuffer requires an OUT pipe with the same address? (here: 0x02)?

As I am running out of ideas what else to try any suggestion or hints are highly appreciated.

Comments

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 14,349

    There are lots of ways to mess up isochronous IN. Is your buffer an even multiple of your packet size times your repeat rate? What I mean is, if your max packet size is 1024 and your interval is 4 times per frame, then your buffer must be a multiple of 4096 bytes.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • HagenHagen Member Posts: 61

    Thanks Tim,
    in this case there is a single package transaction per interval. The buffer itself is a multiple of the transaction size (which is smaller than the max package size). I understand that the transaction size awkwardly needs to be a multiple of the package size if it spawns over multiple packages. But are you saying the buffer itself needs to be a multiple of the package size?
    The isoc buffer in our case is a virtually continues buffer, which the software accesses with different offsets, but already seems to (silently) fail before it gets to do any transaction:
    After a testwise WinUsb_RegisterIsochBuffer() directly followed by a WinUsb_RegisterIsochBuffer() the latter fails with "Element not found" [0x490] on the IN pipe. Same works on the OUT.
    Thanks,
    Hagen

  • HagenHagen Member Posts: 61

    typo (must read):
    After a testwise WinUsb_RegisterIsochBuffer() directly followed by a WinUsb_UnregisterIsochBuffer() the latter fails with "Element not found" [0x490] on the IN pipe. Same works on the OUT.
    sorry.

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 14,349

    The buffer needs to be a multiple of the maximum amount you could possibly get in a single frame. If you have 1024 bytes per transaction and 3 transactions per microframe with an interval of 1 (so 8 tries per frame), then your buffer needs to be a multiple of 24,576 bytes.

    IN transactions are a different kind of beast. Data isn't received linearly. Instead, your buffer is divided up into packet-sized chunks, one packet per interval. If you have room for 3072 bytes in a packet, and your device only sends 1000, you'll get 1000 bytes, and the next 2072 will be skipped. The next packet begins on the next boundary. If your device should happen to send nothing during one interval, that part of the buffer will be skipped. I don't remember whether WinUSB reconstructs things into a linear buffer or not. But because of that, the buffer has to be large enough to handle everything.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • HagenHagen Member Posts: 61

    Thanks Tim,
    all of those prerequisites have been fulfilled (even requesting the isoc transactions with exactly the packet size). No matter wether requesting WinUsb_RegisterIsochBuffer with 10 times the max packet size or 100 times.
    But I still think the problem is where the buffers are created, since WinUsb_UnregisterIsochBuffer() already fails even without requesting any isoc transaction at all. WinUsb_UnregisterIsochBuffer does not fail, if I WinUsb_RegisterIsochBuffer() with pipeID 0x82 (instead as 0x2: "Derived from Bit 3...0 of the bEndpointAddress field in the endpoint descriptor.").
    Thanks,
    Hagen

  • Xiaofan_ChenXiaofan_Chen Member - All Emails Posts: 240

    Not so sure if this can help you or not. We have used libusbk library with Cypress FX3 USB devices succefully with isoc transfer, using either WinUSB driver or libusbk driver. You may want to give it a try.

    Example FW and results.
    https://github.com/mcuee/libusbk/tree/master/BmFW/CYPRESS_FX3

    libusbk WinUSB backend code
    https://github.com/mcuee/libusbk/blob/0585dab3d4aebc725aa381cf67670cd62070950b/libusbK/src/lusbk_bknd_winusb.c

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. Sign in or register to get started.

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Writing WDF Drivers 12 September 2022 Live, Online
Internals & Software Drivers 23 October 2022 Live, Online
Kernel Debugging 14 November 2022 Live, Online
Developing Minifilters 5 December 2022 Live, Online