xref: /illumos-gate/usr/src/uts/sun/sys/zsdev.h (revision 7c478bd9)
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