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
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to