Home | History | Annotate | Download | only in sys
      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