Hello

The attached patch fixes a bug in my driver :

When i unplug the camera during transfer, the camera is marked as
unplugged.
If this happens during a user program is within the read function, it
can happen
that the camera is marked as ready again. (Very bad mistake)
This might be a the reason for some Kernel oops ?!.

I have testet the driver with 2.3.99-pre4 :

OHCI            running ( and fastest )
( OPTi Inc. 82C861 (rev 10) PCI Card )

Both UHCI     running
( Intel Corporation 82371AB PIIX4 USB (rev 01) )

and didn't get any errors.


Randy: Please apply .. (patch is against pre6-3 )

Henning



--- linux/drivers/usb/mdc800.c.orig     Sat Apr 15 18:13:49 2000
+++ linux/drivers/usb/mdc800.c  Sat Apr 15 18:13:59 2000
@@ -30,6 +30,12 @@
  *
  * The driver supports only one camera.
  *
+ * version 0.7.3
+ * bugfix : The mdc800->state field gets set to READY after the 
+ * the diconnect function sets it to NOT_CONNECTED. This makes the
+ * driver running like the camera is connected and causes some 
+ * hang ups.
+ *
  * version 0.7.1
  * MOD_INC and MOD_DEC are changed in usb_probe to prevent load/unload
  * problems when compiled as Module.
@@ -73,8 +79,8 @@
 
 #include <linux/usb.h>
 
-#define VERSION                "0.7.1"
-#define RELEASE_DATE "(26/03/2000)"
+#define VERSION                "0.7.3"
+#define RELEASE_DATE "(15/04/2000)"
 
 /* Vendor and Product Information */
 #define MDC800_VENDOR_ID       0x055f
@@ -110,29 +116,29 @@
 
        unsigned int            endpoint [4];
 
-       purb_t                  irq_urb;
+       purb_t                     irq_urb;
        wait_queue_head_t       irq_wait;
-       char*                   irq_urb_buffer;
+       char*                         irq_urb_buffer;
 
-       int                     camera_busy;             // is camera busy ?
+       int                     camera_busy;          // is camera busy ?
        int                     camera_request_ready; // Status to synchronize with irq
        char                    camera_response [8];     // last Bytes send after busy
 
-       purb_t                  write_urb;
-       char*                   write_urb_buffer;
+       purb_t                     write_urb;
+       char*                         write_urb_buffer;
        wait_queue_head_t       write_wait;
 
 
        purb_t                  download_urb;
-       char*                   download_urb_buffer;
+       char*                         download_urb_buffer;
        wait_queue_head_t       download_wait;
-       int                     download_left;          // Bytes left to download ?
+       int                           download_left;            // Bytes left to 
+download ?
 
 
        /* Device Data */
-       char                    out [64];               // Answer Buffer
+       char                    out [64];       // Answer Buffer
        int                     out_ptr;                // Index to the first not 
readen byte
-       int                     out_count;              // Bytes in the buffer
+       int                     out_count;      // Bytes in the buffer
 
        int                     open;                   // Camera device open ?
        int                     rw_lock;                // Block read <-> write
@@ -284,9 +290,17 @@
        {
                mdc800->camera_request_ready=0;
                err ("timeout waiting for camera.");
-               return 0;
+               return -1;
        }
-       return 1;
+       
+       if (mdc800->state == NOT_CONNECTED)
+       {
+               warn ("Camera gets disconnected during waiting for irq.");
+               mdc800->camera_request_ready=0;
+               return -2;
+       }
+       
+       return 0;
 }
 
 
@@ -301,7 +315,10 @@
        {
                err ("writing command fails (status=%i)", urb->status);
        }
-       mdc800->state=READY;
+       else
+       {       
+               mdc800->state=READY;
+       }
        wake_up_interruptible (&mdc800->write_wait);
 }
 
@@ -328,7 +345,6 @@
        else
        {
                err ("request bytes fails (status:%i)", urb->status);
-               mdc800->state=READY;
        }
        wake_up_interruptible (&mdc800->download_wait);
 }
@@ -416,6 +432,8 @@
 
        mdc800->dev=dev;
        mdc800->state=READY;
+       mdc800->open=0;
+       mdc800->rw_lock=0;
 
        /* Setup URB Structs */
        FILL_INT_URB (
@@ -464,10 +482,8 @@
 
        if (mdc800->state == NOT_CONNECTED)
                return;
-
+       
        mdc800->state=NOT_CONNECTED;
-       mdc800->open=0;
-       mdc800->rw_lock=0;
 
        usb_unlink_urb (mdc800->irq_urb);
        usb_unlink_urb (mdc800->write_urb);
@@ -599,6 +615,12 @@
        if (mdc800->state == NOT_CONNECTED)
                return -EBUSY;
 
+       if (mdc800->state == WORKING)
+       {
+               warn ("Illegal State \"working\" reached during read ?!");
+               return -EBUSY;
+       }
+
        if (!mdc800->open || mdc800->rw_lock)
                return -EBUSY;
        mdc800->rw_lock=1;
@@ -624,15 +646,13 @@
                                if (usb_submit_urb (mdc800->download_urb))
                                {
                                        err ("Can't submit download urb 
(status=%i)",mdc800->download_urb->status);
-                                       mdc800->state=READY;
                                        mdc800->rw_lock=0;
                                        return len-left;
                                }
                                interruptible_sleep_on_timeout 
(&mdc800->download_wait, TO_DOWNLOAD_GET_READY*HZ/1000);
                                if (mdc800->download_urb->status != 0)
                                {
-                                       err ("requesting bytes fails 
(status=%i)",mdc800->download_urb->status);
-                                       mdc800->state=READY;
+                                       err ("request download-bytes fails 
+(status=%i)",mdc800->download_urb->status);
                                        mdc800->rw_lock=0;
                                        return len-left;
                                }
@@ -710,7 +730,12 @@
                {
                        int answersize;
 
-                       mdc800_usb_waitForIRQ (0,TO_GET_READY);
+                       if (mdc800_usb_waitForIRQ (0,TO_GET_READY))
+                       {
+                               err ("Camera didn't get ready.\n");
+                               mdc800->rw_lock=0;
+                               return -EIO;
+                       }
 
                        answersize=mdc800_getAnswerSize (mdc800->in[1]);
 
@@ -720,14 +745,12 @@
                        {
                                err ("submitting write urb fails (status=%i)", 
mdc800->write_urb->status);
                                mdc800->rw_lock=0;
-                               mdc800->state=READY;
                                return -EIO;
                        }
                        interruptible_sleep_on_timeout (&mdc800->write_wait, 
TO_DEFAULT_COMMAND*HZ/1000);
                        if (mdc800->state == WORKING)
                        {
                                usb_unlink_urb (mdc800->write_urb);
-                               mdc800->state=READY;
                                mdc800->rw_lock=0;
                                return -EIO;
                        }
@@ -756,10 +779,9 @@
                                        if (answersize)
                                        {
 
-                                               if (!mdc800_usb_waitForIRQ 
(1,TO_READ_FROM_IRQ))
+                                               if (mdc800_usb_waitForIRQ 
+(1,TO_READ_FROM_IRQ))
                                                {
                                                        err ("requesting answer from 
irq fails");
-                                                       mdc800->state=READY;
                                                        mdc800->rw_lock=0;
                                                        return -EIO;
                                                }
@@ -785,11 +807,10 @@
                                        }
                                        else
                                        {
-                                               if (!mdc800_usb_waitForIRQ 
(0,TO_DEFAULT_COMMAND))
+                                               if (mdc800_usb_waitForIRQ 
+(0,TO_DEFAULT_COMMAND))
                                                {
                                                        err ("Command Timeout.");
                                                        mdc800->rw_lock=0;
-                                                       mdc800->state=READY;
                                                        return -EIO;
                                                }
                                        }

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to