view release on metacpan or search on metacpan
linux-labjack/INSTALL view on Meta::CPAN
Finally, run the test application:
# ./firmware-revision or
# ./analog-outs or
# ./list-all
HID NOTE: If the hid module is loaded (use lsmod to view the modules and
look for "hid"), the provided labjack driver will not work correctly.
Since the Labjack is classified as a HID device, the hid driver will
claim the device. However, the hid driver does not support the "Interrupt"
out endpoint used by the Labjack and thus cannot communicate with the
Labjack. You must remove the hid driver prior to loading the labjack
driver. The following command, as root, should suffice:
# modprobe -r hid
If you absolutely must have the hid device driver loaded, it is possible
to add the Labjack to the HID blacklist. Add the Labjack USB vendor
(0x0cd5) and product (0x0001) IDs to the hid_blacklist structure in hid-core.c
in the drivers/usb directory. An example of the line to insert into the
hid_blacklist structure would be:
linux-labjack/INSTALL view on Meta::CPAN
% make
Finally, run the test application as root:
# ./firmware-revision
HID NOTE: If the hid module is loaded (use lsmod to view the modules and
look for "hid"), the provided labjack driver will not work correctly.
Since the Labjack is classified as a HID device, the hid driver will claim
the device. However, the hid driver does not support the "Interrupt" out
endpoint used by the Labjack and thus cannot communicate with the Labjack.
You must remove the hid driver prior to loading the labjack driver. The
following command, as root, should suffice:
# modprobe -r hid
If you absolutely must have the hid device driver loaded, it is possible to
add the Labjack to the HID blacklist. Add the Labjack USB vendor (0x0cd5)
and product (0x0001) IDs to the hid_blacklist structure in hid-core.c in
the drivers/usb/input directory. An example of the line to insert in the
hid_blacklist structure would be:
linux-labjack/README view on Meta::CPAN
o) Linux Labjack device drivers for the Linux Kernel v2.4 and v2.6.
o) A port of the Windows API (based upon Eric Sorton modified ljackv112.c
and ljackuw.c v1.18).
o) Test application to read the firmware revision, set analog-outs, and
list all the LabJacks connected to your system.
Installation instructions are provided in the INSTALL file.
The Labjack driver is heavily (about 95% code reuse) based upon the device driver
for the LegoUSB tower provided in leJOS. The LegoUSB tower, the Labjack U12, and
several other devices all use Interrupt endpoints (both In and Out) to communicate
over the USB bus. The device driver simply maps the two endpoints to the read()
and write() system calls. At this time, there is no generic capability within the
Linux USB subsystem to support generic read/writes using Interrupt endpoints.
Possibly, in the future, such a capability will be provided by the Linux
kernel and the device drivers will no longer be necessary.
The Windows API code (v1.12 and v1.18) has been modified to work under Linux.
There are some notes within the code.
There are a few restrictions:
o)At this time, there is support for up to 16 LabJacks. They are accessed
the same way as under the Windows API (by their local id).
o)The state of the discretes are not persistent across applications(in the
linux-labjack/driver/linux-2.4/labjack.c view on Meta::CPAN
int open_count; /* number of times this port has been opened */
char* read_buffer;
int read_buffer_length;
wait_queue_head_t read_wait;
wait_queue_head_t write_wait;
char* interrupt_in_buffer;
struct usb_endpoint_descriptor* interrupt_in_endpoint;
struct urb* interrupt_in_urb;
char* interrupt_out_buffer;
struct usb_endpoint_descriptor* interrupt_out_endpoint;
struct urb* interrupt_out_urb;
int read_timeout;
int write_timeout;
};
/* Note that no locking is needed:
* read_buffer is arbitrated by read_buffer_length == 0
* interrupt_out_buffer is arbitrated by interrupt_out_urb->status == -EINPROGRESS
* interrupt_in_buffer belongs to urb alone and is overwritten on overflow
linux-labjack/driver/linux-2.4/labjack.c view on Meta::CPAN
if (dev->open_count > 1) {
retval = -EBUSY;
goto error;
}
file->private_data = dev;
dev->read_buffer_length = 0;
FILL_INT_URB(
dev->interrupt_in_urb,
dev->udev,
usb_rcvintpipe(dev->udev, dev->interrupt_in_endpoint->bEndpointAddress),
dev->interrupt_in_buffer,
dev->interrupt_in_endpoint->wMaxPacketSize,
labjack_interrupt_in_callback,
dev,
dev->interrupt_in_endpoint->bInterval);
retval = usb_submit_urb (dev->interrupt_in_urb);
if (retval != 0) {
err("Couldn't submit interrupt_in_urb");
goto error;
}
goto unlock_exit;
error:
labjack_release_internal (dev);
linux-labjack/driver/linux-2.4/labjack.c view on Meta::CPAN
retval = -ETIMEDOUT;
goto exit;
}
dbg(4," %s : in progress, count = %d", __func__, count);
} else {
dbg(4," %s : sending, count = %d", __func__, count);
/* write the data into interrupt_out_buffer from userspace */
buffer_size = dev->interrupt_out_endpoint->wMaxPacketSize;
bytes_to_write = count > buffer_size ? buffer_size : count;
dbg(4," %s : buffer_size = %d, count = %d, bytes_to_write = %d", __func__, buffer_size, count, bytes_to_write);
if (copy_from_user (dev->interrupt_out_buffer, buffer, bytes_to_write) != 0) {
retval = -EFAULT;
goto exit;
}
/* send off the urb */
FILL_INT_URB(
dev->interrupt_out_urb,
dev->udev,
usb_sndintpipe(dev->udev, dev->interrupt_out_endpoint->bEndpointAddress),
dev->interrupt_out_buffer,
bytes_to_write,
labjack_interrupt_out_callback,
dev,
0);
dev->interrupt_out_urb->actual_length = bytes_to_write;
retval = usb_submit_urb (dev->interrupt_out_urb);
if (retval != 0) {
linux-labjack/driver/linux-2.4/labjack.c view on Meta::CPAN
if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET)) {
dbg(1," %s : nonzero status received: %d", __func__, urb->status);
}
goto exit;
}
down (&dev->sem);
if (urb->actual_length > 0) {
if (dev->read_buffer_length <
(4 * dev->interrupt_in_endpoint->wMaxPacketSize) - (urb->actual_length)) {
memcpy (dev->read_buffer+dev->read_buffer_length, dev->interrupt_in_buffer, urb->actual_length);
dev->read_buffer_length += urb->actual_length;
wake_up_interruptible (&dev->read_wait);
} else {
dbg(1," %s : read_buffer overflow", __func__);
}
}
up (&dev->sem);
linux-labjack/driver/linux-2.4/labjack.c view on Meta::CPAN
dbg(4," %s : leave, status %d", __func__, urb->status);
}
static void * labjack_probe (struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
{
struct labjack_usb *dev = NULL;
int minor;
struct usb_interface* interface;
struct usb_interface_descriptor *iface_desc;
struct usb_endpoint_descriptor* endpoint;
int i;
char name[32];
void *retval = NULL;
dbg(2," %s : enter", __func__);
if (udev == NULL) {
info ("udev is NULL.");
}
linux-labjack/driver/linux-2.4/labjack.c view on Meta::CPAN
dev->minor = minor;
dev->open_count = 0;
dev->read_buffer = NULL;
dev->read_buffer_length = 0;
init_waitqueue_head (&dev->read_wait);
init_waitqueue_head (&dev->write_wait);
dev->interrupt_in_buffer = NULL;
dev->interrupt_in_endpoint = NULL;
dev->interrupt_in_urb = NULL;
dev->interrupt_out_buffer = NULL;
dev->interrupt_out_endpoint = NULL;
dev->interrupt_out_urb = NULL;
/*
* It seems slightly dubious to set up endpoints here, as we may
* change the configuration before calling open. But the endpoints
* should be the same in all configurations.
*/
interface = &dev->udev->actconfig->interface[0];
iface_desc = &interface->altsetting[0];
for (i = 0; i < iface_desc->bNumEndpoints; ++i) {
endpoint = &iface_desc->endpoint[i];
if (((endpoint->bEndpointAddress & USB_DIR_MASK) == USB_DIR_IN) &&
((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
/* we found an interrupt in endpoint */
dev->interrupt_in_endpoint = endpoint;
}
if (((endpoint->bEndpointAddress & USB_DIR_MASK) == USB_DIR_OUT) &&
((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
/* we found an interrupt out endpoint */
dev->interrupt_out_endpoint = endpoint;
}
}
if(dev->interrupt_in_endpoint == NULL) {
err("interrupt in endpoint not found");
retval = NULL;
goto unlock_exit;
}
if (dev->interrupt_out_endpoint == NULL) {
err("interrupt out endpoint not found");
retval = NULL;
goto unlock_exit;
}
dev->read_buffer = kmalloc ((4*dev->interrupt_in_endpoint->wMaxPacketSize), GFP_KERNEL);
if (!dev->read_buffer) {
err("Couldn't allocate read_buffer");
retval = NULL;
goto unlock_exit;
}
dev->interrupt_in_buffer = kmalloc (dev->interrupt_in_endpoint->wMaxPacketSize, GFP_KERNEL);
if (!dev->interrupt_in_buffer) {
err("Couldn't allocate interrupt_in_buffer");
retval = NULL;
goto unlock_exit;
}
dev->interrupt_in_urb = usb_alloc_urb(0);
if (!dev->interrupt_in_urb) {
err("Couldn't allocate interrupt_in_urb");
retval = NULL;
goto unlock_exit;
}
dev->interrupt_out_buffer = kmalloc (dev->interrupt_out_endpoint->wMaxPacketSize, GFP_KERNEL);
if (!dev->interrupt_out_buffer) {
err("Couldn't allocate interrupt_out_buffer");
retval = NULL;
goto unlock_exit;
}
dev->interrupt_out_urb = usb_alloc_urb(0);
if (!dev->interrupt_out_urb) {
err("Couldn't allocate interrupt_out_urb");
retval = NULL;
goto unlock_exit;
linux-labjack/driver/linux-2.6/labjack.c view on Meta::CPAN
size_t read_buffer_length; /* this much came in */
size_t read_packet_length; /* this much will be returned on read */
spinlock_t read_buffer_lock;
int packet_timeout_jiffies;
unsigned long read_last_arrival;
wait_queue_head_t read_wait;
wait_queue_head_t write_wait;
char* interrupt_in_buffer;
struct usb_endpoint_descriptor* interrupt_in_endpoint;
struct urb* interrupt_in_urb;
int interrupt_in_interval;
int interrupt_in_running;
int interrupt_in_done;
char* interrupt_out_buffer;
struct usb_endpoint_descriptor* interrupt_out_endpoint;
struct urb* interrupt_out_urb;
int interrupt_out_interval;
int interrupt_out_busy;
};
static ssize_t labjack_read(struct file *file, char *buffer, size_t count, loff_t *ppos);
static ssize_t labjack_read_feature(struct file *file, char *buffer, size_t count, loff_t *ppos);
static ssize_t labjack_write(struct file *file, const char *buffer, size_t count, loff_t *ppos);
static int labjack_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
linux-labjack/driver/linux-2.6/labjack.c view on Meta::CPAN
goto unlock_exit;
}
dev->open_count = 1;
dev->read_buffer_length = 0;
dev->read_packet_length = 0;
usb_fill_int_urb (dev->interrupt_in_urb,
dev->udev,
usb_rcvintpipe(dev->udev, dev->interrupt_in_endpoint->bEndpointAddress),
dev->interrupt_in_buffer,
dev->interrupt_in_endpoint->wMaxPacketSize,
labjack_interrupt_in_callback,
dev,
dev->interrupt_in_interval);
dev->interrupt_in_running = 1;
dev->interrupt_in_done = 0;
mb();
retval = usb_submit_urb (dev->interrupt_in_urb, GFP_KERNEL);
if (retval) {
linux-labjack/driver/linux-2.6/labjack.c view on Meta::CPAN
bytes_to_write = min(count, write_buffer_size);
dbg(4, "%s: count = %Zd, bytes_to_write = %Zd", __FUNCTION__, count, bytes_to_write);
if (copy_from_user (dev->interrupt_out_buffer, buffer, bytes_to_write)) {
retval = -EFAULT;
goto unlock_exit;
}
usb_fill_int_urb(dev->interrupt_out_urb, dev->udev,
usb_sndintpipe(dev->udev, dev->interrupt_out_endpoint->bEndpointAddress),
dev->interrupt_out_buffer,
bytes_to_write,
labjack_interrupt_out_callback,
dev,
dev->interrupt_out_interval);
dev->interrupt_out_busy = 1;
wmb();
retval = usb_submit_urb (dev->interrupt_out_urb, GFP_KERNEL);
linux-labjack/driver/linux-2.6/labjack.c view on Meta::CPAN
usb_labjack_debug_data(5,__FUNCTION__, urb->actual_length, urb->transfer_buffer);
dbg(4," %s : leave, status %d", __FUNCTION__, urb->status);
}
static int labjack_probe (struct usb_interface *interface, const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(interface);
struct labjack_usb *dev = NULL;
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor* endpoint;
int i;
int retval = -ENOMEM;
dbg(2," %s : enter", __FUNCTION__);
if (udev == NULL) {
info ("udev is NULL.");
}
if ((udev->descriptor.idVendor != LABJACK_USB_VENDOR_ID) ||
linux-labjack/driver/linux-2.6/labjack.c view on Meta::CPAN
dev->read_buffer_length = 0;
dev->read_packet_length = 0;
spin_lock_init (&dev->read_buffer_lock);
dev->packet_timeout_jiffies = packet_timeout * HZ / 1000;
dev->read_last_arrival = jiffies;
init_waitqueue_head (&dev->read_wait);
init_waitqueue_head (&dev->write_wait);
dev->interrupt_in_buffer = NULL;
dev->interrupt_in_endpoint = NULL;
dev->interrupt_in_urb = NULL;
dev->interrupt_in_running = 0;
dev->interrupt_in_done = 0;
dev->interrupt_out_buffer = NULL;
dev->interrupt_out_endpoint = NULL;
dev->interrupt_out_urb = NULL;
dev->interrupt_out_busy = 0;
iface_desc = &interface->altsetting[0];
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
endpoint = &iface_desc->endpoint[i].desc;
if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) &&
((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
dev->interrupt_in_endpoint = endpoint;
}
if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) &&
((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
dev->interrupt_out_endpoint = endpoint;
}
}
if(dev->interrupt_in_endpoint == NULL) {
err("interrupt in endpoint not found");
goto error;
}
if (dev->interrupt_out_endpoint == NULL) {
err("interrupt out endpoint not found");
goto error;
}
dev->read_buffer = kmalloc (read_buffer_size, GFP_KERNEL);
if (!dev->read_buffer) {
err("Couldn't allocate read_buffer");
goto error;
}
dev->interrupt_in_buffer = kmalloc (dev->interrupt_in_endpoint->wMaxPacketSize, GFP_KERNEL);
if (!dev->interrupt_in_buffer) {
err("Couldn't allocate interrupt_in_buffer");
goto error;
}
dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->interrupt_in_urb) {
err("Couldn't allocate interrupt_in_urb");
goto error;
}
dev->interrupt_out_buffer = kmalloc (write_buffer_size, GFP_KERNEL);
if (!dev->interrupt_out_buffer) {
err("Couldn't allocate interrupt_out_buffer");
goto error;
}
dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->interrupt_out_urb) {
err("Couldn't allocate interrupt_out_urb");
goto error;
}
dev->interrupt_in_interval = interrupt_in_interval ? interrupt_in_interval : dev->interrupt_in_endpoint->bInterval;
dev->interrupt_out_interval = interrupt_out_interval ? interrupt_out_interval : dev->interrupt_out_endpoint->bInterval;
usb_set_intfdata (interface, dev);
retval = usb_register_dev (interface, &labjack_class);
if (retval) {
err ("Not able to get a minor for this device.");
usb_set_intfdata (interface, NULL);
goto error;
}
linux-labjack/liblabjack/ljackul.c view on Meta::CPAN
// ReadLabJack
// CloseAll
//
// The LabJack U12 is an HID V1.1 device. Input and Output reports
// are both 8 bytes (although Windows throws on an extra byte
// at the beginning). Feature reports are used to transfer stream
// and burst data from the LabJack to the PC, and are 16*8 or 128
// bytes (plus the extra Windows byte at the beginning).
//
// The first time after enumeration that the LabJack is supposed to
// write 8 bytes to the interrupt IN endpoint, the write does not
// happen. Windows reads nothing. This initial non-response provides
// a good test of the thread timeout we use in our Windows HID
// read function. You will probably see this behavior on other
// operating systems.
//
//----------------------------------------------------------------------
//
// Changes
//
// (08/18/2005) Fixed problem in OpenLabJack when *idnum is 0. Updated