From: Sam Bishop <[EMAIL PROTECTED]>
This patch adds a limit on the number of URBs in flight, per device, and
the size of temporary write buffers.
---
This is similar to the approach I used to add double buffering to the
2.4 version of usb-skeleton.c.
--- linux-2.6.14.4/drivers/usb/usb-skeleton.c.orig 2005-12-14
16:50:41.000000000 -0700
+++ linux-2.6.14.4/drivers/usb/usb-skeleton.c 2005-12-16
20:27:37.656219376 -0700
@@ -1,5 +1,5 @@
/*
- * USB Skeleton driver - 2.0
+ * USB Skeleton driver - 2.1
*
* Copyright (C) 2001-2004 Greg Kroah-Hartman ([EMAIL PROTECTED])
*
@@ -8,8 +8,7 @@
* published by the Free Software Foundation, version 2.
*
* This driver is based on the 2.6.3 version of drivers/usb/usb-skeleton.c
- * but has been rewritten to be easy to read and use, as no locks are now
- * needed anymore.
+ * but has been rewritten to be easier to read and use.
*
*/
@@ -39,6 +38,10 @@ MODULE_DEVICE_TABLE (usb, skel_table);
/* Get a minor range for your devices from the usb maintainer */
#define USB_SKEL_MINOR_BASE 192
+/* You may want to modify these to best match your device */
+#define MAX_WRITE_URBS 4
+#define MAX_WRITE_BYTES (4 * 1024) /*
number of bytes per write urb */
+
/* Structure to hold all of our device specific stuff */
struct usb_skel {
struct usb_device * udev; /* the usb
device for this device */
@@ -48,6 +51,7 @@ struct usb_skel {
__u8 bulk_in_endpointAddr; /* the address
of the bulk in endpoint */
__u8 bulk_out_endpointAddr; /* the address
of the bulk out endpoint */
struct kref kref;
+ struct semaphore num_write_urbs;
};
#define to_skel_dev(d) container_of(d, struct usb_skel, kref)
@@ -152,6 +156,7 @@ static void skel_write_bulk_callback(str
/* free up our allocated buffer */
usb_buffer_free(urb->dev, urb->transfer_buffer_length,
urb->transfer_buffer, urb->transfer_dma);
+ up(&dev->num_write_urbs);
}
static ssize_t skel_write(struct file *file, const char *user_buffer,
size_t count, loff_t *ppos)
@@ -167,6 +172,12 @@ static ssize_t skel_write(struct file *f
if (count == 0)
goto exit;
+ /* make sure that we haven't exceeded our self-imposed urb quota */
+ if (down_interruptible(&dev->num_write_urbs)) {
+ retval = -ERESTARTSYS;
+ goto exit;
+ }
+
/* create a urb, and a buffer for it, and copy the data to the
urb */
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb) {
@@ -174,6 +185,7 @@ static ssize_t skel_write(struct file *f
goto error;
}
+ count = min(count, (size_t)MAX_WRITE_BYTES);
buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL,
&urb->transfer_dma);
if (!buf) {
retval = -ENOMEM;
@@ -207,6 +219,7 @@ exit:
error:
usb_buffer_free(dev->udev, count, buf, urb->transfer_dma);
usb_free_urb(urb);
+ up(&dev->num_write_urbs);
return retval;
}
@@ -246,6 +259,7 @@ static int skel_probe(struct usb_interfa
}
memset(dev, 0x00, sizeof(*dev));
kref_init(&dev->kref);
+ sema_init(&dev->num_write_urbs, MAX_WRITE_URBS);
dev->udev = usb_get_dev(interface_to_usbdev(interface));
dev->interface = interface;
-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems? Stop! Download the new AJAX search engine that makes
searching your log files as easy as surfing the web. DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel