linux/drivers/isdn/hardware/eicon/divasfunc.c
<<
>>
Prefs
   1/* $Id: divasfunc.c,v 1.23.4.2 2004/08/28 20:03:53 armin Exp $
   2 *
   3 * Low level driver for Eicon DIVA Server ISDN cards.
   4 *
   5 * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
   6 * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
   7 *
   8 * This software may be used and distributed according to the terms
   9 * of the GNU General Public License, incorporated herein by reference.
  10 */
  11
  12#include "platform.h"
  13#include "di_defs.h"
  14#include "pc.h"
  15#include "di.h"
  16#include "io.h"
  17#include "divasync.h"
  18#include "diva.h"
  19#include "xdi_vers.h"
  20
  21#define DBG_MINIMUM  (DL_LOG + DL_FTL + DL_ERR)
  22#define DBG_DEFAULT  (DBG_MINIMUM + DL_XLOG + DL_REG)
  23
  24static int debugmask;
  25
  26extern void DIVA_DIDD_Read(void *, int);
  27
  28extern PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
  29
  30extern char *DRIVERRELEASE_DIVAS;
  31
  32static dword notify_handle;
  33static DESCRIPTOR DAdapter;
  34static DESCRIPTOR MAdapter;
  35
  36/* --------------------------------------------------------------------------
  37   MAINT driver connector section
  38   -------------------------------------------------------------------------- */
  39static void no_printf(unsigned char *x, ...)
  40{
  41        /* dummy debug function */
  42}
  43
  44#include "debuglib.c"
  45
  46/*
  47 * get the adapters serial number
  48 */
  49void diva_get_vserial_number(PISDN_ADAPTER IoAdapter, char *buf)
  50{
  51        int contr = 0;
  52
  53        if ((contr = ((IoAdapter->serialNo & 0xff000000) >> 24))) {
  54                sprintf(buf, "%d-%d",
  55                        IoAdapter->serialNo & 0x00ffffff, contr + 1);
  56        } else {
  57                sprintf(buf, "%d", IoAdapter->serialNo);
  58        }
  59}
  60
  61/*
  62 * register a new adapter
  63 */
  64void diva_xdi_didd_register_adapter(int card)
  65{
  66        DESCRIPTOR d;
  67        IDI_SYNC_REQ req;
  68
  69        if (card && ((card - 1) < MAX_ADAPTER) &&
  70            IoAdapters[card - 1] && Requests[card - 1]) {
  71                d.type = IoAdapters[card - 1]->Properties.DescType;
  72                d.request = Requests[card - 1];
  73                d.channels = IoAdapters[card - 1]->Properties.Channels;
  74                d.features = IoAdapters[card - 1]->Properties.Features;
  75                DBG_TRC(("DIDD register A(%d) channels=%d", card,
  76                         d.channels))
  77                        /* workaround for different Name in structure */
  78                        strlcpy(IoAdapters[card - 1]->Name,
  79                                IoAdapters[card - 1]->Properties.Name,
  80                                sizeof(IoAdapters[card - 1]->Name));
  81                req.didd_remove_adapter.e.Req = 0;
  82                req.didd_add_adapter.e.Rc = IDI_SYNC_REQ_DIDD_ADD_ADAPTER;
  83                req.didd_add_adapter.info.descriptor = (void *) &d;
  84                DAdapter.request((ENTITY *)&req);
  85                if (req.didd_add_adapter.e.Rc != 0xff) {
  86                        DBG_ERR(("DIDD register A(%d) failed !", card))
  87                                }
  88                IoAdapters[card - 1]->os_trap_nfy_Fnc = NULL;
  89        }
  90}
  91
  92/*
  93 * remove an adapter
  94 */
  95void diva_xdi_didd_remove_adapter(int card)
  96{
  97        IDI_SYNC_REQ req;
  98        ADAPTER *a = &IoAdapters[card - 1]->a;
  99
 100        IoAdapters[card - 1]->os_trap_nfy_Fnc = NULL;
 101        DBG_TRC(("DIDD de-register A(%d)", card))
 102                req.didd_remove_adapter.e.Req = 0;
 103        req.didd_remove_adapter.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER;
 104        req.didd_remove_adapter.info.p_request =
 105                (IDI_CALL) Requests[card - 1];
 106        DAdapter.request((ENTITY *)&req);
 107        memset(&(a->IdTable), 0x00, 256);
 108}
 109
 110/*
 111 * start debug
 112 */
 113static void start_dbg(void)
 114{
 115        DbgRegister("DIVAS", DRIVERRELEASE_DIVAS, (debugmask) ? debugmask : DBG_DEFAULT);
 116        DBG_LOG(("DIVA ISDNXDI BUILD (%s[%s])",
 117                 DIVA_BUILD, diva_xdi_common_code_build))
 118                }
 119
 120/*
 121 * stop debug
 122 */
 123static void stop_dbg(void)
 124{
 125        DbgDeregister();
 126        memset(&MAdapter, 0, sizeof(MAdapter));
 127        dprintf = no_printf;
 128}
 129
 130/*
 131 * didd callback function
 132 */
 133static void *didd_callback(void *context, DESCRIPTOR *adapter,
 134                           int removal)
 135{
 136        if (adapter->type == IDI_DADAPTER) {
 137                DBG_ERR(("Notification about IDI_DADAPTER change ! Oops."));
 138                return (NULL);
 139        }
 140
 141        if (adapter->type == IDI_DIMAINT) {
 142                if (removal) {
 143                        stop_dbg();
 144                } else {
 145                        memcpy(&MAdapter, adapter, sizeof(MAdapter));
 146                        dprintf = (DIVA_DI_PRINTF) MAdapter.request;
 147                        start_dbg();
 148                }
 149        }
 150        return (NULL);
 151}
 152
 153/*
 154 * connect to didd
 155 */
 156static int __init connect_didd(void)
 157{
 158        int x = 0;
 159        int dadapter = 0;
 160        IDI_SYNC_REQ req;
 161        DESCRIPTOR DIDD_Table[MAX_DESCRIPTORS];
 162
 163        DIVA_DIDD_Read(DIDD_Table, sizeof(DIDD_Table));
 164
 165        for (x = 0; x < MAX_DESCRIPTORS; x++) {
 166                if (DIDD_Table[x].type == IDI_DADAPTER) {       /* DADAPTER found */
 167                        dadapter = 1;
 168                        memcpy(&DAdapter, &DIDD_Table[x], sizeof(DAdapter));
 169                        req.didd_notify.e.Req = 0;
 170                        req.didd_notify.e.Rc =
 171                                IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
 172                        req.didd_notify.info.callback = (void *)didd_callback;
 173                        req.didd_notify.info.context = NULL;
 174                        DAdapter.request((ENTITY *)&req);
 175                        if (req.didd_notify.e.Rc != 0xff) {
 176                                stop_dbg();
 177                                return (0);
 178                        }
 179                        notify_handle = req.didd_notify.info.handle;
 180                } else if (DIDD_Table[x].type == IDI_DIMAINT) { /* MAINT found */
 181                        memcpy(&MAdapter, &DIDD_Table[x], sizeof(DAdapter));
 182                        dprintf = (DIVA_DI_PRINTF) MAdapter.request;
 183                        start_dbg();
 184                }
 185        }
 186
 187        if (!dadapter) {
 188                stop_dbg();
 189        }
 190
 191        return (dadapter);
 192}
 193
 194/*
 195 * disconnect from didd
 196 */
 197static void disconnect_didd(void)
 198{
 199        IDI_SYNC_REQ req;
 200
 201        stop_dbg();
 202
 203        req.didd_notify.e.Req = 0;
 204        req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY;
 205        req.didd_notify.info.handle = notify_handle;
 206        DAdapter.request((ENTITY *)&req);
 207}
 208
 209/*
 210 * init
 211 */
 212int __init divasfunc_init(int dbgmask)
 213{
 214        char *version;
 215
 216        debugmask = dbgmask;
 217
 218        if (!connect_didd()) {
 219                DBG_ERR(("divasfunc: failed to connect to DIDD."))
 220                        return (0);
 221        }
 222
 223        version = diva_xdi_common_code_build;
 224
 225        divasa_xdi_driver_entry();
 226
 227        return (1);
 228}
 229
 230/*
 231 * exit
 232 */
 233void divasfunc_exit(void)
 234{
 235        divasa_xdi_driver_unload();
 236        disconnect_didd();
 237}
 238