Consider the following snippet of code....

                sprintf(tmp, "/dev/usb/0.%d.1", x); /* Get input handle */
                _i = open(tmp, O_RDONLY|O_NDELAY);  /* Open it */
                if (_i < 0) {
                    syslog(LOG_WARNING, "Error opening USB input channel
(%d)", errno);
                } else {
                    y = 8;  /* Set buffer size */
                    if (ioctl(_i, USB_SET_RX_BUFFER_SIZE, &y) < 0) {
                        syslog(LOG_WARNING, "Error setting USB buffer");
                    }
                    y = 0;  /* Set timeout */
                    if (ioctl(_i, USB_SET_RX_TIMEOUT, &y) < 0) {
                        syslog(LOG_WARNING, "Error setting USB timeout
to zero")
;
                    }
                    y = 1;  /* Set short xfer ok */
                    if (ioctl(_i, USB_SET_RX_SHORT_XFER, &y) < 0) {
                        syslog(LOG_WARNING, "Error setting USB short XFER");
                    }
                }
                sprintf(tmp, "/dev/usb/0.%d.2", x); /* Get output handle */
                _o = open(tmp, O_WRONLY);   /* Open it */
                if (_o < 0) {
                    syslog(LOG_WARNING, "Error opening USB output
channel (%d)", errno);
                } else {
                    y = 8;  /* Set buffer size; low-speed device */
                    if (ioctl(_o, USB_SET_TX_BUFFER_SIZE, &y) < 0) {
                        syslog(LOG_WARNING, "Error setting USB TX buffer");
                    }
                    y = 0;  /* Set timeout */
                    if (ioctl(_o, USB_SET_TX_TIMEOUT, &y) < 0) {
                        syslog(LOG_WARNING, "Error setting USB TX timeout");
                    }
                }
              

Ok, we now have two open handles (we have previously ascertained that
the correct device is at the instance in question ("x") by checking its
vendor number, and we know it has two endpoints, one for input and one
for output.  We also know it is a low-speed device and thus
theoretically is limited to 8-character buffering.

So we start reading and writing and it mostly works. select() works on
the filehandles to know if we can read or write as expected, etc.

The format from the device is in the general form of a preamble byte
that is a flag, a length byte (for most of the preambles) and then up to
six bytes of data.  I read the data into a buffer (so if I get more than
one packet, or a packet and a part of a second one I'm ok) and then
whenever a read succeeds I parse through the buffer and empty it of
anything that's complete.

This is working reasonable well...... except for one problem.

Sometimes, without warning, select() will return a ready on the input
file handle and when you read you get the *last* packet of data you read
back.  You read it, you select() again, you get the same packet of data
again and again.  This can and does go on for a *long* time (sometimes
minutes!) but it does eventually clear on its own.  I *suspect* the
device itself is not actually re-sending the data, but it might be -- I
have no good way to be sure that I'm aware of.

In other words I get something like this:

select() returns ready on _i
bytes = read(_i, buffer, 8);

Buffer contains 4 bytes (and bytes = 4):  0x50, 0x02, 0x01, 0x04

select() once again returns ready on _i immediately (no delay)
bytes = read(_i, buffer, 8);

Buffer contains the same four bytes and bytes = 4 again, as if the
read() did not empty the buffer but read it and left the buffer contents
*and count* alone.

If this is a condition of some sort in the device or driver I've not
been able to figure out what it is, or how to force it to clear -- or to
prove whether it's in the device or the ugen driver.

Any ideas?

-- 
Karl Denninger
k...@denninger.net <mailto:k...@denninger.net>
/The Market Ticker/
/[S/MIME encrypted email preferred]/

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

Reply via email to