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