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

Next file: linux/drivers/isdn/eicon/linchr.c
Previous file: linux/drivers/isdn/eicon/kprintf.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/lincfg.c linux/drivers/isdn/eicon/lincfg.c
@@ -0,0 +1,407 @@
+
+/*
+ *
+ * Copyright (C) Eicon Technology Corporation, 2000.
+ *
+ * Eicon File Revision :    1.9  
+ *
+ * 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.
+ *
+ */
+
+
+#include <linux/fs.h>
+#undef N_DATA   /* Because we have our own definition */
+
+#include <asm/segment.h>
+#include <asm/io.h>
+
+#include "sys.h"
+#include "idi.h"
+#include "constant.h"
+#include "divas.h"
+#undef ID_MASK
+#include "pc.h"
+#include "pr_pc.h"
+
+#include "adapter.h"
+#include "uxio.h"
+
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+
+#define HW_ID_EICON_PCI			0x1133
+#define HW_ID_DIVA_SERVER_P		0xE014
+#define HW_ID_DIVA_SERVER_B_ST	0xE010
+#define HW_ID_DIVA_SERVER_B_U	0xE013
+#define HW_ID_DIVA_SERVER_Q   	0xE012
+
+struct file_operations Divas_fops;
+int Divas_major;
+
+extern int do_ioctl(struct inode *pDivasInode, struct file *pDivasFile, 
+			 unsigned int command, unsigned long arg);
+extern unsigned int do_poll(struct file *pFile, struct poll_table_struct *pPollTable);
+extern ssize_t do_read(struct file *pFile, char *pUserBuffer, size_t BufferSize, loff_t *pOffset);
+extern int do_open(struct inode *, struct file *);
+extern int do_release(struct inode *, struct file *);
+
+int FPGA_Done=0;
+
+int DivasCardsDiscover(void)
+{
+	word wNumCards = 0, wDeviceIndex = 0;
+	byte byBus, byFunc;
+	word wPCIConsultation, PCItmp;
+	dword j, i;
+	unsigned int PCIserial;
+	dia_card_t Card;
+	byte *b;
+	
+	while (wDeviceIndex < 10)
+	{
+		wPCIConsultation = pcibios_find_device(HW_ID_EICON_PCI, 
+				HW_ID_DIVA_SERVER_Q, 
+				wDeviceIndex, 
+				&byBus, &byFunc);
+
+		if (wPCIConsultation == PCIBIOS_SUCCESSFUL)
+		{
+
+			dword dwRAM, dwDivasIOBase, dwCFG, dwCTL; 			
+			byte byIRQ;
+			
+			printk(KERN_DEBUG "Divas: DIVA Server 4BRI Found\n");
+			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2,(unsigned int *) &dwRAM);
+			dwRAM &= 0xFFC00000;
+			
+			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_1,(unsigned int *) &dwDivasIOBase);
+			dwDivasIOBase &= 0xFFFFFF00;
+			
+			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_0,(unsigned int *) &dwCFG);
+			dwCFG &= 0xFFFFFF00;
+			
+			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_3,(unsigned int *) &dwCTL);
+			dwCTL &= 0xFFFFE000;
+			
+
+			pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);
+			/* Retrieve the serial number */
+
+			pcibios_write_config_word(byBus,byFunc,0x4E,0x00FC);
+
+			for (j=0, PCItmp=0; j<10000 && !PCItmp; j++)
+			{
+				pcibios_read_config_word(byBus,byFunc,0x4E, &PCItmp);
+				PCItmp &= 0x8000;  // extract done flag
+			}
+
+			pcibios_read_config_dword(byBus,byFunc,0x50, &PCIserial);
+
+		
+			Card.memory[DIVAS_RAM_MEMORY] = ioremap(dwRAM, 0x400000);
+			Card.memory[DIVAS_CTL_MEMORY] = ioremap(dwCTL, 0x2000);
+			Card.memory[DIVAS_CFG_MEMORY] = ioremap(dwCFG, 0x100);
+			Card.io_base=dwDivasIOBase;
+
+			Card.irq = byIRQ;
+			
+			Card.card_type = DIA_CARD_TYPE_DIVA_SERVER_Q;
+			Card.bus_type = DIA_BUS_TYPE_PCI;
+	
+			FPGA_Done = 0;
+
+			/* Create four virtual card structures as we want to treat 
+			   the 4Bri card as 4 Bri cards*/
+			for(i=0;i<4;i++)
+			{
+
+				b=Card.memory[DIVAS_RAM_MEMORY];
+				b+=(MQ_PROTCODE_OFFSET) * (i==0?0:1); 
+				DPRINTF(("divas: offset = 0x%x", i* MQ_PROTCODE_OFFSET));
+				Card.memory[DIVAS_RAM_MEMORY]=b;
+ 
+				b = Card.memory[DIVAS_RAM_MEMORY];
+				b += MQ_SM_OFFSET;
+				Card.memory[DIVAS_SHARED_MEMORY] = b;
+
+				Card.bus_num = byBus;
+				Card.func_num = byFunc;
+				Card.slot = -1;
+
+			
+				/* Fill in Name */
+				Card.name[0] = 'D';
+				Card.name[1] = 'I';
+				Card.name[2] = 'V';
+				Card.name[3] = 'A';
+				Card.name[4] = 'S';
+				Card.name[5] = 'Q';
+				Card.name[6] = '0' + i;
+				Card.name[7] = '\0';
+
+				Card.serial = PCIserial;
+
+			 	Card.card_id = wNumCards;
+
+ 				if (DivasCardNew(&Card) != 0)
+				{
+					// Force for loop to terminate
+					i = 4;
+					continue;
+				}
+				wNumCards++;
+
+			}//for
+		}
+		wDeviceIndex++;
+	}
+
+	wDeviceIndex = 0;
+
+	while (wDeviceIndex < 10)
+	{
+		wPCIConsultation = pcibios_find_device(HW_ID_EICON_PCI, 
+				HW_ID_DIVA_SERVER_B_ST, 
+				wDeviceIndex, 
+				&byBus, &byFunc);
+
+		if (wPCIConsultation == PCIBIOS_SUCCESSFUL)
+		{
+			dword dwPLXIOBase, dwDivasIOBase;
+			byte byIRQ;
+
+			printk(KERN_DEBUG "Divas: DIVA Server BRI (S/T) Found\n");
+			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_1, (unsigned int *) &dwPLXIOBase);
+			dwPLXIOBase &= 0xFFFFFF80;
+
+			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2, (unsigned int *) &dwDivasIOBase);
+			dwDivasIOBase &= 0xFFFFFFFC;
+
+			pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);
+
+			Card.card_id = wNumCards;
+			Card.card_type = DIA_CARD_TYPE_DIVA_SERVER_B;
+			Card.bus_type = DIA_BUS_TYPE_PCI;
+			Card.irq = byIRQ;
+			Card.reset_base = dwPLXIOBase;
+			Card.io_base = dwDivasIOBase;
+			Card.bus_num = byBus;
+			Card.func_num = byFunc;
+			Card.slot = -1;
+			Card.name[0] = 'D';
+			Card.name[1] = 'I';
+			Card.name[2] = 'V';
+			Card.name[3] = 'A';
+			Card.name[4] = 'S';
+			Card.name[5] = 'B';
+			Card.name[6] = '\0';
+
+			if (check_region(Card.io_base, 0x20))
+			{
+				printk(KERN_WARNING "Divas: DIVA I/O Base already in use 0x%x-0x%x\n", Card.io_base, Card.io_base + 0x1F);
+				wDeviceIndex++;
+				continue;
+			}
+
+			if (check_region(Card.reset_base, 0x80))
+			{
+				printk(KERN_WARNING "Divas: PLX I/O Base already in use 0x%x-0x%x\n", Card.reset_base, Card.reset_base + 0x7F);
+				wDeviceIndex++;
+				continue;
+			}
+
+			if (DivasCardNew(&Card) != 0)
+			{
+				wDeviceIndex++;
+				continue;
+			}
+			wNumCards++;
+		}
+
+		wPCIConsultation = pcibios_find_device(HW_ID_EICON_PCI, 
+				HW_ID_DIVA_SERVER_B_U, 
+				wDeviceIndex, 
+				&byBus, &byFunc);
+
+		if (wPCIConsultation == PCIBIOS_SUCCESSFUL)
+		{
+			dword dwPLXIOBase, dwDivasIOBase;
+			byte byIRQ;
+
+			printk(KERN_DEBUG "Divas: DIVA Server BRI (U) Found\n");
+
+			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_1, (unsigned int *) &dwPLXIOBase);
+			dwPLXIOBase &= 0xFFFFFF80;
+
+			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2, (unsigned int *) &dwDivasIOBase);
+			dwDivasIOBase &= 0xFFFFFFFC;
+
+			pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);
+
+			Card.card_id = wNumCards;
+			Card.card_type = DIA_CARD_TYPE_DIVA_SERVER_B;
+			Card.bus_type = DIA_BUS_TYPE_PCI;
+			Card.irq = byIRQ;
+			Card.reset_base = dwPLXIOBase;
+			Card.io_base = dwDivasIOBase;
+			Card.bus_num = byBus;
+			Card.func_num = byFunc;
+			Card.slot = -1;
+			Card.name[0] = 'D';
+			Card.name[1] = 'I';
+			Card.name[2] = 'V';
+			Card.name[3] = 'A';
+			Card.name[4] = 'S';
+			Card.name[5] = 'B';
+			Card.name[6] = '\0';
+
+			if (check_region(Card.io_base, 0x20))
+			{
+				printk(KERN_WARNING "Divas: DIVA I/O Base already in use 0x%x-0x%x\n", Card.io_base, Card.io_base + 0x1F);	
+				wDeviceIndex++;
+				continue;
+			}
+
+			if (check_region(Card.reset_base, 0x80))
+			{
+				printk(KERN_WARNING "Divas: PLX I/O Base already in use 0x%x-0x%x\n", Card.reset_base, Card.reset_base + 0x7F);
+				wDeviceIndex++;
+				continue;
+			}
+
+			if (DivasCardNew(&Card) != 0)
+			{
+				wDeviceIndex++;
+				continue;
+			}
+			wNumCards++;
+		}
+
+		wDeviceIndex++;
+	}
+
+	wDeviceIndex = 0;
+
+	while (wDeviceIndex < 10)
+	{
+		wPCIConsultation = pcibios_find_device(HW_ID_EICON_PCI, 
+				HW_ID_DIVA_SERVER_P, 
+				wDeviceIndex, 
+				&byBus, &byFunc);
+
+		if (wPCIConsultation == PCIBIOS_SUCCESSFUL)
+		{
+			dword dwRAM, dwREG, dwCFG;
+			byte byIRQ;
+
+			printk(KERN_DEBUG "Divas: DIVA Server PRI Found\n");
+
+			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_0, (unsigned int *) &dwRAM);
+			dwRAM &= 0xFFFFF000;
+
+			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2, (unsigned int *) &dwREG);
+			dwREG &= 0xFFFFF000;
+			
+			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_4, (unsigned int *) &dwCFG);
+			dwCFG &= 0xFFFFF000;
+
+			pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);
+
+			Card.memory[DIVAS_RAM_MEMORY] = ioremap(dwRAM, 0x10000);
+			Card.memory[DIVAS_REG_MEMORY] = ioremap(dwREG, 0x4000);
+			Card.memory[DIVAS_CFG_MEMORY] = ioremap(dwCFG, 0x1000);
+			Card.memory[DIVAS_SHARED_MEMORY] = Card.memory[DIVAS_RAM_MEMORY] + DIVAS_SHARED_OFFSET;
+
+/*			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_1, (unsigned int *) &dwPLXIOBase);
+			dwPLXIOBase &= 0xFFFFFFFc;
+
+			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2, (unsigned int *) &dwDivasIOBase);
+			dwDivasIOBase &= 0xFFFFFF80;
+
+			pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);
+*/
+			Card.card_id = wNumCards;
+			Card.card_type = DIA_CARD_TYPE_DIVA_SERVER;
+			Card.bus_type = DIA_BUS_TYPE_PCI;
+			Card.irq = byIRQ;
+/*			Card.reset_base = dwPLXIOBase;
+			Card.io_base = dwDivasIOBase;*/
+			Card.bus_num = byBus;
+			Card.func_num = byFunc;
+			Card.slot = -1;
+			Card.name[0] = 'D';
+			Card.name[1] = 'I';
+			Card.name[2] = 'V';
+			Card.name[3] = 'A';
+			Card.name[4] = 'S';
+			Card.name[5] = 'P';
+			Card.name[6] = '\0';
+
+			if (DivasCardNew(&Card) != 0)
+			{
+				wDeviceIndex++;
+				continue;
+			}
+			wNumCards++;
+		}
+
+		wDeviceIndex++;
+	}
+
+
+	printk(KERN_INFO "Divas: %d cards detected\n", wNumCards);
+
+	if(wNumCards == 0)
+	{
+		return -1;
+	}
+
+	Divas_fops.ioctl = do_ioctl;
+	Divas_fops.poll = do_poll;
+	Divas_fops.read = do_read;
+	Divas_fops.open = do_open;
+	Divas_fops.release = do_release;
+
+	Divas_major = register_chrdev(0, "Divas", &Divas_fops);
+
+	if (Divas_major < 0)
+	{
+		printk(KERN_WARNING "Divas: Unable to register character driver\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/* Error return -1 */
+int DivasConfigGet(dia_card_t *card)
+{
+	/* Retrieve Config from O/S? Not in Linux */
+	return 0;
+}
+
+dia_config_t *DivasConfig(card_t *card, dia_config_t *config)
+{
+	/*	If config retrieved from OS then copy the data into a dia_config_t structure here
+		and return the pointer here. If the config 'came from above' then just 
+
+			return config;
+	*/
+
+	return config;
+}
+

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