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