include upstream ip1000a driver version 2.09f
[linux-2.4.git] / drivers / isdn / eicon / xlog.c
1 /*
2  * Unix Eicon active card driver
3  * XLOG related functions
4  *
5  * Copyright (C) Eicon Technology Corporation, 2000.
6  *
7  * Eicon File Revision :    1.2  
8  *
9  * This software may be used and distributed according to the terms
10  * of the GNU General Public License, incorporated herein by reference.
11  *
12  */
13
14 #include "sys.h"
15 #include "idi.h"
16 #include "pc.h"
17 #include "pc_maint.h"
18 #include "divalog.h"
19
20 #include "adapter.h"
21 #include "uxio.h"
22
23 /*
24  * convert/copy XLOG info into a KLOG entry
25  */
26
27 static
28 void    xlog_to_klog(byte *b, int size, int card_num)
29
30 {
31         typedef struct
32         {
33                 word    code;
34                 word    time_hi;
35                 word    time_lo;
36                 word    xcode;
37                 byte    data[2];
38         } card_xlog_t;
39
40         card_xlog_t     *x;
41
42         klog_t          klog;
43
44         x = (card_xlog_t *) b;
45
46         memset(&klog, 0, sizeof(klog));
47
48         klog.time_stamp = (dword) x->time_hi;
49         klog.time_stamp = (klog.time_stamp << 16) | (dword) x->time_lo;
50
51         klog.length = size > sizeof(klog.buffer) ? sizeof(klog.buffer) : size;
52
53         klog.card = card_num;
54         if (x->code == 1)
55         {
56                 klog.type = KLOG_XTXT_MSG;
57                 klog.code = 0;
58                 memcpy(klog.buffer, &x->xcode, klog.length);
59         }
60         else if (x->code == 2)
61         {
62                 klog.type = KLOG_XLOG_MSG;
63                 klog.code = x->xcode;
64                 memcpy(klog.buffer, &x->data, klog.length);
65         }
66         else
67         {
68                 char    *c; int i;
69                 klog.type = KLOG_TEXT_MSG;
70                 klog.code = 0;
71                 c = "divas: invalid xlog message code from card";
72                 i = 0;
73                 while (*c)
74                 {
75                         klog.buffer[i] = *c;
76                         c++;
77                         i++;
78                 }
79                 klog.buffer[i] = *c;
80         }
81
82     /* send to the log driver and return */
83
84     DivasLogAdd(&klog, sizeof(klog));
85
86         return;
87 }
88
89 /*
90  * send an XLOG request down to specified card
91  * if response available from previous request then read it
92  * if not then just send down new request, ready for next time
93  */
94
95 void    DivasXlogReq(int card_num)
96
97 {
98         card_t                          *card;
99         ADAPTER                         *a;
100
101         if ((card_num < 0) || (card_num > DivasCardNext))
102         {
103                 DPRINTF(("xlog: invalid card number"));
104                 return;
105         }
106
107         card = &DivasCards[card_num];
108
109         if (DivasXlogRetrieve(card))
110         {
111                 return;
112         }
113
114         /* send down request for next time */
115
116         a = &card->a;
117
118         a->ram_out(a, (word *) (card->xlog_offset + 1), 0);
119         a->ram_out(a, (word *) (dword) (card->xlog_offset), DO_LOG);
120
121         return;
122 }
123
124 /*
125  * retrieve XLOG request from specified card
126  * returns non-zero if new request sent to card
127  */
128
129 int             DivasXlogRetrieve(card_t *card)
130
131 {
132         ADAPTER                         *a;
133         struct mi_pc_maint      pcm;
134
135         a = &card->a;
136
137         /* get status of last request */
138
139         pcm.rc = a->ram_in(a, (word *)(card->xlog_offset + 1));
140
141         /* if nothing there from previous request, send down a new one */
142
143         if (pcm.rc == OK)
144         {
145                 /* read in response */
146
147                 a->ram_in_buffer(a, (word *) (dword) card->xlog_offset, &pcm, sizeof(pcm)); 
148
149                 xlog_to_klog((byte *) &pcm.data, sizeof(pcm.data), 
150                                                 (int) (card - DivasCards));
151         }
152
153         /* if any response received from card, re-send request */
154
155         if (pcm.rc)
156         {
157                 a->ram_out(a, (word *) (card->xlog_offset + 1), 0);
158                 a->ram_out(a, (word *) (dword) (card->xlog_offset), DO_LOG);
159
160                 return 1;
161         } 
162
163         return 0;
164 }