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 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _SYS_RMC_COMM_H 28 #define _SYS_RMC_COMM_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 /* 37 * Hardware: serial chip register numbers 38 */ 39 #define SIO_RXD 0 /* read */ 40 #define SIO_TXD 0 /* write */ 41 #define SIO_IER 1 42 #define SIO_EIR 2 /* read */ 43 #define SIO_FCR 2 /* write */ 44 #define SIO_LCR 3 45 #define SIO_BSR 3 /* wierd */ 46 #define SIO_MCR 4 47 #define SIO_LSR 5 48 #define SIO_MSR 6 49 #define SIO_SCR 7 50 51 #define SIO_LBGDL 0 /* bank 1 */ 52 #define SIO_LBGDH 1 /* bank 1 */ 53 54 /* 55 * Hardware: serial chip register bits 56 */ 57 #define SIO_IER_RXHDL_IE 0x01 58 #define SIO_IER_STD 0x00 59 60 #define SIO_FCR_FIFO_EN 0x01 61 #define SIO_FCR_RXSR 0x02 62 #define SIO_FCR_TXSR 0x04 63 #define SIO_FCR_RXFTH0 0x40 64 #define SIO_FCR_STD (SIO_FCR_RXFTH0|SIO_FCR_FIFO_EN) 65 66 #define SIO_LCR_WLS0 0x01 67 #define SIO_LCR_WLS1 0x02 68 #define SIO_LCR_PEN 0x08 69 #define SIO_LCR_EPS 0x10 70 #define SIO_LCR_BKSE 0x80 71 #define SIO_LCR_8BIT (SIO_LCR_WLS0|SIO_LCR_WLS1) 72 #define SIO_LCR_STD (SIO_LCR_8BIT) 73 #define SIO_BSR_BANK0 (SIO_LCR_STD) 74 #define SIO_BSR_BANK1 (SIO_LCR_BKSE|SIO_LCR_STD) 75 76 #define SIO_MCR_ISEN 0x08 77 #define SIO_MCR_STD (SIO_MCR_ISEN) 78 79 /* Line Status Register */ 80 #define SIO_LSR_RXDA 0x01 /* data ready */ 81 #define SIO_LSR_OVRRUN 0x02 /* overrun error */ 82 #define SIO_LSR_PARERR 0x04 /* parity error */ 83 #define SIO_LSR_FRMERR 0x08 /* framing error */ 84 #define SIO_LSR_BRKDET 0x10 /* a break has arrived */ 85 #define SIO_LSR_XHRE 0x20 /* tx hold reg is now empty */ 86 #define SIO_LSR_XSRE 0x40 /* tx shift reg is now empty */ 87 #define SIO_LSR_RFBE 0x80 /* rx FIFO Buffer error */ 88 89 /* 90 * Min/max/default baud rates, and a macro to convert from a baud 91 * rate to the number (divisor) to put in the baud rate registers 92 */ 93 #define SIO_BAUD_MIN 50 94 #define SIO_BAUD_MAX 115200 95 #define SIO_BAUD_DEFAULT 115200 96 #define SIO_BAUD_TO_DIVISOR(b) (115200 / (b)) 97 #define SIO_BAUD_DIVISOR_MIN 1 98 #define SIO_BAUD_DIVISOR_MAX 64 99 100 /* 101 * serial rx buffer size: set to maximum message size + 'bits' 102 * (protocol overhead) 103 */ 104 105 #define SIO_MAX_RXBUF_SIZE (DP_MAX_MSGLEN + 128) 106 107 /* 108 * protocol status struct 109 */ 110 111 typedef struct rmc_comm_serdev_state { 112 113 ddi_acc_handle_t sio_handle; 114 uint8_t *sio_regs; 115 ddi_softintr_t softid; 116 ddi_periodic_t cycid; /* periodical callback */ 117 118 /* 119 * Hardware mutex (initialised using <hw_iblk>), 120 * used to prevent retriggering the softint while 121 * it's still fetching data out of the chip FIFO. 122 */ 123 kmutex_t hw_mutex[1]; 124 ddi_iblock_cookie_t hw_iblk; 125 boolean_t hw_int_enabled; 126 127 /* 128 * Flag to indicate that we've incurred a hardware fault on 129 * accesses to the SIO; once this is set, we fake all further 130 * accesses in order not to provoke additional bus errors. 131 */ 132 boolean_t sio_fault; 133 134 /* 135 * serial device receive buffer 136 */ 137 char serdev_rx_buf[SIO_MAX_RXBUF_SIZE]; 138 uint16_t serdev_rx_count; 139 140 } rmc_comm_serdev_state_t; 141 142 /* 143 * This driver's soft-state structure 144 */ 145 struct rmc_comm_state { 146 /* 147 * Configuration data, set during attach 148 */ 149 dev_info_t *dip; 150 major_t majornum; 151 int instance; 152 int n_registrations; 153 boolean_t is_attached; 154 155 /* 156 * Parameters derived from .conf properties 157 */ 158 int baud; 159 uint32_t debug; 160 int baud_divisor_factor; 161 162 /* 163 * serial device status... 164 */ 165 rmc_comm_serdev_state_t sd_state; 166 167 /* 168 * protocol status struct 169 */ 170 rmc_comm_dp_state_t dp_state; 171 172 /* 173 * driver interface status struct 174 */ 175 rmc_comm_drvintf_state_t drvi_state; 176 }; 177 178 179 /* 180 * Time periods, in nanoseconds 181 */ 182 #define RMC_COMM_ONE_SEC 1000000000LL 183 184 /* 185 * debugging 186 */ 187 188 #define DSER 0x01 /* serial device */ 189 #define DPRO 0x02 /* protocol */ 190 #define DAPI 0x04 /* API */ 191 #define DPKT 0x08 /* packet handling routine */ 192 #define DGEN 0x10 /* generic */ 193 #define DDSC 0x20 /* datascope */ 194 #define DMEM 0x40 /* memory alloc/release */ 195 196 #ifdef DEBUG 197 #define DPRINTF(rcs, d, ARGLIST) { if (rcs->debug & d) cmn_err ARGLIST; } 198 #define DATASCOPE(rcs, c, b, l) { int i, j; char s[80]; \ 199 s[0] = (c); \ 200 s[1] = '\0'; \ 201 for (i = 1; i < (l)+1; i++) { \ 202 j = strlen(s); \ 203 (void) sprintf(s+j, "%02x ", \ 204 (uchar_t)b[i-1]); \ 205 if (i%24 == 0) { \ 206 DPRINTF(rcs, DDSC, \ 207 (CE_CONT, "%s\n", s)); \ 208 s[0] = (c); \ 209 s[1] = '\0'; \ 210 } \ 211 } \ 212 if (i%24 != 0) \ 213 DPRINTF(rcs, DDSC, \ 214 (CE_CONT, "%s\n", s)); \ 215 } 216 #else 217 #define DPRINTF(rcs, d, ARGLIST) 218 #define DATASCOPE(rcs, c, b, l) 219 #endif /* DEBUG */ 220 221 222 /* 223 * function prototypes 224 */ 225 226 int rmc_comm_serdev_init(struct rmc_comm_state *, dev_info_t *); 227 void rmc_comm_serdev_fini(struct rmc_comm_state *, dev_info_t *); 228 void rmc_comm_serdev_receive(struct rmc_comm_state *); 229 void rmc_comm_serdev_send(struct rmc_comm_state *, char *, int); 230 void rmc_comm_serdev_drain(struct rmc_comm_state *); 231 struct rmc_comm_state *rmc_comm_getstate(dev_info_t *, int, const char *); 232 int rmc_comm_register(void); 233 void rmc_comm_unregister(void); 234 235 void rmc_comm_dp_init(struct rmc_comm_state *); 236 void rmc_comm_dp_fini(struct rmc_comm_state *); 237 void rmc_comm_dp_drecv(struct rmc_comm_state *, uint8_t *, int); 238 void rmc_comm_dp_mrecv(struct rmc_comm_state *, uint8_t *); 239 int rmc_comm_dp_msend(struct rmc_comm_state *, dp_message_t *); 240 void rmc_comm_bp_msend(struct rmc_comm_state *, bp_msg_t *); 241 void rmc_comm_bp_srecsend(struct rmc_comm_state *, char *, int); 242 int rmc_comm_dp_ctlsend(struct rmc_comm_state *, uint8_t); 243 void rmc_comm_dp_mcleanup(struct rmc_comm_state *); 244 245 int rmc_comm_drvintf_init(struct rmc_comm_state *); 246 void rmc_comm_drvintf_fini(struct rmc_comm_state *); 247 248 #ifdef __cplusplus 249 } 250 #endif 251 252 #endif /* _SYS_RMC_COMM_H */ 253