View | Details | Raw Unified | Return to bug 20339
Collapse All | Expand All

(-)sio.c (-147 / +62 lines)
Lines 82-87 Link Here
82
#include <machine/resource.h>
82
#include <machine/resource.h>
83
83
84
#include <isa/sioreg.h>
84
#include <isa/sioreg.h>
85
#include <isa/siovar.h>
85
86
86
#ifdef COM_ESP
87
#ifdef COM_ESP
87
#include <isa/ic/esp.h>
88
#include <isa/ic/esp.h>
Lines 167-279 Link Here
167
	"tty-level buffer overflow",
168
	"tty-level buffer overflow",
168
};
169
};
169
170
170
#define	CE_NTYPES			3
171
#define	CE_RECORD(com, errnum)		(++(com)->delta_error_counts[errnum])
171
#define	CE_RECORD(com, errnum)		(++(com)->delta_error_counts[errnum])
172
172
173
/* types.  XXX - should be elsewhere */
174
typedef u_int	Port_t;		/* hardware port */
175
typedef u_char	bool_t;		/* boolean */
176
177
/* queue of linear buffers */
178
struct lbq {
179
	u_char	*l_head;	/* next char to process */
180
	u_char	*l_tail;	/* one past the last char to process */
181
	struct lbq *l_next;	/* next in queue */
182
	bool_t	l_queued;	/* nonzero if queued */
183
};
184
185
/* com device structure */
186
struct com_s {
187
	u_int	flags;		/* Copy isa device flags */
188
	u_char	state;		/* miscellaneous flag bits */
189
	bool_t  active_out;	/* nonzero if the callout device is open */
190
	u_char	cfcr_image;	/* copy of value written to CFCR */
191
#ifdef COM_ESP
192
	bool_t	esp;		/* is this unit a hayes esp board? */
193
#endif
194
	u_char	extra_state;	/* more flag bits, separate for order trick */
195
	u_char	fifo_image;	/* copy of value written to FIFO */
196
	bool_t	hasfifo;	/* nonzero for 16550 UARTs */
197
	bool_t	st16650a;	/* Is a Startech 16650A or RTS/CTS compat */
198
	bool_t	loses_outints;	/* nonzero if device loses output interrupts */
199
	u_char	mcr_image;	/* copy of value written to MCR */
200
#ifdef COM_MULTIPORT
201
	bool_t	multiport;	/* is this unit part of a multiport device? */
202
#endif /* COM_MULTIPORT */
203
	bool_t	no_irq;		/* nonzero if irq is not attached */
204
	bool_t  gone;		/* hardware disappeared */
205
	bool_t	poll;		/* nonzero if polling is required */
206
	bool_t	poll_output;	/* nonzero if polling for output is required */
207
	int	unit;		/* unit	number */
208
	int	dtr_wait;	/* time to hold DTR down on close (* 1/hz) */
209
	u_int	tx_fifo_size;
210
	u_int	wopeners;	/* # processes waiting for DCD in open() */
211
212
	/*
213
	 * The high level of the driver never reads status registers directly
214
	 * because there would be too many side effects to handle conveniently.
215
	 * Instead, it reads copies of the registers stored here by the
216
	 * interrupt handler.
217
	 */
218
	u_char	last_modem_status;	/* last MSR read by intr handler */
219
	u_char	prev_modem_status;	/* last MSR handled by high level */
220
221
	u_char	hotchar;	/* ldisc-specific char to be handled ASAP */
222
	u_char	*ibuf;		/* start of input buffer */
223
	u_char	*ibufend;	/* end of input buffer */
224
	u_char	*ibufold;	/* old input buffer, to be freed */
225
	u_char	*ihighwater;	/* threshold in input buffer */
226
	u_char	*iptr;		/* next free spot in input buffer */
227
	int	ibufsize;	/* size of ibuf (not include error bytes) */
228
	int	ierroff;	/* offset of error bytes in ibuf */
229
230
	struct lbq	obufq;	/* head of queue of output buffers */
231
	struct lbq	obufs[2];	/* output buffers */
232
233
	Port_t	data_port;	/* i/o ports */
234
#ifdef COM_ESP
235
	Port_t	esp_port;
236
#endif
237
	Port_t	int_id_port;
238
	Port_t	iobase;
239
	Port_t	modem_ctl_port;
240
	Port_t	line_status_port;
241
	Port_t	modem_status_port;
242
	Port_t	intr_ctl_port;	/* Ports of IIR register */
243
244
	struct tty	*tp;	/* cross reference */
245
246
	/* Initial state. */
247
	struct termios	it_in;	/* should be in struct tty */
248
	struct termios	it_out;
249
250
	/* Lock state. */
251
	struct termios	lt_in;	/* should be in struct tty */
252
	struct termios	lt_out;
253
254
	bool_t	do_timestamp;
255
	bool_t	do_dcd_timestamp;
256
	struct timeval	timestamp;
257
	struct timeval	dcd_timestamp;
258
	struct	pps_state pps;
259
260
	u_long	bytes_in;	/* statistics */
261
	u_long	bytes_out;
262
	u_int	delta_error_counts[CE_NTYPES];
263
	u_long	error_counts[CE_NTYPES];
264
265
	struct resource *irqres;
266
	struct resource *ioportres;
267
	void *cookie;
268
269
	/*
270
	 * Data area for output buffers.  Someday we should build the output
271
	 * buffer queue without copying data.
272
	 */
273
	u_char	obuf1[256];
274
	u_char	obuf2[256];
275
};
276
277
#ifdef COM_ESP
173
#ifdef COM_ESP
278
static	int	espattach	__P((struct com_s *com, Port_t esp_port));
174
static	int	espattach	__P((struct com_s *com, Port_t esp_port));
279
#endif
175
#endif
Lines 284-290 Link Here
284
static	timeout_t siodtrwakeup;
180
static	timeout_t siodtrwakeup;
285
static	void	comhardclose	__P((struct com_s *com));
181
static	void	comhardclose	__P((struct com_s *com));
286
static	void	sioinput	__P((struct com_s *com));
182
static	void	sioinput	__P((struct com_s *com));
287
static	void	siointr1	__P((struct com_s *com));
288
static	void	siointr		__P((void *arg));
183
static	void	siointr		__P((void *arg));
289
static	int	commctl		__P((struct com_s *com, int bits, int how));
184
static	int	commctl		__P((struct com_s *com, int bits, int how));
290
static	int	comparam	__P((struct tty *tp, struct termios *t));
185
static	int	comparam	__P((struct tty *tp, struct termios *t));
Lines 309-316 Link Here
309
204
310
/* table and macro for fast conversion from a unit number to its com struct */
205
/* table and macro for fast conversion from a unit number to its com struct */
311
static	devclass_t	sio_devclass;
206
static	devclass_t	sio_devclass;
312
#define	com_addr(unit)	((struct com_s *) \
207
static	struct com_s	*p_com_addr[SIO_MAXUNITS];
313
			 devclass_get_softc(sio_devclass, unit))
