Hello, sorry about the last message. I figured it out on my own. I
was always sort of surprised that usb_bulk_msg would work fine with
interrupt endpoints, so it was just a matter of time until it would
not. Anyways, I solved the problem with a callback and a condition
variable.
Everything seems to be working fine, but I am concerned about possible
residual bugs or memory leaks. If anyone can give these two
procedures a quick look I would appreciate it. The code isn't the
best -- it is just a rapid prototype. Thanks.
/* HQCT device structure */
struct usb_hqct {
struct usb_device * udev;
struct usb_interface * interface;
struct semaphore limit_sem;
struct completion read_comp;
unsigned char * intr_in_buffer;
size_t intr_in_size;
__u8 intr_in_endpointAddr;
__u8 intr_out_endpointAddr;
struct kref kref;
int endp_interval;
};
static void hqct_read_callback(struct urb *urb, struct pt_regs *regs)
{
struct usb_hqct *dev;
int i;
dev = (struct usb_hqct *)urb->context;
printk("READ CALLBACK status=%d \n", urb->status);
for(i=0; i < 32; i++) {
printk("%.2X ", dev->intr_in_buffer[i]);
}
printk("\n");
complete(&(dev->read_comp));
printk("READ CALLBACK completed.\n");
}
/* Read: will poll for the next status packet and return it in the raw */
static ssize_t hqct_read(struct file *file, char *buffer, size_t
count, loff_t *ppos)
{
struct usb_hqct *dev;
struct urb *urb = NULL;
int retval = 0;
int bytes_read = 0;
dev = (struct usb_hqct *)file->private_data;
/* create a urb, and a buffer for it, and copy the data to the urb */
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb) {
retval = -ENOMEM;
goto error;
}
/* fill the interrupt urb in */
usb_fill_int_urb(urb, dev->udev,
usb_rcvintpipe(dev->udev, dev->intr_in_endpointAddr),
dev->intr_in_buffer,
min(dev->intr_in_size,count), hqct_read_callback, dev,
dev->endp_interval);
retval = usb_submit_urb(urb, GFP_KERNEL);
if (retval) {
err("%s - failed submitting write urb, error %d",
__FUNCTION__, retval);
goto error;
}
/* block until we receive the buffer */
printk("HQCT Blocking...\n");
wait_for_completion(&(dev->read_comp) );
bytes_read = urb->actual_length;
printk("HQCT READ %d %d\n", count, bytes_read);
/* if successful read, copy the data to userspace */
if (urb->status == 0) {
if (copy_to_user(buffer, dev->intr_in_buffer, count))
retval = -EFAULT;
else
retval = bytes_read;
}
usb_free_urb(urb);
return retval;
error:
printk("HQCT Doh! an error occured: %d\n", retval);
usb_free_urb(urb);
return retval;
}
Again, thanks for the help, kernel-level programming is relatively new to me.
-------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid0709&bid&3057&dat1642
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel