PPP2 driver interface_pp.c overhaul

sbertin@mindspring.com sbertin@mindspring.com
Sun, 29 Aug 1999 01:29:19 -0400 (EDT)


--0-1804289383-935904565=:17938
Content-Type: TEXT/plain; CHARSET=US-ASCII

Forgive me if I step on somebody's toes here, but I just got my camera
today and haven't seen any activity on this list yet.

I start playing around with my new Video Blaster WebCam II and found
some significant deficiencies in the parallel port handling, so I fixed
them.  The attached patch makes the following improvements over the 0.2
version of the driver:

	Support for multiple cameras. (untested)
	
	Auto detection of cameras if CONFIG_PNP_PARPORT_MODULE is
	defined for the kernel.

	More correct usage of the parport driver.

	Cameras detected at init rather than open.

	If there is only one camera and CONFIG_PNP_PARPORT_MODULE is
	set, it will always be /dev/cpia0 regardless of which parallel
	port it is connected to.

It also fixes the client for 16 and 32 bpp X servers.

Scott J. Bertin
sbertin@mindspring.com


--0-1804289383-935904565=:17938
Content-Type: TEXT/plain; CHARSET=US-ASCII
Content-Description: interface_pp_overhaul.diff

diff -u -r -N cpia.old/client/x11.c cpia/client/x11.c
--- cpia.old/client/x11.c	Thu May 13 16:59:16 1999
+++ cpia/client/x11.c	Sat Aug 28 18:50:19 1999
@@ -63,7 +63,7 @@
 	return -1;
 	};
 
-display_bits = info->bits_per_rgb * 3;
+display_bits = info->depth;
 display_bytes = (display_bits+7) >> 3; //round up ...
 
 printf("x11: color depth: %d bits, %d bytes\n",display_bits,display_bytes);
diff -u -r -N cpia.old/module/cpia_entry.h cpia/module/cpia_entry.h
--- cpia.old/module/cpia_entry.h	Sun May 16 13:59:56 1999
+++ cpia/module/cpia_entry.h	Sat Aug 28 22:42:53 1999
@@ -19,6 +19,7 @@
 struct parport			*port;
 enum comstates			state;
 enum camstates			camstate;
+int				open_count;
 };
 
 #endif
diff -u -r -N cpia.old/module/interface_pp.c cpia/module/interface_pp.c
--- cpia.old/module/interface_pp.c	Sun May 16 16:04:39 1999
+++ cpia/module/interface_pp.c	Sun Aug 29 01:04:51 1999
@@ -1,5 +1,8 @@
 
 // (C) 1999 Bas Huisman <bhuism@cs.utwente.nl>
+//          and Scott J. Bertin <sbertin@mindspring.com>
+
+#include <linux/config.h>
 
 #include <linux/parport.h>
 
@@ -12,7 +15,7 @@
 #define MAXCAMS		4
 #define PACKET_LENGTH 	8
 
-struct	cpia_entry *camera[MAXCAMS];
+struct	cpia_entry *camera;
 
 char camstatesstr[12][40] = {
 		"CPIA_PHASE_idle",
@@ -28,45 +31,6 @@
 
 // ***************************************************************************
 //
-//  struct cpia_entry stuff
-//
-// ***************************************************************************
-
-int newcamera(void)
-{
-int i;
-for (i = 0;i < MAXCAMS;i++)
-	{
-	if (camera[i] == NULL)
-		{
-		camera[i] = kmalloc(sizeof(struct cpia_entry),GFP_KERNEL);
-		if (!camera[i])
-			{
-			LOG("kmalloc failed\n");
-			return -1;
-			};
-		return i;
-		};
-	};
-LOG("reached MAXCAMS camera's increase MAXCAMS\n");
-return -1;
-};
-
-int freecam(int camnr)
-{
-if (camera[camnr])
-	{
-	kfree(camera[camnr]);
-	camera[camnr] = NULL;
-	return 0;
-	};
-LOG("hmm.. trying to free a unkmalloc'ed camera\n");
-return -1;
-};
-
-
-// ***************************************************************************
-//
 //  EndTransferMode
 //
 // ***************************************************************************
@@ -121,13 +85,13 @@
 return -1;
 };
 
