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