xref: /illumos-gate/usr/src/uts/sun4u/sys/rmc_comm_dp.h (revision 270993a9)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_SYS_RMC_COMM_DP_H
28 #define	_SYS_RMC_COMM_DP_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 
33 #include <sys/rmc_comm_lproto.h>
34 
35 #ifdef	__cplusplus
36 extern "C" {
37 #endif
38 
39 /*
40  * buffer size (used for tx/rx operations)
41  */
42 #define	DP_BUFFER_SIZE	2048
43 
44 /*
45  * Number of tx/rx buffers. there are 2 (static) buffers: receive buffer and
46  * send buffer. These buffers are basically used by the protocol to packetize
47  * a message to be sent OR to collect data received from the serial device.
48  * Currently, we just need two for send and receive operations respectively
49  * since there is only one request/response session per time (i.e. a new
50  * session is not started until the previous one has not finished)
51  */
52 #define	DP_BUFFER_COUNT		2
53 
54 #define	DP_TX_BUFFER		0
55 #define	DP_RX_BUFFER		1
56 
57 /*
58  * Tx/Rx buffers.
59  */
60 typedef struct dp_buffer {
61 	boolean_t in_use;
62 	uint8_t buf[DP_BUFFER_SIZE];
63 } dp_buffer_t;
64 
65 /*
66  * Data structure used to collect data from the serial device and to
67  * assemble protocol packets
68  */
69 
70 /*
71  * The possible states the message receiver can be in:
72  */
73 #define	WAITING_FOR_SYNC	0
74 #define	WAITING_FOR_SYNC_ESC	1
75 #define	WAITING_FOR_HDR		2
76 #define	RECEIVING_HDR		3
77 #define	RECEIVING_HDR_ESC	4
78 #define	RECEIVING_BODY		5
79 #define	RECEIVING_BODY_ESC	6
80 #define	N_RX_STATES		7
81 
82 /*
83  * This is the structure passed between the message receiver state routines.
84  * It keeps track of all the state of a message that is in the process of
85  * being received.
86  */
87 typedef struct dp_packet {
88 	uint8_t rx_state;	/* Current state of receive engine. */
89 	uint8_t *inbuf;		/* Input characters to be processed. */
90 	int16_t inbuflen;	/* Number of input characters. */
91 	uint8_t *buf;		/* Buffer used to receive current message. */
92 	int16_t bufpos;		/* Position in buffer. */
93 	int16_t full_length;	/* Full length of this message. */
94 } dp_packet_t;
95 
96 
97 /*
98  * message data structure used to send/receive data
99  */
100 typedef struct dp_message {
101 
102 	uint8_t   msg_type;	/* message type */
103 	uint8_t  *msg_buf;	/* message buffer */
104 	uint16_t  msg_bufsiz;	/* size of the buffer */
105 	int16_t   msg_msglen;	/* message length */
106 
107 } dp_message_t;
108 
109 /*
110  * structure used by the protocol to send (and, eventually re-send...)
111  * messages to the remote side. It keeps the status of the data transfer
112  * (message sent, reply received, etc.). It is also used to match
113  * request/response
114  */
115 
116 typedef struct dp_req_resp {
117 
118 	uint8_t		flags;		/* status of the data transfer */
119 
120 #define	MSG_ERROR 	0x01
121 #define	MSG_SENT 	0x02
122 #define	MSG_ACKED 	0x04
123 #define	MSG_REPLY_RXED	0x08
124 #define	MSG_NAKED	0x10
125 #define	MSG_RESET	0x20
126 #define	MSG_SENT_BP	0x40
127 #define	MSG_RXED_BP	0x80
128 
129 	int		error_status;   /* error code */
130 
131 	uint8_t		retries_left;   /* number of retries left */
132 
133 	kcondvar_t  	cv_wait_reply[1];	/* cv variable used to signal */
134 						/* threads waiting for a */
135 						/* reply */
136 
137 	dp_message_t	request;	/* request buffer */
138 
139 	dp_message_t	response;	/* response buffer */
140 
141 } dp_req_resp_t;
142 
143 
144 /*
145  * interrupt handler prototype (asynchronous messages notification)
146  */
147 typedef uint_t (*rmc_comm_intrfunc_t)(caddr_t);
148 
149 /*
150  * data structure used to deal with asynchronous notification (requests)
151  * from the remote side
152  */
153 typedef struct dp_msg_intr {
154 
155 	rmc_comm_intrfunc_t	intr_handler;	/* interrupt handler */
156 
157 	ddi_softintr_t		intr_id;	/* soft intr. id */
158 
159 	uint8_t			intr_msg_type;	/* message type */
160 
161 	caddr_t			intr_arg;	/* message buffer containing */
162 						/* the expected message type */
163 
164 	kmutex_t		*intr_lock;	/* for state flag below */
165 	uint_t			*intr_state;	/* interrupt handler state */
166 
167 } dp_msg_intr_t;
168 
169 /*
170  * data protocol structure
171  */
172 
173 typedef struct rmc_comm_dp_state {
174 
175 	/*
176 	 * data protcol mutex (initialized using <dp_iblk>)
177 	 */
178 	kmutex_t		dp_mutex[1];
179 	ddi_iblock_cookie_t	dp_iblk;
180 
181 	boolean_t	data_link_ok;	/* tells whether the data link has */
182 					/* has been established */
183 
184 	boolean_t	pending_request;	/* tells if a request is */
185 						/* already being processed */
186 
187 	uint8_t		last_tx_seqid;	/* sequence ID of last message */
188 					/* transmitted */
189 	uint8_t		last_rx_seqid;  /* sequence ID of last message */
190 					/* received */
191 	uint8_t		last_rx_ack;    /* last message acknowledged by */
192 					/* remote side */
193 
194 	timeout_id_t	timer_link_setup;	/* timer used to set up the */
195 						/* data link at regular */
196 						/* intervals when the link is */
197 						/* down */
198 	timeout_id_t	timer_delay_ack;	/* timer used to wait a 'bit' */
199 						/* before acknowledging a */
200 						/* received message. In the */
201 						/* meantime a request can be */
202 						/* sent from this side and, */
203 						/* hence, acnowledge that */
204 						/* message */
205 
206 	kcondvar_t	cv_ok_to_send[1];	/* cv variable used to wait */
207 						/* until it is possible to */
208 						/* send the request (no */
209 						/* pending request */
210 
211 	dp_packet_t	dp_packet;		/* used to assemble protocol */
212 						/* packet from data received */
213 						/* from the serial device */
214 
215 	dp_req_resp_t	req_resp;		/* request/response data */
216 						/* structure */
217 
218 	dp_msg_intr_t	msg_intr;		/* messages for which layered */
219 						/* drivers have registered */
220 						/* for an async notification */
221 						/* (soft.intr.) */
222 
223 	dp_buffer_t	dp_buffers[DP_BUFFER_COUNT]; /* protocol buffer  */
224 						/* pool used for    */
225 						/* tx/rx operations */
226 
227 	/* statistical information */
228 
229 	uint16_t	reset_cnt;
230 	uint16_t	nak_cnt;
231 	uint16_t	start_cnt;
232 	uint16_t	stack_cnt;
233 	uint16_t	retries_cnt;
234 	uint16_t	crcerr_cnt;
235 
236 } rmc_comm_dp_state_t;
237 
238 #ifdef	__cplusplus
239 }
240 #endif
241 
242 #endif	/* _SYS_RMC_COMM_DP_H */
243