--- usb-skeleton.c.alt Sun Jan 13 12:35:11 2002
+++ usb-skeleton.c Sun Jan 13 18:48:08 2002
@@ -112,6 +112,7 @@
struct tq_struct tqueue; /* task queue for line
discipline waking up */
int open_count; /* number of times this port
has been opened */
struct semaphore sem; /* locks this structure */
+ int writing; /* write in progress */
};
@@ -253,7 +254,7 @@
/* lock our minor table and get our local data for this minor */
down (&minor_table_mutex);
dev = minor_table[subminor];
- if (dev == NULL) {
+ if (unlikely(dev == NULL)) {
up (&minor_table_mutex);
MOD_DEC_USE_COUNT;
return -ENODEV;
@@ -266,7 +267,10 @@
up (&minor_table_mutex);
/* increment our usage count for the driver */
+ /* make sure there's only one increment. release is called once */
++dev->open_count;
+ if (dev->open_count > 1)
+ MOD_DEC_USE_COUNT;
/* save our object in the file's private structure */
file->private_data = dev;
@@ -287,7 +291,7 @@
int retval = 0;
dev = (struct usb_skel *)file->private_data;
- if (dev == NULL) {
+ if (unlikely(dev == NULL)) {
dbg (__FUNCTION__ " - object is NULL");
return -ENODEV;
}
@@ -300,7 +304,7 @@
/* lock our device */
down (&dev->sem);
- if (dev->open_count <= 0) {
+ if (unlikely(dev->open_count <= 0)) {
dbg (__FUNCTION__ " - device not opened");
retval = -ENODEV;
goto exit_not_opened;
@@ -350,7 +354,7 @@
down (&dev->sem);
/* verify that the device wasn't unplugged */
- if (dev->udev == NULL) {
+ if (unlikely(dev->udev == NULL)) {
up (&dev->sem);
return -ENODEV;
}
@@ -363,8 +367,8 @@
&count, HZ*10);
/* if the read was successful, copy the data to userspace */
- if (!retval) {
- if (copy_to_user (buffer, dev->bulk_in_buffer, count))
+ if (likely(!retval)) {
+ if (unlikely(copy_to_user (buffer, dev->bulk_in_buffer, count)))
retval = -EFAULT;
else
retval = count;
@@ -393,30 +397,33 @@
down (&dev->sem);
/* verify that the device wasn't unplugged */
- if (dev->udev == NULL) {
+ if (unlikely(dev->udev == NULL)) {
retval = -ENODEV;
goto exit;
}
/* verify that we actually have some data to write */
- if (count == 0) {
+ if (unlikely(count == 0)) {
dbg(__FUNCTION__ " - write request of 0 bytes");
goto exit;
}
/* see if we are already in the middle of a write */
- if (dev->write_urb->status == -EINPROGRESS) {
+ if (dev->writing) {
dbg (__FUNCTION__ " - already writing");
goto exit;
}
+ /* We need to make sure that we are known to write */
+ dev->writing = 1;
+
/* we can only write as much as 1 urb will hold */
bytes_written = (count > dev->bulk_out_size) ?
dev->bulk_out_size : count;
/* copy the data from userspace into our urb */
- if (copy_from_user(dev->write_urb->transfer_buffer, buffer,
- bytes_written)) {
+ if (unlikely(copy_from_user(dev->write_urb->transfer_buffer,
+ buffer, bytes_written))) {
retval = -EFAULT;
goto exit;
}
@@ -432,7 +439,7 @@
/* send the data out the bulk port */
retval = usb_submit_urb(dev->write_urb);
- if (retval) {
+ if (unlikely(retval)) {
err(__FUNCTION__ " - failed submitting write urb, error %d",
retval);
} else {
@@ -453,6 +460,7 @@
static int skel_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
struct usb_skel *dev;
+ int retval = -ENOTTY; /* Unsupported ioctl */
dev = (struct usb_skel *)file->private_data;
@@ -460,7 +468,7 @@
down (&dev->sem);
/* verify that the device wasn't unplugged */
- if (dev->udev == NULL) {
+ if (unlikely(dev->udev == NULL)) {
up (&dev->sem);
return -ENODEV;
}
@@ -474,8 +482,7 @@
/* unlock the device */
up (&dev->sem);
- /* return that we did not understand this ioctl call */
- return -ENOTTY;
+ return retval;
}
@@ -488,13 +495,18 @@
dbg(__FUNCTION__ " - minor %d", dev->minor);
- if ((urb->status != -ENOENT) &&
- (urb->status != -ECONNRESET)) {
+ /* We check for errors and report them
+ unless the URB was unlinked */
+ if (unlikely((urb->status != 0) &&
+ (urb->status != -ENOENT) &&
+ (urb->status != -ECONNRESET))) {
dbg(__FUNCTION__ " - nonzero write bulk status received: %d",
urb->status);
+ dev->writing = 0;
return;
}
+ dev->writing = 0;
return;
}
@@ -536,7 +548,7 @@
/* allocate memory for our device state and intialize it */
dev = kmalloc (sizeof(struct usb_skel), GFP_KERNEL);
- if (dev == NULL) {
+ if (unlikely(dev == NULL)) {
err ("Out of memory");
goto exit;
}
@@ -687,4 +699,6 @@
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
+
+
Hi,
this patch fixes
a) the error test in the callback
b) a race condition on write
c) module usage count bug
d) adds likely/unlikely
Regards
Oliver
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel