patch-2.3.99-pre6 linux/drivers/usb/mdc800.c

Next file: linux/drivers/usb/mousedev.c
Previous file: linux/drivers/usb/keybdev.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.99-pre5/linux/drivers/usb/mdc800.c linux/drivers/usb/mdc800.c
@@ -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,20 +79,20 @@
 
 #include <linux/usb.h>
 
-#define VERSION 		"0.7.1"
-#define RELEASE_DATE "(26/03/2000)"
+#define VERSION 	"0.7.3"
+#define RELEASE_DATE 	"(24/04/2000)"
 
 /* Vendor and Product Information */
 #define MDC800_VENDOR_ID 	0x055f
 #define MDC800_PRODUCT_ID	0xa800
 
 /* Timeouts (msec) */
-#define TO_READ_FROM_IRQ 		4000
-#define TO_GET_READY				2000
-#define TO_DOWNLOAD_GET_READY	1500
-#define TO_DOWNLOAD_GET_BUSY	1500
-#define TO_WRITE_GET_READY		3000
+#define TO_DOWNLOAD_GET_READY		1500
+#define TO_DOWNLOAD_GET_BUSY		1500
+#define TO_WRITE_GET_READY		1000
 #define TO_DEFAULT_COMMAND		5000
+#define TO_READ_FROM_IRQ 		TO_DEFAULT_COMMAND
+#define TO_GET_READY			TO_DEFAULT_COMMAND
 
 /* Minor Number of the device (create with mknod /dev/mustek c 180 32) */
 #define MDC800_DEVICE_MINOR_BASE 32
@@ -114,7 +120,7 @@
 	wait_queue_head_t	irq_wait;
 	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
 
@@ -130,9 +136,9 @@
 
 
 	/* 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);
 }
@@ -351,17 +367,18 @@
 
 	dbg ("(mdc800_usb_probe) called.");
 
-	if (mdc800->dev != 0)
-	{
-		warn ("only one Mustek MDC800 is supported.");
-		return 0;
-	}
 
 	if (dev->descriptor.idVendor != MDC800_VENDOR_ID)
 		return 0;
 	if (dev->descriptor.idProduct != MDC800_PRODUCT_ID)
 		return 0;
 
+	if (mdc800->dev != 0)
+	{
+		warn ("only one Mustek MDC800 is supported.");
+		return 0;
+	}
+
 	if (dev->descriptor.bNumConfigurations != 1)
 	{
 		err ("probe fails -> wrong Number of Configuration");
@@ -416,6 +433,8 @@
 
 	mdc800->dev=dev;
 	mdc800->state=READY;
+	mdc800->open=0;
+	mdc800->rw_lock=0;
 
 	/* Setup URB Structs */
 	FILL_INT_URB (
@@ -464,10 +483,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 +616,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 +647,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 +731,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 +746,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);
+			interruptible_sleep_on_timeout (&mdc800->write_wait, TO_WRITE_GET_READY*HZ/1000);
 			if (mdc800->state == WORKING)
 			{
 				usb_unlink_urb (mdc800->write_urb);
-				mdc800->state=READY;
 				mdc800->rw_lock=0;
 				return -EIO;
 			}
@@ -756,10 +780,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 +808,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;
 						}
 					}
@@ -811,21 +833,10 @@
 /* File Operations of this drivers */
 static struct file_operations mdc800_device_ops =
 {
-	0,					/* llseek */
-	mdc800_device_read,
-	mdc800_device_write,
-	0,					/* readdir */
-	0,					/* poll */
-	0,					/* ioctl, this can be used to detect USB ! */
-	0,					/* mmap */
-	mdc800_device_open,
-	0,					/* flush */
-	mdc800_device_release,
-	0,					/* async */
-	0,					/* fasync */
-	0,					/* check_media_change */
-//	0,					/* revalidate */
-//	0					/* lock */
+	read:		mdc800_device_read,
+	write:		mdc800_device_write,
+	open:		mdc800_device_open,
+	release:	mdc800_device_release,
 };
 
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)