~ubuntu-branches/ubuntu/utopic/linux-ti-omap/utopic

« back to all changes in this revision

Viewing changes to drivers/isdn/hardware/eicon/diva.c

  • Committer: Bazaar Package Importer
  • Author(s): Amit Kucheria, Amit Kucheria
  • Date: 2010-03-10 02:28:15 UTC
  • Revision ID: james.westby@ubuntu.com-20100310022815-7sd3gwvn5kenaq33
Tags: 2.6.33-500.1
[ Amit Kucheria ]

* Initial release of a 2.6.33-based OMAP kernel
* UBUNTU: [Upstream] Fix omap 1-wire driver compilation
* UBUNTU: ubuntu: AppArmor -- update to mainline 2010-03-04

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
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
 
 
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
   -------------------------------------------------------------------------- */
 
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
   -------------------------------------------------------------------------- */
 
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
   -------------------------------------------------------------------------- */
 
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
   -------------------------------------------------------------------------- */
 
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
   -------------------------------------------------------------------------- */
 
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
   -------------------------------------------------------------------------- */
 
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
*/
 
389
void *diva_xdi_open_adapter(void *os_handle, const void __user *src,
 
390
                            int length,
 
391
                            divas_xdi_copy_from_user_fn_t cp_fn)
 
392
{
 
393
        diva_xdi_um_cfg_cmd_t msg;
 
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
*/
 
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
 
438
diva_xdi_write(void *adapter, void *os_handle, const void __user *src,
 
439
               int length, divas_xdi_copy_from_user_fn_t cp_fn)
 
440
{
 
441
        diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) adapter;
 
442
        void *data;
 
443
 
 
444
        if (a->xdi_mbox.status & DIVA_XDI_MBOX_BUSY) {
 
445
                DBG_ERR(("A: A(%d) write, mbox busy", a->controller))
 
446
                return (-1);
 
447
        }
 
448
 
 
449
        if (length < sizeof(diva_xdi_um_cfg_cmd_t)) {
 
450
                DBG_ERR(("A: A(%d) write, message too small (%d < %d)",
 
451
                         a->controller, length,
 
452
                         sizeof(diva_xdi_um_cfg_cmd_t)))
 
453
                return (-3);
 
454
        }
 
455
 
 
456
        if (!(data = diva_os_malloc(0, length))) {
 
457
                DBG_ERR(("A: A(%d) write, ENOMEM", a->controller))
 
458
                return (-2);
 
459
        }
 
460
 
 
461
        length = (*cp_fn) (os_handle, data, src, length);
 
462
        if (length > 0) {
 
463
                if ((*(a->interface.cmd_proc))
 
464
                    (a, (diva_xdi_um_cfg_cmd_t *) data, length)) {
 
465
                        length = -3;
 
466
                }
 
467
        } else {
 
468
                DBG_ERR(("A: A(%d) write error (%d)", a->controller,
 
469
                         length))
 
470
        }
 
471
 
 
472
        diva_os_free(0, data);
 
473
 
 
474
        return (length);
 
475
}
 
476
 
 
477
/*
 
478
**  Write answers to user mode utility, if any
 
479
*/
 
480
int
 
481
diva_xdi_read(void *adapter, void *os_handle, void __user *dst,
 
482
              int max_length, divas_xdi_copy_to_user_fn_t cp_fn)
 
483
{
 
484
        diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) adapter;
 
485
        int ret;
 
486
 
 
487
        if (!(a->xdi_mbox.status & DIVA_XDI_MBOX_BUSY)) {
 
488
                DBG_ERR(("A: A(%d) rx mbox empty", a->controller))
 
489
                return (-1);
 
490
        }
 
491
        if (!a->xdi_mbox.data) {
 
492
                a->xdi_mbox.status &= ~DIVA_XDI_MBOX_BUSY;
 
493
                DBG_ERR(("A: A(%d) rx ENOMEM", a->controller))
 
494
                return (-2);
 
495
        }
 
