diff options
Diffstat (limited to 'kernel/drivers/isdn/hardware/eicon/divasfunc.c')
-rw-r--r-- | kernel/drivers/isdn/hardware/eicon/divasfunc.c | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/kernel/drivers/isdn/hardware/eicon/divasfunc.c b/kernel/drivers/isdn/hardware/eicon/divasfunc.c new file mode 100644 index 000000000..4be5f8814 --- /dev/null +++ b/kernel/drivers/isdn/hardware/eicon/divasfunc.c @@ -0,0 +1,237 @@ +/* $Id: divasfunc.c,v 1.23.4.2 2004/08/28 20:03:53 armin Exp $ + * + * Low level driver for Eicon DIVA Server ISDN cards. + * + * Copyright 2000-2003 by Armin Schindler (mac@melware.de) + * Copyright 2000-2003 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 "platform.h" +#include "di_defs.h" +#include "pc.h" +#include "di.h" +#include "io.h" +#include "divasync.h" +#include "diva.h" +#include "xdi_vers.h" + +#define DBG_MINIMUM (DL_LOG + DL_FTL + DL_ERR) +#define DBG_DEFAULT (DBG_MINIMUM + DL_XLOG + DL_REG) + +static int debugmask; + +extern void DIVA_DIDD_Read(void *, int); + +extern PISDN_ADAPTER IoAdapters[MAX_ADAPTER]; + +extern char *DRIVERRELEASE_DIVAS; + +static dword notify_handle; +static DESCRIPTOR DAdapter; +static DESCRIPTOR MAdapter; + +/* -------------------------------------------------------------------------- + MAINT driver connector section + -------------------------------------------------------------------------- */ +static void no_printf(unsigned char *x, ...) +{ + /* dummy debug function */ +} + +#include "debuglib.c" + +/* + * get the adapters serial number + */ +void diva_get_vserial_number(PISDN_ADAPTER IoAdapter, char *buf) +{ + int contr = 0; + + if ((contr = ((IoAdapter->serialNo & 0xff000000) >> 24))) { + sprintf(buf, "%d-%d", + IoAdapter->serialNo & 0x00ffffff, contr + 1); + } else { + sprintf(buf, "%d", IoAdapter->serialNo); + } +} + +/* + * register a new adapter + */ +void diva_xdi_didd_register_adapter(int card) +{ + DESCRIPTOR d; + IDI_SYNC_REQ req; + + if (card && ((card - 1) < MAX_ADAPTER) && + IoAdapters[card - 1] && Requests[card - 1]) { + d.type = IoAdapters[card - 1]->Properties.DescType; + d.request = Requests[card - 1]; + d.channels = IoAdapters[card - 1]->Properties.Channels; + d.features = IoAdapters[card - 1]->Properties.Features; + DBG_TRC(("DIDD register A(%d) channels=%d", card, + d.channels)) + /* workaround for different Name in structure */ + strlcpy(IoAdapters[card - 1]->Name, + IoAdapters[card - 1]->Properties.Name, + sizeof(IoAdapters[card - 1]->Name)); + req.didd_remove_adapter.e.Req = 0; + req.didd_add_adapter.e.Rc = IDI_SYNC_REQ_DIDD_ADD_ADAPTER; + req.didd_add_adapter.info.descriptor = (void *) &d; + DAdapter.request((ENTITY *)&req); + if (req.didd_add_adapter.e.Rc != 0xff) { + DBG_ERR(("DIDD register A(%d) failed !", card)) + } + IoAdapters[card - 1]->os_trap_nfy_Fnc = NULL; + } +} + +/* + * remove an adapter + */ +void diva_xdi_didd_remove_adapter(int card) +{ + IDI_SYNC_REQ req; + ADAPTER *a = &IoAdapters[card - 1]->a; + + IoAdapters[card - 1]->os_trap_nfy_Fnc = NULL; + DBG_TRC(("DIDD de-register A(%d)", card)) + req.didd_remove_adapter.e.Req = 0; + req.didd_remove_adapter.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER; + req.didd_remove_adapter.info.p_request = + (IDI_CALL) Requests[card - 1]; + DAdapter.request((ENTITY *)&req); + memset(&(a->IdTable), 0x00, 256); +} + +/* + * start debug + */ +static void start_dbg(void) +{ + DbgRegister("DIVAS", DRIVERRELEASE_DIVAS, (debugmask) ? debugmask : DBG_DEFAULT); + DBG_LOG(("DIVA ISDNXDI BUILD (%s[%s])", + DIVA_BUILD, diva_xdi_common_code_build)) + } + +/* + * stop debug + */ +static void stop_dbg(void) +{ + DbgDeregister(); + memset(&MAdapter, 0, sizeof(MAdapter)); + dprintf = no_printf; +} + +/* + * didd callback function + */ +static void *didd_callback(void *context, DESCRIPTOR *adapter, + int removal) +{ + if (adapter->type == IDI_DADAPTER) { + DBG_ERR(("Notification about IDI_DADAPTER change ! Oops.")); + return (NULL); + } + + if (adapter->type == IDI_DIMAINT) { + if (removal) { + stop_dbg(); + } else { + memcpy(&MAdapter, adapter, sizeof(MAdapter)); + dprintf = (DIVA_DI_PRINTF) MAdapter.request; + start_dbg(); + } + } + return (NULL); +} + +/* + * connect to didd + */ +static int __init connect_didd(void) +{ + int x = 0; + int dadapter = 0; + IDI_SYNC_REQ req; + DESCRIPTOR DIDD_Table[MAX_DESCRIPTORS]; + + DIVA_DIDD_Read(DIDD_Table, sizeof(DIDD_Table)); + + for (x = 0; x < MAX_DESCRIPTORS; x++) { + if (DIDD_Table[x].type == IDI_DADAPTER) { /* DADAPTER found */ + dadapter = 1; + memcpy(&DAdapter, &DIDD_Table[x], sizeof(DAdapter)); + req.didd_notify.e.Req = 0; + req.didd_notify.e.Rc = + IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY; + req.didd_notify.info.callback = (void *)didd_callback; + req.didd_notify.info.context = NULL; + DAdapter.request((ENTITY *)&req); + if (req.didd_notify.e.Rc != 0xff) { + stop_dbg(); + return (0); + } + notify_handle = req.didd_notify.info.handle; + } else if (DIDD_Table[x].type == IDI_DIMAINT) { /* MAINT found */ + memcpy(&MAdapter, &DIDD_Table[x], sizeof(DAdapter)); + dprintf = (DIVA_DI_PRINTF) MAdapter.request; + start_dbg(); + } + } + + if (!dadapter) { + stop_dbg(); + } + + return (dadapter); +} + +/* + * disconnect from didd + */ +static void disconnect_didd(void) +{ + IDI_SYNC_REQ req; + + stop_dbg(); + + req.didd_notify.e.Req = 0; + req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY; + req.didd_notify.info.handle = notify_handle; + DAdapter.request((ENTITY *)&req); +} + +/* + * init + */ +int __init divasfunc_init(int dbgmask) +{ + char *version; + + debugmask = dbgmask; + + if (!connect_didd()) { + DBG_ERR(("divasfunc: failed to connect to DIDD.")) + return (0); + } + + version = diva_xdi_common_code_build; + + divasa_xdi_driver_entry(); + + return (1); +} + +/* + * exit + */ +void divasfunc_exit(void) +{ + divasa_xdi_driver_unload(); + disconnect_didd(); +} |