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
27static
28void	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
95void	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
129int		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