How to get DUN to consume data in larger chunks/more frequently?

I’ve noticed dialup networking (at least in XP) will issue reads to my modem driver (during a PPP session) of a few different sizes: 2863, 2613, 2363, 2464, 3113 bytes, etc.

These reads come when I complete a pending IOCTL_SERIAL_WAIT_ON_MASK request. The mask is 0x4B2 so DUN is waiting for (among other things) the 0x7E character and the “SERIAL_EV_RX80FULL” event.

I am issuing reads of 4096 bytes to my USB device (using KMDF continuous reader). When a lot of data is coming to my device, these reads can be fulfilled completely (all 4096 bytes returned).

This leads to a problem because the largest read from DUN (at least that I’ve ever seen) is only 3113 bytes, and so (under heavy traffic) a backlog starts to appear in my driver’s buffer.

I’ve tried the following:

  1. I noticed that usbser.sys will fake SERIAL_EV_RX80FULL even when only one byte is present. I don’t know why this is (usbser.sys’s buffer appears to really be 16384 bytes).

However this does have the upside of completing the IOCTL wait from DUN after every USB transfer, causing another read to be issued.

I mimicked this behavior and it helps a lot, but even if I complete that IOCTL after every transfer, eventually it’s not enough (because 3113 < 4096).

  1. I tried completing IOCTL_SERIAL_WAIT_ON_MASK synchronously when the buffer is over 2K or so, but this just freezes the machine (some sort of loop between modem.sys and my driver at DISPATCH_LEVEL).

So my overall questions are:

  1. Is there some way to convince DUN to read more than 3113 bytes, or

  2. Is there some way to convince DUN to read more than once every transfer without locking up the machine?

(My last resort, of course, is to reduce my continuous reader’s read size to something smaller than the smallest read issued by DUN. But I don’t see why this should be necessary as DUN doesn’t know about USB, etc.

Plus, I don’t think this is foolproof anyway since two+ transfers could complete in the time it takes DUN to issue another read/IOCTL, and so on.)

-Chris

I wrote:

  1. Is there some way to convince DUN to read more than once
    every transfer without locking up the machine?

This is what I am going to try. Assuming I have more than 1-2K in my buffer, I will:

  1. Complete any IOCTL_SERIAL_WAIT_ON_MASK request for SERIAL_EV_RX80FULL once synchronously, and then flag a boolean in my device extension as TRUE. If the IOCTL comes around again with the boolean still TRUE, I will pend it, this should eliminate the lockup.

  2. In my read handler, if not enough bytes are consumed and the aforementioned IOCTL is still pending, I will complete it there and flag the boolean to FALSE.

  3. In my USB read completion routine, also complete the pended IOCTL and flag the boolean to FALSE.

Is there any obvious problem with this approach?