--- 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

Reply via email to