v2.4.8 -> v2.4.8.1
[opensuse:kernel.git] / drivers / isdn / eicon / xlog.c
1
2 /*
3  *
4  * Copyright (C) Eicon Technology Corporation, 2000.
5  *
6  * Eicon File Revision :    1.2  
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY 
15  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
16  * See the GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  */
23
24
25 /*
26  * Unix Eicon active card driver
27  * XLOG related functions
28  */
29
30 #include "sys.h"
31 #include "idi.h"
32 #include "pc.h"
33 #include "pc_maint.h"
34 #include "divalog.h"
35
36 #include "adapter.h"
37 #include "uxio.h"
38
39 /*
40  * convert/copy XLOG info into a KLOG entry
41  */
42
43 static
44 void    xlog_to_klog(byte *b, int size, int card_num)
45
46 {
47         typedef struct
48         {
49                 word    code;
50                 word    time_hi;
51                 word    time_lo;
52                 word    xcode;
53                 byte    data[2];
54         } card_xlog_t;
55
56         card_xlog_t     *x;
57
58         klog_t          klog;
59
60         x = (card_xlog_t *) b;
61
62         memset(&klog, 0, sizeof(klog));
63
64         klog.time_stamp = (dword) x->time_hi;
65         klog.time_stamp = (klog.time_stamp << 16) | (dword) x->time_lo;
66
67         klog.length = size > sizeof(klog.buffer) ? sizeof(klog.buffer) : size;
68
69         klog.card = card_num;
70         if (x->code == 1)
71         {
72                 klog.type = KLOG_XTXT_MSG;
73                 klog.code = 0;
74                 memcpy(klog.buffer, &x->xcode, klog.length);
75         }
76         else if (x->code == 2)
77         {
78                 klog.type = KLOG_XLOG_MSG;
79                 klog.code = x->xcode;
80                 memcpy(klog.buffer, &x->data, klog.length);
81         }
82         else
83         {
84                 char    *c; int i;
85                 klog.type = KLOG_TEXT_MSG;
86                 klog.code = 0;
87                 c = "divas: invalid xlog message code from card";
88                 i = 0;
89                 while (*c)
90                 {
91                         klog.buffer[i] = *c;
92                         c++;
93                         i++;
94                 }
95                 klog.buffer[i] = *c;
96         }
97
98     /* send to the log driver and return */
99
100     DivasLogAdd(&klog, sizeof(klog));
101
102         return;
103 }
104
105 /*
106  * send an XLOG request down to specified card
107  * if response available from previous request then read it
108  * if not then just send down new request, ready for next time
109  */
110
111 void    DivasXlogReq(int card_num)
112
113 {
114         card_t                          *card;
115         ADAPTER                         *a;
116
117         if ((card_num < 0) || (card_num > DivasCardNext))
118         {
119                 DPRINTF(("xlog: invalid card number"));
120                 return;
121         }
122
123         card = &DivasCards[card_num];
124
125         if (DivasXlogRetrieve(card))
126         {
127                 return;
128         }
129
130         /* send down request for next time */
131
132         a = &card->a;
133
134         a->ram_out(a, (word *) (card->xlog_offset + 1), 0);
135         a->ram_out(a, (word *) (dword) (card->xlog_offset), DO_LOG);
136
137         return;
138 }
139
140 /*
141  * retrieve XLOG request from specified card
142  * returns non-zero if new request sent to card
143  */
144
145 int             DivasXlogRetrieve(card_t *card)
146
147 {
148         ADAPTER                         *a;
149         struct mi_pc_maint      pcm;
150
151         a = &card->a;
152
153         /* get status of last request */
154
155         pcm.rc = a->ram_in(a, (word *)(card->xlog_offset + 1));
156
157         /* if nothing there from previous request, send down a new one */
158
159         if (pcm.rc == OK)
160         {
161                 /* read in response */
162
163                 a->ram_in_buffer(a, (word *) (dword) card->xlog_offset, &pcm, sizeof(pcm)); 
164
165                 xlog_to_klog((byte *) &pcm.data, sizeof(pcm.data), 
166                                                 (int) (card - DivasCards));
167         }
168
169         /* if any response received from card, re-send request */
170
171         if (pcm.rc)
172         {
173                 a->ram_out(a, (word *) (card->xlog_offset + 1), 0);
174                 a->ram_out(a, (word *) (dword) (card->xlog_offset), DO_LOG);
175
176                 return 1;
177         } 
178
179         return 0;
180 }