1281SN/A/*-
2281SN/A * Copyright (c) 2001 Brian Somers <brian@Awfulhak.org>
3281SN/A *   based on work by Slawa Olhovchenkov
4281SN/A *                    John Prince <johnp@knight-trosoft.com>
5281SN/A *                    Eric Hernes
6281SN/A * All rights reserved.
7281SN/A *
8281SN/A * Redistribution and use in source and binary forms, with or without
9281SN/A * modification, are permitted provided that the following conditions
10281SN/A * are met:
11281SN/A * 1. Redistributions of source code must retain the above copyright
12281SN/A *    notice, this list of conditions and the following disclaimer.
13281SN/A * 2. Redistributions in binary form must reproduce the above copyright
14281SN/A *    notice, this list of conditions and the following disclaimer in the
15281SN/A *    documentation and/or other materials provided with the distribution.
16281SN/A *
17281SN/A * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18281SN/A * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19281SN/A * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20281SN/A * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21281SN/A * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22281SN/A * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23281SN/A * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24281SN/A * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25281SN/A * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26281SN/A * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27281SN/A * SUCH DAMAGE.
28281SN/A *
29281SN/A * $FreeBSD$
30281SN/A */
31281SN/A
32281SN/A#define	W(p)				(*(u_int16_t *)(p))
33281SN/A#define	vW(p)				(*(u_int16_t volatile *)(p))
34281SN/A#define	D(p)				(*(u_int32_t *)(p))
35281SN/A#define	vD(p)				(*(u_int32_t volatile *)(p))
36281SN/A
37281SN/A#define	CE_OVERRUN			0
38281SN/A#define	CE_INTERRUPT_BUF_OVERFLOW	1
39281SN/A#define	CE_TTY_BUF_OVERFLOW		2
40281SN/A#define	CE_NTYPES			3
41281SN/A#define	CE_RECORD(com, errnum)		(++(com)->delta_error_counts[errnum])
42281SN/A
43281SN/A/*#define DIGI_INTERRUPT*/
44281SN/A
45281SN/A#ifndef DEBUG
46281SN/A#define	DEBUG
47281SN/A#endif
48281SN/A
49281SN/A#ifdef DEBUG
50281SN/Aextern unsigned digi_debug;
51281SN/A#define	DLOG(level, args)	if (digi_debug & (level)) device_printf args
52281SN/A#else
53281SN/A#define	DLOG(level, args)
54281SN/A#endif
55281SN/A
56281SN/A
57281SN/Astruct digi_softc;
58281SN/A
59281SN/A/* digiboard port structure */
60281SN/Astruct digi_p {
61281SN/A	struct digi_softc *sc;
62281SN/A
63281SN/A	int status;
64281SN/A#define ENABLED 1
65281SN/A#define DIGI_DTR_OFF 2
66281SN/A#define PAUSE_TX 8
67281SN/A#define PAUSE_RX 16
68281SN/A
69281SN/A	int opencnt;
70281SN/A	u_short txbufsize;
71281SN/A	u_short rxbufsize;
72281SN/A	volatile struct board_chan *bc;
73281SN/A	struct tty *tp;
74281SN/A
75281SN/A	u_char *txbuf;
76281SN/A	u_char *rxbuf;
77281SN/A	u_char txwin;
78281SN/A	u_char rxwin;
79281SN/A
80281SN/A	u_char pnum;		/* port number */
81281SN/A
82281SN/A	u_char modemfake;	/* Modem values to be forced */
83281SN/A	u_char mstat;
84281SN/A	u_char modem;		/* Force values */
85281SN/A
86281SN/A	/*
87281SN/A	 * The high level of the driver never reads status registers directly
88281SN/A	 * because there would be too many side effects to handle conveniently.
89281SN/A	 * Instead, it reads copies of the registers stored here by the
90281SN/A	 * interrupt handler.
91281SN/A	 */
92281SN/A	u_char last_modem_status;	/* last MSR read by intr handler */
93281SN/A	u_char prev_modem_status;	/* last MSR handled by high level */
94281SN/A
95281SN/A	u_long bytes_in, bytes_out;
96281SN/A	u_int delta_error_counts[CE_NTYPES];
97281SN/A	u_long error_counts;
98281SN/A
99281SN/A	tcflag_t c_iflag;		/* hold true IXON/IXOFF/IXANY */
100281SN/A	int lcc, lostcc, lbuf;
101281SN/A	u_char send_ring;
102281SN/A
103281SN/A	unsigned laltpin : 1;		/* Alternate pin settings locked */
104281SN/A	unsigned ialtpin : 1;		/* Initial alternate pin settings */
105281SN/A
106281SN/A	int cd;				/* Depends on the altpin setting */
107281SN/A	int dsr;
108281SN/A};
109281SN/A
110281SN/A/*
111281SN/A * Map TIOCM_* values to digiboard values
112281SN/A */
113281SN/Astruct digi_control_signals {
114281SN/A	int rts;
115281SN/A	int cd;
116281SN/A	int dsr;
117281SN/A	int cts;
118281SN/A	int ri;
119281SN/A	int dtr;
120281SN/A};
121281SN/A
122281SN/Aenum digi_board_status {
123281SN/A	DIGI_STATUS_NOTINIT,
124281SN/A	DIGI_STATUS_ENABLED,
125281SN/A	DIGI_STATUS_DISABLED
126281SN/A};
127281SN/A
128281SN/A/* Digiboard per-board structure */
129281SN/Astruct digi_softc {
130281SN/A	/* struct board_info */
131281SN/A	device_t dev;
132281SN/A
133281SN/A	const char *name;
134281SN/A	enum digi_board_status status;
135281SN/A	u_short numports;		/* number of ports on card */
136281SN/A	u_int port;			/* I/O port */
137281SN/A	u_int wport;			/* window select I/O port */
138281SN/A
139281SN/A	struct {
140281SN/A		struct resource *mem;
141281SN/A		int mrid;
142281SN/A		struct resource *irq;
143281SN/A		int irqrid;
144281SN/A		struct resource *io;
145281SN/A		int iorid;
146281SN/A		void *irqHandler;
147281SN/A		int unit;
148281SN/A		struct cdev *ctldev;
149281SN/A	} res;
150281SN/A
151281SN/A	u_char *vmem;			/* virtual memory address */
152281SN/A	u_char *memcmd;
153281SN/A	volatile u_char *memevent;
154281SN/A	long pmem;			/* physical memory address */
155281SN/A
156281SN/A	struct {
157281SN/A		u_char *data;
158281SN/A		size_t size;
159281SN/A	} bios, fep, link;
160281SN/A
161281SN/A#ifdef DIGI_INTERRUPT
162281SN/A	struct timeval intr_timestamp;
163281SN/A#endif
164281SN/A
165281SN/A	struct digi_p *ports;	/* pointer to array of port descriptors */
166281SN/A	volatile struct global_data *gdata;
167281SN/A	u_char window;		/* saved window */
168281SN/A	int win_size;
169281SN/A	int win_bits;
170281SN/A	int mem_size;
171281SN/A	int mem_seg;
172281SN/A	enum digi_model model;
173281SN/A	const struct digi_control_signals *csigs;
174281SN/A	int opencnt;
175281SN/A	unsigned pcibus : 1;		/* On a PCI bus ? */
176281SN/A
177281SN/A	struct callout_handle callout;	/* poll timeout handle */
178281SN/A	struct callout_handle inttest;	/* int test timeout handle */
179281SN/A	const char *module;
180281SN/A
181281SN/A	u_char *(*setwin)(struct digi_softc *_sc, unsigned _addr);
182281SN/A	void	(*hidewin)(struct digi_softc *_sc);
183281SN/A	void	(*towin)(struct digi_softc *_sc, int _win);
184281SN/A#ifdef DEBUG
185281SN/A	int	intr_count;
186281SN/A#endif
187281SN/A};
188
189extern devclass_t digi_devclass;
190
191extern const struct digi_control_signals digi_xixe_signals;
192extern const struct digi_control_signals digi_normal_signals;
193
194const char	*digi_errortxt(int _id);
195int		 digi_attach(struct digi_softc *);
196int		 digi_detach(device_t _dev);
197int		 digi_shutdown(device_t _dev);
198void		 digi_delay(struct digi_softc *_sc, const char *_txt,
199		     u_long _timo);
200