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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _SYS_ZSDEV_H 28 #define _SYS_ZSDEV_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 /* 33 * Onboard serial ports. 34 * Device dependent software definitions. 35 * All interfaces described in this file are private to the Sun 'zs' driver 36 * implementation and may change at any time without notice. 37 */ 38 39 40 /* 41 * Chip, buffer, and register definitions for Z8530 SCC 42 */ 43 44 #include <sys/spl.h> 45 #include <sys/ksynch.h> 46 #include <sys/dditypes.h> 47 #include <sys/ser_zscc.h> 48 49 #ifdef _MACHDEP 50 #include <sys/zsmach.h> 51 #endif 52 53 #ifdef __cplusplus 54 extern "C" { 55 #endif 56 57 #ifndef _MACHDEP 58 #define ZSDELAY() 59 #define ZSFLUSH() 60 #define ZSNEXTPOLL(zscurr) 61 #endif 62 63 /* 64 * OUTLINE defines the high-order flag bit in the minor device number that 65 * controls use of a tty line for dialin and dialout simultaneously. 66 */ 67 #define OUTLINE ((minor_t)1 << (NBITSMINOR32 - 1)) 68 #define UNIT(x) (getminor(x) & ~OUTLINE) 69 70 #define ZSWR1_INIT (ZSWR1_SIE|ZSWR1_TIE|ZSWR1_RIE) 71 72 extern int zs_usec_delay; 73 74 75 #define ZS_REG_SIZE (2 * sizeof (struct zscc_device)) 76 77 #define PCLK (19660800/4) /* basic clock rate for UARTs */ 78 79 #define SDLCFLAG 0x7E 80 81 #define ZS_ON (ZSWR5_DTR|ZSWR5_RTS) 82 #define ZS_OFF 0 83 84 /* 85 * Modem control commands. 86 */ 87 #define DMSET 0 88 #define DMBIS 1 89 #define DMBIC 2 90 #define DMGET 3 91 92 /* 93 * Macros to access a port 94 */ 95 #define SCC_WRITEA(reg, val) { \ 96 ((struct zscc_device *) \ 97 ((uintptr_t)zs->zs_addr | ZSOFF))->zscc_control = reg; \ 98 ZSDELAY(); \ 99 ((struct zscc_device *) \ 100 ((uintptr_t)zs->zs_addr | ZSOFF))->zscc_control = val; \ 101 ZSDELAY(); \ 102 zs->zs_wreg[reg] = val; \ 103 } 104 #define SCC_WRITEB(reg, val) { \ 105 ((struct zscc_device *) \ 106 ((uintptr_t)zs->zs_addr & ~ZSOFF))->zscc_control = reg; \ 107 ZSDELAY(); \ 108 ((struct zscc_device *) \ 109 ((uintptr_t)zs->zs_addr & ~ZSOFF))->zscc_control = val; \ 110 ZSDELAY(); \ 111 zs->zs_wreg[reg] = val; \ 112 } 113 #define SCC_WRITE(reg, val) { \ 114 zs->zs_addr->zscc_control = reg; \ 115 ZSDELAY(); \ 116 zs->zs_addr->zscc_control = val; \ 117 ZSDELAY(); \ 118 zs->zs_wreg[reg] = val; \ 119 } 120 121 #define SCC_READA(reg, var) { \ 122 ((struct zscc_device *) \ 123 ((uintptr_t)zs->zs_addr | ZSOFF))->zscc_control = reg; \ 124 ZSDELAY(); \ 125 var = ((struct zscc_device *) \ 126 ((uintptr_t)zs->zs_addr | ZSOFF))->zscc_control; \ 127 ZSDELAY(); \ 128 } 129 #define SCC_READB(reg, var) { \ 130 ((struct zscc_device *) \ 131 ((uintptr_t)zs->zs_addr & ~ZSOFF))->zscc_control = reg; \ 132 ZSDELAY(); \ 133 var = ((struct zscc_device *) \ 134 ((uintptr_t)zs->zs_addr & ~ZSOFF))->zscc_control; \ 135 ZSDELAY(); \ 136 } 137 #define SCC_READ(reg, var) { \ 138 register struct zscc_device *tmp; \ 139 tmp = zs->zs_addr; \ 140 tmp->zscc_control = reg; \ 141 ZSDELAY(); \ 142 var = tmp->zscc_control; \ 143 ZSDELAY(); \ 144 } 145 146 #define SCC_BIS(reg, val) { \ 147 zs->zs_addr->zscc_control = reg; \ 148 ZSDELAY(); \ 149 zs->zs_addr->zscc_control = zs->zs_wreg[reg] |= val; \ 150 ZSDELAY(); \ 151 } 152 153 #define SCC_BIC(reg, val) { \ 154 zs->zs_addr->zscc_control = reg; \ 155 ZSDELAY(); \ 156 zs->zs_addr->zscc_control = zs->zs_wreg[reg] &= ~val; \ 157 ZSDELAY(); \ 158 } 159 160 161 #define SCC_WRITE0(val) { \ 162 zs->zs_addr->zscc_control = val; \ 163 ZSDELAY(); \ 164 ZSFLUSH(); \ 165 } 166 167 #define SCC_WRITEDATA(val) { \ 168 zs->zs_addr->zscc_data = val; \ 169 ZSDELAY(); \ 170 ZSFLUSH(); \ 171 } 172 #define SCC_READ0() zs->zs_addr->zscc_control 173 #define SCC_READDATA() zs->zs_addr->zscc_data 174 175 176 /* 177 * Protocol specific entry points for driver routines. 178 */ 179 struct zsops { 180 void (*zsop_txint)(); /* xmit buffer empty */ 181 void (*zsop_xsint)(); /* external/status */ 182 void (*zsop_rxint)(); /* receive char available */ 183 void (*zsop_srint)(); /* special receive condition */ 184 int (*zsop_softint)(); /* second stage interrupt handler */ 185 int (*zsop_suspend)(); /* suspend driver */ 186 int (*zsop_resume)(); /* resume driver */ 187 }; 188 189 /* 190 * Hardware channel common data. One structure per port. 191 * Each of the fields in this structure is required to be protected by a 192 * mutex lock at the highest priority at which it can be altered. 193 * The zs_flags, zs_wreg and zs_next fields can be altered by interrupt 194 * handling code that runs at ZS_PL_HI (IPL 12), so they must be protected 195 * by the mutex whose handle is stored in zs_excl_hi. All others can be 196 * protected by the zs_excl mutex, which is lower priority and adaptive. 197 */ 198 #define ZS_MAX_PRIV_STR 800 /* int */ 199 struct zscom { 200 void (*zs_txint)(); /* SCC interrupt vector routines */ 201 unsigned char *zs_wr_cur; 202 unsigned char *zs_wr_lim; 203 void (*zs_rxint)(); /* SCC interrupt vector routines */ 204 unsigned char *zs_rd_cur; 205 unsigned char *zs_rd_lim; 206 struct zscc_device *zs_addr; /* address of second half of chip */ 207 void (*zs_xsint)(); /* SCC interrupt vector routines */ 208 void (*zs_srint)(); /* SCC interrupt vector routines */ 209 int (*zs_suspend)(); /* routine to suspend driver */ 210 int (*zs_resume)(); /* routine to resume driver */ 211 uchar_t zs_wreg[16]; /* shadow of write registers */ 212 caddr_t zs_priv; /* protocol private data */ 213 struct zsops *zs_ops; /* basic operations vectors */ 214 dev_info_t *zs_dip; /* dev_info */ 215 dev_info_t *zs_hdlc_dip; /* zsh dev_info */ 216 time_t zs_dtrlow; /* time dtr went low */ 217 short zs_unit; /* which channel (0:NZSLINE) */ 218 /* 219 * The zs_wreg, zs_next and zs_flags fields 220 * are protected by zs_excl_hi. 221 */ 222 uchar_t zs_suspended; /* True, if suspended */ 223 struct zs_prog *zs_prog_save; /* H/W state, saved for CPR */ 224 struct zscom *zs_next; /* next in the circularly linked list */ 225 struct zscom *zs_back; /* back in the circularly linked list */ 226 227 kmutex_t *zs_excl_hi; /* zs spinlock mutex */ 228 kmutex_t *zs_excl; /* zs adaptive mutex */ 229 kmutex_t *zs_ocexcl; /* zs adaptive mutex for open/close */ 230 kcondvar_t zs_flags_cv; /* condition variable for flags */ 231 ulong_t zs_priv_str[ZS_MAX_PRIV_STR]; 232 uint_t zs_flags; /* ZS_* flags below */ 233 kstat_t *intrstats; /* interrupt statistics */ 234 timeout_id_t zs_timer; /* close timer */ 235 }; 236 237 /* 238 * Definition for zs_flags field 239 * 240 * ZS_CLOSED is for synchronizing with za_soft_active an za_kick_active. 241 */ 242 #define ZS_NEEDSOFT 0x00000001 243 #define ZS_PROGRESS 0x00000002 244 #define ZS_CLOSING 0x00000004 /* close has started */ 245 #define ZS_CLOSED 0x00000008 /* close is done; stop other activity */ 246 247 #ifdef _KERNEL 248 #define ZS_H_LOG_MAX 0x8000 249 /* 250 * ZSSETSOFT macro to pend a level 3 interrupt if one isn't already pending. 251 */ 252 253 extern kmutex_t zs_soft_lock; /* ptr to lock for zssoftpend */ 254 extern int zssoftpend; /* secondary interrupt pending */ 255 256 extern ddi_softintr_t zs_softintr_id; 257 #define ZSSETSOFT(zs) { \ 258 zs->zs_flags |= ZS_NEEDSOFT; \ 259 if (!zssoftpend) { \ 260 zssoftpend = 1; \ 261 ddi_trigger_softintr(zs_softintr_id); \ 262 } \ 263 } 264 265 #endif /* _KERNEL */ 266 267 /* 268 * Lock priority definitions. 269 * XXX: These should be obtained from configuration data, eventually. 270 */ 271 #define ZS_PL ipltospl(SPL3) /* translates to SPARC IPL 6 */ 272 #define ZS_PL_HI ipltospl(SPLTTY) /* translates to SPARC IPL 12 */ 273 274 /* 275 * Definitions for generic SCC programming routine 276 */ 277 struct zs_prog { 278 struct zscom *zs; /* common data for this channel */ 279 uchar_t flags; /* see definitions below */ 280 uchar_t wr4; /* misc parameters and modes */ 281 uchar_t wr11; /* clock mode control */ 282 uchar_t wr12; /* BRG time constant Lo byte */ 283 uchar_t wr13; /* BRG time constant Hi byte */ 284 uchar_t wr3; /* receiver parameters and control */ 285 uchar_t wr5; /* transmitter parameters and control */ 286 uchar_t wr15; /* external status interrupt control */ 287 }; 288 289 /* 290 * Definitions for zs_prog flags field 291 */ 292 #define ZSP_SYNC 01 /* 0 = async line; 1 = synchronous */ 293 #define ZSP_NRZI 02 /* 0 = NRZ encoding; 1 = NRZI */ 294 #define ZSP_PLL 04 /* request use of PLL clock source */ 295 #define ZSP_LOOP 010 /* request interal loopback mode */ 296 #define ZSP_PARITY_SPECIAL 020 /* parity error causes ext status int */ 297 #define ZSP_ECHO 040 /* request auto echo mode */ 298 299 extern void zsa_init(struct zscom *zs); 300 extern int zsmctl(struct zscom *zs, int bits, int how); 301 extern void zs_program(struct zs_prog *zspp); 302 extern void zsopinit(struct zscom *zs, struct zsops *zso); 303 extern void setzssoft(void); 304 extern dev_info_t *zs_get_dev_info(dev_t dev, int otyp); 305 306 extern char *zssoftCAR; 307 extern int nzs; 308 extern struct zscom *zscom; 309 extern struct zs_prog *zs_prog; 310 extern kmutex_t zs_curr_lock; /* lock protecting zscurr use for clone */ 311 extern struct zsops zsops_null; 312 extern int zs_drain_check; 313 314 #ifdef __cplusplus 315 } 316 #endif 317 318 #endif /* !_SYS_ZSDEV_H */ 319