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