-void pp_irq_handler(int irq,void *a,struct pt_regs *b)
+void pp_irq_handler(int irq,void *handle,struct pt_regs *b)
 {
-int minor = 0; //fixme
-if (camera[minor])
+struct cpia_entry *cam = (struct cpia_entry *)handle;
+if (cam)
 	{
-	if (camera[minor]->camstate == CPIA_PHASE_idle) LOG("image ready (%ld)\n",jiffies);
-	//LOG("(%ld)got IRQ when in %s\n",jiffies,camstatesstr[camera[minor]->camstate]);
+	if (cam->camstate == CPIA_PHASE_idle) LOG("image ready (%ld)\n",jiffies);
+	//LOG("(%ld)got IRQ when in %s\n",jiffies,camstatesstr[cam->camstate]);
 	};
 };
 
@@ -146,10 +110,10 @@
 int if_StreamRead(int minor,unsigned char *buffer,int length)
 {
 int tmp = 0;
-if (!camera[minor]) return -1;
-if (ReverseSetup(camera[minor],1)) return -1;
-tmp = ECPReadBuffer(camera[minor],buffer,length);
-EndTransferMode(camera[minor]);
+struct cpia_entry	*cpia = &camera[minor];
+if (ReverseSetup(cpia,1)) return -1;
+tmp = ECPReadBuffer(cpia,buffer,length);
+EndTransferMode(cpia);
 return tmp;
 };
 
@@ -168,9 +132,7 @@
 u8			cmd[PACKET_LENGTH] = {0,0,0,0,0,0,0,0};
 struct ioctlstruct 	*ioctlstr = (struct ioctlstruct *)iostru;
 int			databytes;
