While doing some speed testing I find that FreeBSD does ~4Mb/sec, but
Linux does 17Mb/sec OS X does 8-10Mb/sec.
Check out the bulk read-ahead support in NetBSD's ugen. This was
written at BBN in 2006 to enable higher data rates with the USRP (for
GNU Radio).
From your description it's not clear that this would help, but given
what you're doing you should probably be aware of it.
UGEN(4) NetBSD Kernel Interfaces ManualUGEN(4)
NAME
ugen -- USB generic device support
SYNOPSIS
ugen* at uhub? flags N
options UGEN_BULK_RA_WB
DESCRIPTION
The ugen driver provides support for all USB devices that do not have a
special driver. It supports access to all parts of the device, but not
in a way that is as convenient as a special purpose driver.
Normally the ugen driver is used when no other driver attaches to a
device. If ``flags 1'' is specified, the ugen will instead attach with a
very high priority and always be used. Together with the vendor and
product locators this can be used to force the ugen driver to be used for
a certain device.
There can be up to 127 USB devices connected to a USB bus. Each USB
device can have up to 16 endpoints. Each of these endpoints will commu-
nicate in one of four different modes: control, isochronous, bulk, or
interrupt. Each of the endpoints will have a different device node. The
four least significant bits in the minor device number determines which
endpoint the device accesses and the rest of the bits determines which
USB device.
If an endpoint address is used both for input and output the device can
be opened for both read or write.
To find out what endpoints exist there are a series of ioctl(2) opera-
tions on the control endpoint that return the USB descriptors of the
device, configurations, interfaces, and endpoints.
The control transfer mode can only happen on the control endpoint which
is always endpoint 0. The control endpoint accepts requests and may
respond with an answer to such requests. Control requests are issued by
ioctl(2) calls.
The bulk transfer mode can be in or out depending on the endpoint. To
perform IO on a bulk endpoint read(2) and write(2) should be used. All
IO operations on a bulk endpoint are normally unbuffered. On kernels
built with the UGEN_BULK_RA_WB option, the USB_SET_BULK_RA and
USB_SET_BULK_WB ioctl(2) calls are available, and enable read-ahead and
write-behind buffering respectively. When read-ahead or write-behind are
enabled, the file descriptor may be set to use non-blocking IO.
When in a UGEN_BULK_RA_WB mode, select(2) for read and write operates
normally, returning true if there is data in the read buffer and space in
the write buffer, respectively. When not in a UGEN_BULK_RA_WB mode,
select(2) always returns true, because there is no way to predict how the
device will respond to a read or write request.
The interrupt transfer mode can be in or out depending on the endpoint.
To perform IO on an interrupt endpoint read(2) and write(2) should be
used. A moderate amount of buffering is done by the driver.
All endpoints handle the following ioctl(2) calls:
USB_SET_SHORT_XFER (int)
Allow short read transfer. Normally a transfer from the device
which is shorter than the request specified is reported as an
error.
USB_SET_TIMEOUT (int)
Set the timeout on the device operations, the time is specified
in milliseconds. The value 0 is used to indicate that there is
no timeout.
The control endpoint (endpoint 0) handles the following ioctl(2) calls:
USB_GET_CONFIG (int)
Get the device configuration number.
USB_SET_CONFIG (int)
Set the device into the given configuration number.
This operation can only be performed when the control endpoint is
the sole open endpoint.
USB_GET_ALTINTERFACE (struct usb_alt_interface)
Get the alternative setting number for the interface with the
given index. The config_index is ignored in this call.
struct usb_alt_interface {
int uai_config_index;
int uai_interface_index;
int uai_alt_no;
};
USB_SET_ALTINTERFACE (struct usb_alt_interface)
Set the alternative setting to the given number in the interface
with the given index. The uai_config_index is ignored in this
call.
This operation can only be performed when no endpoints for the
interface are open.
USB_GET_NO_ALT (struct usb_alt_interface)
Return the number of different alternate settings in the
aui_alt_no