patch-2.2.19 linux/drivers/isdn/eicon/linchr.c

Next file: linux/drivers/isdn/eicon/linio.c
Previous file: linux/drivers/isdn/eicon/lincfg.c
Back to the patch index
Back to the overall index

diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.18/drivers/isdn/eicon/linchr.c linux/drivers/isdn/eicon/linchr.c
@@ -0,0 +1,269 @@
+
+/*
+ *
+ * Copyright (C) Eicon Technology Corporation, 2000.
+ *
+ * Eicon File Revision :    1.12  
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY 
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#define __NO_VERSION__
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/poll.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+
+#undef N_DATA
+
+#include "adapter.h"
+#include "divas.h"
+#include "divalog.h"
+
+extern int DivasCardNext;
+void UxPause(long ms);
+void bcopy(void *pSource, void *pDest, dword dwLength);
+int DivasGetMem(mem_block_t *);
+
+#define DIA_IOCTL_UNLOCK 12
+void UnlockDivas(void);
+
+int do_ioctl(struct inode *pDivasInode, struct file *pDivasFile, 
+			 unsigned int command, unsigned long arg)
+{
+	dia_load_t *pDivaLoad;
+	dia_start_t *pDivaStart;
+	dia_config_t *pDivaConfig;
+	dia_log_t *pDivaLog;
+	byte *pUserCards, card_i;
+	word wCardNum;
+	mem_block_t *mem_block;
+
+	switch (command)
+	{
+		case DIA_IOCTL_CONFIG:
+			pDivaConfig = (dia_config_t *) arg;
+			
+			if (!verify_area(VERIFY_READ, pDivaConfig, sizeof(dia_config_t)))
+			{
+				DivasCardConfig(pDivaConfig);
+			}
+			else
+			{
+				printk(KERN_WARNING "Divas: Unable to complete CONFIG ioctl (verify area failed)\n");
+				return -1;
+			}
+				return 0;
+
+		case DIA_IOCTL_DETECT:
+			pUserCards = (byte *) arg;
+
+			if (!verify_area(VERIFY_WRITE, pUserCards, 20))
+			{
+				put_user(DivasCardNext, pUserCards++);
+
+				for (card_i=1; card_i < 20; card_i++)
+				{
+					put_user((byte) DivasCards[card_i - 1].cfg.card_type, pUserCards++);
+				}
+			}
+			else
+			{
+				printk(KERN_WARNING "Divas: Unable to complete DETECT ioctl (verify area failed)\n");
+				return -1;
+			}
+			return 0;
+
+		case DIA_IOCTL_START:
+			pDivaStart = (dia_start_t *) arg;
+			
+			if (!verify_area(VERIFY_READ, pDivaStart, sizeof(dia_start_t)))
+			{
+				return DivasCardStart(pDivaStart->card_id);
+			}
+			else
+			{
+				printk(KERN_WARNING "Divas: Unable to complete START ioctl (verify area failed)\n");
+				return -1;
+			}
+
+
+		case DIA_IOCTL_FLAVOUR:
+			return 0;
+
+		case DIA_IOCTL_LOAD:
+			pDivaLoad = (dia_load_t *) arg;
+			if (!verify_area(VERIFY_READ, pDivaLoad->code,pDivaLoad->length))
+			{
+				if (DivasCardLoad(pDivaLoad))
+				{
+					printk(KERN_WARNING "Divas: Error loading DIVA Server adapter\n");
+					return -EINVAL;
+				}
+			}
+			else
+			{
+				printk(KERN_WARNING "Divas: Error in LOAD parameters (verify failed)\n");
+				return -EINVAL;
+			}
+			return 0;
+
+		case DIA_IOCTL_LOG:
+			pDivaLog = (dia_log_t *) arg;
+			
+			if (!verify_area(VERIFY_READ, pDivaLog, sizeof(dia_log_t)))
+			{
+				DivasLog(pDivaLog);
+			}
+			else
+			{
+				printk(KERN_WARNING "Divas: Unable to complete LOG ioctl (verify area failed)\n");
+				return -1;
+			}
+			return 0;
+
+		case DIA_IOCTL_XLOG_REQ:
+			
+			if (!verify_area(VERIFY_READ, (void *)arg, sizeof(word)))
+			{
+				wCardNum = * (word *) arg;
+				DivasXlogReq(wCardNum);
+			}
+			else
+			{
+				printk(KERN_WARNING "Divas: Unable to complete XLOG_REQ ioctl (verify area failed)\n");
+				return -1;
+			}
+			return 0;
+
+		case DIA_IOCTL_GET_NUM:
+			
+			if (!verify_area(VERIFY_WRITE, (void *)arg, sizeof(int)))
+			{
+				* (int *) arg = DivasCardNext;
+			}
+			else
+			{
+				printk(KERN_WARNING "Divas: Unable to complete GET_NUM ioctl (verify area failed)\n");
+				return -1;
+			}
+			return 0;
+
+		case DIA_IOCTL_GET_LIST:
+			DPRINTF(("divas: DIA_IOCTL_GET_LIST"));
+			
+			if (!verify_area(VERIFY_WRITE, (void *)arg, sizeof(dia_card_list_t)))
+			{
+				DivasGetList((dia_card_list_t *)arg);
+			}
+			else
+			{
+				printk(KERN_WARNING "Divas: Unable to complete GET_LIST ioctl (verify area failed)\n");
+				return -1;
+			}
+			return 0;
+
+		case DIA_IOCTL_GET_MEM:
+			mem_block = (mem_block_t *) arg;
+			
+			if (!verify_area(VERIFY_WRITE, mem_block, sizeof(mem_block_t)))
+			{
+				DivasGetMem(mem_block);
+			}
+			else
+			{
+				printk(KERN_WARNING "Divas: Unable to complete GET_MEM ioctl (verify area failed)\n");
+				return -1;
+			}
+			return 0;
+
+		case DIA_IOCTL_UNLOCK:
+			UnlockDivas();
+			return 0;
+
+		default:
+			printk(KERN_WARNING "Divas: Unknown IOCTL Received by DIVA Server Driver(%d)\n", command);
+			return -EINVAL;
+	}
+	
+	return -EINVAL;
+}
+
+unsigned int do_poll(struct file *pFile, struct poll_table_struct *pPollTable)
+{
+	word wMask = 0;
+
+    if (!DivasLogFifoEmpty())
+    {
+		wMask |= POLLIN | POLLRDNORM;
+	}
+
+	return wMask;
+}
+
+ssize_t do_read(struct file *pFile, char *pUserBuffer, size_t BufferSize, loff_t *pOffset)
+{
+	klog_t *pClientLogBuffer = (klog_t *) pUserBuffer;
+	klog_t *pHeadItem;
+
+	if (BufferSize < sizeof(klog_t))
+	{
+		printk(KERN_WARNING "Divas: Divalog buffer specifed a size that is too small (%d - %d required)\n",
+			BufferSize, sizeof(klog_t));
+		return 0;
+	}
+
+	pHeadItem = (klog_t *) DivasLogFifoRead();
+
+	if (pHeadItem)
+	{
+		bcopy(pHeadItem, pClientLogBuffer, sizeof(klog_t));
+		kfree(pHeadItem);
+		return sizeof(klog_t);
+	}
+
+	return 0;
+}
+static int private_usage_count;
+
+int do_open(struct inode *pInode, struct file *pFile)
+{
+	MOD_INC_USE_COUNT;
+#ifdef MODULE
+	private_usage_count++;
+#endif
+	return 0;
+}
+
+int do_release(struct inode *pInode, struct file *pFile)
+{
+	MOD_DEC_USE_COUNT;
+#ifdef MODULE
+	private_usage_count--;
+#endif
+	return 0;
+}
+
+void UnlockDivas(void)
+{
+	while (private_usage_count > 0)
+	{
+		private_usage_count--;
+		MOD_DEC_USE_COUNT;
+	}
+}

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