176195Sbrian/*-
276195Sbrian * Copyright (c) 2001 Brian Somers <brian@Awfulhak.org>
378412Sbrian *   based on work by Slawa Olhovchenkov
478412Sbrian *                    John Prince <johnp@knight-trosoft.com>
578412Sbrian *                    Eric Hernes
676195Sbrian * All rights reserved.
776195Sbrian *
876195Sbrian * Redistribution and use in source and binary forms, with or without
976195Sbrian * modification, are permitted provided that the following conditions
1076195Sbrian * are met:
1176195Sbrian * 1. Redistributions of source code must retain the above copyright
1276195Sbrian *    notice, this list of conditions and the following disclaimer.
1376195Sbrian * 2. Redistributions in binary form must reproduce the above copyright
1476195Sbrian *    notice, this list of conditions and the following disclaimer in the
1576195Sbrian *    documentation and/or other materials provided with the distribution.
1676195Sbrian *
1776195Sbrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1876195Sbrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1976195Sbrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2076195Sbrian * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2176195Sbrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2276195Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2376195Sbrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2476195Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2576195Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2676195Sbrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2776195Sbrian * SUCH DAMAGE.
2876195Sbrian *
2976195Sbrian * $FreeBSD$
3076195Sbrian */
3176195Sbrian
3276195Sbrian#define	W(p)				(*(u_int16_t *)(p))
3376195Sbrian#define	vW(p)				(*(u_int16_t volatile *)(p))
3476195Sbrian#define	D(p)				(*(u_int32_t *)(p))
3576195Sbrian#define	vD(p)				(*(u_int32_t volatile *)(p))
3676195Sbrian
3776195Sbrian#define	CE_OVERRUN			0
3876195Sbrian#define	CE_INTERRUPT_BUF_OVERFLOW	1
3976195Sbrian#define	CE_TTY_BUF_OVERFLOW		2
4076195Sbrian#define	CE_NTYPES			3
4176195Sbrian#define	CE_RECORD(com, errnum)		(++(com)->delta_error_counts[errnum])
4276195Sbrian
4376327Sbrian/*#define DIGI_INTERRUPT*/
4476327Sbrian
4576196Sbrian#ifndef DEBUG
4676195Sbrian#define	DEBUG
4776196Sbrian#endif
4876195Sbrian
4976195Sbrian#ifdef DEBUG
5076195Sbrianextern unsigned digi_debug;
5176195Sbrian#define	DLOG(level, args)	if (digi_debug & (level)) device_printf args
5276195Sbrian#else
5376195Sbrian#define	DLOG(level, args)
5476195Sbrian#endif
5576195Sbrian
5676195Sbrian
5776195Sbrianstruct digi_softc;
5876195Sbrian
5976195Sbrian/* digiboard port structure */
6076195Sbrianstruct digi_p {
6176195Sbrian	struct digi_softc *sc;
6276195Sbrian
6376195Sbrian	int status;
6476195Sbrian#define ENABLED 1
6576195Sbrian#define DIGI_DTR_OFF 2
6676195Sbrian#define PAUSE_TX 8
6776195Sbrian#define PAUSE_RX 16
6876195Sbrian
6976195Sbrian	int opencnt;
70118607Sjhb	u_short txbufsize;
71118607Sjhb	u_short rxbufsize;
7276195Sbrian	volatile struct board_chan *bc;
7376195Sbrian	struct tty *tp;
7476195Sbrian
7576195Sbrian	u_char *txbuf;
7676195Sbrian	u_char *rxbuf;
7776195Sbrian	u_char txwin;
7876195Sbrian	u_char rxwin;
7976195Sbrian
8076195Sbrian	u_char pnum;		/* port number */
8176195Sbrian
8276195Sbrian	u_char modemfake;	/* Modem values to be forced */
8376195Sbrian	u_char mstat;
8476195Sbrian	u_char modem;		/* Force values */
8576195Sbrian
8676195Sbrian	/*
8776195Sbrian	 * The high level of the driver never reads status registers directly
8876195Sbrian	 * because there would be too many side effects to handle conveniently.
8976195Sbrian	 * Instead, it reads copies of the registers stored here by the
9076195Sbrian	 * interrupt handler.
9176195Sbrian	 */
9276195Sbrian	u_char last_modem_status;	/* last MSR read by intr handler */
9376195Sbrian	u_char prev_modem_status;	/* last MSR handled by high level */
9476195Sbrian
9576195Sbrian	u_long bytes_in, bytes_out;
9676195Sbrian	u_int delta_error_counts[CE_NTYPES];
9776195Sbrian	u_long error_counts;
9876195Sbrian
9976195Sbrian	tcflag_t c_iflag;		/* hold true IXON/IXOFF/IXANY */
10076195Sbrian	int lcc, lostcc, lbuf;
10176195Sbrian	u_char send_ring;
10278496Sbrian
10378496Sbrian	unsigned laltpin : 1;		/* Alternate pin settings locked */
10478496Sbrian	unsigned ialtpin : 1;		/* Initial alternate pin settings */
10578496Sbrian
10678496Sbrian	int cd;				/* Depends on the altpin setting */
10778496Sbrian	int dsr;
10876195Sbrian};
10976195Sbrian
11076195Sbrian/*
11176195Sbrian * Map TIOCM_* values to digiboard values
11276195Sbrian */
11376195Sbrianstruct digi_control_signals {
11476195Sbrian	int rts;
11576195Sbrian	int cd;
11676195Sbrian	int dsr;
11776195Sbrian	int cts;
11876195Sbrian	int ri;
11976195Sbrian	int dtr;
12076195Sbrian};
12176195Sbrian
12276195Sbrianenum digi_board_status {
12376195Sbrian	DIGI_STATUS_NOTINIT,
12476195Sbrian	DIGI_STATUS_ENABLED,
12576195Sbrian	DIGI_STATUS_DISABLED
12676195Sbrian};
12776195Sbrian
12876195Sbrian/* Digiboard per-board structure */
12976195Sbrianstruct digi_softc {
13076195Sbrian	/* struct board_info */
13176195Sbrian	device_t dev;
13276195Sbrian
13376195Sbrian	const char *name;
13476195Sbrian	enum digi_board_status status;
135118607Sjhb	u_short numports;		/* number of ports on card */
136118509Sbde	u_int port;			/* I/O port */
137118509Sbde	u_int wport;			/* window select I/O port */
13876195Sbrian
13976195Sbrian	struct {
14076195Sbrian		struct resource *mem;
14176195Sbrian		int mrid;
14276195Sbrian		struct resource *irq;
14376195Sbrian		int irqrid;
14476195Sbrian		struct resource *io;
14576195Sbrian		int iorid;
14676195Sbrian		void *irqHandler;
14776195Sbrian		int unit;
148130585Sphk		struct cdev *ctldev;
14976195Sbrian	} res;
15076195Sbrian
15176195Sbrian	u_char *vmem;			/* virtual memory address */
15276195Sbrian	u_char *memcmd;
15376195Sbrian	volatile u_char *memevent;
15476195Sbrian	long pmem;			/* physical memory address */
15576195Sbrian
15676195Sbrian	struct {
15776195Sbrian		u_char *data;
15876195Sbrian		size_t size;
15976195Sbrian	} bios, fep, link;
16076195Sbrian
16176195Sbrian#ifdef DIGI_INTERRUPT
16276195Sbrian	struct timeval intr_timestamp;
16376195Sbrian#endif
16476195Sbrian
16576195Sbrian	struct digi_p *ports;	/* pointer to array of port descriptors */
16676195Sbrian	volatile struct global_data *gdata;
16776195Sbrian	u_char window;		/* saved window */
16876195Sbrian	int win_size;
16976195Sbrian	int win_bits;
17076195Sbrian	int mem_size;
17176195Sbrian	int mem_seg;
17276705Sbrian	enum digi_model model;
17376195Sbrian	const struct digi_control_signals *csigs;
17476195Sbrian	int opencnt;
17576195Sbrian	unsigned pcibus : 1;		/* On a PCI bus ? */
17676195Sbrian
17776195Sbrian	struct callout_handle callout;	/* poll timeout handle */
17876195Sbrian	struct callout_handle inttest;	/* int test timeout handle */
17976195Sbrian	const char *module;
18076195Sbrian
18176195Sbrian	u_char *(*setwin)(struct digi_softc *_sc, unsigned _addr);
18276195Sbrian	void	(*hidewin)(struct digi_softc *_sc);
18376195Sbrian	void	(*towin)(struct digi_softc *_sc, int _win);
18476195Sbrian#ifdef DEBUG
18576195Sbrian	int	intr_count;
18676195Sbrian#endif
18776195Sbrian};
18876195Sbrian
18991445Speterextern devclass_t digi_devclass;
19091445Speter
19176195Sbrianextern const struct digi_control_signals digi_xixe_signals;
19276195Sbrianextern const struct digi_control_signals digi_normal_signals;
19376195Sbrian
19476195Sbrianconst char	*digi_errortxt(int _id);
19576195Sbrianint		 digi_attach(struct digi_softc *);
19676195Sbrianint		 digi_detach(device_t _dev);
19776195Sbrianint		 digi_shutdown(device_t _dev);
19894361Sbrianvoid		 digi_delay(struct digi_softc *_sc, const char *_txt,
19994361Sbrian		     u_long _timo);
200