Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 56847
b: refs/heads/master
c: 9d33efd
h: refs/heads/master
i:
  56845: 122b5c8
  56843: fc99bd4
  56839: 0cc1df4
  56831: d641ca0
v: v3
  • Loading branch information
Oliver Neukum authored and Greg Kroah-Hartman committed May 23, 2007
1 parent 5e5a467 commit e933072
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2adb80e9c52f35a4d63783b98d48386c38c90484
refs/heads/master: 9d33efd9a791041bbe3a9e879925ef8fbb94d812
35 changes: 31 additions & 4 deletions trunk/drivers/usb/misc/ldusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,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;
Expand Down Expand Up @@ -230,10 +232,12 @@ static void ld_usb_interrupt_in_callback(struct urb *urb)
} 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) {
Expand All @@ -244,21 +248,25 @@ static void ld_usb_interrupt_in_callback(struct urb *urb)
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);
Expand Down Expand Up @@ -330,6 +338,7 @@ static int ld_usb_open(struct inode *inode, struct file *file)
/* 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),
Expand Down Expand Up @@ -439,6 +448,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
size_t *actual_buffer;
size_t bytes_to_read;
int retval = 0;
int rv;

dev = file->private_data;

Expand All @@ -460,14 +470,19 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
}

/* 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;
}
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 */
Expand All @@ -486,6 +501,17 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,

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);
Expand Down Expand Up @@ -635,6 +661,7 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id *
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);
Expand Down

0 comments on commit e933072

Please sign in to comment.