The config entries etc were already removed earlier.
+++ /dev/null
-/*
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/fs.h>
-#undef N_DATA
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-
-#include "adapter.h"
-#include "uxio.h"
-
-
-MODULE_DESCRIPTION("ISDN4Linux: Driver for Eicon Diva Server cards");
-MODULE_AUTHOR("Armin Schindler");
-MODULE_LICENSE("GPL");
-
-void DivasInitDpc(void);
-
-#ifdef MODULE
-#include "idi.h"
-void DIVA_DIDD_Write(DESCRIPTOR *, int);
-EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Read);
-EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Write);
-EXPORT_SYMBOL_NOVERS(DivasPrintf);
-#endif
-
-int DivasCardsDiscover(void);
-
-static int __init
-divas_init(void)
-{
- printk(KERN_DEBUG "DIVA Server Driver - initialising\n");
-
- printk(KERN_DEBUG "DIVA Server Driver - Version 2.0.16\n");
-
-#if !defined(CONFIG_PCI)
- printk(KERN_WARNING "CONFIG_PCI is not defined!\n");
- return -ENODEV;
-#endif
-
- DivasInitDpc();
-
- if (DivasCardsDiscover() < 0)
- {
- printk(KERN_WARNING "Divas: Not loaded\n");
- return -ENODEV;
- }
-
- return 0;
-}
-
-static void __exit
-divas_exit(void)
-{
- card_t *pCard;
- word wCardIndex;
- extern int Divas_major;
-
- printk(KERN_DEBUG "DIVA Server Driver - unloading\n");
-
- pCard = DivasCards;
- for (wCardIndex = 0; wCardIndex < MAX_CARDS; wCardIndex++)
- {
- if ((pCard->hw) && (pCard->hw->in_use))
- {
-
- (*pCard->card_reset)(pCard);
-
- UxIsrRemove(pCard->hw, pCard);
- UxCardHandleFree(pCard->hw);
-
- if(pCard->e_tbl != NULL)
- {
- kfree(pCard->e_tbl);
- }
-
-
- if(pCard->hw->card_type == DIA_CARD_TYPE_DIVA_SERVER_B)
- {
- release_region(pCard->hw->io_base,0x20);
- release_region(pCard->hw->reset_base,0x80);
- }
-
- // If this is a 4BRI ...
- if (pCard->hw->card_type == DIA_CARD_TYPE_DIVA_SERVER_Q)
- {
- // Skip over the next 3 virtual adapters
- wCardIndex += 3;
-
- // But free their handles
- pCard++;
- UxCardHandleFree(pCard->hw);
-
- if(pCard->e_tbl != NULL)
- {
- kfree(pCard->e_tbl);
- }
-
- pCard++;
- UxCardHandleFree(pCard->hw);
-
- if(pCard->e_tbl != NULL)
- {
- kfree(pCard->e_tbl);
- }
-
- pCard++;
- UxCardHandleFree(pCard->hw);
-
- if(pCard->e_tbl != NULL)
- {
- kfree(pCard->e_tbl);
- }
- }
- }
- pCard++;
- }
-
- unregister_chrdev(Divas_major, "Divas");
-}
-
-module_init(divas_init);
-module_exit(divas_exit);
-
+++ /dev/null
-#
-# Config.in for Eicon active ISDN support
-#
-config ISDN_DRV_EICON
- bool "Eicon active card support"
- help
- Say Y here if you have an Eicon active ISDN card. In order to use
- this card, additional firmware is necessary, which has to be loaded
- into the card using the eiconctrl utility which is part of the
- latest isdn4k-utils package. Please read the file
- <file:Documentation/isdn/README.eicon> for more information.
-
-choice
- prompt "Eicon active card support"
- optional
- depends on ISDN_DRV_EICON && ISDN && m
-
-config ISDN_DRV_EICON_DIVAS
- tristate "Eicon driver"
- depends on PCI
- help
- Enable this option if you want the eicon driver as standalone
- version with no interface to the ISDN4Linux isdn module. If you
- say Y here, the eicon module only supports the Diva Server PCI
- cards and will provide its own IDI interface. You should say N
- here.
-
-config ISDN_DRV_EICON_OLD
- tristate "Legacy driver"
- help
- Say Y here to use your Eicon active ISDN card with ISDN4Linux
- isdn module.
-
-config ISDN_DRV_EICON_PCI
- bool "Eicon PCI DIVA Server BRI/PRI/4BRI support"
- depends on ISDN_DRV_EICON_OLD && PCI
- help
- Say Y here if you have an Eicon Diva Server (BRI/PRI/4BRI) ISDN
- card. Please read <file:Documentation/isdn/README.eicon> for more
- information.
-
-config ISDN_DRV_EICON_ISA
- bool "Eicon S,SX,SCOM,Quadro,S2M support"
- depends on ISDN_DRV_EICON_OLD
- help
- Say Y here if you have an old-type Eicon active ISDN card. In order
- to use this card, additional firmware is necessary, which has to be
- loaded into the card using the eiconctrl utility which is part of
- the latest isdn4k-utils package. Please read the file
- <file:Documentation/isdn/README.eicon> for more information.
-
-endchoice
-
+++ /dev/null
-# Makefile for the eicon ISDN device driver
-
-# Each configuration option enables a list of files.
-
-obj-$(CONFIG_ISDN_DRV_EICON_OLD) += eicon.o
-obj-$(CONFIG_ISDN_DRV_EICON_DIVAS) += divas.o
-
-# Multipart objects.
-
-eicon-y := eicon_mod.o eicon_isa.o eicon_pci.o \
- eicon_idi.o eicon_io.o
-eicon-$(CONFIG_ISDN_DRV_EICON_PCI) += common.o idi.o bri.o pri.o log.o \
- xlog.o kprintf.o fpga.o fourbri.o lincfg.o \
- linchr.o linsys.o linio.o
-
-divas-y := common.o idi.o bri.o pri.o log.o xlog.o \
- kprintf.o fpga.o fourbri.o lincfg.o \
- linchr.o linsys.o linio.o Divas_mod.o
-
+++ /dev/null
-/*
- * Main internal include file for Diva Server driver
- *
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.7
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#if !defined(ADAPTER_H)
-#define ADAPTER_H
-
-#include "sys.h"
-#include "idi.h"
-#include "divas.h"
-#undef ID_MASK
-#include "pc.h"
-
-#define XMOREC 0x1f
-#define XMOREF 0x20
-#define XBUSY 0x40
-#define RMORE 0x80
-
- /* structure for all information we have to keep on a per */
- /* adapater basis */
-
-typedef struct adapter_s ADAPTER;
-
-struct adapter_s {
- void * io;
-
- byte IdTable[256];
- byte ReadyInt;
-
- byte (* ram_in)(ADAPTER * a, void * adr);
- word (* ram_inw)(ADAPTER * a, void * adr);
- void (* ram_in_buffer)(ADAPTER * a, void * adr, void * P, word length);
- void (* ram_look_ahead)(ADAPTER * a, PBUFFER * RBuffer, ENTITY * e);
-
- void (* ram_out)(ADAPTER * a, void * adr, byte data);
- void (* ram_outw)(ADAPTER * a, void * adr, word data);
- void (* ram_out_buffer)(ADAPTER * a, void * adr, void * P, word length);
-
- void (* ram_inc)(ADAPTER * a, void * adr);
-};
-
-typedef struct card card_t;
-
-typedef int card_load_fn_t(card_t *card, dia_load_t *load);
-typedef int card_config_fn_t(card_t *card, dia_config_t *config);
-typedef int card_start_fn_t(card_t *card, byte *channels);
-typedef int card_reset_fn_t(card_t *card);
-typedef int card_mem_get_fn_t(card_t *card, mem_block_t *mem_block);
-
-#define MAX_PENTITIES 256 /* Number of entities primary adapter */
-#define MAX_ENTITIES 16 /* Number of entities standard adapter */
-
-typedef struct e_info_s E_INFO;
-
-struct e_info_s
-{
- ENTITY *e; /* entity pointer */
- byte next; /* chaining index */
- word assign_ref; /* assign reference */
-};
-
-/* DIVA card info (details hidden from user) */
-
-typedef struct ux_diva_card_s ux_diva_card_t;
-
-/* card info */
-
-struct card
-{
- ADAPTER a; /* per-adapter information */
- dia_card_t cfg; /* card configuration */
- int state; /* State of the adapter */
- dword serial_no; /* serial number */
- int test_int_pend; /* set for interrupt testing */
- ux_diva_card_t *hw; /* O/S-specific handle */
- card_reset_fn_t *card_reset; /* call this to reset card */
- card_load_fn_t *card_load; /* call this to load card */
- card_config_fn_t *card_config; /* call this to config card */
- card_start_fn_t *card_start; /* call this to start card */
- card_mem_get_fn_t *card_mem_get; /* call this to get card memory */
- E_INFO *e_tbl; /* table of ENTITY pointers */
- byte e_head; /* list of active ENTITIES */
- byte e_tail; /* list of active ENTITIES */
- int e_count; /* # of active ENTITIES */
- int e_max; /* total # of ENTITIES */
- byte assign; /* assign queue entry */
- PBUFFER RBuffer; /* Copy of receive lookahead buffer */
- int log_types; /* bit-mask of active logs */
- word xlog_offset; /* offset to XLOG buffer on card */
- void (*out)(ADAPTER *a);
- byte (*dpc)(ADAPTER * a);
- byte (*test_int)(ADAPTER * a);
- void (*clear_int)(ADAPTER * a);
- void (*reset_int)(card_t *c);
- int is_live;
-
- int (*card_isr)(card_t *card);
-
- int int_pend; /* interrupt pending */
- long interrupt_reentered;
- long dpc_reentered;
- int set_xlog_request;
-
-} ;
-
-/* card information */
-
-#define MAX_CARDS 20 /* max number of cards on a system */
-
-extern
-card_t DivasCards[];
-
-extern
-int DivasCardNext;
-
-extern
-dia_config_t DivasCardConfigs[];
-
-extern
-byte DivasFlavourConfig[];
-
-/*------------------------------------------------------------------*/
-/* public functions of IDI common code */
-/*------------------------------------------------------------------*/
-
-void DivasOut(ADAPTER * a);
-byte DivasDpc(ADAPTER * a);
-byte DivasTestInt(ADAPTER * a);
-void DivasClearInt(ADAPTER * a);
-
-/*------------------------------------------------------------------*/
-/* public functions of configuration platform-specific code */
-/*------------------------------------------------------------------*/
-
-int DivasConfigGet(dia_card_t *card);
-
-/*------------------------------------------------------------------*/
-/* public functions of LOG related code */
-/*------------------------------------------------------------------*/
-
-void DivasXlogReq(int card_num);
-int DivasXlogRetrieve(card_t *card);
-void DivasLog(dia_log_t *log);
-void DivasLogIdi(card_t *card, ENTITY *e, int request);
-
-/*------------------------------------------------------------------*/
-/* public functions to initialise cards for each type supported */
-/*------------------------------------------------------------------*/
-
-int DivasPriInit(card_t *card, dia_card_t *cfg);
-
-int DivasBriInit(card_t *card, dia_card_t *cfg);
-int Divas4BriInit(card_t *card, dia_card_t *cfg);
-void DivasBriPatch(card_t *card);
-
-/*------------------------------------------------------------------*/
-/* public functions of log common code */
-/*------------------------------------------------------------------*/
-
-extern char *DivasLogFifoRead(void);
-extern void DivasLogFifoWrite(char *entry, int length);
-extern int DivasLogFifoEmpty(void);
-extern int DivasLogFifoFull(void);
-extern void DivasLogAdd(void *buffer, int length);
-
-/*------------------------------------------------------------------*/
-/* public functions of misc. platform-specific code */
-/*------------------------------------------------------------------*/
-
-int DivasDpcSchedule(void);
-void DivasDoDpc(unsigned long);
-int DivasScheduleRequestDpc(void);
-
-/* table of IDI request functions */
-
-extern
-IDI_CALL DivasIdiRequest[];
-
-/*
- * initialisation entry point
- */
-
-int DivasInit(void);
-
-/*
- * Get information on the number and type of cards present
- */
-
-extern
-int DivasCardsDiscover(void);
-
-/*
- * initialise a new card
- */
-
-int DivasCardNew(dia_card_t *card);
-
-/*
- * configure specified card
- */
-
-int DivasCardConfig(dia_config_t *config);
-
-/*
- * load specified binary code onto card
- */
-
-int DivasCardLoad(dia_load_t *load);
-
-/*
- * start specified card running
- */
-
-int DivasCardStart(int card_id);
-
-/*
- * ISR for card
- * Returns 0 if specified card was interrupting
- */
-
-int DivasIsr(void *arg);
-
-/*
- * Get number of active cards
- */
-
-int DivasGetNum(void);
-
-/*
- * Get list of active cards
- */
-
-int DivasGetList(dia_card_list_t *card_list);
-
-/* definitions common to several card types */
-
-#define DIVAS_SHARED_OFFSET (0x1000)
-
-#endif /* ADAPTER_H */
+++ /dev/null
-/*
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.8
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include "eicon.h"
-#include "sys.h"
-#include "idi.h"
-#include "divas.h"
-#include "pc.h"
-#include "pr_pc.h"
-#include "dsp_defs.h"
-
-#include "adapter.h"
-#include "uxio.h"
-
-#define PCI_BADDR0 0x10
-#define PCI_BADDR1 0x14
-#define PCI_BADDR2 0x18
-
-#define DIVAS_SIGNATURE 0x4447
-
-/* offset to start of MAINT area (used by xlog) */
-
-#define DIVAS_MAINT_OFFSET 0xff00 /* value for BRI card */
-
-#define PROTCAP_TELINDUS 0x1
-#define PROTCAP_V90D 0x8
-
-word GetProtFeatureValue(char *sw_id);
-byte io_in(ADAPTER *a, void *adr);
-word io_inw(ADAPTER *a, void *adr);
-void io_in_buffer(ADAPTER *a, void *adr, void *P, word length);
-void io_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e);
-void io_out(ADAPTER *a, void *adr, byte data);
-void io_outw(ADAPTER *a, void *adr, word data);
-void io_out_buffer(ADAPTER *a, void *adr, void *P, word length);
-void io_inc(ADAPTER *a, void *adr);
-
-static int diva_server_bri_test_int(card_t *card);
-static int bri_ISR (card_t* card);
-
-#define PLX_IOBASE 0
-#define DIVAS_IOBASE 1
-
-#define REG_DATA 0x00
-#define REG_ADDRLO 0x04
-#define REG_ADDRHI 0x0C
-#define REG_IOCTRL 0x10
-
-#define M_PCI_RESET 0x10
-
-byte UxCardPortIoIn(ux_diva_card_t *card, byte *base, int offset);
-word UxCardPortIoInW(ux_diva_card_t *card, byte *base, int offset);
-void UxCardPortIoOut(ux_diva_card_t *card, byte *base, int offset, byte);
-void UxCardPortIoOutW(ux_diva_card_t *card, byte *base, int offset, word);
-
-int DivasBRIInitPCI(card_t *card, dia_card_t *cfg);
-
-static
-int diva_server_bri_reset(card_t *card)
-{
- byte *DivasIOBase;
- word i;
- dword dwWait;
-
- UxCardLog(0);
-
- DPRINTF(("divas: resetting BRI adapter"));
-
- DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
-
- UxCardPortIoOut(card->hw, DivasIOBase, REG_IOCTRL, 0);
-
- for (i=0; i < 50000; i++)
- ;
-
- UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0);
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0);
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_DATA , 0);
-
- UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x0000);
-
- for (i=0; i<0x8000; i++)
- {
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_DATA , 0);
- }
-
- for (dwWait=0; dwWait < 0x00FFFFFF; dwWait++)
- ;
-
- UxCardMemDetach(card->hw, DivasIOBase);
-
- return 0;
-}
-
-static
-void diva_server_bri_reset_int(card_t *card)
-{
- byte *DivasIOBase = NULL;
-
- DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
-
- UxCardPortIoOut(card->hw, DivasIOBase, REG_IOCTRL, 0x08);
-
- UxCardMemDetach(card->hw, DivasIOBase);
-
- return;
-}
-
-static
-int diva_server_bri_start(card_t *card, byte *channels)
-{
- byte *DivasIOBase, *PLXIOBase;
- word wSig = 0;
- word i;
- dword dwSerialNum;
- byte bPLX9060 = FALSE;
-
- DPRINTF(("divas: starting Diva Server BRI card"));
-
- card->is_live = FALSE;
-
- DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
-
- UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x1E);
-
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA , 0);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA , 0);
-
- UxCardPortIoOut(card->hw, DivasIOBase, REG_IOCTRL, 0x08);
-
- /* wait for signature to indicate card has started */
- for (i = 0; i < 300; i++)
- {
- UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x1E);
- wSig = UxCardPortIoInW(card->hw, DivasIOBase, REG_DATA);
-
- if (wSig == DIVAS_SIGNATURE)
- {
- DPRINTF(("divas: card started after %d ms", i * 10));
- break;
- }
- UxPause(10);
- }
-
- if (wSig != DIVAS_SIGNATURE)
- {
- DPRINTF(("divas: card failed to start (Sig=0x%x)", wSig));
- UxCardMemDetach(card->hw, DivasIOBase);
- return -1;
- }
-
- card->is_live = TRUE;
-
- UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x3F6);
- *channels = UxCardPortIoInW(card->hw, DivasIOBase, REG_DATA);
-
- UxCardMemDetach(card->hw, DivasIOBase);
-
- PLXIOBase = UxCardMemAttach(card->hw, PLX_IOBASE);
-
- bPLX9060 = UxCardPortIoInW(card->hw, PLXIOBase, 0x6C) | UxCardPortIoInW(card->hw, PLXIOBase, 0x6E);
-
- if (bPLX9060)
- {
- dwSerialNum = (UxCardPortIoInW(card->hw, PLXIOBase, 0x1E) << 16) |
- (UxCardPortIoInW(card->hw, PLXIOBase, 0x22));
- DPRINTF(("divas: PLX9060 in use. Serial number 0x%04X", dwSerialNum));
- }
- else
- {
- dwSerialNum = (UxCardPortIoInW(card->hw, PLXIOBase, 0x22) << 16) |
- (UxCardPortIoInW(card->hw, PLXIOBase, 0x26));
- DPRINTF(("divas: PLX9050 in use. Serial number 0x%04X", dwSerialNum));
- }
-
- UxCardMemDetach(card->hw, PLXIOBase);
-
- card->serial_no = dwSerialNum;
-
- diva_server_bri_test_int(card);
-
- return 0;
-}
-
-static
-int diva_server_bri_load(card_t *card, dia_load_t *load)
-{
- byte *DivasIOBase;
- dword r3000_base;
- dword dwAddr, dwLength, i;
- word wTest, aWord;
-
- DPRINTF(("divas: loading Diva Server BRI card"));
-
- switch (load->code_type)
- {
- case DIA_CPU_CODE:
- DPRINTF(("divas: loading RISC %s", &load->code[0x80]));
-
- card->hw->features = GetProtFeatureValue((char *)&load->code[0x80]);
- DPRINTF(("divas: features 0x%x", card->hw->features));
- if (card->hw->features == 0xFFFF)
- {
- DPRINTF(("divas: invalid feature string failed load\n"));
- return -1;
- }
-
- r3000_base = 0;
- break;
-
- case DIA_DSP_CODE:
- DPRINTF(("divas: DSP code \"%s\"", load->code));
-
- if ((card->hw->features) && (!(card->hw->features & PROTCAP_TELINDUS)))
- {
- DPRINTF(("divas: only Telindus style binaries supported"));
- return -1;
- }
-
- if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
- {
- DPRINTF(("divas: V.90 DSP binary"));
- r3000_base = (0xBF790000 + (((sizeof(dword) + (sizeof(t_dsp_download_desc)* DSP_MAX_DOWNLOAD_COUNT)) + 3) & 0xFFFFFFFC));
- }
- else
- {
- DPRINTF(("divas: non-V.90 DSP binary"));
- r3000_base = (0xBF7A0000 + (((sizeof(dword) + (sizeof(t_dsp_download_desc)* DSP_MAX_DOWNLOAD_COUNT)) + 3) & 0xFFFFFFFC));
- }
- DPRINTF(("divas: loading at 0x%x", r3000_base));
- break;
-
- case DIA_TABLE_CODE:
- DPRINTF(("divas: TABLE code"));
- if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
- {
- r3000_base = 0xBF790000 + sizeof(dword);
- }
- else
- {
- r3000_base = 0xBF7A0000 + sizeof(dword);
- }
-
- break;
-
- case DIA_DLOAD_CNT:
- DPRINTF(("divas: COUNT code"));
- if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
- {
- r3000_base = 0xBF790000;
- }
- else
- {
- r3000_base = 0xBF7A0000;
- }
- break;
-
- default:
- DPRINTF(("divas: unknown code type %d", load->code_type));
- return -1;
- break;
- }
-
- DPRINTF(("divas: Writing %d bytes to adapter, address 0x%x", load->length, r3000_base));
-
- DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
-
- DPRINTF(("divas: Attached to 0x%04X", DivasIOBase));
-
- dwLength = load->length;
-
- for (i=0; i < dwLength; i++)
- {
- dwAddr = r3000_base + i;
-
- UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, dwAddr >> 16);
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, dwAddr);
-
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, load->code[i]);
- }
-
- DPRINTF(("divas: Verifying"));
-
- for (i=0; i<dwLength; i++)
- {
- dwAddr = r3000_base + i;
-
- UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, dwAddr >> 16);
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, dwAddr);
-
- wTest = UxCardPortIoIn(card->hw, DivasIOBase, REG_DATA);
-
- aWord = load->code[i];
-
- if (wTest != aWord)
- {
- DPRINTF(("divas: load verify failed on byte %d", i));
- DPRINTF(("divas: RAM 0x%x File 0x%x",wTest,aWord));
-
- UxCardMemDetach(card->hw, DivasIOBase);
-
- return -1;
- }
- }
-
- DPRINTF(("divas: Loaded and verified. Detaching from adapter"));
-
- UxCardMemDetach(card->hw, DivasIOBase);
-
- UxCardLog(0);
-
- return 0;
-}
-
-static
-int diva_server_bri_config(card_t *card, dia_config_t *config)
-{
- byte *DivasIOBase, i;
-
- DPRINTF(("divas: configuring Diva Server BRI card"));
-
- DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
-
- UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 8);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->tei);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 9);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->nt2);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 10);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->sig_flags);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 11);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->watchdog);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 12);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->permanent);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 13);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 14);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->stable_l2);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 15);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->no_order_check);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 16);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 17);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 18);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->low_channel);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 19);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->prot_version);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 20);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->crc4);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 21);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
-
- if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
- {
- DPRINTF(("divas: Signifying V.90"));
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 22);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 4);
- }
- else
- {
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 22);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
- }
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 23);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, card->serial_no & 0xFF);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 24);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, (card->serial_no >> 8) & 0xFF);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 25);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, (card->serial_no >> 16) & 0xFF);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 26);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 21);
-
- for (i=0; i<32; i++)
- {
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 32+i);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[0].oad[i]);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 64+i);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[0].osa[i]);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 96+i);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[0].spid[i]);
-
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 128+i);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[1].oad[i]);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 160+i);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[1].osa[i]);
-
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 192+i);
- UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[1].spid[i]);
- }
-
- UxCardMemDetach(card->hw, DivasIOBase);
-
- return 0;
-}
-
-void DivasBriPatch(card_t *card)
-{
- dword PLXIOBase = 0;
- dword DivasIOBase = 0;
-
- PLXIOBase = card->cfg.reset_base;
- DivasIOBase = card->cfg.io_base;
-
- if(card->hw == NULL)
- {
- DPRINTF(("Divas: BRI PATCH (PLX chip) card->hw is null"));
- return;
- }
-
- if (PLXIOBase == 0)
- {
- DPRINTF(("Divas: BRI (PLX chip) cannot be patched. The BRI adapter may"));
- DPRINTF(("Divas: not function properly. If you do encounter problems,"));
- DPRINTF(("Divas: ensure that your machine is using the latest BIOS."));
- return;
- }
-
- DPRINTF(("Divas: PLX I/O Base 0x%x", PLXIOBase));
- DPRINTF(("Divas: Divas I/O Base 0x%x", DivasIOBase));
-
- if (PLXIOBase & 0x80)
- {
- dword dwSize, dwSerialNum, dwCmd;
- boolean_t bPLX9060;
- word wSerHi, wSerLo;
-
- DPRINTF(("Divas: Patch required"));
- dwCmd = 0;
- UxPciConfigWrite(card->hw, 4, PCI_COMMAND, &dwCmd);
-
- PLXIOBase &= ~0x80;
- UxPciConfigWrite(card->hw, 4, PCI_BADDR1, &PLXIOBase);
-
- dwSize = 0xFFFFFFFF;
- UxPciConfigWrite(card->hw, 4, PCI_BADDR1, &dwSize);
- UxPciConfigRead(card->hw, 4, PCI_BADDR1, &dwSize);
-
- dwSize = (~ (dwSize & ~7)) + 1;
-
- DivasIOBase = PLXIOBase + dwSize;
-
- card->cfg.reset_base = PLXIOBase;
- card->cfg.io_base = DivasIOBase;
- UxPciConfigWrite(card->hw, 4, PCI_BADDR1, &card->cfg.reset_base);
- UxPciConfigWrite(card->hw, 4, PCI_BADDR2, &card->cfg.io_base);
-
- dwCmd = 5;
- UxPciConfigWrite(card->hw, 4, PCI_COMMAND, &dwCmd);
-
- bPLX9060 = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x6C) |
- UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x6E);
-
- if (bPLX9060)
- {
- wSerHi = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x1E);
- wSerLo = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x22);
- dwSerialNum = (wSerHi << 16) | wSerLo;
- UxCardLog(0);
- }
- else
- {
- wSerHi = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x22);
- wSerLo = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x26);
- dwSerialNum = (wSerHi << 16) | wSerLo;
- UxCardLog(0);
- }
- }
- else
- {
- word wSerHi, wSerLo;
- boolean_t bPLX9060;
- dword dwSerialNum;
-
- DPRINTF(("divas: No patch required"));
-
- bPLX9060 = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x6C) |
- UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x6E);
-
- if (bPLX9060)
- {
- wSerHi = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x1E);
- wSerLo = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x22);
- dwSerialNum = (wSerHi << 16) | wSerLo;
- }
- else
- {
- wSerHi = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x22);
- wSerLo = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x26);
- dwSerialNum = (wSerHi << 16) | wSerLo;
- }
- }
- DPRINTF(("Divas: After patching:"));
- DPRINTF(("Divas: PLX I/O Base 0x%x", PLXIOBase));
- DPRINTF(("Divas: Divas I/O Base 0x%x", DivasIOBase));
-
-}
-
-#define TEST_INT_DIVAS_BRI 0x12
-static
-int diva_server_bri_test_int(card_t *card)
-{
- boolean_t bPLX9060 = FALSE;
- byte *PLXIOBase = NULL, *DivasIOBase = NULL;
-
- DPRINTF(("divas: test interrupt for Diva Server BRI card"));
-
- PLXIOBase = UxCardMemAttach(card->hw, PLX_IOBASE);
-
- bPLX9060 = UxCardPortIoInW(card->hw, PLXIOBase, 0x6C) || UxCardPortIoInW(card->hw, PLXIOBase, 0x6E);
-
- if (bPLX9060)
- { /* PLX9060 */
- UxCardPortIoOut(card->hw, PLXIOBase, 0x69, 0x09);
- }
- else
- { /* PLX9050 */
- UxCardPortIoOut(card->hw, PLXIOBase, 0x4C, 0x41);
- }
-
- card->test_int_pend = TEST_INT_DIVAS_BRI;
-
- UxCardMemDetach(card->hw, PLXIOBase);
-
- DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
-
- UxCardPortIoOut(card->hw, DivasIOBase, REG_IOCTRL, 0x89);
-
- UxCardMemDetach(card->hw, DivasIOBase);
-
- return 0;
-}
-
-static
-int diva_server_bri_mem_get(card_t *card, mem_block_t *mem_block)
-{
- dword user_addr = mem_block->addr;
- word length = 0;
- dword addr;
- word i;
- byte *DivasIOBase;
-
- DPRINTF(("divas: Retrieving memory from 0x%x", user_addr));
-
- DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
-
- addr = user_addr;
-
- for (i=0; i < (16 * 8); i++)
- {
- addr = user_addr + i;
-
- UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, addr >> 16);
- UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, (word) addr);
-
- mem_block->data[i] = UxCardPortIoIn(card->hw, DivasIOBase, REG_DATA);
- length++;
- }
-
- UxCardMemDetach(card->hw, DivasIOBase);
-
- return length;
-}
-
-int DivasBriInit(card_t *card, dia_card_t *cfg)
-{
- DPRINTF(("divas: initialise Diva Server BRI card"));
-
- if (DivasBRIInitPCI(card, cfg) == -1)
- {
- return -1;
- }
-
- card->card_reset = diva_server_bri_reset;
- card->card_start = diva_server_bri_start;
- card->card_load = diva_server_bri_load;
- card->card_config = diva_server_bri_config;
- card->reset_int = diva_server_bri_reset_int;
- card->card_mem_get = diva_server_bri_mem_get;
-
- card->xlog_offset = DIVAS_MAINT_OFFSET;
-
- card->out = DivasOut;
- card->test_int = DivasTestInt;
- card->dpc = DivasDpc;
- card->clear_int = DivasClearInt;
- card->card_isr = bri_ISR;
-
- card->a.ram_out = io_out;
- card->a.ram_outw = io_outw;
- card->a.ram_out_buffer = io_out_buffer;
- card->a.ram_inc = io_inc;
-
- card->a.ram_in = io_in;
- card->a.ram_inw = io_inw;
- card->a.ram_in_buffer = io_in_buffer;
- card->a.ram_look_ahead = io_look_ahead;
-
- return 0;
-}
-
-word GetProtFeatureValue(char *sw_id)
-{
- word features = 0;
-
- while ((*sw_id) && (sw_id[0] != '['))
- sw_id++;
-
- if (sw_id == NULL)
- {
- DPRINTF(("divas: no feature string present"));
- features = -1;
- }
- else
- {
- byte i, shifter;
-
- sw_id += 3;
-
- for (i=0, shifter=12; i<4; i++, shifter-=4)
- {
- if ((sw_id[i] >= '0') && (sw_id[i] <= '9'))
- {
- features |= (sw_id[i] - '0') << shifter;
- }
- else if ((sw_id[i] >= 'a') && (sw_id[i] <= 'f'))
- {
- features |= (sw_id[i] - 'a' + 10) << shifter;
- }
- else if ((sw_id[i] >= 'A') && (sw_id[i] <= 'F'))
- {
- features |= (sw_id[i] - 'A' + 10) << shifter;
- }
- else
- {
- DPRINTF(("divas: invalid feature string"));
- return -1;
- }
- }
- }
-
- return features;
-}
-
-
-int bri_ISR (card_t* card)
-{
- int served = 0;
- byte *DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
-
- if (UxCardPortIoIn (card->hw, DivasIOBase, M_PCI_RESET) & 0x01)
- {
- served = 1;
- card->int_pend += 1;
- DivasDpcSchedule(); /* ISR DPC */
- UxCardPortIoOut (card->hw, DivasIOBase, M_PCI_RESET, 0x08);
- }
-
- UxCardMemDetach(card->hw, DivasIOBase);
-
- return (served != 0);
-}
-
-
+++ /dev/null
-/*
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.15
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include "eicon.h"
-#include "sys.h"
-#include "idi.h"
-#include "constant.h"
-#include "divas.h"
-#include "pc.h"
-#include "pr_pc.h"
-
-#include "uxio.h"
-
-#define DIVAS_LOAD_CMD 0x02
-#define DIVAS_START_CMD 0x03
-#define DIVAS_IRQ_RESET 0xC18
-#define DIVAS_IRQ_RESET_VAL 0xFE
-
-#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 )
-{
- memset(table, 0, tablelength);
-
- if (tablelength > sizeof(DIDD_Table))
- tablelength = sizeof(DIDD_Table);
-
- if(tablelength % sizeof(DESCRIPTOR)) {
- tablelength /= sizeof(DESCRIPTOR);
- tablelength *= sizeof(DESCRIPTOR);
- }
-
- if (tablelength > 0)
- memcpy((void *)table, (void *)DIDD_Table, tablelength);
-
- return;
-}
-
-void DIVA_DIDD_Write(DESCRIPTOR *table, int tablelength)
-{
- if (tablelength > sizeof(DIDD_Table))
- tablelength = sizeof(DIDD_Table);
-
- memcpy((void *)DIDD_Table, (void *)table, tablelength);
-
- return;
-}
-
-static
-void init_idi_tab(void)
-{
- DESCRIPTOR d[32];
-
- memset(d, 0, 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;
- 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;
- }
-
- 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;
- }
-
- memset(card->e_tbl, 0, 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(unsigned long dummy)
-{
- card_t *card = DivasCards;
- int i = DivasCardNext;
-
- while(i--)
- {
- if (card->state == DIA_RUNNING)
- DivaDoCardDpc(card);
- card++;
- }
-}
-
-/*
- * 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;
-
- memset(card_list, 0, 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;
-}
-
+++ /dev/null
-/*
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.0
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-/*------------------------------------------------------------------*/
-/* Q.931 information elements maximum length */
-/* excluding the identifier, including the length field */
-/*------------------------------------------------------------------*/
-
-#define MAX_LEN_BC 13
-#define MAX_LEN_LLC 19 /* ctr3 */
-#define MAX_LEN_HLC 6 /* ctr3 */
-#define MAX_LEN_UUI 200 /* Hicom USBS req */
-#define MAX_LEN_NUM 24
-#define MAX_LEN_DSP 83 /* ctr3 */
-#define MAX_LEN_NI 4
-#define MAX_LEN_PI 5
-#define MAX_LEN_SIN 3
-#define MAX_LEN_CST 4
-#define MAX_LEN_SIG 2
-#define MAX_LEN_SPID 32
-#define MAX_LEN_EID 3
-#define MAX_LEN_CHI 35 /* ctr3 */
-#define MAX_LEN_CAU 33
-#define MAX_LEN_FTY 130
-#define MAX_LEN_KEY 83 /* ctr3 */
-#define MAX_LEN_RSI 4
-#define MAX_LEN_CAI 11
-#define MAX_NUM_SPID 4
-#define MAX_LEN_USERID 9
-#define MAX_LEN_APPLID 5
-#define MAX_LEN_NTTCIF 15
-
-/*------------------------------------------------------------------*/
-/* decision return values */
-/*------------------------------------------------------------------*/
-
-#define YES 1
-#define NO 0
-
-
-/*-------------------------------------------------------------------*/
-/* w element coding */
-/*-------------------------------------------------------------------*/
-
-#define NTTCIF 0x01
-#define BC 0x04
-#define CAU 0x08
-#define CAD 0x0c
-#define CAI 0x10
-#define CST 0x14
-#define CHI 0x18
-#define LLI 0x19
-#define CHA 0x1a
-#define FTY 0x1c
-#define PI 0x1e
-#define NFAC 0x20
-#define TC 0x24
-#define ATT_EID 0x26
-#define NI 0x27
-#define DSP 0x28
-#define DT 0x29
-#define KEY 0x2c
-#define KP 0x2c
-#define UID 0x2d
-#define SIG 0x34
-#define FI 0x39
-#define SPID 0x3a
-#define EID 0x3b
-#define DSPF 0x3c
-#define ECAD 0x4c
-#define OAD 0x6c
-#define OSA 0x6d
-#define DAD 0x70
-#define CPN 0x70
-#define DSA 0x71
-#define RDX 0x73
-#define RAD 0x74
-#define RDN 0x74
-#define RSI 0x79
-#define SCR 0x7A /* internal unscreened CPN */
-#define MIE 0x7a /* internal management info element */
-#define LLC 0x7c
-#define HLC 0x7d
-#define UUI 0x7e
-#define ESC 0x7f
-
-#define SHIFT 0x90
-#define MORE 0xa0
-#define CL 0xb0
-
-/* information elements used on the spid interface */
-#define SPID_CMD 0xc0
-#define SPID_LINK 0x10
-#define SPID_DN 0x70
-#define SPID_BC 0x04
-#define SPID_SWITCH 0x11
-
-/*------------------------------------------------------------------*/
-/* global configuration parameters, defined in exec.c */
-/* these parameters are configured with program loading */
-/*------------------------------------------------------------------*/
-
-#define PROT_1TR6 0
-#define PROT_ETSI 1
-#define PROT_FRANC 2
-#define PROT_BELG 3
-#define PROT_SWED 4
-#define PROT_NI 5
-#define PROT_5ESS 6
-#define PROT_JAPAN 7
-#define PROT_ATEL 8
-#define PROT_US 9
-#define PROT_ITALY 10
-#define PROT_TWAN 11
-#define PROT_AUSTRAL 12
-
-#define INIT_PROT_1TR6 0x80|PROT_1TR6
-#define INIT_PROT_ETSI 0x80|PROT_ETSI
-#define INIT_PROT_FRANC 0x80|PROT_FRANC
-#define INIT_PROT_BELG 0x80|PROT_BELG
-#define INIT_PROT_SWED 0x80|PROT_SWED
-#define INIT_PROT_NI 0x80|PROT_NI
-#define INIT_PROT_5ESS 0x80|PROT_5ESS
-#define INIT_PROT_JAPAN 0x80|PROT_JAPAN
-#define INIT_PROT_ATEL 0x80|PROT_ATEL
-#define INIT_PROT_ITALY 0x80|PROT_ITALY
-#define INIT_PROT_TWAN 0x80|PROT_TWAN
-#define INIT_PROT_AUSTRAL 0x80|PROT_AUSTRAL
-
-
-/* -----------------------------------------------------------**
-** The PROTOCOL_FEATURE_STRING in feature.h (included **
-** in prstart.sx and astart.sx) defines capabilities and **
-** features of the actual protocol code. It's used as a bit **
-** mask. **
-** The following Bits are defined: **
-** -----------------------------------------------------------*/
-
-#define PROTCAP_TELINDUS 0x0001 /* Telindus Variant of protocol code */
-#define PROTCAP_MANIF 0x0002 /* Management interface implemented */
-#define PROTCAP_V_42 0x0004 /* V42 implemented */
-#define PROTCAP_V90D 0x0008 /* V.90D (implies up to 384k DSP code) */
-#define PROTCAP_EXTD_FAX 0x0010 /* Extended FAX (ECM, 2D, T6, Polling) */
-#define PROTCAP_FREE4 0x0020 /* not used */
-#define PROTCAP_FREE5 0x0040 /* not used */
-#define PROTCAP_FREE6 0x0080 /* not used */
-#define PROTCAP_FREE7 0x0100 /* not used */
-#define PROTCAP_FREE8 0x0200 /* not used */
-#define PROTCAP_FREE9 0x0400 /* not used */
-#define PROTCAP_FREE10 0x0800 /* not used */
-#define PROTCAP_FREE11 0x1000 /* not used */
-#define PROTCAP_FREE12 0x2000 /* not used */
-#define PROTCAP_FREE13 0x4000 /* not used */
-#define PROTCAP_EXTENSION 0x8000 /* used for future extentions */
+++ /dev/null
-/*
- * Include file for defining the kernel logger messages
- * These definitions are shared between the klog driver and the
- * klogd daemon process
- *
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.0
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#if !defined(_KLOGMSG_H)
-#define _KLOGMSG_H
-
-/* define a type for a log entry */
-
-#define KLOG_TEXT_MSG (0)
-#define KLOG_XLOG_MSG (1)
-#define KLOG_XTXT_MSG (2)
-#define KLOG_IDI_REQ (4)
-#define KLOG_IDI_CALLBACK (5)
-#define KLOG_CAPI_MSG (6)
-
-typedef struct
-{
- unsigned long time_stamp; /* in ms since last system boot */
- int card; /* card number (-1 for all) */
- unsigned int type; /* type of log message (0 is text) */
- unsigned int length; /* message length (non-text messages only) */
- unsigned short code; /* message code (non-text messages only) */
- char buffer[110];/* text/data to log */
-} klog_t;
-
-void DivasLogAdd(void *buffer, int length);
-#endif /* of _KLOGMSG_H */
+++ /dev/null
-/*
- * External Diva Server driver include file
- *
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.5
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#if !defined(DIVAS_H)
-#define DIVAS_H
-
-#include "sys.h"
-
-
-/* IOCTL commands */
-
-#define DIA_IOCTL_INIT (0)
-#define DIA_IOCTL_LOAD (1)
-#define DIA_IOCTL_CONFIG (2)
-#define DIA_IOCTL_START (3)
-#define DIA_IOCTL_GET_NUM (4)
-#define DIA_IOCTL_GET_LIST (5)
-#define DIA_IOCTL_LOG (6)
-#define DIA_IOCTL_DETECT (7)
-#define DIA_IOCTL_SPACE (8)
-#define DIA_IOCTL_GET_MEM (9)
-#define DIA_IOCTL_FLAVOUR (10)
-#define DIA_IOCTL_XLOG_REQ (11)
-
-/* Error codes */
-
-#define XLOG_ERR_CARD_NUM (13)
-#define XLOG_ERR_DONE (14)
-#define XLOG_ERR_CMD (15)
-#define XLOG_ERR_TIMEOUT (16)
-#define XLOG_ERR_CARD_STATE (17)
-#define XLOG_ERR_UNKNOWN (18)
-#define XLOG_OK (0)
-
-/* Adapter states */
-
-#define DIA_UNKNOWN (0)
-#define DIA_RESET (1)
-#define DIA_LOADED (2)
-#define DIA_CONFIGURED (3)
-#define DIA_RUNNING (4)
-
-/* Stucture for getting card specific information from active cad driver */
-
-typedef struct
-{
- int card_type;
- int card_slot;
- int state;
-} dia_card_list_t;
-
-/* use following to select which logging to have active */
-
-#define DIVAS_LOG_DEBUG (1 << 0)
-#define DIVAS_LOG_XLOG (1 << 1)
-#define DIVAS_LOG_IDI (1 << 2)
-#define DIVAS_LOG_CAPI (1 << 3)
-
-/* stucture for DIA_IOCTL_LOG to get information from adapter */
-
-typedef struct
-{
- int card_id;
- int log_types; /* bit mask of log types: use DIVAS_LOG_XXX */
-} dia_log_t;
-
-/* list of cards supported by this driver */
-
-#define DIA_CARD_TYPE_DIVA_SERVER (0) /* Diva Server PRI */
-#define DIA_CARD_TYPE_DIVA_SERVER_B (1) /* Diva Server BRI */
-#define DIA_CARD_TYPE_DIVA_SERVER_Q (2) /* Diva Server 4-BRI */
-
-/* bus types */
-
-#define DIA_BUS_TYPE_ISA (0)
-#define DIA_BUS_TYPE_ISA_PNP (1)
-#define DIA_BUS_TYPE_PCI (2)
-#define DIA_BUS_TYPE_MCA (3)
-
-/* types of memory used (index for memory array below) */
-
-#define DIVAS_RAM_MEMORY 0
-#define DIVAS_REG_MEMORY 1
-#define DIVAS_CFG_MEMORY 2
-#define DIVAS_SHARED_MEMORY 3
-#define DIVAS_CTL_MEMORY 4
-/*
- * card config information
- * passed as parameter to DIA_IOCTL_INIT ioctl to initialise new card
- */
-
-typedef struct
-{
- int card_id; /* unique id assigned to this card */
- int card_type; /* use DIA_CARD_TYPE_xxx above */
- int bus_type; /* use DIA_BUS_TYPE_xxx above */
- struct pci_dev *pdev;
- int slot; /* slot number in bus */
- unsigned char irq; /* IRQ number */
- int reset_base; /* Reset register for I/O mapped cards */
- int io_base; /* I/O base for I/O mapped cards */
- void *memory[5]; /* memory base addresses for memory mapped cards */
- char name[9]; /* name of adapter */
- int serial; /* serial number */
- unsigned char int_priority; /* Interrupt priority */
-} dia_card_t;
-
-/*
- * protocol configuration information
- * passed as parameter to DIA_IOCTL_CONFIG ioctl to configure card
- */
-
-typedef struct
-{
- int card_id; /* to identify particular card */
- unsigned char tei;
- unsigned char nt2;
- unsigned char watchdog;
- unsigned char permanent;
- unsigned char x_interface;
- unsigned char stable_l2;
- unsigned char no_order_check;
- unsigned char handset_type;
- unsigned char sig_flags;
- unsigned char low_channel;
- unsigned char prot_version;
- unsigned char crc4;
- struct
- {
- unsigned char oad[32];
- unsigned char osa[32];
- unsigned char spid[32];
- }terminal[2];
-} dia_config_t;
-
-/*
- * code configuration
- * passed as parameter to DIA_IOCTL_LOAD ioctl
- * one of these ioctl per code file to load
- */
-
-typedef struct
-{
- int card_id; /* card to load */
- enum
- {
- DIA_CPU_CODE, /* CPU code */
- DIA_DSP_CODE, /* DSP code */
- DIA_CONT_CODE, /* continuation of code */
- DIA_TABLE_CODE, /* code table */
- DIA_DLOAD_CNT, /* number of downloads*/
- DIA_FPGA_CODE
- } code_type; /* code for CPU or DSP ? */
- int length; /* length of code */
- unsigned char *code; /* pointer (in user-space) to code */
-} dia_load_t;
-
-/*
- * start configuration
- * passed as parameter to DIA_IOCTL_START ioctl
- */
-
-typedef struct
-{
- int card_id; /* card to start */
-} dia_start_t;
-
-/* used for retrieving memory from the card */
-
-typedef struct {
- word card_id;
- dword addr;
- byte data[16 * 8];
-} mem_block_t;
-
-/* DIVA Server specific addresses */
-
-#define DIVAS_CPU_START_ADDR (0x0)
-#define ORG_MAX_PROTOCOL_CODE_SIZE 0x000A0000
-#define ORG_MAX_DSP_CODE_SIZE (0x000F0000 - ORG_MAX_PROTOCOL_CODE_SIZE)
-#define ORG_DSP_CODE_BASE (0xBF7F0000 - ORG_MAX_DSP_CODE_SIZE)
-#define DIVAS_DSP_START_ADDR (0xBF7A0000)
-#define DIVAS_SHARED_OFFSET (0x1000)
-#define MP_DSP_CODE_BASE 0xa03a0000
-#define MQ_PROTCODE_OFFSET 0x100000
-#define MQ_SM_OFFSET 0X0f0000
-
-#define V90D_MAX_PROTOCOL_CODE_SIZE 0x00090000
-#define V90D_MAX_DSP_CODE_SIZE (0x000F0000 - V90D_MAX_PROTOCOL_CODE_SIZE)
-#define V90D_DSP_CODE_BASE (0xBF7F0000 - V90D_MAX_DSP_CODE_SIZE)
-
-#define MQ_ORG_MAX_PROTOCOL_CODE_SIZE 0x000a0000 /* max 640K Protocol-Code */
-#define MQ_ORG_MAX_DSP_CODE_SIZE 0x00050000 /* max 320K DSP-Code */
-#define MQ_ORG_DSP_CODE_BASE (MQ_MAX_DSP_DOWNLOAD_ADDR \
- - MQ_ORG_MAX_DSP_CODE_SIZE)
-#define MQ_V90D_MAX_PROTOCOL_CODE_SIZE 0x00090000 /* max 576K Protocol-Code */
-#define MQ_V90D_MAX_DSP_CODE_SIZE 0x00060000 /* max 384K DSP-Code if V.90D included */
-#define MQ_MAX_DSP_DOWNLOAD_ADDR 0xa03f0000
-#define MQ_V90D_DSP_CODE_BASE (MQ_MAX_DSP_DOWNLOAD_ADDR \
- - MQ_V90D_MAX_DSP_CODE_SIZE)
-
-
-#define ALIGNMENT_MASK_MAESTRA 0xfffffffc
-
-#endif /* DIVAS_H */
+++ /dev/null
-/*
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.0
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#ifndef DSP_DEFS_H_
-#define DSP_DEFS_H_
-
-#ifndef DSPDIDS_H_
-#include "dspdids.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*---------------------------------------------------------------------------*/
-
-#ifndef NULL
-#define NULL 0
-#endif
-#ifndef TRUE
-#define TRUE (0 == 0)
-#endif
-#ifndef FALSE
-#define FALSE (0 != 0)
-#endif
-
-
-/*---------------------------------------------------------------------------*/
-
-#define DSP_MEMORY_TYPE_EXTERNAL_DM 0
-#define DSP_MEMORY_TYPE_EXTERNAL_PM 1
-#define DSP_MEMORY_TYPE_INTERNAL_DM 2
-#define DSP_MEMORY_TYPE_INTERNAL_PM 3
-
-#define DSP_DOWNLOAD_FLAG_BOOTABLE 0x0001
-#define DSP_DOWNLOAD_FLAG_2181 0x0002
-#define DSP_DOWNLOAD_FLAG_TIMECRITICAL 0x0004
-#define DSP_DOWNLOAD_FLAG_COMPAND 0x0008
-
-#define DSP_MEMORY_BLOCK_COUNT 16
-
-#define DSP_SEGMENT_PM_FLAG 0x0001
-#define DSP_SEGMENT_SHARED_FLAG 0x0002
-
-#define DSP_SEGMENT_EXTERNAL_DM DSP_MEMORY_TYPE_EXTERNAL_DM
-#define DSP_SEGMENT_EXTERNAL_PM DSP_MEMORY_TYPE_EXTERNAL_PM
-#define DSP_SEGMENT_INTERNAL_DM DSP_MEMORY_TYPE_INTERNAL_DM
-#define DSP_SEGMENT_INTERNAL_PM DSP_MEMORY_TYPE_INTERNAL_PM
-#define DSP_SEGMENT_FIRST_RELOCATABLE 4
-
-#define DSP_DATA_BLOCK_PM_FLAG 0x0001
-#define DSP_DATA_BLOCK_DWORD_FLAG 0x0002
-#define DSP_DATA_BLOCK_RESOLVE_FLAG 0x0004
-
-#define DSP_RELOC_NONE 0x00
-#define DSP_RELOC_SEGMENT_MASK 0x3f
-#define DSP_RELOC_TYPE_MASK 0xc0
-#define DSP_RELOC_TYPE_0 0x00 /* relocation of address in DM word / high part of PM word */
-#define DSP_RELOC_TYPE_1 0x40 /* relocation of address in low part of PM data word */
-#define DSP_RELOC_TYPE_2 0x80 /* relocation of address in standard command */
-#define DSP_RELOC_TYPE_3 0xc0 /* relocation of address in call/jump on flag in */
-
-#define DSP_COMBIFILE_FORMAT_IDENTIFICATION_SIZE 48
-#define DSP_COMBIFILE_FORMAT_VERSION_BCD 0x0100
-
-#define DSP_FILE_FORMAT_IDENTIFICATION_SIZE 48
-#define DSP_FILE_FORMAT_VERSION_BCD 0x0100
-
-
-typedef struct tag_dsp_combifile_header
-{
- char format_identification[DSP_COMBIFILE_FORMAT_IDENTIFICATION_SIZE];
- word format_version_bcd;
- word header_size;
- word combifile_description_size;
- word directory_entries;
- word directory_size;
- word download_count;
- word usage_mask_size;
-} t_dsp_combifile_header;
-
-typedef struct tag_dsp_combifile_directory_entry
-{
- word card_type_number;
- word file_set_number;
-} t_dsp_combifile_directory_entry;
-
-typedef struct tag_dsp_file_header
-{
- char format_identification[DSP_FILE_FORMAT_IDENTIFICATION_SIZE];
- word format_version_bcd;
- word download_id;
- word download_flags;
- word required_processing_power;
- word interface_channel_count;
- word header_size;
- word download_description_size;
- word memory_block_table_size;
- word memory_block_count;
- word segment_table_size;
- word segment_count;
- word symbol_table_size;
- word symbol_count;
- word total_data_size_dm;
- word data_block_count_dm;
- word total_data_size_pm;
- word data_block_count_pm;
-} t_dsp_file_header;
-
-typedef struct tag_dsp_memory_block_desc
-{
- word alias_memory_block;
- word memory_type;
- word address;
- word size; /* DSP words */
-} t_dsp_memory_block_desc;
-
-typedef struct tag_dsp_segment_desc
-{
- word memory_block;
- word attributes;
- word base;
- word size;
- word alignment; /* ==0 -> no other legal start address than base */
-} t_dsp_segment_desc;
-
-typedef struct tag_dsp_symbol_desc
-{
- word symbol_id;
- word segment;
- word offset;
- word size; /* DSP words */
-} t_dsp_symbol_desc;
-
-typedef struct tag_dsp_data_block_header
-{
- word attributes;
- word segment;
- word offset;
- word size; /* DSP words */
-} t_dsp_data_block_header;
-
-typedef struct tag_dsp_download_desc /* be sure to keep native alignment for MAESTRA's */
-{
- word download_id;
- word download_flags;
- word required_processing_power;
- word interface_channel_count;
- word excess_header_size;
- word memory_block_count;
- word segment_count;
- word symbol_count;
- word data_block_count_dm;
- word data_block_count_pm;
- byte *p_excess_header_data;
- char *p_download_description;
- t_dsp_memory_block_desc *p_memory_block_table;
- t_dsp_segment_desc *p_segment_table;
- t_dsp_symbol_desc *p_symbol_table;
- word *p_data_blocks_dm;
- word *p_data_blocks_pm;
-} t_dsp_download_desc;
-
-#define DSP_DOWNLOAD_INDEX_KERNEL 0
-#define DSP30TX_DOWNLOAD_INDEX_KERNEL 1
-#define DSP30RX_DOWNLOAD_INDEX_KERNEL 2
-#define DSP_MAX_DOWNLOAD_COUNT 35
-
-
-#define DSP_DOWNLOAD_MAX_SEGMENTS 16
-
-#define DSP_UDATA_REQUEST_RECONFIGURE 0
-/*
-parameters:
- <word> reconfigure delay (in 8kHz samples)
- <word> reconfigure code
- <byte> reconfigure hdlc preamble flags
-*/
-
-#define DSP_RECONFIGURE_TX_FLAG 0x8000
-#define DSP_RECONFIGURE_SHORT_TRAIN_FLAG 0x4000
-#define DSP_RECONFIGURE_ECHO_PROTECT_FLAG 0x2000
-#define DSP_RECONFIGURE_HDLC_FLAG 0x1000
-#define DSP_RECONFIGURE_SYNC_FLAG 0x0800
-#define DSP_RECONFIGURE_PROTOCOL_MASK 0x00ff
-#define DSP_RECONFIGURE_IDLE 0
-#define DSP_RECONFIGURE_V25 1
-#define DSP_RECONFIGURE_V21_CH2 2
-#define DSP_RECONFIGURE_V27_2400 3
-#define DSP_RECONFIGURE_V27_4800 4
-#define DSP_RECONFIGURE_V29_7200 5
-#define DSP_RECONFIGURE_V29_9600 6
-#define DSP_RECONFIGURE_V33_12000 7
-#define DSP_RECONFIGURE_V33_14400 8
-#define DSP_RECONFIGURE_V17_7200 9
-#define DSP_RECONFIGURE_V17_9600 10
-#define DSP_RECONFIGURE_V17_12000 11
-#define DSP_RECONFIGURE_V17_14400 12
-
-/*
-data indications if transparent framer
- <byte> data 0
- <byte> data 1
- ...
-
-data indications if HDLC framer
- <byte> data 0
- <byte> data 1
- ...
- <byte> CRC 0
- <byte> CRC 1
- <byte> preamble flags
-*/
-
-#define DSP_UDATA_INDICATION_SYNC 0
-/*
-returns:
- <word> time of sync (sampled from counter at 8kHz)
-*/
-
-#define DSP_UDATA_INDICATION_DCD_OFF 1
-/*
-returns:
- <word> time of DCD off (sampled from counter at 8kHz)
-*/
-
-#define DSP_UDATA_INDICATION_DCD_ON 2
-/*
-returns:
- <word> time of DCD on (sampled from counter at 8kHz)
- <byte> connected norm
- <word> connected options
- <dword> connected speed (bit/s)
-*/
-
-#define DSP_UDATA_INDICATION_CTS_OFF 3
-/*
-returns:
- <word> time of CTS off (sampled from counter at 8kHz)
-*/
-
-#define DSP_UDATA_INDICATION_CTS_ON 4
-/*
-returns:
- <word> time of CTS on (sampled from counter at 8kHz)
- <byte> connected norm
- <word> connected options
- <dword> connected speed (bit/s)
-*/
-
-#define DSP_CONNECTED_NORM_UNSPECIFIED 0
-#define DSP_CONNECTED_NORM_V21 1
-#define DSP_CONNECTED_NORM_V23 2
-#define DSP_CONNECTED_NORM_V22 3
-#define DSP_CONNECTED_NORM_V22_BIS 4
-#define DSP_CONNECTED_NORM_V32_BIS 5
-#define DSP_CONNECTED_NORM_V34 6
-#define DSP_CONNECTED_NORM_V8 7
-#define DSP_CONNECTED_NORM_BELL_212A 8
-#define DSP_CONNECTED_NORM_BELL_103 9
-#define DSP_CONNECTED_NORM_V29_LEASED_LINE 10
-#define DSP_CONNECTED_NORM_V33_LEASED_LINE 11
-#define DSP_CONNECTED_NORM_TFAST 12
-#define DSP_CONNECTED_NORM_V21_CH2 13
-#define DSP_CONNECTED_NORM_V27_TER 14
-#define DSP_CONNECTED_NORM_V29 15
-#define DSP_CONNECTED_NORM_V33 16
-#define DSP_CONNECTED_NORM_V17 17
-
-#define DSP_CONNECTED_OPTION_TRELLIS 0x0001
-
-
-/*---------------------------------------------------------------------------*/
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-/*---------------------------------------------------------------------------*/
+++ /dev/null
-/*
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.0
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#ifndef DSPDIDS_H_
-#define DSPDIDS_H_
-
-
-/*---------------------------------------------------------------------------*/
-
-#define DSP_DID_INVALID 0
-#define DSP_DID_DIVA 1
-#define DSP_DID_DIVA_PRO 2
-#define DSP_DID_DIVA_PRO_20 3
-#define DSP_DID_DIVA_PRO_PCCARD 4
-#define DSP_DID_DIVA_SERVER_BRI_1M 5
-#define DSP_DID_DIVA_SERVER_BRI_2M 6
-#define DSP_DID_DIVA_SERVER_PRI_2M_TX 7
-#define DSP_DID_DIVA_SERVER_PRI_2M_RX 8
-#define DSP_DID_DIVA_SERVER_PRI_30M 9
-#define DSP_DID_TASK_HSCX 100
-#define DSP_DID_TASK_HSCX_PRI_2M_TX 101
-#define DSP_DID_TASK_HSCX_PRI_2M_RX 102
-#define DSP_DID_TASK_V110KRNL 200
-#define DSP_DID_OVERLAY_V1100 201
-#define DSP_DID_OVERLAY_V1101 202
-#define DSP_DID_OVERLAY_V1102 203
-#define DSP_DID_OVERLAY_V1103 204
-#define DSP_DID_OVERLAY_V1104 205
-#define DSP_DID_OVERLAY_V1105 206
-#define DSP_DID_OVERLAY_V1106 207
-#define DSP_DID_OVERLAY_V1107 208
-#define DSP_DID_OVERLAY_V1108 209
-#define DSP_DID_OVERLAY_V1109 210
-#define DSP_DID_TASK_V110_PRI_2M_TX 220
-#define DSP_DID_TASK_V110_PRI_2M_RX 221
-#define DSP_DID_TASK_MODEM 300
-#define DSP_DID_TASK_FAX05 400
-#define DSP_DID_TASK_VOICE 500
-#define DSP_DID_TASK_TIKRNL81 600
-#define DSP_DID_OVERLAY_DIAL 601
-#define DSP_DID_OVERLAY_V22 602
-#define DSP_DID_OVERLAY_V32 603
-#define DSP_DID_OVERLAY_FSK 604
-#define DSP_DID_OVERLAY_FAX 605
-#define DSP_DID_OVERLAY_VXX 606
-#define DSP_DID_OVERLAY_V8 607
-#define DSP_DID_OVERLAY_INFO 608
-#define DSP_DID_OVERLAY_V34 609
-#define DSP_DID_OVERLAY_DFX 610
-#define DSP_DID_PARTIAL_OVERLAY_DIAL 611
-#define DSP_DID_PARTIAL_OVERLAY_FSK 612
-#define DSP_DID_PARTIAL_OVERLAY_FAX 613
-#define DSP_DID_TASK_TIKRNL05 700
-
-
-/*---------------------------------------------------------------------------*/
-
-#endif
-
-/*---------------------------------------------------------------------------*/
+++ /dev/null
-/* $Id: eicon.h,v 1.1.4.1.2.3 2002/10/01 11:29:13 armin Exp $
- *
- * ISDN low-level module for Eicon active ISDN-Cards.
- *
- * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de)
- * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
- * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#ifndef eicon_h
-#define eicon_h
-
-#include <linux/interrupt.h>
-
-#define EICON_IOCTL_SETMMIO 0
-#define EICON_IOCTL_GETMMIO 1
-#define EICON_IOCTL_SETIRQ 2
-#define EICON_IOCTL_GETIRQ 3
-#define EICON_IOCTL_LOADBOOT 4
-#define EICON_IOCTL_ADDCARD 5
-#define EICON_IOCTL_GETTYPE 6
-#define EICON_IOCTL_LOADPCI 7
-#define EICON_IOCTL_LOADISA 8
-#define EICON_IOCTL_GETVER 9
-#define EICON_IOCTL_GETXLOG 10
-
-#define EICON_IOCTL_MANIF 90
-
-#define EICON_IOCTL_FREEIT 97
-#define EICON_IOCTL_TEST 98
-#define EICON_IOCTL_DEBUGVAR 99
-
-#define EICON_IOCTL_DIA_OFFSET 100
-
-/* Bus types */
-#define EICON_BUS_ISA 1
-#define EICON_BUS_MCA 2
-#define EICON_BUS_PCI 3
-
-/* Constants for describing Card-Type */
-#define EICON_CTYPE_S 0
-#define EICON_CTYPE_SX 1
-#define EICON_CTYPE_SCOM 2
-#define EICON_CTYPE_QUADRO 3
-#define EICON_CTYPE_S2M 4
-#define EICON_CTYPE_MAESTRA 5
-#define EICON_CTYPE_MAESTRAQ 6
-#define EICON_CTYPE_MAESTRAQ_U 7
-#define EICON_CTYPE_MAESTRAP 8
-#define EICON_CTYPE_ISABRI 0x10
-#define EICON_CTYPE_ISAPRI 0x20
-#define EICON_CTYPE_MASK 0x0f
-#define EICON_CTYPE_QUADRO_NR(n) (n<<4)
-
-#define MAX_HEADER_LEN 10
-
-#define MAX_STATUS_BUFFER 150
-
-/* Struct for adding new cards */
-typedef struct eicon_cdef {
- int membase;
- int irq;
- char id[10];
-} eicon_cdef;
-
-#define EICON_ISA_BOOT_MEMCHK 1
-#define EICON_ISA_BOOT_NORMAL 2
-
-/* Struct for downloading protocol via ioctl for ISA cards */
-/* same struct for downloading protocol via ioctl for MCA cards */
-typedef struct {
- /* start-up parameters */
- unsigned char tei;
- unsigned char nt2;
- unsigned char skip1;
- unsigned char WatchDog;
- unsigned char Permanent;
- unsigned char XInterface;
- unsigned char StableL2;
- unsigned char NoOrderCheck;
- unsigned char HandsetType;
- unsigned char skip2;
- unsigned char LowChannel;
- unsigned char ProtVersion;
- unsigned char Crc4;
- unsigned char Loopback;
- unsigned char oad[32];
- unsigned char osa[32];
- unsigned char spid[32];
- unsigned char boot_opt;
- unsigned long bootstrap_len;
- unsigned long firmware_len;
- unsigned char code[1]; /* Rest (bootstrap- and firmware code) will be allocated */
-} eicon_isa_codebuf;
-
-/* Data for downloading protocol via ioctl */
-typedef union {
- eicon_isa_codebuf isa;
- eicon_isa_codebuf mca;
-} eicon_codebuf;
-
-/* Data for Management interface */
-typedef struct {
- int count;
- int pos;
- int length[50];
- unsigned char data[700];
-} eicon_manifbuf;
-
-#define TRACE_OK (1)
-
-#ifdef __KERNEL__
-
-/* Kernel includes */
-#include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/workqueue.h>
-#include <linux/interrupt.h>
-#include <linux/skbuff.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/major.h>
-#include <asm/io.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
-#include <linux/ioport.h>
-#include <linux/timer.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include <linux/ctype.h>
-#include <linux/pci.h>
-
-#include <linux/isdn.h>
-#include <linux/isdnif.h>
-
-
-typedef struct {
- __u16 length __attribute__ ((packed)); /* length of data/parameter field */
- __u8 P[1]; /* data/parameter field */
-} eicon_PBUFFER;
-
-#include "eicon_isa.h"
-
-#include "idi.h"
-
-typedef struct {
- __u16 NextReq __attribute__ ((packed)); /* pointer to next Req Buffer */
- __u16 NextRc __attribute__ ((packed)); /* pointer to next Rc Buffer */
- __u16 NextInd __attribute__ ((packed)); /* pointer to next Ind Buffer */
- __u8 ReqInput __attribute__ ((packed)); /* number of Req Buffers sent */
- __u8 ReqOutput __attribute__ ((packed)); /* number of Req Buffers returned */
- __u8 ReqReserved __attribute__ ((packed));/*number of Req Buffers reserved */
- __u8 Int __attribute__ ((packed)); /* ISDN-P interrupt */
- __u8 XLock __attribute__ ((packed)); /* Lock field for arbitration */
- __u8 RcOutput __attribute__ ((packed)); /* number of Rc buffers received */
- __u8 IndOutput __attribute__ ((packed)); /* number of Ind buffers received */
- __u8 IMask __attribute__ ((packed)); /* Interrupt Mask Flag */
- __u8 Reserved1[2] __attribute__ ((packed)); /* reserved field, do not use */
- __u8 ReadyInt __attribute__ ((packed)); /* request field for ready int */
- __u8 Reserved2[12] __attribute__ ((packed)); /* reserved field, do not use */
- __u8 InterfaceType __attribute__ ((packed)); /* interface type 1=16K */
- __u16 Signature __attribute__ ((packed)); /* ISDN-P initialized ind */
- __u8 B[1]; /* buffer space for Req,Ind and Rc */
-} eicon_pr_ram;
-
-/* Macro for delay via schedule() */
-#define SLEEP(j) { \
- set_current_state(TASK_UNINTERRUPTIBLE); \
- schedule_timeout(j); \
-}
-
-typedef struct {
- __u8 Req; /* pending request */
- __u8 Rc; /* return code received */
- __u8 Ind; /* indication received */
- __u8 ReqCh; /* channel of current Req */
- __u8 RcCh; /* channel of current Rc */
- __u8 IndCh; /* channel of current Ind */
- __u8 D3Id; /* ID used by this entity */
- __u8 B2Id; /* ID used by this entity */
- __u8 GlobalId; /* reserved field */
- __u8 XNum; /* number of X-buffers */
- __u8 RNum; /* number of R-buffers */
- struct sk_buff_head X; /* X-buffer queue */
- struct sk_buff_head R; /* R-buffer queue */
- __u8 RNR; /* receive not ready flag */
- __u8 complete; /* receive complete status */
- __u8 busy; /* busy flag */
- __u16 ref; /* saved reference */
-} entity;
-
-#define FAX_MAX_SCANLINE 256
-
-typedef struct {
- __u8 PrevObject;
- __u8 NextObject;
- __u8 abLine[FAX_MAX_SCANLINE];
- __u8 abFrame[FAX_MAX_SCANLINE];
- unsigned int LineLen;
- unsigned int LineDataLen;
- __u32 LineData;
- unsigned int NullBytesPos;
- __u8 NullByteExist;
- int PageCount;
- __u8 Dle;
- __u8 Eop;
-} eicon_ch_fax_buf;
-
-typedef struct {
- int No; /* Channel Number */
- unsigned short fsm_state; /* Current D-Channel state */
- unsigned short statectrl; /* State controling bits */
- unsigned short eazmask; /* EAZ-Mask for this Channel */
- int queued; /* User-Data Bytes in TX queue */
- int pqueued; /* User-Data Packets in TX queue */
- int waitq; /* User-Data Bytes in wait queue */
- int waitpq; /* User-Data Bytes in packet queue */
- struct sk_buff *tskb1; /* temp skb 1 */
- struct sk_buff *tskb2; /* temp skb 2 */
- unsigned char l2prot; /* Layer 2 protocol */
- unsigned char l3prot; /* Layer 3 protocol */
-#ifdef CONFIG_ISDN_TTY_FAX
- T30_s *fax; /* pointer to fax data in LL */
- eicon_ch_fax_buf fax2; /* fax related struct */
-#endif
- entity e; /* Native Entity */
- ENTITY de; /* Divas D Entity */
- ENTITY be; /* Divas B Entity */
- char cpn[32]; /* remember cpn */
- char oad[32]; /* remember oad */
- char dsa[32]; /* remember dsa */
- char osa[32]; /* remember osa */
- unsigned char cause[2]; /* Last Cause */
- unsigned char si1;
- unsigned char si2;
- unsigned char plan;
- unsigned char screen;
-} eicon_chan;
-
-typedef struct {
- eicon_chan *ptr;
-} eicon_chan_ptr;
-
-#include "eicon_pci.h"
-
-#define EICON_FLAGS_RUNNING 1 /* Cards driver activated */
-#define EICON_FLAGS_PVALID 2 /* Cards port is valid */
-#define EICON_FLAGS_IVALID 4 /* Cards irq is valid */
-#define EICON_FLAGS_MVALID 8 /* Cards membase is valid */
-#define EICON_FLAGS_LOADED 8 /* Firmware loaded */
-
-/* D-Channel states */
-#define EICON_STATE_NULL 0
-#define EICON_STATE_ICALL 1
-#define EICON_STATE_OCALL 2
-#define EICON_STATE_IWAIT 3
-#define EICON_STATE_OWAIT 4
-#define EICON_STATE_IBWAIT 5
-#define EICON_STATE_OBWAIT 6
-#define EICON_STATE_BWAIT 7
-#define EICON_STATE_BHWAIT 8
-#define EICON_STATE_BHWAIT2 9
-#define EICON_STATE_DHWAIT 10
-#define EICON_STATE_DHWAIT2 11
-#define EICON_STATE_BSETUP 12
-#define EICON_STATE_ACTIVE 13
-#define EICON_STATE_ICALLW 14
-#define EICON_STATE_LISTEN 15
-#define EICON_STATE_WMCONN 16
-
-#define EICON_MAX_QUEUE 2138
-
-typedef union {
- eicon_isa_card isa;
- eicon_pci_card pci;
- eicon_isa_card mca;
-} eicon_hwif;
-
-typedef struct {
- __u8 ret;
- __u8 id;
- __u8 ch;
-} eicon_ack;
-
-typedef struct {
- __u8 code;
- __u8 id;
- __u8 ch;
-} eicon_req;
-
-typedef struct {
- __u8 ret;
- __u8 id;
- __u8 ch;
- __u8 more;
-} eicon_indhdr;
-
-/*
- * Per card driver data
- */
-typedef struct eicon_card {
- eicon_hwif hwif; /* Hardware dependent interface */
- DESCRIPTOR *d; /* IDI Descriptor */
- u_char ptype; /* Protocol type (1TR6 or Euro) */
- u_char bus; /* Bustype (ISA, MCA, PCI) */
- u_char type; /* Cardtype (EICON_CTYPE_...) */
- struct eicon_card *qnext; /* Pointer to next quadro adapter */
- int Feature; /* Protocol Feature Value */
- struct eicon_card *next; /* Pointer to next device struct */
- int myid; /* Driver-Nr. assigned by linklevel */
- unsigned long flags; /* Statusflags */
- struct sk_buff_head rcvq; /* Receive-Message queue */
- struct sk_buff_head sndq; /* Send-Message queue */
- struct sk_buff_head rackq; /* Req-Ack-Message queue */
- struct sk_buff_head sackq; /* Data-Ack-Message queue */
- struct sk_buff_head statq; /* Status-Message queue */
- int statq_entries;
- struct tasklet_struct snd_tq; /* Task struct for xmit bh */
- struct tasklet_struct rcv_tq; /* Task struct for rcv bh */
- struct tasklet_struct ack_tq; /* Task struct for ack bh */
- eicon_chan* IdTable[256]; /* Table to find entity */
- __u16 ref_in;
- __u16 ref_out;
- int nchannels; /* Number of B-Channels */
- int ReadyInt; /* Ready Interrupt */
- eicon_chan *bch; /* B-Channel status/control */
- DBUFFER *dbuf; /* Dbuffer for Diva Server */
- BUFFERS *sbuf; /* Buffer for Diva Server */
- char *sbufp; /* Data Buffer for Diva Server */
- isdn_if interface; /* Interface to upper layer */
- char regname[35]; /* Drivers card name */
-#ifdef CONFIG_MCA
- int mca_slot; /* # of cards MCA slot */
- int mca_io; /* MCA cards IO port */
-#endif /* CONFIG_MCA */
-} eicon_card;
-
-#include "eicon_idi.h"
-
-extern eicon_card *cards;
-extern char *eicon_ctype_name[];
-
-
-extern __inline__ void eicon_schedule_tx(eicon_card *card)
-{
- tasklet_schedule(&card->snd_tq);
-}
-
-extern __inline__ void eicon_schedule_rx(eicon_card *card)
-{
- tasklet_schedule(&card->rcv_tq);
-}
-
-extern __inline__ void eicon_schedule_ack(eicon_card *card)
-{
- tasklet_schedule(&card->ack_tq);
-}
-
-extern int eicon_addcard(int, int, int, char *, int);
-extern void eicon_io_transmit(eicon_card *card);
-extern irqreturn_t eicon_irq(int irq, void *dev_id, struct pt_regs *regs);
-extern void eicon_io_rcv_dispatch(eicon_card *ccard);
-extern void eicon_io_ack_dispatch(eicon_card *ccard);
-#ifdef CONFIG_MCA
-extern int eicon_mca_find_card(int, int, int, char *);
-extern int eicon_mca_probe(int, int, int, int, char *);
-extern int eicon_info(char *, int , void *);
-#endif /* CONFIG_MCA */
-
-extern ulong DebugVar;
-extern void eicon_log(eicon_card * card, int level, const char *fmt, ...);
-extern void eicon_putstatus(eicon_card * card, char * buf);
-
-extern spinlock_t eicon_lock;
-
-#endif /* __KERNEL__ */
-
-#endif /* eicon_h */
+++ /dev/null
-/* $Id: eicon_dsp.h,v 1.1.4.1.2.2 2002/10/01 11:29:13 armin Exp $
- *
- * ISDN lowlevel-module for Eicon active cards.
- * DSP definitions
- *
- * Copyright 1999,2000 by Armin Schindler (mac@melware.de)
- * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#ifndef DSP_H
-#define DSP_H
-
-#include "dsp_defs.h"
-
-
-#define DSP_UDATA_REQUEST_SWITCH_FRAMER 1
-/*
-parameters:
- <byte> transmit framer type
- <byte> receive framer type
-*/
-
-#define DSP_REQUEST_SWITCH_FRAMER_HDLC 0
-#define DSP_REQUEST_SWITCH_FRAMER_TRANSPARENT 1
-#define DSP_REQUEST_SWITCH_FRAMER_ASYNC 2
-
-
-#define DSP_UDATA_REQUEST_CLEARDOWN 2
-/*
-parameters:
- - none -
-*/
-
-
-#define DSP_UDATA_REQUEST_TX_CONFIRMATION_ON 3
-/*
-parameters:
- - none -
-*/
-
-
-#define DSP_UDATA_REQUEST_TX_CONFIRMATION_OFF 4
-/*
-parameters:
- - none -
-*/
-
-typedef struct eicon_dsp_ind {
- __u16 time __attribute__ ((packed));
- __u8 norm __attribute__ ((packed));
- __u16 options __attribute__ ((packed));
- __u32 speed __attribute__ ((packed));
- __u16 delay __attribute__ ((packed));
- __u32 txspeed __attribute__ ((packed));
- __u32 rxspeed __attribute__ ((packed));
-} eicon_dsp_ind;
-
-#define DSP_CONNECTED_OPTION_V42_TRANS 0x0002
-#define DSP_CONNECTED_OPTION_V42_LAPM 0x0004
-#define DSP_CONNECTED_OPTION_SHORT_TRAIN 0x0008
-#define DSP_CONNECTED_OPTION_TALKER_ECHO_PROTECT 0x0010
-
-#define DSP_UDATA_INDICATION_DISCONNECT 5
-/*
-returns:
- <byte> cause
-*/
-
-#define DSP_DISCONNECT_CAUSE_NONE 0x00
-#define DSP_DISCONNECT_CAUSE_BUSY_TONE 0x01
-#define DSP_DISCONNECT_CAUSE_CONGESTION_TONE 0x02
-#define DSP_DISCONNECT_CAUSE_INCOMPATIBILITY 0x03
-#define DSP_DISCONNECT_CAUSE_CLEARDOWN 0x04
-#define DSP_DISCONNECT_CAUSE_TRAINING_TIMEOUT 0x05
-
-#define DSP_UDATA_INDICATION_TX_CONFIRMATION 6
-/*
-returns:
- <word> confirmation number
-*/
-
-
-#define DSP_UDATA_REQUEST_SEND_DTMF_DIGITS 16
-/*
-parameters:
- <word> tone duration (ms)
- <word> gap duration (ms)
- <byte> digit 0 tone code
- ...
- <byte> digit n tone code
-*/
-
-#define DSP_SEND_DTMF_DIGITS_HEADER_LENGTH 5
-
-#define DSP_DTMF_DIGIT_TONE_LOW_GROUP_697_HZ 0x00
-#define DSP_DTMF_DIGIT_TONE_LOW_GROUP_770_HZ 0x01
-#define DSP_DTMF_DIGIT_TONE_LOW_GROUP_852_HZ 0x02
-#define DSP_DTMF_DIGIT_TONE_LOW_GROUP_941_HZ 0x03
-#define DSP_DTMF_DIGIT_TONE_LOW_GROUP_MASK 0x03
-#define DSP_DTMF_DIGIT_TONE_HIGH_GROUP_1209_HZ 0x00
-#define DSP_DTMF_DIGIT_TONE_HIGH_GROUP_1336_HZ 0x04
-#define DSP_DTMF_DIGIT_TONE_HIGH_GROUP_1477_HZ 0x08
-#define DSP_DTMF_DIGIT_TONE_HIGH_GROUP_1633_HZ 0x0c
-#define DSP_DTMF_DIGIT_TONE_HIGH_GROUP_MASK 0x0c
-
-#define DSP_DTMF_DIGIT_TONE_CODE_0 0x07
-#define DSP_DTMF_DIGIT_TONE_CODE_1 0x00
-#define DSP_DTMF_DIGIT_TONE_CODE_2 0x04
-#define DSP_DTMF_DIGIT_TONE_CODE_3 0x08
-#define DSP_DTMF_DIGIT_TONE_CODE_4 0x01
-#define DSP_DTMF_DIGIT_TONE_CODE_5 0x05
-#define DSP_DTMF_DIGIT_TONE_CODE_6 0x09
-#define DSP_DTMF_DIGIT_TONE_CODE_7 0x02
-#define DSP_DTMF_DIGIT_TONE_CODE_8 0x06
-#define DSP_DTMF_DIGIT_TONE_CODE_9 0x0a
-#define DSP_DTMF_DIGIT_TONE_CODE_STAR 0x03
-#define DSP_DTMF_DIGIT_TONE_CODE_HASHMARK 0x0b
-#define DSP_DTMF_DIGIT_TONE_CODE_A 0x0c
-#define DSP_DTMF_DIGIT_TONE_CODE_B 0x0d
-#define DSP_DTMF_DIGIT_TONE_CODE_C 0x0e
-#define DSP_DTMF_DIGIT_TONE_CODE_D 0x0f
-
-
-#define DSP_UDATA_INDICATION_DTMF_DIGITS_SENT 16
-/*
-returns:
- - none -
- One indication will be sent for every request.
-*/
-
-
-#define DSP_UDATA_REQUEST_ENABLE_DTMF_RECEIVER 17
-/*
-parameters:
- <word> tone duration (ms)
- <word> gap duration (ms)
-*/
-typedef struct enable_dtmf_s {
- __u16 tone;
- __u16 gap;
-} enable_dtmf_s;
-
-#define DSP_UDATA_REQUEST_DISABLE_DTMF_RECEIVER 18
-/*
-parameters:
- - none -
-*/
-
-#define DSP_UDATA_INDICATION_DTMF_DIGITS_RECEIVED 17
-/*
-returns:
- <byte> digit 0 tone code
- ...
- <byte> digit n tone code
-*/
-
-#define DSP_DTMF_DIGITS_RECEIVED_HEADER_LENGTH 1
-
-
-#define DSP_UDATA_INDICATION_MODEM_CALLING_TONE 18
-/*
-returns:
- - none -
-*/
-
-#define DSP_UDATA_INDICATION_FAX_CALLING_TONE 19
-/*
-returns:
- - none -
-*/
-
-#define DSP_UDATA_INDICATION_ANSWER_TONE 20
-/*
-returns:
- - none -
-*/
-
-/* ============= FAX ================ */
-
-#define EICON_FAXID_LEN 20
-
-typedef struct eicon_t30_s {
- __u8 code;
- __u8 rate;
- __u8 resolution;
- __u8 format;
- __u8 pages_low;
- __u8 pages_high;
- __u8 atf;
- __u8 control_bits_low;
- __u8 control_bits_high;
- __u8 feature_bits_low;
- __u8 feature_bits_high;
- __u8 universal_5;
- __u8 universal_6;
- __u8 universal_7;
- __u8 station_id_len;
- __u8 head_line_len;
- __u8 station_id[EICON_FAXID_LEN];
-/* __u8 head_line[]; */
-} eicon_t30_s;
-
- /* EDATA transmit messages */
-#define EDATA_T30_DIS 0x01
-#define EDATA_T30_FTT 0x02
-#define EDATA_T30_MCF 0x03
-
- /* EDATA receive messages */
-#define EDATA_T30_DCS 0x81
-#define EDATA_T30_TRAIN_OK 0x82
-#define EDATA_T30_EOP 0x83
-#define EDATA_T30_MPS 0x84
-#define EDATA_T30_EOM 0x85
-#define EDATA_T30_DTC 0x86
-
-#define T30_FORMAT_SFF 0
-#define T30_FORMAT_ASCII 1
-#define T30_FORMAT_COUNT 2
-
-#define T30_CONTROL_BIT_DISABLE_FINE 0x0001
-#define T30_CONTROL_BIT_ENABLE_ECM 0x0002
-#define T30_CONTROL_BIT_ECM_64_BYTES 0x0004
-#define T30_CONTROL_BIT_ENABLE_2D_CODING 0x0008
-#define T30_CONTROL_BIT_ENABLE_T6_CODING 0x0010
-#define T30_CONTROL_BIT_ENABLE_UNCOMPR 0x0020
-#define T30_CONTROL_BIT_ACCEPT_POLLING 0x0040
-#define T30_CONTROL_BIT_REQUEST_POLLING 0x0080
-#define T30_CONTROL_BIT_MORE_DOCUMENTS 0x0100
-
-#define T30_CONTROL_BIT_ALL_FEATURES\
- (T30_CONTROL_BIT_ENABLE_ECM | T30_CONTROL_BIT_ENABLE_2D_CODING |\
- T30_CONTROL_BIT_ENABLE_T6_CODING | T30_CONTROL_BIT_ENABLE_UNCOMPR)
-
-#define T30_FEATURE_BIT_FINE 0x0001
-#define T30_FEATURE_BIT_ECM 0x0002
-#define T30_FEATURE_BIT_ECM_64_BYTES 0x0004
-#define T30_FEATURE_BIT_2D_CODING 0x0008
-#define T30_FEATURE_BIT_T6_CODING 0x0010
-#define T30_FEATURE_BIT_UNCOMPR_ENABLED 0x0020
-#define T30_FEATURE_BIT_POLLING 0x0040
-
-#define FAX_OBJECT_DOCU 1
-#define FAX_OBJECT_PAGE 2
-#define FAX_OBJECT_LINE 3
-
-#define T4_EOL 0x800
-#define T4_EOL_BITSIZE 12
-#define T4_EOL_DWORD (T4_EOL << (32 - T4_EOL_BITSIZE))
-#define T4_EOL_MASK_DWORD ((__u32) -1 << (32 - T4_EOL_BITSIZE))
-
-#define SFF_LEN_FLD_SIZE 3
-
-#define _DLE_ 0x10
-#define _ETX_ 0x03
-
-typedef struct eicon_sff_dochead {
- __u32 id __attribute__ ((packed));
- __u8 version __attribute__ ((packed));
- __u8 reserved1 __attribute__ ((packed));
- __u16 userinfo __attribute__ ((packed));
- __u16 pagecount __attribute__ ((packed));
- __u16 off1pagehead __attribute__ ((packed));
- __u32 offnpagehead __attribute__ ((packed));
- __u32 offdocend __attribute__ ((packed));
-} eicon_sff_dochead;
-
-typedef struct eicon_sff_pagehead {
- __u8 pageheadid __attribute__ ((packed));
- __u8 pageheadlen __attribute__ ((packed));
- __u8 resvert __attribute__ ((packed));
- __u8 reshoriz __attribute__ ((packed));
- __u8 coding __attribute__ ((packed));
- __u8 reserved2 __attribute__ ((packed));
- __u16 linelength __attribute__ ((packed));
- __u16 pagelength __attribute__ ((packed));
- __u32 offprevpage __attribute__ ((packed));
- __u32 offnextpage __attribute__ ((packed));
-} eicon_sff_pagehead;
-
-#endif /* DSP_H */
-
+++ /dev/null
-/* $Id: eicon_idi.c,v 1.1.4.1.2.4 2002/10/01 11:29:13 armin Exp $
- *
- * ISDN lowlevel-module for Eicon active cards.
- * IDI interface
- *
- * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
- * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
- *
- * Thanks to Deutsche Mailbox Saar-Lor-Lux GmbH
- * for sponsoring and testing fax
- * capabilities with Diva Server cards.
- * (dor@deutschemailbox.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/config.h>
-#include "eicon.h"
-#include "eicon_idi.h"
-#include "eicon_dsp.h"
-#include "uxio.h"
-
-#undef EICON_FULL_SERVICE_OKTETT
-
-char *eicon_idi_revision = "$Revision: 1.1.4.1.2.4 $";
-
-eicon_manifbuf *manbuf;
-
-int eicon_idi_manage_assign(eicon_card *card);
-int eicon_idi_manage_remove(eicon_card *card);
-int idi_fill_in_T30(eicon_chan *chan, unsigned char *buffer);
-
-int
-idi_assign_req(eicon_REQ *reqbuf, int signet, eicon_chan *chan)
-{
- int l = 0;
- int tmp;
-
- tmp = 0;
- if (!signet) {
- /* Signal Layer */
- reqbuf->XBuffer.P[l++] = CAI;
- reqbuf->XBuffer.P[l++] = 1;
- reqbuf->XBuffer.P[l++] = 0;
- reqbuf->XBuffer.P[l++] = KEY;
- reqbuf->XBuffer.P[l++] = 3;
- reqbuf->XBuffer.P[l++] = 'I';
- reqbuf->XBuffer.P[l++] = '4';
- reqbuf->XBuffer.P[l++] = 'L';
- reqbuf->XBuffer.P[l++] = SHIFT|6;
- reqbuf->XBuffer.P[l++] = SIN;
- reqbuf->XBuffer.P[l++] = 2;
- reqbuf->XBuffer.P[l++] = 0;
- reqbuf->XBuffer.P[l++] = 0;
- reqbuf->XBuffer.P[l++] = 0; /* end */
- reqbuf->Req = ASSIGN;
- reqbuf->ReqCh = 0;
- reqbuf->ReqId = DSIG_ID;
- reqbuf->XBuffer.length = l;
- reqbuf->Reference = 0; /* Sig Entity */
- }
- else {
- /* Network Layer */
- reqbuf->XBuffer.P[l++] = CAI;
- reqbuf->XBuffer.P[l++] = 1;
- reqbuf->XBuffer.P[l++] = chan->e.D3Id;
- reqbuf->XBuffer.P[l++] = LLC;
- reqbuf->XBuffer.P[l++] = 2;
- switch(chan->l2prot) {
- case ISDN_PROTO_L2_V11096:
- case ISDN_PROTO_L2_V11019:
- case ISDN_PROTO_L2_V11038:
- case ISDN_PROTO_L2_TRANS:
- reqbuf->XBuffer.P[l++] = 2; /* transparent */
- break;
- case ISDN_PROTO_L2_X75I:
- case ISDN_PROTO_L2_X75UI:
- case ISDN_PROTO_L2_X75BUI:
- reqbuf->XBuffer.P[l++] = 5; /* X.75 */
- break;
- case ISDN_PROTO_L2_MODEM:
- if (chan->fsm_state == EICON_STATE_IWAIT)
- reqbuf->XBuffer.P[l++] = 9; /* V.42 incoming */
- else
- reqbuf->XBuffer.P[l++] = 10; /* V.42 */
- break;
- case ISDN_PROTO_L2_HDLC:
- case ISDN_PROTO_L2_FAX:
- if (chan->fsm_state == EICON_STATE_IWAIT)
- reqbuf->XBuffer.P[l++] = 3; /* autoconnect on incoming */
- else
- reqbuf->XBuffer.P[l++] = 2; /* transparent */
- break;
- default:
- reqbuf->XBuffer.P[l++] = 1;
- }
- switch(chan->l3prot) {
- case ISDN_PROTO_L3_FCLASS2:
-#ifdef CONFIG_ISDN_TTY_FAX
- reqbuf->XBuffer.P[l++] = 6;
- reqbuf->XBuffer.P[l++] = NLC;
- tmp = idi_fill_in_T30(chan, &reqbuf->XBuffer.P[l+1]);
- reqbuf->XBuffer.P[l++] = tmp;
- l += tmp;
- break;
-#endif
- case ISDN_PROTO_L3_TRANS:
- default:
- reqbuf->XBuffer.P[l++] = 4;
- }
- reqbuf->XBuffer.P[l++] = 0; /* end */
- reqbuf->Req = ASSIGN;
- reqbuf->ReqCh = 0;
- reqbuf->ReqId = NL_ID;
- reqbuf->XBuffer.length = l;
- reqbuf->Reference = 1; /* Net Entity */
- }
- return(0);
-}
-
-int
-idi_put_req(eicon_REQ *reqbuf, int rq, int signet, int Ch)
-{
- reqbuf->Req = rq;
- reqbuf->ReqCh = Ch;
- reqbuf->ReqId = 1;
- reqbuf->XBuffer.length = 1;
- reqbuf->XBuffer.P[0] = 0;
- reqbuf->Reference = signet;
- return(0);
-}
-
-int
-idi_put_suspend_req(eicon_REQ *reqbuf, eicon_chan *chan)
-{
- reqbuf->Req = SUSPEND;
- reqbuf->ReqCh = 0;
- reqbuf->ReqId = 1;
- reqbuf->XBuffer.P[0] = CAI;
- reqbuf->XBuffer.P[1] = 1;
- reqbuf->XBuffer.P[2] = chan->No;
- reqbuf->XBuffer.P[3] = 0;
- reqbuf->XBuffer.length = 4;
- reqbuf->Reference = 0; /* Sig Entity */
- return(0);
-}
-
-int
-idi_call_res_req(eicon_REQ *reqbuf, eicon_chan *chan)
-{
- int l = 9;
- reqbuf->Req = CALL_RES;
- reqbuf->ReqCh = 0;
- reqbuf->ReqId = 1;
- reqbuf->XBuffer.P[0] = CAI;
- reqbuf->XBuffer.P[1] = 6;
- reqbuf->XBuffer.P[2] = 9;
- reqbuf->XBuffer.P[3] = 0;
- reqbuf->XBuffer.P[4] = 0;
- reqbuf->XBuffer.P[5] = 0;
- reqbuf->XBuffer.P[6] = 32;
- reqbuf->XBuffer.P[7] = 0;
- switch(chan->l2prot) {
- case ISDN_PROTO_L2_X75I:
- case ISDN_PROTO_L2_X75UI:
- case ISDN_PROTO_L2_X75BUI:
- case ISDN_PROTO_L2_HDLC:
- reqbuf->XBuffer.P[1] = 1;
- reqbuf->XBuffer.P[2] = 0x05;
- l = 4;
- break;
- case ISDN_PROTO_L2_V11096:
- reqbuf->XBuffer.P[2] = 0x0d;
- reqbuf->XBuffer.P[3] = 5;
- reqbuf->XBuffer.P[4] = 0;
- break;
- case ISDN_PROTO_L2_V11019:
- reqbuf->XBuffer.P[2] = 0x0d;
- reqbuf->XBuffer.P[3] = 6;
- reqbuf->XBuffer.P[4] = 0;
- break;
- case ISDN_PROTO_L2_V11038:
- reqbuf->XBuffer.P[2] = 0x0d;
- reqbuf->XBuffer.P[3] = 7;
- reqbuf->XBuffer.P[4] = 0;
- break;
- case ISDN_PROTO_L2_MODEM:
- reqbuf->XBuffer.P[2] = 0x11;
- reqbuf->XBuffer.P[3] = 7;
- reqbuf->XBuffer.P[4] = 0;
- reqbuf->XBuffer.P[5] = 0;
- reqbuf->XBuffer.P[6] = 128;
- reqbuf->XBuffer.P[7] = 0;
- break;
- case ISDN_PROTO_L2_FAX:
- reqbuf->XBuffer.P[2] = 0x10;
- reqbuf->XBuffer.P[3] = 0;
- reqbuf->XBuffer.P[4] = 0;
- reqbuf->XBuffer.P[5] = 0;
- reqbuf->XBuffer.P[6] = 128;
- reqbuf->XBuffer.P[7] = 0;
- break;
- case ISDN_PROTO_L2_TRANS:
- switch(chan->l3prot) {
- case ISDN_PROTO_L3_TRANSDSP:
- reqbuf->XBuffer.P[2] = 22; /* DTMF, audio events on */
- }
- break;
- }
- reqbuf->XBuffer.P[8] = 0;
- reqbuf->XBuffer.length = l;
- reqbuf->Reference = 0; /* Sig Entity */
- eicon_log(NULL, 8, "idi_req: Ch%d: Call_Res\n", chan->No);
- return(0);
-}
-
-int
-idi_do_req(eicon_card *card, eicon_chan *chan, int cmd, int layer)
-{
- struct sk_buff *skb;
- struct sk_buff *skb2;
- eicon_REQ *reqbuf;
- eicon_chan_ptr *chan2;
-
- skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
- skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
-
- if ((!skb) || (!skb2)) {
- eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in do_req()\n", chan->No);
- if (skb)
- dev_kfree_skb(skb);
- if (skb2)
- dev_kfree_skb(skb2);
- return -ENOMEM;
- }
-
- chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
- chan2->ptr = chan;
-
- reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
- eicon_log(card, 8, "idi_req: Ch%d: req %x (%s)\n", chan->No, cmd, (layer)?"Net":"Sig");
- if (layer) cmd |= 0x700;
- switch(cmd) {
- case ASSIGN:
- case ASSIGN|0x700:
- idi_assign_req(reqbuf, layer, chan);
- break;
- case REMOVE:
- case REMOVE|0x700:
- idi_put_req(reqbuf, REMOVE, layer, 0);
- break;
- case INDICATE_REQ:
- idi_put_req(reqbuf, INDICATE_REQ, 0, 0);
- break;
- case HANGUP:
- idi_put_req(reqbuf, HANGUP, 0, 0);
- break;
- case SUSPEND:
- idi_put_suspend_req(reqbuf, chan);
- break;
- case RESUME:
- idi_put_req(reqbuf, RESUME, 0 ,0);
- break;
- case REJECT:
- idi_put_req(reqbuf, REJECT, 0 ,0);
- break;
- case CALL_ALERT:
- idi_put_req(reqbuf, CALL_ALERT, 0, 0);
- break;
- case CALL_RES:
- idi_call_res_req(reqbuf, chan);
- break;
- case CALL_HOLD:
- idi_put_req(reqbuf, CALL_HOLD, 0, 0);
- break;
- case N_CONNECT|0x700:
- idi_put_req(reqbuf, N_CONNECT, 1, 0);
- break;
- case N_CONNECT_ACK|0x700:
- idi_put_req(reqbuf, N_CONNECT_ACK, 1, 0);
- break;
- case N_DISC|0x700:
- idi_put_req(reqbuf, N_DISC, 1, chan->e.IndCh);
- break;
- case N_DISC_ACK|0x700:
- idi_put_req(reqbuf, N_DISC_ACK, 1, chan->e.IndCh);
- break;
- default:
- eicon_log(card, 1, "idi_req: Ch%d: Unknown request\n", chan->No);
- dev_kfree_skb(skb);
- dev_kfree_skb(skb2);
- return(-1);
- }
-
- skb_queue_tail(&chan->e.X, skb);
- skb_queue_tail(&card->sndq, skb2);
- eicon_schedule_tx(card);
- return(0);
-}
-
-int
-eicon_idi_listen_req(eicon_card *card, eicon_chan *chan)
-{
- if ((!card) || (!chan))
- return 1;
-
- eicon_log(card, 16, "idi_req: Ch%d: Listen_Req eazmask=0x%x\n",chan->No, chan->eazmask);
- if (!chan->e.D3Id) {
- idi_do_req(card, chan, ASSIGN, 0);
- }
- if (chan->fsm_state == EICON_STATE_NULL) {
- if (!(chan->statectrl & HAVE_CONN_REQ)) {
- idi_do_req(card, chan, INDICATE_REQ, 0);
- chan->fsm_state = EICON_STATE_LISTEN;
- }
- }
- return(0);
-}
-
-unsigned char
-idi_si2bc(int si1, int si2, char *bc, char *hlc)
-{
- hlc[0] = 0;
- switch(si1) {
- case 1:
- bc[0] = 0x90; /* 3,1 kHz audio */
- bc[1] = 0x90; /* 64 kbit/s */
- bc[2] = 0xa3; /* G.711 A-law */
-#ifdef EICON_FULL_SERVICE_OKTETT
- if (si2 == 1) {
- bc[0] = 0x80; /* Speech */
- hlc[0] = 0x02; /* hlc len */
- hlc[1] = 0x91; /* first hic */
- hlc[2] = 0x81; /* Telephony */
- }
-#endif
- return(3);
- case 2:
- bc[0] = 0x90; /* 3,1 kHz audio */
- bc[1] = 0x90; /* 64 kbit/s */
- bc[2] = 0xa3; /* G.711 A-law */
-#ifdef EICON_FULL_SERVICE_OKTETT
- if (si2 == 2) {
- hlc[0] = 0x02; /* hlc len */
- hlc[1] = 0x91; /* first hic */
- hlc[2] = 0x84; /* Fax Gr.2/3 */
- }
-#endif
- return(3);
- case 5:
- case 7:
- default:
- bc[0] = 0x88;
- bc[1] = 0x90;
- return(2);
- }
- return (0);
-}
-
-int
-idi_hangup(eicon_card *card, eicon_chan *chan)
-{
- if ((!card) || (!chan))
- return 1;
-
- if ((chan->fsm_state == EICON_STATE_ACTIVE) ||
- (chan->fsm_state == EICON_STATE_WMCONN)) {
- if (chan->e.B2Id) idi_do_req(card, chan, N_DISC, 1);
- }
- if (chan->e.B2Id) idi_do_req(card, chan, REMOVE, 1);
- if (chan->fsm_state != EICON_STATE_NULL) {
- chan->statectrl |= WAITING_FOR_HANGUP;
- idi_do_req(card, chan, HANGUP, 0);
- chan->fsm_state = EICON_STATE_NULL;
- }
- eicon_log(card, 8, "idi_req: Ch%d: Hangup\n", chan->No);
-#ifdef CONFIG_ISDN_TTY_FAX
- chan->fax = 0;
-#endif
- return(0);
-}
-
-int
-capipmsg(eicon_card *card, eicon_chan *chan, capi_msg *cm)
-{
- if ((cm->para[0] != 3) || (cm->para[1] != 0))
- return -1;
- if (cm->para[2] < 3)
- return -1;
- if (cm->para[4] != 0)
- return -1;
- switch(cm->para[3]) {
- case 4: /* Suspend */
- eicon_log(card, 8, "idi_req: Ch%d: Call Suspend\n", chan->No);
- if (cm->para[5]) {
- idi_do_req(card, chan, SUSPEND, 0);
- } else {
- idi_do_req(card, chan, CALL_HOLD, 0);
- }
- break;
- case 5: /* Resume */
- eicon_log(card, 8, "idi_req: Ch%d: Call Resume\n", chan->No);
- idi_do_req(card, chan, RESUME, 0);
- break;
- }
- return 0;
-}
-
-int
-idi_connect_res(eicon_card *card, eicon_chan *chan)
-{
- if ((!card) || (!chan))
- return 1;
-
- chan->fsm_state = EICON_STATE_IWAIT;
-
- /* check if old NetID has been removed */
- if (chan->e.B2Id) {
- eicon_log(card, 1, "eicon: Ch%d: old net_id %x still exist, removing.\n",
- chan->No, chan->e.B2Id);
- idi_do_req(card, chan, REMOVE, 1);
- }
-
- idi_do_req(card, chan, ASSIGN, 1);
- idi_do_req(card, chan, CALL_RES, 0);
- return(0);
-}
-
-int
-idi_connect_req(eicon_card *card, eicon_chan *chan, char *phone,
- char *eazmsn, int si1, int si2)
-{
- int l = 0;
- int i;
- unsigned char tmp;
- unsigned char *sub, *sp;
- unsigned char bc[5];
- unsigned char hlc[5];
- struct sk_buff *skb;
- struct sk_buff *skb2;
- eicon_REQ *reqbuf;
- eicon_chan_ptr *chan2;
-
- if ((!card) || (!chan))
- return 1;
-
- skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
- skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
-
- if ((!skb) || (!skb2)) {
- eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in connect_req()\n", chan->No);
- if (skb)
- dev_kfree_skb(skb);
- if (skb2)
- dev_kfree_skb(skb2);
- return -ENOMEM;
- }
-
- chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
- chan2->ptr = chan;
-
- reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
- reqbuf->Req = CALL_REQ;
- reqbuf->ReqCh = 0;
- reqbuf->ReqId = 1;
-
- sub = NULL;
- sp = phone;
- while (*sp) {
- if (*sp == '.') {
- sub = sp + 1;
- *sp = 0;
- } else
- sp++;
- }
- reqbuf->XBuffer.P[l++] = CPN;
- reqbuf->XBuffer.P[l++] = strlen(phone) + 1;
- reqbuf->XBuffer.P[l++] = 0x81;
- for(i=0; i<strlen(phone);i++)
- reqbuf->XBuffer.P[l++] = phone[i] & 0x7f;
- if (sub) {
- reqbuf->XBuffer.P[l++] = DSA;
- reqbuf->XBuffer.P[l++] = strlen(sub) + 2;
- reqbuf->XBuffer.P[l++] = 0x80; /* NSAP coded */
- reqbuf->XBuffer.P[l++] = 0x50; /* local IDI format */
- while (*sub)
- reqbuf->XBuffer.P[l++] = *sub++ & 0x7f;
- }
-
- sub = NULL;
- sp = eazmsn;
- while (*sp) {
- if (*sp == '.') {
- sub = sp + 1;
- *sp = 0;
- } else
- sp++;
- }
- reqbuf->XBuffer.P[l++] = OAD;
- reqbuf->XBuffer.P[l++] = strlen(eazmsn) + 2;
- reqbuf->XBuffer.P[l++] = 0x01;
- reqbuf->XBuffer.P[l++] = 0x80;
- for(i=0; i<strlen(eazmsn);i++)
- reqbuf->XBuffer.P[l++] = eazmsn[i] & 0x7f;
- if (sub) {
- reqbuf->XBuffer.P[l++] = OSA;
- reqbuf->XBuffer.P[l++] = strlen(sub) + 2;
- reqbuf->XBuffer.P[l++] = 0x80; /* NSAP coded */
- reqbuf->XBuffer.P[l++] = 0x50; /* local IDI format */
- while (*sub)
- reqbuf->XBuffer.P[l++] = *sub++ & 0x7f;
- }
-
- if (si2 > 2) {
- reqbuf->XBuffer.P[l++] = SHIFT|6;
- reqbuf->XBuffer.P[l++] = SIN;
- reqbuf->XBuffer.P[l++] = 2;
- reqbuf->XBuffer.P[l++] = si1;
- reqbuf->XBuffer.P[l++] = si2;
- }
- else if ((tmp = idi_si2bc(si1, si2, bc, hlc)) > 0) {
- reqbuf->XBuffer.P[l++] = BC;
- reqbuf->XBuffer.P[l++] = tmp;
- for(i=0; i<tmp;i++)
- reqbuf->XBuffer.P[l++] = bc[i];
- if ((tmp=hlc[0])) {
- reqbuf->XBuffer.P[l++] = HLC;
- reqbuf->XBuffer.P[l++] = tmp;
- for(i=1; i<=tmp;i++)
- reqbuf->XBuffer.P[l++] = hlc[i];
- }
- }
-
- reqbuf->XBuffer.P[l++] = CAI;
- reqbuf->XBuffer.P[l++] = 6;
- reqbuf->XBuffer.P[l++] = 0x09;
- reqbuf->XBuffer.P[l++] = 0;
- reqbuf->XBuffer.P[l++] = 0;
- reqbuf->XBuffer.P[l++] = 0;
- reqbuf->XBuffer.P[l++] = 32;
- reqbuf->XBuffer.P[l++] = 0;
- switch(chan->l2prot) {
- case ISDN_PROTO_L2_X75I:
- case ISDN_PROTO_L2_X75UI:
- case ISDN_PROTO_L2_X75BUI:
- case ISDN_PROTO_L2_HDLC:
- reqbuf->XBuffer.P[l-6] = 5;
- reqbuf->XBuffer.P[l-7] = 1;
- l -= 5;
- break;
- case ISDN_PROTO_L2_V11096:
- reqbuf->XBuffer.P[l-7] = 3;
- reqbuf->XBuffer.P[l-6] = 0x0d;
- reqbuf->XBuffer.P[l-5] = 5;
- reqbuf->XBuffer.P[l-4] = 0;
- l -= 3;
- break;
- case ISDN_PROTO_L2_V11019:
- reqbuf->XBuffer.P[l-7] = 3;
- reqbuf->XBuffer.P[l-6] = 0x0d;
- reqbuf->XBuffer.P[l-5] = 6;
- reqbuf->XBuffer.P[l-4] = 0;
- l -= 3;
- break;
- case ISDN_PROTO_L2_V11038:
- reqbuf->XBuffer.P[l-7] = 3;
- reqbuf->XBuffer.P[l-6] = 0x0d;
- reqbuf->XBuffer.P[l-5] = 7;
- reqbuf->XBuffer.P[l-4] = 0;
- l -= 3;
- break;
- case ISDN_PROTO_L2_MODEM:
- reqbuf->XBuffer.P[l-6] = 0x11;
- reqbuf->XBuffer.P[l-5] = 7;
- reqbuf->XBuffer.P[l-4] = 0;
- reqbuf->XBuffer.P[l-3] = 0;
- reqbuf->XBuffer.P[l-2] = 128;
- reqbuf->XBuffer.P[l-1] = 0;
- break;
- case ISDN_PROTO_L2_FAX:
- reqbuf->XBuffer.P[l-6] = 0x10;
- reqbuf->XBuffer.P[l-5] = 0;
- reqbuf->XBuffer.P[l-4] = 0;
- reqbuf->XBuffer.P[l-3] = 0;
- reqbuf->XBuffer.P[l-2] = 128;
- reqbuf->XBuffer.P[l-1] = 0;
- break;
- case ISDN_PROTO_L2_TRANS:
- switch(chan->l3prot) {
- case ISDN_PROTO_L3_TRANSDSP:
- reqbuf->XBuffer.P[l-6] = 22; /* DTMF, audio events on */
- }
- break;
- }
-
- reqbuf->XBuffer.P[l++] = 0; /* end */
- reqbuf->XBuffer.length = l;
- reqbuf->Reference = 0; /* Sig Entity */
-
- if (chan->statectrl & WAITING_FOR_HANGUP) {
- /* If the line did not disconnect yet,
- we have to delay this command */
- eicon_log(card, 32, "idi_req: Ch%d: delaying conn_req\n", chan->No);
- chan->statectrl |= HAVE_CONN_REQ;
- chan->tskb1 = skb;
- chan->tskb2 = skb2;
- } else {
- skb_queue_tail(&chan->e.X, skb);
- skb_queue_tail(&card->sndq, skb2);
- eicon_schedule_tx(card);
- }
-
- eicon_log(card, 8, "idi_req: Ch%d: Conn_Req %s -> %s\n",chan->No, eazmsn, phone);
- return(0);
-}
-
-
-void
-idi_IndParse(eicon_card *ccard, eicon_chan *chan, idi_ind_message *message, unsigned char *buffer, int len)
-{
- int i,j;
- int pos = 0;
- int codeset = 0;
- int wlen = 0;
- int lock = 0;
- __u8 w;
- __u16 code;
- isdn_ctrl cmd;
-
- memset(message, 0, sizeof(idi_ind_message));
-
- if ((!len) || (!buffer[pos])) return;
-
- while(pos <= len) {
- w = buffer[pos++];
- if (!w) return;
- if (w & 0x80) {
- wlen = 0;
- }
- else {
- wlen = buffer[pos++];
- }
-
- if (pos > len) return;
-
- if (lock & 0x80) lock &= 0x7f;
- else codeset = lock;
-
- if((w&0xf0) == SHIFT) {
- codeset = w;
- if(!(codeset & 0x08)) lock = codeset & 7;
- codeset &= 7;
- lock |= 0x80;
- }
- else {
- if (w==ESC && wlen >=2) {
- code = buffer[pos++]|0x800;
- wlen--;
- }
- else code = w;
- code |= (codeset<<8);
-
- if (pos + wlen > len) {
- eicon_log(ccard, 1, "idi_err: Ch%d: IElen %d of %x exceeds Ind_Length (+%d)\n", chan->No,
- wlen, code, (pos + wlen) - len);
- return;
- }
-
- switch(code) {
- case OAD:
- if (wlen > sizeof(message->oad)) {
- pos += wlen;
- break;
- }
- j = 1;
- if (wlen) {
- message->plan = buffer[pos++];
- if (message->plan &0x80)
- message->screen = 0;
- else {
- message->screen = buffer[pos++];
- j = 2;
- }
- }
- for(i=0; i < wlen-j; i++)
- message->oad[i] = buffer[pos++];
- eicon_log(ccard, 2, "idi_inf: Ch%d: OAD=(0x%02x,0x%02x) %s\n", chan->No,
- message->plan, message->screen, message->oad);
- break;
- case RDN:
- if (wlen > sizeof(message->rdn)) {
- pos += wlen;
- break;
- }
- j = 1;
- if (wlen) {
- if (!(buffer[pos++] & 0x80)) {
- pos++;
- j = 2;
- }
- }
- for(i=0; i < wlen-j; i++)
- message->rdn[i] = buffer[pos++];
- eicon_log(ccard, 2, "idi_inf: Ch%d: RDN= %s\n", chan->No,
- message->rdn);
- break;
- case CPN:
- if (wlen > sizeof(message->cpn)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->cpn[i] = buffer[pos++];
- eicon_log(ccard, 2, "idi_inf: Ch%d: CPN=(0x%02x) %s\n", chan->No,
- (__u8)message->cpn[0], message->cpn + 1);
- break;
- case DSA:
- if (wlen > sizeof(message->dsa)) {
- pos += wlen;
- break;
- }
- pos += 2;
- for(i=0; i < wlen-2; i++)
- message->dsa[i] = buffer[pos++];
- eicon_log(ccard, 2, "idi_inf: Ch%d: DSA=%s\n", chan->No, message->dsa);
- break;
- case OSA:
- if (wlen > sizeof(message->osa)) {
- pos += wlen;
- break;
- }
- pos += 2;
- for(i=0; i < wlen-2; i++)
- message->osa[i] = buffer[pos++];
- eicon_log(ccard, 2, "idi_inf: Ch%d: OSA=%s\n", chan->No, message->osa);
- break;
- case CAD:
- pos += wlen;
- eicon_log(ccard, 2, "idi_inf: Ch%d: Connected Address in ind, len:%x\n",
- chan->No, wlen);
- break;
- case BC:
- if (wlen > sizeof(message->bc)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->bc[i] = buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: BC = 0x%02x 0x%02x 0x%02x\n", chan->No,
- message->bc[0],message->bc[1],message->bc[2]);
- break;
- case 0x800|BC:
- if (wlen > sizeof(message->e_bc)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->e_bc[i] = buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: ESC/BC=%d\n", chan->No, message->bc[0]);
- break;
- case LLC:
- if (wlen > sizeof(message->llc)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->llc[i] = buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: LLC=%d %d %d %d ...\n", chan->No, message->llc[0],
- message->llc[1],message->llc[2],message->llc[3]);
- break;
- case HLC:
- if (wlen > sizeof(message->hlc)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->hlc[i] = buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: HLC=%x %x %x %x %x ...\n", chan->No,
- message->hlc[0], message->hlc[1],
- message->hlc[2], message->hlc[3], message->hlc[4]);
- break;
- case DSP:
- case 0x600|DSP:
- if (wlen > sizeof(message->display)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->display[i] = buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: Display: %s\n", chan->No,
- message->display);
- break;
- case 0x600|KEY:
- if (wlen > sizeof(message->keypad)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->keypad[i] = buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: Keypad: %s\n", chan->No,
- message->keypad);
- break;
- case NI:
- case 0x600|NI:
- if (wlen) {
- switch(buffer[pos] & 127) {
- case 0:
- eicon_log(ccard, 4, "idi_inf: Ch%d: User suspended.\n", chan->No);
- break;
- case 1:
- eicon_log(ccard, 4, "idi_inf: Ch%d: User resumed.\n", chan->No);
- break;
- case 2:
- eicon_log(ccard, 4, "idi_inf: Ch%d: Bearer service change.\n", chan->No);
- break;
- default:
- eicon_log(ccard, 4, "idi_inf: Ch%d: Unknown Notification %x.\n",
- chan->No, buffer[pos] & 127);
- }
- pos += wlen;
- }
- break;
- case PI:
- case 0x600|PI:
- if (wlen > 1) {
- switch(buffer[pos+1] & 127) {
- case 1:
- eicon_log(ccard, 4, "idi_inf: Ch%d: Call is not end-to-end ISDN.\n", chan->No);
- break;
- case 2:
- eicon_log(ccard, 4, "idi_inf: Ch%d: Destination address is non ISDN.\n", chan->No);
- break;
- case 3:
- eicon_log(ccard, 4, "idi_inf: Ch%d: Origination address is non ISDN.\n", chan->No);
- break;
- case 4:
- eicon_log(ccard, 4, "idi_inf: Ch%d: Call has returned to the ISDN.\n", chan->No);
- break;
- case 5:
- eicon_log(ccard, 4, "idi_inf: Ch%d: Interworking has occurred.\n", chan->No);
- break;
- case 8:
- eicon_log(ccard, 4, "idi_inf: Ch%d: In-band information available.\n", chan->No);
- break;
- default:
- eicon_log(ccard, 4, "idi_inf: Ch%d: Unknown Progress %x.\n",
- chan->No, buffer[pos+1] & 127);
- }
- }
- pos += wlen;
- break;
- case CAU:
- if (wlen > sizeof(message->cau)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->cau[i] = buffer[pos++];
- memcpy(&chan->cause, &message->cau, 2);
- eicon_log(ccard, 4, "idi_inf: Ch%d: CAU=%d %d\n", chan->No,
- message->cau[0],message->cau[1]);
- break;
- case 0x800|CAU:
- if (wlen > sizeof(message->e_cau)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->e_cau[i] = buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: ECAU=%d %d\n", chan->No,
- message->e_cau[0],message->e_cau[1]);
- break;
- case 0x800|CHI:
- if (wlen > sizeof(message->e_chi)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->e_chi[i] = buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: ESC/CHI=%d\n", chan->No,
- message->e_cau[0]);
- break;
- case 0x800|0x7a:
- pos ++;
- message->e_mt=buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: EMT=0x%x\n", chan->No, message->e_mt);
- break;
- case DT:
- if (wlen > sizeof(message->dt)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->dt[i] = buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: DT: %02d.%02d.%02d %02d:%02d:%02d\n", chan->No,
- message->dt[2], message->dt[1], message->dt[0],
- message->dt[3], message->dt[4], message->dt[5]);
- break;
- case 0x600|SIN:
- if (wlen > sizeof(message->sin)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->sin[i] = buffer[pos++];
- eicon_log(ccard, 2, "idi_inf: Ch%d: SIN=%d %d\n", chan->No,
- message->sin[0],message->sin[1]);
- break;
- case 0x600|CPS:
- eicon_log(ccard, 2, "idi_inf: Ch%d: Called Party Status in ind\n", chan->No);
- pos += wlen;
- break;
- case 0x600|CIF:
- for (i = 0; i < wlen; i++)
- if (buffer[pos + i] != '0') break;
- memcpy(&cmd.parm.num, &buffer[pos + i], wlen - i);
- cmd.parm.num[wlen - i] = 0;
- eicon_log(ccard, 2, "idi_inf: Ch%d: CIF=%s\n", chan->No, cmd.parm.num);
- pos += wlen;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_CINF;
- cmd.arg = chan->No;
- ccard->interface.statcallb(&cmd);
- break;
- case 0x600|DATE:
- eicon_log(ccard, 2, "idi_inf: Ch%d: Date in ind\n", chan->No);
- pos += wlen;
- break;
- case 0xa1:
- eicon_log(ccard, 2, "idi_inf: Ch%d: Sending Complete in ind.\n", chan->No);
- pos += wlen;
- break;
- case 0xe08:
- case 0xe7a:
- case 0xe04:
- case 0xe00:
- /* *** TODO *** */
- case CHA:
- /* Charge advice */
- case FTY:
- case 0x600|FTY:
- case CHI:
- case 0x800:
- /* Not yet interested in this */
- pos += wlen;
- break;
- case 0x880:
- /* Managment Information Element */
- if (!manbuf) {
- eicon_log(ccard, 1, "idi_err: manbuf not allocated\n");
- }
- else {
- memcpy(&manbuf->data[manbuf->pos], &buffer[pos], wlen);
- manbuf->length[manbuf->count] = wlen;
- manbuf->count++;
- manbuf->pos += wlen;
- }
- pos += wlen;
- break;
- default:
- pos += wlen;
- eicon_log(ccard, 6, "idi_inf: Ch%d: unknown information element 0x%x in ind, len:%x\n",
- chan->No, code, wlen);
- }
- }
- }
-}
-
-void
-idi_bc2si(unsigned char *bc, unsigned char *hlc, unsigned char *sin, unsigned char *si1, unsigned char *si2)
-{
- si1[0] = 0;
- si2[0] = 0;
-
- switch (bc[0] & 0x7f) {
- case 0x00: /* Speech */
- si1[0] = 1;
-#ifdef EICON_FULL_SERVICE_OKTETT
- si1[0] = sin[0];
- si2[0] = sin[1];
-#endif
- break;
- case 0x10: /* 3.1 Khz audio */
- si1[0] = 1;
-#ifdef EICON_FULL_SERVICE_OKTETT
- si1[0] = sin[0];
- si2[0] = sin[1];
-#endif
- break;
- case 0x08: /* Unrestricted digital information */
- si1[0] = 7;
- si2[0] = sin[1];
- break;
- case 0x09: /* Restricted digital information */
- si1[0] = 2;
- break;
- case 0x11:
- /* Unrestr. digital information with
- * tones/announcements ( or 7 kHz audio
- */
- si1[0] = 3;
- break;
- case 0x18: /* Video */
- si1[0] = 4;
- break;
- }
- switch (bc[1] & 0x7f) {
- case 0x40: /* packed mode */
- si1[0] = 8;
- break;
- case 0x10: /* 64 kbit */
- case 0x11: /* 2*64 kbit */
- case 0x13: /* 384 kbit */
- case 0x15: /* 1536 kbit */
- case 0x17: /* 1920 kbit */
- /* moderate = bc[1] & 0x7f; */
- break;
- }
-}
-
-/********************* FAX stuff ***************************/
-
-#ifdef CONFIG_ISDN_TTY_FAX
-
-int
-idi_fill_in_T30(eicon_chan *chan, unsigned char *buffer)
-{
- eicon_t30_s *t30 = (eicon_t30_s *) buffer;
-
- if (!chan->fax) {
- eicon_log(NULL, 1,"idi_T30: fill_in with NULL fax struct, ERROR\n");
- return 0;
- }
- memset(t30, 0, sizeof(eicon_t30_s));
- t30->station_id_len = EICON_FAXID_LEN;
- memcpy(&t30->station_id[0], &chan->fax->id[0], EICON_FAXID_LEN);
- t30->resolution = chan->fax->resolution;
- t30->rate = chan->fax->rate + 1; /* eicon rate starts with 1 */
- t30->format = T30_FORMAT_SFF;
- t30->pages_low = 0;
- t30->pages_high = 0;
- t30->atf = 1; /* optimised for AT+F command set */
- t30->code = 0;
- t30->feature_bits_low = 0;
- t30->feature_bits_high = 0;
- t30->control_bits_low = 0;
- t30->control_bits_high = 0;
-
- if (chan->fax->nbc) {
- /* set compression by DCC value */
- switch(chan->fax->compression) {
- case (0): /* 1-D modified */
- break;
- case (1): /* 2-D modified Read */
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING;
- t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING;
- break;
- case (2): /* 2-D uncompressed */
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_UNCOMPR;
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING;
- t30->feature_bits_low |= T30_FEATURE_BIT_UNCOMPR_ENABLED;
- t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING;
- break;
- case (3): /* 2-D modified Read */
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_T6_CODING;
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING;
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_UNCOMPR;
- t30->feature_bits_low |= T30_FEATURE_BIT_UNCOMPR_ENABLED;
- t30->feature_bits_low |= T30_FEATURE_BIT_T6_CODING;
- t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING;
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM;
- t30->feature_bits_low |= T30_FEATURE_BIT_ECM;
- break;
- }
- } else {
- /* set compression to best */
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_T6_CODING;
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING;
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_UNCOMPR;
- t30->feature_bits_low |= T30_FEATURE_BIT_UNCOMPR_ENABLED;
- t30->feature_bits_low |= T30_FEATURE_BIT_T6_CODING;
- t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING;
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM;
- t30->feature_bits_low |= T30_FEATURE_BIT_ECM;
- }
- switch(chan->fax->ecm) {
- case (0): /* disable ECM */
- break;
- case (1):
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM;
- t30->control_bits_low |= T30_CONTROL_BIT_ECM_64_BYTES;
- t30->feature_bits_low |= T30_FEATURE_BIT_ECM;
- t30->feature_bits_low |= T30_FEATURE_BIT_ECM_64_BYTES;
- break;
- case (2):
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM;
- t30->feature_bits_low |= T30_FEATURE_BIT_ECM;
- break;
- }
-
- if (DebugVar & 128) {
- char st[40];
- eicon_log(NULL, 128, "sT30:code = %x\n", t30->code);
- eicon_log(NULL, 128, "sT30:rate = %x\n", t30->rate);
- eicon_log(NULL, 128, "sT30:res = %x\n", t30->resolution);
- eicon_log(NULL, 128, "sT30:format = %x\n", t30->format);
- eicon_log(NULL, 128, "sT30:pages_low = %x\n", t30->pages_low);
- eicon_log(NULL, 128, "sT30:pages_high = %x\n", t30->pages_high);
- eicon_log(NULL, 128, "sT30:atf = %x\n", t30->atf);
- eicon_log(NULL, 128, "sT30:control_bits_low = %x\n", t30->control_bits_low);
- eicon_log(NULL, 128, "sT30:control_bits_high = %x\n", t30->control_bits_high);
- eicon_log(NULL, 128, "sT30:feature_bits_low = %x\n", t30->feature_bits_low);
- eicon_log(NULL, 128, "sT30:feature_bits_high = %x\n", t30->feature_bits_high);
- //eicon_log(NULL, 128, "sT30:universal_5 = %x\n", t30->universal_5);
- //eicon_log(NULL, 128, "sT30:universal_6 = %x\n", t30->universal_6);
- //eicon_log(NULL, 128, "sT30:universal_7 = %x\n", t30->universal_7);
- eicon_log(NULL, 128, "sT30:station_id_len = %x\n", t30->station_id_len);
- eicon_log(NULL, 128, "sT30:head_line_len = %x\n", t30->head_line_len);
- strlcpy(st, t30->station_id, t30->station_id_len + 1);
- eicon_log(NULL, 128, "sT30:station_id = <%s>\n", st);
- }
- return(sizeof(eicon_t30_s));
-}
-
-/* send fax struct */
-int
-idi_send_edata(eicon_card *card, eicon_chan *chan)
-{
- struct sk_buff *skb;
- struct sk_buff *skb2;
- eicon_REQ *reqbuf;
- eicon_chan_ptr *chan2;
-
- if ((chan->fsm_state == EICON_STATE_NULL) || (chan->fsm_state == EICON_STATE_LISTEN)) {
- eicon_log(card, 1, "idi_snd: Ch%d: send edata on state %d !\n", chan->No, chan->fsm_state);
- return -ENODEV;
- }
- eicon_log(card, 128, "idi_snd: Ch%d: edata (fax)\n", chan->No);
-
- skb = alloc_skb(sizeof(eicon_REQ) + sizeof(eicon_t30_s), GFP_ATOMIC);
- skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
-
- if ((!skb) || (!skb2)) {
- eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in send_edata()\n", chan->No);
- if (skb)
- dev_kfree_skb(skb);
- if (skb2)
- dev_kfree_skb(skb2);
- return -ENOMEM;
- }
-
- chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
- chan2->ptr = chan;
-
- reqbuf = (eicon_REQ *)skb_put(skb, sizeof(eicon_t30_s) + sizeof(eicon_REQ));
-
- reqbuf->Req = N_EDATA;
- reqbuf->ReqCh = chan->e.IndCh;
- reqbuf->ReqId = 1;
-
- reqbuf->XBuffer.length = idi_fill_in_T30(chan, reqbuf->XBuffer.P);
- reqbuf->Reference = 1; /* Net Entity */
-
- skb_queue_tail(&chan->e.X, skb);
- skb_queue_tail(&card->sndq, skb2);
- eicon_schedule_tx(card);
- return (0);
-}
-
-void
-idi_parse_edata(eicon_card *ccard, eicon_chan *chan, unsigned char *buffer, int len)
-{
- eicon_t30_s *p = (eicon_t30_s *)buffer;
- int i;
-
- if (DebugVar & 128) {
- char st[40];
- eicon_log(ccard, 128, "rT30:len %d , size %d\n", len, sizeof(eicon_t30_s));
- eicon_log(ccard, 128, "rT30:code = %x\n", p->code);
- eicon_log(ccard, 128, "rT30:rate = %x\n", p->rate);
- eicon_log(ccard, 128, "rT30:res = %x\n", p->resolution);
- eicon_log(ccard, 128, "rT30:format = %x\n", p->format);
- eicon_log(ccard, 128, "rT30:pages_low = %x\n", p->pages_low);
- eicon_log(ccard, 128, "rT30:pages_high = %x\n", p->pages_high);
- eicon_log(ccard, 128, "rT30:atf = %x\n", p->atf);
- eicon_log(ccard, 128, "rT30:control_bits_low = %x\n", p->control_bits_low);
- eicon_log(ccard, 128, "rT30:control_bits_high = %x\n", p->control_bits_high);
- eicon_log(ccard, 128, "rT30:feature_bits_low = %x\n", p->feature_bits_low);
- eicon_log(ccard, 128, "rT30:feature_bits_high = %x\n", p->feature_bits_high);
- //eicon_log(ccard, 128, "rT30:universal_5 = %x\n", p->universal_5);
- //eicon_log(ccard, 128, "rT30:universal_6 = %x\n", p->universal_6);
- //eicon_log(ccard, 128, "rT30:universal_7 = %x\n", p->universal_7);
- eicon_log(ccard, 128, "rT30:station_id_len = %x\n", p->station_id_len);
- eicon_log(ccard, 128, "rT30:head_line_len = %x\n", p->head_line_len);
- strlcpy(st, p->station_id, p->station_id_len + 1);
- eicon_log(ccard, 128, "rT30:station_id = <%s>\n", st);
- }
- if (!chan->fax) {
- eicon_log(ccard, 1, "idi_edata: parse to NULL fax struct, ERROR\n");
- return;
- }
- chan->fax->code = p->code;
- i = (p->station_id_len < FAXIDLEN) ? p->station_id_len : (FAXIDLEN - 1);
- memcpy(chan->fax->r_id, p->station_id, i);
- chan->fax->r_id[i] = 0;
- chan->fax->r_resolution = p->resolution;
- chan->fax->r_rate = p->rate - 1;
- chan->fax->r_binary = 0; /* no binary support */
- chan->fax->r_width = 0;
- chan->fax->r_length = 2;
- chan->fax->r_scantime = 0;
- chan->fax->r_compression = 0;
- chan->fax->r_ecm = 0;
- if (p->feature_bits_low & T30_FEATURE_BIT_2D_CODING) {
- chan->fax->r_compression = 1;
- if (p->feature_bits_low & T30_FEATURE_BIT_UNCOMPR_ENABLED) {
- chan->fax->r_compression = 2;
- }
- }
- if (p->feature_bits_low & T30_FEATURE_BIT_T6_CODING) {
- chan->fax->r_compression = 3;
- }
-
- if (p->feature_bits_low & T30_FEATURE_BIT_ECM) {
- chan->fax->r_ecm = 2;
- if (p->feature_bits_low & T30_FEATURE_BIT_ECM_64_BYTES)
- chan->fax->r_ecm = 1;
- }
-}
-
-void
-idi_fax_send_header(eicon_card *card, eicon_chan *chan, int header)
-{
- static __u16 wd2sff[] = {
- 1728, 2048, 2432, 1216, 864
- };
- static __u16 ln2sff[2][3] = {
- { 1143, 1401, 0 } , { 2287, 2802, 0 }
- };
- struct sk_buff *skb;
- eicon_sff_dochead *doc;
- eicon_sff_pagehead *page;
- u_char *docp;
-
- if (!chan->fax) {
- eicon_log(card, 1, "idi_fax: send head with NULL fax struct, ERROR\n");
- return;
- }
- if (header == 2) { /* DocHeader + PageHeader */
- skb = alloc_skb(sizeof(eicon_sff_dochead) + sizeof(eicon_sff_pagehead), GFP_ATOMIC);
- } else {
- skb = alloc_skb(sizeof(eicon_sff_pagehead), GFP_ATOMIC);
- }
- if (!skb) {
- eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in fax_send_header()\n", chan->No);
- return;
- }
-
- if (header == 2) { /* DocHeader + PageHeader */
- docp = skb_put(skb, sizeof(eicon_sff_dochead) + sizeof(eicon_sff_pagehead));
- doc = (eicon_sff_dochead *) docp;
- page = (eicon_sff_pagehead *) (docp + sizeof(eicon_sff_dochead));
- memset(docp, 0,sizeof(eicon_sff_dochead) + sizeof(eicon_sff_pagehead));
- doc->id = 0x66666653;
- doc->version = 0x01;
- doc->off1pagehead = sizeof(eicon_sff_dochead);
- } else {
- page = (eicon_sff_pagehead *)skb_put(skb, sizeof(eicon_sff_pagehead));
- memset(page, 0, sizeof(eicon_sff_pagehead));
- }
-
- switch(header) {
- case 1: /* PageHeaderEnd */
- page->pageheadid = 254;
- page->pageheadlen = 0;
- break;
- case 0: /* PageHeader */
- case 2: /* DocHeader + PageHeader */
- page->pageheadid = 254;
- page->pageheadlen = sizeof(eicon_sff_pagehead) - 2;
- page->resvert = chan->fax->resolution;
- page->reshoriz = 0; /* always 203 dpi */
- page->coding = 0; /* always 1D */
- page->linelength = wd2sff[chan->fax->width];
- page->pagelength = ln2sff[chan->fax->resolution][chan->fax->length];
- eicon_log(card, 128, "sSFF-Head: linelength = %d\n", page->linelength);
- eicon_log(card, 128, "sSFF-Head: pagelength = %d\n", page->pagelength);
- break;
- }
- idi_send_data(card, chan, 0, skb, 0, 0);
-}
-
-void
-idi_fax_cmd(eicon_card *card, eicon_chan *chan)
-{
- isdn_ctrl cmd;
-
- if ((!card) || (!chan))
- return;
-
- if (!chan->fax) {
- eicon_log(card, 1, "idi_fax: cmd with NULL fax struct, ERROR\n");
- return;
- }
- switch (chan->fax->code) {
- case ISDN_TTY_FAX_DT:
- if (chan->fax->phase == ISDN_FAX_PHASE_B) {
- idi_send_edata(card, chan);
- break;
- }
- if (chan->fax->phase == ISDN_FAX_PHASE_D) {
- idi_send_edata(card, chan);
- break;
- }
- break;
-
- case ISDN_TTY_FAX_DR:
- if (chan->fax->phase == ISDN_FAX_PHASE_B) {
- idi_send_edata(card, chan);
-
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_CFR;
- card->interface.statcallb(&cmd);
-
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_RID;
- card->interface.statcallb(&cmd);
-
- /* telling 1-D compression */
- chan->fax->r_compression = 0;
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_DCS;
- card->interface.statcallb(&cmd);
-
- chan->fax2.NextObject = FAX_OBJECT_DOCU;
- chan->fax2.PrevObject = FAX_OBJECT_DOCU;
-
- break;
- }
- if (chan->fax->phase == ISDN_FAX_PHASE_D) {
- idi_send_edata(card, chan);
- break;
- }
- break;
-
- case ISDN_TTY_FAX_ET:
- switch(chan->fax->fet) {
- case 0:
- case 1:
- idi_fax_send_header(card, chan, 0);
- break;
- case 2:
- idi_fax_send_header(card, chan, 1);
- break;
- }
- break;
- }
-}
-
-void
-idi_edata_rcveop(eicon_card *card, eicon_chan *chan)
-{
- isdn_ctrl cmd;
-
- if (!chan->fax) {
- eicon_log(card, 1, "idi_edata: rcveop with NULL fax struct, ERROR\n");
- return;
- }
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_ET;
- card->interface.statcallb(&cmd);
-}
-
-void
-idi_reset_fax_stat(eicon_chan *chan)
-{
- chan->fax2.LineLen = 0;
- chan->fax2.LineData = 0;
- chan->fax2.LineDataLen = 0;
- chan->fax2.NullByteExist = 0;
- chan->fax2.Dle = 0;
- chan->fax2.PageCount = 0;
- chan->fax2.Eop = 0;
-}
-
-void
-idi_edata_action(eicon_card *ccard, eicon_chan *chan, char *buffer, int len)
-{
- isdn_ctrl cmd;
-
- if (!chan->fax) {
- eicon_log(ccard, 1, "idi_edata: action with NULL fax struct, ERROR\n");
- return;
- }
- if (chan->fax->direction == ISDN_TTY_FAX_CONN_OUT) {
- idi_parse_edata(ccard, chan, buffer, len);
-
- if (chan->fax->phase == ISDN_FAX_PHASE_A) {
- idi_reset_fax_stat(chan);
-
- chan->fsm_state = EICON_STATE_ACTIVE;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_BCONN;
- cmd.arg = chan->No;
- strcpy(cmd.parm.num, "");
- ccard->interface.statcallb(&cmd);
-
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_FCON;
- ccard->interface.statcallb(&cmd);
-
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_RID;
- ccard->interface.statcallb(&cmd);
-
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_DIS;
- ccard->interface.statcallb(&cmd);
-
- if (chan->fax->r_compression != 0) {
- /* telling fake compression in second DIS message */
- chan->fax->r_compression = 0;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_DIS;
- ccard->interface.statcallb(&cmd);
- }
-
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_SENT; /* OK message */
- ccard->interface.statcallb(&cmd);
- } else
- if (chan->fax->phase == ISDN_FAX_PHASE_D) {
-
- if ((chan->fax->code == EDATA_T30_MCF) &&
- (chan->fax->fet != 2)) {
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_PTS;
- ccard->interface.statcallb(&cmd);
- }
-
- switch(chan->fax->fet) {
- case 0: /* new page */
- /* stay in phase D , wait on cmd +FDT */
- break;
- case 1: /* new document */
- /* link-level switch to phase B */
- break;
- case 2: /* session end */
- default:
- /* send_edata produces error on some */
- /* fax-machines here, so we don't */
- /* idi_send_edata(ccard, chan); */
- break;
- }
- }
- }
-
- if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) {
- idi_parse_edata(ccard, chan, buffer, len);
-
- if ((chan->fax->code == EDATA_T30_DCS) &&
- (chan->fax->phase == ISDN_FAX_PHASE_A)) {
- idi_reset_fax_stat(chan);
-
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_BCONN;
- cmd.arg = chan->No;
- strcpy(cmd.parm.num, "");
- ccard->interface.statcallb(&cmd);
-
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_FCON_I;
- ccard->interface.statcallb(&cmd);
- } else
- if ((chan->fax->code == EDATA_T30_TRAIN_OK) &&
- (chan->fax->phase == ISDN_FAX_PHASE_A)) {
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_RID;
- ccard->interface.statcallb(&cmd);
-
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_TRAIN_OK;
- ccard->interface.statcallb(&cmd);
- } else
- if ((chan->fax->code == EDATA_T30_TRAIN_OK) &&
- (chan->fax->phase == ISDN_FAX_PHASE_B)) {
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_TRAIN_OK;
- ccard->interface.statcallb(&cmd);
- } else
- if (chan->fax->phase == ISDN_FAX_PHASE_C) {
- switch(chan->fax->code) {
- case EDATA_T30_TRAIN_OK:
- idi_send_edata(ccard, chan);
- break;
- case EDATA_T30_MPS:
- chan->fax->fet = 0;
- idi_edata_rcveop(ccard, chan);
- break;
- case EDATA_T30_EOM:
- chan->fax->fet = 1;
- idi_edata_rcveop(ccard, chan);
- break;
- case EDATA_T30_EOP:
- chan->fax->fet = 2;
- idi_edata_rcveop(ccard, chan);
- break;
- }
- }
- }
-}
-
-void
-fax_put_rcv(eicon_card *ccard, eicon_chan *chan, u_char *Data, int len)
-{
- struct sk_buff *skb;
-
- skb = alloc_skb(len + MAX_HEADER_LEN, GFP_ATOMIC);
- if (!skb) {
- eicon_log(ccard, 1, "idi_err: Ch%d: alloc_skb failed in fax_put_rcv()\n", chan->No);
- return;
- }
- skb_reserve(skb, MAX_HEADER_LEN);
- memcpy(skb_put(skb, len), Data, len);
- ccard->interface.rcvcallb_skb(ccard->myid, chan->No, skb);
-}
-
-void
-idi_faxdata_rcv(eicon_card *ccard, eicon_chan *chan, struct sk_buff *skb)
-{
- eicon_OBJBUFFER InBuf;
- eicon_OBJBUFFER LineBuf;
- unsigned int Length = 0;
- unsigned int aLength = 0;
- unsigned int ObjectSize = 0;
- unsigned int ObjHeadLen = 0;
- unsigned int ObjDataLen = 0;
- __u8 Recordtype;
- __u8 PageHeaderLen;
- __u8 Event;
- eicon_sff_pagehead *ob_page;
-
- __u16 Cl2Eol = 0x8000;
-
-# define EVENT_NONE 0
-# define EVENT_NEEDDATA 1
-
- if (!chan->fax) {
- eicon_log(ccard, 1, "idi_fax: rcvdata with NULL fax struct, ERROR\n");
- return;
- }
-
-
-
- if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) {
- InBuf.Data = skb->data;
- InBuf.Size = skb->len;
- InBuf.Len = 0;
- InBuf.Next = InBuf.Data;
- LineBuf.Data = chan->fax2.abLine;
- LineBuf.Size = sizeof(chan->fax2.abLine);
- LineBuf.Len = chan->fax2.LineLen;
- LineBuf.Next = LineBuf.Data + LineBuf.Len;
-
- Event = EVENT_NONE;
- while (Event == EVENT_NONE) {
- switch(chan->fax2.NextObject) {
- case FAX_OBJECT_DOCU:
- Length = LineBuf.Len + (InBuf.Size - InBuf.Len);
- if (Length < sizeof(eicon_sff_dochead)) {
- Event = EVENT_NEEDDATA;
- break;
- }
- ObjectSize = sizeof(eicon_sff_dochead);
- Length = ObjectSize;
- if (LineBuf.Len < Length) {
- Length -= LineBuf.Len;
- LineBuf.Len = 0;
- LineBuf.Next = LineBuf.Data;
- InBuf.Len += Length;
- InBuf.Next += Length;
- } else {
- LineBuf.Len -= Length;
- LineBuf.Next = LineBuf.Data + LineBuf.Len;
- memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len);
- }
- chan->fax2.PrevObject = FAX_OBJECT_DOCU;
- chan->fax2.NextObject = FAX_OBJECT_PAGE;
- break;
-
- case FAX_OBJECT_PAGE:
- Length = LineBuf.Len + (InBuf.Size - InBuf.Len);
- if (Length < 2) {
- Event = EVENT_NEEDDATA;
- break;
- }
- if (LineBuf.Len == 0) {
- *LineBuf.Next++ = *InBuf.Next++;
- LineBuf.Len++;
- InBuf.Len++;
- }
- if (LineBuf.Len == 1) {
- *LineBuf.Next++ = *InBuf.Next++;
- LineBuf.Len++;
- InBuf.Len++;
- }
- PageHeaderLen = *(LineBuf.Data + 1);
- ObjectSize = (PageHeaderLen == 0) ? 2 : sizeof(eicon_sff_pagehead);
- if (Length < ObjectSize) {
- Event = EVENT_NEEDDATA;
- break;
- }
- Length = ObjectSize;
- /* extract page dimensions */
- if (LineBuf.Len < Length) {
- aLength = Length - LineBuf.Len;
- memcpy(LineBuf.Next, InBuf.Next, aLength);
- LineBuf.Next += aLength;
- InBuf.Next += aLength;
- LineBuf.Len += aLength;
- InBuf.Len += aLength;
- }
- if (Length > 2) {
- ob_page = (eicon_sff_pagehead *)LineBuf.Data;
- switch(ob_page->linelength) {
- case 2048:
- chan->fax->r_width = 1;
- break;
- case 2432:
- chan->fax->r_width = 2;
- break;
- case 1216:
- chan->fax->r_width = 3;
- break;
- case 864:
- chan->fax->r_width = 4;
- break;
- case 1728:
- default:
- chan->fax->r_width = 0;
- }
- switch(ob_page->pagelength) {
- case 1143:
- case 2287:
- chan->fax->r_length = 0;
- break;
- case 1401:
- case 2802:
- chan->fax->r_length = 1;
- break;
- default:
- chan->fax->r_length = 2;
- }
- eicon_log(ccard, 128, "rSFF-Head: linelength = %d\n", ob_page->linelength);
- eicon_log(ccard, 128, "rSFF-Head: pagelength = %d\n", ob_page->pagelength);
- }
- LineBuf.Len -= Length;
- LineBuf.Next = LineBuf.Data + LineBuf.Len;
- memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len);
-
- chan->fax2.PrevObject = FAX_OBJECT_PAGE;
- chan->fax2.NextObject = FAX_OBJECT_LINE;
- break;
-
- case FAX_OBJECT_LINE:
- Length = LineBuf.Len + (InBuf.Size - InBuf.Len);
- if (Length < 1) {
- Event = EVENT_NEEDDATA;
- break;
- }
- if (LineBuf.Len == 0) {
- *LineBuf.Next++ = *InBuf.Next++;
- LineBuf.Len++;
- InBuf.Len++;
- }
- Recordtype = *LineBuf.Data;
- if (Recordtype == 0) {
- /* recordtype pixel row (2 byte length) */
- ObjHeadLen = 3;
- if (Length < ObjHeadLen) {
- Event = EVENT_NEEDDATA;
- break;
- }
- while (LineBuf.Len < ObjHeadLen) {
- *LineBuf.Next++ = *InBuf.Next++;
- LineBuf.Len++;
- InBuf.Len++;
- }
- ObjDataLen = *((__u16*) (LineBuf.Data + 1));
- ObjectSize = ObjHeadLen + ObjDataLen;
- if (Length < ObjectSize) {
- Event = EVENT_NEEDDATA;
- break;
- }
- } else
- if ((Recordtype >= 1) && (Recordtype <= 216)) {
- /* recordtype pixel row (1 byte length) */
- ObjHeadLen = 1;
- ObjDataLen = Recordtype;
- ObjectSize = ObjHeadLen + ObjDataLen;
- if (Length < ObjectSize) {
- Event = EVENT_NEEDDATA;
- break;
- }
- } else
- if ((Recordtype >= 217) && (Recordtype <= 253)) {
- /* recordtype empty lines */
- ObjHeadLen = 1;
- ObjDataLen = 0;
- ObjectSize = ObjHeadLen + ObjDataLen;
- LineBuf.Len--;
- LineBuf.Next = LineBuf.Data + LineBuf.Len;
- memmove(LineBuf.Data, LineBuf.Data + 1, LineBuf.Len);
- break;
- } else
- if (Recordtype == 254) {
- /* recordtype page header */
- chan->fax2.PrevObject = FAX_OBJECT_LINE;
- chan->fax2.NextObject = FAX_OBJECT_PAGE;
- break;
- } else {
- /* recordtype user information */
- ObjHeadLen = 2;
- if (Length < ObjHeadLen) {
- Event = EVENT_NEEDDATA;
- break;
- }
- while (LineBuf.Len < ObjHeadLen) {
- *LineBuf.Next++ = *InBuf.Next++;
- LineBuf.Len++;
- InBuf.Len++;
- }
- ObjDataLen = *(LineBuf.Data + 1);
- ObjectSize = ObjHeadLen + ObjDataLen;
- if (ObjDataLen == 0) {
- /* illegal line coding */
- LineBuf.Len -= ObjHeadLen;
- LineBuf.Next = LineBuf.Data + LineBuf.Len;
- memmove(LineBuf.Data, LineBuf.Data + ObjHeadLen, LineBuf.Len);
- break;
- } else {
- /* user information */
- if (Length < ObjectSize) {
- Event = EVENT_NEEDDATA;
- break;
- }
- Length = ObjectSize;
- if (LineBuf.Len < Length) {
- Length -= LineBuf.Len;
- LineBuf.Len = 0;
- LineBuf.Next = LineBuf.Data;
- InBuf.Len += Length;
- InBuf.Next += Length;
- } else {
- LineBuf.Len -= Length;
- LineBuf.Next = LineBuf.Data + LineBuf.Len;
- memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len);
- }
- }
- break;
- }
- Length = ObjectSize;
- if (LineBuf.Len > ObjHeadLen) {
- fax_put_rcv(ccard, chan, LineBuf.Data + ObjHeadLen,
- (LineBuf.Len - ObjHeadLen));
- }
- Length -= LineBuf.Len;
- LineBuf.Len = 0;
- LineBuf.Next = LineBuf.Data;
- if (Length > 0) {
- fax_put_rcv(ccard, chan, InBuf.Next, Length);
- InBuf.Len += Length;
- InBuf.Next += Length;
- }
- fax_put_rcv(ccard, chan, (__u8 *)&Cl2Eol, sizeof(Cl2Eol));
- break;
- } /* end of switch (chan->fax2.NextObject) */
- } /* end of while (Event==EVENT_NONE) */
- if (InBuf.Len < InBuf.Size) {
- Length = InBuf.Size - InBuf.Len;
- if ((LineBuf.Len + Length) > LineBuf.Size) {
- eicon_log(ccard, 1, "idi_fax: Ch%d: %d bytes dropping, small buffer\n", chan->No,
- Length);
- } else {
- memcpy(LineBuf.Next, InBuf.Next, Length);
- LineBuf.Len += Length;
- }
- }
- chan->fax2.LineLen = LineBuf.Len;
- } else { /* CONN_OUT */
- /* On CONN_OUT we do not need incoming data, drop it */
- /* maybe later for polling */
- }
-
-# undef EVENT_NONE
-# undef EVENT_NEEDDATA
-
- return;
-}
-
-int
-idi_fax_send_outbuf(eicon_card *ccard, eicon_chan *chan, eicon_OBJBUFFER *OutBuf)
-{
- struct sk_buff *skb;
-
- skb = alloc_skb(OutBuf->Len, GFP_ATOMIC);
- if (!skb) {
- eicon_log(ccard, 1, "idi_err: Ch%d: alloc_skb failed in fax_send_outbuf()\n", chan->No);
- return(-1);
- }
- memcpy(skb_put(skb, OutBuf->Len), OutBuf->Data, OutBuf->Len);
-
- OutBuf->Len = 0;
- OutBuf->Next = OutBuf->Data;
-
- return(idi_send_data(ccard, chan, 0, skb, 1, 0));
-}
-
-int
-idi_faxdata_send(eicon_card *ccard, eicon_chan *chan, struct sk_buff *skb)
-{
- isdn_ctrl cmd;
- eicon_OBJBUFFER InBuf;
- __u8 InData;
- __u8 InMask;
- eicon_OBJBUFFER OutBuf;
- eicon_OBJBUFFER LineBuf;
- __u32 LineData;
- unsigned int LineDataLen;
- __u8 Byte;
- __u8 Event;
- int ret = 1;
-
-# define EVENT_NONE 0
-# define EVENT_EOD 1
-# define EVENT_EOL 2
-# define EVENT_EOP 3
-
- if ((!ccard) || (!chan))
- return -1;
-
- if (!chan->fax) {
- eicon_log(ccard, 1, "idi_fax: senddata with NULL fax struct, ERROR\n");
- return -1;
- }
-
- if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) {
- /* Simply ignore any data written in data mode when receiving a fax. */
- /* This is not completely correct because only XON's should come here. */
- dev_kfree_skb(skb);
- return 1;
- }
-
- if (chan->fax->phase != ISDN_FAX_PHASE_C) {
- dev_kfree_skb(skb);
- return 1;
- }
-
- if (chan->queued + skb->len > 1200)
- return 0;
- if (chan->pqueued > 1)
- return 0;
-
- InBuf.Data = skb->data;
- InBuf.Size = skb->len;
- InBuf.Len = 0;
- InBuf.Next = InBuf.Data;
- InData = 0;
- InMask = 0;
-
- LineBuf.Data = chan->fax2.abLine;
- LineBuf.Size = sizeof(chan->fax2.abLine);
- LineBuf.Len = chan->fax2.LineLen;
- LineBuf.Next = LineBuf.Data + LineBuf.Len;
- LineData = chan->fax2.LineData;
- LineDataLen = chan->fax2.LineDataLen;
-
- OutBuf.Data = chan->fax2.abFrame;
- OutBuf.Size = sizeof(chan->fax2.abFrame);
- OutBuf.Len = 0;
- OutBuf.Next = OutBuf.Data;
-
- Event = EVENT_NONE;
-
- chan->fax2.Eop = 0;
-
- for (;;) {
- for (;;) {
- if (InMask == 0) {
- if (InBuf.Len >= InBuf.Size) {
- Event = EVENT_EOD;
- break;
- }
- if ((chan->fax2.Dle != _DLE_) && *InBuf.Next == _DLE_) {
- chan->fax2.Dle = _DLE_;
- InBuf.Next++;
- InBuf.Len++;
- if (InBuf.Len >= InBuf.Size) {
- Event = EVENT_EOD;
- break;
- }
- }
- if (chan->fax2.Dle == _DLE_) {
- chan->fax2.Dle = 0;
- if (*InBuf.Next == _ETX_) {
- Event = EVENT_EOP;
- break;
- } else
- if (*InBuf.Next == _DLE_) {
- /* do nothing */
- } else {
- eicon_log(ccard, 1,
- "idi_err: Ch%d: unknown DLE escape %02x found\n",
- chan->No, *InBuf.Next);
- InBuf.Next++;
- InBuf.Len++;
- if (InBuf.Len >= InBuf.Size) {
- Event = EVENT_EOD;
- break;
- }
- }
- }
- InBuf.Len++;
- InData = *InBuf.Next++;
- InMask = (chan->fax->bor) ? 0x80 : 0x01;
- }
- while (InMask) {
- LineData >>= 1;
- LineDataLen++;
- if (InData & InMask)
- LineData |= 0x80000000;
- if (chan->fax->bor)
- InMask >>= 1;
- else
- InMask <<= 1;
-
- if ((LineDataLen >= T4_EOL_BITSIZE) &&
- ((LineData & T4_EOL_MASK_DWORD) == T4_EOL_DWORD)) {
- Event = EVENT_EOL;
- if (LineDataLen > T4_EOL_BITSIZE) {
- Byte = (__u8)
- ((LineData & ~T4_EOL_MASK_DWORD) >>
- (32 - LineDataLen));
- if (Byte == 0) {
- if (! chan->fax2.NullByteExist) {
- chan->fax2.NullBytesPos = LineBuf.Len;
- chan->fax2.NullByteExist = 1;
- }
- } else {
- chan->fax2.NullByteExist = 0;
- }
- if (LineBuf.Len < LineBuf.Size) {
- *LineBuf.Next++ = Byte;
- LineBuf.Len++;
- }
- }
- LineDataLen = 0;
- break;
- }
- if (LineDataLen >= T4_EOL_BITSIZE + 8) {
- Byte = (__u8)
- ((LineData & ~T4_EOL_MASK_DWORD) >>
- (32 - T4_EOL_BITSIZE - 8));
- LineData &= T4_EOL_MASK_DWORD;
- LineDataLen = T4_EOL_BITSIZE;
- if (Byte == 0) {
- if (! chan->fax2.NullByteExist) {
- chan->fax2.NullBytesPos = LineBuf.Len;
- chan->fax2.NullByteExist = 1;
- }
- } else {
- chan->fax2.NullByteExist = 0;
- }
- if (LineBuf.Len < LineBuf.Size) {
- *LineBuf.Next++ = Byte;
- LineBuf.Len++;
- }
- }
- }
- if (Event != EVENT_NONE)
- break;
- }
-
- if ((Event != EVENT_EOL) && (Event != EVENT_EOP))
- break;
-
- if ((Event == EVENT_EOP) && (LineDataLen > 0)) {
- LineData >>= 32 - LineDataLen;
- LineDataLen = 0;
- while (LineData != 0) {
- Byte = (__u8) LineData;
- LineData >>= 8;
- if (Byte == 0) {
- if (! chan->fax2.NullByteExist) {
- chan->fax2.NullBytesPos = LineBuf.Len;
- chan->fax2.NullByteExist = 1;
- }
- } else {
- chan->fax2.NullByteExist = 0;
- }
- if (LineBuf.Len < LineBuf.Size) {
- *LineBuf.Next++ = Byte;
- LineBuf.Len++;
- }
-
- }
- }
- if (chan->fax2.NullByteExist) {
- if (chan->fax2.NullBytesPos == 0) {
- LineBuf.Len = 0;
- } else {
- LineBuf.Len = chan->fax2.NullBytesPos + 1;
- }
- }
- if (LineBuf.Len > 0) {
- if (OutBuf.Len + LineBuf.Len + SFF_LEN_FLD_SIZE > OutBuf.Size) {
- ret = idi_fax_send_outbuf(ccard, chan, &OutBuf);
- }
- if (LineBuf.Len <= 216) {
- *OutBuf.Next++ = (__u8) LineBuf.Len;
- OutBuf.Len++;
- } else {
- *OutBuf.Next++ = 0;
- *((__u16 *) OutBuf.Next)++ = (__u16) LineBuf.Len;
- OutBuf.Len += 3;
- }
- memcpy(OutBuf.Next, LineBuf.Data, LineBuf.Len);
- OutBuf.Next += LineBuf.Len;
- OutBuf.Len += LineBuf.Len;
- }
- LineBuf.Len = 0;
- LineBuf.Next = LineBuf.Data;
- chan->fax2.NullByteExist = 0;
- if (Event == EVENT_EOP)
- break;
-
- Event = EVENT_NONE;
- }
-
- if (Event == EVENT_EOP) {
- chan->fax2.Eop = 1;
- chan->fax2.PageCount++;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_EOP;
- ccard->interface.statcallb(&cmd);
- }
- if (OutBuf.Len > 0) {
- ret = idi_fax_send_outbuf(ccard, chan, &OutBuf);
- }
-
- chan->fax2.LineLen = LineBuf.Len;
- chan->fax2.LineData = LineData;
- chan->fax2.LineDataLen = LineDataLen;
-
-# undef EVENT_NONE
-# undef EVENT_EOD
-# undef EVENT_EOL
-# undef EVENT_EOP
-
- if (ret >= 0)
- dev_kfree_skb(skb);
- if (ret == 0)
- ret = 1;
- return(ret);
-}
-
-void
-idi_fax_hangup(eicon_card *ccard, eicon_chan *chan)
-{
- isdn_ctrl cmd;
-
- if (!chan->fax) {
- eicon_log(ccard, 1, "idi_fax: hangup with NULL fax struct, ERROR\n");
- return;
- }
- if ((chan->fax->direction == ISDN_TTY_FAX_CONN_OUT) &&
- (chan->fax->code == 0)) {
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_PTS;
- ccard->interface.statcallb(&cmd);
- }
- if ((chan->fax->code > 1) && (chan->fax->code < 120))
- chan->fax->code += 120;
- eicon_log(ccard, 8, "idi_fax: Ch%d: Hangup (code=%d)\n", chan->No, chan->fax->code);
- chan->fax->r_code = ISDN_TTY_FAX_HNG;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- ccard->interface.statcallb(&cmd);
-}
-
-#endif /******** FAX ********/
-
-int
-idi_send_udata(eicon_card *card, eicon_chan *chan, int UReq, u_char *buffer, int len)
-{
- struct sk_buff *skb;
- struct sk_buff *skb2;
- eicon_REQ *reqbuf;
- eicon_chan_ptr *chan2;
-
- if ((chan->fsm_state == EICON_STATE_NULL) || (chan->fsm_state == EICON_STATE_LISTEN)) {
- eicon_log(card, 1, "idi_snd: Ch%d: send udata on state %d !\n", chan->No, chan->fsm_state);
- return -ENODEV;
- }
- eicon_log(card, 8, "idi_snd: Ch%d: udata 0x%x: %d %d %d %d\n", chan->No,
- UReq, buffer[0], buffer[1], buffer[2], buffer[3]);
-
- skb = alloc_skb(sizeof(eicon_REQ) + len + 1, GFP_ATOMIC);
- skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
-
- if ((!skb) || (!skb2)) {
- eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in send_udata()\n", chan->No);
- if (skb)
- dev_kfree_skb(skb);
- if (skb2)
- dev_kfree_skb(skb2);
- return -ENOMEM;
- }
-
- chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
- chan2->ptr = chan;
-
- reqbuf = (eicon_REQ *)skb_put(skb, 1 + len + sizeof(eicon_REQ));
-
- reqbuf->Req = N_UDATA;
- reqbuf->ReqCh = chan->e.IndCh;
- reqbuf->ReqId = 1;
-
- reqbuf->XBuffer.length = len + 1;
- reqbuf->XBuffer.P[0] = UReq;
- memcpy(&reqbuf->XBuffer.P[1], buffer, len);
- reqbuf->Reference = 1; /* Net Entity */
-
- skb_queue_tail(&chan->e.X, skb);
- skb_queue_tail(&card->sndq, skb2);
- eicon_schedule_tx(card);
- return (0);
-}
-
-void
-idi_audio_cmd(eicon_card *ccard, eicon_chan *chan, int cmd, u_char *value)
-{
- u_char buf[6];
- struct enable_dtmf_s *dtmf_buf = (struct enable_dtmf_s *)buf;
-
- if ((!ccard) || (!chan))
- return;
-
- memset(buf, 0, 6);
- switch(cmd) {
- case ISDN_AUDIO_SETDD:
- if (value[0]) {
- dtmf_buf->tone = (__u16) (value[1] * 5);
- dtmf_buf->gap = (__u16) (value[1] * 5);
- idi_send_udata(ccard, chan,
- DSP_UDATA_REQUEST_ENABLE_DTMF_RECEIVER,
- buf, 4);
- } else {
- idi_send_udata(ccard, chan,
- DSP_UDATA_REQUEST_DISABLE_DTMF_RECEIVER,
- buf, 0);
- }
- break;
- }
-}
-
-void
-idi_parse_udata(eicon_card *ccard, eicon_chan *chan, unsigned char *buffer, int len)
-{
- isdn_ctrl cmd;
- eicon_dsp_ind *p = (eicon_dsp_ind *) (&buffer[1]);
- static char *connmsg[] =
- {"", "V.21", "V.23", "V.22", "V.22bis", "V.32bis", "V.34",
- "V.8", "Bell 212A", "Bell 103", "V.29 Leased", "V.33 Leased", "V.90",
- "V.21 CH2", "V.27ter", "V.29", "V.33", "V.17", "V.32", "K56Flex",
- "X2", "V.18", "V.18LH", "V.18HL", "V.21LH", "V.21HL",
- "Bell 103LH", "Bell 103HL", "V.23", "V.23", "EDT 110",
- "Baudot45", "Baudot47", "Baudot50", "DTMF" };
- static u_char dtmf_code[] = {
- '1','4','7','*','2','5','8','0','3','6','9','#','A','B','C','D'
- };
-
- if ((!ccard) || (!chan))
- return;
-
- switch (buffer[0]) {
- case DSP_UDATA_INDICATION_SYNC:
- eicon_log(ccard, 16, "idi_ind: Ch%d: UDATA_SYNC time %d\n", chan->No, p->time);
- break;
- case DSP_UDATA_INDICATION_DCD_OFF:
- eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DCD_OFF time %d\n", chan->No, p->time);
- break;
- case DSP_UDATA_INDICATION_DCD_ON:
- if ((chan->l2prot == ISDN_PROTO_L2_MODEM) &&
- (chan->fsm_state == EICON_STATE_WMCONN)) {
- chan->fsm_state = EICON_STATE_ACTIVE;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_BCONN;
- cmd.arg = chan->No;
- if (p->norm > 34) {
- sprintf(cmd.parm.num, "%d/(%d)", p->speed, p->norm);
- } else {
- sprintf(cmd.parm.num, "%d/%s", p->speed, connmsg[p->norm]);
- }
- ccard->interface.statcallb(&cmd);
- }
- eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DCD_ON time %d\n", chan->No, p->time);
- eicon_log(ccard, 8, "idi_ind: Ch%d: %d %d %d %d\n", chan->No,
- p->norm, p->options, p->speed, p->delay);
- break;
- case DSP_UDATA_INDICATION_CTS_OFF:
- eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_CTS_OFF time %d\n", chan->No, p->time);
- break;
- case DSP_UDATA_INDICATION_CTS_ON:
- eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_CTS_ON time %d\n", chan->No, p->time);
- eicon_log(ccard, 8, "idi_ind: Ch%d: %d %d %d %d\n", chan->No,
- p->norm, p->options, p->speed, p->delay);
- break;
- case DSP_UDATA_INDICATION_DISCONNECT:
- eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DISCONNECT cause %d\n", chan->No, buffer[1]);
- break;
- case DSP_UDATA_INDICATION_DTMF_DIGITS_RECEIVED:
- eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DTMF_REC '%c'\n", chan->No,
- dtmf_code[buffer[1]]);
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_AUDIO;
- cmd.parm.num[0] = ISDN_AUDIO_DTMF;
- cmd.parm.num[1] = dtmf_code[buffer[1]];
- cmd.arg = chan->No;
- ccard->interface.statcallb(&cmd);
- break;
- default:
- eicon_log(ccard, 8, "idi_ind: Ch%d: UNHANDLED UDATA Indication 0x%02x\n", chan->No, buffer[0]);
- }
-}
-
-void
-eicon_parse_trace(eicon_card *ccard, unsigned char *buffer, int len)
-{
- int i,j,n;
- int buflen = len * 3 + 30;
- char *p;
- struct trace_s {
- unsigned long time;
- unsigned short size;
- unsigned short code;
- unsigned char data[1];
- } *q;
-
- if (!(p = kmalloc(buflen, GFP_ATOMIC))) {
- eicon_log(ccard, 1, "idi_err: Ch??: could not allocate trace buffer\n");
- return;
- }
- memset(p, 0, buflen);
- q = (struct trace_s *)buffer;
-
- if (DebugVar & 512) {
- if ((q->code == 3) || (q->code == 4)) {
- n = (short) *(q->data);
- if (n) {
- j = sprintf(p, "DTRC:");
- for (i = 0; i < n; i++) {
- j += sprintf(p + j, "%02x ", q->data[i+2]);
- }
- j += sprintf(p + j, "\n");
- }
- }
- } else {
- j = sprintf(p, "XLOG: %lx %04x %04x ",
- q->time, q->size, q->code);
-
- for (i = 0; i < q->size; i++) {
- j += sprintf(p + j, "%02x ", q->data[i]);
- }
- j += sprintf(p + j, "\n");
- }
- if (strlen(p))
- eicon_putstatus(ccard, p);
- kfree(p);
-}
-
-void
-idi_handle_ind(eicon_card *ccard, struct sk_buff *skb)
-{
- int tmp;
- char tnum[64];
- int dlev;
- int free_buff;
- ulong flags;
- struct sk_buff *skb2;
- eicon_IND *ind = (eicon_IND *)skb->data;
- eicon_chan *chan;
- idi_ind_message message;
- isdn_ctrl cmd;
-
- if (!ccard) {
- eicon_log(ccard, 1, "idi_err: Ch??: null card in handle_ind\n");
- dev_kfree_skb(skb);
- return;
- }
-
- if ((chan = ccard->IdTable[ind->IndId]) == NULL) {
- eicon_log(ccard, 1, "idi_err: Ch??: null chan in handle_ind\n");
- dev_kfree_skb(skb);
- return;
- }
-
- if ((ind->Ind != 8) && (ind->Ind != 0xc))
- dlev = 144;
- else
- dlev = 128;
-
- eicon_log(ccard, dlev, "idi_hdl: Ch%d: Ind=%x Id=%x Ch=%x MInd=%x MLen=%x Len=%x\n", chan->No,
- ind->Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,ind->RBuffer.length);
-
- free_buff = 1;
- /* Signal Layer */
- if (chan->e.D3Id == ind->IndId) {
- idi_IndParse(ccard, chan, &message, ind->RBuffer.P, ind->RBuffer.length);
- switch(ind->Ind) {
- case HANGUP:
- eicon_log(ccard, 8, "idi_ind: Ch%d: Hangup\n", chan->No);
- while((skb2 = skb_dequeue(&chan->e.X))) {
- dev_kfree_skb(skb2);
- }
- spin_lock_irqsave(&eicon_lock, flags);
- chan->queued = 0;
- chan->pqueued = 0;
- chan->waitq = 0;
- chan->waitpq = 0;
- spin_unlock_irqrestore(&eicon_lock, flags);
- if (message.e_cau[0] & 0x7f) {
- cmd.driver = ccard->myid;
- cmd.arg = chan->No;
- sprintf(cmd.parm.num,"E%02x%02x",
- chan->cause[0]&0x7f, message.e_cau[0]&0x7f);
- cmd.command = ISDN_STAT_CAUSE;
- ccard->interface.statcallb(&cmd);
- }
- chan->cause[0] = 0;
- if (((chan->fsm_state == EICON_STATE_ACTIVE) ||
- (chan->fsm_state == EICON_STATE_WMCONN)) ||
- ((chan->l2prot == ISDN_PROTO_L2_FAX) &&
- (chan->fsm_state == EICON_STATE_OBWAIT))) {
- chan->fsm_state = EICON_STATE_NULL;
- } else {
- if (chan->e.B2Id)
- idi_do_req(ccard, chan, REMOVE, 1);
- chan->statectrl &= ~WAITING_FOR_HANGUP;
- chan->statectrl &= ~IN_HOLD;
- if (chan->statectrl & HAVE_CONN_REQ) {
- eicon_log(ccard, 32, "idi_req: Ch%d: queueing delayed conn_req\n", chan->No);
- chan->statectrl &= ~HAVE_CONN_REQ;
- if ((chan->tskb1) && (chan->tskb2)) {
- skb_queue_tail(&chan->e.X, chan->tskb1);
- skb_queue_tail(&ccard->sndq, chan->tskb2);
- eicon_schedule_tx(ccard);
- }
- chan->tskb1 = NULL;
- chan->tskb2 = NULL;
- } else {
- chan->fsm_state = EICON_STATE_NULL;
- cmd.driver = ccard->myid;
- cmd.arg = chan->No;
- cmd.command = ISDN_STAT_DHUP;
- ccard->interface.statcallb(&cmd);
- eicon_idi_listen_req(ccard, chan);
-#ifdef CONFIG_ISDN_TTY_FAX
- chan->fax = 0;
-#endif
- }
- }
- break;
- case INDICATE_IND:
- eicon_log(ccard, 8, "idi_ind: Ch%d: Indicate_Ind\n", chan->No);
- if (chan->fsm_state != EICON_STATE_LISTEN) {
- eicon_log(ccard, 1, "idi_err: Ch%d: Incoming call on wrong state (%d).\n",
- chan->No, chan->fsm_state);
- idi_do_req(ccard, chan, HANGUP, 0);
- break;
- }
- chan->fsm_state = EICON_STATE_ICALL;
- idi_bc2si(message.bc, message.hlc, message.sin, &chan->si1, &chan->si2);
- strcpy(chan->cpn, message.cpn + 1);
- strcpy(chan->oad, message.oad);
- strcpy(chan->dsa, message.dsa);
- strcpy(chan->osa, message.osa);
- chan->plan = message.plan;
- chan->screen = message.screen;
- try_stat_icall_again:
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_ICALL;
- cmd.arg = chan->No;
- cmd.parm.setup.si1 = chan->si1;
- cmd.parm.setup.si2 = chan->si2;
- strcpy(tnum, chan->cpn);
- if (strlen(chan->dsa)) {
- strcat(tnum, ".");
- strcat(tnum, chan->dsa);
- }
- tnum[ISDN_MSNLEN - 1] = 0;
- strcpy(cmd.parm.setup.eazmsn, tnum);
- strcpy(tnum, chan->oad);
- if (strlen(chan->osa)) {
- strcat(tnum, ".");
- strcat(tnum, chan->osa);
- }
- tnum[ISDN_MSNLEN - 1] = 0;
- strcpy(cmd.parm.setup.phone, tnum);
- cmd.parm.setup.plan = chan->plan;
- cmd.parm.setup.screen = chan->screen;
- tmp = ccard->interface.statcallb(&cmd);
- switch(tmp) {
- case 0: /* no user responding */
- idi_do_req(ccard, chan, HANGUP, 0);
- chan->fsm_state = EICON_STATE_NULL;
- break;
- case 1: /* alert */
- eicon_log(ccard, 8, "idi_req: Ch%d: Call Alert\n", chan->No);
- if ((chan->fsm_state == EICON_STATE_ICALL) || (chan->fsm_state == EICON_STATE_ICALLW)) {
- chan->fsm_state = EICON_STATE_ICALL;
- idi_do_req(ccard, chan, CALL_ALERT, 0);
- }
- break;
- case 2: /* reject */
- eicon_log(ccard, 8, "idi_req: Ch%d: Call Reject\n", chan->No);
- idi_do_req(ccard, chan, REJECT, 0);
- break;
- case 3: /* incomplete number */
- eicon_log(ccard, 8, "idi_req: Ch%d: Incomplete Number\n", chan->No);
- chan->fsm_state = EICON_STATE_ICALLW;
- break;
- }
- break;
- case INFO_IND:
- eicon_log(ccard, 8, "idi_ind: Ch%d: Info_Ind\n", chan->No);
- if ((chan->fsm_state == EICON_STATE_ICALLW) &&
- (message.cpn[0])) {
- strcat(chan->cpn, message.cpn + 1);
- goto try_stat_icall_again;
- }
- break;
- case CALL_IND:
- eicon_log(ccard, 8, "idi_ind: Ch%d: Call_Ind\n", chan->No);
- if ((chan->fsm_state == EICON_STATE_ICALL) || (chan->fsm_state == EICON_STATE_IWAIT)) {
- chan->fsm_state = EICON_STATE_IBWAIT;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_DCONN;
- cmd.arg = chan->No;
- ccard->interface.statcallb(&cmd);
- switch(chan->l2prot) {
- case ISDN_PROTO_L2_FAX:
-#ifdef CONFIG_ISDN_TTY_FAX
- if (chan->fax)
- chan->fax->phase = ISDN_FAX_PHASE_A;
-#endif
- break;
- case ISDN_PROTO_L2_MODEM:
- /* do nothing, wait for connect */
- break;
- case ISDN_PROTO_L2_V11096:
- case ISDN_PROTO_L2_V11019:
- case ISDN_PROTO_L2_V11038:
- case ISDN_PROTO_L2_TRANS:
- idi_do_req(ccard, chan, N_CONNECT, 1);
- break;
- default:;
- /* On most incoming calls we use automatic connect */
- /* idi_do_req(ccard, chan, N_CONNECT, 1); */
- }
- } else {
- if (chan->fsm_state != EICON_STATE_ACTIVE)
- idi_hangup(ccard, chan);
- }
- break;
- case CALL_CON:
- eicon_log(ccard, 8, "idi_ind: Ch%d: Call_Con\n", chan->No);
- if (chan->fsm_state == EICON_STATE_OCALL) {
- /* check if old NetID has been removed */
- if (chan->e.B2Id) {
- eicon_log(ccard, 1, "eicon: Ch%d: old net_id %x still exist, removing.\n",
- chan->No, chan->e.B2Id);
- idi_do_req(ccard, chan, REMOVE, 1);
- }
-#ifdef CONFIG_ISDN_TTY_FAX
- if (chan->l2prot == ISDN_PROTO_L2_FAX) {
- if (chan->fax) {
- chan->fax->phase = ISDN_FAX_PHASE_A;
- } else {
- eicon_log(ccard, 1, "idi_ind: Call_Con with NULL fax struct, ERROR\n");
- idi_hangup(ccard, chan);
- break;
- }
- }
-#endif
- chan->fsm_state = EICON_STATE_OBWAIT;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_DCONN;
- cmd.arg = chan->No;
- ccard->interface.statcallb(&cmd);
-
- idi_do_req(ccard, chan, ASSIGN, 1);
- idi_do_req(ccard, chan, N_CONNECT, 1);
- } else
- idi_hangup(ccard, chan);
- break;
- case AOC_IND:
- eicon_log(ccard, 8, "idi_ind: Ch%d: Advice of Charge\n", chan->No);
- break;
- case CALL_HOLD_ACK:
- chan->statectrl |= IN_HOLD;
- eicon_log(ccard, 8, "idi_ind: Ch%d: Call Hold Ack\n", chan->No);
- break;
- case SUSPEND_REJ:
- eicon_log(ccard, 8, "idi_ind: Ch%d: Suspend Rejected\n", chan->No);
- break;
- case SUSPEND:
- eicon_log(ccard, 8, "idi_ind: Ch%d: Suspend Ack\n", chan->No);
- break;
- case RESUME:
- eicon_log(ccard, 8, "idi_ind: Ch%d: Resume Ack\n", chan->No);
- break;
- default:
- eicon_log(ccard, 8, "idi_ind: Ch%d: UNHANDLED SigIndication 0x%02x\n", chan->No, ind->Ind);
- }
- }
- /* Network Layer */
- else if (chan->e.B2Id == ind->IndId) {
-
- if (chan->No == ccard->nchannels) {
- /* Management Indication */
- if (ind->Ind == 0x04) { /* Trace_Ind */
- eicon_parse_trace(ccard, ind->RBuffer.P, ind->RBuffer.length);
- } else {
- idi_IndParse(ccard, chan, &message, ind->RBuffer.P, ind->RBuffer.length);
- chan->fsm_state = 1;
- }
- }
- else
- switch(ind->Ind) {
- case N_CONNECT_ACK:
- eicon_log(ccard, 16, "idi_ind: Ch%d: N_Connect_Ack\n", chan->No);
- if (chan->l2prot == ISDN_PROTO_L2_MODEM) {
- chan->fsm_state = EICON_STATE_WMCONN;
- break;
- }
- if (chan->l2prot == ISDN_PROTO_L2_FAX) {
-#ifdef CONFIG_ISDN_TTY_FAX
- chan->fsm_state = EICON_STATE_ACTIVE;
- idi_parse_edata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
- if (chan->fax) {
- if (chan->fax->phase == ISDN_FAX_PHASE_B) {
- idi_fax_send_header(ccard, chan, 2);
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_DCS;
- ccard->interface.statcallb(&cmd);
- }
- }
- else {
- eicon_log(ccard, 1, "idi_ind: N_Connect_Ack with NULL fax struct, ERROR\n");
- }
-#endif
- break;
- }
- chan->fsm_state = EICON_STATE_ACTIVE;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_BCONN;
- cmd.arg = chan->No;
- strcpy(cmd.parm.num, "64000");
- ccard->interface.statcallb(&cmd);
- break;
- case N_CONNECT:
- eicon_log(ccard, 16,"idi_ind: Ch%d: N_Connect\n", chan->No);
- chan->e.IndCh = ind->IndCh;
- if (chan->e.B2Id) idi_do_req(ccard, chan, N_CONNECT_ACK, 1);
- if (chan->l2prot == ISDN_PROTO_L2_FAX) {
- break;
- }
- if (chan->l2prot == ISDN_PROTO_L2_MODEM) {
- chan->fsm_state = EICON_STATE_WMCONN;
- break;
- }
- chan->fsm_state = EICON_STATE_ACTIVE;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_BCONN;
- cmd.arg = chan->No;
- strcpy(cmd.parm.num, "64000");
- ccard->interface.statcallb(&cmd);
- break;
- case N_DISC:
- eicon_log(ccard, 16, "idi_ind: Ch%d: N_Disc\n", chan->No);
- if (chan->e.B2Id) {
- while((skb2 = skb_dequeue(&chan->e.X))) {
- dev_kfree_skb(skb2);
- }
- idi_do_req(ccard, chan, N_DISC_ACK, 1);
- idi_do_req(ccard, chan, REMOVE, 1);
- }
-#ifdef CONFIG_ISDN_TTY_FAX
- if ((chan->l2prot == ISDN_PROTO_L2_FAX) && (chan->fax)){
- idi_parse_edata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
- idi_fax_hangup(ccard, chan);
- }
-#endif
- chan->e.IndCh = 0;
- spin_lock_irqsave(&eicon_lock, flags);
- chan->queued = 0;
- chan->pqueued = 0;
- chan->waitq = 0;
- chan->waitpq = 0;
- spin_unlock_irqrestore(&eicon_lock, flags);
- if (!(chan->statectrl & IN_HOLD)) {
- idi_do_req(ccard, chan, HANGUP, 0);
- }
- if (chan->fsm_state == EICON_STATE_ACTIVE) {
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_BHUP;
- cmd.arg = chan->No;
- ccard->interface.statcallb(&cmd);
- chan->fsm_state = EICON_STATE_NULL;
- if (!(chan->statectrl & IN_HOLD)) {
- chan->statectrl |= WAITING_FOR_HANGUP;
- }
- }
-#ifdef CONFIG_ISDN_TTY_FAX
- chan->fax = 0;
-#endif
- break;
- case N_DISC_ACK:
- eicon_log(ccard, 16, "idi_ind: Ch%d: N_Disc_Ack\n", chan->No);
-#ifdef CONFIG_ISDN_TTY_FAX
- if (chan->l2prot == ISDN_PROTO_L2_FAX) {
- idi_parse_edata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
- idi_fax_hangup(ccard, chan);
- }
-#endif
- break;
- case N_DATA_ACK:
- eicon_log(ccard, 128, "idi_ind: Ch%d: N_Data_Ack\n", chan->No);
- break;
- case N_DATA:
- skb_pull(skb, sizeof(eicon_IND) - 1);
- eicon_log(ccard, 128, "idi_rcv: Ch%d: %d bytes\n", chan->No, skb->len);
- if (chan->l2prot == ISDN_PROTO_L2_FAX) {
-#ifdef CONFIG_ISDN_TTY_FAX
- idi_faxdata_rcv(ccard, chan, skb);
-#endif
- } else {
- ccard->interface.rcvcallb_skb(ccard->myid, chan->No, skb);
- free_buff = 0;
- }
- break;
- case N_UDATA:
- idi_parse_udata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
- break;
-#ifdef CONFIG_ISDN_TTY_FAX
- case N_EDATA:
- idi_edata_action(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
- break;
-#endif
- default:
- eicon_log(ccard, 8, "idi_ind: Ch%d: UNHANDLED NetIndication 0x%02x\n", chan->No, ind->Ind);
- }
- }
- else {
- eicon_log(ccard, 1, "idi_ind: Ch%d: Ind is neither SIG nor NET !\n", chan->No);
- }
- if (free_buff)
- dev_kfree_skb(skb);
-}
-
-int
-idi_handle_ack_ok(eicon_card *ccard, eicon_chan *chan, eicon_RC *ack)
-{
- ulong flags;
- isdn_ctrl cmd;
- int tqueued = 0;
- int twaitpq = 0;
-
- if (ack->RcId != ((chan->e.ReqCh) ? chan->e.B2Id : chan->e.D3Id)) {
- /* I don't know why this happens, should not ! */
- /* just ignoring this RC */
- eicon_log(ccard, 16, "idi_ack: Ch%d: RcId %d not equal to last %d\n", chan->No,
- ack->RcId, (chan->e.ReqCh) ? chan->e.B2Id : chan->e.D3Id);
- return 1;
- }
-
- /* Management Interface */
- if (chan->No == ccard->nchannels) {
- /* Managementinterface: changing state */
- if (chan->e.Req != 0x02)
- chan->fsm_state = 1;
- }
-
- /* Remove an Id */
- if (chan->e.Req == REMOVE) {
- if (ack->Reference != chan->e.ref) {
- /* This should not happen anymore */
- eicon_log(ccard, 16, "idi_ack: Ch%d: Rc-Ref %d not equal to stored %d\n", chan->No,
- ack->Reference, chan->e.ref);
- }
- spin_lock_irqsave(&eicon_lock, flags);
- ccard->IdTable[ack->RcId] = NULL;
- if (!chan->e.ReqCh)
- chan->e.D3Id = 0;
- else
- chan->e.B2Id = 0;
- spin_unlock_irqrestore(&eicon_lock, flags);
- eicon_log(ccard, 16, "idi_ack: Ch%d: Removed : Id=%x Ch=%d (%s)\n", chan->No,
- ack->RcId, ack->RcCh, (chan->e.ReqCh)? "Net":"Sig");
- return 1;
- }
-
- /* Signal layer */
- if (!chan->e.ReqCh) {
- eicon_log(ccard, 16, "idi_ack: Ch%d: RC OK Id=%x Ch=%d (ref:%d)\n", chan->No,
- ack->RcId, ack->RcCh, ack->Reference);
- } else {
- /* Network layer */
- switch(chan->e.Req & 0x0f) {
- case N_CONNECT:
- chan->e.IndCh = ack->RcCh;
- eicon_log(ccard, 16, "idi_ack: Ch%d: RC OK Id=%x Ch=%d (ref:%d)\n", chan->No,
- ack->RcId, ack->RcCh, ack->Reference);
- break;
- case N_MDATA:
- case N_DATA:
- tqueued = chan->queued;
- twaitpq = chan->waitpq;
- if ((chan->e.Req & 0x0f) == N_DATA) {
- spin_lock_irqsave(&eicon_lock, flags);
- chan->waitpq = 0;
- if(chan->pqueued)
- chan->pqueued--;
- spin_unlock_irqrestore(&eicon_lock, flags);
-#ifdef CONFIG_ISDN_TTY_FAX
- if (chan->l2prot == ISDN_PROTO_L2_FAX) {
- if (((chan->queued - chan->waitq) < 1) &&
- (chan->fax2.Eop)) {
- chan->fax2.Eop = 0;
- if (chan->fax) {
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_SENT;
- ccard->interface.statcallb(&cmd);
- }
- else {
- eicon_log(ccard, 1, "idi_ack: Sent with NULL fax struct, ERROR\n");
- }
- }
- }
-#endif
- }
- spin_lock_irqsave(&eicon_lock, flags);
- chan->queued -= chan->waitq;
- if (chan->queued < 0) chan->queued = 0;
- spin_unlock_irqrestore(&eicon_lock, flags);
- if (((chan->e.Req & 0x0f) == N_DATA) && (tqueued)) {
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_BSENT;
- cmd.arg = chan->No;
- cmd.parm.length = twaitpq;
- ccard->interface.statcallb(&cmd);
- }
- break;
- default:
- eicon_log(ccard, 16, "idi_ack: Ch%d: RC OK Id=%x Ch=%d (ref:%d)\n", chan->No,
- ack->RcId, ack->RcCh, ack->Reference);
- }
- }
- return 1;
-}
-
-void
-idi_handle_ack(eicon_card *ccard, struct sk_buff *skb)
-{
- int j;
- ulong flags;
- eicon_RC *ack = (eicon_RC *)skb->data;
- eicon_chan *chan;
- isdn_ctrl cmd;
- int dCh = -1;
-
- if (!ccard) {
- eicon_log(ccard, 1, "idi_err: Ch??: null card in handle_ack\n");
- dev_kfree_skb(skb);
- return;
- }
-
- spin_lock_irqsave(&eicon_lock, flags);
- if ((chan = ccard->IdTable[ack->RcId]) != NULL)
- dCh = chan->No;
- spin_unlock_irqrestore(&eicon_lock, flags);
-
- switch (ack->Rc) {
- case OK_FC:
- case N_FLOW_CONTROL:
- case ASSIGN_RC:
- eicon_log(ccard, 1, "idi_ack: Ch%d: unhandled RC 0x%x\n",
- dCh, ack->Rc);
- break;
- case READY_INT:
- case TIMER_INT:
- /* we do nothing here */
- break;
-
- case OK:
- if (!chan) {
- eicon_log(ccard, 1, "idi_ack: Ch%d: OK on chan without Id\n", dCh);
- break;
- }
- if (!idi_handle_ack_ok(ccard, chan, ack))
- chan = NULL;
- break;
-
- case ASSIGN_OK:
- if (chan) {
- eicon_log(ccard, 1, "idi_ack: Ch%d: ASSIGN-OK on chan already assigned (%x,%x)\n",
- chan->No, chan->e.D3Id, chan->e.B2Id);
- }
- spin_lock_irqsave(&eicon_lock, flags);
- for(j = 0; j < ccard->nchannels + 1; j++) {
- if ((ccard->bch[j].e.ref == ack->Reference) &&
- (ccard->bch[j].e.Req == ASSIGN)) {
- if (!ccard->bch[j].e.ReqCh)
- ccard->bch[j].e.D3Id = ack->RcId;
- else
- ccard->bch[j].e.B2Id = ack->RcId;
- ccard->IdTable[ack->RcId] = &ccard->bch[j];
- chan = &ccard->bch[j];
- break;
- }
- }
- spin_unlock_irqrestore(&eicon_lock, flags);
- eicon_log(ccard, 16, "idi_ack: Ch%d: Id %x assigned (%s)\n", j,
- ack->RcId, (ccard->bch[j].e.ReqCh)? "Net":"Sig");
- if (j > ccard->nchannels) {
- eicon_log(ccard, 24, "idi_ack: Ch??: ref %d not found for Id %d\n",
- ack->Reference, ack->RcId);
- }
- break;
-
- case OUT_OF_RESOURCES:
- case UNKNOWN_COMMAND:
- case WRONG_COMMAND:
- case WRONG_ID:
- case ADAPTER_DEAD:
- case WRONG_CH:
- case UNKNOWN_IE:
- case WRONG_IE:
- default:
- if (!chan) {
- eicon_log(ccard, 1, "idi_ack: Ch%d: Not OK !! on chan without Id\n", dCh);
- break;
- } else
- switch (chan->e.Req) {
- case 12: /* Alert */
- eicon_log(ccard, 2, "eicon_err: Ch%d: Alert Not OK : Rc=%d Id=%x Ch=%d\n",
- dCh, ack->Rc, ack->RcId, ack->RcCh);
- break;
- default:
- if (dCh != ccard->nchannels)
- eicon_log(ccard, 1, "eicon_err: Ch%d: Ack Not OK !!: Rc=%d Id=%x Ch=%d Req=%d\n",
- dCh, ack->Rc, ack->RcId, ack->RcCh, chan->e.Req);
- }
- if (dCh == ccard->nchannels) { /* Management */
- chan->fsm_state = 2;
- eicon_log(ccard, 8, "eicon_err: Ch%d: Ack Not OK !!: Rc=%d Id=%x Ch=%d Req=%d\n",
- dCh, ack->Rc, ack->RcId, ack->RcCh, chan->e.Req);
- } else if (dCh >= 0) {
- /* any other channel */
- /* card reports error: we hangup */
- idi_hangup(ccard, chan);
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_DHUP;
- cmd.arg = chan->No;
- ccard->interface.statcallb(&cmd);
- }
- }
- spin_lock_irqsave(&eicon_lock, flags);
- if (chan) {
- chan->e.ref = 0;
- chan->e.busy = 0;
- }
- spin_unlock_irqrestore(&eicon_lock, flags);
- dev_kfree_skb(skb);
- eicon_schedule_tx(ccard);
-}
-
-int
-idi_send_data(eicon_card *card, eicon_chan *chan, int ack, struct sk_buff *skb, int que, int chk)
-{
- struct sk_buff *xmit_skb;
- struct sk_buff *skb2;
- eicon_REQ *reqbuf;
- eicon_chan_ptr *chan2;
- int len, plen = 0, offset = 0;
- unsigned long flags;
-
- if ((!card) || (!chan)) {
- eicon_log(card, 1, "idi_err: Ch??: null card/chan in send_data\n");
- return -1;
- }
-
- if (chan->fsm_state != EICON_STATE_ACTIVE) {
- eicon_log(card, 1, "idi_snd: Ch%d: send bytes on state %d !\n", chan->No, chan->fsm_state);
- return -ENODEV;
- }
-
- len = skb->len;
- if (len > EICON_MAX_QUEUE) /* too much for the shared memory */
- return -1;
- if (!len)
- return 0;
-
- if ((chk) && (chan->pqueued > 1))
- return 0;
-
- eicon_log(card, 128, "idi_snd: Ch%d: %d bytes (Pqueue=%d)\n",
- chan->No, len, chan->pqueued);
-
- spin_lock_irqsave(&eicon_lock, flags);
- while(offset < len) {
-
- plen = ((len - offset) > 270) ? 270 : len - offset;
-
- xmit_skb = alloc_skb(plen + sizeof(eicon_REQ), GFP_ATOMIC);
- skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
-
- if ((!xmit_skb) || (!skb2)) {
- spin_unlock_irqrestore(&eicon_lock, flags);
- eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in send_data()\n", chan->No);
- if (xmit_skb)
- dev_kfree_skb(xmit_skb);
- if (skb2)
- dev_kfree_skb(skb2);
- return -ENOMEM;
- }
-
- chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
- chan2->ptr = chan;
-
- reqbuf = (eicon_REQ *)skb_put(xmit_skb, plen + sizeof(eicon_REQ));
- if ((len - offset) > 270) {
- reqbuf->Req = N_MDATA;
- } else {
- reqbuf->Req = N_DATA;
- /* if (ack) reqbuf->Req |= N_D_BIT; */
- }
- reqbuf->ReqCh = chan->e.IndCh;
- reqbuf->ReqId = 1;
- memcpy(&reqbuf->XBuffer.P, skb->data + offset, plen);
- reqbuf->XBuffer.length = plen;
- reqbuf->Reference = 1; /* Net Entity */
-
- skb_queue_tail(&chan->e.X, xmit_skb);
- skb_queue_tail(&card->sndq, skb2);
-
- offset += plen;
- }
- if (que) {
- chan->queued += len;
- chan->pqueued++;
- }
- spin_unlock_irqrestore(&eicon_lock, flags);
- eicon_schedule_tx(card);
- dev_kfree_skb(skb);
- return len;
-}
-
-
-int
-eicon_idi_manage_assign(eicon_card *card)
-{
- struct sk_buff *skb;
- struct sk_buff *skb2;
- eicon_REQ *reqbuf;
- eicon_chan *chan;
- eicon_chan_ptr *chan2;
-
- chan = &(card->bch[card->nchannels]);
-
- skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
- skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
-
- if ((!skb) || (!skb2)) {
- eicon_log(card, 1, "idi_err: alloc_skb failed in manage_assign()\n");
- if (skb)
- dev_kfree_skb(skb);
- if (skb2)
- dev_kfree_skb(skb2);
- return -ENOMEM;
- }
-
- chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
- chan2->ptr = chan;
-
- reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
-
- reqbuf->XBuffer.P[0] = 0;
- reqbuf->Req = ASSIGN;
- reqbuf->ReqCh = 0;
- reqbuf->ReqId = MAN_ID;
- reqbuf->XBuffer.length = 1;
- reqbuf->Reference = 2; /* Man Entity */
-
- skb_queue_tail(&chan->e.X, skb);
- skb_queue_tail(&card->sndq, skb2);
- eicon_schedule_tx(card);
- return(0);
-}
-
-
-int
-eicon_idi_manage_remove(eicon_card *card)
-{
- struct sk_buff *skb;
- struct sk_buff *skb2;
- eicon_REQ *reqbuf;
- eicon_chan *chan;
- eicon_chan_ptr *chan2;
-
- chan = &(card->bch[card->nchannels]);
-
- skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
- skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
-
- if ((!skb) || (!skb2)) {
- eicon_log(card, 1, "idi_err: alloc_skb failed in manage_remove()\n");
- if (skb)
- dev_kfree_skb(skb);
- if (skb2)
- dev_kfree_skb(skb2);
- return -ENOMEM;
- }
-
- chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
- chan2->ptr = chan;
-
- reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
-
- reqbuf->Req = REMOVE;
- reqbuf->ReqCh = 0;
- reqbuf->ReqId = 1;
- reqbuf->XBuffer.length = 0;
- reqbuf->Reference = 2; /* Man Entity */
-
- skb_queue_tail(&chan->e.X, skb);
- skb_queue_tail(&card->sndq, skb2);
- eicon_schedule_tx(card);
- return(0);
-}
-
-
-int
-eicon_idi_manage(eicon_card *card, eicon_manifbuf *mb)
-{
- int l = 0;
- int ret = 0;
- unsigned long timeout;
- int i;
- struct sk_buff *skb;
- struct sk_buff *skb2;
- eicon_REQ *reqbuf;
- eicon_chan *chan;
- eicon_chan_ptr *chan2;
-
- chan = &(card->bch[card->nchannels]);
-
- if (!(chan->e.D3Id)) {
- chan->e.D3Id = 1;
- while((skb2 = skb_dequeue(&chan->e.X)))
- dev_kfree_skb(skb2);
- chan->e.busy = 0;
-
- if ((ret = eicon_idi_manage_assign(card))) {
- chan->e.D3Id = 0;
- return(ret);
- }
-
- timeout = jiffies + HZ / 2;
- while (time_before(jiffies, timeout)) {
- if (chan->e.B2Id) break;
- SLEEP(10);
- }
- if (!chan->e.B2Id) {
- chan->e.D3Id = 0;
- return -EIO;
- }
- }
-
- chan->fsm_state = 0;
-
- if (!(manbuf = kmalloc(sizeof(eicon_manifbuf), GFP_KERNEL))) {
- eicon_log(card, 1, "idi_err: alloc_manifbuf failed\n");
- return -ENOMEM;
- }
- if (copy_from_user(manbuf, mb, sizeof(eicon_manifbuf))) {
- kfree(manbuf);
- return -EFAULT;
- }
-
- skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
- skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
-
- if ((!skb) || (!skb2)) {
- eicon_log(card, 1, "idi_err_manif: alloc_skb failed in manage()\n");
- if (skb)
- dev_kfree_skb(skb);
- if (skb2)
- dev_kfree_skb(skb2);
- kfree(manbuf);
- return -ENOMEM;
- }
-
- chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
- chan2->ptr = chan;
-
- reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
-
- reqbuf->XBuffer.P[l++] = ESC;
- reqbuf->XBuffer.P[l++] = 6;
- reqbuf->XBuffer.P[l++] = 0x80;
- for (i = 0; i < manbuf->length[0]; i++)
- reqbuf->XBuffer.P[l++] = manbuf->data[i];
- reqbuf->XBuffer.P[1] = manbuf->length[0] + 1;
-
- reqbuf->XBuffer.P[l++] = 0;
- reqbuf->Req = (manbuf->count) ? manbuf->count : MAN_READ;
- reqbuf->ReqCh = 0;
- reqbuf->ReqId = 1;
- reqbuf->XBuffer.length = l;
- reqbuf->Reference = 2; /* Man Entity */
-
- skb_queue_tail(&chan->e.X, skb);
- skb_queue_tail(&card->sndq, skb2);
-
- manbuf->count = 0;
- manbuf->pos = 0;
-
- eicon_schedule_tx(card);
-
- timeout = jiffies + HZ / 2;
- while (time_before(jiffies, timeout)) {
- if (chan->fsm_state) break;
- SLEEP(10);
- }
- if ((!chan->fsm_state) || (chan->fsm_state == 2)) {
- kfree(manbuf);
- return -EIO;
- }
- if (copy_to_user(mb, manbuf, sizeof(eicon_manifbuf))) {
- kfree(manbuf);
- return -EFAULT;
- }
-
- kfree(manbuf);
- return(0);
-}
+++ /dev/null
-/* $Id: eicon_idi.h,v 1.1.4.1.2.2 2002/10/01 11:29:13 armin Exp $
- *
- * ISDN lowlevel-module for the Eicon active cards.
- * IDI-Interface
- *
- * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
- * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#ifndef E_IDI_H
-#define E_IDI_H
-
-#include <linux/config.h>
-
-#undef N_DATA
-#undef ID_MASK
-
-#include "pc.h"
-
-#define AOC_IND 26 /* Advice of Charge */
-#define PI 0x1e /* Progress Indicator */
-#define NI 0x27 /* Notification Indicator */
-
-#define CALL_HOLD 0x22
-#define CALL_HOLD_ACK 0x24
-
-/* defines for statectrl */
-#define WAITING_FOR_HANGUP 0x01
-#define HAVE_CONN_REQ 0x02
-#define IN_HOLD 0x04
-
-typedef struct {
- char cpn[32];
- char oad[32];
- char dsa[32];
- char osa[32];
- __u8 plan;
- __u8 screen;
- __u8 sin[4];
- __u8 chi[4];
- __u8 e_chi[4];
- __u8 bc[12];
- __u8 e_bc[12];
- __u8 llc[18];
- __u8 hlc[5];
- __u8 cau[4];
- __u8 e_cau[2];
- __u8 e_mt;
- __u8 dt[6];
- char display[83];
- char keypad[35];
- char rdn[32];
-} idi_ind_message;
-
-typedef struct {
- __u16 next __attribute__ ((packed));
- __u8 Req __attribute__ ((packed));
- __u8 ReqId __attribute__ ((packed));
- __u8 ReqCh __attribute__ ((packed));
- __u8 Reserved1 __attribute__ ((packed));
- __u16 Reference __attribute__ ((packed));
- __u8 Reserved[8] __attribute__ ((packed));
- eicon_PBUFFER XBuffer;
-} eicon_REQ;
-
-typedef struct {
- __u16 next __attribute__ ((packed));
- __u8 Rc __attribute__ ((packed));
- __u8 RcId __attribute__ ((packed));
- __u8 RcCh __attribute__ ((packed));
- __u8 Reserved1 __attribute__ ((packed));
- __u16 Reference __attribute__ ((packed));
- __u8 Reserved2[8] __attribute__ ((packed));
-} eicon_RC;
-
-typedef struct {
- __u16 next __attribute__ ((packed));
- __u8 Ind __attribute__ ((packed));
- __u8 IndId __attribute__ ((packed));
- __u8 IndCh __attribute__ ((packed));
- __u8 MInd __attribute__ ((packed));
- __u16 MLength __attribute__ ((packed));
- __u16 Reference __attribute__ ((packed));
- __u8 RNR __attribute__ ((packed));
- __u8 Reserved __attribute__ ((packed));
- __u32 Ack __attribute__ ((packed));
- eicon_PBUFFER RBuffer;
-} eicon_IND;
-
-typedef struct {
- __u8 *Data;
- unsigned int Size;
- unsigned int Len;
- __u8 *Next;
-} eicon_OBJBUFFER;
-
-extern int idi_do_req(eicon_card *card, eicon_chan *chan, int cmd, int layer);
-extern int idi_hangup(eicon_card *card, eicon_chan *chan);
-extern int idi_connect_res(eicon_card *card, eicon_chan *chan);
-extern int eicon_idi_listen_req(eicon_card *card, eicon_chan *chan);
-extern int idi_connect_req(eicon_card *card, eicon_chan *chan, char *phone,
- char *eazmsn, int si1, int si2);
-
-extern void idi_handle_ack(eicon_card *card, struct sk_buff *skb);
-extern void idi_handle_ind(eicon_card *card, struct sk_buff *skb);
-extern int eicon_idi_manage(eicon_card *card, eicon_manifbuf *mb);
-extern int idi_send_data(eicon_card *card, eicon_chan *chan, int ack, struct sk_buff *skb, int que, int chk);
-extern void idi_audio_cmd(eicon_card *ccard, eicon_chan *chan, int cmd, u_char *value);
-extern int capipmsg(eicon_card *card, eicon_chan *chan, capi_msg *cm);
-#ifdef CONFIG_ISDN_TTY_FAX
-extern void idi_fax_cmd(eicon_card *card, eicon_chan *chan);
-extern int idi_faxdata_send(eicon_card *ccard, eicon_chan *chan, struct sk_buff *skb);
-#endif
-
-#endif
+++ /dev/null
-/* $Id: eicon_io.c,v 1.1.4.1.2.2 2002/10/01 11:29:13 armin Exp $
- *
- * ISDN low-level module for Eicon active ISDN-Cards.
- * Code for communicating with hardware.
- *
- * Copyright 1999,2000 by Armin Schindler (mac@melware.de)
- * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * Thanks to Eicon Networks for
- * documents, informations and hardware.
- *
- */
-
-#include <linux/config.h>
-#include "eicon.h"
-#include "uxio.h"
-
-void
-eicon_io_rcv_dispatch(eicon_card *ccard) {
- ulong flags;
- struct sk_buff *skb, *skb2, *skb_new;
- eicon_IND *ind, *ind2, *ind_new;
- eicon_chan *chan;
-
- if (!ccard) {
- eicon_log(ccard, 1, "eicon_err: NULL card in rcv_dispatch !\n");
- return;
- }
-
- while((skb = skb_dequeue(&ccard->rcvq))) {
- ind = (eicon_IND *)skb->data;
-
- spin_lock_irqsave(&eicon_lock, flags);
- if ((chan = ccard->IdTable[ind->IndId]) == NULL) {
- spin_unlock_irqrestore(&eicon_lock, flags);
- if (DebugVar & 1) {
- switch(ind->Ind) {
- case N_DISC_ACK:
- /* doesn't matter if this happens */
- break;
- default:
- eicon_log(ccard, 1, "idi: Indication for unknown channel Ind=%d Id=%x\n", ind->Ind, ind->IndId);
- eicon_log(ccard, 1, "idi_hdl: Ch??: Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n",
- ind->Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,ind->RBuffer.length);
- }
- }
- dev_kfree_skb(skb);
- continue;
- }
- spin_unlock_irqrestore(&eicon_lock, flags);
-
- if (chan->e.complete) { /* check for rec-buffer chaining */
- if (ind->MLength == ind->RBuffer.length) {
- chan->e.complete = 1;
- idi_handle_ind(ccard, skb);
- continue;
- }
- else {
- chan->e.complete = 0;
- ind->Ind = ind->MInd;
- skb_queue_tail(&chan->e.R, skb);
- continue;
- }
- }
- else {
- if (!(skb2 = skb_dequeue(&chan->e.R))) {
- chan->e.complete = 1;
- eicon_log(ccard, 1, "eicon: buffer incomplete, but 0 in queue\n");
- dev_kfree_skb(skb);
- continue;
- }
- ind2 = (eicon_IND *)skb2->data;
- skb_new = alloc_skb(((sizeof(eicon_IND)-1)+ind->RBuffer.length+ind2->RBuffer.length),
- GFP_ATOMIC);
- if (!skb_new) {
- eicon_log(ccard, 1, "eicon_io: skb_alloc failed in rcv_dispatch()\n");
- dev_kfree_skb(skb);
- dev_kfree_skb(skb2);
- continue;
- }
- ind_new = (eicon_IND *)skb_put(skb_new,
- ((sizeof(eicon_IND)-1)+ind->RBuffer.length+ind2->RBuffer.length));
- ind_new->Ind = ind2->Ind;
- ind_new->IndId = ind2->IndId;
- ind_new->IndCh = ind2->IndCh;
- ind_new->MInd = ind2->MInd;
- ind_new->MLength = ind2->MLength;
- ind_new->RBuffer.length = ind2->RBuffer.length + ind->RBuffer.length;
- memcpy(&ind_new->RBuffer.P, &ind2->RBuffer.P, ind2->RBuffer.length);
- memcpy((&ind_new->RBuffer.P)+ind2->RBuffer.length, &ind->RBuffer.P, ind->RBuffer.length);
- dev_kfree_skb(skb);
- dev_kfree_skb(skb2);
- if (ind->MLength == ind->RBuffer.length) {
- chan->e.complete = 2;
- idi_handle_ind(ccard, skb_new);
- continue;
- }
- else {
- chan->e.complete = 0;
- skb_queue_tail(&chan->e.R, skb_new);
- continue;
- }
- }
- }
-}
-
-void
-eicon_io_ack_dispatch(eicon_card *ccard) {
- struct sk_buff *skb;
-
- if (!ccard) {
- eicon_log(ccard, 1, "eicon_err: NULL card in ack_dispatch!\n");
- return;
- }
- while((skb = skb_dequeue(&ccard->rackq))) {
- idi_handle_ack(ccard, skb);
- }
-}
-
-
-/*
- * IO-Functions for ISA cards
- */
-
-u8 ram_inb(eicon_card *card, void *adr) {
- u32 addr = (u32) adr;
-
- return(readb(addr));
-}
-
-u16 ram_inw(eicon_card *card, void *adr) {
- u32 addr = (u32) adr;
-
- return(readw(addr));
-}
-
-void ram_outb(eicon_card *card, void *adr, u8 data) {
- u32 addr = (u32) adr;
-
- writeb(data, addr);
-}
-
-void ram_outw(eicon_card *card, void *adr , u16 data) {
- u32 addr = (u32) adr;
-
- writew(data, addr);
-}
-
-void ram_copyfromcard(eicon_card *card, void *adrto, void *adr, int len) {
- memcpy_fromio(adrto, adr, len);
-}
-
-void ram_copytocard(eicon_card *card, void *adrto, void *adr, int len) {
- memcpy_toio(adrto, adr, len);
-}
-
-
-#ifdef CONFIG_ISDN_DRV_EICON_PCI
-/*
- * IDI-Callback function
- */
-void
-eicon_idi_callback(ENTITY *de)
-{
- eicon_card *ccard = (eicon_card *)de->R;
- struct sk_buff *skb;
- eicon_RC *ack;
- eicon_IND *ind;
- int len = 0;
-
- if (de->complete == 255) {
- /* Return Code */
- skb = alloc_skb(sizeof(eicon_RC), GFP_ATOMIC);
- if (!skb) {
- eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _idi_callback()\n");
- } else {
- ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC));
- ack->Rc = de->Rc;
- if (de->Rc == ASSIGN_OK) {
- ack->RcId = de->Id;
- de->user[1] = de->Id;
- } else {
- ack->RcId = de->user[1];
- }
- ack->RcCh = de->RcCh;
- ack->Reference = de->user[0];
- skb_queue_tail(&ccard->rackq, skb);
- eicon_schedule_ack(ccard);
- eicon_log(ccard, 128, "idi_cbk: Ch%d: Rc=%x Id=%x RLen=%x compl=%x\n",
- de->user[0], de->Rc, ack->RcId, de->RLength, de->complete);
- }
- } else {
- /* Indication */
- if (de->complete) {
- len = de->RLength;
- } else {
- len = 270;
- if (de->RLength <= 270)
- eicon_log(ccard, 1, "eicon_cbk: ind not complete but <= 270\n");
- }
- skb = alloc_skb((sizeof(eicon_IND) + len - 1), GFP_ATOMIC);
- if (!skb) {
- eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _idi_callback()\n");
- } else {
- ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1));
- ind->Ind = de->Ind;
- ind->IndId = de->user[1];
- ind->IndCh = de->IndCh;
- ind->MInd = de->Ind;
- ind->RBuffer.length = len;
- ind->MLength = de->RLength;
- memcpy(&ind->RBuffer.P, &de->RBuffer->P, len);
- skb_queue_tail(&ccard->rcvq, skb);
- eicon_schedule_rx(ccard);
- eicon_log(ccard, 128, "idi_cbk: Ch%d: Ind=%x Id=%x RLen=%x compl=%x\n",
- de->user[0], de->Ind, ind->IndId, de->RLength, de->complete);
- }
- }
-
- de->RNum = 0;
- de->RNR = 0;
- de->Rc = 0;
- de->Ind = 0;
-}
-#endif /* CONFIG_ISDN_DRV_EICON_PCI */
-
-/*
- * Transmit-Function
- */
-void
-eicon_io_transmit(eicon_card *ccard) {
- eicon_isa_card *isa_card;
- struct sk_buff *skb;
- struct sk_buff *skb2;
- unsigned long flags;
- eicon_pr_ram *prram = 0;
- eicon_isa_com *com = 0;
- eicon_REQ *ReqOut = 0;
- eicon_REQ *reqbuf = 0;
- eicon_chan *chan;
- eicon_chan_ptr *chan2;
- int ReqCount;
- int scom = 0;
- int tmp = 0;
- int tmpid = 0;
- int quloop = 1;
- int dlev = 0;
- ENTITY *ep = 0;
-
- isa_card = &ccard->hwif.isa;
-
- if (!ccard) {
- eicon_log(ccard, 1, "eicon_transmit: NULL card!\n");
- return;
- }
-
- switch(ccard->type) {
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
- case EICON_CTYPE_S:
- case EICON_CTYPE_SX:
- case EICON_CTYPE_SCOM:
- case EICON_CTYPE_QUADRO:
- scom = 1;
- com = (eicon_isa_com *)isa_card->shmem;
- break;
- case EICON_CTYPE_S2M:
- scom = 0;
- prram = (eicon_pr_ram *)isa_card->shmem;
- break;
-#endif
-#ifdef CONFIG_ISDN_DRV_EICON_PCI
- case EICON_CTYPE_MAESTRAP:
- scom = 2;
- break;
- case EICON_CTYPE_MAESTRAQ:
- scom = 2;
- break;
- case EICON_CTYPE_MAESTRA:
- scom = 2;
- break;
-#endif
- default:
- eicon_log(ccard, 1, "eicon_transmit: unsupported card-type!\n");
- return;
- }
-
- ReqCount = 0;
- if (!(skb2 = skb_dequeue(&ccard->sndq)))
- quloop = 0;
- while(quloop) {
- spin_lock_irqsave(&eicon_lock, flags);
- switch (scom) {
- case 1:
- if ((ram_inb(ccard, &com->Req)) || (ccard->ReadyInt)) {
- if (!ccard->ReadyInt) {
- tmp = ram_inb(ccard, &com->ReadyInt) + 1;
- ram_outb(ccard, &com->ReadyInt, tmp);
- ccard->ReadyInt++;
- }
- spin_unlock_irqrestore(&eicon_lock, flags);
- skb_queue_head(&ccard->sndq, skb2);
- eicon_log(ccard, 32, "eicon: transmit: Card not ready\n");
- return;
- }
- break;
- case 0:
- if (!(ram_inb(ccard, &prram->ReqOutput) - ram_inb(ccard, &prram->ReqInput))) {
- spin_unlock_irqrestore(&eicon_lock, flags);
- skb_queue_head(&ccard->sndq, skb2);
- eicon_log(ccard, 32, "eicon: transmit: Card not ready\n");
- return;
- }
- break;
- }
- spin_unlock_irqrestore(&eicon_lock, flags);
-
- chan2 = (eicon_chan_ptr *)skb2->data;
- chan = chan2->ptr;
- if (!chan->e.busy) {
- if((skb = skb_dequeue(&chan->e.X))) {
-
- reqbuf = (eicon_REQ *)skb->data;
- if ((reqbuf->Reference) && (chan->e.B2Id == 0) && (reqbuf->ReqId & 0x1f)) {
- eicon_log(ccard, 16, "eicon: transmit: error Id=0 on %d (Net)\n", chan->No);
- } else {
- spin_lock_irqsave(&eicon_lock, flags);
-
- switch (scom) {
- case 1:
- ram_outw(ccard, &com->XBuffer.length, reqbuf->XBuffer.length);
- ram_copytocard(ccard, &com->XBuffer.P, &reqbuf->XBuffer.P, reqbuf->XBuffer.length);
- ram_outb(ccard, &com->ReqCh, reqbuf->ReqCh);
- break;
- case 0:
- /* get address of next available request buffer */
- ReqOut = (eicon_REQ *)&prram->B[ram_inw(ccard, &prram->NextReq)];
- ram_outw(ccard, &ReqOut->XBuffer.length, reqbuf->XBuffer.length);
- ram_copytocard(ccard, &ReqOut->XBuffer.P, &reqbuf->XBuffer.P, reqbuf->XBuffer.length);
- ram_outb(ccard, &ReqOut->ReqCh, reqbuf->ReqCh);
- ram_outb(ccard, &ReqOut->Req, reqbuf->Req);
- break;
- }
-
- dlev = 160;
-
- if (reqbuf->ReqId & 0x1f) { /* if this is no ASSIGN */
-
- if (!reqbuf->Reference) { /* Signal Layer */
- switch (scom) {
- case 1:
- ram_outb(ccard, &com->ReqId, chan->e.D3Id);
- break;
- case 0:
- ram_outb(ccard, &ReqOut->ReqId, chan->e.D3Id);
- break;
- case 2:
- ep = &chan->de;
- break;
- }
- tmpid = chan->e.D3Id;
- chan->e.ReqCh = 0;
- }
- else { /* Net Layer */
- switch(scom) {
- case 1:
- ram_outb(ccard, &com->ReqId, chan->e.B2Id);
- break;
- case 0:
- ram_outb(ccard, &ReqOut->ReqId, chan->e.B2Id);
- break;
- case 2:
- ep = &chan->be;
- break;
- }
- tmpid = chan->e.B2Id;
- chan->e.ReqCh = 1;
- if (((reqbuf->Req & 0x0f) == 0x08) ||
- ((reqbuf->Req & 0x0f) == 0x01)) { /* Send Data */
- chan->waitq = reqbuf->XBuffer.length;
- chan->waitpq += reqbuf->XBuffer.length;
- dlev = 128;
- }
- }
-
- } else { /* It is an ASSIGN */
-
- switch(scom) {
- case 1:
- ram_outb(ccard, &com->ReqId, reqbuf->ReqId);
- break;
- case 0:
- ram_outb(ccard, &ReqOut->ReqId, reqbuf->ReqId);
- break;
- case 2:
- if (!reqbuf->Reference)
- ep = &chan->de;
- else
- ep = &chan->be;
- ep->Id = reqbuf->ReqId;
- break;
- }
- tmpid = reqbuf->ReqId;
-
- if (!reqbuf->Reference)
- chan->e.ReqCh = 0;
- else
- chan->e.ReqCh = 1;
- }
-
- switch(scom) {
- case 1:
- chan->e.ref = ccard->ref_out++;
- break;
- case 0:
- chan->e.ref = ram_inw(ccard, &ReqOut->Reference);
- break;
- case 2:
- chan->e.ref = chan->No;
- break;
- }
-
- chan->e.Req = reqbuf->Req;
- ReqCount++;
-
- switch (scom) {
- case 1:
- ram_outb(ccard, &com->Req, reqbuf->Req);
- break;
- case 0:
- ram_outw(ccard, &prram->NextReq, ram_inw(ccard, &ReqOut->next));
- break;
- case 2:
-#ifdef CONFIG_ISDN_DRV_EICON_PCI
- if (!ep) break;
- ep->callback = eicon_idi_callback;
- ep->R = (BUFFERS *)ccard;
- ep->user[0] = (word)chan->No;
- ep->user[1] = (word)tmpid;
- ep->XNum = 1;
- ep->RNum = 0;
- ep->RNR = 0;
- ep->Rc = 0;
- ep->Ind = 0;
- ep->X->PLength = reqbuf->XBuffer.length;
- memcpy(ep->X->P, &reqbuf->XBuffer.P, reqbuf->XBuffer.length);
- ep->ReqCh = reqbuf->ReqCh;
- ep->Req = reqbuf->Req;
-#endif
- break;
- }
-
- chan->e.busy = 1;
- spin_unlock_irqrestore(&eicon_lock, flags);
- eicon_log(ccard, dlev, "eicon: Req=%d Id=%x Ch=%d Len=%d Ref=%d\n",
- reqbuf->Req, tmpid,
- reqbuf->ReqCh, reqbuf->XBuffer.length,
- chan->e.ref);
-#ifdef CONFIG_ISDN_DRV_EICON_PCI
- if (scom == 2) {
- if (ep) {
- ccard->d->request(ep);
- if (ep->Rc)
- eicon_idi_callback(ep);
- }
- }
-#endif
- }
- dev_kfree_skb(skb);
- }
- dev_kfree_skb(skb2);
- }
- else {
- skb_queue_tail(&ccard->sackq, skb2);
- eicon_log(ccard, 128, "eicon: transmit: busy chan %d\n", chan->No);
- }
-
- switch(scom) {
- case 1:
- quloop = 0;
- break;
- case 0:
- case 2:
- if (!(skb2 = skb_dequeue(&ccard->sndq)))
- quloop = 0;
- break;
- }
-
- }
- if (!scom)
- ram_outb(ccard, &prram->ReqInput, (__u8)(ram_inb(ccard, &prram->ReqInput) + ReqCount));
-
- while((skb = skb_dequeue(&ccard->sackq))) {
- skb_queue_tail(&ccard->sndq, skb);
- }
-}
-
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
-/*
- * IRQ handler
- */
-irqreturn_t
-eicon_irq(int irq, void *dev_id, struct pt_regs *regs) {
- eicon_card *ccard = (eicon_card *)dev_id;
- eicon_isa_card *isa_card;
- eicon_pr_ram *prram = 0;
- eicon_isa_com *com = 0;
- eicon_RC *RcIn;
- eicon_IND *IndIn;
- struct sk_buff *skb;
- int Count = 0;
- int Rc = 0;
- int Ind = 0;
- unsigned char *irqprobe = 0;
- int scom = 0;
- int tmp = 0;
- int dlev = 0;
-
-
- if (!ccard) {
- eicon_log(ccard, 1, "eicon_irq: spurious interrupt %d\n", irq);
- return IRQ_NONE;
- }
-
- if (ccard->type == EICON_CTYPE_QUADRO) {
- tmp = 4;
- while(tmp) {
- com = (eicon_isa_com *)ccard->hwif.isa.shmem;
- if ((readb(ccard->hwif.isa.intack))) { /* quadro found */
- break;
- }
- ccard = ccard->qnext;
- tmp--;
- }
- }
-
- isa_card = &ccard->hwif.isa;
-
- switch(ccard->type) {
- case EICON_CTYPE_S:
- case EICON_CTYPE_SX:
- case EICON_CTYPE_SCOM:
- case EICON_CTYPE_QUADRO:
- scom = 1;
- com = (eicon_isa_com *)isa_card->shmem;
- irqprobe = &isa_card->irqprobe;
- break;
- case EICON_CTYPE_S2M:
- scom = 0;
- prram = (eicon_pr_ram *)isa_card->shmem;
- irqprobe = &isa_card->irqprobe;
- break;
- default:
- eicon_log(ccard, 1, "eicon_irq: unsupported card-type!\n");
- return IRQ_NONE;
- }
-
- if (*irqprobe) {
- switch(ccard->type) {
- case EICON_CTYPE_S:
- case EICON_CTYPE_SX:
- case EICON_CTYPE_SCOM:
- case EICON_CTYPE_QUADRO:
- if (readb(isa_card->intack)) {
- writeb(0, &com->Rc);
- writeb(0, isa_card->intack);
- }
- (*irqprobe)++;
- break;
- case EICON_CTYPE_S2M:
- if (readb(isa_card->intack)) {
- writeb(0, &prram->RcOutput);
- writeb(0, isa_card->intack);
- }
- (*irqprobe)++;
- break;
- }
- return IRQ_HANDLED;
- }
-
- switch(ccard->type) {
- case EICON_CTYPE_S:
- case EICON_CTYPE_SX:
- case EICON_CTYPE_SCOM:
- case EICON_CTYPE_QUADRO:
- case EICON_CTYPE_S2M:
- if (!(readb(isa_card->intack))) { /* card did not interrupt */
- eicon_log(ccard, 1, "eicon: IRQ: card reports no interrupt!\n");
- return IRQ_NONE;
- }
- break;
- }
-
- if (scom) {
-
- /* if a return code is available ... */
- if ((tmp = ram_inb(ccard, &com->Rc))) {
- eicon_RC *ack;
- if (tmp == READY_INT) {
- eicon_log(ccard, 64, "eicon: IRQ Rc=READY_INT\n");
- if (ccard->ReadyInt) {
- ccard->ReadyInt--;
- ram_outb(ccard, &com->Rc, 0);
- eicon_schedule_tx(ccard);
- }
- } else {
- skb = alloc_skb(sizeof(eicon_RC), GFP_ATOMIC);
- if (!skb) {
- eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n");
- } else {
- ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC));
- ack->Rc = tmp;
- ack->RcId = ram_inb(ccard, &com->RcId);
- ack->RcCh = ram_inb(ccard, &com->RcCh);
- ack->Reference = ccard->ref_in++;
- eicon_log(ccard, 128, "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%d\n",
- tmp,ack->RcId,ack->RcCh,ack->Reference);
- skb_queue_tail(&ccard->rackq, skb);
- eicon_schedule_ack(ccard);
- }
- ram_outb(ccard, &com->Req, 0);
- ram_outb(ccard, &com->Rc, 0);
- }
-
- } else {
-
- /* if an indication is available ... */
- if ((tmp = ram_inb(ccard, &com->Ind))) {
- eicon_IND *ind;
- int len = ram_inw(ccard, &com->RBuffer.length);
- skb = alloc_skb((sizeof(eicon_IND) + len - 1), GFP_ATOMIC);
- if (!skb) {
- eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n");
- } else {
- ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1));
- ind->Ind = tmp;
- ind->IndId = ram_inb(ccard, &com->IndId);
- ind->IndCh = ram_inb(ccard, &com->IndCh);
- ind->MInd = ram_inb(ccard, &com->MInd);
- ind->MLength = ram_inw(ccard, &com->MLength);
- ind->RBuffer.length = len;
- if ((tmp == 1) || (tmp == 8))
- dlev = 128;
- else
- dlev = 192;
- eicon_log(ccard, dlev, "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n",
- tmp,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,len);
- ram_copyfromcard(ccard, &ind->RBuffer.P, &com->RBuffer.P, len);
- skb_queue_tail(&ccard->rcvq, skb);
- eicon_schedule_rx(ccard);
- }
- ram_outb(ccard, &com->Ind, 0);
- }
- }
-
- } else {
-
- /* if return codes are available ... */
- if((Count = ram_inb(ccard, &prram->RcOutput))) {
- eicon_RC *ack;
- /* get the buffer address of the first return code */
- RcIn = (eicon_RC *)&prram->B[ram_inw(ccard, &prram->NextRc)];
- /* for all return codes do ... */
- while(Count--) {
-
- if((Rc=ram_inb(ccard, &RcIn->Rc))) {
- skb = alloc_skb(sizeof(eicon_RC), GFP_ATOMIC);
- if (!skb) {
- eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n");
- } else {
- ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC));
- ack->Rc = Rc;
- ack->RcId = ram_inb(ccard, &RcIn->RcId);
- ack->RcCh = ram_inb(ccard, &RcIn->RcCh);
- ack->Reference = ram_inw(ccard, &RcIn->Reference);
- eicon_log(ccard, 128, "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%d\n",
- Rc,ack->RcId,ack->RcCh,ack->Reference);
- skb_queue_tail(&ccard->rackq, skb);
- eicon_schedule_ack(ccard);
- }
- ram_outb(ccard, &RcIn->Rc, 0);
- }
- /* get buffer address of next return code */
- RcIn = (eicon_RC *)&prram->B[ram_inw(ccard, &RcIn->next)];
- }
- /* clear all return codes (no chaining!) */
- ram_outb(ccard, &prram->RcOutput, 0);
- }
-
- /* if indications are available ... */
- if((Count = ram_inb(ccard, &prram->IndOutput))) {
- eicon_IND *ind;
- /* get the buffer address of the first indication */
- IndIn = (eicon_IND *)&prram->B[ram_inw(ccard, &prram->NextInd)];
- /* for all indications do ... */
- while(Count--) {
- Ind = ram_inb(ccard, &IndIn->Ind);
- if(Ind) {
- int len = ram_inw(ccard, &IndIn->RBuffer.length);
- skb = alloc_skb((sizeof(eicon_IND) + len - 1), GFP_ATOMIC);
- if (!skb) {
- eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n");
- } else {
- ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1));
- ind->Ind = Ind;
- ind->IndId = ram_inb(ccard, &IndIn->IndId);
- ind->IndCh = ram_inb(ccard, &IndIn->IndCh);
- ind->MInd = ram_inb(ccard, &IndIn->MInd);
- ind->MLength = ram_inw(ccard, &IndIn->MLength);
- ind->RBuffer.length = len;
- if ((Ind == 1) || (Ind == 8))
- dlev = 128;
- else
- dlev = 192;
- eicon_log(ccard, dlev, "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n",
- Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,len);
- ram_copyfromcard(ccard, &ind->RBuffer.P, &IndIn->RBuffer.P, len);
- skb_queue_tail(&ccard->rcvq, skb);
- eicon_schedule_rx(ccard);
- }
- ram_outb(ccard, &IndIn->Ind, 0);
- }
- /* get buffer address of next indication */
- IndIn = (eicon_IND *)&prram->B[ram_inw(ccard, &IndIn->next)];
- }
- ram_outb(ccard, &prram->IndOutput, 0);
- }
-
- }
-
- /* clear interrupt */
- switch(ccard->type) {
- case EICON_CTYPE_QUADRO:
- writeb(0, isa_card->intack);
- writeb(0, &com[0x401]);
- break;
- case EICON_CTYPE_S:
- case EICON_CTYPE_SX:
- case EICON_CTYPE_SCOM:
- case EICON_CTYPE_S2M:
- writeb(0, isa_card->intack);
- break;
- }
-
- return IRQ_HANDLED;
-}
-#endif
+++ /dev/null
-/* $Id: eicon_isa.c,v 1.1.4.1.2.3 2002/10/01 11:29:13 armin Exp $
- *
- * ISDN low-level module for Eicon active ISDN-Cards.
- * Hardware-specific code for old ISA cards.
- *
- * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de)
- * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
- * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/config.h>
-#include "eicon.h"
-#include "eicon_isa.h"
-
-#define check_shmem check_region
-#define release_shmem release_region
-#define request_shmem request_region
-
-char *eicon_isa_revision = "$Revision: 1.1.4.1.2.3 $";
-
-#undef EICON_MCA_DEBUG
-
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
-
-/* Mask for detecting invalid IRQ parameter */
-static int eicon_isa_valid_irq[] = {
- 0x1c1c, /* 2, 3, 4, 10, 11, 12 (S)*/
- 0x1c1c, /* 2, 3, 4, 10, 11, 12 (SX) */
- 0x1cbc, /* 2, 3, 4, 5, 7, 10, 11, 12 (SCOM) */
- 0x1cbc, /* 2, 3, 4, 5, 6, 10, 11, 12 (Quadro) */
- 0x1cbc /* 2, 3, 4, 5, 7, 10, 11, 12 (S2M) */
-};
-
-static void
-eicon_isa_release_shmem(eicon_isa_card *card) {
- if (card->mvalid) {
- iounmap(card->shmem);
- release_mem_region(card->physmem, card->ramsize);
- }
- card->mvalid = 0;
-}
-
-static void
-eicon_isa_release_irq(eicon_isa_card *card) {
- if (!card->master)
- return;
- if (card->ivalid)
- free_irq(card->irq, card);
- card->ivalid = 0;
-}
-
-void
-eicon_isa_release(eicon_isa_card *card) {
- eicon_isa_release_irq(card);
- eicon_isa_release_shmem(card);
-}
-
-void
-eicon_isa_printpar(eicon_isa_card *card) {
- switch (card->type) {
- case EICON_CTYPE_S:
- case EICON_CTYPE_SX:
- case EICON_CTYPE_SCOM:
- case EICON_CTYPE_QUADRO:
- case EICON_CTYPE_S2M:
- printk(KERN_INFO "Eicon %s at 0x%lx, irq %d.\n",
- eicon_ctype_name[card->type],
- card->physmem,
- card->irq);
- }
-}
-
-int
-eicon_isa_find_card(int Mem, int Irq, char * Id)
-{
- int primary = 1;
- unsigned long amem;
-
- if (!strlen(Id))
- return -1;
-
- if (Mem == -1)
- return -1;
-
- /* Check for valid membase address */
- if ((Mem < 0x0c0000) ||
- (Mem > 0x0fc000) ||
- (Mem & 0xfff)) {
- printk(KERN_WARNING "eicon_isa: invalid membase 0x%x for %s\n",
- Mem, Id);
- return -1;
- }
- if (check_mem_region(Mem, RAMSIZE)) {
- printk(KERN_WARNING "eicon_isa_boot: memory at 0x%x already in use.\n", Mem);
- return -1;
- }
-
- amem = (unsigned long) ioremap(Mem, RAMSIZE);
- writew(0x55aa, amem + 0x402);
- if (readw(amem + 0x402) != 0x55aa) primary = 0;
- writew(0, amem + 0x402);
- if (readw(amem + 0x402) != 0) primary = 0;
-
- printk(KERN_INFO "Eicon: Driver-ID: %s\n", Id);
- if (primary) {
- printk(KERN_INFO "Eicon: assuming pri card at 0x%x\n", Mem);
- writeb(0, amem + 0x3ffe);
- iounmap((unsigned char *)amem);
- return EICON_CTYPE_ISAPRI;
- } else {
- printk(KERN_INFO "Eicon: assuming bri card at 0x%x\n", Mem);
- writeb(0, amem + 0x400);
- iounmap((unsigned char *)amem);
- return EICON_CTYPE_ISABRI;
- }
- return -1;
-}
-
-int
-eicon_isa_bootload(eicon_isa_card *card, eicon_isa_codebuf *cb) {
- int tmp;
- unsigned long timeout;
- eicon_isa_codebuf cbuf;
- unsigned char *code;
- eicon_isa_boot *boot;
-
- if (copy_from_user(&cbuf, cb, sizeof(eicon_isa_codebuf)))
- return -EFAULT;
-
- /* Allocate code-buffer and copy code from userspace */
- if (cbuf.bootstrap_len > 1024) {
- printk(KERN_WARNING "eicon_isa_boot: Invalid startup-code size %ld\n",
- cbuf.bootstrap_len);
- return -EINVAL;
- }
- if (!(code = kmalloc(cbuf.bootstrap_len, GFP_KERNEL))) {
- printk(KERN_WARNING "eicon_isa_boot: Couldn't allocate code buffer\n");
- return -ENOMEM;
- }
- if (copy_from_user(code, &cb->code, cbuf.bootstrap_len)) {
- kfree(code);
- return -EFAULT;
- }
-
- if (card->type == EICON_CTYPE_ISAPRI)
- card->ramsize = RAMSIZE_P;
- else
- card->ramsize = RAMSIZE;
-
- if (check_mem_region(card->physmem, card->ramsize)) {
- printk(KERN_WARNING "eicon_isa_boot: memory at 0x%lx already in use.\n",
- card->physmem);
- kfree(code);
- return -EBUSY;
- }
- request_mem_region(card->physmem, card->ramsize, "Eicon ISA ISDN");
- card->shmem = (eicon_isa_shmem *) ioremap(card->physmem, card->ramsize);
-#ifdef EICON_MCA_DEBUG
- printk(KERN_INFO "eicon_isa_boot: card->ramsize = %d.\n", card->ramsize);
-#endif
- card->mvalid = 1;
-
- switch(card->type) {
- case EICON_CTYPE_S:
- case EICON_CTYPE_SX:
- case EICON_CTYPE_SCOM:
- case EICON_CTYPE_QUADRO:
- case EICON_CTYPE_ISABRI:
- card->intack = (__u8 *)card->shmem + INTACK;
- card->startcpu = (__u8 *)card->shmem + STARTCPU;
- card->stopcpu = (__u8 *)card->shmem + STOPCPU;
- break;
- case EICON_CTYPE_S2M:
- case EICON_CTYPE_ISAPRI:
- card->intack = (__u8 *)card->shmem + INTACK_P;
- card->startcpu = (__u8 *)card->shmem + STARTCPU_P;
- card->stopcpu = (__u8 *)card->shmem + STOPCPU_P;
- break;
- default:
- printk(KERN_WARNING "eicon_isa_boot: Invalid card type %d\n", card->type);
- eicon_isa_release_shmem(card);
- kfree(code);
- return -EINVAL;
- }
-
- /* clear any pending irq's */
- readb(card->intack);
-#ifdef CONFIG_MCA
- if (MCA_bus) {
- if (card->type == EICON_CTYPE_SCOM) {
- outb_p(0,card->io+1);
- }
- else {
- printk(KERN_WARNING "eicon_isa_boot: Card type not supported yet.\n");
- eicon_isa_release_shmem(card);
- return -EINVAL;
- };
-
-#ifdef EICON_MCA_DEBUG
- printk(KERN_INFO "eicon_isa_boot: card->io = %x.\n", card->io);
- printk(KERN_INFO "eicon_isa_boot: card->irq = %d.\n", (int)card->irq);
-#endif
- }
-#else
- /* set reset-line active */
- writeb(0, card->stopcpu);
-#endif /* CONFIG_MCA */
- /* clear irq-requests */
- writeb(0, card->intack);
- readb(card->intack);
-
- /* Copy code into card */
- memcpy_toio(&card->shmem->c, code, cbuf.bootstrap_len);
-
- /* Check for properly loaded code */
- if (!check_signature((unsigned long)&card->shmem->c, code, 1020)) {
- printk(KERN_WARNING "eicon_isa_boot: Could not load startup-code\n");
- eicon_isa_release_shmem(card);
- kfree(code);
- return -EIO;
- }
- /* if 16k-ramsize, duplicate the reset-jump-code */
- if (card->ramsize == RAMSIZE_P)
- memcpy_toio((__u8 *)card->shmem + 0x3ff0, &code[0x3f0], 12);
-
- kfree(code);
- boot = &card->shmem->boot;
-
- /* Delay 0.2 sec. */
- SLEEP(HZ / 5);
-
- /* Start CPU */
- writeb(cbuf.boot_opt, &boot->ctrl);
-#ifdef CONFIG_MCA
- if (MCA_bus) {
- outb_p(0, card->io);
- }
-#else
- writeb(0, card->startcpu);
-#endif /* CONFIG_MCA */
-
- /* Delay 0.2 sec. */
- SLEEP(HZ / 5);
-
- timeout = jiffies + (HZ * 22);
- while (time_before(jiffies, timeout)) {
- if (readb(&boot->ctrl) == 0)
- break;
- SLEEP(10);
- }
- if (readb(&boot->ctrl) != 0) {
- printk(KERN_WARNING "eicon_isa_boot: CPU test failed.\n");
-#ifdef EICON_MCA_DEBUG
- printk(KERN_INFO "eicon_isa_boot: &boot->ctrl = %d.\n",
- readb(&boot->ctrl));
-#endif
- eicon_isa_release_shmem(card);
- return -EIO;
- }
-
- /* Check for memory-test errors */
- if (readw(&boot->ebit)) {
- printk(KERN_WARNING "eicon_isa_boot: memory test failed (bit 0x%04x at 0x%08x)\n",
- readw(&boot->ebit), readl(&boot->eloc));
- eicon_isa_release_shmem(card);
- return -EIO;
- }
-
- /* Check card type and memory size */
- tmp = readb(&boot->card);
- if ((tmp < 0) || (tmp > 4)) {
- printk(KERN_WARNING "eicon_isa_boot: Type detect failed\n");
- eicon_isa_release_shmem(card);
- return -EIO;
- }
- card->type = tmp;
- ((eicon_card *)card->card)->type = tmp;
-
- tmp = readb(&boot->msize);
- if (tmp != 8 && tmp != 16 && tmp != 24 &&
- tmp != 32 && tmp != 48 && tmp != 60) {
- printk(KERN_WARNING "eicon_isa_boot: invalid memsize\n");
- eicon_isa_release_shmem(card);
- return -EIO;
- }
- printk(KERN_INFO "%s: startup-code loaded\n", eicon_ctype_name[card->type]);
- if ((card->type == EICON_CTYPE_QUADRO) && (card->master)) {
- tmp = eicon_addcard(card->type, card->physmem, card->irq,
- ((eicon_card *)card->card)->regname, 0);
- printk(KERN_INFO "Eicon: %d adapters added\n", tmp);
- }
- return 0;
-}
-
-int
-eicon_isa_load(eicon_isa_card *card, eicon_isa_codebuf *cb) {
- eicon_isa_boot *boot;
- int tmp;
- unsigned long timeout;
- int j;
- eicon_isa_codebuf cbuf;
- unsigned char *code;
- unsigned char *p;
-
- if (copy_from_user(&cbuf, cb, sizeof(eicon_isa_codebuf)))
- return -EFAULT;
-
- if (!(code = kmalloc(cbuf.firmware_len, GFP_KERNEL))) {
- printk(KERN_WARNING "eicon_isa_load: Couldn't allocate code buffer\n");
- return -ENOMEM;
- }
-
- if (copy_from_user(code, &cb->code, cbuf.firmware_len)) {
- kfree(code);
- return -EFAULT;
- }
-
- boot = &card->shmem->boot;
-
- if ((!card->ivalid) && card->master) {
- card->irqprobe = 1;
- /* Check for valid IRQ */
- if ((card->irq < 0) || (card->irq > 15) ||
- (!((1 << card->irq) & eicon_isa_valid_irq[card->type & 0x0f]))) {
- printk(KERN_WARNING "eicon_isa_load: invalid irq: %d\n", card->irq);
- eicon_isa_release_shmem(card);
- kfree(code);
- return -EINVAL;
- }
- /* Register irq */
- if (!request_irq(card->irq, &eicon_irq, 0, "Eicon ISA ISDN", card))
- card->ivalid = 1;
- else {
- printk(KERN_WARNING "eicon_isa_load: irq %d already in use.\n",
- card->irq);
- eicon_isa_release_shmem(card);
- kfree(code);
- return -EBUSY;
- }
- }
-
- tmp = readb(&boot->msize);
- if (tmp != 8 && tmp != 16 && tmp != 24 &&
- tmp != 32 && tmp != 48 && tmp != 60) {
- printk(KERN_WARNING "eicon_isa_load: invalid memsize\n");
- eicon_isa_release_shmem(card);
- return -EIO;
- }
-
- eicon_isa_printpar(card);
-
- /* Download firmware */
- printk(KERN_INFO "%s %dkB, loading firmware ...\n",
- eicon_ctype_name[card->type],
- tmp * 16);
- tmp = cbuf.firmware_len >> 8;
- p = code;
- while (tmp--) {
- memcpy_toio(&boot->b, p, 256);
- writeb(1, &boot->ctrl);
- timeout = jiffies + HZ / 10;
- while (time_before(jiffies, timeout)) {
- if (readb(&boot->ctrl) == 0)
- break;
- SLEEP(2);
- }
- if (readb(&boot->ctrl)) {
- printk(KERN_WARNING "eicon_isa_load: download timeout at 0x%x\n", p-code);
- eicon_isa_release(card);
- kfree(code);
- return -EIO;
- }
- p += 256;
- }
- kfree(code);
-
- /* Initialize firmware parameters */
- memcpy_toio(&card->shmem->c[8], &cbuf.tei, 14);
- memcpy_toio(&card->shmem->c[32], &cbuf.oad, 96);
- memcpy_toio(&card->shmem->c[128], &cbuf.oad, 96);
-
- /* Start firmware, wait for signature */
- writeb(2, &boot->ctrl);
- timeout = jiffies + (5*HZ);
- while (time_before(jiffies, timeout)) {
- if (readw(&boot->signature) == 0x4447)
- break;
- SLEEP(2);
- }
- if (readw(&boot->signature) != 0x4447) {
- printk(KERN_WARNING "eicon_isa_load: firmware selftest failed %04x\n",
- readw(&boot->signature));
- eicon_isa_release(card);
- return -EIO;
- }
-
- card->channels = readb(&card->shmem->c[0x3f6]);
-
- /* clear irq-requests, reset irq-count */
- readb(card->intack);
- writeb(0, card->intack);
-
- if (card->master) {
- card->irqprobe = 1;
- /* Trigger an interrupt and check if it is delivered */
- tmp = readb(&card->shmem->com.ReadyInt);
- tmp ++;
- writeb(tmp, &card->shmem->com.ReadyInt);
- timeout = jiffies + HZ / 5;
- while (time_before(jiffies, timeout)) {
- if (card->irqprobe > 1)
- break;
- SLEEP(2);
- }
- if (card->irqprobe == 1) {
- printk(KERN_WARNING "eicon_isa_load: IRQ # %d test failed\n", card->irq);
- eicon_isa_release(card);
- return -EIO;
- }
- }
-#ifdef EICON_MCA_DEBUG
- printk(KERN_INFO "eicon_isa_load: IRQ # %d test succeeded.\n", card->irq);
-#endif
-
- writeb(card->irq, &card->shmem->com.Int);
-
- /* initializing some variables */
- ((eicon_card *)card->card)->ReadyInt = 0;
- ((eicon_card *)card->card)->ref_in = 1;
- ((eicon_card *)card->card)->ref_out = 1;
- for(j=0; j<256; j++) ((eicon_card *)card->card)->IdTable[j] = NULL;
- for(j=0; j< (card->channels + 1); j++) {
- ((eicon_card *)card->card)->bch[j].e.busy = 0;
- ((eicon_card *)card->card)->bch[j].e.D3Id = 0;
- ((eicon_card *)card->card)->bch[j].e.B2Id = 0;
- ((eicon_card *)card->card)->bch[j].e.ref = 0;
- ((eicon_card *)card->card)->bch[j].e.Req = 0;
- ((eicon_card *)card->card)->bch[j].e.complete = 1;
- ((eicon_card *)card->card)->bch[j].fsm_state = EICON_STATE_NULL;
- }
-
- printk(KERN_INFO "Eicon: Supported channels: %d\n", card->channels);
- printk(KERN_INFO "%s successfully started\n", eicon_ctype_name[card->type]);
-
- /* Enable normal IRQ processing */
- card->irqprobe = 0;
- return 0;
-}
-
-#endif /* CONFIG_ISDN_DRV_EICON_ISA */
+++ /dev/null
-/* $Id: eicon_isa.h,v 1.1.4.1.2.2 2002/10/01 11:29:13 armin Exp $
- *
- * ISDN low-level module for Eicon active ISDN-Cards.
- *
- * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de)
- * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
- * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#ifndef eicon_isa_h
-#define eicon_isa_h
-
-#ifdef __KERNEL__
-#include <linux/config.h>
-
-/* Factory defaults for ISA-Cards */
-#define EICON_ISA_MEMBASE 0xd0000
-#define EICON_ISA_IRQ 3
-/* shmem offset for Quadro parts */
-#define EICON_ISA_QOFFSET 0x0800
-
-typedef struct {
- __u16 length __attribute__ ((packed)); /* length of data/parameter field */
- __u8 P[270]; /* data/parameter field */
-} eicon_scom_PBUFFER;
-
-/* General communication buffer */
-typedef struct {
- __u8 Req; /* request register */
- __u8 ReqId; /* request task/entity identification */
- __u8 Rc; /* return code register */
- __u8 RcId; /* return code task/entity identification */
- __u8 Ind; /* Indication register */
- __u8 IndId; /* Indication task/entity identification */
- __u8 IMask; /* Interrupt Mask Flag */
- __u8 RNR; /* Receiver Not Ready (set by PC) */
- __u8 XLock; /* XBuffer locked Flag */
- __u8 Int; /* ISDN interrupt */
- __u8 ReqCh; /* Channel field for layer-3 Requests */
- __u8 RcCh; /* Channel field for layer-3 Returncodes */
- __u8 IndCh; /* Channel field for layer-3 Indications */
- __u8 MInd; /* more data indication field */
- __u16 MLength; /* more data total packet length */
- __u8 ReadyInt; /* request field for ready interrupt */
- __u8 Reserved[12]; /* reserved space */
- __u8 IfType; /* 1 = 16k-Interface */
- __u16 Signature __attribute__ ((packed)); /* ISDN adapter Signature */
- eicon_scom_PBUFFER XBuffer; /* Transmit Buffer */
- eicon_scom_PBUFFER RBuffer; /* Receive Buffer */
-} eicon_isa_com;
-
-/* struct for downloading firmware */
-typedef struct {
- __u8 ctrl;
- __u8 card;
- __u8 msize;
- __u8 fill0;
- __u16 ebit __attribute__ ((packed));
- __u32 eloc __attribute__ ((packed));
- __u8 reserved[20];
- __u16 signature __attribute__ ((packed));
- __u8 fill[224];
- __u8 b[256];
-} eicon_isa_boot;
-
-/* Shared memory */
-typedef union {
- unsigned char c[0x400];
- eicon_isa_com com;
- eicon_isa_boot boot;
-} eicon_isa_shmem;
-
-/*
- * card's description
- */
-typedef struct {
- int ramsize;
- int irq; /* IRQ */
- unsigned long physmem; /* physical memory address */
-#ifdef CONFIG_MCA
- int io; /* IO-port for MCA brand */
-#endif /* CONFIG_MCA */
- void* card;
- eicon_isa_shmem* shmem; /* Shared-memory area */
- unsigned char* intack; /* Int-Acknowledge */
- unsigned char* stopcpu; /* Writing here stops CPU */
- unsigned char* startcpu; /* Writing here starts CPU */
- unsigned char type; /* card type */
- int channels; /* No. of channels */
- unsigned char irqprobe; /* Flag: IRQ-probing */
- unsigned char mvalid; /* Flag: Memory is valid */
- unsigned char ivalid; /* Flag: IRQ is valid */
- unsigned char master; /* Flag: Card ist Quadro 1/4 */
-} eicon_isa_card;
-
-/* Offsets for special locations on standard cards */
-#define INTACK 0x03fe
-#define STOPCPU 0x0400
-#define STARTCPU 0x0401
-#define RAMSIZE 0x0400
-/* Offsets for special location on PRI card */
-#define INTACK_P 0x3ffc
-#define STOPCPU_P 0x3ffe
-#define STARTCPU_P 0x3fff
-#define RAMSIZE_P 0x4000
-
-
-extern int eicon_isa_load(eicon_isa_card *card, eicon_isa_codebuf *cb);
-extern int eicon_isa_bootload(eicon_isa_card *card, eicon_isa_codebuf *cb);
-extern void eicon_isa_release(eicon_isa_card *card);
-extern void eicon_isa_printpar(eicon_isa_card *card);
-extern void eicon_isa_transmit(eicon_isa_card *card);
-extern int eicon_isa_find_card(int Mem, int Irq, char * Id);
-
-#endif /* __KERNEL__ */
-
-#endif /* eicon_isa_h */
+++ /dev/null
-/* $Id: eicon_mod.c,v 1.1.4.1.2.4 2002/10/01 11:29:13 armin Exp $
- *
- * ISDN lowlevel-module for Eicon active cards.
- *
- * Copyright 1997 by Fritz Elfert (fritz@isdn4linux.de)
- * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
- * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * Thanks to Eicon Networks for
- * documents, informations and hardware.
- *
- * Deutsche Mailbox Saar-Lor-Lux GmbH
- * for sponsoring and testing fax
- * capabilities with Diva Server cards.
- * (dor@deutschemailbox.de)
- *
- */
-
-#define DRIVERNAME "Eicon active ISDN driver"
-#define DRIVERRELEASE "2.0"
-#define DRIVERPATCH ".16"
-
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#ifdef CONFIG_MCA
-#include <linux/mca.h>
-#include <linux/mca-legacy.h>
-#endif /* CONFIG_MCA */
-
-#include "eicon.h"
-
-#include <linux/isdn/capicmd.h>
-
-#undef N_DATA
-#include "adapter.h"
-#include "uxio.h"
-
-#define INCLUDE_INLINE_FUNCS
-
-static eicon_card *cards = (eicon_card *) NULL; /* glob. var , contains
- start of card-list */
-
-static char *eicon_revision = "$Revision: 1.1.4.1.2.4 $";
-
-extern char *eicon_pci_revision;
-extern char *eicon_isa_revision;
-extern char *eicon_idi_revision;
-
-extern int do_ioctl(struct inode *pDivasInode, struct file *pDivasFile,
- unsigned int command, unsigned long arg);
-extern void eicon_pci_init_conf(eicon_card *card);
-
-#define EICON_CTRL_VERSION 2
-
-ulong DebugVar;
-
-spinlock_t eicon_lock;
-
-DESCRIPTOR idi_d[32];
-
-/* Parameters to be set by insmod */
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
-static int membase = -1;
-static int irq = -1;
-#endif
-static char *id = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
-
-MODULE_DESCRIPTION( "ISDN4Linux: Driver for Eicon active ISDN cards");
-MODULE_AUTHOR( "Armin Schindler");
-MODULE_LICENSE( "GPL");
-MODULE_PARM_DESC(id, "ID-String of first card");
-MODULE_PARM(id, "s");
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
-MODULE_PARM_DESC(membase, "Base address of first ISA card");
-MODULE_PARM_DESC(irq, "IRQ of first card");
-MODULE_PARM(membase, "i");
-MODULE_PARM(irq, "i");
-#endif
-
-char *eicon_ctype_name[] = {
- "ISDN-S",
- "ISDN-SX",
- "ISDN-SCOM",
- "ISDN-QUADRO",
- "ISDN-S2M",
- "DIVA Server BRI/PCI",
- "DIVA Server 4BRI/PCI",
- "DIVA Server 4BRI/PCI",
- "DIVA Server PRI/PCI"
-};
-
-static char *
-eicon_getrev(const char *revision)
-{
- char *rev;
- char *p;
- if ((p = strchr(revision, ':'))) {
- rev = p + 2;
- p = strchr(rev, '$');
- *--p = 0;
- } else rev = "?.??";
- return rev;
-
-}
-
-static eicon_chan *
-find_channel(eicon_card *card, int channel)
-{
- if ((channel >= 0) && (channel < card->nchannels))
- return &(card->bch[channel]);
- eicon_log(card, 1, "eicon: Invalid channel %d\n", channel);
- return NULL;
-}
-
-#ifdef CONFIG_PCI
-#ifdef CONFIG_ISDN_DRV_EICON_PCI
-/*
- * Find pcicard with given card number
- */
-static inline eicon_card *
-eicon_findnpcicard(int driverid)
-{
- eicon_card *p = cards;
-
- while (p) {
- if ((p->regname[strlen(p->regname)-1] == (driverid + '0')) &&
- (p->bus == EICON_BUS_PCI))
- return p;
- p = p->next;
- }
- return (eicon_card *) 0;
-}
-#endif
-#endif /* CONFIG_PCI */
-
-static void
-eicon_rcv_dispatch(unsigned long context)
-{
- struct eicon_card *card = (struct eicon_card *)context;
-
- switch (card->bus) {
- case EICON_BUS_ISA:
- case EICON_BUS_MCA:
- case EICON_BUS_PCI:
- eicon_io_rcv_dispatch(card);
- break;
- default:
- eicon_log(card, 1,
- "eicon_rcv_dispatch: Illegal bustype %d\n", card->bus);
- }
-}
-
-static void
-eicon_ack_dispatch(unsigned long context)
-{
- struct eicon_card *card = (struct eicon_card *)context;
-
- switch (card->bus) {
- case EICON_BUS_ISA:
- case EICON_BUS_MCA:
- case EICON_BUS_PCI:
- eicon_io_ack_dispatch(card);
- break;
- default:
- eicon_log(card, 1,
- "eicon_ack_dispatch: Illegal bustype %d\n", card->bus);
- }
-}
-
-static void
-eicon_transmit(unsigned long context)
-{
- struct eicon_card *card = (struct eicon_card *)context;
-
- switch (card->bus) {
- case EICON_BUS_ISA:
- case EICON_BUS_MCA:
- case EICON_BUS_PCI:
- eicon_io_transmit(card);
- break;
- default:
- eicon_log(card, 1,
- "eicon_transmit: Illegal bustype %d\n", card->bus);
- }
-}
-
-static int
-eicon_command(eicon_card * card, isdn_ctrl * c)
-{
- ulong a;
- eicon_chan *chan;
- eicon_cdef cdef;
-#ifdef CONFIG_PCI
-#ifdef CONFIG_ISDN_DRV_EICON_PCI
- dia_start_t dstart;
- int idi_length = 0;
-#endif
-#endif
- isdn_ctrl cmd;
- int ret = 0;
- unsigned long flags;
-
- eicon_log(card, 16, "eicon_cmd 0x%x with arg 0x%lx (0x%lx)\n",
- c->command, c->arg, (ulong) *c->parm.num);
-
- switch (c->command) {
- case ISDN_CMD_IOCTL:
- memcpy(&a, c->parm.num, sizeof(ulong));
- switch (c->arg) {
- case EICON_IOCTL_GETVER:
- return(EICON_CTRL_VERSION);
- case EICON_IOCTL_GETTYPE:
- if (card->bus == EICON_BUS_PCI) {
- if (copy_to_user((char *)a,
- &card->hwif.pci.master,
- sizeof(int)))
- return -EFAULT;
- }
- return(card->type);
- case EICON_IOCTL_GETMMIO:
- switch (card->bus) {
- case EICON_BUS_ISA:
- case EICON_BUS_MCA:
- return (int)card->hwif.isa.shmem;
- default:
- eicon_log(card, 1,
- "eicon: Illegal BUS type %d\n",
- card->bus);
- ret = -ENODEV;
- }
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
- case EICON_IOCTL_SETMMIO:
- if (card->flags & EICON_FLAGS_LOADED)
- return -EBUSY;
- switch (card->bus) {
- case EICON_BUS_ISA:
- if (eicon_isa_find_card(a,
- card->hwif.isa.irq,
- card->regname) < 0)
- return -EFAULT;
- card->hwif.isa.shmem = (eicon_isa_shmem *)a;
- return 0;
- case EICON_BUS_MCA:
-#ifdef CONFIG_MCA
- if (eicon_mca_find_card(
- 0, a,
- card->hwif.isa.irq,
- card->regname) < 0)
- return -EFAULT;
- card->hwif.isa.shmem = (eicon_isa_shmem *)a;
- return 0;
-#endif /* CONFIG_MCA */
- default:
- eicon_log(card, 1,
- "eicon: Illegal BUS type %d\n",
- card->bus);
- ret = -ENODEV;
- }
-#endif
- case EICON_IOCTL_GETIRQ:
- switch (card->bus) {
- case EICON_BUS_ISA:
- case EICON_BUS_MCA:
- return card->hwif.isa.irq;
- default:
- eicon_log(card, 1,
- "eicon: Illegal BUS type %d\n",
- card->bus);
- ret = -ENODEV;
- }
- case EICON_IOCTL_SETIRQ:
- if (card->flags & EICON_FLAGS_LOADED)
- return -EBUSY;
- if ((a < 2) || (a > 15))
- return -EFAULT;
- switch (card->bus) {
- case EICON_BUS_ISA:
- case EICON_BUS_MCA:
- card->hwif.isa.irq = a;
- return 0;
- default:
- eicon_log(card, 1,
- "eicon: Illegal BUS type %d\n",
- card->bus);
- ret = -ENODEV;
- }
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
- case EICON_IOCTL_LOADBOOT:
- if (card->flags & EICON_FLAGS_RUNNING)
- return -EBUSY;
- switch (card->bus) {
- case EICON_BUS_ISA:
- case EICON_BUS_MCA:
- ret = eicon_isa_bootload(
- &(card->hwif.isa),
- &(((eicon_codebuf *)a)->isa));
- break;
- default:
- eicon_log(card, 1,
- "eicon: Illegal BUS type %d\n",
- card->bus);
- ret = -ENODEV;
- }
- return ret;
-#endif
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
- case EICON_IOCTL_LOADISA:
- if (card->flags & EICON_FLAGS_RUNNING)
- return -EBUSY;
- switch (card->bus) {
- case EICON_BUS_ISA:
- case EICON_BUS_MCA:
- ret = eicon_isa_load(
- &(card->hwif.isa),
- &(((eicon_codebuf *)a)->isa));
- if (!ret) {
- card->flags |= EICON_FLAGS_LOADED;
- card->flags |= EICON_FLAGS_RUNNING;
- if (card->hwif.isa.channels > 1) {
- cmd.command = ISDN_STAT_ADDCH;
- cmd.driver = card->myid;
- cmd.arg = card->hwif.isa.channels - 1;
- card->interface.statcallb(&cmd);
- }
- cmd.command = ISDN_STAT_RUN;
- cmd.driver = card->myid;
- cmd.arg = 0;
- card->interface.statcallb(&cmd);
- }
- break;
- default:
- eicon_log(card, 1,
- "eicon: Illegal BUS type %d\n",
- card->bus);
- ret = -ENODEV;
- }
- return ret;
-#endif
- case EICON_IOCTL_MANIF:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!card->d)
- return -ENODEV;
- if (!card->d->features & DI_MANAGE)
- return -ENODEV;
- ret = eicon_idi_manage(
- card,
- (eicon_manifbuf *)a);
- return ret;
-
- case EICON_IOCTL_GETXLOG:
- return -ENODEV;
-
- case EICON_IOCTL_ADDCARD:
- if (copy_from_user(&cdef, (char *)a,
- sizeof(cdef)))
- return -EFAULT;
- if (!(eicon_addcard(0, cdef.membase, cdef.irq, cdef.id, 0)))
- return -EIO;
- return 0;
- case EICON_IOCTL_DEBUGVAR:
- DebugVar = a;
- eicon_log(card, 1, "Eicon: Debug Value set to %ld\n", DebugVar);
- return 0;
- case EICON_IOCTL_LOADPCI:
- eicon_log(card, 1, "Eicon: Wrong version of load-utility,\n");
- eicon_log(card, 1, "Eicon: re-compile eiconctrl !\n");
- eicon_log(card, 1, "Eicon: Maybe update of utility is necessary !\n");
- return -EINVAL;
- default:
-#ifdef CONFIG_PCI
-#ifdef CONFIG_ISDN_DRV_EICON_PCI
- if (c->arg < EICON_IOCTL_DIA_OFFSET)
- return -EINVAL;
- if (copy_from_user(&dstart, (char *)a,
- sizeof(dstart)))
- return -EFAULT;
- if (!(card = eicon_findnpcicard(dstart.card_id)))
- return -EINVAL;
- ret = do_ioctl(NULL, NULL,
- c->arg - EICON_IOCTL_DIA_OFFSET,
- (unsigned long) a);
- if (((c->arg - EICON_IOCTL_DIA_OFFSET)==DIA_IOCTL_START) && (!ret)) {
- if (card->type != EICON_CTYPE_MAESTRAQ) {
- DIVA_DIDD_Read(idi_d, sizeof(idi_d));
- for(idi_length = 0; idi_length < 32; idi_length++) {
- if (idi_d[idi_length].type == 0) break;
- }
- if ((idi_length < 1) || (idi_length >= 32)) {
- eicon_log(card, 1, "eicon: invalid idi table length.\n");
- break;
- }
- card->d = &idi_d[idi_length - 1];
- card->flags |= EICON_FLAGS_LOADED;
- card->flags |= EICON_FLAGS_RUNNING;
- eicon_pci_init_conf(card);
- if (card->d->channels > 1) {
- cmd.command = ISDN_STAT_ADDCH;
- cmd.driver = card->myid;
- cmd.arg = card->d->channels - 1;
- card->interface.statcallb(&cmd);
- }
- cmd.command = ISDN_STAT_RUN;
- cmd.driver = card->myid;
- cmd.arg = 0;
- card->interface.statcallb(&cmd);
- eicon_log(card, 1, "Eicon: %s started, %d channels (feat. 0x%x)\n",
- (card->type == EICON_CTYPE_MAESTRA) ? "BRI" : "PRI",
- card->d->channels, card->d->features);
- } else {
- int i;
- DIVA_DIDD_Read(idi_d, sizeof(idi_d));
- for(idi_length = 0; idi_length < 32; idi_length++)
- if (idi_d[idi_length].type == 0) break;
- if ((idi_length < 1) || (idi_length >= 32)) {
- eicon_log(card, 1, "eicon: invalid idi table length.\n");
- break;
- }
- for(i = 3; i >= 0; i--) {
- if (!(card = eicon_findnpcicard(dstart.card_id - i)))
- return -EINVAL;
-
- card->flags |= EICON_FLAGS_LOADED;
- card->flags |= EICON_FLAGS_RUNNING;
- card->d = &idi_d[idi_length - (i+1)];
- eicon_pci_init_conf(card);
- if (card->d->channels > 1) {
- cmd.command = ISDN_STAT_ADDCH;
- cmd.driver = card->myid;
- cmd.arg = card->d->channels - 1;
- card->interface.statcallb(&cmd);
- }
- cmd.command = ISDN_STAT_RUN;
- cmd.driver = card->myid;
- cmd.arg = 0;
- card->interface.statcallb(&cmd);
- eicon_log(card, 1, "Eicon: %d/4BRI started, %d channels (feat. 0x%x)\n",
- 4-i, card->d->channels, card->d->features);
- }
- }
- }
- return ret;
-#else
- return -EINVAL;
-#endif
-#endif /* CONFIG_PCI */
- }
- break;
- case ISDN_CMD_DIAL:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- spin_lock_irqsave(&eicon_lock, flags);
- if ((chan->fsm_state != EICON_STATE_NULL) && (chan->fsm_state != EICON_STATE_LISTEN)) {
- spin_unlock_irqrestore(&eicon_lock, flags);
- eicon_log(card, 1, "Dial on channel %d with state %d\n",
- chan->No, chan->fsm_state);
- return -EBUSY;
- }
- chan->fsm_state = EICON_STATE_OCALL;
- spin_unlock_irqrestore(&eicon_lock, flags);
-
- ret = idi_connect_req(card, chan, c->parm.setup.phone,
- c->parm.setup.eazmsn,
- c->parm.setup.si1,
- c->parm.setup.si2);
- if (ret) {
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_DHUP;
- cmd.arg &= 0x1f;
- card->interface.statcallb(&cmd);
- }
- return ret;
- case ISDN_CMD_ACCEPTD:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- if (chan->fsm_state == EICON_STATE_ICALL) {
- idi_connect_res(card, chan);
- }
- return 0;
- case ISDN_CMD_ACCEPTB:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- return 0;
- case ISDN_CMD_HANGUP:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- idi_hangup(card, chan);
- return 0;
- case ISDN_CMD_SETEAZ:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- chan->eazmask = 0x3ff;
- eicon_idi_listen_req(card, chan);
- return 0;
- case ISDN_CMD_CLREAZ:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- chan->eazmask = 0;
- eicon_idi_listen_req(card, chan);
- return 0;
- case ISDN_CMD_SETL2:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- chan->l2prot = (c->arg >> 8);
- return 0;
- case ISDN_CMD_SETL3:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- chan->l3prot = (c->arg >> 8);
-#ifdef CONFIG_ISDN_TTY_FAX
- if (chan->l3prot == ISDN_PROTO_L3_FCLASS2) {
- chan->fax = c->parm.fax;
- eicon_log(card, 128, "idi_cmd: Ch%d: SETL3 struct fax=0x%x\n",chan->No, chan->fax);
- }
-#endif
- return 0;
-#ifdef CONFIG_ISDN_TTY_FAX
- case ISDN_CMD_FAXCMD:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- if (!chan->fax)
- break;
- idi_fax_cmd(card, chan);
- return 0;
-#endif
- case ISDN_CMD_AUDIO:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- idi_audio_cmd(card, chan, c->arg >> 8, c->parm.num);
- return 0;
- case CAPI_PUT_MESSAGE:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- if (c->parm.cmsg.Length < 8)
- break;
- switch(c->parm.cmsg.Command) {
- case CAPI_FACILITY:
- if (c->parm.cmsg.Subcommand == CAPI_REQ)
- return(capipmsg(card, chan, &c->parm.cmsg));
- break;
- case CAPI_MANUFACTURER:
- default:
- break;
- }
- return 0;
- }
-
- return -EINVAL;
-}
-
-/*
- * Find card with given driverId
- */
-static inline eicon_card *
-eicon_findcard(int driverid)
-{
- eicon_card *p = cards;
-
- while (p) {
- if (p->myid == driverid)
- return p;
- p = p->next;
- }
- return (eicon_card *) 0;
-}
-
-/*
- * Wrapper functions for interface to linklevel
- */
-static int
-if_command(isdn_ctrl * c)
-{
- eicon_card *card = eicon_findcard(c->driver);
-
- if (card)
- return (eicon_command(card, c));
- printk(KERN_ERR
- "eicon: if_command %d called with invalid driverId %d!\n",
- c->command, c->driver);
- return -ENODEV;
-}
-
-static int
-if_writecmd(const u_char * buf, int len, int user, int id, int channel)
-{
- return (len);
-}
-
-static int
-if_readstatus(u_char * buf, int len, int user, int id, int channel)
-{
- int count = 0;
- int cnt = 0;
- ulong flags = 0;
- u_char *p = buf;
- struct sk_buff *skb;
-
- eicon_card *card = eicon_findcard(id);
-
- if (card) {
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
-
- spin_lock_irqsave(&eicon_lock, flags);
- while((skb = skb_dequeue(&card->statq))) {
-
- if ((skb->len + count) > len)
- cnt = len - count;
- else
- cnt = skb->len;
-
- if (user) {
- spin_unlock_irqrestore(&eicon_lock, flags);
- if (copy_to_user(p, skb->data, cnt))
- return -EFAULT;
- spin_lock_irqsave(&eicon_lock, flags);
- }
- else
- memcpy(p, skb->data, cnt);
-
- count += cnt;
- p += cnt;
-
- if (cnt == skb->len) {
- dev_kfree_skb(skb);
- if (card->statq_entries > 0)
- card->statq_entries--;
- } else {
- skb_pull(skb, cnt);
- skb_queue_head(&card->statq, skb);
- spin_unlock_irqrestore(&eicon_lock, flags);
- return count;
- }
- }
- card->statq_entries = 0;
- spin_unlock_irqrestore(&eicon_lock, flags);
- return count;
- }
- printk(KERN_ERR
- "eicon: if_readstatus called with invalid driverId!\n");
- return 0;
-}
-
-static int
-if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
-{
- eicon_card *card = eicon_findcard(id);
- eicon_chan *chan;
- int ret = 0;
- int len;
-
- len = skb->len;
-
- if (card) {
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, channel)))
- return -ENODEV;
-
- if (chan->fsm_state == EICON_STATE_ACTIVE) {
-#ifdef CONFIG_ISDN_TTY_FAX
- if (chan->l2prot == ISDN_PROTO_L2_FAX) {
- if ((ret = idi_faxdata_send(card, chan, skb)) > 0)
- ret = len;
- }
- else
-#endif
- ret = idi_send_data(card, chan, ack, skb, 1, 1);
- return (ret);
- } else {
- return -ENODEV;
- }
- }
- printk(KERN_ERR
- "eicon: if_sendbuf called with invalid driverId!\n");
- return -ENODEV;
-}
-
-/* jiftime() copied from HiSax */
-static inline int jiftime(char *s, long mark)
-{
- s += 8;
-
- *s-- = '\0';
- *s-- = mark % 10 + '0';
- mark /= 10;
- *s-- = mark % 10 + '0';
- mark /= 10;
- *s-- = '.';
- *s-- = mark % 10 + '0';
- mark /= 10;
- *s-- = mark % 6 + '0';
- mark /= 6;
- *s-- = ':';
- *s-- = mark % 10 + '0';
- mark /= 10;
- *s-- = mark % 10 + '0';
- return(8);
-}
-
-void
-eicon_putstatus(eicon_card * card, char * buf)
-{
- ulong flags;
- int count;
- isdn_ctrl cmd;
- u_char *p;
- struct sk_buff *skb;
-
- if (!card) {
- if (!(card = cards))
- return;
- }
-
- spin_lock_irqsave(&eicon_lock, flags);
- count = strlen(buf);
- skb = alloc_skb(count, GFP_ATOMIC);
- if (!skb) {
- spin_unlock_irqrestore(&eicon_lock, flags);
- printk(KERN_ERR "eicon: could not alloc skb in putstatus\n");
- return;
- }
- p = skb_put(skb, count);
- memcpy(p, buf, count);
-
- skb_queue_tail(&card->statq, skb);
-
- if (card->statq_entries >= MAX_STATUS_BUFFER) {
- if ((skb = skb_dequeue(&card->statq))) {
- count -= skb->len;
- dev_kfree_skb(skb);
- } else
- count = 0;
- } else
- card->statq_entries++;
-
- spin_unlock_irqrestore(&eicon_lock, flags);
- if (count) {
- cmd.command = ISDN_STAT_STAVAIL;
- cmd.driver = card->myid;
- cmd.arg = count;
- card->interface.statcallb(&cmd);
- }
-}
-
-/*
- * Debug and Log
- */
-void
-eicon_log(eicon_card * card, int level, const char *fmt, ...)
-{
- va_list args;
- char Line[160];
- u_char *p;
-
-
- if ((DebugVar & level) || (DebugVar & 256)) {
- va_start(args, fmt);
-
- if (DebugVar & level) {
- if (DebugVar & 256) {
- /* log-buffer */
- p = Line;
- p += jiftime(p, jiffies);
- *p++ = 32;
- p += vsprintf(p, fmt, args);
- *p = 0;
- eicon_putstatus(card, Line);
- } else {
- /* printk, syslogd */
- vsprintf(Line, fmt, args);
- printk(KERN_DEBUG "%s", Line);
- }
- }
-
- va_end(args);
- }
-}
-
-
-/*
- * Allocate a new card-struct, initialize it
- * link it into cards-list.
- */
-static void
-eicon_alloccard(int Type, int membase, int irq, char *id, int card_id)
-{
- int i;
- int j;
- int qloop;
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
- char qid[5];
-#endif
- eicon_card *card;
-
- qloop = (Type == EICON_CTYPE_QUADRO)?2:0;
- for (i = 0; i <= qloop; i++) {
- if (!(card = (eicon_card *) kmalloc(sizeof(eicon_card), GFP_KERNEL))) {
- eicon_log(card, 1,
- "eicon: (%s) Could not allocate card-struct.\n", id);
- return;
- }
- memset((char *) card, 0, sizeof(eicon_card));
- skb_queue_head_init(&card->sndq);
- skb_queue_head_init(&card->rcvq);
- skb_queue_head_init(&card->rackq);
- skb_queue_head_init(&card->sackq);
- skb_queue_head_init(&card->statq);
- card->statq_entries = 0;
- tasklet_init(&card->snd_tq, eicon_transmit, (unsigned long)card);
- tasklet_init(&card->rcv_tq, eicon_rcv_dispatch, (unsigned long)card);
- tasklet_init(&card->ack_tq, eicon_ack_dispatch, (unsigned long)card);
- card->interface.owner = THIS_MODULE;
- card->interface.maxbufsize = 4000;
- card->interface.command = if_command;
- card->interface.writebuf_skb = if_sendbuf;
- card->interface.writecmd = if_writecmd;
- card->interface.readstat = if_readstatus;
- card->interface.features =
- ISDN_FEATURE_L2_X75I |
- ISDN_FEATURE_L2_HDLC |
- ISDN_FEATURE_L2_TRANS |
- ISDN_FEATURE_L3_TRANS |
- ISDN_FEATURE_P_UNKNOWN;
- card->interface.hl_hdrlen = 20;
- card->ptype = ISDN_PTYPE_UNKNOWN;
- strlcpy(card->interface.id, id, sizeof(card->interface.id));
- card->myid = -1;
- card->type = Type;
- switch (Type) {
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
-#ifdef CONFIG_MCA /* only needed for MCA */
- case EICON_CTYPE_S:
- case EICON_CTYPE_SX:
- case EICON_CTYPE_SCOM:
- if (MCA_bus) {
- if (membase == -1)
- membase = EICON_ISA_MEMBASE;
- if (irq == -1)
- irq = EICON_ISA_IRQ;
- card->bus = EICON_BUS_MCA;
- card->hwif.isa.card = (void *)card;
- card->hwif.isa.shmem = (eicon_isa_shmem *)membase;
- card->hwif.isa.physmem = (unsigned long)membase;
- card->hwif.isa.master = 1;
-
- card->hwif.isa.irq = irq;
- card->hwif.isa.type = Type;
- card->nchannels = 2;
- card->interface.channels = 1;
- } else {
- printk(KERN_WARNING
- "eicon (%s): no MCA bus detected.\n",
- card->interface.id);
- kfree(card);
- return;
- }
- break;
-#endif /* CONFIG_MCA */
- case EICON_CTYPE_QUADRO:
- if (membase == -1)
- membase = EICON_ISA_MEMBASE;
- if (irq == -1)
- irq = EICON_ISA_IRQ;
- card->bus = EICON_BUS_ISA;
- card->hwif.isa.card = (void *)card;
- card->hwif.isa.shmem = (eicon_isa_shmem *)(membase + (i+1) * EICON_ISA_QOFFSET);
- card->hwif.isa.physmem = (unsigned long)(membase + (i+1) * EICON_ISA_QOFFSET);
- card->hwif.isa.master = 0;
- strcpy(card->interface.id, id);
- if (id[strlen(id) - 1] == 'a') {
- card->interface.id[strlen(id) - 1] = 'a' + i + 1;
- } else {
- sprintf(qid, "_%c",'2' + i);
- strcat(card->interface.id, qid);
- }
- printk(KERN_INFO "Eicon: Quadro: Driver-Id %s added.\n",
- card->interface.id);
- if (i == 0) {
- eicon_card *p = cards;
- while(p) {
- if ((p->hwif.isa.master) && (p->hwif.isa.irq == irq)) {
- p->qnext = card;
- break;
- }
- p = p->next;
- }
- if (!p) {
- eicon_log(card, 1, "eicon_alloccard: Quadro Master not found.\n");
- kfree(card);
- return;
- }
- } else {
- cards->qnext = card;
- }
- card->hwif.isa.irq = irq;
- card->hwif.isa.type = Type;
- card->nchannels = 2;
- card->interface.channels = 1;
- break;
-#endif
-#ifdef CONFIG_PCI
-#ifdef CONFIG_ISDN_DRV_EICON_PCI
- case EICON_CTYPE_MAESTRA:
- card->bus = EICON_BUS_PCI;
- card->interface.features |=
- ISDN_FEATURE_L2_V11096 |
- ISDN_FEATURE_L2_V11019 |
- ISDN_FEATURE_L2_V11038 |
- ISDN_FEATURE_L2_MODEM |
- ISDN_FEATURE_L2_FAX |
- ISDN_FEATURE_L3_TRANSDSP |
- ISDN_FEATURE_L3_FCLASS2;
- card->hwif.pci.card = (void *)card;
- card->hwif.pci.master = card_id;
- card->hwif.pci.irq = irq;
- card->hwif.pci.type = Type;
- card->flags = 0;
- card->nchannels = 2;
- card->interface.channels = 1;
- break;
-
- case EICON_CTYPE_MAESTRAQ:
- card->bus = EICON_BUS_PCI;
- card->interface.features |=
- ISDN_FEATURE_L2_V11096 |
- ISDN_FEATURE_L2_V11019 |
- ISDN_FEATURE_L2_V11038 |
- ISDN_FEATURE_L2_MODEM |
- ISDN_FEATURE_L2_FAX |
- ISDN_FEATURE_L3_TRANSDSP |
- ISDN_FEATURE_L3_FCLASS2;
- card->hwif.pci.card = (void *)card;
- card->hwif.pci.master = card_id;
- card->hwif.pci.irq = irq;
- card->hwif.pci.type = Type;
- card->flags = 0;
- card->nchannels = 2;
- card->interface.channels = 1;
- break;
-
- case EICON_CTYPE_MAESTRAP:
- card->bus = EICON_BUS_PCI;
- card->interface.features |=
- ISDN_FEATURE_L2_V11096 |
- ISDN_FEATURE_L2_V11019 |
- ISDN_FEATURE_L2_V11038 |
- ISDN_FEATURE_L2_MODEM |
- ISDN_FEATURE_L2_FAX |
- ISDN_FEATURE_L3_TRANSDSP |
- ISDN_FEATURE_L3_FCLASS2;
- card->hwif.pci.card = (void *)card;
- card->hwif.pci.master = card_id;
- card->hwif.pci.irq = irq;
- card->hwif.pci.type = Type;
- card->flags = 0;
- card->nchannels = 30;
- card->interface.channels = 1;
- break;
-#endif
-#endif
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
- case EICON_CTYPE_ISABRI:
- if (membase == -1)
- membase = EICON_ISA_MEMBASE;
- if (irq == -1)
- irq = EICON_ISA_IRQ;
- card->bus = EICON_BUS_ISA;
- card->hwif.isa.card = (void *)card;
- card->hwif.isa.shmem = (eicon_isa_shmem *)membase;
- card->hwif.isa.physmem = (unsigned long)membase;
- card->hwif.isa.master = 1;
- card->hwif.isa.irq = irq;
- card->hwif.isa.type = Type;
- card->nchannels = 2;
- card->interface.channels = 1;
- break;
- case EICON_CTYPE_ISAPRI:
- if (membase == -1)
- membase = EICON_ISA_MEMBASE;
- if (irq == -1)
- irq = EICON_ISA_IRQ;
- card->bus = EICON_BUS_ISA;
- card->hwif.isa.card = (void *)card;
- card->hwif.isa.shmem = (eicon_isa_shmem *)membase;
- card->hwif.isa.physmem = (unsigned long)membase;
- card->hwif.isa.master = 1;
- card->hwif.isa.irq = irq;
- card->hwif.isa.type = Type;
- card->nchannels = 30;
- card->interface.channels = 1;
- break;
-#endif
- default:
- eicon_log(card, 1, "eicon_alloccard: Invalid type %d\n", Type);
- kfree(card);
- return;
- }
- if (!(card->bch = (eicon_chan *) kmalloc(sizeof(eicon_chan) * (card->nchannels + 1)
- , GFP_KERNEL))) {
- eicon_log(card, 1,
- "eicon: (%s) Could not allocate bch-struct.\n", id);
- kfree(card);
- return;
- }
- for (j=0; j< (card->nchannels + 1); j++) {
- memset((char *)&card->bch[j], 0, sizeof(eicon_chan));
- card->bch[j].statectrl = 0;
- card->bch[j].l2prot = ISDN_PROTO_L2_X75I;
- card->bch[j].l3prot = ISDN_PROTO_L3_TRANS;
- card->bch[j].e.D3Id = 0;
- card->bch[j].e.B2Id = 0;
- card->bch[j].e.Req = 0;
- card->bch[j].No = j;
- card->bch[j].tskb1 = NULL;
- card->bch[j].tskb2 = NULL;
- skb_queue_head_init(&card->bch[j].e.X);
- skb_queue_head_init(&card->bch[j].e.R);
- }
-
-#ifdef CONFIG_ISDN_DRV_EICON_PCI
- /* *** Diva Server *** */
- if (!(card->dbuf = (DBUFFER *) kmalloc((sizeof(DBUFFER) * (card->nchannels + 1))*2
- , GFP_KERNEL))) {
- eicon_log(card, 1,
- "eicon: (%s) Could not allocate DBUFFER-struct.\n", id);
- kfree(card);
- kfree(card->bch);
- return;
- }
- if (!(card->sbuf = (BUFFERS *) kmalloc((sizeof(BUFFERS) * (card->nchannels + 1)) * 2, GFP_KERNEL))) {
- eicon_log(card, 1,
- "eicon: (%s) Could not allocate BUFFERS-struct.\n", id);
- kfree(card);
- kfree(card->bch);
- kfree(card->dbuf);
- return;
- }
- if (!(card->sbufp = (char *) kmalloc((270 * (card->nchannels + 1)) * 2, GFP_KERNEL))) {
- eicon_log(card, 1,
- "eicon: (%s) Could not allocate BUFFERSP-struct.\n", id);
- kfree(card);
- kfree(card->bch);
- kfree(card->dbuf);
- kfree(card->sbuf);
- return;
- }
- for (j=0; j< (card->nchannels + 1); j++) {
- memset((char *)&card->dbuf[j], 0, sizeof(DBUFFER));
- card->bch[j].de.RBuffer = (DBUFFER *)&card->dbuf[j];
- memset((char *)&card->dbuf[j+(card->nchannels+1)], 0, sizeof(BUFFERS));
- card->bch[j].be.RBuffer = (DBUFFER *)&card->dbuf[j+(card->nchannels+1)];
-
- memset((char *)&card->sbuf[j], 0, sizeof(BUFFERS));
- card->bch[j].de.X = (BUFFERS *)&card->sbuf[j];
- memset((char *)&card->sbuf[j+(card->nchannels+1)], 0, sizeof(BUFFERS));
- card->bch[j].be.X = (BUFFERS *)&card->sbuf[j+(card->nchannels+1)];
-
- memset((char *)&card->sbufp[j], 0, 270);
- card->bch[j].de.X->P = (char *)&card->sbufp[j * 270];
- memset((char *)&card->sbufp[j+(card->nchannels+1)], 0, 270);
- card->bch[j].be.X->P = (char *)&card->sbufp[(j+(card->nchannels+1)) * 270];
- }
- /* *** */
-#endif /* CONFIG_ISDN_DRV_EICON_PCI */
-
- card->next = cards;
- cards = card;
- }
-}
-
-/*
- * register card at linklevel
- */
-static int
-eicon_registercard(eicon_card * card)
-{
- switch (card->bus) {
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
- case EICON_BUS_ISA:
- /* TODO something to print */
- break;
-#ifdef CONFIG_MCA
- case EICON_BUS_MCA:
- eicon_isa_printpar(&card->hwif.isa);
- break;
-#endif /* CONFIG_MCA */
-#endif
- case EICON_BUS_PCI:
- break;
- default:
- eicon_log(card, 1,
- "eicon_registercard: Illegal BUS type %d\n",
- card->bus);
- return -1;
- }
- if (!register_isdn(&card->interface)) {
- printk(KERN_WARNING
- "eicon_registercard: Unable to register %s\n",
- card->interface.id);
- return -1;
- }
- card->myid = card->interface.channels;
- sprintf(card->regname, "%s", card->interface.id);
- return 0;
-}
-
-static void __exit
-unregister_card(eicon_card * card)
-{
- isdn_ctrl cmd;
-
- cmd.command = ISDN_STAT_UNLOAD;
- cmd.driver = card->myid;
- card->interface.statcallb(&cmd);
- switch (card->bus) {
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
- case EICON_BUS_ISA:
-#ifdef CONFIG_MCA
- case EICON_BUS_MCA:
-#endif /* CONFIG_MCA */
- eicon_isa_release(&card->hwif.isa);
- break;
-#endif
- case EICON_BUS_PCI:
- break;
- default:
- eicon_log(card, 1,
- "eicon: Invalid BUS type %d\n",
- card->bus);
- break;
- }
-}
-
-static void
-eicon_freecard(eicon_card *card) {
- int i;
-
- for(i = 0; i < (card->nchannels + 1); i++) {
- skb_queue_purge(&card->bch[i].e.X);
- skb_queue_purge(&card->bch[i].e.R);
- }
- skb_queue_purge(&card->sndq);
- skb_queue_purge(&card->rcvq);
- skb_queue_purge(&card->rackq);
- skb_queue_purge(&card->sackq);
- skb_queue_purge(&card->statq);
-
-#ifdef CONFIG_ISDN_DRV_EICON_PCI
- kfree(card->sbufp);
- kfree(card->sbuf);
- kfree(card->dbuf);
-#endif
- kfree(card->bch);
- kfree(card);
-}
-
-int
-eicon_addcard(int Type, int membase, int irq, char *id, int card_id)
-{
- eicon_card *p;
- eicon_card *q = NULL;
- int registered;
- int added = 0;
- int failed = 0;
-
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
- if (!Type) /* ISA */
- if ((Type = eicon_isa_find_card(membase, irq, id)) < 0)
- return 0;
-#endif
- eicon_alloccard(Type, membase, irq, id, card_id);
- p = cards;
- while (p) {
- registered = 0;
- if (!p->interface.statcallb) {
- /* Not yet registered.
- * Try to register and activate it.
- */
- added++;
- switch (p->bus) {
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
- case EICON_BUS_ISA:
- case EICON_BUS_MCA:
- if (eicon_registercard(p))
- break;
- registered = 1;
- break;
-#endif
- case EICON_BUS_PCI:
-#ifdef CONFIG_PCI
-#ifdef CONFIG_ISDN_DRV_EICON_PCI
- if (eicon_registercard(p))
- break;
- registered = 1;
- break;
-#endif
-#endif
- default:
- printk(KERN_ERR
- "eicon: addcard: Invalid BUS type %d\n",
- p->bus);
- }
- } else
- /* Card already registered */
- registered = 1;
- if (registered) {
- /* Init OK, next card ... */
- q = p;
- p = p->next;
- } else {
- /* registering failed, remove card from list, free memory */
- printk(KERN_ERR
- "eicon: Initialization of %s failed\n",
- p->interface.id);
- if (q) {
- q->next = p->next;
- eicon_freecard(p);
- p = q->next;
- } else {
- cards = p->next;
- eicon_freecard(p);
- p = cards;
- }
- failed++;
- }
- }
- return (added - failed);
-}
-
-
-static int __init
-eicon_init(void)
-{
- int card_count = 0;
- char tmprev[50];
-
- DebugVar = 1;
- eicon_lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
-
- printk(KERN_INFO "%s Rev: ", DRIVERNAME);
- strcpy(tmprev, eicon_revision);
- printk("%s/", eicon_getrev(tmprev));
- strcpy(tmprev, eicon_pci_revision);
-#ifdef CONFIG_ISDN_DRV_EICON_PCI
- printk("%s/", eicon_getrev(tmprev));
-#else
- printk("---/");
-#endif
- strcpy(tmprev, eicon_isa_revision);
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
- printk("%s/", eicon_getrev(tmprev));
-#else
- printk("---/");
-#endif
- strcpy(tmprev, eicon_idi_revision);
- printk("%s\n", eicon_getrev(tmprev));
- printk(KERN_INFO "%s Release: %s%s\n", DRIVERNAME,
- DRIVERRELEASE, DRIVERPATCH);
-
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
-#ifdef CONFIG_MCA
- /* Check if we have MCA-bus */
- if (!MCA_bus)
- {
- printk(KERN_INFO
- "eicon: No MCA bus, ISDN-interfaces not probed.\n");
- } else {
- eicon_log(NULL, 8,
- "eicon_mca_find_card, irq=%d.\n",
- irq);
- if (!eicon_mca_find_card(0, membase, irq, id))
- card_count++;
- };
-#else
- card_count = eicon_addcard(0, membase, irq, id, 0);
-#endif /* CONFIG_MCA */
-#endif /* CONFIG_ISDN_DRV_EICON_ISA */
-
-#ifdef CONFIG_PCI
-#ifdef CONFIG_ISDN_DRV_EICON_PCI
- DivasCardsDiscover();
- card_count += eicon_pci_find_card(id);
-#endif
-#endif
-
- if (!cards) {
-#ifdef MODULE
-#ifndef CONFIG_ISDN_DRV_EICON_PCI
-#ifndef CONFIG_ISDN_DRV_EICON_ISA
- printk(KERN_INFO "Eicon: Driver is neither ISA nor PCI compiled !\n");
- printk(KERN_INFO "Eicon: Driver not loaded !\n");
-#else
- printk(KERN_INFO "Eicon: No cards defined, driver not loaded !\n");
-#endif
-#else
- printk(KERN_INFO "Eicon: No PCI-cards found, driver not loaded !\n");
-#endif
-#endif /* MODULE */
- return -ENODEV;
-
- } else
- printk(KERN_INFO "Eicon: %d card%s added\n", card_count,
- (card_count>1)?"s":"");
- return 0;
-}
-
-#ifdef CONFIG_ISDN_DRV_EICON_PCI
-void DIVA_DIDD_Write(DESCRIPTOR *, int);
-EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Read);
-EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Write);
-EXPORT_SYMBOL_NOVERS(DivasPrintf);
-#else
-int DivasCardNext;
-card_t DivasCards[1];
-#endif
-
-static void __exit
-eicon_exit(void)
-{
-#ifdef CONFIG_PCI
-#ifdef CONFIG_ISDN_DRV_EICON_PCI
- card_t *pCard;
- word wCardIndex;
- extern int Divas_major;
- int iTmp = 0;
-#endif
-#endif
-
- eicon_card *card = cards;
- eicon_card *last;
-
- while (card) {
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
-#ifdef CONFIG_MCA
- if (MCA_bus)
- {
- mca_mark_as_unused (card->mca_slot);
- mca_set_adapter_procfn(card->mca_slot, NULL, NULL);
- };
-#endif /* CONFIG_MCA */
-#endif
- unregister_card(card);
- card = card->next;
- }
- card = cards;
- while (card) {
- last = card;
- card = card->next;
- eicon_freecard(last);
- }
-
-#ifdef CONFIG_PCI
-#ifdef CONFIG_ISDN_DRV_EICON_PCI
- pCard = DivasCards;
- for (wCardIndex = 0; wCardIndex < MAX_CARDS; wCardIndex++)
- {
- if ((pCard->hw) && (pCard->hw->in_use))
- {
- (*pCard->card_reset)(pCard);
-
- UxIsrRemove(pCard->hw, pCard);
- UxCardHandleFree(pCard->hw);
-
- if(pCard->e_tbl != NULL)
- {
- kfree(pCard->e_tbl);
- }
-
- if(pCard->hw->card_type == DIA_CARD_TYPE_DIVA_SERVER_B)
- {
- release_region(pCard->hw->io_base,0x20);
- release_region(pCard->hw->reset_base,0x80);
- }
-
- // If this is a 4BRI ...
- if (pCard->hw->card_type == DIA_CARD_TYPE_DIVA_SERVER_Q)
- {
- // Skip over the next 3 virtual adapters
- wCardIndex += 3;
-
- // But free their handles
- for (iTmp = 0; iTmp < 3; iTmp++)
- {
- pCard++;
- UxCardHandleFree(pCard->hw);
-
- if(pCard->e_tbl != NULL)
- {
- kfree(pCard->e_tbl);
- }
- }
- }
- }
- pCard++;
- }
- unregister_chrdev(Divas_major, "Divas");
-#endif
-#endif /* CONFIG_PCI */
- printk(KERN_INFO "%s unloaded\n", DRIVERNAME);
-}
-
-#ifndef MODULE
-
-static int __init
-eicon_setup(char *line)
-{
- int i, argc;
- int ints[5];
- char *str;
-
- str = get_options(line, 4, ints);
-
- argc = ints[0];
- i = 1;
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
- if (argc) {
- membase = irq = -1;
- if (argc) {
- membase = ints[i];
- i++;
- argc--;
- }
- if (argc) {
- irq = ints[i];
- i++;
- argc--;
- }
- if (strlen(str)) {
- strcpy(id, str);
- } else {
- strcpy(id, "eicon");
- }
- printk(KERN_INFO "Eicon ISDN active driver setup (id=%s membase=0x%x irq=%d)\n",
- id, membase, irq);
- }
-#else
- printk(KERN_INFO "Eicon ISDN active driver setup\n");
-#endif
- return(1);
-}
-__setup("eicon=", eicon_setup);
-
-#endif /* MODULE */
-
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
-#ifdef CONFIG_MCA
-
-struct eicon_mca_adapters_struct {
- char * name;
- int adf_id;
-};
-/* possible MCA-brands of eicon cards */
-struct eicon_mca_adapters_struct eicon_mca_adapters[] = {
- { "ISDN-P/2 Adapter", 0x6abb },
- { "ISDN-[S|SX|SCOM]/2 Adapter", 0x6a93 },
- { "DIVA /MCA", 0x6336 },
- { NULL, 0 },
-};
-
-int eicon_mca_find_card(int type, /* type-idx of eicon-card */
- int membase,
- int irq,
- char * id) /* name of eicon-isdn-dev */
-{
- int j, curr_slot = 0;
-
- eicon_log(NULL, 8,
- "eicon_mca_find_card type: %d, membase: %#x, irq %d \n",
- type, membase, irq);
- /* find a no-driver-assigned eicon card */
- for (j=0; eicon_mca_adapters[j].adf_id != 0; j++)
- {
- for ( curr_slot=0; curr_slot<=MCA_MAX_SLOT_NR; curr_slot++)
- {
- curr_slot = mca_find_unused_adapter(
- eicon_mca_adapters[j].adf_id, curr_slot);
- if (curr_slot != MCA_NOTFOUND)
- {
- /* check if pre-set parameters match
- these of the card, check cards memory */
- if (!(int) eicon_mca_probe(curr_slot,
- j,
- membase,
- irq,
- id))
- {
- return 0;
- /* means: adapter parms did match */
- };
- };
- break;
- /* MCA_NOTFOUND-branch: no matching adapter of
- THIS flavor found, next flavor */
-
- };
- };
- /* all adapter flavors checked without match, finito with: */
- return -ENODEV;
-};
-
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- * stolen from 3c523.c/elmc_getinfo, ewe, 10.5.1999
- */
-int eicon_info(char * buf, int slot, void *d)
-{
- int len = 0;
- struct eicon_card *dev;
-
- dev = (struct eicon_card *) d;
-
- if (dev == NULL)
- return len;
- len += sprintf(buf+len, "eicon ISDN adapter, type %d.\n",dev->type);
- len += sprintf(buf+len, "IRQ: %d\n", dev->hwif.isa.irq);
- len += sprintf(buf+len, "MEMBASE: %#lx\n", (unsigned long)dev->hwif.isa.shmem);
-
- return len;
-};
-
-int eicon_mca_probe(int slot, /* slot-nr where the card was detected */
- int a_idx, /* idx-nr of probed card in eicon_mca_adapters */
- int membase,
- int irq,
- char * id) /* name of eicon-isdn-dev */
-{
- unsigned char adf_pos0;
- int cards_irq, cards_membase, cards_io;
- int type = EICON_CTYPE_S;
- int irq_array[]={0,3,4,2};
- int irq_array1[]={3,4,0,0,2,10,11,12};
-
- adf_pos0 = mca_read_stored_pos(slot,2);
- eicon_log(NULL, 8,
- "eicon_mca_probe irq=%d, membase=%d\n",
- irq,
- membase);
- switch (a_idx) {
- case 0: /* P/2-Adapter (== PRI/S2M ? ) */
- cards_membase= 0xC0000+((adf_pos0>>4)*0x4000);
- if (membase == -1) {
- membase = cards_membase;
- } else {
- if (membase != cards_membase)
- return -ENODEV;
- };
- cards_irq=irq_array[((adf_pos0 & 0xC)>>2)];
- if (irq == -1) {
- irq = cards_irq;
- } else {
- if (irq != cards_irq)
- return -ENODEV;
- };
- cards_io= 0xC00 + ((adf_pos0>>4)*0x10);
- type = EICON_CTYPE_ISAPRI;
- break;
-
- case 1: /* [S|SX|SCOM]/2 */
- cards_membase= 0xC0000+((adf_pos0>>4)*0x2000);
- if (membase == -1) {
- membase = cards_membase;
- } else {
- if (membase != cards_membase)
- return -ENODEV;
- };
- cards_irq=irq_array[((adf_pos0 & 0xC)>>2)];
- if (irq == -1) {
- irq = cards_irq;
- } else {
- if (irq != cards_irq)
- return -ENODEV;
- };
-
- cards_io= 0xC00 + ((adf_pos0>>4)*0x10);
- type = EICON_CTYPE_SCOM;
- break;
-
- case 2: /* DIVA/MCA */
- cards_io = 0x200+ ((adf_pos0>>4)* 0x20);
- cards_irq = irq_array1[(adf_pos0 & 0x7)];
- if (irq == -1) {
- irq = cards_irq;
- } else {
- if (irq != cards_irq)
- return -ENODEV;
- };
- type = 0;
- break;
- default:
- return -ENODEV;
- };
- /* matching membase & irq */
- if ( 1 == eicon_addcard(type, membase, irq, id, 0)) {
- mca_set_adapter_name(slot, eicon_mca_adapters[a_idx].name);
- mca_set_adapter_procfn(slot, (MCA_ProcFn) eicon_info, cards);
-
- mca_mark_as_used(slot);
- cards->mca_slot = slot;
- /* card->io noch setzen oder ?? */
- cards->mca_io = cards_io;
- cards->hwif.isa.io = cards_io;
- /* reset card */
- outb_p(0,cards_io+1);
-
- eicon_log(NULL, 8, "eicon_addcard: successful for slot # %d.\n",
- cards->mca_slot+1);
- return 0 ; /* eicon_addcard added a card */
- } else {
- return -ENODEV;
- };
-};
-#endif /* CONFIG_MCA */
-#endif /* CONFIG_ISDN_DRV_EICON_ISA */
-
-module_init(eicon_init);
-module_exit(eicon_exit);
+++ /dev/null
-/* $Id: eicon_pci.c,v 1.1.4.1.2.3 2002/10/01 11:29:13 armin Exp $
- *
- * ISDN low-level module for Eicon active ISDN-Cards.
- * Hardware-specific code for PCI cards.
- *
- * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
- * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * Thanks to Eicon Networks for
- * documents, informations and hardware.
- *
- */
-
-#include <linux/config.h>
-#include <linux/pci.h>
-
-#include "eicon.h"
-#include "eicon_pci.h"
-
-#undef N_DATA
-#include "adapter.h"
-#include "uxio.h"
-
-char *eicon_pci_revision = "$Revision: 1.1.4.1.2.3 $";
-
-#ifdef CONFIG_PCI /* entire stuff is only for PCI */
-#ifdef CONFIG_ISDN_DRV_EICON_PCI
-
-int eicon_pci_find_card(char *ID)
-{
- int pci_cards = 0;
- int card_id = 0;
- int had_q = 0;
- int ctype = 0;
- char did[20];
- card_t *pCard;
- word wCardIndex;
-
- pCard = DivasCards;
- for (wCardIndex = 0; wCardIndex < MAX_CARDS; wCardIndex++)
- {
- if ((pCard->hw) && (pCard->hw->in_use))
- {
- switch(pCard->hw->card_type) {
- case DIA_CARD_TYPE_DIVA_SERVER:
- ctype = EICON_CTYPE_MAESTRAP;
- card_id++;
- had_q = 0;
- break;
- case DIA_CARD_TYPE_DIVA_SERVER_B:
- ctype = EICON_CTYPE_MAESTRA;
- card_id++;
- had_q = 0;
- break;
- case DIA_CARD_TYPE_DIVA_SERVER_Q:
- ctype = EICON_CTYPE_MAESTRAQ;
- if (!had_q)
- card_id++;
- if (++had_q >=4)
- had_q = 0;
- break;
- default:
- printk(KERN_ERR "eicon_pci: unknown card type %d !\n",
- pCard->hw->card_type);
- goto err;
- }
- sprintf(did, "%s%d", (strlen(ID) < 1) ? "eicon":ID, pci_cards);
- if ((!ctype) || (!(eicon_addcard(ctype, 0, pCard->hw->irq, did, card_id)))) {
- printk(KERN_ERR "eicon_pci: Card could not be added !\n");
- } else {
- pci_cards++;
- printk(KERN_INFO "%s: DriverID='%s' CardID=%d\n",
- eicon_ctype_name[ctype], did, card_id);
- }
-err:;
- }
- pCard++;
- }
- return pci_cards;
-}
-
-void
-eicon_pci_init_conf(eicon_card *card)
-{
- int j;
-
- /* initializing some variables */
- card->ReadyInt = 0;
-
- for(j = 0; j < 256; j++)
- card->IdTable[j] = NULL;
-
- for(j = 0; j < (card->d->channels + 1); j++) {
- card->bch[j].e.busy = 0;
- card->bch[j].e.D3Id = 0;
- card->bch[j].e.B2Id = 0;
- card->bch[j].e.ref = 0;
- card->bch[j].e.Req = 0;
- card->bch[j].e.complete = 1;
- card->bch[j].fsm_state = EICON_STATE_NULL;
- }
-}
-
-#endif
-#endif /* CONFIG_PCI */
-
+++ /dev/null
-/* $Id: eicon_pci.h,v 1.1.4.1.2.2 2002/10/01 11:29:13 armin Exp $
- *
- * ISDN low-level module for Eicon active ISDN-Cards (PCI part).
- *
- * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
- * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#ifndef eicon_pci_h
-#define eicon_pci_h
-
-#ifdef __KERNEL__
-
-/*
- * card's description
- */
-typedef struct {
- int irq; /* IRQ */
- int channels; /* No. of supported channels */
- void* card;
- unsigned char type; /* card type */
- unsigned char master; /* Flag: Card is Quadro 1/4 */
-} eicon_pci_card;
-
-extern int eicon_pci_find_card(char *ID);
-
-#endif /* __KERNEL__ */
-
-#endif /* eicon_pci_h */
-
+++ /dev/null
-/*
- * Diva Server 4BRI specific part of initialisation
- *
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.7
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include "sys.h"
-#include "idi.h"
-#include "divas.h"
-#include "pc.h"
-#include "pr_pc.h"
-#include "dsp_defs.h"
-#include "constant.h"
-#include "adapter.h"
-#include "uxio.h"
-
-#define TEST_INT_DIVAS_Q 0x13
-
-#define DIVAS_MAINT_OFFSET 0xff00 /* value for 4BRI card */
-#define MQ_BOARD_DSP_OFFSET 0x00a00000
-#define MQ_DSP1_ADDR_OFFSET 0x00000008
-#define MQ_DSP_JUNK_OFFSET 0x00000400
-#define MQ_DSP1_DATA_OFFSET 0x00000000
-#define MQ_BOARD_ISAC_DSP_RESET 0x00800028
-#define MQ_BREG_RISC 0x1200 /* RISC Reset */
-#define MQ_ISAC_DSP_RESET 0x0028 /* ISAC and DSP reset address offset */
-#define MQ_RISC_COLD_RESET_MASK 0x0001 /* RISC Cold reset */
-#define MQ_RISC_WARM_RESET_MASK 0x0002 /* RISC Warm reset */
-#define MQ_IRQ_REQ_ON 0x1
-#define MQ_IRQ_REQ_OFF 0x0
-#define MQ_BREG_IRQ_TEST 0x0608
-#define PLX9054_INTCSR 0x69
-#define PLX9054_INT_ENA 0x09
-
-#define DIVAS_IOBASE 0x01
-#define M_PCI_RESET 0x10
-
-byte mem_in(ADAPTER *a, void *adr);
-word mem_inw(ADAPTER *a, void *adr);
-void mem_in_buffer(ADAPTER *a, void *adr, void *P, word length);
-void mem_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e);
-void mem_out(ADAPTER *a, void *adr, byte data);
-void mem_outw(ADAPTER *a, void *adr, word data);
-void mem_out_buffer(ADAPTER *a, void *adr, void *P, word length);
-void mem_inc(ADAPTER *a, void *adr);
-
-int Divas4BRIInitPCI(card_t *card, dia_card_t *cfg);
-static int fourbri_ISR (card_t* card);
-
-int FPGA_Download(word, dword, byte *, byte *, int);
-extern byte FPGA_Bytes[];
-extern void *get_card(int);
-
-byte UxCardPortIoIn(ux_diva_card_t *card, byte *base, int offset);
-void UxCardPortIoOut(ux_diva_card_t *card, byte *base, int offset, byte);
-word GetProtFeatureValue(char *sw_id);
-
-void memcp(byte *dst, byte *src, dword dwLen);
-int memcm(byte *dst, byte *src, dword dwLen);
-
-static int diva_server_4bri_reset(card_t *card)
-{
- byte *ctl;
-
- DPRINTF(("divas: reset Diva Server 4BRI"));
-
- ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);
-
- /* stop RISC, DSP's and ISAC */
- UxCardMemOut(card->hw, &ctl[MQ_BREG_RISC], 0);
- UxCardMemOut(card->hw, &ctl[MQ_ISAC_DSP_RESET], 0);
-
- UxCardMemDetach(card->hw, ctl);
-
- return 0;
-}
-
-static int diva_server_4bri_config(card_t *card, dia_config_t *config)
-{
- byte *shared;
- int i, j;
-
- DPRINTF(("divas: configure Diva Server 4BRI"));
-
- shared = (byte *) UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
-
- for (i=0; i<256; i++)
- {
- UxCardMemOut(card->hw, &shared[i], 0);
- }
-
- UxCardMemOut(card->hw, &shared[ 8], config->tei);
- UxCardMemOut(card->hw, &shared[ 9], config->nt2);
- UxCardMemOut(card->hw, &shared[10], config->sig_flags);
- UxCardMemOut(card->hw, &shared[11], config->watchdog);
- UxCardMemOut(card->hw, &shared[12], config->permanent);
- UxCardMemOut(card->hw, &shared[13], config->x_interface);
- UxCardMemOut(card->hw, &shared[14], config->stable_l2);
- UxCardMemOut(card->hw, &shared[15], config->no_order_check);
- UxCardMemOut(card->hw, &shared[16], config->handset_type);
- UxCardMemOut(card->hw, &shared[17], 0);
- UxCardMemOut(card->hw, &shared[18], config->low_channel);
- UxCardMemOut(card->hw, &shared[19], config->prot_version);
- UxCardMemOut(card->hw, &shared[20], config->crc4);
-
- if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
- {
- DPRINTF(("divas: Signifying V.90"));
- UxCardMemOut(card->hw, &shared[22], 4);
- }
- else
- {
- UxCardMemOut(card->hw, &shared[22], 0);
- }
-
- for (i=0; i<2; i++)
- {
- for (j=0; j<32; j++)
- {
- UxCardMemOut(card->hw, &shared[32+(i*96)+j],config->terminal[i].oad[j]);
- }
-
- for (j=0; j<32; j++)
- {
- UxCardMemOut(card->hw, &shared[64+(i*96)+j],config->terminal[i].osa[j]);
- }
-
- for (j=0; j<32; j++)
- {
- UxCardMemOut(card->hw, &shared[96+(i*96)+j],config->terminal[i].spid[j]);
- }
- }
-
- UxCardMemDetach(card->hw, shared);
-
- return 0;
-}
-
-static
-void diva_server_4bri_reset_int(card_t *card)
-{
- byte *ctl;
-
- ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);
-
- UxCardMemOut(card->hw, &ctl[MQ_BREG_IRQ_TEST], MQ_IRQ_REQ_OFF);
-
- UxCardMemDetach(card->hw, ctl);
-
- return;
-}
-
-
-static int diva_server_4bri_test_int(card_t *card)
-{
- byte *ctl, i;
- byte *reg;
-
- DPRINTF(("divas: test interrupt for Diva Server 4BRI"));
-
- /* We get the last (dummy) adapter in so we need to go back to the first */
-
- card = get_card(card->cfg.card_id - 3);
-
- /* Enable interrupts on PLX chip */
-
- reg = UxCardMemAttach(card->hw, DIVAS_REG_MEMORY);
-
- UxCardPortIoOut(card->hw, reg, PLX9054_INTCSR, PLX9054_INT_ENA);
-
- UxCardMemDetach(card->hw, reg);
-
- /* Set the test interrupt flag */
- card->test_int_pend = TEST_INT_DIVAS_Q;
-
- /* Now to trigger the interrupt */
-
- ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);
-
- UxCardMemOut(card->hw, &ctl[MQ_BREG_IRQ_TEST], MQ_IRQ_REQ_ON);
-
- UxCardMemDetach(card->hw, ctl);
-
- for (i = 0; i < 50; i++)
- {
- if (!card->test_int_pend)
- {
- break;
- }
- UxPause(10);
- }
-
- if (card->test_int_pend)
- {
- DPRINTF(("active: timeout waiting for card to interrupt"));
- return (-1);
- }
-
- return 0;
-}
-
-
-static void print_hdr(unsigned char *code, int offset)
-{
- unsigned char hdr[80];
- int i;
-
- i = 0;
-
- while ((i < (DIM(hdr) -1)) &&
- (code[offset + i] != '\0') &&
- (code[offset + i] != '\r') &&
- (code[offset + i] != '\n'))
- {
- hdr[i] = code[offset + i];
- i++;
- }
-
- hdr[i] = '\0';
-
- DPRINTF(("divas: loading %s", hdr));
-}
-
-static int diva_server_4bri_load(card_t *card, dia_load_t *load)
-{
- byte *pRAM=NULL;
- int download_offset=0;
- card_t *FirstCard;
- byte sw_id[80];
-
- DPRINTF(("divas: loading Diva Server 4BRI[%d]", load->card_id));
-
- switch(load->code_type)
- {
- case DIA_CPU_CODE:
- DPRINTF(("divas: RISC code"));
- print_hdr(load->code, 0x80);
- card->hw->features = GetProtFeatureValue((char *)&load->code[0x80]);
- download_offset = 0; // Protocol code written to offset 0
- pRAM = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);
- break;
-
- case DIA_DSP_CODE:
- DPRINTF(("divas: DSP code"));
- print_hdr(load->code, 0x0);
- FirstCard = get_card(load->card_id - 3);
- if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
- {
- download_offset = MQ_V90D_DSP_CODE_BASE;
- }
- else
- {
- download_offset = MQ_ORG_DSP_CODE_BASE;
- }
- pRAM = UxCardMemAttach(FirstCard->hw, DIVAS_RAM_MEMORY);
- download_offset += (((sizeof(dword) + (sizeof(t_dsp_download_desc)* DSP_MAX_DOWNLOAD_COUNT)) + 3) & 0xFFFFFFFC);
-
- break;
-
- case DIA_TABLE_CODE:
- DPRINTF(("divas: TABLE code"));
- FirstCard = get_card(load->card_id - 3);
- if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
- {
- download_offset = MQ_V90D_DSP_CODE_BASE + sizeof(dword);
- }
- else
- {
- download_offset = MQ_ORG_DSP_CODE_BASE + sizeof(dword);
- }
- pRAM = UxCardMemAttach(FirstCard->hw, DIVAS_RAM_MEMORY);
- break;
-
- case DIA_CONT_CODE:
- DPRINTF(("divas: continuation code"));
- break;
-
- case DIA_DLOAD_CNT:
- DPRINTF(("divas: COUNT code"));
- FirstCard = get_card(load->card_id - 3);
- if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
- {
- download_offset = MQ_V90D_DSP_CODE_BASE;
- }
- else
- {
- download_offset = MQ_ORG_DSP_CODE_BASE;
- }
- pRAM = UxCardMemAttach(FirstCard->hw, DIVAS_RAM_MEMORY);
- break;
-
- case DIA_FPGA_CODE:
- DPRINTF(("divas: 4BRI FPGA download - %d bytes", load->length));
- if (FPGA_Download(IDI_ADAPTER_MAESTRAQ,
- card->hw->io_base,
- sw_id,
- load->code,
- load->length
- ) == -1)
- {
- DPRINTF(("divas: FPGA download failed"));
- return -1;
- }
-
- /* NOW reset the 4BRI */
- diva_server_4bri_reset(card);
- return 0; // No need for anything further loading
-
- default:
- DPRINTF(("divas: unknown code type"));
- return -1;
- }
-
- memcp(pRAM + (download_offset & 0x3FFFFF), load->code, load->length);
-
- {
- int mism_off;
- if ((mism_off = memcm(pRAM + (download_offset & 0x3FFFFF), load->code, load->length)))
- {
- DPRINTF(("divas: memory mismatch at offset %d", mism_off));
- UxCardMemDetach(card->hw, pRAM);
- return -1;
- }
- }
-
- UxCardMemDetach(card->hw, pRAM);
-
- return 0;
-}
-
-static int diva_server_4bri_start(card_t *card, byte *channels)
-{
- byte *ctl;
- byte *shared, i;
- int adapter_num;
-
- DPRINTF(("divas: start Diva Server 4BRI"));
- *channels = 0;
- card->is_live = FALSE;
-
- ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);
-
- UxCardMemOutW(card->hw, &ctl[MQ_BREG_RISC], MQ_RISC_COLD_RESET_MASK);
-
- UxPause(2);
-
- UxCardMemOutW(card->hw, &ctl[MQ_BREG_RISC], MQ_RISC_WARM_RESET_MASK | MQ_RISC_COLD_RESET_MASK);
-
- UxPause(10);
-
- UxCardMemDetach(card->hw, ctl);
-
- shared = (byte *) UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
-
- for ( i = 0 ; i < 300 ; ++i )
- {
- UxPause (10) ;
-
- if ( UxCardMemInW(card->hw, &shared[0x1E]) == 0x4447 )
- {
- DPRINTF(("divas: Protocol startup time %d.%02d seconds",
- (i / 100), (i % 100) ));
-
- break;
- }
- }
-
- if (i==300)
- {
- DPRINTF(("divas: Timeout starting card"));
- DPRINTF(("divas: Signature == 0x%04X", UxCardMemInW(card->hw, &shared[0x1E])));
-
- UxCardMemDetach(card->hw, shared);
- return -1;
- }
-
- UxCardMemDetach(card->hw, shared);
-
- for (adapter_num=3; adapter_num >= 0; adapter_num--)
- {
- card_t *qbri_card;
-
- qbri_card = get_card(card->cfg.card_id - adapter_num);
-
- if (qbri_card)
- {
- qbri_card->is_live = TRUE;
- shared = UxCardMemAttach(qbri_card->hw, DIVAS_SHARED_MEMORY);
- *channels += UxCardMemIn(qbri_card->hw, &shared[0x3F6]);
- UxCardMemDetach(qbri_card->hw, shared);
- }
- else
- {
- DPRINTF(("divas: Couldn't get card info %d", card->cfg.card_id));
- }
- }
-
- diva_server_4bri_test_int(card);
-
- return 0;
-}
-
-static
-int diva_server_4bri_mem_get(card_t *card, mem_block_t *mem_block)
-
-{
- byte *a;
- byte *card_addr;
- word length = 0;
- int i;
-
- a = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);
-
- card_addr = a;
- card_addr += mem_block->addr;
-
- for (i=0; i < sizeof(mem_block->data); i++)
- {
- mem_block->data[i] = UxCardMemIn(card->hw, card_addr);
- card_addr++;
- length++;
- }
-
- UxCardMemDetach(card->hw, a);
-
- return length;
-}
-
-/*
- * Initialise 4BRI specific entry points
- */
-
-int Divas4BriInit(card_t *card, dia_card_t *cfg)
-{
-// byte sw_id[80];
-// extern int FPGA_Done;
-
- DPRINTF(("divas: initialise Diva Server 4BRI"));
-
- if (Divas4BRIInitPCI(card, cfg) == -1)
- {
- return -1;
- }
-
- /* Need to download the FPGA */
-/* if (!FPGA_Done)
- {
- int retVal;
-
- retVal=FPGA_Download(IDI_ADAPTER_MAESTRAQ,
- cfg->io_base,
- sw_id,
- FPGA_Bytes
- );
- if(retVal==-1)
- {
-
- DPRINTF(("divas: FPGA Download Failed"));
- return -1;
-
- }
- FPGA_Done = 1;
- } */
-
- card->card_reset = diva_server_4bri_reset;
- card->card_load = diva_server_4bri_load;
- card->card_config = diva_server_4bri_config;
- card->card_start = diva_server_4bri_start;
- card->reset_int = diva_server_4bri_reset_int;
- card->card_mem_get = diva_server_4bri_mem_get;
-
- card->xlog_offset = DIVAS_MAINT_OFFSET;
-
- card->out = DivasOut;
- card->test_int = DivasTestInt;
- card->dpc = DivasDpc;
- card->clear_int = DivasClearInt;
- card->card_isr = fourbri_ISR;
-
- card->a.ram_out = mem_out;
- card->a.ram_outw = mem_outw;
- card->a.ram_out_buffer = mem_out_buffer;
- card->a.ram_inc = mem_inc;
-
- card->a.ram_in = mem_in;
- card->a.ram_inw = mem_inw;
- card->a.ram_in_buffer = mem_in_buffer;
- card->a.ram_look_ahead = mem_look_ahead;
-
- return 0;
-}
-
-void memcp(byte *dst, byte *src, dword dwLen)
-{
- while (dwLen)
- {
- *dst = *src;
- dst++; src++;
- dwLen--;
- }
-}
-
-int memcm(byte *dst, byte *src, dword dwLen)
-{
- int offset = 0;
-
- while (offset < dwLen)
- {
- if(*dst != *src)
- return (offset+1);
-
- offset++;
- src++;
- dst++;
- }
-
- return 0;
-}
-
-
-
-/*int fourbri_ISR (card_t* card)
-{
- int served = 0;
- byte *DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
-
-
- if (UxCardPortIoIn (card->hw, DivasIOBase, M_PCI_RESET) & 0x01)
- {
- served = 1;
- card->int_pend += 1;
- DivasDpcSchedule();
- UxCardPortIoOut (card->hw, DivasIOBase, M_PCI_RESET, 0x08);
- }
-
- UxCardMemDetach(card->hw, DivasIOBase);
-
- return (served != 0);
-}*/
-
-
-static int fourbri_ISR (card_t* card)
-{
- byte *ctl;
-
- card->int_pend += 1;
- DivasDpcSchedule(); /* ISR DPC */
-
- ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);
- UxCardMemOut(card->hw, &ctl[MQ_BREG_IRQ_TEST], MQ_IRQ_REQ_OFF);
- UxCardMemDetach(card->hw, ctl);
-
- return (1);
-}
+++ /dev/null
-/*
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.2
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include "sys.h"
-#include "idi.h"
-#include "uxio.h"
-
-#define FPGA_PORT 0x6E
-#define FPGA_DLOAD_BUFLEN 256
-#define NAME_OFFSET 0x10
-#define NAME_MAXLEN 12
-#define DATE_OFFSET 0x2c
-#define DATE_MAXLEN 10
-
-word UxCardPortIoInW(ux_diva_card_t *card, byte *base, int offset);
-void UxCardPortIoOutW(ux_diva_card_t *card, byte *base, int offset, word);
-void UxPause(long int);
-
-/*-------------------------------------------------------------------------*/
-/* Loads the FPGA configuration file onto the hardware. */
-/* Function returns 0 on success, else an error number. */
-/* On success, an identifier string is returned in the buffer */
-/* */
-/* A buffer of FPGA_BUFSIZE, a handle to the already opened bitstream */
-/* file and a file read function has to be provided by the operating */
-/* system part. */
-/* ----------------------------------------------------------------------- */
-int FPGA_Download( word cardtype,
- dword RegBase,
- byte *strbuf,
- byte FPGA_SRC[],
- int FPGA_LEN
- )
-{
- word i, j, k;
- word baseval, Mask_PROGRAM, Mask_DONE, Mask_CCLK, Mask_DIN;
- dword addr;
- byte *pFPGA;
-
- //--- check for legal cardtype
- switch (cardtype)
- {
- case IDI_ADAPTER_MAESTRAQ:
- addr = RegBase ; // address where to access FPGA
- Mask_PROGRAM = 0x0001; // FPGA pins at address
- Mask_DONE = 0x0002;
- Mask_CCLK = 0x0100;
- Mask_DIN = 0x0400;
- baseval = 0x000d; // PROGRAM hi, CCLK lo, DIN lo by default
- break;
-
- default:
-
- DPRINTF(("divas: FPGA Download ,Illegal Card"));
- return -1; // illegal card
- }
-
- //--- generate id string from file content
- for (j=NAME_OFFSET, k=0; j<(NAME_OFFSET+NAME_MAXLEN); j++, k++) //name
- {
- if (!FPGA_SRC[j]) break;
- strbuf[k] = FPGA_SRC[j];
- }
- strbuf[k++] = ' ';
- for (j=DATE_OFFSET; j<(DATE_OFFSET+DATE_MAXLEN); j++, k++) // date
- {
- if (!FPGA_SRC[j]) break;
- strbuf[k] = FPGA_SRC[j];
- }
- strbuf[k] = 0;
-
- DPRINTF(("divas: FPGA Download - %s", strbuf));
-
- //--- prepare download, Pulse PROGRAM pin down.
- UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval &~Mask_PROGRAM); // PROGRAM low pulse
- UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval); // release
- UxPause(50); // wait until FPGA finised internal memory clear
-
- //--- check done pin, must be low
- if (UxCardPortIoInW(NULL, (byte *) addr, FPGA_PORT) &Mask_DONE)
- {
- DPRINTF(("divas: FPGA_ERR_DONE_WRONG_LEVEL"));
- return -1;
- }
-
- pFPGA = FPGA_SRC;
-
- i = 0;
- /* Move past the header */
- while ((FPGA_SRC[i] != 0xFF) && (i < FPGA_LEN))
- {
- i++;
- }
-
- // We've hit the 0xFF so move on to the next byte
- // i++;
- DPRINTF(("divas: FPGA Code starts at offset %d", i));
-
- //--- put data onto the FPGA
- for (;i<FPGA_LEN; i++)
- {
- //--- put byte onto FPGA
- for (j=0; j<8; j++)
- {
- if (FPGA_SRC[i] &(0x80>>j)) baseval |= Mask_DIN; // write a hi
- else baseval &=~Mask_DIN; // write a lo
- UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval);
- UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval | Mask_CCLK); // set CCLK hi
- UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval); // set CCLK lo
- }
- }
-
- //--- add some additional startup clock cycles and check done pin
- for (i=0; i<5; i++)
- {
- UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval | Mask_CCLK); // set CCLK hi
- UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval); // set CCLK lo
- }
-
- UxPause(100);
-
- if (UxCardPortIoInW(NULL, (byte *) addr, FPGA_PORT) &Mask_DONE)
- {
- DPRINTF(("divas: FPGA download successful"));
- }
- else
- {
- DPRINTF(("divas: FPGA download failed - 0x%x", UxCardPortIoInW(NULL, (byte *) addr, FPGA_PORT)));
- return -1;
- }
-
-return 0;
-}
-
+++ /dev/null
-/*
- * Core driver for Diva Server cards
- * Implements the IDI interface
- *
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.8
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include "idi.h"
-#include "adapter.h"
-#include "pc.h"
-#include "pr_pc.h"
-#include "sys.h"
-#include "uxio.h"
-
-/* IDI request functions */
-
-static void request(card_t *card, ENTITY *e);
-
-static void req_0(ENTITY *e) { request(&DivasCards[ 0], e); }
-static void req_1(ENTITY *e) { request(&DivasCards[ 1], e); }
-static void req_2(ENTITY *e) { request(&DivasCards[ 2], e); }
-static void req_3(ENTITY *e) { request(&DivasCards[ 3], e); }
-static void req_4(ENTITY *e) { request(&DivasCards[ 4], e); }
-static void req_5(ENTITY *e) { request(&DivasCards[ 5], e); }
-static void req_6(ENTITY *e) { request(&DivasCards[ 6], e); }
-static void req_7(ENTITY *e) { request(&DivasCards[ 7], e); }
-static void req_8(ENTITY *e) { request(&DivasCards[ 8], e); }
-static void req_9(ENTITY *e) { request(&DivasCards[ 9], e); }
-static void req_10(ENTITY *e) { request(&DivasCards[10], e); }
-static void req_11(ENTITY *e) { request(&DivasCards[11], e); }
-static void req_12(ENTITY *e) { request(&DivasCards[12], e); }
-static void req_13(ENTITY *e) { request(&DivasCards[13], e); }
-static void req_14(ENTITY *e) { request(&DivasCards[14], e); }
-static void req_15(ENTITY *e) { request(&DivasCards[15], e); }
-
-IDI_CALL DivasIdiRequest[16] =
-{
- &req_0, &req_1, &req_2, &req_3,
- &req_4, &req_5, &req_6, &req_7,
- &req_8, &req_9, &req_10, &req_11,
- &req_12, &req_13, &req_14, &req_15
-};
-
-#define PR_RAM ((struct pr_ram *)0)
-#define RAM ((struct dual *)0)
-
-/*------------------------------------------------------------------*/
-/* local function prototypes */
-/*------------------------------------------------------------------*/
-
-static byte isdn_rc(ADAPTER *, byte, byte, byte, word);
-static byte isdn_ind(ADAPTER *, byte, byte, byte, PBUFFER *, byte, word);
-
-/*
- * IDI related functions
- */
-
-static
-ENTITY *entity_ptr(ADAPTER *a, byte e_no)
-{
- card_t *card;
-
- card = a->io;
-
- return card->e_tbl[e_no].e;
-}
-
-static
-void CALLBACK(ADAPTER *a, ENTITY *e)
-{
- card_t *card = a->io;
-
- if (card->log_types & DIVAS_LOG_IDI)
- {
- DivasLogIdi(card, e, FALSE);
- }
-
- (*e->callback)(e);
-}
-
-static
-void *PTR_P(ADAPTER *a, ENTITY *e, void *P)
-{
- return(P);
-}
-
-static
-void *PTR_R(ADAPTER *a, ENTITY *e)
-{
- return((void*)e->R);
-}
-
-static
-void *PTR_X(ADAPTER *a, ENTITY *e)
-{
- return((void*)e->X);
-}
-
-static
-void free_entity(ADAPTER *a, byte e_no)
-{
- card_t *card;
- int ipl;
-
- card = a->io;
-
- ipl = UxCardLock(card->hw);
-
- card->e_tbl[e_no].e = NULL;
- card->e_count--;
-
- UxCardUnlock(card->hw, ipl);
-
- return;
-}
-
-static
-void assign_queue(ADAPTER * a, byte e_no, word ref)
-{
- card_t *card;
- int ipl;
-
- card = a->io;
-
- ipl = UxCardLock(card->hw);
-
- card->e_tbl[e_no].assign_ref = ref;
- card->e_tbl[e_no].next = card->assign;
- card->assign = e_no;
-
- UxCardUnlock(card->hw, ipl);
-
- return;
-}
-
-static
-byte get_assign(ADAPTER *a, word ref)
-{
- card_t *card;
- byte e_no;
- int ipl;
-
- card = a->io;
-
- ipl = UxCardLock(card->hw);
-
- e_no = (byte)card->assign;
- while (e_no)
- {
- if (card->e_tbl[e_no].assign_ref == ref)
- {
- break;
- }
- e_no = card->e_tbl[e_no].next;
- }
-
- UxCardUnlock(card->hw, ipl);
-
- return e_no;
-}
-
-static
-void req_queue(ADAPTER * a, byte e_no)
-{
- card_t *card;
- int ipl;
-
- card = a->io;
-
- ipl = UxCardLock(card->hw);
-
- card->e_tbl[e_no].next = 0;
-
- if (card->e_head)
- {
- card->e_tbl[card->e_tail].next = e_no;
- card->e_tail = e_no;
- }
- else
- {
- card->e_head = e_no;
- card->e_tail = e_no;
- }
-
- UxCardUnlock(card->hw, ipl);
-
- return;
-}
-
-static
-byte look_req(ADAPTER * a)
-{
- card_t *card;
-
- card = a->io;
-
- return(card->e_head);
-}
-
-static
-void next_req(ADAPTER * a)
-{
- card_t *card;
- int ipl;
-
-
- card = a->io;
-
- ipl = UxCardLock(card->hw);
-
- card->e_head = card->e_tbl[card->e_head].next;
- if (!card->e_head)
- {
- card->e_tail = 0;
- }
-
- UxCardUnlock(card->hw, ipl);
-
- return;
-}
-
-
-/*
- * IDI request function for active cards
- */
-static
-void request(card_t *card, ENTITY *e)
-{
- word *special_req;
- int i;
- int ipl;
-
-
- if (card->log_types & DIVAS_LOG_IDI)
- {
- DivasLogIdi(card, e, TRUE);
- }
-
- if (!e->Req)
- {
- special_req = (word *) e;
-
- switch (*special_req)
- {
- case REQ_REMOVE:
- return;
-
- case REQ_NAME:
- for (i=0; i < DIM(card->cfg.name); i++)
- {
- ((struct get_name_s *) e)->name[i] = card->cfg.name[i];
- }
- return;
-
- case REQ_SERIAL:
- case REQ_XLOG:
- DPRINTF(("IDI: attempted REQ_SERIAL or REQ_XLOG"));
- return;
-
- default:
- return;
- }
- }
-
- ipl = UxCardLock(card->hw);
-
- if (!(e->Id & 0x1f))
- {
- DPRINTF(("IDI: ASSIGN req"));
-
- for (i = 1; i < card->e_max; i++)
- {
- if (!card->e_tbl[i].e)
- {
- break;
- }
- }
-
- if (i == card->e_max)
- {
- DPRINTF(("IDI: request all ids in use (IDI req ignored)"));
- UxCardUnlock(card->hw, ipl);
- e->Rc = OUT_OF_RESOURCES;
- return;
- }
-
- card->e_tbl[i].e = e;
- card->e_count++;
-
- e->No = (byte) i;
- e->More = 0;
- e->RCurrent = 0xff;
- }
- else
- {
- i = e->No;
- }
-
- if (e->More & XBUSY)
- {
- DPRINTF(("IDI: request - entity is busy"));
- UxCardUnlock(card->hw, ipl);
- return;
- }
-
- e->More |= XBUSY;
- e->More &= ~ XMOREF;
- e->XCurrent = 0;
- e->XOffset = 0;
-
- card->e_tbl[i].next = 0;
-
- if(card->e_head)
- {
- card->e_tbl[card->e_tail].next = i;
- card->e_tail = i;
- }
- else
- {
- card->e_head = i;
- card->e_tail = i;
- }
-
- UxCardUnlock(card->hw, ipl);
-
- DivasScheduleRequestDpc();
-
- return;
-}
-
-static byte pr_ready(ADAPTER * a)
-{
- byte ReadyCount;
-
- ReadyCount = (byte)(a->ram_in(a, &PR_RAM->ReqOutput) -
- a->ram_in(a, &PR_RAM->ReqInput));
-
- if(!ReadyCount) {
- if(!a->ReadyInt) {
- a->ram_inc(a, &PR_RAM->ReadyInt);
- a->ReadyInt++;
- }
- }
- return ReadyCount;
-}
-
-/*------------------------------------------------------------------*/
-/* output function */
-/*------------------------------------------------------------------*/
-
-void DivasOut(ADAPTER * a)
-{
- byte e_no;
- ENTITY * this = NULL;
- BUFFERS *X;
- word length;
- word i;
- word clength;
- REQ * ReqOut;
- byte more;
- byte ReadyCount;
- byte ReqCount;
- byte Id;
-
- /* while a request is pending ... */
- e_no = look_req(a);
- if(!e_no)
- {
- return;
- }
-
- ReadyCount = pr_ready(a);
- if(!ReadyCount)
- {
- DPRINTF(("IDI: card not ready for next request"));
- return;
- }
-
- ReqCount = 0;
- while(e_no && ReadyCount) {
-
- next_req(a);
-
- this = entity_ptr(a, e_no);
-
-#ifdef USE_EXTENDED_DEBUGS
- if ( !this )
- {
- ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ;
- DBG_FTL(("!A%d ==> NULL entity ptr - try to ignore", (int)io->ANum))
- e_no = look_req(a) ;
- ReadyCount-- ;
- continue ;
- }
- {
- ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ;
- DPRINTF(("IDI: >A%d Id=0x%x Req=0x%x", io->ANum, this->Id, this->Req))
- }
-#else
- DPRINTF(("IDI: >REQ=%x,Id=%x,Ch=%x",this->Req,this->Id,this->ReqCh));
-#endif
-
- /* get address of next available request buffer */
- ReqOut = (REQ *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextReq)];
-
- /* now copy the data from the current data buffer into the */
- /* adapters request buffer */
- length = 0;
- i = this->XCurrent;
- X = PTR_X(a,this);
- while(i<this->XNum && length<270) {
- clength = (word)(270-length);
- if (clength > X[i].PLength-this->XOffset)
- clength = X[i].PLength-this->XOffset;
- a->ram_out_buffer(a,
- &ReqOut->XBuffer.P[length],
- PTR_P(a,this,&X[i].P[this->XOffset]),
- clength);
-
- length +=clength;
- this->XOffset +=clength;
- if(this->XOffset==X[i].PLength) {
- this->XCurrent = (byte)++i;
- this->XOffset = 0;
- }
- }
-
- a->ram_outw(a, &ReqOut->XBuffer.length, length);
- a->ram_out(a, &ReqOut->ReqId, this->Id);
- a->ram_out(a, &ReqOut->ReqCh, this->ReqCh);
-
- /* if it's a specific request (no ASSIGN) ... */
-
- if(this->Id &0x1f) {
-
- /* if buffers are left in the list of data buffers do */
- /* do chaining (LL_MDATA, N_MDATA) */
-
- this->More++;
- if(i<this->XNum && this->MInd) {
- a->ram_out(a, &ReqOut->Req, this->MInd);
- more = TRUE;
- }
- else {
- this->More |=XMOREF;
- a->ram_out(a, &ReqOut->Req, this->Req);
- more = FALSE;
- }
-
- /* if we did chaining, this entity is put back into the */
- /* request queue */
-
- if(more) {
- req_queue(a,this->No);
- }
- }
-
- /* else it's a ASSIGN */
-
- else {
-
- /* save the request code used for buffer chaining */
-
- this->MInd = 0;
- if (this->Id==BLLC_ID) this->MInd = LL_MDATA;
- if (this->Id==NL_ID ||
- this->Id==TASK_ID ||
- this->Id==MAN_ID
- ) this->MInd = N_MDATA;
-
- /* send the ASSIGN */
-
- this->More |=XMOREF;
- a->ram_out(a, &ReqOut->Req, this->Req);
-
- /* save the reference of the ASSIGN */
-
- assign_queue(a, this->No, a->ram_inw(a, &ReqOut->Reference));
- }
- a->ram_outw(a, &PR_RAM->NextReq, a->ram_inw(a, &ReqOut->next));
- ReadyCount--;
- ReqCount++;
-
- e_no = look_req(a);
- }
-
- /* send the filled request buffers to the ISDN adapter */
-
- a->ram_out(a, &PR_RAM->ReqInput,
- (byte)(a->ram_in(a, &PR_RAM->ReqInput) + ReqCount));
-
- /* if it is a 'unreturncoded' UREMOVE request, remove the */
- /* Id from our table after sending the request */
- if(this->Req==UREMOVE && this->Id) {
- Id = this->Id;
- e_no = a->IdTable[Id];
- free_entity(a, e_no);
- a->IdTable[Id] = 0;
- this->Id = 0;
- }
-
-}
-
-/*------------------------------------------------------------------*/
-/* isdn interrupt handler */
-/*------------------------------------------------------------------*/
-
-byte DivasDpc(ADAPTER * a)
-{
- byte Count;
- RC * RcIn;
- IND * IndIn;
- byte c;
- byte RNRId;
- byte Rc;
- byte Ind;
-
- /* if return codes are available ... */
- if((Count = a->ram_in(a, &PR_RAM->RcOutput))) {
-
- DPRINTF(("IDI: #Rc=%x",Count));
-
- /* get the buffer address of the first return code */
- RcIn = (RC *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextRc)];
-
- /* for all return codes do ... */
- while(Count--) {
-
- if((Rc=a->ram_in(a, &RcIn->Rc))) {
-
- /* call return code handler, if it is not our return code */
- /* the handler returns 2 */
- /* for all return codes we process, we clear the Rc field */
- isdn_rc(a,
- Rc,
- a->ram_in(a, &RcIn->RcId),
- a->ram_in(a, &RcIn->RcCh),
- a->ram_inw(a, &RcIn->Reference));
-
- a->ram_out(a, &RcIn->Rc, 0);
- }
-
- /* get buffer address of next return code */
- RcIn = (RC *)&PR_RAM->B[a->ram_inw(a, &RcIn->next)];
- }
-
- /* clear all return codes (no chaining!) */
- a->ram_out(a, &PR_RAM->RcOutput ,0);
-
- /* call output function */
- DivasOut(a);
- }
-
- /* clear RNR flag */
- RNRId = 0;
-
- /* if indications are available ... */
- if((Count = a->ram_in(a, &PR_RAM->IndOutput))) {
-
- DPRINTF(("IDI: #Ind=%x",Count));
-
- /* get the buffer address of the first indication */
- IndIn = (IND *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextInd)];
-
- /* for all indications do ... */
- while(Count--) {
-
- /* if the application marks an indication as RNR, all */
- /* indications from the same Id delivered in this interrupt */
- /* are marked RNR */
- if(RNRId && RNRId==a->ram_in(a, &IndIn->IndId)) {
- a->ram_out(a, &IndIn->Ind, 0);
- a->ram_out(a, &IndIn->RNR, TRUE);
- }
- else {
- Ind = a->ram_in(a, &IndIn->Ind);
- if(Ind) {
- RNRId = 0;
-
- /* call indication handler, a return value of 2 means chain */
- /* a return value of 1 means RNR */
- /* for all indications we process, we clear the Ind field */
- c = isdn_ind(a,
- Ind,
- a->ram_in(a, &IndIn->IndId),
- a->ram_in(a, &IndIn->IndCh),
- &IndIn->RBuffer,
- a->ram_in(a, &IndIn->MInd),
- a->ram_inw(a, &IndIn->MLength));
-
- if(c==1) {
- DPRINTF(("IDI: RNR"));
- a->ram_out(a, &IndIn->Ind, 0);
- RNRId = a->ram_in(a, &IndIn->IndId);
- a->ram_out(a, &IndIn->RNR, TRUE);
- }
- }
- }
-
- /* get buffer address of next indication */
- IndIn = (IND *)&PR_RAM->B[a->ram_inw(a, &IndIn->next)];
- }
-
- a->ram_out(a, &PR_RAM->IndOutput, 0);
- }
- return FALSE;
-}
-
-byte DivasTestInt(ADAPTER * a)
-{
- return a->ram_in(a,(void *)0x3fe);
-}
-
-void DivasClearInt(ADAPTER * a)
-{
- a->ram_out(a,(void *)0x3fe,0);
-}
-
-/*------------------------------------------------------------------*/
-/* return code handler */
-/*------------------------------------------------------------------*/
-
-static
-byte isdn_rc(ADAPTER * a,
- byte Rc,
- byte Id,
- byte Ch,
- word Ref)
-{
- ENTITY * this;
- byte e_no;
-
-#ifdef USE_EXTENDED_DEBUGS
- {
- ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ;
- DPRINTF(("IDI: <A%d Id=0x%x Rc=0x%x", io->ANum, Id, Rc))
- }
-#else
- DPRINTF(("IDI: <RC(Rc=%x,Id=%x,Ch=%x)",Rc,Id,Ch));
-#endif
-
- /* check for ready interrupt */
- if(Rc==READY_INT) {
- if(a->ReadyInt) {
- a->ReadyInt--;
- return 0;
- }
- return 2;
- }
-
- /* if we know this Id ... */
- e_no = a->IdTable[Id];
- if(e_no) {
-
- this = entity_ptr(a,e_no);
-
- this->RcCh = Ch;
-
- /* if it is a return code to a REMOVE request, remove the */
- /* Id from our table */
- if(this->Req==REMOVE && Rc==OK) {
- free_entity(a, e_no);
- a->IdTable[Id] = 0;
- this->Id = 0;
-/**************************************************************/
- if ((this->More & XMOREC) > 1) {
- this->More &= ~XMOREC;
- this->More |= 1;
- DPRINTF(("isdn_rc, Id=%x, correct More on REMOVE", Id));
- }
- }
-
- if (Rc==OK_FC) {
- this->Rc = Rc;
- this->More = (this->More & (~XBUSY | XMOREC)) | 1;
- this->complete = 0xFF;
- CALLBACK(a, this);
- return 0;
- }
- if(this->More &XMOREC)
- this->More--;
-
- /* call the application callback function */
- if(this->More &XMOREF && !(this->More &XMOREC)) {
- this->Rc = Rc;
- this->More &=~XBUSY;
- this->complete=0xff;
- CALLBACK(a, this);
- }
- return 0;
- }
-
- /* if it's an ASSIGN return code check if it's a return */
- /* code to an ASSIGN request from us */
- if((Rc &0xf0)==ASSIGN_RC) {
-
- e_no = get_assign(a, Ref);
-
- if(e_no) {
-
- this = entity_ptr(a,e_no);
-
- this->Id = Id;
-
- /* call the application callback function */
- this->Rc = Rc;
- this->More &=~XBUSY;
- this->complete=0xff;
- CALLBACK(a, this);
-
- if(Rc==ASSIGN_OK) {
- a->IdTable[Id] = e_no;
- }
- else
- {
- free_entity(a, e_no);
- a->IdTable[Id] = 0;
- this->Id = 0;
- }
- return 1;
- }
- }
- return 2;
-}
-
-/*------------------------------------------------------------------*/
-/* indication handler */
-/*------------------------------------------------------------------*/
-
-static
-byte isdn_ind(ADAPTER * a,
- byte Ind,
- byte Id,
- byte Ch,
- PBUFFER * RBuffer,
- byte MInd,
- word MLength)
-{
- ENTITY * this;
- word clength;
- word offset;
- BUFFERS *R;
-
-#ifdef USE_EXTENDED_DEBUGS
- {
- ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ;
- DPRINTF(("IDI: <A%d Id=0x%x Ind=0x%x", io->ANum, Id, Ind))
- }
-#else
- DPRINTF(("IDI: <IND(Ind=%x,Id=%x,Ch=%x)",Ind,Id,Ch));
-#endif
-
- if(a->IdTable[Id]) {
-
- this = entity_ptr(a,a->IdTable[Id]);
-
- this->IndCh = Ch;
-
- /* if the Receive More flag is not yet set, this is the */
- /* first buffer of the packet */
- if(this->RCurrent==0xff) {
-
- /* check for receive buffer chaining */
- if(Ind==this->MInd) {
- this->complete = 0;
- this->Ind = MInd;
- }
- else {
- this->complete = 1;
- this->Ind = Ind;
- }
-
- /* call the application callback function for the receive */
- /* look ahead */
- this->RLength = MLength;
-
- a->ram_look_ahead(a, RBuffer, this);
-
- this->RNum = 0;
- CALLBACK(a, this);
-
- /* map entity ptr, selector could be re-mapped by call to */
- /* IDI from within callback */
- this = entity_ptr(a,a->IdTable[Id]);
-
- /* check for RNR */
- if(this->RNR==1) {
- this->RNR = 0;
- return 1;
- }
-
- /* if no buffers are provided by the application, the */
- /* application want to copy the data itself including */
- /* N_MDATA/LL_MDATA chaining */
- if(!this->RNR && !this->RNum) {
- return 0;
- }
-
- /* if there is no RNR, set the More flag */
- this->RCurrent = 0;
- this->ROffset = 0;
- }
-
- if(this->RNR==2) {
- if(Ind!=this->MInd) {
- this->RCurrent = 0xff;
- this->RNR = 0;
- }
- return 0;
- }
- /* if we have received buffers from the application, copy */
- /* the data into these buffers */
- offset = 0;
- R = PTR_R(a,this);
- do {
- if(this->ROffset==R[this->RCurrent].PLength) {
- this->ROffset = 0;
- this->RCurrent++;
- }
- clength = a->ram_inw(a, &RBuffer->length)-offset;
- if (clength > R[this->RCurrent].PLength-this->ROffset)
- clength = R[this->RCurrent].PLength-this->ROffset;
- if(R[this->RCurrent].P) {
- a->ram_in_buffer(a,
- &RBuffer->P[offset],
- PTR_P(a,this,&R[this->RCurrent].P[this->ROffset]),
- clength);
- }
- offset +=clength;
- this->ROffset +=clength;
- } while(offset<(a->ram_inw(a, &RBuffer->length)));
-
- /* if it's the last buffer of the packet, call the */
- /* application callback function for the receive complete */
- /* call */
- if(Ind!=this->MInd) {
- R[this->RCurrent].PLength = this->ROffset;
- if(this->ROffset) this->RCurrent++;
- this->RNum = this->RCurrent;
- this->RCurrent = 0xff;
- this->Ind = Ind;
- this->complete = 2;
- CALLBACK(a, this);
- }
- return 0;
- }
- return 2;
-}
+++ /dev/null
-/*
- * External IDI interface
- *
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.0
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#if !defined(IDI_H)
-#define IDI_H
-
-#include "sys.h"
-
-/* typedefs for our data structures */
-
-typedef struct get_name_s GET_NAME;
-typedef struct entity_s ENTITY;
-typedef struct buffers_s BUFFERS;
-
-/* IDI request/callback function pointer */
-
-typedef void (* IDI_CALL)(ENTITY *);
-
-typedef struct {
- word length; /* length of data/parameter field */
- byte P[270]; /* data/parameter field */
-} DBUFFER;
-
-#define REQ_NAME 0x0100
-#define BOARD_NAME_LENGTH 9
-struct get_name_s {
- word command; /* command = 0x0100 */
- byte name[BOARD_NAME_LENGTH];
-};
-
-#define REQ_REMOVE 0x0000 /* pointer to word which is 0 */
-#define REQ_SERIAL 0x0200
-struct get_serial_s {
- word command; /* command = 0x0200 */
- dword serial; /* serial number */
-};
-
-#define REQ_POSTCALL 0x0300
-struct postcall_s {
- word command; /* command = 0x0300 */
- word dummy; /* not used */
- IDI_CALL callback; /* routine address to call back */
- ENTITY *contxt; /* ptr to entity to use */
-};
-
-#define REQ_XLOG 0x0400 /* structure is card dependent/defined locally */
-
-struct buffers_s {
- word PLength;
- byte *P;
-};
-
-struct entity_s {
- byte Req; /* pending request */
- byte Rc; /* return code received */
- byte Ind; /* indication received */
- byte ReqCh; /* channel of current Req */
- byte RcCh; /* channel of current Rc */
- byte IndCh; /* channel of current Ind */
- byte Id; /* ID used by this entity */
- byte GlobalId; /* reserved field */
- byte XNum; /* number of X-buffers */
- byte RNum; /* number of R-buffers */
- BUFFERS *X; /* pointer to X-buffer list */
- BUFFERS *R; /* pointer to R-buffer list */
- word RLength; /* length of current R-data */
- DBUFFER *RBuffer; /* buffer of current R-data */
- byte RNR; /* receive not ready flag */
- byte complete; /* receive complete status */
- IDI_CALL callback;
-
- word user[2];
-
- /* fields used by the driver internally */
- byte No; /* entity number */
- byte reserved2; /* reserved field */
- byte More; /* R/X More flags */
- byte MInd; /* MDATA coding for this ID */
- byte XCurrent; /* current transmit buffer */
- byte RCurrent; /* current receive buffer */
- word XOffset; /* offset in x-buffer */
- word ROffset; /* offset in r-buffer */
-};
-
-typedef struct {
- byte type;
- byte channels;
- word features;
- /* dword serial; */
- IDI_CALL request;
-} DESCRIPTOR;
-
-extern void DIVA_DIDD_Read(DESCRIPTOR *, int);
-
- /* descriptor type field coding */
-#define IDI_ADAPTER_S 1
-#define IDI_ADAPTER_PR 2
-#define IDI_ADAPTER_DIVA 3
-#define IDI_ADAPTER_MAESTRA 4
-#define IDI_ADAPTER_MAESTRAQ 5
-#define IDI_ADAPTER_MAESTRAP 6
-#define IDI_VADAPTER 0x40
-#define IDI_DRIVER 0x80
-#define IDI_DIMAINT 0xff
-
-/* feature bit mask values */
-
-#define DI_VOICE 0x0 /* obsolete define */
-#define DI_FAX3 0x1
-#define DI_MODEM 0x2
-#define DI_POST 0x4
-#define DI_V110 0x8
-#define DI_V120 0x10
-#define DI_POTS 0x20
-#define DI_CODEC 0x40
-#define DI_MANAGE 0x80
-#define DI_V_42 0x0100
-#define DI_EXTD_FAX 0x0200 /* Extended FAX (ECM, 2D, T.6, Polling) */
-
-#endif /* IDI_H */
+++ /dev/null
-/*
- * Source file for kernel interface to kernel log facility
- *
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.3
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include "eicon.h"
-#include "sys.h"
-#include <stdarg.h>
-
-#include "divas.h"
-#include "divalog.h"
-#include "uxio.h"
-
-void DivasPrintf(char *fmt, ...)
-
-{
- klog_t log; /* log entry buffer */
-
- va_list argptr; /* pointer to additional args */
-
- va_start(argptr, fmt);
-
- /* clear log entry */
-
- memset((void *) &log, 0, sizeof(klog_t));
-
- log.card = -1;
- log.type = KLOG_TEXT_MSG;
-
- /* time stamp the entry */
-
- log.time_stamp = UxTimeGet();
-
- /* call vsprintf to format the user's information */
-
- vsnprintf(log.buffer, DIM(log.buffer), fmt, argptr);
-
- va_end(argptr);
-
- /* send to the log streams driver and return */
-
- DivasLogAdd(&log, sizeof(klog_t));
-
- return;
-}
+++ /dev/null
-/*
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.9
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/fs.h>
-#undef N_DATA /* Because we have our own definition */
-
-#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>
-
-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)
-{
- struct pci_dev *pdev = NULL;
- word wNumCards = 0, wDeviceIndex = 0;
- word PCItmp;
- dword j, i;
- unsigned int PCIserial;
- dia_card_t Card;
- byte *b;
-
- while ((pdev = pci_find_device(PCI_VENDOR_ID_EICON,
- PCI_DEVICE_ID_EICON_MAESTRAQ,
- pdev))) {
- dword dwRAM, dwDivasIOBase, dwCFG, dwCTL;
-
- printk(KERN_DEBUG "Divas: DIVA Server 4BRI Found\n");
-
- dwRAM = pci_resource_start(pdev, 2);
- dwDivasIOBase = pci_resource_start(pdev, 1);
- dwCFG = pci_resource_start(pdev, 0);
- dwCTL = pci_resource_start(pdev, 3);
-
- /* Retrieve the serial number */
- pci_write_config_word(pdev, 0x4E, 0x00FC);
- for (j=0, PCItmp=0; j<10000 && !PCItmp; j++) {
- pci_read_config_word(pdev, 0x4E, &PCItmp);
- PCItmp &= 0x8000; // extract done flag
- }
- pci_read_config_dword(pdev, 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.card_type = DIA_CARD_TYPE_DIVA_SERVER_Q;
- Card.bus_type = DIA_BUS_TYPE_PCI;
- Card.pdev = pdev;
- Card.irq = pdev->irq;
-
- 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.slot = -1;
-
- sprintf(Card.name, "DIVASQ%ld", i);
-
- Card.serial = PCIserial;
-
- Card.card_id = wNumCards;
-
- if (DivasCardNew(&Card) != 0) {
- break;
- }
- wNumCards++;
-
- }
- }
-
- pdev = NULL;
- while ((pdev = pci_find_device(PCI_VENDOR_ID_EICON,
- PCI_DEVICE_ID_EICON_MAESTRA,
- pdev))) {
- dword dwPLXIOBase, dwDivasIOBase;
-
- printk(KERN_DEBUG "Divas: DIVA Server BRI (S/T) Found\n");
- dwPLXIOBase = pci_resource_start(pdev, 1);
- dwDivasIOBase = pci_resource_start(pdev, 2);
-
- Card.card_id = wNumCards;
- Card.card_type = DIA_CARD_TYPE_DIVA_SERVER_B;
- Card.bus_type = DIA_BUS_TYPE_PCI;
- Card.pdev = pdev;
- Card.irq = pdev->irq;
- Card.reset_base = dwPLXIOBase;
- Card.io_base = dwDivasIOBase;
- Card.slot = -1;
- strcpy(Card.name, "DIVASB");
-
- 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);
- }
-
- 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);
- continue;
- }
-
- if (DivasCardNew(&Card) != 0) {
- continue;
- }
- wNumCards++;
- }
-
- pdev = NULL;
- while ((pdev = pci_find_device(PCI_VENDOR_ID_EICON,
- PCI_DEVICE_ID_EICON_MAESTRAQ_U,
- pdev))) {
- dword dwPLXIOBase, dwDivasIOBase;
-
- printk(KERN_DEBUG "Divas: DIVA Server BRI (U) Found\n");
-
- dwPLXIOBase = pci_resource_start(pdev, 1);
- dwDivasIOBase = pci_resource_start(pdev, 2);
-
- Card.card_id = wNumCards;
- Card.card_type = DIA_CARD_TYPE_DIVA_SERVER_B;
- Card.bus_type = DIA_BUS_TYPE_PCI;
- Card.pdev = pdev;
- Card.irq = pdev->irq;
- Card.reset_base = dwPLXIOBase;
- Card.io_base = dwDivasIOBase;
- Card.slot = -1;
- strcpy(Card.name, "DIVASB");
-
- 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);
- 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);
- continue;
- }
-
- if (DivasCardNew(&Card) != 0) {
- continue;
- }
- wNumCards++;
- }
-
- wDeviceIndex = 0;
-
- pdev = NULL;
- while ((pdev = pci_find_device(PCI_VENDOR_ID_EICON,
- PCI_DEVICE_ID_EICON_MAESTRAQ_U,
- pdev))) {
- dword dwRAM, dwREG, dwCFG;
-
- printk(KERN_DEBUG "Divas: DIVA Server PRI Found\n");
-
- dwRAM = pci_resource_start(pdev, 0);
- dwREG = pci_resource_start(pdev, 2);
- dwCFG = pci_resource_start(pdev, 4);
-
- 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;
-
- Card.card_id = wNumCards;
- Card.card_type = DIA_CARD_TYPE_DIVA_SERVER;
- Card.bus_type = DIA_BUS_TYPE_PCI;
- Card.pdev = pdev;
- Card.irq = pdev->irq;
- Card.slot = -1;
- strcpy(Card.name, "DIVASP");
- if (DivasCardNew(&Card) != 0) {
- continue;
- }
- wNumCards++;
- }
-
-
- 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;
-}
-
+++ /dev/null
-/*
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.12
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#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);
-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)
-{
- byte *pUserCards, card_i;
- word wCardNum;
-
- switch (command)
- {
- case DIA_IOCTL_CONFIG:
- {
- dia_config_t DivaConfig;
- if (copy_from_user(&DivaConfig, (void *)arg, sizeof(dia_config_t)))
- return -EFAULT;
- DivasCardConfig(&DivaConfig);
- return 0;
- }
-
- case DIA_IOCTL_DETECT:
- pUserCards = (byte *) arg;
-
- if (!verify_area(VERIFY_WRITE, pUserCards, 20))
- {
- if(__put_user(DivasCardNext, pUserCards++))
- return -EFAULT;
-
- for (card_i=1; card_i < 20; card_i++)
- {
- if(__put_user((byte) DivasCards[card_i - 1].cfg.card_type, pUserCards++))
- return -EFAULT;
- }
- }
- else return -EFAULT;
-
- return 0;
-
- case DIA_IOCTL_START:
- {
- dia_start_t DivaStart;
- if (copy_from_user(&DivaStart, (void *)arg, sizeof(dia_start_t)))
- return -EFAULT;
- return DivasCardStart(DivaStart.card_id);
- }
-
- case DIA_IOCTL_FLAVOUR:
- return 0;
-
- case DIA_IOCTL_LOAD:
- {
- dia_load_t DivaLoad;
- if(copy_from_user(&DivaLoad, (void *)arg, sizeof(dia_load_t)))
- return -EFAULT;
- if (!verify_area(VERIFY_READ, DivaLoad.code,DivaLoad.length))
- {
- if (DivasCardLoad(&DivaLoad))
- {
- printk(KERN_WARNING "Divas: Error loading DIVA Server adapter\n");
- return -EINVAL;
- }
- return 0;
- }
- return -EFAULT;
- }
- case DIA_IOCTL_LOG:
- {
- dia_log_t DivaLog;
- if (copy_from_user(&DivaLog, (void *) arg, sizeof(dia_log_t)))
- return -EFAULT;
- DivasLog(&DivaLog);
- return 0;
- }
-
- case DIA_IOCTL_XLOG_REQ:
- if(get_user(wCardNum, (word *) arg))
- return -EFAULT;
- DivasXlogReq(wCardNum);
- return 0;
-
- case DIA_IOCTL_GET_NUM:
- if(put_user(DivasCardNext, (int *)arg))
- return -EFAULT;
- return 0;
-
- case DIA_IOCTL_GET_LIST:
- {
- dia_card_list_t cards;
- DPRINTF(("divas: DIA_IOCTL_GET_LIST"));
- DivasGetList(&cards);
- if(copy_to_user((void *)arg, &cards, sizeof(cards)))
- return -EFAULT;
- return 0;
- }
- case DIA_IOCTL_GET_MEM:
- {
- mem_block_t mem_block;
- if (copy_from_user(&mem_block, (void *)arg, sizeof(mem_block_t)))
- return -EFAULT;
- DivasGetMem(&mem_block);
- return 0;
- }
-
- case DIA_IOCTL_UNLOCK:
- UnlockDivas();
- return 0;
-
- default:
- 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))
- return -EIO;
-
- pHeadItem = (klog_t *) DivasLogFifoRead();
-
- if (pHeadItem) {
- if (copy_to_user(pClientLogBuffer, pHeadItem, sizeof(klog_t))) {
- kfree(pHeadItem);
- return -EFAULT;
- }
- 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;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.16
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#define N_DATA
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#undef N_DATA
-
-#include "uxio.h"
-
-static
-int log_on=0;
-
-int Divasdevflag = 0;
-
-spinlock_t diva_lock = SPIN_LOCK_UNLOCKED;
-
-static
-ux_diva_card_t card_pool[MAX_CARDS];
-
-void UxPause(long int ms)
-{
- unsigned long timeout = jiffies + ((ms * HZ) / 1000);
-
- while (time_before(jiffies, timeout));
-}
-
-int UxCardHandleGet(ux_diva_card_t **card, dia_card_t *cfg)
-{
- int i;
- ux_diva_card_t *c;
-
- if (cfg->bus_type != DIA_BUS_TYPE_PCI)
- {
- DPRINTF(("divas hw: type not PCI (%d)", cfg->bus_type));
- return -1;
- }
-
- for (i = 0; (i < DIM(card_pool)) && (card_pool[i].in_use); i++)
- {
- ;
- }
-
- if (i == DIM(card_pool))
- {
- DPRINTF(("divas hw: card_pool exhausted"));
- return -1;
- }
-
- c = *card = &card_pool[i];
-
- switch (cfg->bus_type)
- {
- case DIA_BUS_TYPE_PCI:
- c->pdev = cfg->pdev;
- c->io_base = cfg->io_base;
- c->reset_base = cfg->reset_base;
- c->card_type = cfg->card_type;
- c->mapped = NULL;
- c->slot = cfg->slot;
- c->irq = (int) cfg->irq;
- c->pDRAM = cfg->memory[DIVAS_RAM_MEMORY];
- c->pDEVICES = cfg->memory[DIVAS_REG_MEMORY];
- c->pCONFIG = cfg->memory[DIVAS_CFG_MEMORY];
- c->pSHARED = cfg->memory[DIVAS_SHARED_MEMORY];
- c->pCONTROL = cfg->memory[DIVAS_CTL_MEMORY];
-
- /* c->bus_type = DIA_BUS_TYPE_PCI;
- c->bus_num = cfg->bus_num & 0x3f;
- c->slot = cfg->slot;
- c->irq = (int) cfg->irq;
- c->int_priority = (int) cfg->int_priority;
- c->card_type = cfg->card_type;
- c->io_base = cfg->io_base;
- c->reset_base = cfg->reset_base;
- c->pDRAM = cfg->memory[DIVAS_RAM_MEMORY];
- c->pDEVICES = cfg->memory[DIVAS_REG_MEMORY];
- c->pCONFIG = cfg->memory[DIVAS_CFG_MEMORY];
- c->pSHARED = cfg->memory[DIVAS_SHARED_MEMORY];
- DPRINTF(("divas hw: pDRAM is 0x%x", c->pDRAM));
- DPRINTF(("divas hw: pSHARED is 0x%x", c->pSHARED));
- DPRINTF(("divas hw: pCONFIG is 0x%x", c->pCONFIG));
- c->cm_key = cm_getbrdkey("Divas", cfg->card_id);*/
- break;
- default:
- break;
- }
-
- c->in_use = TRUE;
-
- return 0;
-}
-
-void UxCardHandleFree(ux_diva_card_t *card)
-{
- card->in_use = FALSE;
-}
-
-
-#define PLX_IOBASE 0
-#define DIVAS_IOBASE 1
-void *UxCardMemAttach(ux_diva_card_t *card, int id)
-{
- if (card->card_type == DIA_CARD_TYPE_DIVA_SERVER)
- {
- switch (id)
- {
- case DIVAS_SHARED_MEMORY:
- card->mapped = card->pSHARED;
- return card->pSHARED;
- break;
- case DIVAS_RAM_MEMORY:
- card->mapped = card->pDRAM;
- return card->pDRAM;
- break;
- case DIVAS_REG_MEMORY:
- card->mapped = card->pDEVICES;
- return card->pDEVICES;
- break;
- case DIVAS_CFG_MEMORY:
- card->mapped = card->pCONFIG;
- return card->pCONFIG;
- break;
- default:
- ASSERT(FALSE);
- card->mapped = NULL;
- return (void *) 0;
- }
- }
- else if (card->card_type == DIA_CARD_TYPE_DIVA_SERVER_B)
- {
- switch (id)
- {
- case PLX_IOBASE:
- return (void *) card->reset_base;
- break;
- case DIVAS_IOBASE:
- return (void *) card->io_base;
- break;
- default:
- ASSERT(FALSE);
- return 0;
- }
- }
-
- else if (card->card_type == DIA_CARD_TYPE_DIVA_SERVER_Q)
- {
- switch (id)
- {
- case DIVAS_SHARED_MEMORY:
- card->mapped = card->pSHARED;
- return card->pSHARED;
- break;
- case DIVAS_RAM_MEMORY:
- card->mapped = card->pDRAM;
- return card->pDRAM;
- break;
- case DIVAS_REG_MEMORY:
- card->mapped = (void *) card->io_base;
- return (void *) card->io_base;
- break;
- case DIVAS_CTL_MEMORY:
- card->mapped = card->pCONTROL;
- return card->pCONTROL;
- break;
- default:
- // ASSERT(FALSE);
- DPRINTF(("divas: Trying to attach to mem %d", id));
- card->mapped = NULL;
- return (void *) 0;
- }
- } else
- DPRINTF(("divas: Tried to attach to unknown card"));
-
- /* Unknown card type */
- return NULL;
-}
-
-void UxCardMemDetach(ux_diva_card_t *card, void *address)
-{
- return; // Just a place holder. No un-mapping done.
-}
-
-void UxCardLog(int turn_on)
-{
- log_on = turn_on;
-}
-
-/*
- * Control Register I/O Routines to be performed on Attached I/O ports
- */
-
-void UxCardPortIoOut(ux_diva_card_t *card, void *AttachedBase, int offset, byte the_byte)
-{
- word base = (word) (dword) AttachedBase;
-
- base += offset;
-
- outb(the_byte, base);
-}
-
-void UxCardPortIoOutW(ux_diva_card_t *card, void *AttachedBase, int offset, word the_word)
-{
- word base = (word) (dword) AttachedBase;
-
- base += offset;
-
- outw(the_word, base);
-}
-
-void UxCardPortIoOutD(ux_diva_card_t *card, void *AttachedBase, int offset, dword the_dword)
-{
- word base = (word) (dword) AttachedBase;
-
- base += offset;
-
- outl(the_dword, base);
-}
-
-byte UxCardPortIoIn(ux_diva_card_t *card, void *AttachedBase, int offset)
-{
- word base = (word) (dword) AttachedBase;
-
- base += offset;
-
- return inb(base);
-}
-
-word UxCardPortIoInW(ux_diva_card_t *card, void *AttachedBase, int offset)
-{
- word base = (word) (dword) AttachedBase;
-
- base += offset;
-
- return inw(base);
-}
-
-/*
- * Memory mapped card I/O functions
- */
-
-byte UxCardMemIn(ux_diva_card_t *card, void *address)
-{
- byte b;
- volatile byte* t = (byte*)address;
-
- b = *t;
-
- if (log_on)
- {
- byte *a = address;
- a -= (int) card->mapped;
- DPRINTF(("divas hw: read 0x%02x from 0x%x (memory mapped)", b & 0xff, a));
- }
-
- return(b);
-}
-
-word UxCardMemInW(ux_diva_card_t *card, void *address)
-{
- word w;
- volatile word* t = (word*)address;
-
- w = *t;
-
- if (log_on)
- {
- byte *a = address;
- a -= (int) card->mapped;
- DPRINTF(("divas hw: read 0x%04x from 0x%x (memory mapped)", w & 0xffff, a));
- }
-
- return (w);
-}
-
-dword UxCardMemInD(ux_diva_card_t *card, void *address)
-{
- dword dw;
- volatile dword* t = (dword*)address;
-
- dw = *t;
-
- if (log_on)
- {
- byte *a = address;
- a -= (int) card->mapped;
- DPRINTF(("divas hw: read 0x%08x from 0x%x (memory mapped)", dw, a));
- }
-
- return (dw);
-}
-
-void UxCardMemInBuffer(ux_diva_card_t *card, void *address, void *buffer, int length)
-{
- volatile byte *pSource = address;
- byte *pDest = buffer;
-
- while (length--)
- {
- *pDest++ = *pSource++;
- }
-
- if (log_on)
- {
- byte *a = address;
- a -= (int) card->mapped;
- pDest = buffer;
- DPRINTF(("divas hw: read %02x %02x %02x %02x %02x %02x %02x %02x from 0x%x (memory mapped)",
- pDest[0] & 0xff, pDest[1] & 0xff, pDest[2] & 0xff, pDest[3] & 0xff,
- pDest[4] & 0xff, pDest[5] & 0xff, pDest[6] & 0xff, pDest[7] & 0xff,
- a));
- }
-
- return;
-}
-
-void UxCardMemOut(ux_diva_card_t *card, void *address, byte data)
-{
- volatile byte* t = (byte*)address;
-
- if (log_on)
- {
- byte *a = address;
- a -= (int) card->mapped;
- DPRINTF(("divas hw: wrote 0x%02x to 0x%x (memory mapped)", data & 0xff, a));
- }
-
- *t = data;
-
- return;
-}
-
-void UxCardMemOutW(ux_diva_card_t *card, void *address, word data)
-{
- volatile word* t = (word*)address;
-
- if (log_on)
- {
- byte *a = address;
- a -= (int) card->mapped;
- DPRINTF(("divas hw: wrote 0x%04x to 0x%x (memory mapped)", data & 0xffff, a));
- }
-
- *t = data;
- return;
-}
-
-void UxCardMemOutD(ux_diva_card_t *card, void *address, dword data)
-{
- volatile dword* t = (dword*)address;
-
- if (log_on)
- {
- byte *a = address;
- a -= (int) card->mapped;
- DPRINTF(("divas hw: wrote 0x%08x to 0x%x (memory mapped)", data, a));
- }
-
- *t = data;
- return;
-}
-
-void UxCardMemOutBuffer(ux_diva_card_t *card, void *address, void *buffer, int length)
-{
- byte *pSource = buffer;
- byte *pDest = address;
-
- while (length--)
- {
- *pDest++ = *pSource++;
- }
-
- if (log_on)
- {
- byte *a = address;
- a -= (int) card->mapped;
- pDest = buffer;
- DPRINTF(("divas hw: wrote %02x %02x %02x %02x %02x %02x %02x %02x to 0x%x (memory mapped)",
- pDest[0] & 0xff, pDest[1] & 0xff, pDest[2] & 0xff, pDest[3] & 0xff,
- pDest[4] & 0xff, pDest[5] & 0xff, pDest[6] & 0xff, pDest[7] & 0xff,
- a));
- }
-
- return;
-}
-
-/*
- * Memory mapped card I/O functions
- */
-
-byte UxCardIoIn(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address)
-
-{
- byte the_byte;
-
- outb(0xFF, card->io_base + 0xC);
- outw((word) (dword) address, card->io_base + 4);
-
- the_byte = inb(card->io_base);
-
- if (log_on)
- {
- DPRINTF(("divas hw: read 0x%02x from 0x%x (I/O mapped)",
- the_byte & 0xff, address));
- }
-
- return the_byte;
-}
-
-word UxCardIoInW(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address)
-
-{
- word the_word;
-
- outb(0xFF, card->io_base + 0xC);
- outw((word) (dword) address, card->io_base + 4);
- the_word = inw(card->io_base);
-
- if (log_on)
- {
- DPRINTF(("divas hw: read 0x%04x from 0x%x (I/O mapped)",
- the_word & 0xffff, address));
- }
-
- return the_word;
-}
-
-dword UxCardIoInD(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address)
-
-{
- dword the_dword;
-
- outb(0xFF, card->io_base + 0xC);
- outw((word) (dword) address, card->io_base + 4);
- the_dword = inl(card->io_base);
-
- if (log_on)
- {
- DPRINTF(("divas hw: read 0x%08x from 0x%x (I/O mapped)",
- the_dword, address));
- }
-
- return the_dword;
-}
-
-void UxCardIoInBuffer(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address, void *buffer, int length)
-
-{
- byte *pSource = address;
- byte *pDest = buffer;
-
- if ((word) (dword) address & 0x1)
- {
- outb(0xFF, card->io_base + 0xC);
- outw((word) (dword) pSource, card->io_base + 4);
- *pDest = (byte) inb(card->io_base);
- pDest++;
- pSource++;
- length--;
- if (!length)
- {
- return;
- }
- }
-
- outb(0xFF, card->io_base + 0xC);
- outw((word) (dword) pSource, card->io_base + 4);
- insw(card->io_base, (word *)pDest,length%2 ? (length+1)>>1 : length>>1);
-
- if (log_on)
- {
- pDest = buffer;
- DPRINTF(("divas hw: read %02x %02x %02x %02x %02x %02x %02x %02x from 0x%x (I/O mapped)",
- pDest[0] & 0xff, pDest[1] & 0xff, pDest[2] & 0xff, pDest[3] & 0xff,
- pDest[4] & 0xff, pDest[5] & 0xff, pDest[6] & 0xff, pDest[7] & 0xff,
- address));
- }
-
- return;
-}
-
-/* Output */
-
-void UxCardIoOut(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address, byte data)
-{
- if (log_on)
- {
- DPRINTF(("divas hw: wrote 0x%02x to 0x%x (I/O mapped)",
- data & 0xff, address));
- }
-
- outb(0xFF, card->io_base + 0xC);
- outw((word) (dword) address, card->io_base + 4);
- outb((byte) data & 0xFF, card->io_base);
-
- return;
-}
-
-void UxCardIoOutW(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address, word data)
-{
- if (log_on)
- {
- DPRINTF(("divas hw: wrote 0x%04x to 0x%x (I/O mapped)",
- data & 0xffff, address));
- }
-
- outb(0xFF, card->io_base + 0xC);
- outw((word) (dword) address, card->io_base + 4);
- outw((word) data & 0xFFFF, card->io_base);
-
- return;
-}
-
-void UxCardIoOutD(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address, dword data)
-{
- if (log_on)
- {
- DPRINTF(("divas hw: wrote 0x%08x to 0x%x (I/O mapped)", data, address));
- }
-
- outb(0xFF, card->io_base + 0xC);
- outw((word) (dword) address, card->io_base + 4);
- outl((dword) data & 0xFFFFFFFF, card->io_base);
-
- return;
-}
-
-void UxCardIoOutBuffer(ux_diva_card_t *card, void *AttachedDivasIOBase, void *address, void *buffer, int length)
-
-{
- byte *pSource = buffer;
- byte *pDest = address;
-
- if ((word) (dword) address & 1)
- {
- outb(0xFF, card->io_base + 0xC);
- outw((word) (dword) pDest, card->io_base + 4);
- outb(*pSource, card->io_base);
- pSource++;
- pDest++;
- length--;
- if (!length)
- {
- return;
- }
- }
-
- outb(0xFF, card->io_base + 0xC);
- outw((word) (dword) pDest, card->io_base + 4);
- outsw(card->io_base, (word *)pSource, length%2 ? (length+1)>>1 : length>>1);
-
- if (log_on)
- {
- pDest = buffer;
- DPRINTF(("divas hw: wrote %02x %02x %02x %02x %02x %02x %02x %02x to 0x%x (I/O mapped)",
- pDest[0] & 0xff, pDest[1] & 0xff, pDest[2] & 0xff, pDest[3] & 0xff,
- pDest[4] & 0xff, pDest[5] & 0xff, pDest[6] & 0xff, pDest[7] & 0xff,
- address));
- }
-
- return;
-}
-
-irqreturn_t Divasintr(int arg, void *unused, struct pt_regs *unused_regs)
-{
- int i;
- card_t *card = NULL;
- ux_diva_card_t *ux_ref = NULL;
-
- for (i = 0; i < DivasCardNext; i++)
- {
-
- if (arg == DivasCards[i].cfg.irq)
- {
- card = &DivasCards[i];
- ux_ref = card->hw;
-
- if ((ux_ref) && (card->is_live))
- {
- (*ux_ref->user_isr)(ux_ref->user_isr_arg);
- }
- else
- {
- DPRINTF(("divas: ISR couldn't locate card"));
- }
- }
- }
-
- return IRQ_HANDLED;
-}
-
-
-int UxIsrInstall(ux_diva_card_t *card, isr_fn_t *isr_fn, void *isr_arg)
-{
- int result;
-
- card->user_isr = isr_fn;
- card->user_isr_arg = isr_arg;
-
- result = request_irq(card->irq, Divasintr, SA_INTERRUPT | SA_SHIRQ, "Divas", (void *) isr_arg);
-
- return result;
-}
-
-void UxIsrRemove(ux_diva_card_t *card, void *dev_id)
-{
- free_irq(card->irq, card->user_isr_arg);
-}
-
-void UxPciConfigWrite(ux_diva_card_t *card, int size, int offset, void *value)
-{
- switch (size) {
- case sizeof(byte):
- pci_write_config_byte(card->pdev, offset, * (byte *) value);
- break;
- case sizeof(word):
- pci_write_config_word(card->pdev, offset, * (word *) value);
- break;
- case sizeof(dword):
- pci_write_config_dword(card->pdev, offset, * (dword *) value);
- break;
- default:
- printk(KERN_WARNING "Divas: Invalid size in UxPciConfigWrite\n");
- }
-}
-
-void UxPciConfigRead(ux_diva_card_t *card, int size, int offset, void *value)
-{
- switch (size) {
- case sizeof(byte):
- pci_read_config_byte(card->pdev, offset, (byte *) value);
- break;
- case sizeof(word):
- pci_read_config_word(card->pdev, offset, (word *) value);
- break;
- case sizeof(dword):
- pci_read_config_dword(card->pdev, offset, (unsigned int *) value);
- break;
- default:
- printk(KERN_WARNING "Divas: Invalid size in UxPciConfigRead\n");
- }
-}
-
-void *UxAlloc(unsigned int size)
-{
- void *m;
-
- m = kmalloc(size, GFP_ATOMIC);
-
- return m;
-}
-
-void UxFree(void *ptr)
-{
- kfree(ptr);
-}
-
-long UxCardLock(ux_diva_card_t *card)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&diva_lock, flags);
-
- return flags;
-}
-
-void UxCardUnlock(ux_diva_card_t *card, unsigned long ipl)
-{
- spin_unlock_irqrestore(&diva_lock, ipl);
-}
-
-dword UxTimeGet(void)
-{
- return jiffies;
-}
-
-long UxInterlockedIncrement(ux_diva_card_t *card, long *dst)
-{
- register volatile long *p;
- register long ret;
- int ipl;
-
- p =dst;
-
- ipl = UxCardLock(card);
-
- *p += 1;
- ret = *p;
-
- UxCardUnlock(card,ipl);
-
- return(ret);
-
-}
-
-long UxInterlockedDecrement(ux_diva_card_t *card, long *dst)
-{
- register volatile long *p;
- register long ret;
- int ipl;
-
- p =dst;
-
- ipl = UxCardLock(card);
-
- *p -= 1;
- ret = *p;
-
- UxCardUnlock(card,ipl);
-
- return(ret);
-
-}
+++ /dev/null
-/*
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.10
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/sched.h>
-#undef N_DATA
-#include <linux/workqueue.h>
-
-#include <linux/smp.h>
-struct pt_regs;
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-
-#include "sys.h"
-#include "divas.h"
-#include "adapter.h"
-#include "divalog.h"
-
-#include "uxio.h"
-
-static struct tasklet_struct DivasTask;
-
-int Divas4BRIInitPCI(card_t *card, dia_card_t *cfg)
-{
- /* Use UxPciConfigWrite routines to initialise PCI config space */
-
-/* wPCIcommand = 0x03;
- cm_write_devconfig16(CMKey, PCI_COMMAND, &wPCIcommand);
-
- wPCIcommand = 0x280;
- cm_write_devconfig16(CMKey, PCI_STATUS, &wPCIcommand);
-
- bPCIcommand = 0x30;
- cm_write_devconfig16(CMKey, PCI_STATUS, &wPCIcommand);
-*/
- return 0;
-}
-
-int DivasPRIInitPCI(card_t *card, dia_card_t *cfg)
-{
- /* Use UxPciConfigWrite routines to initialise PCI config space */
-
-/* wPCIcommand = 0x03;
- cm_write_devconfig16(CMKey, PCI_COMMAND, &wPCIcommand);
-
- wPCIcommand = 0x280;
- cm_write_devconfig16(CMKey, PCI_STATUS, &wPCIcommand);
-
- bPCIcommand = 0x30;
- cm_write_devconfig8(CMKey, PCI_LATENCY, &bPCIcommand);*/
-
- return 0;
-}
-
-int DivasBRIInitPCI(card_t *card, dia_card_t *cfg)
-{
- /* Need to set these platform dependent values after patching */
-
- card->hw->reset_base = card->cfg.reset_base;
- card->hw->io_base = card->cfg.io_base;
-
- request_region(card->hw->reset_base,0x80,"Divas");
- request_region(card->hw->io_base,0x20,"Divas");
-
-
- /* Same as for PRI */
- return DivasPRIInitPCI(card, cfg);
-}
-
-/* ######################### Stubs of routines that are not done yet ################## */
-/*void DivasLogIdi(card_t *card, ENTITY *e, int request)
-{
-}
-*/
-
-int DivasDpcSchedule(void)
-{
- tasklet_schedule(&DivasTask);
-
- return 0;
-}
-
-int DivasScheduleRequestDpc(void)
-{
- tasklet_schedule(&DivasTask);
-
- return 0;
-}
-
-void DivasInitDpc(void)
-{
- tasklet_init(&DivasTask, DivasDoDpc, 0);
-}
-
-void DivasLogAdd(void *buffer, int length)
-{
- static
- boolean_t overflow = FALSE;
- static
- boolean_t busy = FALSE;
-
- /* make sure we're not interrupting ourselves */
-
- if (busy)
- {
- printk(KERN_DEBUG "Divas: Logging interrupting self !\n");
- return;
- }
- busy = TRUE;
-
- /* ignore call if daemon isn't running and we've reached limit */
-
- if (DivasLogFifoFull())
- {
- if (!overflow)
- {
- printk(KERN_DEBUG "Divas: Trace buffer full\n");
- overflow = TRUE;
- }
- busy = FALSE;
- return;
- }
-
- DivasLogFifoWrite(buffer, length);
-
- busy = FALSE;
- return;
-}
-
-/* #################################################################################### */
+++ /dev/null
-/*
- * Source file for diva log facility
- *
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.5
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include "sys.h"
-#include "idi.h"
-#include "divas.h"
-#include "adapter.h"
-#include "divalog.h"
-
-#include "uxio.h"
-
-/*Counter to monitor number of messages */
-static int m_count;
-
-#define MAX_BUFFERED_MSGS (1000)
-
-/* Our Linked List Structure to hold message */
-typedef struct klog_link{
- klog_t klog;
- struct klog_link *next;
-}KNODE;
-
-/* First & Last structures in list*/
-KNODE *head;
-KNODE *tail;
-
-/*
- * retrieve message from FIFO buffer
- * returns NULL if buffer empty
- * otherwise returns pointer to entry
- */
-
-char *DivasLogFifoRead(void)
-
-{
- KNODE *old_head;
-
- if(head==NULL)
- {
- /* Buffer Empty - No Messages */
- return NULL;
- }
-
- m_count--;
- /* Keep track of message to be read & increment to next message*/
- old_head = head;
- head = head->next;
- /*Return ptr to Msg */
- return((char *)old_head);
-}
-
-/*
- * write message into FIFO buffer
- */
-
-void DivasLogFifoWrite(char *entry, int length)
-
-{
- KNODE *new_klog;
-
- if(head == NULL)
- {
- /* No Entries in Log */
- tail=NULL;
- m_count=0;
- new_klog=UxAlloc(sizeof(KNODE));
-
- if(new_klog==NULL)
- {
- return;
- }
-
- m_count++;
- memset(new_klog, 0, sizeof(KNODE));
-
- /* Set head & tail to point to the new Msg Struct */
- head=tail=new_klog;
- tail->next=NULL;
- }
- else
- {
- new_klog=UxAlloc(sizeof(KNODE));
-
- if(new_klog==NULL)
- {
- return;
- }
-
- m_count++;
- memset(new_klog, 0, sizeof(KNODE));
-
- /* Let last Msg Struct point to new Msg Struct & inc tail */
- tail->next=new_klog;
- tail=new_klog;
- tail->next=NULL;
- }
-
- if (length > sizeof(klog_t))
- {
- length = sizeof(klog_t);
- }
-
- memcpy(&tail->klog, entry, length);
-
- return;
-}
-
-/*
- * DivaslogFifoEmpty:return TRUE if FIFO buffer is empty,otherwise FALSE
- */
-int DivasLogFifoEmpty(void)
-{
- return (m_count == 0);
-}
-
-/*
- *DivasLogFifoFull:return TRUE if FIFO buffer is full,otherwise FALSE
- */
-int DivasLogFifoFull(void)
-{
- return (m_count == MAX_BUFFERED_MSGS);
-}
-
-/*
- * generate an IDI log entry
- */
-
-void DivasLogIdi(card_t *card, ENTITY *e, int request)
-
-{
- klog_t klog;
-
- memset(&klog, 0, sizeof(klog));
-
- klog.time_stamp = UxTimeGet();
-
- klog.length = sizeof(ENTITY) > sizeof(klog.buffer) ?
- sizeof(klog.buffer) : sizeof(ENTITY);
-
- klog.card = (int) (card - DivasCards);
-
- klog.type = request ? KLOG_IDI_REQ : KLOG_IDI_CALLBACK;
- klog.code = 0;
- memcpy(klog.buffer, e, klog.length);
-
- /* send to the log driver and return */
-
- DivasLogAdd(&klog, sizeof(klog));
-
- return;
-}
+++ /dev/null
-/*
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.2
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#ifndef PC_H_INCLUDED
-#define PC_H_INCLUDED
-
-/*------------------------------------------------------------------*/
-/* buffer definition */
-/*------------------------------------------------------------------*/
-
-typedef struct {
- word length; /* length of data/parameter field */
- byte P[270]; /* data/parameter field */
-} PBUFFER;
-
-/*------------------------------------------------------------------*/
-/* dual port ram structure */
-/*------------------------------------------------------------------*/
-
-struct dual
-{
- byte Req; /* request register */
- byte ReqId; /* request task/entity identification */
- byte Rc; /* return code register */
- byte RcId; /* return code task/entity identification */
- byte Ind; /* Indication register */
- byte IndId; /* Indication task/entity identification */
- byte IMask; /* Interrupt Mask Flag */
- byte RNR; /* Receiver Not Ready (set by PC) */
- byte XLock; /* XBuffer locked Flag */
- byte Int; /* ISDN-S interrupt */
- byte ReqCh; /* Channel field for layer-3 Requests */
- byte RcCh; /* Channel field for layer-3 Returncodes */
- byte IndCh; /* Channel field for layer-3 Indications */
- byte MInd; /* more data indication field */
- word MLength; /* more data total packet length */
- byte ReadyInt; /* request field for ready interrupt */
- byte SWReg; /* Software register for special purposes */
- byte Reserved[11]; /* reserved space */
- byte InterfaceType; /* interface type 1=16K interface */
- word Signature; /* ISDN-S adapter Signature (GD) */
- PBUFFER XBuffer; /* Transmit Buffer */
- PBUFFER RBuffer; /* Receive Buffer */
-};
-
-/*------------------------------------------------------------------*/
-/* SWReg Values (0 means no command) */
-/*------------------------------------------------------------------*/
-#define SWREG_DIE_WITH_LEDON 0x01
-#define SWREG_HALT_CPU 0x02 /* Push CPU into a while(1) loop */
-
-/*------------------------------------------------------------------*/
-/* Id Fields Coding */
-/*------------------------------------------------------------------*/
-
-#define ID_MASK 0xe0 /* Mask for the ID field */
-#define GL_ERR_ID 0x1f /* ID for error reporting on global requests*/
-
-#define DSIG_ID 0x00 /* ID for D-channel signaling */
-#define NL_ID 0x20 /* ID for network-layer access (B or D) */
-#define BLLC_ID 0x60 /* ID for B-channel link level access */
-#define TASK_ID 0x80 /* ID for dynamic user tasks */
-#define TIMER_ID 0xa0 /* ID for timer task */
-#define TEL_ID 0xc0 /* ID for telephone support */
-#define MAN_ID 0xe0 /* ID for management */
-
-/*------------------------------------------------------------------*/
-/* ASSIGN and REMOVE requests are the same for all entities */
-/*------------------------------------------------------------------*/
-
-#define ASSIGN 0x01
-#define UREMOVE 0xfe /* without returncode */
-#define REMOVE 0xff
-
-/*------------------------------------------------------------------*/
-/* Timer Interrupt Task Interface */
-/*------------------------------------------------------------------*/
-
-#define ASSIGN_TIM 0x01
-#define REMOVE_TIM 0xff
-
-/*------------------------------------------------------------------*/
-/* dynamic user task interface */
-/*------------------------------------------------------------------*/
-
-#define ASSIGN_TSK 0x01
-#define REMOVE_TSK 0xff
-
-#define LOAD 0xf0
-#define RELOCATE 0xf1
-#define START 0xf2
-#define LOAD2 0xf3
-#define RELOCATE2 0xf4
-
-/*------------------------------------------------------------------*/
-/* dynamic user task messages */
-/*------------------------------------------------------------------*/
-
-#define TSK_B2 0x0000
-#define TSK_WAKEUP 0x2000
-#define TSK_TIMER 0x4000
-#define TSK_TSK 0x6000
-#define TSK_PC 0xe000
-
-/*------------------------------------------------------------------*/
-/* LL management primitives */
-/*------------------------------------------------------------------*/
-
-#define ASSIGN_LL 1 /* assign logical link */
-#define REMOVE_LL 0xff /* remove logical link */
-
-/*------------------------------------------------------------------*/
-/* LL service primitives */
-/*------------------------------------------------------------------*/
-
-#define LL_UDATA 1 /* link unit data request/indication */
-#define LL_ESTABLISH 2 /* link establish request/indication */
-#define LL_RELEASE 3 /* link release request/indication */
-#define LL_DATA 4 /* data request/indication */
-#define LL_LOCAL 5 /* switch to local operation (COM only) */
-#define LL_DATA_PEND 5 /* data pending indication (SDLC SHM only) */
-#define LL_REMOTE 6 /* switch to remote operation (COM only) */
-#define LL_TEST 8 /* link test request */
-#define LL_MDATA 9 /* more data request/indication */
-#define LL_BUDATA 10 /* broadcast unit data request/indication */
-#define LL_XID 12 /* XID command request/indication */
-#define LL_XID_R 13 /* XID response request/indication */
-
-/*------------------------------------------------------------------*/
-/* NL service primitives */
-/*------------------------------------------------------------------*/
-
-#define N_MDATA 1 /* more data to come REQ/IND */
-#define N_CONNECT 2 /* OSI N-CONNECT REQ/IND */
-#define N_CONNECT_ACK 3 /* OSI N-CONNECT CON/RES */
-#define N_DISC 4 /* OSI N-DISC REQ/IND */
-#define N_DISC_ACK 5 /* OSI N-DISC CON/RES */
-#define N_RESET 6 /* OSI N-RESET REQ/IND */
-#define N_RESET_ACK 7 /* OSI N-RESET CON/RES */
-#define N_DATA 8 /* OSI N-DATA REQ/IND */
-#define N_EDATA 9 /* OSI N-EXPEDITED DATA REQ/IND */
-#define N_UDATA 10 /* OSI D-UNIT-DATA REQ/IND */
-#define N_BDATA 11 /* BROADCAST-DATA REQ/IND */
-#define N_DATA_ACK 12 /* data ack ind for D-bit procedure */
-#define N_EDATA_ACK 13 /* data ack ind for INTERRUPT */
-
-#define N_Q_BIT 0x10 /* Q-bit for req/ind */
-#define N_M_BIT 0x20 /* M-bit for req/ind */
-#define N_D_BIT 0x40 /* D-bit for req/ind */
-
-/*------------------------------------------------------------------*/
-/* Signaling management primitives */
-/*------------------------------------------------------------------*/
-
-#define ASSIGN_SIG 1 /* assign signaling task */
-#define UREMOVE_SIG 0xfe /* remove signaling task without returncode */
-#define REMOVE_SIG 0xff /* remove signaling task */
-
-/*------------------------------------------------------------------*/
-/* Signaling service primitives */
-/*------------------------------------------------------------------*/
-
-#define CALL_REQ 1 /* call request */
-#define CALL_CON 1 /* call confirmation */
-#define CALL_IND 2 /* incoming call connected */
-#define LISTEN_REQ 2 /* listen request */
-#define HANGUP 3 /* hangup request/indication */
-#define SUSPEND 4 /* call suspend request/confirm */
-#define RESUME 5 /* call resume request/confirm */
-#define SUSPEND_REJ 6 /* suspend rejected indication */
-#define USER_DATA 8 /* user data for user to user signaling */
-#define CONGESTION 9 /* network congestion indication */
-#define INDICATE_REQ 10 /* request to indicate an incoming call */
-#define INDICATE_IND 10 /* indicates that there is an incoming call */
-#define CALL_RES 11 /* accept an incoming call */
-#define CALL_ALERT 12 /* send ALERT for incoming call */
-#define INFO_REQ 13 /* INFO request */
-#define INFO_IND 13 /* INFO indication */
-#define REJECT 14 /* reject an incoming call */
-#define RESOURCES 15 /* reserve B-Channel hardware resources */
-#define TEL_CTRL 16 /* Telephone control request/indication */
-#define STATUS_REQ 17 /* Request D-State (returned in INFO_IND) */
-#define FAC_REG_REQ 18 /* connection idependent fac registration */
-#define FAC_REG_ACK 19 /* fac registration acknowledge */
-#define FAC_REG_REJ 20 /* fac registration reject */
-#define CALL_COMPLETE 21/* send a CALL_PROC for incoming call */
-#define FACILITY_REQ 22 /* send a Facility Message type */
-#define FACILITY_IND 22 /* Facility Message type indication */
-#define SIG_CTRL 29 /* Control for signalling hardware */
-#define DSP_CTRL 30 /* Control for DSPs */
-#define LAW_REQ 31 /* Law config request for (returns info_i) */
-
-
-/*------------------------------------------------------------------*/
-/* management service primitives */
-/*------------------------------------------------------------------*/
-
-#define MAN_READ 2
-#define MAN_WRITE 3
-#define MAN_EXECUTE 4
-#define MAN_EVENT_ON 5
-#define MAN_EVENT_OFF 6
-#define MAN_LOCK 7
-#define MAN_UNLOCK 8
-
-#define MAN_INFO_IND 2
-#define MAN_EVENT_IND 3
-#define MAN_TRACE_IND 4
-
-#define MAN_ESC 0x80
-
-/*------------------------------------------------------------------*/
-/* return code coding */
-/*------------------------------------------------------------------*/
-
-#define UNKNOWN_COMMAND 0x01 /* unknown command */
-#define WRONG_COMMAND 0x02 /* wrong command */
-#define WRONG_ID 0x03 /* unknown task/entity id */
-#define WRONG_CH 0x04 /* wrong task/entity id */
-#define UNKNOWN_IE 0x05 /* unknown information el. */
-#define WRONG_IE 0x06 /* wrong information el. */
-#define OUT_OF_RESOURCES 0x07 /* ISDN-S card out of res. */
-#define ADAPTER_DEAD 0x08 /* ISDN card CPU halted */
-#define N_FLOW_CONTROL 0x10 /* Flow-Control, retry */
-#define ASSIGN_RC 0xe0 /* ASSIGN acknowledgement */
-#define ASSIGN_OK 0xef /* ASSIGN OK */
-#define OK_FC 0xfc /* Flow-Control RC */
-#define READY_INT 0xfd /* Ready interrupt */
-#define TIMER_INT 0xfe /* timer interrupt */
-#define OK 0xff /* command accepted */
-
-/*------------------------------------------------------------------*/
-/* information elements */
-/*------------------------------------------------------------------*/
-
-#define SHIFT 0x90 /* codeset shift */
-#define MORE 0xa0 /* more data */
-#define CL 0xb0 /* congestion level */
-
- /* codeset 0 */
-
-#define BC 0x04 /* Bearer Capability */
-#define CAU 0x08 /* cause */
-#define CAD 0x0c /* Connected address */
-#define CAI 0x10 /* call identity */
-#define CHI 0x18 /* channel identification */
-#define LLI 0x19 /* logical link id */
-#define CHA 0x1a /* charge advice */
-#define DT 0x29 /* ETSI date/time */
-#define KEY 0x2c /* keypad information element */
-#define FTY 0x1c /* facility information element */
-#define DSP 0x28 /* display */
-#define OAD 0x6c /* origination address */
-#define OSA 0x6d /* origination sub-address */
-#define CPN 0x70 /* called party number */
-#define DSA 0x71 /* destination sub-address */
-#define RDX 0x73 /* redirected number extended */
-#define RDN 0x74 /* redirected number */
-#define LLC 0x7c /* low layer compatibility */
-#define HLC 0x7d /* high layer compatibility */
-#define UUI 0x7e /* user user information */
-#define ESC 0x7f /* escape extension */
-
-#define DLC 0x20 /* data link layer configuration */
-#define NLC 0x21 /* network layer configuration */
-
- /* codeset 6 */
-
-#define SIN 0x01 /* service indicator */
-#define CIF 0x02 /* charging information */
-#define DATE 0x03 /* date */
-#define CPS 0x07 /* called party status */
-
-/*------------------------------------------------------------------*/
-/* TEL_CTRL contents */
-/*------------------------------------------------------------------*/
-
-#define RING_ON 0x01
-#define RING_OFF 0x02
-#define HANDS_FREE_ON 0x03
-#define HANDS_FREE_OFF 0x04
-#define ON_HOOK 0x80
-#define OFF_HOOK 0x90
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.0
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#ifndef PC_MAINT_H
-#define PC_MAINT_H
-
-#if !defined(MIPS_SCOM)
-#define BUFFER_SZ 48
-#define MAINT_OFFS 0x380
-#else
-#define BUFFER_SZ 128
-#define MAINT_OFFS 0xff00
-#endif
-
-#define MIPS_BUFFER_SZ 128
-#define MIPS_MAINT_OFFS 0xff00
-
-#define DO_LOG 1
-#define MEMR 2
-#define MEMW 3
-#define IOR 4
-#define IOW 5
-#define B1TEST 6
-#define B2TEST 7
-#define BTESTOFF 8
-#define DSIG_STATS 9
-#define B_CH_STATS 10
-#define D_CH_STATS 11
-#define BL1_STATS 12
-#define BL1_STATS_C 13
-#define GET_VERSION 14
-#define OS_STATS 15
-#define XLOG_SET_MASK 16
-#define XLOG_GET_MASK 17
-#define DSP_READ 20
-#define DSP_WRITE 21
-
-#define OK 0xff
-#define MORE_EVENTS 0xfe
-#define NO_EVENT 1
-
-struct DSigStruc
-{
- byte Id;
- byte uX;
- byte listen;
- byte active;
- byte sin[3];
- byte bc[6];
- byte llc[6];
- byte hlc[6];
- byte oad[20];
-};
-
-struct BL1Struc {
- dword cx_b1;
- dword cx_b2;
- dword cr_b1;
- dword cr_b2;
- dword px_b1;
- dword px_b2;
- dword pr_b1;
- dword pr_b2;
- word er_b1;
- word er_b2;
-};
-
-struct L2Struc {
- dword XTotal;
- dword RTotal;
- word XError;
- word RError;
-};
-
-struct OSStruc {
- word free_n;
-};
-
-typedef union
-{
- struct DSigStruc DSigStats;
- struct BL1Struc BL1Stats;
- struct L2Struc L2Stats;
- struct OSStruc OSStats;
- byte b[BUFFER_SZ];
- word w[BUFFER_SZ>>1];
- word l[BUFFER_SZ>>2]; /* word is wrong, do not use! Use 'd' instead. */
- dword d[BUFFER_SZ>>2];
-} BUFFER;
-
-typedef union
-{
- struct DSigStruc DSigStats;
- struct BL1Struc BL1Stats;
- struct L2Struc L2Stats;
- struct OSStruc OSStats;
- byte b[MIPS_BUFFER_SZ];
- word w[MIPS_BUFFER_SZ>>1];
- word l[BUFFER_SZ>>2]; /* word is wrong, do not use! Use 'd' instead. */
- dword d[MIPS_BUFFER_SZ>>2];
-} MIPS_BUFFER;
-
-
-#if !defined(MIPS_SCOM)
-struct pc_maint
-{
- byte req;
- byte rc;
- byte *mem; /*far*/
- short length;
- word port;
- byte fill[6];
- BUFFER data;
-};
-#else
-struct pc_maint
-{
- byte req;
- byte rc;
- byte reserved[2]; /* R3000 alignment ... */
- byte far *mem;
- short length;
- word port;
- byte fill[4]; /* data at offset 16 */
- BUFFER data;
-};
-#endif
-
-struct mi_pc_maint
-{
- byte req;
- byte rc;
- byte reserved[2]; /* R3000 alignment ... */
- byte *mem; /*far*/
- short length;
- word port;
- byte fill[4]; /* data at offset 16 */
- MIPS_BUFFER data;
-};
-
-#endif /* PC_MAINT_H */
+++ /dev/null
-/*
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.0
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-
-#if !defined(PR_PC_H)
-#define PR_PC_H
-
-struct pr_ram {
- word NextReq; /* pointer to next Req Buffer */
- word NextRc; /* pointer to next Rc Buffer */
- word NextInd; /* pointer to next Ind Buffer */
- byte ReqInput; /* number of Req Buffers sent */
- byte ReqOutput; /* number of Req Buffers returned */
- byte ReqReserved; /* number of Req Buffers reserved */
- byte Int; /* ISDN-P interrupt */
- byte XLock; /* Lock field for arbitration */
- byte RcOutput; /* number of Rc buffers received */
- byte IndOutput; /* number of Ind buffers received */
- byte IMask; /* Interrupt Mask Flag */
- byte Reserved1[2]; /* reserved field, do not use */
- byte ReadyInt; /* request field for ready interrupt */
- byte Reserved2[12]; /* reserved field, do not use */
- byte InterfaceType; /* interface type 1=16K interface */
- word Signature; /* ISDN-P initialized indication */
- byte B[1]; /* buffer space for Req,Ind and Rc */
-};
-
-typedef struct {
- word next;
- byte Req;
- byte ReqId;
- byte ReqCh;
- byte Reserved1;
- word Reference;
- byte Reserved[8];
- PBUFFER XBuffer;
-} REQ;
-
-typedef struct {
- word next;
- byte Rc;
- byte RcId;
- byte RcCh;
- byte Reserved1;
- word Reference;
- byte Reserved2[8];
-} RC;
-
-typedef struct {
- word next;
- byte Ind;
- byte IndId;
- byte IndCh;
- byte MInd;
- word MLength;
- word Reference;
- byte RNR;
- byte Reserved;
- dword Ack;
- PBUFFER RBuffer;
-} IND;
-
-#endif
+++ /dev/null
-/*
- * Diva Server PRI specific part of initialisation
- *
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.5
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include "sys.h"
-#include "idi.h"
-#include "divas.h"
-#include "pc.h"
-#include "pr_pc.h"
-#include "dsp_defs.h"
-
-#include "adapter.h"
-#include "uxio.h"
-
-#define DIVAS_LOAD_CMD 0x02
-#define DIVAS_START_CMD 0x03
-#define DIVAS_IRQ_RESET 0xC18
-#define DIVAS_IRQ_RESET_VAL 0xFE
-
-#define TEST_INT_DIVAS 0x11
-#define TEST_INT_DIVAS_BRI 0x12
-
-#define DIVAS_RESET 0x81
-#define DIVAS_LED1 0x04
-#define DIVAS_LED2 0x08
-#define DIVAS_LED3 0x20
-#define DIVAS_LED4 0x40
-
-#define DIVAS_RESET_REG 0x20
-
-#define DIVAS_SIGNATURE 0x4447
-
-/* offset to start of MAINT area (used by xlog) */
-
-#define DIVAS_MAINT_OFFSET 0xef00 /* value for PRI card */
-
-#define MP_PROTOCOL_ADDR 0xA0011000
-#define MP_DSP_CODE_BASE 0xa03a0000
-
-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;
-
-byte mem_in(ADAPTER *a, void *adr);
-word mem_inw(ADAPTER *a, void *adr);
-void mem_in_buffer(ADAPTER *a, void *adr, void *P, word length);
-void mem_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e);
-void mem_out(ADAPTER *a, void *adr, byte data);
-void mem_outw(ADAPTER *a, void *adr, word data);
-void mem_out_buffer(ADAPTER *a, void *adr, void *P, word length);
-void mem_inc(ADAPTER *a, void *adr);
-
-int DivasPRIInitPCI(card_t *card, dia_card_t *cfg);
-static int pri_ISR (card_t* card);
-
-static int diva_server_reset(card_t *card)
-{
- byte *reg;
- diva_server_boot_t *boot = NULL;
- dword live = 0;
- int i = 0;
- dword dwWait;
-
- DPRINTF(("divas: reset Diva Server PRI"));
-
- reg = UxCardMemAttach(card->hw, DIVAS_REG_MEMORY);
-
- UxCardMemOut(card->hw, ®[DIVAS_RESET_REG], DIVAS_RESET |
- DIVAS_LED1 | DIVAS_LED2 | DIVAS_LED3 | DIVAS_LED4);
-
- for (dwWait = 0x000fffff; dwWait; dwWait--)
- ;
-
- UxCardMemOut(card->hw, ®[DIVAS_RESET_REG], 0x00);
-
- for (dwWait = 0x000fffff; dwWait; dwWait--)
- ;
-
- UxCardMemDetach(card->hw, reg);
-
- boot = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);
-
- UxCardMemOutD(card->hw, boot->reserved, 0);
-
- live = UxCardMemInD(card->hw, &boot->live);
-
- for (i=0; i<5; i++)
- {
- if (live != UxCardMemInD(card->hw, &boot->live))
- {
- break;
- }
- UxPause(10);
- }
-
- if (i == 5)
- {
- UxCardMemDetach(card->hw, boot);
-
- DPRINTF(("divas: card is reset but CPU not running"));
- return -1;
- }
-
- UxCardMemDetach(card->hw, boot);
-
- DPRINTF(("divas: card reset after %d ms", i * 10));
-
- return 0;
-}
-
-static int diva_server_config(card_t *card, dia_config_t *config)
-{
- byte *shared;
- int i, j;
-
- DPRINTF(("divas: configure Diva Server PRI"));
-
- shared = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
-
- UxCardLog(0);
- for (i=0; i<256; i++)
- {
- UxCardMemOut(card->hw, &shared[i], 0);
- }
-
- UxCardMemOut(card->hw, &shared[ 8], config->tei);
- UxCardMemOut(card->hw, &shared[ 9], config->nt2);
- UxCardMemOut(card->hw, &shared[10], config->sig_flags);
- UxCardMemOut(card->hw, &shared[11], config->watchdog);
- UxCardMemOut(card->hw, &shared[12], config->permanent);
- UxCardMemOut(card->hw, &shared[13], config->x_interface);
- UxCardMemOut(card->hw, &shared[14], config->stable_l2);
- UxCardMemOut(card->hw, &shared[15], config->no_order_check);
- UxCardMemOut(card->hw, &shared[16], config->handset_type);
- UxCardMemOut(card->hw, &shared[17], 0);
- UxCardMemOut(card->hw, &shared[18], config->low_channel);
- UxCardMemOut(card->hw, &shared[19], config->prot_version);
- UxCardMemOut(card->hw, &shared[20], config->crc4);
-
- for (i=0; i<2; i++)
- {
- for (j=0; j<32; j++)
- {
- UxCardMemOut(card->hw, &shared[32+(i*96)+j],config->terminal[i].oad[j]);
- }
-
- for (j=0; j<32; j++)
- {
- UxCardMemOut(card->hw, &shared[64+(i*96)+j],config->terminal[i].osa[j]);
- }
-
- for (j=0; j<32; j++)
- {
- UxCardMemOut(card->hw, &shared[96+(i*96)+j],config->terminal[i].spid[j]);
- }
- }
-
- UxCardMemDetach(card->hw, shared);
-
- return 0;
-}
-
-static
-void diva_server_reset_int(card_t *card)
-{
- byte *cfg;
-
- cfg = UxCardMemAttach(card->hw, DIVAS_CFG_MEMORY);
-
- UxCardMemOutW(card->hw, &cfg[DIVAS_IRQ_RESET], DIVAS_IRQ_RESET_VAL);
- UxCardMemOutW(card->hw, &cfg[DIVAS_IRQ_RESET + 2], 0);
- UxCardMemDetach(card->hw, cfg);
-
- return;
-}
-
-
-static int diva_server_test_int(card_t *card)
-{
- int i;
- byte *shared;
- byte req_int;
-
- DPRINTF(("divas: test interrupt for Diva Server PRI"));
-
- shared = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
-
- UxCardMemIn(card->hw, &shared[0x3FE]);
- UxCardMemOut(card->hw, &shared[0x3FE], 0);
- UxCardMemIn(card->hw, &shared[0x3FE]);
-
- UxCardMemDetach(card->hw, shared);
-
- diva_server_reset_int(card);
-
- shared = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
-
- card->test_int_pend = TEST_INT_DIVAS;
-
- req_int = UxCardMemIn(card->hw, &(((struct pr_ram *)shared)->ReadyInt));
-
- req_int++;
-
- UxCardMemOut(card->hw, &(((struct pr_ram *)shared)->ReadyInt), req_int);
-
- UxCardMemDetach(card->hw, shared);
-
- UxCardLog(0);
- for (i = 0; i < 50; i++)
- {
- if (!card->test_int_pend)
- {
- break;
- }
- UxPause(10);
- }
-
-
- if (card->test_int_pend)
- {
-
- DPRINTF(("active: timeout waiting for card to interrupt"));
- return (-1);
-
- }
-
- return 0;
-}
-
-
-static void print_hdr(unsigned char *code, int offset)
-{
- unsigned char hdr[80];
- int i;
-
- i = 0;
-
- while ((i < (DIM(hdr) -1)) &&
- (code[offset + i] != '\0') &&
- (code[offset + i] != '\r') &&
- (code[offset + i] != '\n'))
- {
- hdr[i] = code[offset + i];
- i++;
- }
-
- hdr[i] = '\0';
-
- DPRINTF(("divas: loading %s", hdr));
-}
-
-static int diva_server_load(card_t *card, dia_load_t *load)
-{
- diva_server_boot_t *boot;
- int i, offset, length;
- dword cmd = 0;
-
- DPRINTF(("divas: loading Diva Server PRI"));
-
- boot = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);
-
- switch(load->code_type)
- {
- case DIA_CPU_CODE:
- DPRINTF(("divas: RISC code"));
- print_hdr(load->code, 0x80);
-
- UxCardMemOutD(card->hw, &boot->addr, MP_PROTOCOL_ADDR);
- break;
-
- case DIA_DSP_CODE:
- DPRINTF(("divas: DSP code"));
- print_hdr(load->code, 0x0);
-
- UxCardMemOutD(card->hw, &boot->addr,
- (MP_DSP_CODE_BASE + (((sizeof(dword) +
- (sizeof(t_dsp_download_desc) * DSP_MAX_DOWNLOAD_COUNT))
- + ~ALIGNMENT_MASK_MAESTRA) & ALIGNMENT_MASK_MAESTRA)));
- break;
-
- case DIA_TABLE_CODE:
- DPRINTF(("divas: TABLE code"));
- UxCardMemOutD(card->hw, &boot->addr,
- (MP_DSP_CODE_BASE + sizeof(dword)));
- break;
-
- case DIA_CONT_CODE:
- DPRINTF(("divas: continuation code"));
- break;
-
- case DIA_DLOAD_CNT:
- DPRINTF(("divas: COUNT code"));
- UxCardMemOutD(card->hw, &boot->addr, MP_DSP_CODE_BASE);
- break;
-
- default:
- DPRINTF(("divas: unknown code type"));
- UxCardMemDetach(card->hw, boot);
- return -1;
- }
-
- UxCardLog(0);
- offset = 0;
-
- do
- {
- length = (load->length - offset >= 400) ? 400 : load->length - offset;
-
- for (i=0; i<length; i++)
- {
- UxCardMemOut(card->hw, &boot->data[i], load->code[offset+i]);
- }
-
- for (i=0; i<length; i++)
- {
- if (load->code[offset + i] != UxCardMemIn(card->hw, &boot->data[i]))
- {
- UxCardMemDetach(card->hw, boot);
-
- DPRINTF(("divas: card code block verify failed"));
- return -1;
- }
- }
-
- UxCardMemOutD(card->hw, &boot->len, (length + 3) / 4);
- UxCardMemOutD(card->hw, &boot->cmd, DIVAS_LOAD_CMD);
-
- for (i=0; i<50000; i++)
- {
- cmd = UxCardMemInD(card->hw, &boot->cmd);
- if (!cmd)
- {
- break;
- }
- /*UxPause(1);*/
- }
-
- if (cmd)
- {
- DPRINTF(("divas: timeout waiting for card to ACK load (offset = %d)", offset));
- UxCardMemDetach(card->hw, boot);
- return -1;
- }
-
- offset += length;
-
- } while (offset < load->length);
-
- UxCardMemDetach(card->hw, boot);
-
- DPRINTF(("divas: DIVA Server card loaded"));
-
- return 0;
-}
-
-static int diva_server_start(card_t *card, byte *channels)
-{
- diva_server_boot_t *boot;
- byte *ram;
- int i;
- dword signature = 0;
-
- DPRINTF(("divas: start Diva Server PRI"));
-
- card->is_live = FALSE;
-
- boot = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);
-
- UxCardMemOutD(card->hw, &boot->addr, MP_PROTOCOL_ADDR);
- UxCardMemOutD(card->hw, &boot->cmd, DIVAS_START_CMD);
-
- UxCardLog(0);
-
- for (i = 0; i < 300; i++)
- {
- signature = UxCardMemInD(card->hw, &boot->signature);
- if ((signature >> 16) == DIVAS_SIGNATURE)
- {
- DPRINTF(("divas: started card after %d ms", i * 10));
- break;
- }
- UxPause(10);
- }
-
- if ((signature >> 16) != DIVAS_SIGNATURE)
- {
- UxCardMemDetach(card->hw, boot);
- DPRINTF(("divas: timeout waiting for card to run protocol code (sig = 0x%x)", signature));
- return -1;
- }
-
- card->is_live = TRUE;
-
- ram = (byte *) boot;
- ram += DIVAS_SHARED_OFFSET;
-
- *channels = UxCardMemIn(card->hw, &ram[0x3F6]);
- card->serial_no = UxCardMemInD(card->hw, &ram[0x3F0]);
-
- UxCardMemDetach(card->hw, boot);
-
- if (diva_server_test_int(card))
- {
- DPRINTF(("divas: interrupt test failed"));
- return -1;
- }
-
- DPRINTF(("divas: DIVA Server card started"));
-
- return 0;
-}
-
-static
-int diva_server_mem_get(card_t *card, mem_block_t *mem_block)
-
-{
- byte *a;
- byte *card_addr;
- word length = 0;
- int i;
-
- a = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);
-
- card_addr = a;
- card_addr += mem_block->addr;
-
- for (i=0; i < sizeof(mem_block->data); i++)
- {
- mem_block->data[i] = UxCardMemIn(card->hw, card_addr);
- card_addr++;
- length++;
- }
-
- UxCardMemDetach(card->hw, a);
-
- return length;
-}
-
-/*
- * Initialise PRI specific entry points
- */
-
-int DivasPriInit(card_t *card, dia_card_t *cfg)
-{
- DPRINTF(("divas: initialise Diva Server PRI"));
-
- if (DivasPRIInitPCI(card, cfg) == -1)
- {
- return -1;
- }
-
- card->card_reset = diva_server_reset;
- card->card_load = diva_server_load;
- card->card_config = diva_server_config;
- card->card_start = diva_server_start;
- card->reset_int = diva_server_reset_int;
- card->card_mem_get = diva_server_mem_get;
-
- card->xlog_offset = DIVAS_MAINT_OFFSET;
-
- card->out = DivasOut;
- card->test_int = DivasTestInt;
- card->dpc = DivasDpc;
- card->clear_int = DivasClearInt;
- card->card_isr = pri_ISR;
-
- card->a.ram_out = mem_out;
- card->a.ram_outw = mem_outw;
- card->a.ram_out_buffer = mem_out_buffer;
- card->a.ram_inc = mem_inc;
-
- card->a.ram_in = mem_in;
- card->a.ram_inw = mem_inw;
- card->a.ram_in_buffer = mem_in_buffer;
- card->a.ram_look_ahead = mem_look_ahead;
-
- return 0;
-}
-
-
-static int pri_ISR (card_t* card)
-{
- int served = 0;
- byte* cfg = UxCardMemAttach(card->hw, DIVAS_CFG_MEMORY);
- volatile unsigned long* isr = (unsigned long*)&cfg[DIVAS_IRQ_RESET];
- register unsigned long val = *isr;
-
- if (val & 0x80000000) /* our card had caused interrupt ??? */
- {
- served = 1;
- card->int_pend += 1;
- DivasDpcSchedule(); /* ISR DPC */
-
- *isr = (unsigned long)~0x03E00000; /* Clear interrupt line */
- }
-
- UxCardMemDetach(card->hw, cfg);
-
- return (served != 0);
-}
-
-
+++ /dev/null
-/*
- * Environment provided by system and miscellaneous definitions
- *
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.2
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#if !defined(SYS_H)
-#define SYS_H
-
-/* abreviations for unsigned types */
-typedef int boolean_t;
-
-typedef unsigned char byte;
-
-typedef unsigned long dword;
-typedef unsigned short word;
-
-/* abreviations for volatile types */
-
-typedef volatile byte vbyte;
-typedef volatile word vword;
-typedef volatile dword vdword;
-
-/* Booleans */
-
-#if !defined(TRUE)
-#define TRUE (1)
-#define FALSE (0)
-#endif
-
-/* NULL pointer */
-
-#if !defined(NULL)
-#define NULL ((void *) 0)
-#endif
-
-/* Return the dimension of an array */
-
-#if !defined(DIM)
-#define DIM(array) (sizeof (array)/sizeof ((array)[0]))
-#endif
-
-/*
- * Return the number of milliseconds since last boot
- */
-
-extern dword UxTimeGet(void);
-
-extern void DivasSprintf(char *buffer, char *format, ...);
-extern void DivasPrintf(char *format, ...);
-
-/* fatal errors, asserts and tracing */
-
-void HwFatalErrorFrom(char *file, int line);
-void HwFatalError(void);
-/* void HwAssert(char *file, int line, char *condition); */
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-
-#define _PRINTK printk
-
-#define _PRINTF DivasPrintf
-void _PRINTF(char *format, ...);
-#define PRINTF(arg_list) _PRINTF arg_list
-#if defined DTRACE
-# define DPRINTF(arg_list) _PRINTF arg_list
-# define KDPRINTF(arg_list) _PRINTF arg_list ; _PRINTK arg_list ; _PRINTK("\n");
-#else
-# define DPRINTF(arg_list) (void)0
-# define KDPRINTF(arg_list) _PRINTK arg_list ; _PRINTK("\n");
-#endif
-
-#if !defined(ASSERT)
-#if defined DEBUG || defined DBG
-# define HwFatalError() HwFatalErrorFrom(__FILE__, __LINE__)
-# define ASSERT(cond) \
- if (!(cond)) \
- { \
-/* HwAssert(__FILE__, __LINE__, #cond);*/ \
- }
-#else
-# define ASSERT(cond) ((void)0)
-#endif
-#endif /* !defined(ASSERT) */
-
-#define TRACE (_PRINTF(__FILE__"@%d\n", __LINE__))
-
-#endif /* SYS_H */
+++ /dev/null
-/*
- * Interface to Unix specific code for performing card I/O
- *
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.6
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#if !defined(UXIO_H)
-#define UXIO_H
-
-#include "sys.h"
-#include "adapter.h"
-
-
-struct pt_regs;
-
-/* user callback, returns zero if interrupt was from this card */
-typedef void isr_fn_t(void *);
-struct ux_diva_card_s
-{
- word in_use;
- int io_base;
- int reset_base;
- int card_type;
- byte *mapped;
- struct pci_dev *pdev;
- int slot;
- int irq;
- byte *pDRAM;
- byte *pDEVICES;
- byte *pCONFIG;
- byte *pSHARED;
- byte *pCONTROL;
- word features;
- void *user_isr_arg;
- isr_fn_t *user_isr;
-};
-
-/*
- * Get a card handle to enable card to be accessed
- */
-
-int UxCardHandleGet( ux_diva_card_t **card,
- dia_card_t *cfg);
-
-/*
- * Free a card handle as no longer needed
- */
-
-void UxCardHandleFree(ux_diva_card_t *card);
-
-/*
- * Lock and unlock access to a card
- */
-
-long UxCardLock(ux_diva_card_t *card);
-void UxCardUnlock(ux_diva_card_t *card, unsigned long ipl);
-
-/*
- * Set the mapping address for PCI cards
- */
-
-int UxCardAddrMappingSet(ux_diva_card_t *card,
- int id,
- void *address,
- int size);
-
-/*
- * Attach card to memory to enable it to be accessed
- * Returns the mapped address
- */
-
-void *UxCardMemAttach(ux_diva_card_t *card, int id);
-
-/*
- * map card out of memory after completion of access
- */
-
-void UxCardMemDetach(ux_diva_card_t *card, void *address);
-
-/*
- * input functions for memory-mapped cards
- */
-
-byte UxCardMemIn(ux_diva_card_t *card, void *address);
-
-word UxCardMemInW(ux_diva_card_t *card, void *address);
-
-dword UxCardMemInD(ux_diva_card_t *card, void *address);
-
-void UxCardMemInBuffer( ux_diva_card_t *card,
- void *address,
- void *buffer,
- int length);
-
-/*
- * output functions for memory-mapped cards
- */
-
-void UxCardMemOut(ux_diva_card_t *card, void *address, byte data);
-
-void UxCardMemOutW(ux_diva_card_t *card, void *address, word data);
-
-void UxCardMemOutD(ux_diva_card_t *card, void *address, dword data);
-
-void UxCardMemOutBuffer( ux_diva_card_t *card,
- void *address,
- void *buffer,
- int length);
-
-/*
- * input functions for I/O-mapped cards
- */
-
-byte UxCardIoIn(ux_diva_card_t *card, void *, void *address);
-
-word UxCardIoInW(ux_diva_card_t *card, void *, void *address);
-
-dword UxCardIoInD(ux_diva_card_t *card, void *, void *address);
-
-void UxCardIoInBuffer( ux_diva_card_t *card,
- void *, void *address,
- void *buffer,
- int length);
-
-/*
- * output functions for I/O-mapped cards
- */
-
-void UxCardIoOut(ux_diva_card_t *card, void *, void *address, byte data);
-
-void UxCardIoOutW(ux_diva_card_t *card, void *, void *address, word data);
-
-void UxCardIoOutD(ux_diva_card_t *card, void *, void *address, dword data);
-
-void UxCardIoOutBuffer( ux_diva_card_t *card,
- void *, void *address,
- void *buffer,
- int length);
-
-/*
- * Get specified PCI config
- */
-
-void UxPciConfigRead(ux_diva_card_t *card,
- int size,
- int offset,
- void *value);
-
-/*
- * Set specified PCI config
- */
-
-void UxPciConfigWrite(ux_diva_card_t *card,
- int size,
- int offset,
- void *value);
-
-/* allocate memory, returning NULL if none available */
-
-void *UxAlloc(unsigned int size);
-
-void UxFree(void *);
-
-/*
- * Pause for specified number of milli-seconds
- */
-
-void UxPause(long ms);
-
-/*
- * Install an ISR for the specified card
- */
-
-int UxIsrInstall(ux_diva_card_t *card, isr_fn_t *isr_fn, void *isr_arg);
-
-/*
- * Remove an ISR for the specified card
- */
-void UxIsrRemove(ux_diva_card_t *card, void *);
-
-/*
- * DEBUG function to turn logging ON or OFF
- */
-
-void UxCardLog(int turn_on);
-
-long UxInterlockedIncrement(ux_diva_card_t *card, long *dst);
-long UxInterlockedDecrement(ux_diva_card_t *card, long *dst);
-
-#endif /* of UXIO_H */
+++ /dev/null
-/*
- * Unix Eicon active card driver
- * XLOG related functions
- *
- * Copyright (C) Eicon Technology Corporation, 2000.
- *
- * Eicon File Revision : 1.2
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include "sys.h"
-#include "idi.h"
-#include "pc.h"
-#include "pc_maint.h"
-#include "divalog.h"
-
-#include "adapter.h"
-#include "uxio.h"
-
-/*
- * convert/copy XLOG info into a KLOG entry
- */
-
-static
-void xlog_to_klog(byte *b, int size, int card_num)
-
-{
- typedef struct
- {
- word code;
- word time_hi;
- word time_lo;
- word xcode;
- byte data[2];
- } card_xlog_t;
-
- card_xlog_t *x;
-
- klog_t klog;
-
- x = (card_xlog_t *) b;
-
- memset(&klog, 0, sizeof(klog));
-
- klog.time_stamp = (dword) x->time_hi;
- klog.time_stamp = (klog.time_stamp << 16) | (dword) x->time_lo;
-
- klog.length = size > sizeof(klog.buffer) ? sizeof(klog.buffer) : size;
-
- klog.card = card_num;
- if (x->code == 1)
- {
- klog.type = KLOG_XTXT_MSG;
- klog.code = 0;
- memcpy(klog.buffer, &x->xcode, klog.length);
- }
- else if (x->code == 2)
- {
- klog.type = KLOG_XLOG_MSG;
- klog.code = x->xcode;
- memcpy(klog.buffer, &x->data, klog.length);
- }
- else
- {
- char *c; int i;
- klog.type = KLOG_TEXT_MSG;
- klog.code = 0;
- c = "divas: invalid xlog message code from card";
- i = 0;
- while (*c)
- {
- klog.buffer[i] = *c;
- c++;
- i++;
- }
- klog.buffer[i] = *c;
- }
-
- /* send to the log driver and return */
-
- DivasLogAdd(&klog, sizeof(klog));
-
- return;
-}
-
-/*
- * send an XLOG request down to specified card
- * if response available from previous request then read it
- * if not then just send down new request, ready for next time
- */
-
-void DivasXlogReq(int card_num)
-
-{
- card_t *card;
- ADAPTER *a;
-
- if ((card_num < 0) || (card_num > DivasCardNext))
- {
- DPRINTF(("xlog: invalid card number"));
- return;
- }
-
- card = &DivasCards[card_num];
-
- if (DivasXlogRetrieve(card))
- {
- return;
- }
-
- /* send down request for next time */
-
- a = &card->a;
-
- a->ram_out(a, (word *) (card->xlog_offset + 1), 0);
- a->ram_out(a, (word *) (dword) (card->xlog_offset), DO_LOG);
-
- return;
-}
-
-/*
- * retrieve XLOG request from specified card
- * returns non-zero if new request sent to card
- */
-
-int DivasXlogRetrieve(card_t *card)
-
-{
- ADAPTER *a;
- struct mi_pc_maint pcm;
-
- a = &card->a;
-
- /* get status of last request */
-
- pcm.rc = a->ram_in(a, (word *)(card->xlog_offset + 1));
-
- /* if nothing there from previous request, send down a new one */
-
- if (pcm.rc == OK)
- {
- /* read in response */
-
- a->ram_in_buffer(a, (word *) (dword) card->xlog_offset, &pcm, sizeof(pcm));
-
- xlog_to_klog((byte *) &pcm.data, sizeof(pcm.data),
- (int) (card - DivasCards));
- }
-
- /* if any response received from card, re-send request */
-
- if (pcm.rc)
- {
- a->ram_out(a, (word *) (card->xlog_offset + 1), 0);
- a->ram_out(a, (word *) (dword) (card->xlog_offset), DO_LOG);
-
- return 1;
- }
-
- return 0;
-}