xref: /titanic_51/usr/src/uts/common/sys/ecppvar.h (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #ifndef	_SYS_ECPPVAR_H
28*7c478bd9Sstevel@tonic-gate #define	_SYS_ECPPVAR_H
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate #include <sys/note.h>
33*7c478bd9Sstevel@tonic-gate 
34*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
35*7c478bd9Sstevel@tonic-gate extern "C" {
36*7c478bd9Sstevel@tonic-gate #endif
37*7c478bd9Sstevel@tonic-gate 
38*7c478bd9Sstevel@tonic-gate struct ecppunit;
39*7c478bd9Sstevel@tonic-gate 
40*7c478bd9Sstevel@tonic-gate /*
41*7c478bd9Sstevel@tonic-gate  * Hardware-abstraction structure
42*7c478bd9Sstevel@tonic-gate  */
43*7c478bd9Sstevel@tonic-gate struct ecpp_hw {
44*7c478bd9Sstevel@tonic-gate 	int	(*map_regs)(struct ecppunit *);		/* map registers */
45*7c478bd9Sstevel@tonic-gate 	void	(*unmap_regs)(struct ecppunit *);	/* unmap registers */
46*7c478bd9Sstevel@tonic-gate 	int	(*config_chip)(struct ecppunit *);	/* configure SuperIO */
47*7c478bd9Sstevel@tonic-gate 	void	(*config_mode)(struct ecppunit *);	/* config new mode */
48*7c478bd9Sstevel@tonic-gate 	void	(*mask_intr)(struct ecppunit *);	/* mask interrupts */
49*7c478bd9Sstevel@tonic-gate 	void	(*unmask_intr)(struct ecppunit *);	/* unmask interrupts */
50*7c478bd9Sstevel@tonic-gate 	int	(*dma_start)(struct ecppunit *);	/* start DMA transfer */
51*7c478bd9Sstevel@tonic-gate 	int	(*dma_stop)(struct ecppunit *, size_t *); /* stop DMA xfer */
52*7c478bd9Sstevel@tonic-gate 	size_t	(*dma_getcnt)(struct ecppunit *);	/* get DMA counter */
53*7c478bd9Sstevel@tonic-gate 	ddi_dma_attr_t	*attr;				/* DMA attributes */
54*7c478bd9Sstevel@tonic-gate };
55*7c478bd9Sstevel@tonic-gate 
56*7c478bd9Sstevel@tonic-gate #define	ECPP_MAP_REGS(pp)		(pp)->hw->map_regs(pp)
57*7c478bd9Sstevel@tonic-gate #define	ECPP_UNMAP_REGS(pp)		(pp)->hw->unmap_regs(pp)
58*7c478bd9Sstevel@tonic-gate #define	ECPP_CONFIG_CHIP(pp)		(pp)->hw->config_chip(pp)
59*7c478bd9Sstevel@tonic-gate #define	ECPP_CONFIG_MODE(pp)		(pp)->hw->config_mode(pp)
60*7c478bd9Sstevel@tonic-gate #define	ECPP_MASK_INTR(pp)		(pp)->hw->mask_intr(pp)
61*7c478bd9Sstevel@tonic-gate #define	ECPP_UNMASK_INTR(pp)		(pp)->hw->unmask_intr(pp)
62*7c478bd9Sstevel@tonic-gate #define	ECPP_DMA_START(pp)		(pp)->hw->dma_start(pp)
63*7c478bd9Sstevel@tonic-gate #define	ECPP_DMA_STOP(pp, cnt)		(pp)->hw->dma_stop(pp, cnt)
64*7c478bd9Sstevel@tonic-gate #define	ECPP_DMA_GETCNT(pp)		(pp)->hw->dma_getcnt(pp)
65*7c478bd9Sstevel@tonic-gate 
66*7c478bd9Sstevel@tonic-gate /* NSC 87332/97317 and EBus DMAC */
67*7c478bd9Sstevel@tonic-gate struct ecpp_ebus {
68*7c478bd9Sstevel@tonic-gate 	struct config_reg	*c_reg; 	/* configuration registers */
69*7c478bd9Sstevel@tonic-gate 	ddi_acc_handle_t	c_handle;	/* handle for conf regs */
70*7c478bd9Sstevel@tonic-gate 	struct cheerio_dma_reg	*dmac;		/* ebus dmac registers */
71*7c478bd9Sstevel@tonic-gate 	ddi_acc_handle_t	d_handle;	/* handle for dmac registers */
72*7c478bd9Sstevel@tonic-gate 	struct config2_reg	*c2_reg; 	/* 97317 2nd level conf regs */
73*7c478bd9Sstevel@tonic-gate 	ddi_acc_handle_t	c2_handle;	/* handle for c2_reg */
74*7c478bd9Sstevel@tonic-gate };
75*7c478bd9Sstevel@tonic-gate 
76*7c478bd9Sstevel@tonic-gate /* Southbridge SuperIO and 8237 DMAC */
77*7c478bd9Sstevel@tonic-gate struct ecpp_m1553 {
78*7c478bd9Sstevel@tonic-gate 	struct isaspace		*isa_space;	/* all of isa space */
79*7c478bd9Sstevel@tonic-gate 	ddi_acc_handle_t	d_handle;	/* handle for isa space */
80*7c478bd9Sstevel@tonic-gate 	uint8_t			chn;		/* 8237 dma channel */
81*7c478bd9Sstevel@tonic-gate 	int			isadma_entered;	/* Southbridge DMA workaround */
82*7c478bd9Sstevel@tonic-gate };
83*7c478bd9Sstevel@tonic-gate 
84*7c478bd9Sstevel@tonic-gate #if defined(__x86)
85*7c478bd9Sstevel@tonic-gate struct ecpp_x86 {
86*7c478bd9Sstevel@tonic-gate 	uint8_t			chn;
87*7c478bd9Sstevel@tonic-gate };
88*7c478bd9Sstevel@tonic-gate #endif
89*7c478bd9Sstevel@tonic-gate 
90*7c478bd9Sstevel@tonic-gate /*
91*7c478bd9Sstevel@tonic-gate  * Hardware binding structure
92*7c478bd9Sstevel@tonic-gate  */
93*7c478bd9Sstevel@tonic-gate struct ecpp_hw_bind {
94*7c478bd9Sstevel@tonic-gate 	char		*name;		/* binding name */
95*7c478bd9Sstevel@tonic-gate 	struct ecpp_hw	*hw;		/* hw description */
96*7c478bd9Sstevel@tonic-gate 	char		*info;		/* info string */
97*7c478bd9Sstevel@tonic-gate };
98*7c478bd9Sstevel@tonic-gate 
99*7c478bd9Sstevel@tonic-gate /*
100*7c478bd9Sstevel@tonic-gate  * ecpp soft state structure
101*7c478bd9Sstevel@tonic-gate  */
102*7c478bd9Sstevel@tonic-gate struct ecppunit {
103*7c478bd9Sstevel@tonic-gate 	kmutex_t	umutex;		/* lock for this structure */
104*7c478bd9Sstevel@tonic-gate 	int		instance;	/* instance number */
105*7c478bd9Sstevel@tonic-gate 	dev_info_t	*dip;		/* device information */
106*7c478bd9Sstevel@tonic-gate 	ddi_iblock_cookie_t ecpp_trap_cookie;	/* interrupt cookie */
107*7c478bd9Sstevel@tonic-gate 	boolean_t	e_busy;		/* ecpp busy flag */
108*7c478bd9Sstevel@tonic-gate 	kcondvar_t	pport_cv;	/* cv to signal idle state */
109*7c478bd9Sstevel@tonic-gate 	/*
110*7c478bd9Sstevel@tonic-gate 	 * common SuperIO registers
111*7c478bd9Sstevel@tonic-gate 	 */
112*7c478bd9Sstevel@tonic-gate 	struct info_reg		*i_reg; 	/* info registers */
113*7c478bd9Sstevel@tonic-gate 	struct fifo_reg		*f_reg; 	/* fifo register */
114*7c478bd9Sstevel@tonic-gate 	ddi_acc_handle_t	i_handle;
115*7c478bd9Sstevel@tonic-gate 	ddi_acc_handle_t	f_handle;
116*7c478bd9Sstevel@tonic-gate 	/*
117*7c478bd9Sstevel@tonic-gate 	 * DMA support
118*7c478bd9Sstevel@tonic-gate 	 */
119*7c478bd9Sstevel@tonic-gate 	ddi_dma_handle_t	dma_handle;	/* DMA handle */
120*7c478bd9Sstevel@tonic-gate 	ddi_dma_cookie_t	dma_cookie;	/* current cookie */
121*7c478bd9Sstevel@tonic-gate 	uint_t			dma_cookie_count;	/* # of cookies */
122*7c478bd9Sstevel@tonic-gate 	uint_t			dma_nwin;	/* # of DMA windows */
123*7c478bd9Sstevel@tonic-gate 	uint_t			dma_curwin;	/* current window number */
124*7c478bd9Sstevel@tonic-gate 	uint_t			dma_dir;	/* transfer direction */
125*7c478bd9Sstevel@tonic-gate 	/*
126*7c478bd9Sstevel@tonic-gate 	 * hardware-dependent stuff
127*7c478bd9Sstevel@tonic-gate 	 */
128*7c478bd9Sstevel@tonic-gate 	struct ecpp_hw	*hw;		/* operations/attributes */
129*7c478bd9Sstevel@tonic-gate 	union {				/* hw-dependent data */
130*7c478bd9Sstevel@tonic-gate 		struct ecpp_ebus	ebus;
131*7c478bd9Sstevel@tonic-gate 		struct ecpp_m1553	m1553;
132*7c478bd9Sstevel@tonic-gate #if defined(__x86)
133*7c478bd9Sstevel@tonic-gate 		struct ecpp_x86 	x86;
134*7c478bd9Sstevel@tonic-gate #endif
135*7c478bd9Sstevel@tonic-gate 	} uh;
136*7c478bd9Sstevel@tonic-gate 	/*
137*7c478bd9Sstevel@tonic-gate 	 * DDI/STREAMS stuff
138*7c478bd9Sstevel@tonic-gate 	 */
139*7c478bd9Sstevel@tonic-gate 	boolean_t	oflag;		/* instance open flag */
140*7c478bd9Sstevel@tonic-gate 	queue_t		*readq;		/* pointer to readq */
141*7c478bd9Sstevel@tonic-gate 	queue_t		*writeq;	/* pointer to writeq */
142*7c478bd9Sstevel@tonic-gate 	mblk_t		*msg;		/* current message block */
143*7c478bd9Sstevel@tonic-gate 	boolean_t	suspended;	/* driver suspended status */
144*7c478bd9Sstevel@tonic-gate 	/*
145*7c478bd9Sstevel@tonic-gate 	 * Modes of operation
146*7c478bd9Sstevel@tonic-gate 	 */
147*7c478bd9Sstevel@tonic-gate 	int		current_mode;	/* 1284 mode */
148*7c478bd9Sstevel@tonic-gate 	uchar_t		current_phase;	/* 1284 phase */
149*7c478bd9Sstevel@tonic-gate 	uchar_t		backchannel;	/* backchannel mode supported */
150*7c478bd9Sstevel@tonic-gate 	uchar_t		io_mode;	/* transfer mode: PIO/DMA */
151*7c478bd9Sstevel@tonic-gate 	/*
152*7c478bd9Sstevel@tonic-gate 	 * Ioctls support
153*7c478bd9Sstevel@tonic-gate 	 */
154*7c478bd9Sstevel@tonic-gate 	struct ecpp_transfer_parms xfer_parms;	/* transfer parameters */
155*7c478bd9Sstevel@tonic-gate 	struct ecpp_regs regs;		/* control/status registers */
156*7c478bd9Sstevel@tonic-gate 	uint8_t		saved_dsr;	/* store the dsr returned from TESTIO */
157*7c478bd9Sstevel@tonic-gate 	boolean_t	timeout_error;	/* store the timeout for GETERR */
158*7c478bd9Sstevel@tonic-gate 	uchar_t		port;		/* xfer type: dma/pio/tfifo */
159*7c478bd9Sstevel@tonic-gate 	struct prn_timeouts prn_timeouts; /* prnio timeouts */
160*7c478bd9Sstevel@tonic-gate 	/*
161*7c478bd9Sstevel@tonic-gate 	 * ecpp.conf parameters
162*7c478bd9Sstevel@tonic-gate 	 */
163*7c478bd9Sstevel@tonic-gate 	uchar_t		init_seq;	/* centronics init seq */
164*7c478bd9Sstevel@tonic-gate 	uint32_t	wsrv_retry;	/* delay (ms) before next wsrv */
165*7c478bd9Sstevel@tonic-gate 	uint32_t	wait_for_busy;	/* wait for BUSY to deassert */
166*7c478bd9Sstevel@tonic-gate 	uint32_t	data_setup_time; /* pio centronics handshake */
167*7c478bd9Sstevel@tonic-gate 	uint32_t	strobe_pulse_width; /* pio centronics handshake */
168*7c478bd9Sstevel@tonic-gate 	uint8_t		fast_centronics; /* DMA/PIO centronics */
169*7c478bd9Sstevel@tonic-gate 	uint8_t		fast_compat;	/* DMA/PIO 1284 compatible mode */
170*7c478bd9Sstevel@tonic-gate 	uint32_t	ecp_rev_speed;	/* rev xfer speed in ECP, bytes/sec */
171*7c478bd9Sstevel@tonic-gate 	uint32_t	rev_watchdog;	/* rev xfer watchdog period, ms */
172*7c478bd9Sstevel@tonic-gate 	/*
173*7c478bd9Sstevel@tonic-gate 	 * Timeouts
174*7c478bd9Sstevel@tonic-gate 	 */
175*7c478bd9Sstevel@tonic-gate 	timeout_id_t	timeout_id;	/* io transfers timer */
176*7c478bd9Sstevel@tonic-gate 	timeout_id_t	fifo_timer_id;	/* drain SuperIO FIFO */
177*7c478bd9Sstevel@tonic-gate 	timeout_id_t	wsrv_timer_id;	/* wsrv timeout */
178*7c478bd9Sstevel@tonic-gate 	/*
179*7c478bd9Sstevel@tonic-gate 	 * Softintr data
180*7c478bd9Sstevel@tonic-gate 	 */
181*7c478bd9Sstevel@tonic-gate 	ddi_softintr_t	softintr_id;
182*7c478bd9Sstevel@tonic-gate 	int		softintr_flags;	/* flags indicating softintr task */
183*7c478bd9Sstevel@tonic-gate 	uint8_t		softintr_pending;
184*7c478bd9Sstevel@tonic-gate 	/*
185*7c478bd9Sstevel@tonic-gate 	 * Misc stuff
186*7c478bd9Sstevel@tonic-gate 	 */
187*7c478bd9Sstevel@tonic-gate 	caddr_t		ioblock;	/* transfer buffer block */
188*7c478bd9Sstevel@tonic-gate 	size_t		xfercnt;	/* # of bytes to transfer */
189*7c478bd9Sstevel@tonic-gate 	size_t		resid;		/* # of bytes not transferred */
190*7c478bd9Sstevel@tonic-gate 	caddr_t		next_byte;	/* next byte for PIO transfer */
191*7c478bd9Sstevel@tonic-gate 	caddr_t		last_byte;	/* last byte for PIO transfer */
192*7c478bd9Sstevel@tonic-gate 	uint32_t	ecpp_drain_counter;	/* allows fifo to drain */
193*7c478bd9Sstevel@tonic-gate 	uchar_t		dma_cancelled;	/* flushed while dma'ing */
194*7c478bd9Sstevel@tonic-gate 	uint8_t		tfifo_intr;	/* TFIFO switch interrupt workaround */
195*7c478bd9Sstevel@tonic-gate 	size_t		nread;		/* requested read */
196*7c478bd9Sstevel@tonic-gate 	size_t		last_dmacnt;	/* DMA counter value for rev watchdog */
197*7c478bd9Sstevel@tonic-gate 	uint32_t	rev_timeout_cnt; /* number of watchdog invocations */
198*7c478bd9Sstevel@tonic-gate 	/*
199*7c478bd9Sstevel@tonic-gate 	 * Spurious interrupt detection
200*7c478bd9Sstevel@tonic-gate 	 */
201*7c478bd9Sstevel@tonic-gate 	hrtime_t	lastspur;	/* last time spurious intrs started */
202*7c478bd9Sstevel@tonic-gate 	long		nspur;		/* spurious intrs counter */
203*7c478bd9Sstevel@tonic-gate 	/*
204*7c478bd9Sstevel@tonic-gate 	 * Statistics
205*7c478bd9Sstevel@tonic-gate 	 */
206*7c478bd9Sstevel@tonic-gate 	kstat_t		*ksp;		/* kstat pointer */
207*7c478bd9Sstevel@tonic-gate 	kstat_t		*intrstats;	/* kstat interrupt counter */
208*7c478bd9Sstevel@tonic-gate 	/*
209*7c478bd9Sstevel@tonic-gate 	 * number of bytes, transferred in and out in each mode
210*7c478bd9Sstevel@tonic-gate 	 */
211*7c478bd9Sstevel@tonic-gate 	uint32_t	ctxpio_obytes;
212*7c478bd9Sstevel@tonic-gate 	uint32_t	obytes[ECPP_EPP_MODE+1];
213*7c478bd9Sstevel@tonic-gate 	uint32_t	ibytes[ECPP_EPP_MODE+1];
214*7c478bd9Sstevel@tonic-gate 	/*
215*7c478bd9Sstevel@tonic-gate 	 * other stats
216*7c478bd9Sstevel@tonic-gate 	 */
217*7c478bd9Sstevel@tonic-gate 	uint32_t	to_mode[ECPP_EPP_MODE+1]; /* # transitions to mode */
218*7c478bd9Sstevel@tonic-gate 	uint32_t	xfer_tout;	/* # transfer timeouts */
219*7c478bd9Sstevel@tonic-gate 	uint32_t	ctx_cf;		/* # periph check failures */
220*7c478bd9Sstevel@tonic-gate 	uint32_t	joblen;		/* of bytes xfer'd since open */
221*7c478bd9Sstevel@tonic-gate 	uint32_t	isr_reattempt_high;	/* max times isr has looped */
222*7c478bd9Sstevel@tonic-gate 	/*
223*7c478bd9Sstevel@tonic-gate 	 * interrupt stats
224*7c478bd9Sstevel@tonic-gate 	 */
225*7c478bd9Sstevel@tonic-gate 	uint_t		intr_hard;
226*7c478bd9Sstevel@tonic-gate 	uint_t		intr_spurious;
227*7c478bd9Sstevel@tonic-gate 	uint_t		intr_soft;
228*7c478bd9Sstevel@tonic-gate 	/*
229*7c478bd9Sstevel@tonic-gate 	 * identify second register set for ecp mode on Sx86
230*7c478bd9Sstevel@tonic-gate 	 */
231*7c478bd9Sstevel@tonic-gate 	int		noecpregs;
232*7c478bd9Sstevel@tonic-gate };
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(ecppunit::umutex, ecppunit))
235*7c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ecppunit::dip))
236*7c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ecppunit::instance))
237*7c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ecppunit::i_reg))
238*7c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ecppunit::f_reg))
239*7c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ecppunit::i_handle))
240*7c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ecppunit::f_handle))
241*7c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ecppunit::ecpp_trap_cookie))
242*7c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ecppunit::readq))
243*7c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ecppunit::writeq))
244*7c478bd9Sstevel@tonic-gate 
245*7c478bd9Sstevel@tonic-gate /*
246*7c478bd9Sstevel@tonic-gate  * current_phase values
247*7c478bd9Sstevel@tonic-gate  */
248*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_INIT		0x00	/* initialization */
249*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_NEGO		0x01	/* negotiation */
250*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_TERM		0x02	/* termination */
251*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_PO		0x03	/* power-on */
252*7c478bd9Sstevel@tonic-gate 
253*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_C_FWD_DMA	0x10	/* cntrx/compat fwd dma xfer */
254*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_C_FWD_PIO	0x11	/* cntrx/compat fwd PIO xfer */
255*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_C_IDLE	0x12	/* cntrx/compat idle */
256*7c478bd9Sstevel@tonic-gate 
257*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_NIBT_REVDATA	0x20	/* nibble/byte reverse data */
258*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_NIBT_AVAIL	0x21	/* nibble/byte reverse data available */
259*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_NIBT_NAVAIL	0x22	/* nibble/byte reverse data not avail */
260*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_NIBT_REVIDLE	0x22	/* nibble/byte reverse idle */
261*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_NIBT_REVINTR	0x23	/* nibble/byte reverse interrupt */
262*7c478bd9Sstevel@tonic-gate 
263*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_ECP_SETUP	0x30	/* ecp setup */
264*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_ECP_FWD_XFER	0x31	/* ecp forward transfer */
265*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_ECP_FWD_IDLE	0x32	/* ecp forward idle */
266*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_ECP_FWD_REV	0x33	/* ecp forward to reverse */
267*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_ECP_REV_XFER	0x34	/* ecp reverse transfer */
268*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_ECP_REV_IDLE	0x35	/* ecp reverse idle */
269*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_ECP_REV_FWD	0x36	/* ecp reverse to forward */
270*7c478bd9Sstevel@tonic-gate 
271*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_EPP_INIT_IDLE 0x40	/* epp init phase */
272*7c478bd9Sstevel@tonic-gate #define	ECPP_PHASE_EPP_IDLE	0x41	/* epp all-round phase */
273*7c478bd9Sstevel@tonic-gate 
274*7c478bd9Sstevel@tonic-gate #define	FAILURE_PHASE		0x80
275*7c478bd9Sstevel@tonic-gate #define	UNDEFINED_PHASE		0x81
276*7c478bd9Sstevel@tonic-gate 
277*7c478bd9Sstevel@tonic-gate /* ecpp return values */
278*7c478bd9Sstevel@tonic-gate #define	SUCCESS		1
279*7c478bd9Sstevel@tonic-gate #define	FAILURE		2
280*7c478bd9Sstevel@tonic-gate 
281*7c478bd9Sstevel@tonic-gate /* ecpp e_busy states */
282*7c478bd9Sstevel@tonic-gate #define	ECPP_IDLE	1 /* No ongoing transfers */
283*7c478bd9Sstevel@tonic-gate #define	ECPP_BUSY	2 /* Ongoing transfers on the cable */
284*7c478bd9Sstevel@tonic-gate #define	ECPP_DATA	3 /* Not used */
285*7c478bd9Sstevel@tonic-gate #define	ECPP_ERR	4 /* Bad status in Centronics mode */
286*7c478bd9Sstevel@tonic-gate #define	ECPP_FLUSH	5 /* Currently flushing the q */
287*7c478bd9Sstevel@tonic-gate 
288*7c478bd9Sstevel@tonic-gate #define	TRUE		1
289*7c478bd9Sstevel@tonic-gate #define	FALSE		0
290*7c478bd9Sstevel@tonic-gate 
291*7c478bd9Sstevel@tonic-gate /* message type */
292*7c478bd9Sstevel@tonic-gate #define	ECPP_BACKCHANNEL	0x45
293*7c478bd9Sstevel@tonic-gate 
294*7c478bd9Sstevel@tonic-gate /* transfer modes */
295*7c478bd9Sstevel@tonic-gate #define	ECPP_DMA		0x1
296*7c478bd9Sstevel@tonic-gate #define	ECPP_PIO		0x2
297*7c478bd9Sstevel@tonic-gate 
298*7c478bd9Sstevel@tonic-gate /* tuneable timing defaults */
299*7c478bd9Sstevel@tonic-gate #define	CENTRONICS_RETRY	750	/* 750 milliseconds */
300*7c478bd9Sstevel@tonic-gate #define	WAIT_FOR_BUSY		1000	/* 1000 microseconds */
301*7c478bd9Sstevel@tonic-gate #define	SUSPEND_TOUT		10	/* # seconds before suspend fails */
302*7c478bd9Sstevel@tonic-gate 
303*7c478bd9Sstevel@tonic-gate /* Centronics hanshaking defaults */
304*7c478bd9Sstevel@tonic-gate #define	DATA_SETUP_TIME		2	/* 2 uSec Data Setup Time (2x min) */
305*7c478bd9Sstevel@tonic-gate #define	STROBE_PULSE_WIDTH	2	/* 2 uSec Strobe Pulse (2x min) */
306*7c478bd9Sstevel@tonic-gate 
307*7c478bd9Sstevel@tonic-gate /* 1284 Extensibility Request values */
308*7c478bd9Sstevel@tonic-gate #define	ECPP_XREQ_NIBBLE	0x00    /* Nibble Mode Rev Channel Transfer */
309*7c478bd9Sstevel@tonic-gate #define	ECPP_XREQ_BYTE		0x01    /* Byte Mode Rev Channel Transfer */
310*7c478bd9Sstevel@tonic-gate #define	ECPP_XREQ_ID		0x04    /* Request Device ID */
311*7c478bd9Sstevel@tonic-gate #define	ECPP_XREQ_ECP		0x10    /* Request ECP Mode */
312*7c478bd9Sstevel@tonic-gate #define	ECPP_XREQ_ECPRLE	0x30    /* Request ECP Mode with RLE */
313*7c478bd9Sstevel@tonic-gate #define	ECPP_XREQ_EPP		0x40	/* Request EPP Mode */
314*7c478bd9Sstevel@tonic-gate #define	ECPP_XREQ_XLINK		0x80    /* Request Extensibility Link */
315*7c478bd9Sstevel@tonic-gate 
316*7c478bd9Sstevel@tonic-gate /* softintr flags */
317*7c478bd9Sstevel@tonic-gate #define	ECPP_SOFTINTR_PIONEXT	0x1	/* write next byte in PIO mode */
318*7c478bd9Sstevel@tonic-gate 
319*7c478bd9Sstevel@tonic-gate /* Stream  defaults */
320*7c478bd9Sstevel@tonic-gate #define	IO_BLOCK_SZ	1024 * 128	/* transfer buffer size */
321*7c478bd9Sstevel@tonic-gate #define	ECPPHIWAT	32 * 1024  * 6
322*7c478bd9Sstevel@tonic-gate #define	ECPPLOWAT	32 * 1024  * 4
323*7c478bd9Sstevel@tonic-gate 
324*7c478bd9Sstevel@tonic-gate /* Loop timers */
325*7c478bd9Sstevel@tonic-gate #define	ECPP_REG_WRITE_MAX_LOOP	100	/* cpu is faster than superio */
326*7c478bd9Sstevel@tonic-gate #define	ECPP_ISR_MAX_DELAY	30	/* DMAC slow PENDING status */
327*7c478bd9Sstevel@tonic-gate 
328*7c478bd9Sstevel@tonic-gate /* misc constants */
329*7c478bd9Sstevel@tonic-gate #define	ECPP_FIFO_SZ		16	/* FIFO size */
330*7c478bd9Sstevel@tonic-gate #define	FIFO_DRAIN_PERIOD	250000	/* max FIFO drain period in usec */
331*7c478bd9Sstevel@tonic-gate #define	NIBBLE_REV_BLKSZ	1024	/* send up to # bytes at a time */
332*7c478bd9Sstevel@tonic-gate #define	FWD_TIMEOUT_DEFAULT	90	/* forward xfer timeout in seconds */
333*7c478bd9Sstevel@tonic-gate #define	REV_TIMEOUT_DEFAULT	0	/* reverse xfer timeout in seconds */
334*7c478bd9Sstevel@tonic-gate 
335*7c478bd9Sstevel@tonic-gate /* ECP mode constants */
336*7c478bd9Sstevel@tonic-gate #define	ECP_REV_BLKSZ		1024	/* send up to # bytes at a time */
337*7c478bd9Sstevel@tonic-gate #define	ECP_REV_BLKSZ_MAX	(4 * 1024)	/* maximum of # bytes */
338*7c478bd9Sstevel@tonic-gate #define	ECP_REV_SPEED		(1 * 1024 * 1024)	/* bytes/sec */
339*7c478bd9Sstevel@tonic-gate #define	ECP_REV_MINTOUT		5	/* min ECP rev xfer timeout in ms */
340*7c478bd9Sstevel@tonic-gate #define	REV_WATCHDOG		100	/* poll DMA counter every # ms */
341*7c478bd9Sstevel@tonic-gate 
342*7c478bd9Sstevel@tonic-gate /* spurious interrupt detection */
343*7c478bd9Sstevel@tonic-gate #define	SPUR_CRITICAL		100	/* number of interrupts... */
344*7c478bd9Sstevel@tonic-gate #define	SPUR_PERIOD		1000000000 /* in # ns */
345*7c478bd9Sstevel@tonic-gate 
346*7c478bd9Sstevel@tonic-gate /*
347*7c478bd9Sstevel@tonic-gate  * Copyin/copyout states
348*7c478bd9Sstevel@tonic-gate  */
349*7c478bd9Sstevel@tonic-gate #define	ECPP_STRUCTIN		0
350*7c478bd9Sstevel@tonic-gate #define	ECPP_STRUCTOUT		1
351*7c478bd9Sstevel@tonic-gate #define	ECPP_ADDRIN 		2
352*7c478bd9Sstevel@tonic-gate #define	ECPP_ADDROUT		3
353*7c478bd9Sstevel@tonic-gate 
354*7c478bd9Sstevel@tonic-gate /*
355*7c478bd9Sstevel@tonic-gate  * As other ioctls require the same structure, put inner struct's into union
356*7c478bd9Sstevel@tonic-gate  */
357*7c478bd9Sstevel@tonic-gate struct ecpp_copystate {
358*7c478bd9Sstevel@tonic-gate 	int	state;		/* see above */
359*7c478bd9Sstevel@tonic-gate 	void	*uaddr;		/* user address of the following structure */
360*7c478bd9Sstevel@tonic-gate 	union {
361*7c478bd9Sstevel@tonic-gate 		struct ecpp_device_id		devid;
362*7c478bd9Sstevel@tonic-gate 		struct prn_1284_device_id	prn_devid;
363*7c478bd9Sstevel@tonic-gate 		struct prn_interface_info	prn_if;
364*7c478bd9Sstevel@tonic-gate 	} un;
365*7c478bd9Sstevel@tonic-gate };
366*7c478bd9Sstevel@tonic-gate 
367*7c478bd9Sstevel@tonic-gate /*
368*7c478bd9Sstevel@tonic-gate  * The structure is dynamically created for each M_IOCTL and is bound to mblk
369*7c478bd9Sstevel@tonic-gate  */
370*7c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("unique per call", ecpp_copystate))
371*7c478bd9Sstevel@tonic-gate 
372*7c478bd9Sstevel@tonic-gate /* kstat structure */
373*7c478bd9Sstevel@tonic-gate struct ecppkstat {
374*7c478bd9Sstevel@tonic-gate 	/*
375*7c478bd9Sstevel@tonic-gate 	 * number of bytes, transferred in and out in each mode
376*7c478bd9Sstevel@tonic-gate 	 */
377*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_ctx_obytes;
378*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_ctxpio_obytes;
379*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_nib_ibytes;
380*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_ecp_obytes;
381*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_ecp_ibytes;
382*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_epp_obytes;
383*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_epp_ibytes;
384*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_diag_obytes;
385*7c478bd9Sstevel@tonic-gate 	/*
386*7c478bd9Sstevel@tonic-gate 	 * number of transitions to particular mode
387*7c478bd9Sstevel@tonic-gate 	 */
388*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_to_ctx;
389*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_to_nib;
390*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_to_ecp;
391*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_to_epp;
392*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_to_diag;
393*7c478bd9Sstevel@tonic-gate 	/*
394*7c478bd9Sstevel@tonic-gate 	 * other stats
395*7c478bd9Sstevel@tonic-gate 	 */
396*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_xfer_tout;	/* # transfer timeouts */
397*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_ctx_cf;	/* # periph check failures */
398*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_joblen;	/* # bytes xfer'd since open */
399*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_isr_reattempt_high;	/* max # times */
400*7c478bd9Sstevel@tonic-gate 							/* isr has looped */
401*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_mode;	/* 1284 mode */
402*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_phase;	/* 1284 ECP phase */
403*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_backchan;	/* backchannel mode supported */
404*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_iomode;	/* transfer mode: pio/dma */
405*7c478bd9Sstevel@tonic-gate 	struct kstat_named	ek_state;	/* ecpp busy flag */
406*7c478bd9Sstevel@tonic-gate };
407*7c478bd9Sstevel@tonic-gate 
408*7c478bd9Sstevel@tonic-gate /* Macros for superio programming */
409*7c478bd9Sstevel@tonic-gate #define	PP_PUTB(x, y, z)  	ddi_put8(x, y, z)
410*7c478bd9Sstevel@tonic-gate #define	PP_GETB(x, y)		ddi_get8(x, y)
411*7c478bd9Sstevel@tonic-gate 
412*7c478bd9Sstevel@tonic-gate #define	DSR_READ(pp)		PP_GETB((pp)->i_handle, &(pp)->i_reg->dsr)
413*7c478bd9Sstevel@tonic-gate #define	DCR_READ(pp)		PP_GETB((pp)->i_handle, &(pp)->i_reg->dcr)
414*7c478bd9Sstevel@tonic-gate #define	ECR_READ(pp)		\
415*7c478bd9Sstevel@tonic-gate 	(pp->noecpregs) ? 0xff : PP_GETB((pp)->f_handle, &(pp)->f_reg->ecr)
416*7c478bd9Sstevel@tonic-gate #define	DATAR_READ(pp)		PP_GETB((pp)->i_handle, &(pp)->i_reg->ir.datar)
417*7c478bd9Sstevel@tonic-gate #define	DFIFO_READ(pp)		\
418*7c478bd9Sstevel@tonic-gate 	(pp->noecpregs) ? 0xff : PP_GETB((pp)->f_handle, &(pp)->f_reg->fr.dfifo)
419*7c478bd9Sstevel@tonic-gate #define	TFIFO_READ(pp)		\
420*7c478bd9Sstevel@tonic-gate 	(pp->noecpregs) ? 0xff : PP_GETB((pp)->f_handle, &(pp)->f_reg->fr.tfifo)
421*7c478bd9Sstevel@tonic-gate 
422*7c478bd9Sstevel@tonic-gate #define	DCR_WRITE(pp, val)	PP_PUTB((pp)->i_handle, &(pp)->i_reg->dcr, val)
423*7c478bd9Sstevel@tonic-gate #define	ECR_WRITE(pp, val)	\
424*7c478bd9Sstevel@tonic-gate 	if (!pp->noecpregs) PP_PUTB((pp)->f_handle, &(pp)->f_reg->ecr, val)
425*7c478bd9Sstevel@tonic-gate #define	DATAR_WRITE(pp, val)	\
426*7c478bd9Sstevel@tonic-gate 			PP_PUTB((pp)->i_handle, &(pp)->i_reg->ir.datar, val)
427*7c478bd9Sstevel@tonic-gate #define	DFIFO_WRITE(pp, val)	\
428*7c478bd9Sstevel@tonic-gate 	if (!pp->noecpregs) PP_PUTB((pp)->f_handle, &(pp)->f_reg->fr.dfifo, val)
429*7c478bd9Sstevel@tonic-gate #define	TFIFO_WRITE(pp, val)	\
430*7c478bd9Sstevel@tonic-gate 	if (!pp->noecpregs) PP_PUTB((pp)->f_handle, &(pp)->f_reg->fr.tfifo, val)
431*7c478bd9Sstevel@tonic-gate 
432*7c478bd9Sstevel@tonic-gate /*
433*7c478bd9Sstevel@tonic-gate  * Macros to manipulate register bits
434*7c478bd9Sstevel@tonic-gate  */
435*7c478bd9Sstevel@tonic-gate #define	OR_SET_BYTE_R(handle, addr, val) \
436*7c478bd9Sstevel@tonic-gate {		\
437*7c478bd9Sstevel@tonic-gate 	uint8_t tmpval;					\
438*7c478bd9Sstevel@tonic-gate 	tmpval = ddi_get8(handle, (uint8_t *)addr);	\
439*7c478bd9Sstevel@tonic-gate 	tmpval |= val;					\
440*7c478bd9Sstevel@tonic-gate 	ddi_put8(handle, (uint8_t *)addr, tmpval);	\
441*7c478bd9Sstevel@tonic-gate }
442*7c478bd9Sstevel@tonic-gate 
443*7c478bd9Sstevel@tonic-gate #define	OR_SET_LONG_R(handle, addr, val) \
444*7c478bd9Sstevel@tonic-gate {		\
445*7c478bd9Sstevel@tonic-gate 	uint32_t tmpval;				\
446*7c478bd9Sstevel@tonic-gate 	tmpval = ddi_get32(handle, (uint32_t *)addr);	\
447*7c478bd9Sstevel@tonic-gate 	tmpval |= val;					\
448*7c478bd9Sstevel@tonic-gate 	ddi_put32(handle, (uint32_t *)addr, tmpval);	\
449*7c478bd9Sstevel@tonic-gate }
450*7c478bd9Sstevel@tonic-gate 
451*7c478bd9Sstevel@tonic-gate #define	AND_SET_BYTE_R(handle, addr, val) \
452*7c478bd9Sstevel@tonic-gate {		\
453*7c478bd9Sstevel@tonic-gate 	uint8_t tmpval;					\
454*7c478bd9Sstevel@tonic-gate 	tmpval = ddi_get8(handle, (uint8_t *)addr);	\
455*7c478bd9Sstevel@tonic-gate 	tmpval &= val; 					\
456*7c478bd9Sstevel@tonic-gate 	ddi_put8(handle, (uint8_t *)addr, tmpval);	\
457*7c478bd9Sstevel@tonic-gate }
458*7c478bd9Sstevel@tonic-gate 
459*7c478bd9Sstevel@tonic-gate #define	AND_SET_LONG_R(handle, addr, val) \
460*7c478bd9Sstevel@tonic-gate {		\
461*7c478bd9Sstevel@tonic-gate 	uint32_t tmpval;				\
462*7c478bd9Sstevel@tonic-gate 	tmpval = ddi_get32(handle, (uint32_t *)addr);	\
463*7c478bd9Sstevel@tonic-gate 	tmpval &= val; 					\
464*7c478bd9Sstevel@tonic-gate 	ddi_put32(handle, (uint32_t *)addr, tmpval);	\
465*7c478bd9Sstevel@tonic-gate }
466*7c478bd9Sstevel@tonic-gate 
467*7c478bd9Sstevel@tonic-gate #define	NOR_SET_LONG_R(handle, addr, val, mask) \
468*7c478bd9Sstevel@tonic-gate {		\
469*7c478bd9Sstevel@tonic-gate 	uint32_t tmpval;				\
470*7c478bd9Sstevel@tonic-gate 	tmpval = ddi_get32(handle, (uint32_t *)addr);	\
471*7c478bd9Sstevel@tonic-gate 	tmpval &= ~(mask);				\
472*7c478bd9Sstevel@tonic-gate 	tmpval |= val;					\
473*7c478bd9Sstevel@tonic-gate 	ddi_put32(handle, (uint32_t *)addr, tmpval);	\
474*7c478bd9Sstevel@tonic-gate }
475*7c478bd9Sstevel@tonic-gate 
476*7c478bd9Sstevel@tonic-gate /*
477*7c478bd9Sstevel@tonic-gate  * Macros for Cheerio/RIO DMAC programming
478*7c478bd9Sstevel@tonic-gate  */
479*7c478bd9Sstevel@tonic-gate #define	SET_DMAC_CSR(pp, val)	ddi_put32(pp->uh.ebus.d_handle, \
480*7c478bd9Sstevel@tonic-gate 				((uint32_t *)&pp->uh.ebus.dmac->csr), \
481*7c478bd9Sstevel@tonic-gate 				((uint32_t)val))
482*7c478bd9Sstevel@tonic-gate #define	GET_DMAC_CSR(pp)	ddi_get32(pp->uh.ebus.d_handle, \
483*7c478bd9Sstevel@tonic-gate 				(uint32_t *)&(pp->uh.ebus.dmac->csr))
484*7c478bd9Sstevel@tonic-gate 
485*7c478bd9Sstevel@tonic-gate #define	SET_DMAC_ACR(pp, val)	ddi_put32(pp->uh.ebus.d_handle, \
486*7c478bd9Sstevel@tonic-gate 				((uint32_t *)&pp->uh.ebus.dmac->acr), \
487*7c478bd9Sstevel@tonic-gate 				((uint32_t)val))
488*7c478bd9Sstevel@tonic-gate 
489*7c478bd9Sstevel@tonic-gate #define	GET_DMAC_ACR(pp)	ddi_get32(pp->uh.ebus.d_handle, \
490*7c478bd9Sstevel@tonic-gate 				(uint32_t *)&pp->uh.ebus.dmac->acr)
491*7c478bd9Sstevel@tonic-gate 
492*7c478bd9Sstevel@tonic-gate #define	SET_DMAC_BCR(pp, val)	ddi_put32(pp->uh.ebus.d_handle, \
493*7c478bd9Sstevel@tonic-gate 				((uint32_t *)&pp->uh.ebus.dmac->bcr), \
494*7c478bd9Sstevel@tonic-gate 				((uint32_t)val))
495*7c478bd9Sstevel@tonic-gate 
496*7c478bd9Sstevel@tonic-gate #define	GET_DMAC_BCR(pp)	ddi_get32(pp->uh.ebus.d_handle, \
497*7c478bd9Sstevel@tonic-gate 				((uint32_t *)&pp->uh.ebus.dmac->bcr))
498*7c478bd9Sstevel@tonic-gate 
499*7c478bd9Sstevel@tonic-gate #define	DMAC_RESET_TIMEOUT	10000	/* in usec */
500*7c478bd9Sstevel@tonic-gate 
501*7c478bd9Sstevel@tonic-gate /*
502*7c478bd9Sstevel@tonic-gate  * Macros to distinguish between PIO and DMA Compatibility mode
503*7c478bd9Sstevel@tonic-gate  */
504*7c478bd9Sstevel@tonic-gate #define	COMPAT_PIO(pp) (((pp)->io_mode == ECPP_PIO) &&		\
505*7c478bd9Sstevel@tonic-gate 		    ((pp)->current_mode == ECPP_CENTRONICS ||	\
506*7c478bd9Sstevel@tonic-gate 		    (pp)->current_mode == ECPP_COMPAT_MODE))
507*7c478bd9Sstevel@tonic-gate 
508*7c478bd9Sstevel@tonic-gate #define	COMPAT_DMA(pp) (((pp)->io_mode == ECPP_DMA) &&		\
509*7c478bd9Sstevel@tonic-gate 		    ((pp)->current_mode == ECPP_CENTRONICS ||	\
510*7c478bd9Sstevel@tonic-gate 		    (pp)->current_mode == ECPP_COMPAT_MODE))
511*7c478bd9Sstevel@tonic-gate 
512*7c478bd9Sstevel@tonic-gate /*
513*7c478bd9Sstevel@tonic-gate  * Other useful macros
514*7c478bd9Sstevel@tonic-gate  */
515*7c478bd9Sstevel@tonic-gate #define	NELEM(a)	(sizeof (a) / sizeof (*(a)))
516*7c478bd9Sstevel@tonic-gate #define	offsetof(s, m)	((size_t)(&(((s *)0)->m)))
517*7c478bd9Sstevel@tonic-gate 
518*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
519*7c478bd9Sstevel@tonic-gate }
520*7c478bd9Sstevel@tonic-gate #endif
521*7c478bd9Sstevel@tonic-gate 
522*7c478bd9Sstevel@tonic-gate #endif	/* _SYS_ECPPVAR_H */
523