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
xlog_to_klog(byte * b,int size,int card_num)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 
DivasXlogReq(int card_num)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 
DivasXlogRetrieve(card_t * card)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 }
165