Blame view

kernel/linux-rt-4.4.41/drivers/isdn/hardware/eicon/diddfunc.c 2.58 KB
5113f6f70   김현기   kernel add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
  /* $Id: diddfunc.c,v 1.14.6.2 2004/08/28 20:03:53 armin Exp $
   *
   * DIDD Interface module for Eicon active cards.
   *
   * Functions are in dadapter.c
   *
   * Copyright 2002-2003 by Armin Schindler (mac@melware.de)
   * Copyright 2002-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 "dadapter.h"
  #include "divasync.h"
  
  #define DBG_MINIMUM  (DL_LOG + DL_FTL + DL_ERR)
  #define DBG_DEFAULT  (DBG_MINIMUM + DL_XLOG + DL_REG)
  
  
  extern void DIVA_DIDD_Read(void *, int);
  extern char *DRIVERRELEASE_DIDD;
  static dword notify_handle;
  static DESCRIPTOR _DAdapter;
  
  /*
   * 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);
  	} else if (adapter->type == IDI_DIMAINT) {
  		if (removal) {
  			DbgDeregister();
  		} else {
  			DbgRegister("DIDD", DRIVERRELEASE_DIDD, DBG_DEFAULT);
  		}
  	}
  	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)
  				return (0);
  			notify_handle = req.didd_notify.info.handle;
  		} else if (DIDD_Table[x].type == IDI_DIMAINT) {	/* MAINT found */
  			DbgRegister("DIDD", DRIVERRELEASE_DIDD, DBG_DEFAULT);
  		}
  	}
  	return (dadapter);
  }
  
  /*
   * disconnect from didd
   */
  static void __exit disconnect_didd(void)
  {
  	IDI_SYNC_REQ req;
  
  	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 diddfunc_init(void)
  {
  	diva_didd_load_time_init();
  
  	if (!connect_didd()) {
  		DBG_ERR(("init: failed to connect to DIDD."))
  			diva_didd_load_time_finit();
  		return (0);
  	}
  	return (1);
  }
  
  /*
   * finit
   */
  void __exit diddfunc_finit(void)
  {
  	DbgDeregister();
  	disconnect_didd();
  	diva_didd_load_time_finit();
  }