Author Topic: WinUSB & RAW_IO & (packetSize*nPackets*nBuffers > MAX_TRANSFER_SIZE) = GUI Hang  (Read 9550 times)

dsmtoday

  • Member
  • ***
  • Posts: 7
This isn't a question, but some advice in case this happens to you.

Moving my WinUSB project to use RAW_IO caused a strange problem - during transfers, occasionally the entire Windows GUI would hang.  And by that, I mean the mouse moved around, but the GUI did not respond at all.  Nor would it update at all - even the clock in the toolbar stopped incrementing.  Then if I turned my device off, causing the driver to close, the GUI sprang back to life.  It had even cached all my mouseclicks during the hang and started minimizing windows and moving them around.  But here's the kicker - the tasks in the background were actually still running during the GUI hang.  My USB test program claimed it never got a single dropped packet up until the time the device was turned off.

This strangeness was repeated on a few computers around here, all with different kinds of hardware and video cards.

The issue came down to these lines in the WinUSB docs concerning RAW_IO that confused me.
http://msdn.microsoft.com/en-us/library/windows/hardware/ff540266(v=vs.85).aspx

  • The buffer length must be a multiple of the maximum endpoint packet size.
  • The length must be less than or equal to the value of MAX_TRANSFER_SIZE retrieved by WinUsb_GetPipePolicy.

Checking that policy on my pipes, it always returns 0x40000, which is a quarter megabyte.

So I'm using overlapped I/O and the size of all of my buffers is 8*64= 512, so I think I'm way under this limit and should be fine.  But it turns out, what I should have interpreted the documentation to mean is something like "If you are using overlapped I/O, the total size of all the buffers you submit to the driver for completion I/O must be less than MAX_TRANSFER_SIZE."  And in my case, due to a bug, I was using 550 buffers in my circular buffer pool, which makes my total buffer size handed to the driver just over a quarter megabyte.

Cutting the number of buffers back to a more reasonable number resulted in no more GUI hangs.

So I guess I was lucky that I didn't cause a bluescreen with this.  But what a strange way to fail, eh?  If you have an explanation for why this strange behavior would occur, I'd be interested in hearing it.

In summary, if you get a GUI hang like this, shut off your device and the GUI will come back.  Then take a close look at your buffering scheme.
« Last Edit: June 30, 2012, 06:50:48 am by dsmtoday »