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]-%s-%s)",
 117                 DIVA_BUILD, diva_xdi_common_code_build, __DATE__,
 118                 __TIME__))
 119}
 120
 121/*
 122 * stop debug
 123 */
 124static void stop_dbg(void)
 125{
 126        DbgDeregister();
 127        memset(&MAdapter, 0, sizeof(MAdapter));
 128        dprintf = no_printf;
 129}
 130
 131/*
 132 * didd callback function
 133 */
 134static void *didd_callback(void *context, DESCRIPTOR * adapter,
 135                           int removal)
 136{
 137        if (adapter->type == IDI_DADAPTER) {
 138                DBG_ERR(("Notification about IDI_DADAPTER change ! Oops."));
 139                return (NULL);
 140        }
 141
 142        if (adapter->type == IDI_DIMAINT) {
 143                if (removal) {
 144                        stop_dbg();
 145                } else {
 146                        memcpy(&MAdapter, adapter, sizeof(MAdapter));
 147                        dprintf = (DIVA_DI_PRINTF) MAdapter.request;
 148                        start_dbg();
 149                }
 150        }
 151        return (NULL);
 152}
 153
 154/*
 155 * connect to didd
 156 */
 157static int DIVA_INIT_FUNCTION connect_didd(void)
 158{
 159        int x = 0;
 160        int dadapter = 0;
 161        IDI_SYNC_REQ req;
 162        DESCRIPTOR DIDD_Table[MAX_DESCRIPTORS];
 163
 164        DIVA_DIDD_Read(DIDD_Table, sizeof(DIDD_Table));
 165
 166        for (x = 0; x < MAX_DESCRIPTORS; x++) {
 167                if (DIDD_Table[x].type == IDI_DADAPTER) {       /* DADAPTER found */
 168                        dadapter = 1;
 169                        memcpy(&DAdapter, &DIDD_Table[x], sizeof(DAdapter));
 170                        req.didd_notify.e.Req = 0;
 171                        req.didd_notify.e.Rc =
 172                            IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
 173                        req.didd_notify.info.callback = (void *)didd_callback;
 174                        req.didd_notify.info.context = NULL;
 175                        DAdapter.request((ENTITY *) & req);
 176                        if (req.didd_notify.e.Rc != 0xff) {
 177                                stop_dbg();
 178                                return (0);
 179                        }
 180                        notify_handle = req.didd_notify.info.handle;
 181                } else if (DIDD_Table[x].type == IDI_DIMAINT) { /* MAINT found */
 182                        memcpy(&MAdapter, &DIDD_Table[x], sizeof(DAdapter));
 183                        dprintf = (DIVA_DI_PRINTF) MAdapter.request;
 184                        start_dbg();
 185                }
 186        }
 187
 188        if (!dadapter) {
 189                stop_dbg();
 190        }
 191
 192        return (dadapter);
 193}
 194
 195/*
 196 * disconnect from didd
 197 */
 198static void disconnect_didd(void)
 199{
 200        IDI_SYNC_REQ req;
 201
 202        stop_dbg();
 203
 204        req.didd_notify.e.Req = 0;
 205        req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY;
 206        req.didd_notify.info.handle = notify_handle;
 207        DAdapter.request((ENTITY *) & req);
 208}
 209
 210/*
 211 * init
 212 */
 213int DIVA_INIT_FUNCTION divasfunc_init(int dbgmask)
 214{
 215        char *version;
 216
 217        debugmask = dbgmask;
 218        
 219        if (!connect_didd()) {
 220                DBG_ERR(("divasfunc: failed to connect to DIDD."))
 221                return (0);
 222        }
 223
 224        version = diva_xdi_common_code_build;
 225
 226        divasa_xdi_driver_entry();
 227
 228        return (1);
 229}
 230
 231/*
 232 * exit
 233 */
 234void divasfunc_exit(void)
 235{
 236        divasa_xdi_driver_unload();
 237        disconnect_didd();
 238}
 239