496
 
 
497
        if (max_length < a->xdi_mbox.data_length) {
 
498
                DBG_ERR(("A: A(%d) rx buffer too short(%d < %d)",
 
499
                         a->controller, max_length,
 
500
                         a->xdi_mbox.data_length))
 
501
                return (-3);
 
502
        }
 
503
 
 
504
        ret = (*cp_fn) (os_handle, dst, a->xdi_mbox.data,
 
505
                      a->xdi_mbox.data_length);
 
506
        if (ret > 0) {
 
507
                diva_os_free(0, a->xdi_mbox.data);
 
508
                a->xdi_mbox.data = NULL;
 
509
                a->xdi_mbox.status &= ~DIVA_XDI_MBOX_BUSY;
 
510
        }
 
511
 
 
512
        return (ret);
 
513
}
 
514
 
 
515
 
 
516
irqreturn_t diva_os_irq_wrapper(int irq, void *context)
 
517
{
 
518
        diva_os_xdi_adapter_t *a = context;
 
519
        diva_xdi_clear_interrupts_proc_t clear_int_proc;
 
520
 
 
521
        if (!a || !a->xdi_adapter.diva_isr_handler)
 
522
                return IRQ_NONE;
 
523
 
 
524
        if ((clear_int_proc = a->clear_interrupts_proc)) {
 
525
                (*clear_int_proc) (a);
 
526
                a->clear_interrupts_proc = NULL;
 
527
                return IRQ_HANDLED;
 
528
        }
 
529
 
 
530
        (*(a->xdi_adapter.diva_isr_handler)) (&a->xdi_adapter);
 
531
        return IRQ_HANDLED;
 
532
}
 
533
 
 
534
static void diva_init_request_array(void)
 
535
{
 
536
        Requests[0] = DivaIdiRequest0;
 
537
        Requests[1] = DivaIdiRequest1;
 
538
        Requests[2] = DivaIdiRequest2;
 
539
        Requests[3] = DivaIdiRequest3;
 
540
        Requests[4] = DivaIdiRequest4;
 
541
        Requests[5] = DivaIdiRequest5;
 
542
        Requests[6] = DivaIdiRequest6;
 
543
        Requests[7] = DivaIdiRequest7;
 
544
        Requests[8] = DivaIdiRequest8;
 
545
        Requests[9] = DivaIdiRequest9;
 
546
        Requests[10] = DivaIdiRequest10;
 
547
        Requests[11] = DivaIdiRequest11;
 
548
        Requests[12] = DivaIdiRequest12;
 
549
        Requests[13] = DivaIdiRequest13;
 
550
        Requests[14] = DivaIdiRequest14;
 
551
        Requests[15] = DivaIdiRequest15;
 
552
        Requests[16] = DivaIdiRequest16;
 
553
        Requests[17] = DivaIdiRequest17;
 
554
        Requests[18] = DivaIdiRequest18;
 
555
        Requests[19] = DivaIdiRequest19;
 
556
        Requests[20] = DivaIdiRequest20;
 
557
        Requests[21] = DivaIdiRequest21;
 
558
        Requests[22] = DivaIdiRequest22;
 
559
        Requests[23] = DivaIdiRequest23;
 
560
        Requests[24] = DivaIdiRequest24;
 
561
        Requests[25] = DivaIdiRequest25;
 
562
        Requests[26] = DivaIdiRequest26;
 
563
        Requests[27] = DivaIdiRequest27;
 
564
        Requests[28] = DivaIdiRequest28;
 
565
        Requests[29] = DivaIdiRequest29;
 
566
        Requests[30] = DivaIdiRequest30;
 
567
        Requests[31] = DivaIdiRequest31;
 
568
}
 
569
 
 
570
void diva_xdi_display_adapter_features(int card)
 
571
{
 
572
        dword features;
 
573
        if (!card || ((card - 1) >= MAX_ADAPTER) || !IoAdapters[card - 1]) {
 
574
                return;
 
575
        }
 
576
        card--;
 
577
        features = IoAdapters[card]->Properties.Features;
 
578
 
 
579
        DBG_LOG(("FEATURES FOR ADAPTER: %d", card + 1))
 
580
        DBG_LOG((" DI_FAX3          :  %s",
 
581
                     (features & DI_FAX3) ? "Y" : "N"))
 
582
        DBG_LOG((" DI_MODEM         :  %s",
 
583
                     (features & DI_MODEM) ? "Y" : "N"))
 
584
        DBG_LOG((" DI_POST          :  %s",
 
585
                     (features & DI_POST) ? "Y" : "N"))
 
586
        DBG_LOG((" DI_V110          :  %s",
 
587
                     (features & DI_V110) ? "Y" : "N"))
 
588
        DBG_LOG((" DI_V120          :  %s",
 
589
                     (features & DI_V120) ? "Y" : "N"))
 
590
        DBG_LOG((" DI_POTS          :  %s",
 
591
                     (features & DI_POTS) ? "Y" : "N"))
 
592
        DBG_LOG((" DI_CODEC         :  %s",
 
593
                     (features & DI_CODEC) ? "Y" : "N"))
 
594
        DBG_LOG((" DI_MANAGE        :  %s",
 
595
                     (features & DI_MANAGE) ? "Y" : "N"))
 
596
        DBG_LOG((" DI_V_42          :  %s",
 
597
                     (features & DI_V_42) ? "Y" : "N"))
 
598
        DBG_LOG((" DI_EXTD_FAX      :  %s",
 
599
                     (features & DI_EXTD_FAX) ? "Y" : "N"))
 
600
        DBG_LOG((" DI_AT_PARSER     :  %s",
 
601
                     (features & DI_AT_PARSER) ? "Y" : "N"))
 
602
        DBG_LOG((" DI_VOICE_OVER_IP :  %s",
 
603
                     (features & DI_VOICE_OVER_IP) ? "Y" : "N"))
 
604
}
 
605
 
 
606
void diva_add_slave_adapter(diva_os_xdi_adapter_t * a)
 
607
{
 
608
        diva_os_spin_lock_magic_t old_irql;
 
609
 
 
610
        diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add_slave");
 
611
        list_add_tail(&a->link, &adapter_queue);
 
612
        diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add_slave");
 
613
}
 
614
 
 
615
int diva_card_read_xlog(diva_os_xdi_adapter_t * a)
 
616
{
 
617
        diva_get_xlog_t *req;
 
618
        byte *data;
 
619
 
 
620
        if (!a->xdi_adapter.Initialized || !a->xdi_adapter.DIRequest) {
 
621
                return (-1);
 
622
        }
 
623
        if (!(data = diva_os_malloc(0, sizeof(struct mi_pc_maint)))) {
 
624
                return (-1);
 
625
        }
 
626
        memset(data, 0x00, sizeof(struct mi_pc_maint));
 
627
 
 
628
        if (!(req = diva_os_malloc(0, sizeof(*req)))) {
 
629
                diva_os_free(0, data);
 
630
                return (-1);
 
631
        }
 
632
        req->command = 0x0400;
 
633
        req->req = LOG;
 
634
        req->rc = 0x00;
 
635
 
 
636
        (*(a->xdi_adapter.DIRequest)) (&a->xdi_adapter, (ENTITY *) req);
 
637
 
 
638
        if (!req->rc || req->req) {
 
639
                diva_os_free(0, data);
 
640
                diva_os_free(0, req);
 
641
                return (-1);
 
642
        }
 
643
 
 
644
        memcpy(data, &req->req, sizeof(struct mi_pc_maint));
 
645
 
 
646
        diva_os_free(0, req);
 
647
 
 
648
        a->xdi_mbox.data_length = sizeof(struct mi_pc_maint);
 
649
        a->xdi_mbox.data = data;
 
650
        a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
 
651
 
 
652
        return (0);
 
653
}
 
654
 
 
655
void xdiFreeFile(void *handle)
 
656
{
 
657
}