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

Next file: linux/drivers/isdn/eicon/constant.h
Previous file: linux/drivers/isdn/eicon/bri.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/common.c linux/drivers/isdn/eicon/common.c
@@ -0,0 +1,896 @@
+
+/*
+ *
+ * Copyright (C) Eicon Technology Corporation, 2000.
+ *
+ * Eicon File Revision :    1.15  
+ *
+ * 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 "sys.h"
+#include "idi.h"
+#include "constant.h"
+#include "divas.h"
+#include "pc.h"
+#include "pr_pc.h"
+
+#include "uxio.h"
+#include <sys/types.h>
+
+#define MAX_ADDR_LEN
+
+#define DIVAS_LOAD_CMD		0x02
+#define DIVAS_START_CMD		0x03
+#define DIVAS_IRQ_RESET		0xC18
+#define DIVAS_IRQ_RESET_VAL	0xFE
+
+#define	PCI_COMMAND	0x04
+#define	PCI_STATUS	0x06
+#define	PCI_LATENCY	0x0D
+#define PCI_INTERRUPT	0x3C
+
+#define TEST_INT_DIVAS		0x11
+#define TEST_INT_DIVAS_BRI	0x12
+#define TEST_INT_DIVAS_Q	0x13
+
+#define DIVAS_RESET	0x81
+#define DIVAS_LED1	0x04
+#define DIVAS_LED2	0x08
+#define DIVAS_LED3	0x20
+#define DIVAS_LED4	0x40
+
+#define DIVAS_SIGNATURE 0x4447
+
+#define MP_PROTOCOL_ADDR 0xA0011000
+
+#define PLX_IOBASE	0
+#define	DIVAS_IOBASE	1
+
+typedef struct {
+		dword cmd;
+		dword addr;
+		dword len;
+		dword err;
+		dword live;
+		dword reserved[(0x1020>>2)-6];
+		dword signature;
+		byte  data[1];
+} diva_server_boot_t;
+
+int		DivasCardNext;
+card_t	DivasCards[MAX_CARDS];
+
+dia_config_t *DivasConfig(card_t *, dia_config_t *);
+
+static
+DESCRIPTOR DIDD_Table[32];
+
+void    DIVA_DIDD_Read( DESCRIPTOR *table, int tablelength )
+{
+        bzero(table, tablelength);
+
+        if (tablelength > sizeof(DIDD_Table))
+          tablelength = sizeof(DIDD_Table);
+
+        if(tablelength % sizeof(DESCRIPTOR)) {
+          tablelength /= sizeof(DESCRIPTOR);
+          tablelength *= sizeof(DESCRIPTOR);
+        }
+
+        if (tablelength > 0)
+          bcopy((caddr_t)DIDD_Table, (caddr_t)table, tablelength);
+
+	return;
+}
+
+void 	DIVA_DIDD_Write(DESCRIPTOR *table, int tablelength)
+{
+        if (tablelength > sizeof(DIDD_Table))
+          tablelength = sizeof(DIDD_Table);
+
+	bcopy((caddr_t)table, (caddr_t)DIDD_Table, tablelength);
+
+	return;
+}
+
+static
+void    init_idi_tab(void)
+{
+    DESCRIPTOR d[32];
+
+    bzero(d, sizeof(d));
+
+    d[0].type = IDI_DIMAINT;  /* identify the DIMAINT entry */
+    d[0].channels = 0; /* zero channels associated with dimaint*/
+    d[0].features = 0; /* no features associated with dimaint */
+    d[0].request = (IDI_CALL) DivasPrintf;
+    
+    DIVA_DIDD_Write(d, sizeof(d));
+
+    return;
+}
+
+/*
+ * I/O routines for memory mapped cards
+ */
+
+byte mem_in(ADAPTER *a, void *adr)
+{
+	card_t			*card = a->io;
+	unsigned char	*b, *m;
+	byte			value;
+
+	m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
+
+	m += (unsigned int) adr;
+
+	value = UxCardMemIn(card->hw, m);
+
+	UxCardMemDetach(card->hw, b);
+
+	return value;
+}
+
+word mem_inw(ADAPTER *a, void *adr)
+{
+	card_t			*card = a->io;
+	unsigned char	*b, *m;
+	word			value;
+
+	m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
+
+	m += (unsigned int) adr;
+
+	value = UxCardMemInW(card->hw, m);
+
+	UxCardMemDetach(card->hw, b);
+
+	return value;
+}
+
+void mem_in_buffer(ADAPTER *a, void *adr, void *P, word length)
+{
+	card_t			*card = a->io;
+	unsigned char	*b, *m;
+
+	m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
+
+	m += (unsigned int) adr;
+
+	UxCardMemInBuffer(card->hw, m, P, length);
+
+	UxCardMemDetach(card->hw, b);
+
+	return;
+}
+
+void mem_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e)
+{
+	card_t			*card = a->io;
+	unsigned char	*b, *m;
+
+	m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
+
+	m += (dword) &RBuffer->length;
+	card->RBuffer.length = UxCardMemInW(card->hw, m);
+
+	m = b;
+	m += (dword) &RBuffer->P;
+	UxCardMemInBuffer(card->hw, m, card->RBuffer.P, card->RBuffer.length);
+
+	e->RBuffer = (DBUFFER *) &card->RBuffer;
+
+	UxCardMemDetach(card->hw, b);
+
+	return;
+}
+
+void mem_out(ADAPTER *a, void *adr, byte data)
+{
+	card_t			*card = a->io;
+	unsigned char	*b, *m;
+
+	m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
+
+	m += (unsigned int) adr;
+
+	UxCardMemOut(card->hw, m, data);
+
+	UxCardMemDetach(card->hw, b);
+
+	return;
+}
+
+void mem_outw(ADAPTER *a, void *adr, word data)
+{
+	card_t			*card = a->io;
+	unsigned char	*b, *m;
+
+	m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
+
+	m += (unsigned int) adr;
+
+	UxCardMemOutW(card->hw, m, data);
+
+	UxCardMemDetach(card->hw, b);
+
+	return;
+}
+
+void mem_out_buffer(ADAPTER *a, void *adr, void *P, word length)
+{
+	card_t			*card = a->io;
+	unsigned char	*b, *m;
+
+	m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
+
+	m += (unsigned int) adr;
+
+	UxCardMemOutBuffer(card->hw, m, P, length);
+
+	UxCardMemDetach(card->hw, b);
+
+	return;
+}
+
+void mem_inc(ADAPTER *a, void *adr)
+{
+	word			value;
+	card_t			*card = a->io;
+	unsigned char	*b, *m;
+
+	m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
+
+	m += (unsigned int) adr;
+
+	value = UxCardMemInW(card->hw, m);
+	value++;
+	UxCardMemOutW(card->hw, m, value);
+
+	UxCardMemDetach(card->hw, b);
+
+	return;
+}
+
+/*
+ * I/O routines for I/O mapped cards
+ */
+
+byte io_in(ADAPTER *a, void *adr)
+{
+	card_t		    *card = a->io;
+	byte		    value;
+	byte	*DivasIOBase = NULL;
+
+	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
+
+	value = UxCardIoIn(card->hw, DivasIOBase, adr);
+
+	UxCardMemDetach(card->hw, DivasIOBase);
+
+    return value;
+}
+
+word io_inw(ADAPTER *a, void *adr)
+{
+	card_t		*card = a->io;
+	word		value;
+	byte	*DivasIOBase = NULL;
+
+	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
+
+	value = UxCardIoInW(card->hw, DivasIOBase, adr);
+
+	UxCardMemDetach(card->hw, DivasIOBase);
+
+	return value;
+}
+
+void io_in_buffer(ADAPTER *a, void *adr, void *P, word length)
+{
+	card_t *card = a->io;
+	byte *DivasIOBase = NULL;
+
+	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
+
+	UxCardIoInBuffer(card->hw, DivasIOBase, adr, P,length);
+
+	UxCardMemDetach(card->hw, DivasIOBase);
+
+    return;
+}
+
+void io_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e)
+{
+	card_t *card = a->io;
+	byte *DivasIOBase = NULL;
+
+	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
+
+	card->RBuffer.length = UxCardIoInW(card->hw, DivasIOBase, (byte *) RBuffer);
+
+	UxCardIoInBuffer(card->hw, DivasIOBase, &RBuffer->P, card->RBuffer.P, card->RBuffer.length);
+
+	UxCardMemDetach(card->hw, DivasIOBase);
+
+	e->RBuffer = (DBUFFER *) &card->RBuffer;
+
+    return;
+}
+
+void io_out(ADAPTER *a, void *adr, byte data)
+{
+	card_t		*card = a->io;
+	byte	*DivasIOBase = NULL;
+
+	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
+
+	UxCardIoOut(card->hw, DivasIOBase, adr, data);
+
+	UxCardMemDetach(card->hw, DivasIOBase);
+
+    return;
+}
+
+void io_outw(ADAPTER *a, void *adr, word data)
+{
+	card_t		*card = a->io;
+	byte	*DivasIOBase = NULL;
+
+	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
+
+	UxCardIoOutW(card->hw, DivasIOBase, adr, data);
+
+	UxCardMemDetach(card->hw, DivasIOBase);
+
+    return;
+}
+
+void io_out_buffer(ADAPTER *a, void *adr, void *P, word length)
+{
+	card_t		*card = a->io;
+	byte *DivasIOBase = NULL;
+
+	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
+
+	UxCardIoOutBuffer(card->hw, DivasIOBase, adr, P, length);
+
+	UxCardMemDetach(card->hw, DivasIOBase);
+
+    return;
+}
+
+void io_inc(ADAPTER *a, void *adr)
+{
+	word		value;
+	card_t		*card = a->io;
+	byte *DivasIOBase;
+
+	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
+
+	value = UxCardIoInW(card->hw, DivasIOBase, adr);
+	
+	value++;
+
+	UxCardIoOutW(card->hw, DivasIOBase, adr, value);
+
+	UxCardMemDetach(card->hw, DivasIOBase);
+
+    return;
+}
+
+static
+void test_int(card_t *card)
+
+{
+	byte *shared, *DivasIOBase;
+
+	switch (card->test_int_pend)
+	{
+		case TEST_INT_DIVAS:
+			DPRINTF(("divas: test interrupt pending"));
+			shared = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
+
+			if (UxCardMemIn(card->hw, &shared[0x3FE]))
+			{
+				UxCardMemOut(card->hw, 
+								&(((struct pr_ram *)shared)->RcOutput), 0);
+				UxCardMemDetach(card->hw, shared);
+            	(*card->reset_int)(card);
+				shared = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
+				UxCardMemOut(card->hw, &shared[0x3FE], 0);
+				DPRINTF(("divas: test interrupt cleared"));
+			}
+
+			UxCardMemDetach(card->hw, shared);
+
+			card->test_int_pend = 0;
+			break;
+
+		case TEST_INT_DIVAS_BRI:
+			DPRINTF(("divas: BRI test interrupt pending"));
+			(*card->reset_int)(card);
+			DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
+			UxCardIoOutW(card->hw, DivasIOBase, (void *) 0x3FE, 0);
+			UxCardMemDetach(card->hw, DivasIOBase);
+			DPRINTF(("divas: test interrupt cleared"));
+			card->test_int_pend = 0;
+			break;
+
+		case TEST_INT_DIVAS_Q:
+			DPRINTF(("divas: 4BRI test interrupt pending"));
+			(*card->reset_int)(card);
+			card->test_int_pend = 0;
+			break;
+
+		default:
+			DPRINTF(("divas: unknown test interrupt pending"));
+			return;
+	}
+	return;
+}
+
+void card_isr (void *dev_id)
+{
+	card_t *card = (card_t *) dev_id;
+	ADAPTER *a = &card->a;
+	int ipl;
+
+	if (card->test_int_pend)
+	{
+		ipl = UxCardLock(card->hw);
+		card->int_pend=0;
+		test_int(card);
+		UxCardUnlock(card->hw,ipl);
+		return;
+	}
+	
+	if(card->card_isr)
+	{
+		(*(card->card_isr))(card);
+	}
+	else
+	{
+		ipl = UxCardLock(card->hw);
+	
+		if ((card->test_int)(a))
+		{
+			(card->reset_int)(card);
+		}
+		
+		UxCardUnlock(card->hw,ipl);
+		
+	}
+
+}
+
+int DivasCardNew(dia_card_t *card_info)
+{
+	card_t *card;
+	byte b;
+	static boolean_t first_call = TRUE;
+	boolean_t NeedISRandReset = FALSE;
+
+	DPRINTF(("divas: new card "));
+
+	if (first_call)
+	{
+		first_call = FALSE;
+		init_idi_tab();
+	}
+
+	DivasConfigGet(card_info);
+	
+	if (DivasCardNext == DIM(DivasCards))
+	{
+		KDPRINTF((KERN_WARNING "Divas: no space available for new card"));
+		return -1;
+	}
+
+	card = &DivasCards[DivasCardNext];
+
+	card->state = DIA_UNKNOWN;
+
+	card->cfg = *card_info;
+
+	card->a.io = card;
+
+	if (UxCardHandleGet(&card->hw, card_info))
+	{
+		KDPRINTF((KERN_WARNING "Divas: cannot get OS specific handle for card"));
+		return -1;
+	}
+
+	if (card_info->card_type == DIA_CARD_TYPE_DIVA_SERVER_B)
+	{
+		DivasBriPatch(card);
+		card_info->io_base = card->cfg.io_base;
+	}
+
+	switch (card_info->card_type)
+	{
+		case DIA_CARD_TYPE_DIVA_SERVER:
+			if (DivasPriInit(card, card_info))
+			{
+				return -1;
+			}
+			NeedISRandReset = TRUE;
+			break;
+
+		case DIA_CARD_TYPE_DIVA_SERVER_B:
+			if (DivasBriInit(card, card_info))
+			{
+				return -1;
+			}
+			NeedISRandReset = TRUE;
+			break;
+
+ 		case DIA_CARD_TYPE_DIVA_SERVER_Q:
+			if (Divas4BriInit(card, card_info))
+			{
+				return -1;
+			}
+
+			if (card_info->name[6] == '0')
+			{
+				NeedISRandReset = TRUE;
+			}
+			else // Need to set paramater for ISR anyway
+			{
+				card->hw->user_isr_arg = card;
+				card->hw->user_isr = card_isr;
+			}
+			break;   
+
+		default:
+			KDPRINTF((KERN_WARNING "Divas: unsupported card type (%d)", card_info->card_type));
+			return -1;
+	}
+
+	if (NeedISRandReset)
+	{
+		if (UxIsrInstall(card->hw, card_isr, card))
+		{
+			KDPRINTF((KERN_WARNING "Divas: Install ISR failed (IRQ %d)", card->cfg.irq));
+			UxCardHandleFree(card->hw);
+			return -1;
+		}
+
+		b = card->cfg.irq;
+
+		UxPciConfigWrite(card->hw, sizeof(b), PCI_INTERRUPT, &b);
+
+		if (card_info->card_type != DIA_CARD_TYPE_DIVA_SERVER_Q)
+		{
+			if ((*card->card_reset)(card))
+			{
+				KDPRINTF((KERN_WARNING "Divas: Adapter reset failed"));
+				return -1;
+			}
+			card->state = DIA_RESET;
+		}
+
+		NeedISRandReset = FALSE;
+	}
+
+	DivasCardNext++;
+
+	return 0;
+}
+
+void	*get_card(int card_id)
+{
+	int i;
+
+	for (i=0; i < DivasCardNext; i++)
+	{
+		if (DivasCards[i].cfg.card_id == card_id)
+		{
+			return(&DivasCards[i]);
+		}
+	}
+
+	DPRINTF(("divas: get_card() : no such card id (%d)", card_id));
+
+	return NULL;
+}
+
+int DivasCardConfig(dia_config_t *config)
+{
+	card_t *card;
+	int status;
+
+	DPRINTF(("divas: configuring card"));
+
+	card = get_card(config->card_id);
+	if (!card)
+	{
+		return -1;
+	}
+
+	config = DivasConfig(card, config);
+
+	status = (*card->card_config)(card, config);
+
+	if (!status)
+	{
+		card->state = DIA_CONFIGURED;
+	}
+	return status;
+}
+
+int DivasCardLoad(dia_load_t *load)
+{
+	card_t *card;
+	int	status;
+
+	card = get_card(load->card_id);
+	if (!card)
+	{
+		return -1;
+	}
+
+	if (card->state == DIA_RUNNING)
+	{
+		(*card->card_reset)(card);
+	}
+
+	status = (*card->card_load)(card, load);
+	if (!status)
+	{
+		card->state = DIA_LOADED;
+	}
+	return status;
+}
+
+static int idi_register(card_t *card, byte channels)
+{
+    DESCRIPTOR d[32];
+    int length, num_entities;
+
+	DPRINTF(("divas: registering card with IDI"));
+
+	num_entities = (channels > 2) ? MAX_PENTITIES : MAX_ENTITIES;
+	card->e_tbl = UxAlloc(sizeof(E_INFO) * num_entities);
+
+	if (!card->e_tbl)
+	{
+		KDPRINTF((KERN_WARNING "Divas: IDI register failed - no memory available"));
+		return -1;
+	}
+
+	bzero(card->e_tbl, sizeof(E_INFO) * num_entities);
+	card->e_max = num_entities;
+
+    DIVA_DIDD_Read(d, sizeof(d));
+
+        for(length=0; length < DIM(d); length++)
+          if (d[length].type == 0) break;
+
+	if (length >= DIM(d))
+	{
+		KDPRINTF((KERN_WARNING "Divas: IDI register failed - table full"));
+		return -1;
+	}
+
+	switch (card->cfg.card_type)
+	{
+		case DIA_CARD_TYPE_DIVA_SERVER:
+		d[length].type = IDI_ADAPTER_PR;
+		/* d[length].serial = card->serial_no; */
+		break;
+
+		case DIA_CARD_TYPE_DIVA_SERVER_B:
+		d[length].type = IDI_ADAPTER_MAESTRA;
+		/* d[length].serial = card->serial_no; */
+		break;
+
+		// 4BRI is treated as 4 BRI adapters
+		case DIA_CARD_TYPE_DIVA_SERVER_Q:
+		d[length].type = IDI_ADAPTER_MAESTRA;
+		/* d[length].serial = card->cfg.serial; */
+	}
+
+	d[length].features = 0;
+	d[length].features |= DI_FAX3|DI_MODEM|DI_POST|DI_V110|DI_V120;
+
+	if ( card->hw->features & PROTCAP_MANIF )
+	{
+		d[length].features |= DI_MANAGE ;
+	}
+	if ( card->hw->features & PROTCAP_V_42 )
+	{
+		d[length].features |= DI_V_42 ;
+	}
+	if ( card->hw->features & PROTCAP_EXTD_FAX )
+	{
+		d[length].features |= DI_EXTD_FAX ;
+	}
+
+	d[length].channels = channels;
+	d[length].request = DivasIdiRequest[card - DivasCards];
+
+	length++;
+
+	DIVA_DIDD_Write(d, sizeof(d));
+
+    return 0;
+}
+
+int DivasCardStart(int card_id)
+{
+	card_t *card;
+	byte channels;
+	int status;
+
+	DPRINTF(("divas: starting card"));
+
+	card = get_card(card_id);
+	if (!card)
+	{
+		return -1;
+	}
+
+	status = (*card->card_start)(card, &channels);
+	if (status)
+	{
+		return status;
+	}
+
+	/* 4BRI == 4 x BRI so call idi_register 4 times each with 2 channels */
+	if (card->cfg.card_type == DIA_CARD_TYPE_DIVA_SERVER_Q)
+	{
+		int i;
+		card_t *FourBRISlave;
+
+		for (i=3; i >= 0; i--)
+		{
+			FourBRISlave = get_card(card_id - i); /* 0, 1, 2, 3 */
+			if (FourBRISlave)
+			{
+				idi_register(FourBRISlave, 2);
+				FourBRISlave->state = DIA_RUNNING;
+			}
+		}
+		card->serial_no = card->cfg.serial;
+
+		DPRINTF(("divas: card id %d (4BRI), serial no. 0x%x ready with %d channels", 
+				card_id - 3, card->serial_no, (int) channels));
+	}
+	else
+	{
+		status = idi_register(card, channels);
+		if (!status)
+		{
+			card->state = DIA_RUNNING;
+			DPRINTF(("divas: card id %d, serial no. 0x%x ready with %d channels", 
+						card_id, card->serial_no, (int) channels));
+		}
+	}
+
+	return status;
+}
+
+int DivasGetMem(mem_block_t *mem_block)
+{
+	card_t *card;
+	word	card_id = mem_block->card_id;
+
+	card = get_card(card_id);
+	if (!card)
+	{
+		return 0;
+	}
+
+	return (*card->card_mem_get)(card, mem_block);
+}
+
+
+/*
+ * Deleyed Procedure Call for handling interrupts from card
+ */
+
+void	DivaDoCardDpc(card_t *card)
+{
+	ADAPTER	*a;
+
+	a = &card->a;
+
+	if(UxInterlockedIncrement(card->hw, &card->dpc_reentered) > 1)
+	{
+		return;
+	}
+
+	do{
+		if((*(card->test_int))(a))
+		{
+			(*(card->dpc))(a);
+			(*(card->clear_int))(a);
+		}
+			(*(card->out))(a);
+	}while(UxInterlockedDecrement(card->hw, &card->dpc_reentered));
+			
+}
+
+void	DivasDoDpc(void *pData)
+{
+	card_t	*card = DivasCards;
+	int 	i = DivasCardNext;
+	
+	while(i--)
+	{
+		DivaDoCardDpc(card++);
+	}
+}
+
+void	DivasDoRequestDpc(void *pData)
+{
+	DivasDoDpc(pData);
+}
+
+/*
+ * DivasGetNum
+ * Returns the number of active adapters
+ */
+
+int DivasGetNum(void)
+{
+	return(DivasCardNext);
+}
+
+/*
+ * DivasGetList
+ * Returns a list of active adapters
+ */
+int DivasGetList(dia_card_list_t *card_list)
+{
+	int i;
+
+	bzero(card_list, sizeof(dia_card_list_t));
+
+	for(i = 0; i < DivasCardNext; i++)
+	{
+		card_list->card_type = DivasCards[i].cfg.card_type;
+		card_list->card_slot = DivasCards[i].cfg.slot;
+		card_list->state     = DivasCards[i].state;
+		card_list++;
+	}
+
+	return 0;
+
+}
+
+/*
+ * control logging for specified card
+ */
+
+void	DivasLog(dia_log_t *log)
+{
+	card_t *card;
+
+	card = get_card(log->card_id);
+	if (!card)
+	{
+		return;
+	}
+
+	card->log_types = log->log_types;
+
+	return;
+}
+

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