-struct cpia_entry	*cpia = camera[minor];
-
-if (!camera[minor]) return -1;
+struct cpia_entry	*cpia = &camera[minor];
 
 if ((ioctlnr<0)||(ioctlnr >= ((sizeof(ioctl2proc))/sizeof(ioctl2proc[0]))))
 	{
@@ -255,64 +217,28 @@
 
 int if_Open(int minor)
 {
-struct parport *port = NULL;
-struct pardevice *pdev = NULL;
-int camnr;
-
-if (camera[minor])  // if cpia_arr[minor]
-	{
-	LOG("camera[%d] != NULL already opened this thing ?\n",minor);
-	return -EBUSY;
-	};
-
-for (port = parport_enumerate();port;port = port->next)
+if(minor >= MAXCAMS || camera[minor].pdev == NULL)
 	{
-	if (port->number == minor) break;
-	};
-
-if (!port)
-	{
-	LOG("can't find parport number %d\n",minor);
+	LOG("Trying to open non-existent camera[%d]\n",minor);
 	return -ENXIO;
 	};
 
-if (!port->modes & PARPORT_MODE_PCECP) //fixme
+if(camera[minor].open_count > 0)
 	{
-	LOG("port is not ECP capable\n");
-	return -ENXIO;
-	};
-
-pdev = parport_register_device(port,"cpia",NULL,NULL,pp_irq_handler,0,NULL);
-
-if (!pdev)
-	{
-	LOG("failed to parport_register_device\n");
-	return -ENXIO;
+	return -EBUSY;
 	}
 
-if (parport_claim(pdev))
+if (parport_claim(camera[minor].pdev))
 	{
 	LOG("failed to claim the port\n");
-	parport_unregister_device(pdev);
 	return -EBUSY;
 	};
 
-if ((camnr = newcamera()) < 0)
-	{
-	parport_release(pdev);
-	parport_unregister_device(pdev);
-	return -EBUSY;
-	};
-
-camera[camnr]->pdev = pdev;
-camera[camnr]->port = port;
-camera[camnr]->state = CPIA_FORWARD;
-camera[camnr]->camstate = CPIA_PHASE_idle;
-
+++camera[minor].open_count;
 /* detect the thing */
 
-parport_write_econtrol(port,PARPORT_MODE_PCECR);
-parport_pc_disable_irq(port);
+parport_write_econtrol(camera[minor].port,PARPORT_MODE_PCECR);
+parport_pc_disable_irq(camera[minor].port);
 
 return 0; // success
 };
@@ -325,34 +251,89 @@
 
 int if_Close(int minor)
 {
-if (camera[minor])
+if(--camera[minor].open_count == 0)
 	{
-	if (camera[minor]->port->irq > 0) parport_pc_disable_irq(camera[minor]->port);
-	parport_release(camera[minor]->pdev);
-	parport_unregister_device(camera[minor]->pdev);
-	freecam(minor);
+	if (camera[minor].port->irq > 0) parport_pc_disable_irq(camera[minor].port);
+	parport_release(camera[minor].pdev);
 	}
-else	LOG("strange ... camera[%d] already NULL\n",minor);
+else LOG("Multiply opened camera[%d]\n", minor);
 return 0;
 };
 
+int cpia_register(int minor, struct parport *port)
+{
+struct pardevice *pdev = NULL;
+
+#ifdef CONFIG_PNP_PARPORT_MODULE
+if(port->probe_info.class != PARPORT_CLASS_MEDIA ||
+   port->probe_info.cmdset == NULL ||
+   strncmp(port->probe_info.cmdset, "CPIA_1", 6) != 0)
+	{
+	return -ENXIO;
+	}
+#endif /* CONFIG_PNP_PARPORT_MODULE */
+
+pdev = parport_register_device(port,"cpia",NULL,NULL,pp_irq_handler,0,&camera[minor]);
+
+if (!pdev)
+        {
+        LOG("failed to parport_register_device\n");
+        return -ENXIO;
+        }
+
+if (!(port->modes & PARPORT_MODE_PCECP))
+	{
+	LOG("port is not ECP capable\n");
+	parport_unregister_device(pdev);
+	return -ENXIO;
+	};
+
+camera[minor].pdev = pdev;
+camera[minor].port = port;
+camera[minor].state = CPIA_FORWARD;
+camera[minor].camstate = CPIA_PHASE_idle;
+camera[minor].open_count = 0;
+
+return 0; // success
+}
+
 int if_Init(void)
 {
-int i;
-for (i = 0;i < MAXCAMS;i++) camera[i] = NULL;
+struct parport *port;
+int i=0;
+camera = kmalloc(MAXCAMS*sizeof(struct cpia_entry),GFP_KERNEL);
+for (port = parport_enumerate(); port; port = port->next) {
+	if (!cpia_register(i, port))
+		if (++i == MAXCAMS)
+			break;
+}
+if(i == 0) {
+	LOG("No cameras found\n");
+	kfree(camera);
+	return -ENODEV;
+}
+while (i < MAXCAMS)
+	{
+	camera[i].pdev = NULL;
+	camera[i].port = NULL;
+	camera[i].open_count = 0;
+	++i;
+	};
 return 0;
 };
 
 int if_Cleanup(void)
 {
 int i;
-for (i = 0;i < MAXCAMS;i++)
+for (i = 0;camera[i].pdev != NULL && i < MAXCAMS;i++)
 	{
-	if (camera[i])
+	if (camera[i].open_count > 0)
 		{
 		LOG("You forgot to close minor %d, will do it for you\n",i);
 		if_Close(i);
 		};
+	parport_unregister_device(camera[i].pdev);
 	};
+kfree(camera);
 return 0;
 };
diff -u -r -N cpia.old/module/module.c cpia/module/module.c
--- cpia.old/module/module.c	Thu May 13 14:14:33 1999
+++ cpia/module/module.c	Sat Aug 28 21:05:34 1999
@@ -19,6 +19,7 @@
 int pp_cpia_open(struct inode *inode, struct file *file) // open()
 {
 if (if_Open(MINOR(inode->i_rdev))) return -1;
+file->private_data = (void *)MINOR(inode->i_rdev);
 MOD_INC_USE_COUNT;
 return 0;
 };
@@ -31,15 +32,13 @@
 
 ssize_t pp_cpia_read(struct file *file,char *buffer,size_t length, loff_t *lofft)
 {
-int minor = 0; //fixme
 if (!buffer) return -EINVAL;
-return if_StreamRead(minor,buffer,length);
+return if_StreamRead((int)file->private_data,buffer,length);
 };
 
 int pp_cpia_ioctl(struct inode *inode,struct file *file,unsigned int ioctlnr,unsigned long arg)
 {
-int minor = 0; //fixme
-return if_TransferMsg(minor,ioctlnr,(struct ioctlstruct *)arg);
+return if_TransferMsg(MINOR(inode->i_rdev),ioctlnr,(struct ioctlstruct *)arg);
 };
 
 struct file_operations cpia_fops =

--0-1804289383-935904565=:17938--
-----------------------------------------------------------------------------
To unsubscribe from this mailinglist, send the line "unsubscribe vision-webcam" in the
body of a message to "majordomo@errors.no".