Alan Stern wrote:
> There are two possible approaches.  The easy way is just to use a very,
> very long timeout.  Alternatively, when a timeout does occur don't
> return to the user; instead loop back and submit another usb_bulk_msg.
> 
> Alan Stern

As suggested, I've modified my driver to continually retry a 
usb_bulk_msg if a timeout occurs (ETIMEDOUT is returned). My read 
function now only returns if data has been read, or another error type 
occurs.

The only problem now is that a program reading from my device will not 
respond to a ^C (or kill). I guess it's stuck in the read loop waiting 
for data!

Any suggestions? Do I need to adjust the way the 'locking' is working

Here is the modified code:

static ssize_t usbDIO_read(struct file *file, char __user *buffer, 
size_t count, loff_t *ppos)
{
        struct usbDIO_deviceData *deviceData;
        int retval = 0;
        int bytesRead;

        deviceData = (struct usbDIO_deviceData *)file->private_data;

        mutex_lock(&deviceData->ioMutex);

        if (!deviceData->interface)
        {
                // disconnect() was called
                retval = -ENODEV;
                goto exit;
        }

        do
        {
                // Do a blocking bulk read to get data from the device
                retval = usb_bulk_msg(deviceData->device,
                        usb_rcvbulkpipe(deviceData->device,
                        deviceData->bulk_in_endpointAddr),
                        deviceData->bulk_in_buffer,
                        min(deviceData->bulk_in_size, count),
                        &bytesRead,
                        HZ);    // 1 second
        }
        while(retval == -ETIMEDOUT);

        if (retval == 0)
        {
                // If successful, copy the data to userspace
                if (copy_to_user(buffer, deviceData->bulk_in_buffer,
                                count)) retval = -EFAULT;
                else retval = bytesRead;
        }
        else
        {
                err("usbDIO: %s - Read failed, error %d", __FUNCTION__, retval);
        }

exit:
        mutex_unlock(&deviceData->ioMutex);
        return retval;
}

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Linux-usb-users@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-users

Reply via email to