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