• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* $Id: diva.c,v 1.21.4.1 2004/05/08 14:33:43 armin Exp $ */
2 
3 #define CARDTYPE_H_WANT_DATA            1
4 #define CARDTYPE_H_WANT_IDI_DATA        0
5 #define CARDTYPE_H_WANT_RESOURCE_DATA   0
6 #define CARDTYPE_H_WANT_FILE_DATA       0
7 
8 #include "platform.h"
9 #include "debuglib.h"
10 #include "cardtype.h"
11 #include "pc.h"
12 #include "di_defs.h"
13 #include "di.h"
14 #include "io.h"
15 #include "pc_maint.h"
16 #include "xdi_msg.h"
17 #include "xdi_adapter.h"
18 #include "diva_pci.h"
19 #include "diva.h"
20 
21 #ifdef CONFIG_ISDN_DIVAS_PRIPCI
22 #include "os_pri.h"
23 #endif
24 #ifdef CONFIG_ISDN_DIVAS_BRIPCI
25 #include "os_bri.h"
26 #include "os_4bri.h"
27 #endif
28 
29 PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
30 extern IDI_CALL Requests[MAX_ADAPTER];
31 extern int create_adapter_proc(diva_os_xdi_adapter_t *a);
32 extern void remove_adapter_proc(diva_os_xdi_adapter_t *a);
33 
34 #define DivaIdiReqFunc(N)						\
35 	static void DivaIdiRequest##N(ENTITY *e)			\
36 	{ if (IoAdapters[N]) (*IoAdapters[N]->DIRequest)(IoAdapters[N], e); }
37 
38 /*
39 **  Create own 32 Adapters
40 */
41 DivaIdiReqFunc(0)
42 DivaIdiReqFunc(1)
43 DivaIdiReqFunc(2)
44 DivaIdiReqFunc(3)
45 DivaIdiReqFunc(4)
46 DivaIdiReqFunc(5)
47 DivaIdiReqFunc(6)
48 DivaIdiReqFunc(7)
49 DivaIdiReqFunc(8)
50 DivaIdiReqFunc(9)
51 DivaIdiReqFunc(10)
52 DivaIdiReqFunc(11)
53 DivaIdiReqFunc(12)
54 DivaIdiReqFunc(13)
55 DivaIdiReqFunc(14)
56 DivaIdiReqFunc(15)
57 DivaIdiReqFunc(16)
58 DivaIdiReqFunc(17)
59 DivaIdiReqFunc(18)
60 DivaIdiReqFunc(19)
61 DivaIdiReqFunc(20)
62 DivaIdiReqFunc(21)
63 DivaIdiReqFunc(22)
64 DivaIdiReqFunc(23)
65 DivaIdiReqFunc(24)
66 DivaIdiReqFunc(25)
67 DivaIdiReqFunc(26)
68 DivaIdiReqFunc(27)
69 DivaIdiReqFunc(28)
70 DivaIdiReqFunc(29)
71 DivaIdiReqFunc(30)
72 DivaIdiReqFunc(31)
73 
74 /*
75 **  LOCALS
76 */
77 static LIST_HEAD(adapter_queue);
78 
79 typedef struct _diva_get_xlog {
80 	word command;
81 	byte req;
82 	byte rc;
83 	byte data[sizeof(struct mi_pc_maint)];
84 } diva_get_xlog_t;
85 
86 typedef struct _diva_supported_cards_info {
87 	int CardOrdinal;
88 	diva_init_card_proc_t init_card;
89 } diva_supported_cards_info_t;
90 
91 static diva_supported_cards_info_t divas_supported_cards[] = {
92 #ifdef CONFIG_ISDN_DIVAS_PRIPCI
93 	/*
94 	  PRI Cards
95 	*/
96 	{CARDTYPE_DIVASRV_P_30M_PCI, diva_pri_init_card},
97 	/*
98 	  PRI Rev.2 Cards
99 	*/
100 	{CARDTYPE_DIVASRV_P_30M_V2_PCI, diva_pri_init_card},
101 	/*
102 	  PRI Rev.2 VoIP Cards
103 	*/
104 	{CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI, diva_pri_init_card},
105 #endif
106 #ifdef CONFIG_ISDN_DIVAS_BRIPCI
107 	/*
108 	  4BRI Rev 1 Cards
109 	*/
110 	{CARDTYPE_DIVASRV_Q_8M_PCI, diva_4bri_init_card},
111 	{CARDTYPE_DIVASRV_VOICE_Q_8M_PCI, diva_4bri_init_card},
112 	/*
113 	  4BRI Rev 2 Cards
114 	*/
115 	{CARDTYPE_DIVASRV_Q_8M_V2_PCI, diva_4bri_init_card},
116 	{CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI, diva_4bri_init_card},
117 	/*
118 	  4BRI Based BRI Rev 2 Cards
119 	*/
120 	{CARDTYPE_DIVASRV_B_2M_V2_PCI, diva_4bri_init_card},
121 	{CARDTYPE_DIVASRV_B_2F_PCI, diva_4bri_init_card},
122 	{CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI, diva_4bri_init_card},
123 	/*
124 	  BRI
125 	*/
126 	{CARDTYPE_MAESTRA_PCI, diva_bri_init_card},
127 #endif
128 
129 	/*
130 	  EOL
131 	*/
132 	{-1}
133 };
134 
135 static void diva_init_request_array(void);
136 static void *divas_create_pci_card(int handle, void *pci_dev_handle);
137 
138 static diva_os_spin_lock_t adapter_lock;
139 
diva_find_free_adapters(int base,int nr)140 static int diva_find_free_adapters(int base, int nr)
141 {
142 	int i;
143 
144 	for (i = 0; i < nr; i++) {
145 		if (IoAdapters[base + i]) {
146 			return (-1);
147 		}
148 	}
149 
150 	return (0);
151 }
152 
diva_q_get_next(struct list_head * what)153 static diva_os_xdi_adapter_t *diva_q_get_next(struct list_head *what)
154 {
155 	diva_os_xdi_adapter_t *a = NULL;
156 
157 	if (what && (what->next != &adapter_queue))
158 		a = list_entry(what->next, diva_os_xdi_adapter_t, link);
159 
160 	return (a);
161 }
162 
163 /* --------------------------------------------------------------------------
164    Add card to the card list
165    -------------------------------------------------------------------------- */
diva_driver_add_card(void * pdev,unsigned long CardOrdinal)166 void *diva_driver_add_card(void *pdev, unsigned long CardOrdinal)
167 {
168 	diva_os_spin_lock_magic_t old_irql;
169 	diva_os_xdi_adapter_t *pdiva, *pa;
170 	int i, j, max, nr;
171 
172 	for (i = 0; divas_supported_cards[i].CardOrdinal != -1; i++) {
173 		if (divas_supported_cards[i].CardOrdinal == CardOrdinal) {
174 			if (!(pdiva = divas_create_pci_card(i, pdev))) {
175 				return NULL;
176 			}
177 			switch (CardOrdinal) {
178 			case CARDTYPE_DIVASRV_Q_8M_PCI:
179 			case CARDTYPE_DIVASRV_VOICE_Q_8M_PCI:
180 			case CARDTYPE_DIVASRV_Q_8M_V2_PCI:
181 			case CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI:
182 				max = MAX_ADAPTER - 4;
183 				nr = 4;
184 				break;
185 
186 			default:
187 				max = MAX_ADAPTER;
188 				nr = 1;
189 			}
190 
191 			diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add card");
192 
193 			for (i = 0; i < max; i++) {
194 				if (!diva_find_free_adapters(i, nr)) {
195 					pdiva->controller = i + 1;
196 					pdiva->xdi_adapter.ANum = pdiva->controller;
197 					IoAdapters[i] = &pdiva->xdi_adapter;
198 					diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card");
199 					create_adapter_proc(pdiva);	/* add adapter to proc file system */
200 
201 					DBG_LOG(("add %s:%d",
202 						 CardProperties
203 						 [CardOrdinal].Name,
204 						 pdiva->controller))
205 
206 						diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add card");
207 					pa = pdiva;
208 					for (j = 1; j < nr; j++) {	/* slave adapters, if any */
209 						pa = diva_q_get_next(&pa->link);
210 						if (pa && !pa->interface.cleanup_adapter_proc) {
211 							pa->controller = i + 1 + j;
212 							pa->xdi_adapter.ANum = pa->controller;
213 							IoAdapters[i + j] = &pa->xdi_adapter;
214 							diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card");
215 							DBG_LOG(("add slave adapter (%d)",
216 								 pa->controller))
217 								create_adapter_proc(pa);	/* add adapter to proc file system */
218 							diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add card");
219 						} else {
220 							DBG_ERR(("slave adapter problem"))
221 								break;
222 						}
223 					}
224 
225 					diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card");
226 					return (pdiva);
227 				}
228 			}
229 
230 			diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card");
231 
232 			/*
233 			  Not able to add adapter - remove it and return error
234 			*/
235 			DBG_ERR(("can not alloc request array"))
236 				diva_driver_remove_card(pdiva);
237 
238 			return NULL;
239 		}
240 	}
241 
242 	return NULL;
243 }
244 
245 /* --------------------------------------------------------------------------
246    Called on driver load, MAIN, main, DriverEntry
247    -------------------------------------------------------------------------- */
divasa_xdi_driver_entry(void)248 int divasa_xdi_driver_entry(void)
249 {
250 	diva_os_initialize_spin_lock(&adapter_lock, "adapter");
251 	memset(&IoAdapters[0], 0x00, sizeof(IoAdapters));
252 	diva_init_request_array();
253 
254 	return (0);
255 }
256 
257 /* --------------------------------------------------------------------------
258    Remove adapter from list
259    -------------------------------------------------------------------------- */
get_and_remove_from_queue(void)260 static diva_os_xdi_adapter_t *get_and_remove_from_queue(void)
261 {
262 	diva_os_spin_lock_magic_t old_irql;
263 	diva_os_xdi_adapter_t *a = NULL;
264 
265 	diva_os_enter_spin_lock(&adapter_lock, &old_irql, "driver_unload");
266 
267 	if (!list_empty(&adapter_queue)) {
268 		a = list_entry(adapter_queue.next, diva_os_xdi_adapter_t, link);
269 		list_del(adapter_queue.next);
270 	}
271 
272 	diva_os_leave_spin_lock(&adapter_lock, &old_irql, "driver_unload");
273 	return (a);
274 }
275 
276 /* --------------------------------------------------------------------------
277    Remove card from the card list
278    -------------------------------------------------------------------------- */
diva_driver_remove_card(void * pdiva)279 void diva_driver_remove_card(void *pdiva)
280 {
281 	diva_os_spin_lock_magic_t old_irql;
282 	diva_os_xdi_adapter_t *a[4];
283 	diva_os_xdi_adapter_t *pa;
284 	int i;
285 
286 	pa = a[0] = (diva_os_xdi_adapter_t *) pdiva;
287 	a[1] = a[2] = a[3] = NULL;
288 
289 	diva_os_enter_spin_lock(&adapter_lock, &old_irql, "remode adapter");
290 
291 	for (i = 1; i < 4; i++) {
292 		if ((pa = diva_q_get_next(&pa->link))
293 		    && !pa->interface.cleanup_adapter_proc) {
294 			a[i] = pa;
295 		} else {
296 			break;
297 		}
298 	}
299 
300 	for (i = 0; ((i < 4) && a[i]); i++) {
301 		list_del(&a[i]->link);
302 	}
303 
304 	diva_os_leave_spin_lock(&adapter_lock, &old_irql, "driver_unload");
305 
306 	(*(a[0]->interface.cleanup_adapter_proc)) (a[0]);
307 
308 	for (i = 0; i < 4; i++) {
309 		if (a[i]) {
310 			if (a[i]->controller) {
311 				DBG_LOG(("remove adapter (%d)",
312 					 a[i]->controller)) IoAdapters[a[i]->controller - 1] = NULL;
313 				remove_adapter_proc(a[i]);
314 			}
315 			diva_os_free(0, a[i]);
316 		}
317 	}
318 }
319 
320 /* --------------------------------------------------------------------------
321    Create diva PCI adapter and init internal adapter structures
322    -------------------------------------------------------------------------- */
divas_create_pci_card(int handle,void * pci_dev_handle)323 static void *divas_create_pci_card(int handle, void *pci_dev_handle)
324 {
325 	diva_supported_cards_info_t *pI = &divas_supported_cards[handle];
326 	diva_os_spin_lock_magic_t old_irql;
327 	diva_os_xdi_adapter_t *a;
328 
329 	DBG_LOG(("found %d-%s", pI->CardOrdinal, CardProperties[pI->CardOrdinal].Name))
330 
331 		if (!(a = (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a)))) {
332 			DBG_ERR(("A: can't alloc adapter"));
333 			return NULL;
334 		}
335 
336 	memset(a, 0x00, sizeof(*a));
337 
338 	a->CardIndex = handle;
339 	a->CardOrdinal = pI->CardOrdinal;
340 	a->Bus = DIVAS_XDI_ADAPTER_BUS_PCI;
341 	a->xdi_adapter.cardType = a->CardOrdinal;
342 	a->resources.pci.bus = diva_os_get_pci_bus(pci_dev_handle);
343 	a->resources.pci.func = diva_os_get_pci_func(pci_dev_handle);
344 	a->resources.pci.hdev = pci_dev_handle;
345 
346 	/*
347 	  Add master adapter first, so slave adapters will receive higher
348 	  numbers as master adapter
349 	*/
350 	diva_os_enter_spin_lock(&adapter_lock, &old_irql, "found_pci_card");
351 	list_add_tail(&a->link, &adapter_queue);
352 	diva_os_leave_spin_lock(&adapter_lock, &old_irql, "found_pci_card");
353 
354 	if ((*(pI->init_card)) (a)) {
355 		diva_os_enter_spin_lock(&adapter_lock, &old_irql, "found_pci_card");
356 		list_del(&a->link);
357 		diva_os_leave_spin_lock(&adapter_lock, &old_irql, "found_pci_card");
358 		diva_os_free(0, a);
359 		DBG_ERR(("A: can't get adapter resources"));
360 		return NULL;
361 	}
362 
363 	return (a);
364 }
365 
366 /* --------------------------------------------------------------------------
367    Called on driver unload FINIT, finit, Unload
368    -------------------------------------------------------------------------- */
divasa_xdi_driver_unload(void)369 void divasa_xdi_driver_unload(void)
370 {
371 	diva_os_xdi_adapter_t *a;
372 
373 	while ((a = get_and_remove_from_queue())) {
374 		if (a->interface.cleanup_adapter_proc) {
375 			(*(a->interface.cleanup_adapter_proc)) (a);
376 		}
377 		if (a->controller) {
378 			IoAdapters[a->controller - 1] = NULL;
379 			remove_adapter_proc(a);
380 		}
381 		diva_os_free(0, a);
382 	}
383 	diva_os_destroy_spin_lock(&adapter_lock, "adapter");
384 }
385 
386 /*
387 **  Receive and process command from user mode utility
388 */
diva_xdi_open_adapter(void * os_handle,const void __user * src,int length,void * mptr,divas_xdi_copy_from_user_fn_t cp_fn)389 void *diva_xdi_open_adapter(void *os_handle, const void __user *src,
390 			    int length, void *mptr,
391 			    divas_xdi_copy_from_user_fn_t cp_fn)
392 {
393 	diva_xdi_um_cfg_cmd_t *msg = (diva_xdi_um_cfg_cmd_t *)mptr;
394 	diva_os_xdi_adapter_t *a = NULL;
395 	diva_os_spin_lock_magic_t old_irql;
396 	struct list_head *tmp;
397 
398 	if (length < sizeof(diva_xdi_um_cfg_cmd_t)) {
399 		DBG_ERR(("A: A(?) open, msg too small (%d < %d)",
400 			 length, sizeof(diva_xdi_um_cfg_cmd_t)))
401 			return NULL;
402 	}
403 	if ((*cp_fn) (os_handle, msg, src, sizeof(*msg)) <= 0) {
404 		DBG_ERR(("A: A(?) open, write error"))
405 			return NULL;
406 	}
407 	diva_os_enter_spin_lock(&adapter_lock, &old_irql, "open_adapter");
408 	list_for_each(tmp, &adapter_queue) {
409 		a = list_entry(tmp, diva_os_xdi_adapter_t, link);
410 		if (a->controller == (int)msg->adapter)
411 			break;
412 		a = NULL;
413 	}
414 	diva_os_leave_spin_lock(&adapter_lock, &old_irql, "open_adapter");
415 
416 	if (!a) {
417 		DBG_ERR(("A: A(%d) open, adapter not found", msg->adapter))
418 			}
419 
420 	return (a);
421 }
422 
423 /*
424 **  Easy cleanup mailbox status
425 */
diva_xdi_close_adapter(void * adapter,void * os_handle)426 void diva_xdi_close_adapter(void *adapter, void *os_handle)
427 {
428 	diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) adapter;
429 
430 	a->xdi_mbox.status &= ~DIVA_XDI_MBOX_BUSY;
431 	if (a->xdi_mbox.data) {
432 		diva_os_free(0, a->xdi_mbox.data);
433 		a->xdi_mbox.data = NULL;
434 	}
435 }
436 
437 int
diva_xdi_write(void * adapter,void * os_handle,const void __user * src,int length,void * mptr,divas_xdi_copy_from_user_fn_t cp_fn)438 diva_xdi_write(void *adapter, void *os_handle, const void __user *src,
439 	       int length, void *mptr,
440 	       divas_xdi_copy_from_user_fn_t cp_fn)
441 {
442 	diva_xdi_um_cfg_cmd_t *msg = (diva_xdi_um_cfg_cmd_t *)mptr;
443 	diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) adapter;
444 	void *data;
445 
446 	if (a->xdi_mbox.status & DIVA_XDI_MBOX_BUSY) {
447 		DBG_ERR(("A: A(%d) write, mbox busy", a->controller))
448 			return (-1);
449 	}
450 
451 	if (length < sizeof(diva_xdi_um_cfg_cmd_t)) {
452 		DBG_ERR(("A: A(%d) write, message too small (%d < %d)",
453 			 a->controller, length,
454 			 sizeof(diva_xdi_um_cfg_cmd_t)))
455 			return (-3);
456 	}
457 
458 	if (!(data = diva_os_malloc(0, length))) {
459 		DBG_ERR(("A: A(%d) write, ENOMEM", a->controller))
460 			return (-2);
461 	}
462 
463 	if (msg) {
464 		*(diva_xdi_um_cfg_cmd_t *)data = *msg;
465 		length = (*cp_fn) (os_handle, (char *)data + sizeof(*msg),
466 				   src + sizeof(*msg), length - sizeof(*msg));
467 	} else {
468 		length = (*cp_fn) (os_handle, data, src, length);
469 	}
470 	if (length > 0) {
471 		if ((*(a->interface.cmd_proc))
472 		    (a, (diva_xdi_um_cfg_cmd_t *) data, length)) {
473 			length = -3;
474 		}
475 	} else {
476 		DBG_ERR(("A: A(%d) write error (%d)", a->controller,
477 			 length))
478 			}
479 
480 	diva_os_free(0, data);
481 
482 	return (length);
483 }
484 
485 /*
486 **  Write answers to user mode utility, if any
487 */
488 int
diva_xdi_read(void * adapter,void * os_handle,void __user * dst,int max_length,divas_xdi_copy_to_user_fn_t cp_fn)489 diva_xdi_read(void *adapter, void *os_handle, void __user *dst,
490 	      int max_length, divas_xdi_copy_to_user_fn_t cp_fn)
491 {
492 	diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) adapter;
493 	int ret;
494 
495 	if (!(a->xdi_mbox.status & DIVA_XDI_MBOX_BUSY)) {
496 		DBG_ERR(("A: A(%d) rx mbox empty", a->controller))
497 			return (-1);
498 	}
499 	if (!a->xdi_mbox.data) {
500 		a->xdi_mbox.status &= ~DIVA_XDI_MBOX_BUSY;
501 		DBG_ERR(("A: A(%d) rx ENOMEM", a->controller))
502 			return (-2);
503 	}
504 
505 	if (max_length < a->xdi_mbox.data_length) {
506 		DBG_ERR(("A: A(%d) rx buffer too short(%d < %d)",
507 			 a->controller, max_length,
508 			 a->xdi_mbox.data_length))
509 			return (-3);
510 	}
511 
512 	ret = (*cp_fn) (os_handle, dst, a->xdi_mbox.data,
513 			a->xdi_mbox.data_length);
514 	if (ret > 0) {
515 		diva_os_free(0, a->xdi_mbox.data);
516 		a->xdi_mbox.data = NULL;
517 		a->xdi_mbox.status &= ~DIVA_XDI_MBOX_BUSY;
518 	}
519 
520 	return (ret);
521 }
522 
523 
diva_os_irq_wrapper(int irq,void * context)524 irqreturn_t diva_os_irq_wrapper(int irq, void *context)
525 {
526 	diva_os_xdi_adapter_t *a = context;
527 	diva_xdi_clear_interrupts_proc_t clear_int_proc;
528 
529 	if (!a || !a->xdi_adapter.diva_isr_handler)
530 		return IRQ_NONE;
531 
532 	if ((clear_int_proc = a->clear_interrupts_proc)) {
533 		(*clear_int_proc) (a);
534 		a->clear_interrupts_proc = NULL;
535 		return IRQ_HANDLED;
536 	}
537 
538 	(*(a->xdi_adapter.diva_isr_handler)) (&a->xdi_adapter);
539 	return IRQ_HANDLED;
540 }
541 
diva_init_request_array(void)542 static void diva_init_request_array(void)
543 {
544 	Requests[0] = DivaIdiRequest0;
545 	Requests[1] = DivaIdiRequest1;
546 	Requests[2] = DivaIdiRequest2;
547 	Requests[3] = DivaIdiRequest3;
548 	Requests[4] = DivaIdiRequest4;
549 	Requests[5] = DivaIdiRequest5;
550 	Requests[6] = DivaIdiRequest6;
551 	Requests[7] = DivaIdiRequest7;
552 	Requests[8] = DivaIdiRequest8;
553 	Requests[9] = DivaIdiRequest9;
554 	Requests[10] = DivaIdiRequest10;
555 	Requests[11] = DivaIdiRequest11;
556 	Requests[12] = DivaIdiRequest12;
557 	Requests[13] = DivaIdiRequest13;
558 	Requests[14] = DivaIdiRequest14;
559 	Requests[15] = DivaIdiRequest15;
560 	Requests[16] = DivaIdiRequest16;
561 	Requests[17] = DivaIdiRequest17;
562 	Requests[18] = DivaIdiRequest18;
563 	Requests[19] = DivaIdiRequest19;
564 	Requests[20] = DivaIdiRequest20;
565 	Requests[21] = DivaIdiRequest21;
566 	Requests[22] = DivaIdiRequest22;
567 	Requests[23] = DivaIdiRequest23;
568 	Requests[24] = DivaIdiRequest24;
569 	Requests[25] = DivaIdiRequest25;
570 	Requests[26] = DivaIdiRequest26;
571 	Requests[27] = DivaIdiRequest27;
572 	Requests[28] = DivaIdiRequest28;
573 	Requests[29] = DivaIdiRequest29;
574 	Requests[30] = DivaIdiRequest30;
575 	Requests[31] = DivaIdiRequest31;
576 }
577 
diva_xdi_display_adapter_features(int card)578 void diva_xdi_display_adapter_features(int card)
579 {
580 	dword features;
581 	if (!card || ((card - 1) >= MAX_ADAPTER) || !IoAdapters[card - 1]) {
582 		return;
583 	}
584 	card--;
585 	features = IoAdapters[card]->Properties.Features;
586 
587 	DBG_LOG(("FEATURES FOR ADAPTER: %d", card + 1))
588 		DBG_LOG((" DI_FAX3          :  %s",
589 			 (features & DI_FAX3) ? "Y" : "N"))
590 		DBG_LOG((" DI_MODEM         :  %s",
591 			 (features & DI_MODEM) ? "Y" : "N"))
592 		DBG_LOG((" DI_POST          :  %s",
593 			 (features & DI_POST) ? "Y" : "N"))
594 		DBG_LOG((" DI_V110          :  %s",
595 			 (features & DI_V110) ? "Y" : "N"))
596 		DBG_LOG((" DI_V120          :  %s",
597 			 (features & DI_V120) ? "Y" : "N"))
598 		DBG_LOG((" DI_POTS          :  %s",
599 			 (features & DI_POTS) ? "Y" : "N"))
600 		DBG_LOG((" DI_CODEC         :  %s",
601 			 (features & DI_CODEC) ? "Y" : "N"))
602 		DBG_LOG((" DI_MANAGE        :  %s",
603 			 (features & DI_MANAGE) ? "Y" : "N"))
604 		DBG_LOG((" DI_V_42          :  %s",
605 			 (features & DI_V_42) ? "Y" : "N"))
606 		DBG_LOG((" DI_EXTD_FAX      :  %s",
607 			 (features & DI_EXTD_FAX) ? "Y" : "N"))
608 		DBG_LOG((" DI_AT_PARSER     :  %s",
609 			 (features & DI_AT_PARSER) ? "Y" : "N"))
610 		DBG_LOG((" DI_VOICE_OVER_IP :  %s",
611 			 (features & DI_VOICE_OVER_IP) ? "Y" : "N"))
612 		}
613 
diva_add_slave_adapter(diva_os_xdi_adapter_t * a)614 void diva_add_slave_adapter(diva_os_xdi_adapter_t *a)
615 {
616 	diva_os_spin_lock_magic_t old_irql;
617 
618 	diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add_slave");
619 	list_add_tail(&a->link, &adapter_queue);
620 	diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add_slave");
621 }
622 
diva_card_read_xlog(diva_os_xdi_adapter_t * a)623 int diva_card_read_xlog(diva_os_xdi_adapter_t *a)
624 {
625 	diva_get_xlog_t *req;
626 	byte *data;
627 
628 	if (!a->xdi_adapter.Initialized || !a->xdi_adapter.DIRequest) {
629 		return (-1);
630 	}
631 	if (!(data = diva_os_malloc(0, sizeof(struct mi_pc_maint)))) {
632 		return (-1);
633 	}
634 	memset(data, 0x00, sizeof(struct mi_pc_maint));
635 
636 	if (!(req = diva_os_malloc(0, sizeof(*req)))) {
637 		diva_os_free(0, data);
638 		return (-1);
639 	}
640 	req->command = 0x0400;
641 	req->req = LOG;
642 	req->rc = 0x00;
643 
644 	(*(a->xdi_adapter.DIRequest)) (&a->xdi_adapter, (ENTITY *) req);
645 
646 	if (!req->rc || req->req) {
647 		diva_os_free(0, data);
648 		diva_os_free(0, req);
649 		return (-1);
650 	}
651 
652 	memcpy(data, &req->req, sizeof(struct mi_pc_maint));
653 
654 	diva_os_free(0, req);
655 
656 	a->xdi_mbox.data_length = sizeof(struct mi_pc_maint);
657 	a->xdi_mbox.data = data;
658 	a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
659 
660 	return (0);
661 }
662 
xdiFreeFile(void * handle)663 void xdiFreeFile(void *handle)
664 {
665 }
666