208
#define	com_addr(unit)	(p_com_addr[unit])
314
209
315
static device_method_t sio_isa_methods[] = {
210
static device_method_t sio_isa_methods[] = {
316
	/* Device interface */
211
	/* Device interface */
Lines 969-1000 Link Here
969
	return (sioattach(dev));
864
	return (sioattach(dev));
970
}
865
}
971
866
972
static int
867
int
973
sioattach(dev)
868
sio_attach_unit(com, unit, iobase, flags, no_irq)
974
	device_t	dev;
975
{
976
	struct com_s	*com;
869
	struct com_s	*com;
870
	int		unit;
871
	Port_t		iobase;
872
	u_int		flags;
873
	bool_t		no_irq;
874
{
977
#ifdef COM_ESP
875
#ifdef COM_ESP
978
	Port_t		*espp;
876
	Port_t		*espp;
979
#endif
877
#endif
980
	Port_t		iobase;
878
	if (unit >= SIO_MAXUNITS)
981
	int		unit;
879
		return ENXIO;
982
	u_int		flags;
983
	int		rid;
984
	struct resource *port;
985
	int		ret;
986
987
	rid = 0;
988
	port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
989
				  0, ~0, IO_COMSIZE, RF_ACTIVE);
990
	if (!port)
991
		return (ENXIO);
992
993
	iobase = rman_get_start(port);
994
	unit = device_get_unit(dev);
995
	com = device_get_softc(dev);
996
	flags = device_get_flags(dev);
997
998
	if (unit >= sio_numunits)
880
	if (unit >= sio_numunits)
999
		sio_numunits = unit + 1;
881
		sio_numunits = unit + 1;
1000
	/*
882
	/*
Lines 1011-1021 Link Here
1011
	 */
893
	 */
1012
	bzero(com, sizeof *com);
894
	bzero(com, sizeof *com);
1013
	com->unit = unit;
895
	com->unit = unit;
1014
	com->ioportres = port;
1015
	com->cfcr_image = CFCR_8BITS;
896
	com->cfcr_image = CFCR_8BITS;
1016
	com->dtr_wait = 3 * hz;
897
	com->dtr_wait = 3 * hz;
1017
	com->loses_outints = COM_LOSESOUTINTS(flags) != 0;
898
	com->loses_outints = COM_LOSESOUTINTS(flags) != 0;
1018
	com->no_irq = bus_get_resource(dev, SYS_RES_IRQ, 0, NULL, NULL) != 0;
899
	com->no_irq = no_irq;
1019
	com->tx_fifo_size = 1;
900
	com->tx_fifo_size = 1;
1020
	com->obufs[0].l_head = com->obuf1;
901
	com->obufs[0].l_head = com->obuf1;
1021
	com->obufs[1].l_head = com->obuf2;
902
	com->obufs[1].l_head = com->obuf2;
Lines 1052-1063 Link Here
1052
		com->it_in.c_ispeed = com->it_in.c_ospeed = TTYDEF_SPEED;
933
		com->it_in.c_ispeed = com->it_in.c_ospeed = TTYDEF_SPEED;
1053
	if (siosetwater(com, com->it_in.c_ispeed) != 0) {
934
	if (siosetwater(com, com->it_in.c_ispeed) != 0) {
1054
		enable_intr();
935
		enable_intr();
1055
		/*
1056
		 * Leave i/o resources allocated if this is a `cn'-level
1057
		 * console, so that other devices can't snarf them.
1058
		 */
1059
		if (iobase != siocniobase)
1060
			bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
1061
		return (ENOMEM);
936
		return (ENOMEM);
1062
	}
937
	}
1063
	enable_intr();
938
	enable_intr();
Lines 1164-1180 Link Here
1164
1039
1165
#ifdef COM_MULTIPORT
1040
#ifdef COM_MULTIPORT
1166
	if (COM_ISMULTIPORT(flags)) {
1041
	if (COM_ISMULTIPORT(flags)) {
1167
		device_t masterdev;
1168
1169
		com->multiport = TRUE;
1042
		com->multiport = TRUE;
1170
		printf(" (multiport");
1043
		printf(" (multiport");
1171
		if (unit == COM_MPMASTER(flags))
1044
		if (unit == COM_MPMASTER(flags))
1172
			printf(" master");
1045
			printf(" master");
1173
		printf(")");
1046
		printf(")");
1174
		masterdev = devclass_get_device(sio_devclass,
1175
		    COM_MPMASTER(flags));
1176
		com->no_irq = (masterdev == NULL || bus_get_resource(masterdev,
1177
		    SYS_RES_IRQ, 0, NULL, NULL) != 0);
1178
	 }
1047
	 }
1179
#endif /* COM_MULTIPORT */
1048
#endif /* COM_MULTIPORT */
1180
	if (unit == comconsole)
1049
	if (unit == comconsole)
Lines 1183-1188 Link Here
1183
		printf(" with a bogus IIR_TXRDY register");
1052
		printf(" with a bogus IIR_TXRDY register");
1184
	printf("\n");
1053
	printf("\n");
1185
1054
1055
	com_addr(unit) = com;
1056
1186
	if (!sio_registered) {
1057
	if (!sio_registered) {
1187
		register_swi(SWI_TTY, siopoll);
1058
		register_swi(SWI_TTY, siopoll);
1188
		sio_registered = TRUE;
1059
		sio_registered = TRUE;
Lines 1203-1208 Link Here
1203
	com->pps.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR;
1074
	com->pps.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR;
1204
	pps_init(&com->pps);
1075
	pps_init(&com->pps);
1205
1076
1077
	return (0);
1078
}
1079
1080
static int
1081
sioattach(dev)
1082
	device_t	dev;
1083
{
1084
	int		rid, ret, no_irq;
1085
	struct resource *port;
1086
	struct com_s	*com;
1087
	Port_t		iobase;
1088
	u_int		flags;
1089
1090
	rid = 0;
1091
	port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
1092
				  0, ~0, IO_COMSIZE, RF_ACTIVE);
1093
	if (!port)
1094
		return (ENXIO);
1095
1096
	iobase = rman_get_start(port);
1097
	com = device_get_softc(dev);
1098
	flags = device_get_flags(dev);
1099
1100
#ifdef COM_MULTIPORT
1101
	if (COM_ISMULTIPORT(flags)) {
1102
		device_t masterdev;
1103
1104
		masterdev = devclass_get_device(sio_devclass,
1105
		    COM_MPMASTER(flags));
1106
		no_irq = (masterdev == NULL || bus_get_resource(masterdev,
1107
		    SYS_RES_IRQ, 0, NULL, NULL) != 0);
1108
	 } else
1109
#endif /* COM_MULTIPORT */
1110
	no_irq = bus_get_resource(dev, SYS_RES_IRQ, 0, NULL, NULL) != 0;
1111
1112
	ret = sio_attach_unit(com, device_get_unit(dev), iobase, flags, no_irq);
1113
	if (ret != 0) {
1114
		/* Leave i/o resources allocated if this is a `cn'-level
1115
		 * console, so that other devices can't snarf them. */
1116
		if (iobase != siocniobase)
1117
			bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
1118
		return ret;
1119
	}
1120
1206
	rid = 0;
1121
	rid = 0;
1207
	com->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1,
1122
	com->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1,
1208
	    RF_ACTIVE);
1123
	    RF_ACTIVE);
Lines 1220-1227 Link Here
1220
		if (ret)
1135
		if (ret)
1221
			device_printf(dev, "could not activate interrupt\n");
1136
			device_printf(dev, "could not activate interrupt\n");
1222
	}
1137
	}
1223
1138
	com->ioportres = port;
1224
	return (0);
1139
	return 0;
1225
}
1140
}
1226
1141
1227
static int
1142
static int
Lines 1713-1719 Link Here
1713
#endif /* COM_MULTIPORT */
1628
#endif /* COM_MULTIPORT */
1714
}
1629
}
1715
1630
1716
static void
1631
void
1717
siointr1(com)
1632
siointr1(com)
1718
	struct com_s	*com;
1633
	struct com_s	*com;
1719
{
1634
{

Return to bug 20339