Am Donnerstag, 5. April 2007 06:41 schrieb Shawn Bohrer:
> This patch does seem to fix the problem I described, though admittedly
> I haven't exactly figured out how you are supposed to use the ldusb
> driver. It looks like I need to first write some magic numbers to
> initialize the device before a read will produce useful data. I guess
> I need to study Greg KH's Go!Temp driver to figure out what exactly I
> am supposed to write to the device.
Hi,
could you test this patch?
It should fix both the problem on subsequent reads and introduce some
flow control.
Regards
Oliver
Signed-off-by: Oliver Neukum <[EMAIL PROTECTED]>
----
--- a/drivers/usb/misc/ldusb.c 2007-04-18 09:21:23.000000000 +0200
+++ b/drivers/usb/misc/ldusb.c 2007-04-18 09:23:02.000000000 +0200
@@ -162,6 +162,8 @@ struct ld_usb {
size_t interrupt_in_endpoint_size;
int interrupt_in_running;
int interrupt_in_done;
+ int buffer_overflow;
+ spinlock_t rbsl;
char* interrupt_out_buffer;
struct usb_endpoint_descriptor* interrupt_out_endpoint;
@@ -227,10 +229,12 @@ static void ld_usb_interrupt_in_callback
} else {
dbg_info(&dev->intf->dev, "%s: nonzero status received:
%d\n",
__FUNCTION__, urb->status);
+ spin_lock(&dev->rbsl);
goto resubmit; /* maybe we can recover */
}
}
+ spin_lock(&dev->rbsl);
if (urb->actual_length > 0) {
next_ring_head = (dev->ring_head+1) % ring_buffer_size;
if (next_ring_head != dev->ring_tail) {
@@ -241,21 +245,25 @@ static void ld_usb_interrupt_in_callback
dev->ring_head = next_ring_head;
dbg_info(&dev->intf->dev, "%s: received %d bytes\n",
__FUNCTION__, urb->actual_length);
- } else
+ } else {
dev_warn(&dev->intf->dev,
"Ring buffer overflow, %d bytes dropped\n",
urb->actual_length);
+ dev->buffer_overflow = 1;
+ }
}
resubmit:
/* resubmit if we're still running */
- if (dev->interrupt_in_running && dev->intf) {
+ if (dev->interrupt_in_running && !dev->buffer_overflow && dev->intf) {
retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC);
- if (retval)
+ if (retval) {
dev_err(&dev->intf->dev,
"usb_submit_urb failed (%d)\n", retval);
+ dev->buffer_overflow = 1;
+ }
}
-
+ spin_unlock(&dev->rbsl);
exit:
dev->interrupt_in_done = 1;
wake_up_interruptible(&dev->read_wait);
@@ -327,6 +335,7 @@ static int ld_usb_open(struct inode *ino
/* initialize in direction */
dev->ring_head = 0;
dev->ring_tail = 0;
+ dev->buffer_overflow = 0;
usb_fill_int_urb(dev->interrupt_in_urb,
interface_to_usbdev(interface),
usb_rcvintpipe(interface_to_usbdev(interface),
@@ -436,6 +445,7 @@ static ssize_t ld_usb_read(struct file *
size_t *actual_buffer;
size_t bytes_to_read;
int retval = 0;
+ int rv;
dev = file->private_data;
@@ -457,7 +467,10 @@ static ssize_t ld_usb_read(struct file *
}
/* wait for data */
+ spin_lock_irq(&dev->rbsl);
if (dev->ring_head == dev->ring_tail) {
+ dev->interrupt_in_done = 0;
+ spin_unlock_irq(&dev->rbsl);
if (file->f_flags & O_NONBLOCK) {
retval = -EAGAIN;
goto unlock_exit;
@@ -465,6 +478,8 @@ static ssize_t ld_usb_read(struct file *
retval = wait_event_interruptible(dev->read_wait,
dev->interrupt_in_done);
if (retval < 0)
goto unlock_exit;
+ } else {
+ spin_unlock_irq(&dev->rbsl);
}
/* actual_buffer contains actual_length + interrupt_in_buffer */
@@ -483,6 +498,17 @@ static ssize_t ld_usb_read(struct file *
retval = bytes_to_read;
+ spin_lock_irq(&dev->rbsl);
+ if (dev->buffer_overflow) {
+ dev->buffer_overflow = 0;
+ spin_unlock_irq(&dev->rbsl);
+ rv = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
+ if (rv < 0)
+ dev->buffer_overflow = 1;
+ } else {
+ spin_unlock_irq(&dev->rbsl);
+ }
+
unlock_exit:
/* unlock the device */
up(&dev->sem);
@@ -632,6 +658,7 @@ static int ld_usb_probe(struct usb_inter
goto exit;
}
init_MUTEX(&dev->sem);
+ spin_lock_init(&dev->rbsl);
dev->intf = intf;
init_waitqueue_head(&dev->read_wait);
init_waitqueue_head(&dev->write_wait);
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel