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