Deleted Added
full compact
si.c (50671) si.c (51654)
1/*
2 * Device driver for Specialix range (SI/XIO) of serial line multiplexors.
3 *
4 * Copyright (C) 1990, 1992, 1998 Specialix International,
5 * Copyright (C) 1993, Andy Rutter <andy@acronym.co.uk>
6 * Copyright (C) 1995, Peter Wemm <peter@netplex.com.au>
7 *
8 * Originally derived from: SunOS 4.x version
9 * Ported from BSDI version to FreeBSD by Peter Wemm.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notices, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notices, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by Andy Rutter of
22 * Advanced Methods and Tools Ltd. based on original information
23 * from Specialix International.
24 * 4. Neither the name of Advanced Methods and Tools, nor Specialix
25 * International may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED
29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
31 * NO EVENT SHALL THE AUTHORS BE LIABLE.
32 *
1/*
2 * Device driver for Specialix range (SI/XIO) of serial line multiplexors.
3 *
4 * Copyright (C) 1990, 1992, 1998 Specialix International,
5 * Copyright (C) 1993, Andy Rutter <andy@acronym.co.uk>
6 * Copyright (C) 1995, Peter Wemm <peter@netplex.com.au>
7 *
8 * Originally derived from: SunOS 4.x version
9 * Ported from BSDI version to FreeBSD by Peter Wemm.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notices, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notices, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by Andy Rutter of
22 * Advanced Methods and Tools Ltd. based on original information
23 * from Specialix International.
24 * 4. Neither the name of Advanced Methods and Tools, nor Specialix
25 * International may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED
29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
31 * NO EVENT SHALL THE AUTHORS BE LIABLE.
32 *
33 * $FreeBSD: head/sys/dev/si/si.c 50671 1999-08-30 20:52:14Z phk $
33 * $FreeBSD: head/sys/dev/si/si.c 51654 1999-09-25 16:21:39Z phk $
34 */
35
36#ifndef lint
37static const char si_copyright1[] = "@(#) Copyright (C) Specialix International, 1990,1992,1998",
38 si_copyright2[] = "@(#) Copyright (C) Andy Rutter 1993",
39 si_copyright3[] = "@(#) Copyright (C) Peter Wemm 1995";
40#endif /* not lint */
41
42#include "opt_compat.h"
43#include "opt_debug_si.h"
44
45#include <sys/param.h>
46#include <sys/systm.h>
47#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
48#include <sys/ioctl_compat.h>
49#endif
50#include <sys/tty.h>
51#include <sys/proc.h>
52#include <sys/conf.h>
53#include <sys/fcntl.h>
54#include <sys/dkstat.h>
55#include <sys/kernel.h>
56#include <sys/malloc.h>
57#include <sys/sysctl.h>
58
59#include <machine/clock.h>
60
61#include <vm/vm.h>
62#include <vm/pmap.h>
63
64#include <i386/isa/icu.h>
65#include <i386/isa/isa.h>
66#include <i386/isa/isa_device.h>
67
68#include <i386/isa/sireg.h>
69#include <machine/si.h>
70#include <machine/stdarg.h>
71
72#include "pci.h"
73#if NPCI > 0
74#include <pci/pcivar.h>
75#endif
76
77#include "eisa.h"
78#if NEISA > 0
79#warning "Fix si eisa code! - newbus casualty"
80#undef NEISA
81#define NEISA 0
82#endif
83#if NEISA > 0
84#include <i386/eisa/eisaconf.h>
85#include <i386/isa/icu.h>
86#endif
87
88#include "si.h"
89
90/*
91 * This device driver is designed to interface the Specialix International
92 * SI, XIO and SX range of serial multiplexor cards to FreeBSD on an ISA,
93 * EISA or PCI bus machine.
94 *
95 * The controller is interfaced to the host via dual port RAM
96 * and an interrupt.
97 *
98 * The code for the Host 1 (very old ISA cards) has not been tested.
99 */
100
101#define POLL /* turn on poller to scan for lost interrupts */
102#define REALPOLL /* on each poll, scan for work regardless */
103#define POLLHZ (hz/10) /* 10 times per second */
104#define SI_I_HIGH_WATER (TTYHOG - 2 * SI_BUFFERSIZE)
105#define INT_COUNT 25000 /* max of 125 ints per second */
106#define JET_INT_COUNT 100 /* max of 100 ints per second */
107#define RXINT_COUNT 1 /* one rxint per 10 milliseconds */
108
109enum si_mctl { GET, SET, BIS, BIC };
110
111static void si_command __P((struct si_port *, int, int));
112static int si_modem __P((struct si_port *, enum si_mctl, int));
113static void si_write_enable __P((struct si_port *, int));
114static int si_Sioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
115static void si_start __P((struct tty *));
34 */
35
36#ifndef lint
37static const char si_copyright1[] = "@(#) Copyright (C) Specialix International, 1990,1992,1998",
38 si_copyright2[] = "@(#) Copyright (C) Andy Rutter 1993",
39 si_copyright3[] = "@(#) Copyright (C) Peter Wemm 1995";
40#endif /* not lint */
41
42#include "opt_compat.h"
43#include "opt_debug_si.h"
44
45#include <sys/param.h>
46#include <sys/systm.h>
47#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
48#include <sys/ioctl_compat.h>
49#endif
50#include <sys/tty.h>
51#include <sys/proc.h>
52#include <sys/conf.h>
53#include <sys/fcntl.h>
54#include <sys/dkstat.h>
55#include <sys/kernel.h>
56#include <sys/malloc.h>
57#include <sys/sysctl.h>
58
59#include <machine/clock.h>
60
61#include <vm/vm.h>
62#include <vm/pmap.h>
63
64#include <i386/isa/icu.h>
65#include <i386/isa/isa.h>
66#include <i386/isa/isa_device.h>
67
68#include <i386/isa/sireg.h>
69#include <machine/si.h>
70#include <machine/stdarg.h>
71
72#include "pci.h"
73#if NPCI > 0
74#include <pci/pcivar.h>
75#endif
76
77#include "eisa.h"
78#if NEISA > 0
79#warning "Fix si eisa code! - newbus casualty"
80#undef NEISA
81#define NEISA 0
82#endif
83#if NEISA > 0
84#include <i386/eisa/eisaconf.h>
85#include <i386/isa/icu.h>
86#endif
87
88#include "si.h"
89
90/*
91 * This device driver is designed to interface the Specialix International
92 * SI, XIO and SX range of serial multiplexor cards to FreeBSD on an ISA,
93 * EISA or PCI bus machine.
94 *
95 * The controller is interfaced to the host via dual port RAM
96 * and an interrupt.
97 *
98 * The code for the Host 1 (very old ISA cards) has not been tested.
99 */
100
101#define POLL /* turn on poller to scan for lost interrupts */
102#define REALPOLL /* on each poll, scan for work regardless */
103#define POLLHZ (hz/10) /* 10 times per second */
104#define SI_I_HIGH_WATER (TTYHOG - 2 * SI_BUFFERSIZE)
105#define INT_COUNT 25000 /* max of 125 ints per second */
106#define JET_INT_COUNT 100 /* max of 100 ints per second */
107#define RXINT_COUNT 1 /* one rxint per 10 milliseconds */
108
109enum si_mctl { GET, SET, BIS, BIC };
110
111static void si_command __P((struct si_port *, int, int));
112static int si_modem __P((struct si_port *, enum si_mctl, int));
113static void si_write_enable __P((struct si_port *, int));
114static int si_Sioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
115static void si_start __P((struct tty *));
116static void si_stop __P((struct tty *, int));
116static timeout_t si_lstart;
117static void si_disc_optim __P((struct tty *tp, struct termios *t,
118 struct si_port *pp));
119static void sihardclose __P((struct si_port *pp));
120static void sidtrwakeup __P((void *chan));
121
122static int siparam __P((struct tty *, struct termios *));
123
124static int siprobe __P((struct isa_device *id));
125static int siattach __P((struct isa_device *id));
126static void si_modem_state __P((struct si_port *pp, struct tty *tp, int hi_ip));
127static void si_intr __P((int unit));
128static char * si_modulename __P((int host_type, int uart_type));
129
130struct isa_driver sidriver =
131 { siprobe, siattach, "si" };
132
133static u_long sipcieisacount = 0;
134
135#if NPCI > 0
136
137static const char *sipciprobe __P((pcici_t, pcidi_t));
138static void sipciattach __P((pcici_t, int));
139
140static struct pci_device sipcidev = {
141 "si",
142 sipciprobe,
143 sipciattach,
144 &sipcieisacount,
145 NULL,
146};
147
148COMPAT_PCI_DRIVER (sipci, sipcidev);
149
150#endif
151
152#if NEISA > 0
153
154static int si_eisa_probe __P((void));
155static int si_eisa_attach __P((struct eisa_device *ed));
156
157static struct eisa_driver si_eisa_driver = {
158 "si",
159 si_eisa_probe,
160 si_eisa_attach,
161 NULL,
162 &sipcieisacount,
163};
164
165DATA_SET(eisadriver_set, si_eisa_driver);
166
167#endif
168
169static d_open_t siopen;
170static d_close_t siclose;
171static d_read_t siread;
172static d_write_t siwrite;
173static d_ioctl_t siioctl;
117static timeout_t si_lstart;
118static void si_disc_optim __P((struct tty *tp, struct termios *t,
119 struct si_port *pp));
120static void sihardclose __P((struct si_port *pp));
121static void sidtrwakeup __P((void *chan));
122
123static int siparam __P((struct tty *, struct termios *));
124
125static int siprobe __P((struct isa_device *id));
126static int siattach __P((struct isa_device *id));
127static void si_modem_state __P((struct si_port *pp, struct tty *tp, int hi_ip));
128static void si_intr __P((int unit));
129static char * si_modulename __P((int host_type, int uart_type));
130
131struct isa_driver sidriver =
132 { siprobe, siattach, "si" };
133
134static u_long sipcieisacount = 0;
135
136#if NPCI > 0
137
138static const char *sipciprobe __P((pcici_t, pcidi_t));
139static void sipciattach __P((pcici_t, int));
140
141static struct pci_device sipcidev = {
142 "si",
143 sipciprobe,
144 sipciattach,
145 &sipcieisacount,
146 NULL,
147};
148
149COMPAT_PCI_DRIVER (sipci, sipcidev);
150
151#endif
152
153#if NEISA > 0
154
155static int si_eisa_probe __P((void));
156static int si_eisa_attach __P((struct eisa_device *ed));
157
158static struct eisa_driver si_eisa_driver = {
159 "si",
160 si_eisa_probe,
161 si_eisa_attach,
162 NULL,
163 &sipcieisacount,
164};
165
166DATA_SET(eisadriver_set, si_eisa_driver);
167
168#endif
169
170static d_open_t siopen;
171static d_close_t siclose;
172static d_read_t siread;
173static d_write_t siwrite;
174static d_ioctl_t siioctl;
174static d_stop_t sistop;
175static d_devtotty_t sidevtotty;
176
177#define CDEV_MAJOR 68
178static struct cdevsw si_cdevsw = {
179 /* open */ siopen,
180 /* close */ siclose,
181 /* read */ siread,
182 /* write */ siwrite,
183 /* ioctl */ siioctl,
175
176#define CDEV_MAJOR 68
177static struct cdevsw si_cdevsw = {
178 /* open */ siopen,
179 /* close */ siclose,
180 /* read */ siread,
181 /* write */ siwrite,
182 /* ioctl */ siioctl,
184 /* stop */ sistop,
183 /* stop */ nostop,
185 /* reset */ noreset,
184 /* reset */ noreset,
186 /* devtotty */ sidevtotty,
187 /* poll */ ttpoll,
185 /* devtotty */ nodevtotty,
186 /* poll */ ttypoll,
188 /* mmap */ nommap,
189 /* strategy */ nostrategy,
190 /* name */ "si",
191 /* parms */ noparms,
192 /* maj */ CDEV_MAJOR,
193 /* dump */ nodump,
194 /* psize */ nopsize,
195 /* flags */ D_TTY,
196 /* maxio */ 0,
197 /* bmaj */ -1
198};
199
200#ifdef SI_DEBUG /* use: ``options "SI_DEBUG"'' in your config file */
201
202static void si_dprintf __P((struct si_port *pp, int flags, const char *fmt,
203 ...));
204static char *si_mctl2str __P((enum si_mctl cmd));
205
206#define DPRINT(x) si_dprintf x
207
208#else
209#define DPRINT(x) /* void */
210#endif
211
212static int si_Nports;
213static int si_Nmodules;
214static int si_debug = 0; /* data, not bss, so it's patchable */
215
216SYSCTL_INT(_machdep, OID_AUTO, si_debug, CTLFLAG_RW, &si_debug, 0, "");
217
218static struct tty *si__tty;
219
220/* where the firmware lives; defined in si2_z280.c and si3_t225.c */
221/* old: si2_z280.c */
222extern unsigned char si2_z280_download[];
223extern unsigned short si2_z280_downloadaddr;
224extern int si2_z280_dsize;
225/* new: si3_t225.c */
226extern unsigned char si3_t225_download[];
227extern unsigned short si3_t225_downloadaddr;
228extern int si3_t225_dsize;
229extern unsigned char si3_t225_bootstrap[];
230extern unsigned short si3_t225_bootloadaddr;
231extern int si3_t225_bsize;
232
233
234struct si_softc {
235 int sc_type; /* adapter type */
236 char *sc_typename; /* adapter type string */
237
238 struct si_port *sc_ports; /* port structures for this card */
239
240 caddr_t sc_paddr; /* physical addr of iomem */
241 caddr_t sc_maddr; /* kvaddr of iomem */
242 int sc_nport; /* # ports on this card */
243 int sc_irq; /* copy of attach irq */
244#if NEISA > 0
245 int sc_eisa_iobase; /* EISA io port address */
246 int sc_eisa_irq; /* EISA irq number */
247#endif
248};
249static struct si_softc si_softc[NSI]; /* up to 4 elements */
250
251#ifndef B2000 /* not standard, but the hardware knows it. */
252# define B2000 2000
253#endif
254static struct speedtab bdrates[] = {
255 { B75, CLK75, }, /* 0x0 */
256 { B110, CLK110, }, /* 0x1 */
257 { B150, CLK150, }, /* 0x3 */
258 { B300, CLK300, }, /* 0x4 */
259 { B600, CLK600, }, /* 0x5 */
260 { B1200, CLK1200, }, /* 0x6 */
261 { B2000, CLK2000, }, /* 0x7 */
262 { B2400, CLK2400, }, /* 0x8 */
263 { B4800, CLK4800, }, /* 0x9 */
264 { B9600, CLK9600, }, /* 0xb */
265 { B19200, CLK19200, }, /* 0xc */
266 { B38400, CLK38400, }, /* 0x2 (out of order!) */
267 { B57600, CLK57600, }, /* 0xd */
268 { B115200, CLK110, }, /* 0x1 (dupe!, 110 baud on "si") */
269 { -1, -1 },
270};
271
272
273/* populated with approx character/sec rates - translated at card
274 * initialisation time to chars per tick of the clock */
275static int done_chartimes = 0;
276static struct speedtab chartimes[] = {
277 { B75, 8, },
278 { B110, 11, },
279 { B150, 15, },
280 { B300, 30, },
281 { B600, 60, },
282 { B1200, 120, },
283 { B2000, 200, },
284 { B2400, 240, },
285 { B4800, 480, },
286 { B9600, 960, },
287 { B19200, 1920, },
288 { B38400, 3840, },
289 { B57600, 5760, },
290 { B115200, 11520, },
291 { -1, -1 },
292};
293static volatile int in_intr = 0; /* Inside interrupt handler? */
294
295#ifdef POLL
296static int si_pollrate; /* in addition to irq */
297static int si_realpoll; /* poll HW on timer */
298
299SYSCTL_INT(_machdep, OID_AUTO, si_pollrate, CTLFLAG_RW, &si_pollrate, 0, "");
300SYSCTL_INT(_machdep, OID_AUTO, si_realpoll, CTLFLAG_RW, &si_realpoll, 0, "");
301
302static int init_finished = 0;
303static void si_poll __P((void *));
304#endif
305
306/*
307 * Array of adapter types and the corresponding RAM size. The order of
308 * entries here MUST match the ordinal of the adapter type.
309 */
310static char *si_type[] = {
311 "EMPTY",
312 "SIHOST",
313 "SIMCA", /* FreeBSD does not support Microchannel */
314 "SIHOST2",
315 "SIEISA",
316 "SIPCI",
317 "SXPCI",
318 "SXISA",
319};
320
321#if NPCI > 0
322
323static const char *
324sipciprobe(configid, deviceid)
325pcici_t configid;
326pcidi_t deviceid;
327{
328 switch (deviceid)
329 {
330 case 0x400011cb:
331 return("Specialix SI/XIO PCI host card");
332 break;
333 case 0x200011cb:
334 if (pci_conf_read(configid, SIJETSSIDREG) == 0x020011cb)
335 return("Specialix SX PCI host card");
336 else
337 return NULL;
338 break;
339 default:
340 return NULL;
341 }
342 /*NOTREACHED*/
343}
344
345void
346sipciattach(configid, unit)
347pcici_t configid;
348int unit;
349{
350 struct isa_device id;
351 vm_offset_t vaddr,paddr;
352 u_long mapval = 0; /* shut up gcc, should not be needed */
353
354 switch (pci_conf_read(configid, 0) >> 16) {
355 case 0x4000:
356 si_softc[unit].sc_type = SIPCI;
357 mapval = SIPCIBADR;
358 break;
359 case 0x2000:
360 si_softc[unit].sc_type = SIJETPCI;
361 mapval = SIJETBADR;
362 break;
363 }
364 if (!pci_map_mem(configid, mapval, &vaddr, &paddr))
365 {
366 printf("si%d: couldn't map memory\n", unit);
367 }
368
369 /*
370 * We're cheating here a little bit. The argument to an ISA
371 * interrupt routine is the unit number. The argument to a
372 * PCI interrupt handler is a void *, but we're simply going
373 * to be lazy and hand it the unit number.
374 */
375 if (!pci_map_int(configid, (pci_inthand_t *) si_intr, (void *)unit, &tty_imask)) {
376 printf("si%d: couldn't map interrupt\n", unit);
377 }
378 si_softc[unit].sc_typename = si_type[si_softc[unit].sc_type];
379
380 /*
381 * More cheating: We're going to dummy up a struct isa_device
382 * and call the other attach routine. We don't really have to
383 * fill in very much of the structure, since we filled in a
384 * little of the soft state already.
385 */
386 id.id_unit = unit;
387 id.id_maddr = (caddr_t) vaddr;
388 siattach(&id);
389}
390
391#endif
392
393#if NEISA > 0
394
395static const char *si_eisa_match __P((eisa_id_t id));
396
397static const char *
398si_eisa_match(id)
399 eisa_id_t id;
400{
401 if (id == SIEISADEVID)
402 return ("Specialix SI/XIO EISA host card");
403 return (NULL);
404}
405
406static int
407si_eisa_probe(void)
408{
409 struct eisa_device *ed = NULL;
410 int count, irq;
411
412 for (count = 0; (ed = eisa_match_dev(ed, si_eisa_match)) != NULL;
413 count++) {
414 u_long port,maddr;
415
416 port = (ed->ioconf.slot * EISA_SLOT_SIZE) + SIEISABASE;
417 eisa_add_iospace(ed, port, SIEISAIOSIZE, RESVADDR_NONE);
418 maddr = (inb(port+1) << 24) | (inb(port) << 16);
419 irq = ((inb(port+2) >> 4) & 0xf);
420 eisa_add_mspace(ed, maddr, SIEISA_MEMSIZE, RESVADDR_NONE);
421 eisa_add_intr(ed, irq);
422 eisa_registerdev(ed, &si_eisa_driver);
423 count++;
424 }
425 return count;
426}
427
428static int
429si_eisa_attach(ed)
430 struct eisa_device *ed;
431{
432 struct isa_device id;
433 resvaddr_t *maddr,*iospace;
434 u_int irq;
435 struct si_softc *sc;
436
437 sc = &si_softc[ed->unit];
438
439 sc->sc_type = SIEISA;
440 sc->sc_typename = si_type[sc->sc_type];
441
442 if ((iospace = ed->ioconf.ioaddrs.lh_first) == NULL) {
443 printf("si%lu: no iospace??\n", ed->unit);
444 return -1;
445 }
446 sc->sc_eisa_iobase = iospace->addr;
447
448 irq = ((inb(iospace->addr + 2) >> 4) & 0xf);
449 sc->sc_eisa_irq = irq;
450
451 if ((maddr = ed->ioconf.maddrs.lh_first) == NULL) {
452 printf("si%lu: where am I??\n", ed->unit);
453 return -1;
454 }
455 eisa_reg_start(ed);
456 if (eisa_reg_iospace(ed, iospace)) {
457 printf("si%lu: failed to register iospace %p\n",
458 ed->unit, (void *)iospace);
459 return -1;
460 }
461 if (eisa_reg_mspace(ed, maddr)) {
462 printf("si%lu: failed to register memspace %p\n",
463 ed->unit, (void *)maddr);
464 return -1;
465 }
466 /*
467 * We're cheating here a little bit. The argument to an ISA
468 * interrupt routine is the unit number. The argument to a
469 * EISA interrupt handler is a void *, but we're simply going
470 * to be lazy and hand it the unit number.
471 */
472 if (eisa_reg_intr(ed, irq, (void (*)(void *)) si_intr,
473 (void *)(intptr_t)(ed->unit), &tty_imask, 1)) {
474 printf("si%lu: failed to register interrupt %d\n",
475 ed->unit, irq);
476 return -1;
477 }
478 eisa_reg_end(ed);
479 if (eisa_enable_intr(ed, irq)) {
480 return -1;
481 }
482
483 /*
484 * More cheating: We're going to dummy up a struct isa_device
485 * and call the other attach routine. We don't really have to
486 * fill in very much of the structure, since we filled in a
487 * little of the soft state already.
488 */
489 id.id_unit = ed->unit;
490 id.id_maddr = (caddr_t) pmap_mapdev(maddr->addr, SIEISA_MEMSIZE);
491 return (siattach(&id));
492}
493
494#endif
495
496
497/* Look for a valid board at the given mem addr */
498static int
499siprobe(id)
500 struct isa_device *id;
501{
502 struct si_softc *sc;
503 int type;
504 u_int i, ramsize;
505 volatile BYTE was, *ux;
506 volatile unsigned char *maddr;
507 unsigned char *paddr;
508
509 si_pollrate = POLLHZ; /* default 10 per second */
510#ifdef REALPOLL
511 si_realpoll = 1; /* scan always */
512#endif
513 maddr = id->id_maddr; /* virtual address... */
514 paddr = (caddr_t)vtophys(id->id_maddr); /* physical address... */
515
516 DPRINT((0, DBG_AUTOBOOT, "si%d: probe at virtual=0x%x physical=0x%x\n",
517 id->id_unit, id->id_maddr, paddr));
518
519 /*
520 * this is a lie, but it's easier than trying to handle caching
521 * and ram conflicts in the >1M and <16M region.
522 */
523 if ((caddr_t)paddr < (caddr_t)IOM_BEGIN ||
524 (caddr_t)paddr >= (caddr_t)IOM_END) {
525 printf("si%d: iomem (%p) out of range\n",
526 id->id_unit, (void *)paddr);
527 return(0);
528 }
529
530 if (id->id_unit >= NSI) {
531 /* THIS IS IMPOSSIBLE */
532 return(0);
533 }
534
535 if (((u_int)paddr & 0x7fff) != 0) {
536 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
537 "si%d: iomem (%x) not on 32k boundary\n",
538 id->id_unit, paddr));
539 return(0);
540 }
541
542 if (si_softc[id->id_unit].sc_typename) {
543 /* EISA or PCI has taken this unit, choose another */
544 for (i = 0; i < NSI; i++) {
545 if (si_softc[i].sc_typename == NULL) {
546 id->id_unit = i;
547 break;
548 }
549 }
550 if (i >= NSI) {
551 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
552 "si%d: cannot realloc unit\n", id->id_unit));
553 return (0);
554 }
555 }
556
557 for (i = 0; i < NSI; i++) {
558 sc = &si_softc[i];
559 if ((caddr_t)sc->sc_paddr == (caddr_t)paddr) {
560 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
561 "si%d: iomem (%x) already configured to si%d\n",
562 id->id_unit, sc->sc_paddr, i));
563 return(0);
564 }
565 }
566
567 /* Is there anything out there? (0x17 is just an arbitrary number) */
568 *maddr = 0x17;
569 if (*maddr != 0x17) {
570 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
571 "si%d: 0x17 check fail at phys 0x%x\n",
572 id->id_unit, paddr));
573fail:
574 return(0);
575 }
576 /*
577 * Let's look first for a JET ISA card, since that's pretty easy
578 *
579 * All jet hosts are supposed to have this string in the IDROM,
580 * but it's not worth checking on self-IDing busses like PCI.
581 */
582 {
583 unsigned char *jet_chk_str = "JET HOST BY KEV#";
584
585 for (i = 0; i < strlen(jet_chk_str); i++)
586 if (jet_chk_str[i] != *(maddr + SIJETIDSTR + 2 * i))
587 goto try_mk2;
588 }
589 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
590 "si%d: JET first check - 0x%x\n",
591 id->id_unit, (*(maddr+SIJETIDBASE))));
592 if (*(maddr+SIJETIDBASE) != (SISPLXID&0xff))
593 goto try_mk2;
594 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
595 "si%d: JET second check - 0x%x\n",
596 id->id_unit, (*(maddr+SIJETIDBASE+2))));
597 if (*(maddr+SIJETIDBASE+2) != ((SISPLXID&0xff00)>>8))
598 goto try_mk2;
599 /* It must be a Jet ISA or RIO card */
600 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
601 "si%d: JET id check - 0x%x\n",
602 id->id_unit, (*(maddr+SIUNIQID))));
603 if ((*(maddr+SIUNIQID) & 0xf0) != 0x20)
604 goto try_mk2;
605 /* It must be a Jet ISA SI/XIO card */
606 *(maddr + SIJETCONFIG) = 0;
607 type = SIJETISA;
608 ramsize = SIJET_RAMSIZE;
609 goto got_card;
610 /*
611 * OK, now to see if whatever responded is really an SI card.
612 * Try for a MK II next (SIHOST2)
613 */
614try_mk2:
615 for (i = SIPLSIG; i < SIPLSIG + 8; i++)
616 if ((*(maddr+i) & 7) != (~(BYTE)i & 7))
617 goto try_mk1;
618
619 /* It must be an SIHOST2 */
620 *(maddr + SIPLRESET) = 0;
621 *(maddr + SIPLIRQCLR) = 0;
622 *(maddr + SIPLIRQSET) = 0x10;
623 type = SIHOST2;
624 ramsize = SIHOST2_RAMSIZE;
625 goto got_card;
626
627 /*
628 * Its not a MK II, so try for a MK I (SIHOST)
629 */
630try_mk1:
631 *(maddr+SIRESET) = 0x0; /* reset the card */
632 *(maddr+SIINTCL) = 0x0; /* clear int */
633 *(maddr+SIRAM) = 0x17;
634 if (*(maddr+SIRAM) != (BYTE)0x17)
635 goto fail;
636 *(maddr+0x7ff8) = 0x17;
637 if (*(maddr+0x7ff8) != (BYTE)0x17) {
638 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
639 "si%d: 0x17 check fail at phys 0x%x = 0x%x\n",
640 id->id_unit, paddr+0x77f8, *(maddr+0x77f8)));
641 goto fail;
642 }
643
644 /* It must be an SIHOST (maybe?) - there must be a better way XXX */
645 type = SIHOST;
646 ramsize = SIHOST_RAMSIZE;
647
648got_card:
649 DPRINT((0, DBG_AUTOBOOT, "si%d: found type %d card, try memory test\n",
650 id->id_unit, type));
651 /* Try the acid test */
652 ux = maddr + SIRAM;
653 for (i = 0; i < ramsize; i++, ux++)
654 *ux = (BYTE)(i&0xff);
655 ux = maddr + SIRAM;
656 for (i = 0; i < ramsize; i++, ux++) {
657 if ((was = *ux) != (BYTE)(i&0xff)) {
658 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
659 "si%d: match fail at phys 0x%x, was %x should be %x\n",
660 id->id_unit, paddr + i, was, i&0xff));
661 goto fail;
662 }
663 }
664
665 /* clear out the RAM */
666 ux = maddr + SIRAM;
667 for (i = 0; i < ramsize; i++)
668 *ux++ = 0;
669 ux = maddr + SIRAM;
670 for (i = 0; i < ramsize; i++) {
671 if ((was = *ux++) != 0) {
672 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
673 "si%d: clear fail at phys 0x%x, was %x\n",
674 id->id_unit, paddr + i, was));
675 goto fail;
676 }
677 }
678
679 /*
680 * Success, we've found a valid board, now fill in
681 * the adapter structure.
682 */
683 switch (type) {
684 case SIHOST2:
685 if ((id->id_irq & (IRQ11|IRQ12|IRQ15)) == 0) {
686bad_irq:
687 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
688 "si%d: bad IRQ value - %d\n",
689 id->id_unit, id->id_irq));
690 return(0);
691 }
692 id->id_msize = SIHOST2_MEMSIZE;
693 break;
694 case SIHOST:
695 if ((id->id_irq & (IRQ11|IRQ12|IRQ15)) == 0) {
696 goto bad_irq;
697 }
698 id->id_msize = SIHOST_MEMSIZE;
699 break;
700 case SIJETISA:
701 if ((id->id_irq & (IRQ9|IRQ10|IRQ11|IRQ12|IRQ15)) == 0) {
702 goto bad_irq;
703 }
704 id->id_msize = SIJETISA_MEMSIZE;
705 break;
706 case SIMCA: /* MCA */
707 default:
708 printf("si%d: %s not supported\n", id->id_unit, si_type[type]);
709 return(0);
710 }
711 id->id_intr = (inthand2_t *)si_intr; /* set here instead of config */
712 si_softc[id->id_unit].sc_type = type;
713 si_softc[id->id_unit].sc_typename = si_type[type];
714 return(-1); /* -1 == found */
715}
716
717/*
718 * We have to make an 8 bit version of bcopy, since some cards can't
719 * deal with 32 bit I/O
720 */
721static void __inline
722si_bcopy(const void *src, void *dst, size_t len)
723{
724 while (len--)
725 *(((u_char *)dst)++) = *(((const u_char *)src)++);
726}
727static void __inline
728si_vbcopy(const volatile void *src, void *dst, size_t len)
729{
730 while (len--)
731 *(((u_char *)dst)++) = *(((const volatile u_char *)src)++);
732}
733static void __inline
734si_bcopyv(const void *src, volatile void *dst, size_t len)
735{
736 while (len--)
737 *(((volatile u_char *)dst)++) = *(((const u_char *)src)++);
738}
739
740/*
741 * Attach the device. Initialize the card.
742 *
743 * This routine also gets called by the EISA and PCI attach routines.
744 * It presumes that the softstate for the unit has had had its type field
745 * and the EISA specific stuff filled in, as well as the kernel virtual
746 * base address and the unit number of the isa_device struct.
747 */
748static int
749siattach(id)
750 struct isa_device *id;
751{
752 int unit = id->id_unit;
753 struct si_softc *sc = &si_softc[unit];
754 struct si_port *pp;
755 volatile struct si_channel *ccbp;
756 volatile struct si_reg *regp;
757 volatile caddr_t maddr;
758 struct si_module *modp;
759 struct tty *tp;
760 struct speedtab *spt;
761 int nmodule, nport, x, y;
762 int uart_type;
763
764 DPRINT((0, DBG_AUTOBOOT, "si%d: siattach\n", id->id_unit));
765
766 sc->sc_paddr = (caddr_t)vtophys(id->id_maddr);
767 sc->sc_maddr = id->id_maddr;
768 sc->sc_irq = id->id_irq;
769
770 DPRINT((0, DBG_AUTOBOOT, "si%d: type: %s paddr: %x maddr: %x\n", unit,
771 sc->sc_typename, sc->sc_paddr, sc->sc_maddr));
772
773 sc->sc_ports = NULL; /* mark as uninitialised */
774
775 maddr = sc->sc_maddr;
776
777 /* Stop the CPU first so it won't stomp around while we load */
778
779 switch (sc->sc_type) {
780#if NEISA > 0
781 case SIEISA:
782 outb(sc->sc_eisa_iobase + 2, sc->sc_eisa_irq << 4);
783 break;
784#endif
785#if NPCI > 0
786 case SIPCI:
787 *(maddr+SIPCIRESET) = 0;
788 break;
789 case SIJETPCI: /* fall through to JET ISA */
790#endif
791 case SIJETISA:
792 *(maddr+SIJETCONFIG) = 0;
793 break;
794 case SIHOST2:
795 *(maddr+SIPLRESET) = 0;
796 break;
797 case SIHOST:
798 *(maddr+SIRESET) = 0;
799 break;
800 default: /* this should never happen */
801 printf("si%d: unsupported configuration\n", unit);
802 return 0;
803 break;
804 }
805
806 /* OK, now lets download the download code */
807
808 if (SI_ISJET(sc->sc_type)) {
809 DPRINT((0, DBG_DOWNLOAD, "si%d: jet_download: nbytes %d\n",
810 id->id_unit, si3_t225_dsize));
811 si_bcopy(si3_t225_download, maddr + si3_t225_downloadaddr,
812 si3_t225_dsize);
813 DPRINT((0, DBG_DOWNLOAD,
814 "si%d: jet_bootstrap: nbytes %d -> %x\n",
815 id->id_unit, si3_t225_bsize, si3_t225_bootloadaddr));
816 si_bcopy(si3_t225_bootstrap, maddr + si3_t225_bootloadaddr,
817 si3_t225_bsize);
818 } else {
819 DPRINT((0, DBG_DOWNLOAD, "si%d: si_download: nbytes %d\n",
820 id->id_unit, si2_z280_dsize));
821 si_bcopy(si2_z280_download, maddr + si2_z280_downloadaddr,
822 si2_z280_dsize);
823 }
824
825 /* Now start the CPU */
826
827 switch (sc->sc_type) {
828#if NEISA > 0
829 case SIEISA:
830 /* modify the download code to tell it that it's on an EISA */
831 *(maddr + 0x42) = 1;
832 outb(sc->sc_eisa_iobase + 2, (sc->sc_eisa_irq << 4) | 4);
833 (void)inb(sc->sc_eisa_iobase + 3); /* reset interrupt */
834 break;
835#endif
836 case SIPCI:
837 /* modify the download code to tell it that it's on a PCI */
838 *(maddr+0x42) = 1;
839 *(maddr+SIPCIRESET) = 1;
840 *(maddr+SIPCIINTCL) = 0;
841 break;
842 case SIJETPCI:
843 *(maddr+SIJETRESET) = 0;
844 *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN;
845 break;
846 case SIJETISA:
847 *(maddr+SIJETRESET) = 0;
848 switch (sc->sc_irq) {
849 case IRQ9:
850 *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0x90;
851 break;
852 case IRQ10:
853 *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xa0;
854 break;
855 case IRQ11:
856 *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xb0;
857 break;
858 case IRQ12:
859 *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xc0;
860 break;
861 case IRQ15:
862 *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xf0;
863 break;
864 }
865 break;
866 case SIHOST:
867 *(maddr+SIRESET_CL) = 0;
868 *(maddr+SIINTCL_CL) = 0;
869 break;
870 case SIHOST2:
871 *(maddr+SIPLRESET) = 0x10;
872 switch (sc->sc_irq) {
873 case IRQ11:
874 *(maddr+SIPLIRQ11) = 0x10;
875 break;
876 case IRQ12:
877 *(maddr+SIPLIRQ12) = 0x10;
878 break;
879 case IRQ15:
880 *(maddr+SIPLIRQ15) = 0x10;
881 break;
882 }
883 *(maddr+SIPLIRQCLR) = 0x10;
884 break;
885 default: /* this should _REALLY_ never happen */
886 printf("si%d: Uh, it was supported a second ago...\n", unit);
887 return 0;
888 }
889
890 DELAY(1000000); /* wait around for a second */
891
892 regp = (struct si_reg *)maddr;
893 y = 0;
894 /* wait max of 5 sec for init OK */
895 while (regp->initstat == 0 && y++ < 10) {
896 DELAY(500000);
897 }
898 switch (regp->initstat) {
899 case 0:
900 printf("si%d: startup timeout - aborting\n", unit);
901 sc->sc_type = SIEMPTY;
902 return 0;
903 case 1:
904 if (SI_ISJET(sc->sc_type)) {
905 /* set throttle to 100 times per second */
906 regp->int_count = JET_INT_COUNT;
907 /* rx_intr_count is a NOP in Jet */
908 } else {
909 /* set throttle to 125 times per second */
910 regp->int_count = INT_COUNT;
911 /* rx intr max of 25 times per second */
912 regp->rx_int_count = RXINT_COUNT;
913 }
914 regp->int_pending = 0; /* no intr pending */
915 regp->int_scounter = 0; /* reset counter */
916 break;
917 case 0xff:
918 /*
919 * No modules found, so give up on this one.
920 */
921 printf("si%d: %s - no ports found\n", unit,
922 si_type[sc->sc_type]);
923 return 0;
924 default:
925 printf("si%d: download code version error - initstat %x\n",
926 unit, regp->initstat);
927 return 0;
928 }
929
930 /*
931 * First time around the ports just count them in order
932 * to allocate some memory.
933 */
934 nport = 0;
935 modp = (struct si_module *)(maddr + 0x80);
936 for (;;) {
937 DPRINT((0, DBG_DOWNLOAD, "si%d: ccb addr 0x%x\n", unit, modp));
938 switch (modp->sm_type) {
939 case TA4:
940 DPRINT((0, DBG_DOWNLOAD,
941 "si%d: Found old TA4 module, 4 ports\n",
942 unit));
943 x = 4;
944 break;
945 case TA8:
946 DPRINT((0, DBG_DOWNLOAD,
947 "si%d: Found old TA8 module, 8 ports\n",
948 unit));
949 x = 8;
950 break;
951 case TA4_ASIC:
952 DPRINT((0, DBG_DOWNLOAD,
953 "si%d: Found ASIC TA4 module, 4 ports\n",
954 unit));
955 x = 4;
956 break;
957 case TA8_ASIC:
958 DPRINT((0, DBG_DOWNLOAD,
959 "si%d: Found ASIC TA8 module, 8 ports\n",
960 unit));
961 x = 8;
962 break;
963 case MTA:
964 DPRINT((0, DBG_DOWNLOAD,
965 "si%d: Found CD1400 module, 8 ports\n",
966 unit));
967 x = 8;
968 break;
969 case SXDC:
970 DPRINT((0, DBG_DOWNLOAD,
971 "si%d: Found SXDC module, 8 ports\n",
972 unit));
973 x = 8;
974 break;
975 default:
976 printf("si%d: unknown module type %d\n",
977 unit, modp->sm_type);
978 goto try_next;
979 }
980
981 /* this was limited in firmware and is also a driver issue */
982 if ((nport + x) > SI_MAXPORTPERCARD) {
983 printf("si%d: extra ports ignored\n", unit);
984 goto try_next;
985 }
986
987 nport += x;
988 si_Nports += x;
989 si_Nmodules++;
990
991try_next:
992 if (modp->sm_next == 0)
993 break;
994 modp = (struct si_module *)
995 (maddr + (unsigned)(modp->sm_next & 0x7fff));
996 }
997 sc->sc_ports = (struct si_port *)malloc(sizeof(struct si_port) * nport,
998 M_DEVBUF, M_NOWAIT);
999 if (sc->sc_ports == 0) {
1000mem_fail:
1001 printf("si%d: fail to malloc memory for port structs\n",
1002 unit);
1003 return 0;
1004 }
1005 bzero(sc->sc_ports, sizeof(struct si_port) * nport);
1006 sc->sc_nport = nport;
1007
1008 /*
1009 * allocate tty structures for ports
1010 */
1011 tp = (struct tty *)malloc(sizeof(*tp) * nport, M_DEVBUF, M_NOWAIT);
1012 if (tp == 0)
1013 goto mem_fail;
1014 bzero(tp, sizeof(*tp) * nport);
1015 si__tty = tp;
1016
1017 /*
1018 * Scan round the ports again, this time initialising.
1019 */
1020 pp = sc->sc_ports;
1021 nmodule = 0;
1022 modp = (struct si_module *)(maddr + 0x80);
1023 uart_type = 1000; /* arbitary, > uchar_max */
1024 for (;;) {
1025 switch (modp->sm_type) {
1026 case TA4:
1027 nport = 4;
1028 break;
1029 case TA8:
1030 nport = 8;
1031 break;
1032 case TA4_ASIC:
1033 nport = 4;
1034 break;
1035 case TA8_ASIC:
1036 nport = 8;
1037 break;
1038 case MTA:
1039 nport = 8;
1040 break;
1041 case SXDC:
1042 nport = 8;
1043 break;
1044 default:
1045 goto try_next2;
1046 }
1047 nmodule++;
1048 ccbp = (struct si_channel *)((char *)modp + 0x100);
1049 if (uart_type == 1000)
1050 uart_type = ccbp->type;
1051 else if (uart_type != ccbp->type)
1052 printf("si%d: Warning: module %d mismatch! (%d%s != %d%s)\n",
1053 unit, nmodule,
1054 ccbp->type, si_modulename(sc->sc_type, ccbp->type),
1055 uart_type, si_modulename(sc->sc_type, uart_type));
1056
1057 for (x = 0; x < nport; x++, pp++, ccbp++) {
1058 pp->sp_ccb = ccbp; /* save the address */
1059 pp->sp_tty = tp++;
1060 pp->sp_pend = IDLE_CLOSE;
1061 pp->sp_state = 0; /* internal flag */
1062 pp->sp_dtr_wait = 3 * hz;
1063 pp->sp_iin.c_iflag = TTYDEF_IFLAG;
1064 pp->sp_iin.c_oflag = TTYDEF_OFLAG;
1065 pp->sp_iin.c_cflag = TTYDEF_CFLAG;
1066 pp->sp_iin.c_lflag = TTYDEF_LFLAG;
1067 termioschars(&pp->sp_iin);
1068 pp->sp_iin.c_ispeed = pp->sp_iin.c_ospeed =
1069 TTYDEF_SPEED;;
1070 pp->sp_iout = pp->sp_iin;
1071 }
1072try_next2:
1073 if (modp->sm_next == 0) {
1074 printf("si%d: card: %s, ports: %d, modules: %d, type: %d%s\n",
1075 unit,
1076 sc->sc_typename,
1077 sc->sc_nport,
1078 nmodule,
1079 uart_type,
1080 si_modulename(sc->sc_type, uart_type));
1081 break;
1082 }
1083 modp = (struct si_module *)
1084 (maddr + (unsigned)(modp->sm_next & 0x7fff));
1085 }
1086 if (done_chartimes == 0) {
1087 for (spt = chartimes ; spt->sp_speed != -1; spt++) {
1088 if ((spt->sp_code /= hz) == 0)
1089 spt->sp_code = 1;
1090 }
1091 done_chartimes = 1;
1092 }
1093
1094/* path name devsw minor type uid gid perm*/
1095 for (x = 0; x < sc->sc_nport; x++) {
1096 /* sync with the manuals that start at 1 */
1097 y = x + 1 + id->id_unit * (1 << SI_CARDSHIFT);
1098 make_dev(&si_cdevsw, x, 0, 0, 0600, "ttyA%02d", y);
1099 make_dev(&si_cdevsw, x + 0x00080, 0, 0, 0600, "cuaA%02d", y);
1100 make_dev(&si_cdevsw, x + 0x10000, 0, 0, 0600, "ttyiA%02d", y);
1101 make_dev(&si_cdevsw, x + 0x10080, 0, 0, 0600, "cuaiA%02d", y);
1102 make_dev(&si_cdevsw, x + 0x20000, 0, 0, 0600, "ttylA%02d", y);
1103 make_dev(&si_cdevsw, x + 0x20080, 0, 0, 0600, "cualA%02d", y);
1104 }
1105 make_dev(&si_cdevsw, 0x40000, 0, 0, 0600, "si_control");
1106 return (1);
1107}
1108
1109static int
1110siopen(dev, flag, mode, p)
1111 dev_t dev;
1112 int flag, mode;
1113 struct proc *p;
1114{
1115 int oldspl, error;
1116 int card, port;
1117 register struct si_softc *sc;
1118 register struct tty *tp;
1119 volatile struct si_channel *ccbp;
1120 struct si_port *pp;
1121 int mynor = minor(dev);
1122
1123 /* quickly let in /dev/si_control */
1124 if (IS_CONTROLDEV(mynor)) {
1125 if ((error = suser(p)))
1126 return(error);
1127 return(0);
1128 }
1129
1130 card = SI_CARD(mynor);
1131 if (card >= NSI)
1132 return (ENXIO);
1133 sc = &si_softc[card];
1134
1135 if (sc->sc_type == SIEMPTY) {
1136 DPRINT((0, DBG_OPEN|DBG_FAIL, "si%d: type %s??\n",
1137 card, sc->sc_typename));
1138 return(ENXIO);
1139 }
1140
1141 port = SI_PORT(mynor);
1142 if (port >= sc->sc_nport) {
1143 DPRINT((0, DBG_OPEN|DBG_FAIL, "si%d: nports %d\n",
1144 card, sc->sc_nport));
1145 return(ENXIO);
1146 }
1147
1148#ifdef POLL
1149 /*
1150 * We've now got a device, so start the poller.
1151 */
1152 if (init_finished == 0) {
1153 timeout(si_poll, (caddr_t)0L, si_pollrate);
1154 init_finished = 1;
1155 }
1156#endif
1157
1158 /* initial/lock device */
1159 if (IS_STATE(mynor)) {
1160 return(0);
1161 }
1162
1163 pp = sc->sc_ports + port;
1164 tp = pp->sp_tty; /* the "real" tty */
187 /* mmap */ nommap,
188 /* strategy */ nostrategy,
189 /* name */ "si",
190 /* parms */ noparms,
191 /* maj */ CDEV_MAJOR,
192 /* dump */ nodump,
193 /* psize */ nopsize,
194 /* flags */ D_TTY,
195 /* maxio */ 0,
196 /* bmaj */ -1
197};
198
199#ifdef SI_DEBUG /* use: ``options "SI_DEBUG"'' in your config file */
200
201static void si_dprintf __P((struct si_port *pp, int flags, const char *fmt,
202 ...));
203static char *si_mctl2str __P((enum si_mctl cmd));
204
205#define DPRINT(x) si_dprintf x
206
207#else
208#define DPRINT(x) /* void */
209#endif
210
211static int si_Nports;
212static int si_Nmodules;
213static int si_debug = 0; /* data, not bss, so it's patchable */
214
215SYSCTL_INT(_machdep, OID_AUTO, si_debug, CTLFLAG_RW, &si_debug, 0, "");
216
217static struct tty *si__tty;
218
219/* where the firmware lives; defined in si2_z280.c and si3_t225.c */
220/* old: si2_z280.c */
221extern unsigned char si2_z280_download[];
222extern unsigned short si2_z280_downloadaddr;
223extern int si2_z280_dsize;
224/* new: si3_t225.c */
225extern unsigned char si3_t225_download[];
226extern unsigned short si3_t225_downloadaddr;
227extern int si3_t225_dsize;
228extern unsigned char si3_t225_bootstrap[];
229extern unsigned short si3_t225_bootloadaddr;
230extern int si3_t225_bsize;
231
232
233struct si_softc {
234 int sc_type; /* adapter type */
235 char *sc_typename; /* adapter type string */
236
237 struct si_port *sc_ports; /* port structures for this card */
238
239 caddr_t sc_paddr; /* physical addr of iomem */
240 caddr_t sc_maddr; /* kvaddr of iomem */
241 int sc_nport; /* # ports on this card */
242 int sc_irq; /* copy of attach irq */
243#if NEISA > 0
244 int sc_eisa_iobase; /* EISA io port address */
245 int sc_eisa_irq; /* EISA irq number */
246#endif
247};
248static struct si_softc si_softc[NSI]; /* up to 4 elements */
249
250#ifndef B2000 /* not standard, but the hardware knows it. */
251# define B2000 2000
252#endif
253static struct speedtab bdrates[] = {
254 { B75, CLK75, }, /* 0x0 */
255 { B110, CLK110, }, /* 0x1 */
256 { B150, CLK150, }, /* 0x3 */
257 { B300, CLK300, }, /* 0x4 */
258 { B600, CLK600, }, /* 0x5 */
259 { B1200, CLK1200, }, /* 0x6 */
260 { B2000, CLK2000, }, /* 0x7 */
261 { B2400, CLK2400, }, /* 0x8 */
262 { B4800, CLK4800, }, /* 0x9 */
263 { B9600, CLK9600, }, /* 0xb */
264 { B19200, CLK19200, }, /* 0xc */
265 { B38400, CLK38400, }, /* 0x2 (out of order!) */
266 { B57600, CLK57600, }, /* 0xd */
267 { B115200, CLK110, }, /* 0x1 (dupe!, 110 baud on "si") */
268 { -1, -1 },
269};
270
271
272/* populated with approx character/sec rates - translated at card
273 * initialisation time to chars per tick of the clock */
274static int done_chartimes = 0;
275static struct speedtab chartimes[] = {
276 { B75, 8, },
277 { B110, 11, },
278 { B150, 15, },
279 { B300, 30, },
280 { B600, 60, },
281 { B1200, 120, },
282 { B2000, 200, },
283 { B2400, 240, },
284 { B4800, 480, },
285 { B9600, 960, },
286 { B19200, 1920, },
287 { B38400, 3840, },
288 { B57600, 5760, },
289 { B115200, 11520, },
290 { -1, -1 },
291};
292static volatile int in_intr = 0; /* Inside interrupt handler? */
293
294#ifdef POLL
295static int si_pollrate; /* in addition to irq */
296static int si_realpoll; /* poll HW on timer */
297
298SYSCTL_INT(_machdep, OID_AUTO, si_pollrate, CTLFLAG_RW, &si_pollrate, 0, "");
299SYSCTL_INT(_machdep, OID_AUTO, si_realpoll, CTLFLAG_RW, &si_realpoll, 0, "");
300
301static int init_finished = 0;
302static void si_poll __P((void *));
303#endif
304
305/*
306 * Array of adapter types and the corresponding RAM size. The order of
307 * entries here MUST match the ordinal of the adapter type.
308 */
309static char *si_type[] = {
310 "EMPTY",
311 "SIHOST",
312 "SIMCA", /* FreeBSD does not support Microchannel */
313 "SIHOST2",
314 "SIEISA",
315 "SIPCI",
316 "SXPCI",
317 "SXISA",
318};
319
320#if NPCI > 0
321
322static const char *
323sipciprobe(configid, deviceid)
324pcici_t configid;
325pcidi_t deviceid;
326{
327 switch (deviceid)
328 {
329 case 0x400011cb:
330 return("Specialix SI/XIO PCI host card");
331 break;
332 case 0x200011cb:
333 if (pci_conf_read(configid, SIJETSSIDREG) == 0x020011cb)
334 return("Specialix SX PCI host card");
335 else
336 return NULL;
337 break;
338 default:
339 return NULL;
340 }
341 /*NOTREACHED*/
342}
343
344void
345sipciattach(configid, unit)
346pcici_t configid;
347int unit;
348{
349 struct isa_device id;
350 vm_offset_t vaddr,paddr;
351 u_long mapval = 0; /* shut up gcc, should not be needed */
352
353 switch (pci_conf_read(configid, 0) >> 16) {
354 case 0x4000:
355 si_softc[unit].sc_type = SIPCI;
356 mapval = SIPCIBADR;
357 break;
358 case 0x2000:
359 si_softc[unit].sc_type = SIJETPCI;
360 mapval = SIJETBADR;
361 break;
362 }
363 if (!pci_map_mem(configid, mapval, &vaddr, &paddr))
364 {
365 printf("si%d: couldn't map memory\n", unit);
366 }
367
368 /*
369 * We're cheating here a little bit. The argument to an ISA
370 * interrupt routine is the unit number. The argument to a
371 * PCI interrupt handler is a void *, but we're simply going
372 * to be lazy and hand it the unit number.
373 */
374 if (!pci_map_int(configid, (pci_inthand_t *) si_intr, (void *)unit, &tty_imask)) {
375 printf("si%d: couldn't map interrupt\n", unit);
376 }
377 si_softc[unit].sc_typename = si_type[si_softc[unit].sc_type];
378
379 /*
380 * More cheating: We're going to dummy up a struct isa_device
381 * and call the other attach routine. We don't really have to
382 * fill in very much of the structure, since we filled in a
383 * little of the soft state already.
384 */
385 id.id_unit = unit;
386 id.id_maddr = (caddr_t) vaddr;
387 siattach(&id);
388}
389
390#endif
391
392#if NEISA > 0
393
394static const char *si_eisa_match __P((eisa_id_t id));
395
396static const char *
397si_eisa_match(id)
398 eisa_id_t id;
399{
400 if (id == SIEISADEVID)
401 return ("Specialix SI/XIO EISA host card");
402 return (NULL);
403}
404
405static int
406si_eisa_probe(void)
407{
408 struct eisa_device *ed = NULL;
409 int count, irq;
410
411 for (count = 0; (ed = eisa_match_dev(ed, si_eisa_match)) != NULL;
412 count++) {
413 u_long port,maddr;
414
415 port = (ed->ioconf.slot * EISA_SLOT_SIZE) + SIEISABASE;
416 eisa_add_iospace(ed, port, SIEISAIOSIZE, RESVADDR_NONE);
417 maddr = (inb(port+1) << 24) | (inb(port) << 16);
418 irq = ((inb(port+2) >> 4) & 0xf);
419 eisa_add_mspace(ed, maddr, SIEISA_MEMSIZE, RESVADDR_NONE);
420 eisa_add_intr(ed, irq);
421 eisa_registerdev(ed, &si_eisa_driver);
422 count++;
423 }
424 return count;
425}
426
427static int
428si_eisa_attach(ed)
429 struct eisa_device *ed;
430{
431 struct isa_device id;
432 resvaddr_t *maddr,*iospace;
433 u_int irq;
434 struct si_softc *sc;
435
436 sc = &si_softc[ed->unit];
437
438 sc->sc_type = SIEISA;
439 sc->sc_typename = si_type[sc->sc_type];
440
441 if ((iospace = ed->ioconf.ioaddrs.lh_first) == NULL) {
442 printf("si%lu: no iospace??\n", ed->unit);
443 return -1;
444 }
445 sc->sc_eisa_iobase = iospace->addr;
446
447 irq = ((inb(iospace->addr + 2) >> 4) & 0xf);
448 sc->sc_eisa_irq = irq;
449
450 if ((maddr = ed->ioconf.maddrs.lh_first) == NULL) {
451 printf("si%lu: where am I??\n", ed->unit);
452 return -1;
453 }
454 eisa_reg_start(ed);
455 if (eisa_reg_iospace(ed, iospace)) {
456 printf("si%lu: failed to register iospace %p\n",
457 ed->unit, (void *)iospace);
458 return -1;
459 }
460 if (eisa_reg_mspace(ed, maddr)) {
461 printf("si%lu: failed to register memspace %p\n",
462 ed->unit, (void *)maddr);
463 return -1;
464 }
465 /*
466 * We're cheating here a little bit. The argument to an ISA
467 * interrupt routine is the unit number. The argument to a
468 * EISA interrupt handler is a void *, but we're simply going
469 * to be lazy and hand it the unit number.
470 */
471 if (eisa_reg_intr(ed, irq, (void (*)(void *)) si_intr,
472 (void *)(intptr_t)(ed->unit), &tty_imask, 1)) {
473 printf("si%lu: failed to register interrupt %d\n",
474 ed->unit, irq);
475 return -1;
476 }
477 eisa_reg_end(ed);
478 if (eisa_enable_intr(ed, irq)) {
479 return -1;
480 }
481
482 /*
483 * More cheating: We're going to dummy up a struct isa_device
484 * and call the other attach routine. We don't really have to
485 * fill in very much of the structure, since we filled in a
486 * little of the soft state already.
487 */
488 id.id_unit = ed->unit;
489 id.id_maddr = (caddr_t) pmap_mapdev(maddr->addr, SIEISA_MEMSIZE);
490 return (siattach(&id));
491}
492
493#endif
494
495
496/* Look for a valid board at the given mem addr */
497static int
498siprobe(id)
499 struct isa_device *id;
500{
501 struct si_softc *sc;
502 int type;
503 u_int i, ramsize;
504 volatile BYTE was, *ux;
505 volatile unsigned char *maddr;
506 unsigned char *paddr;
507
508 si_pollrate = POLLHZ; /* default 10 per second */
509#ifdef REALPOLL
510 si_realpoll = 1; /* scan always */
511#endif
512 maddr = id->id_maddr; /* virtual address... */
513 paddr = (caddr_t)vtophys(id->id_maddr); /* physical address... */
514
515 DPRINT((0, DBG_AUTOBOOT, "si%d: probe at virtual=0x%x physical=0x%x\n",
516 id->id_unit, id->id_maddr, paddr));
517
518 /*
519 * this is a lie, but it's easier than trying to handle caching
520 * and ram conflicts in the >1M and <16M region.
521 */
522 if ((caddr_t)paddr < (caddr_t)IOM_BEGIN ||
523 (caddr_t)paddr >= (caddr_t)IOM_END) {
524 printf("si%d: iomem (%p) out of range\n",
525 id->id_unit, (void *)paddr);
526 return(0);
527 }
528
529 if (id->id_unit >= NSI) {
530 /* THIS IS IMPOSSIBLE */
531 return(0);
532 }
533
534 if (((u_int)paddr & 0x7fff) != 0) {
535 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
536 "si%d: iomem (%x) not on 32k boundary\n",
537 id->id_unit, paddr));
538 return(0);
539 }
540
541 if (si_softc[id->id_unit].sc_typename) {
542 /* EISA or PCI has taken this unit, choose another */
543 for (i = 0; i < NSI; i++) {
544 if (si_softc[i].sc_typename == NULL) {
545 id->id_unit = i;
546 break;
547 }
548 }
549 if (i >= NSI) {
550 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
551 "si%d: cannot realloc unit\n", id->id_unit));
552 return (0);
553 }
554 }
555
556 for (i = 0; i < NSI; i++) {
557 sc = &si_softc[i];
558 if ((caddr_t)sc->sc_paddr == (caddr_t)paddr) {
559 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
560 "si%d: iomem (%x) already configured to si%d\n",
561 id->id_unit, sc->sc_paddr, i));
562 return(0);
563 }
564 }
565
566 /* Is there anything out there? (0x17 is just an arbitrary number) */
567 *maddr = 0x17;
568 if (*maddr != 0x17) {
569 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
570 "si%d: 0x17 check fail at phys 0x%x\n",
571 id->id_unit, paddr));
572fail:
573 return(0);
574 }
575 /*
576 * Let's look first for a JET ISA card, since that's pretty easy
577 *
578 * All jet hosts are supposed to have this string in the IDROM,
579 * but it's not worth checking on self-IDing busses like PCI.
580 */
581 {
582 unsigned char *jet_chk_str = "JET HOST BY KEV#";
583
584 for (i = 0; i < strlen(jet_chk_str); i++)
585 if (jet_chk_str[i] != *(maddr + SIJETIDSTR + 2 * i))
586 goto try_mk2;
587 }
588 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
589 "si%d: JET first check - 0x%x\n",
590 id->id_unit, (*(maddr+SIJETIDBASE))));
591 if (*(maddr+SIJETIDBASE) != (SISPLXID&0xff))
592 goto try_mk2;
593 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
594 "si%d: JET second check - 0x%x\n",
595 id->id_unit, (*(maddr+SIJETIDBASE+2))));
596 if (*(maddr+SIJETIDBASE+2) != ((SISPLXID&0xff00)>>8))
597 goto try_mk2;
598 /* It must be a Jet ISA or RIO card */
599 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
600 "si%d: JET id check - 0x%x\n",
601 id->id_unit, (*(maddr+SIUNIQID))));
602 if ((*(maddr+SIUNIQID) & 0xf0) != 0x20)
603 goto try_mk2;
604 /* It must be a Jet ISA SI/XIO card */
605 *(maddr + SIJETCONFIG) = 0;
606 type = SIJETISA;
607 ramsize = SIJET_RAMSIZE;
608 goto got_card;
609 /*
610 * OK, now to see if whatever responded is really an SI card.
611 * Try for a MK II next (SIHOST2)
612 */
613try_mk2:
614 for (i = SIPLSIG; i < SIPLSIG + 8; i++)
615 if ((*(maddr+i) & 7) != (~(BYTE)i & 7))
616 goto try_mk1;
617
618 /* It must be an SIHOST2 */
619 *(maddr + SIPLRESET) = 0;
620 *(maddr + SIPLIRQCLR) = 0;
621 *(maddr + SIPLIRQSET) = 0x10;
622 type = SIHOST2;
623 ramsize = SIHOST2_RAMSIZE;
624 goto got_card;
625
626 /*
627 * Its not a MK II, so try for a MK I (SIHOST)
628 */
629try_mk1:
630 *(maddr+SIRESET) = 0x0; /* reset the card */
631 *(maddr+SIINTCL) = 0x0; /* clear int */
632 *(maddr+SIRAM) = 0x17;
633 if (*(maddr+SIRAM) != (BYTE)0x17)
634 goto fail;
635 *(maddr+0x7ff8) = 0x17;
636 if (*(maddr+0x7ff8) != (BYTE)0x17) {
637 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
638 "si%d: 0x17 check fail at phys 0x%x = 0x%x\n",
639 id->id_unit, paddr+0x77f8, *(maddr+0x77f8)));
640 goto fail;
641 }
642
643 /* It must be an SIHOST (maybe?) - there must be a better way XXX */
644 type = SIHOST;
645 ramsize = SIHOST_RAMSIZE;
646
647got_card:
648 DPRINT((0, DBG_AUTOBOOT, "si%d: found type %d card, try memory test\n",
649 id->id_unit, type));
650 /* Try the acid test */
651 ux = maddr + SIRAM;
652 for (i = 0; i < ramsize; i++, ux++)
653 *ux = (BYTE)(i&0xff);
654 ux = maddr + SIRAM;
655 for (i = 0; i < ramsize; i++, ux++) {
656 if ((was = *ux) != (BYTE)(i&0xff)) {
657 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
658 "si%d: match fail at phys 0x%x, was %x should be %x\n",
659 id->id_unit, paddr + i, was, i&0xff));
660 goto fail;
661 }
662 }
663
664 /* clear out the RAM */
665 ux = maddr + SIRAM;
666 for (i = 0; i < ramsize; i++)
667 *ux++ = 0;
668 ux = maddr + SIRAM;
669 for (i = 0; i < ramsize; i++) {
670 if ((was = *ux++) != 0) {
671 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
672 "si%d: clear fail at phys 0x%x, was %x\n",
673 id->id_unit, paddr + i, was));
674 goto fail;
675 }
676 }
677
678 /*
679 * Success, we've found a valid board, now fill in
680 * the adapter structure.
681 */
682 switch (type) {
683 case SIHOST2:
684 if ((id->id_irq & (IRQ11|IRQ12|IRQ15)) == 0) {
685bad_irq:
686 DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
687 "si%d: bad IRQ value - %d\n",
688 id->id_unit, id->id_irq));
689 return(0);
690 }
691 id->id_msize = SIHOST2_MEMSIZE;
692 break;
693 case SIHOST:
694 if ((id->id_irq & (IRQ11|IRQ12|IRQ15)) == 0) {
695 goto bad_irq;
696 }
697 id->id_msize = SIHOST_MEMSIZE;
698 break;
699 case SIJETISA:
700 if ((id->id_irq & (IRQ9|IRQ10|IRQ11|IRQ12|IRQ15)) == 0) {
701 goto bad_irq;
702 }
703 id->id_msize = SIJETISA_MEMSIZE;
704 break;
705 case SIMCA: /* MCA */
706 default:
707 printf("si%d: %s not supported\n", id->id_unit, si_type[type]);
708 return(0);
709 }
710 id->id_intr = (inthand2_t *)si_intr; /* set here instead of config */
711 si_softc[id->id_unit].sc_type = type;
712 si_softc[id->id_unit].sc_typename = si_type[type];
713 return(-1); /* -1 == found */
714}
715
716/*
717 * We have to make an 8 bit version of bcopy, since some cards can't
718 * deal with 32 bit I/O
719 */
720static void __inline
721si_bcopy(const void *src, void *dst, size_t len)
722{
723 while (len--)
724 *(((u_char *)dst)++) = *(((const u_char *)src)++);
725}
726static void __inline
727si_vbcopy(const volatile void *src, void *dst, size_t len)
728{
729 while (len--)
730 *(((u_char *)dst)++) = *(((const volatile u_char *)src)++);
731}
732static void __inline
733si_bcopyv(const void *src, volatile void *dst, size_t len)
734{
735 while (len--)
736 *(((volatile u_char *)dst)++) = *(((const u_char *)src)++);
737}
738
739/*
740 * Attach the device. Initialize the card.
741 *
742 * This routine also gets called by the EISA and PCI attach routines.
743 * It presumes that the softstate for the unit has had had its type field
744 * and the EISA specific stuff filled in, as well as the kernel virtual
745 * base address and the unit number of the isa_device struct.
746 */
747static int
748siattach(id)
749 struct isa_device *id;
750{
751 int unit = id->id_unit;
752 struct si_softc *sc = &si_softc[unit];
753 struct si_port *pp;
754 volatile struct si_channel *ccbp;
755 volatile struct si_reg *regp;
756 volatile caddr_t maddr;
757 struct si_module *modp;
758 struct tty *tp;
759 struct speedtab *spt;
760 int nmodule, nport, x, y;
761 int uart_type;
762
763 DPRINT((0, DBG_AUTOBOOT, "si%d: siattach\n", id->id_unit));
764
765 sc->sc_paddr = (caddr_t)vtophys(id->id_maddr);
766 sc->sc_maddr = id->id_maddr;
767 sc->sc_irq = id->id_irq;
768
769 DPRINT((0, DBG_AUTOBOOT, "si%d: type: %s paddr: %x maddr: %x\n", unit,
770 sc->sc_typename, sc->sc_paddr, sc->sc_maddr));
771
772 sc->sc_ports = NULL; /* mark as uninitialised */
773
774 maddr = sc->sc_maddr;
775
776 /* Stop the CPU first so it won't stomp around while we load */
777
778 switch (sc->sc_type) {
779#if NEISA > 0
780 case SIEISA:
781 outb(sc->sc_eisa_iobase + 2, sc->sc_eisa_irq << 4);
782 break;
783#endif
784#if NPCI > 0
785 case SIPCI:
786 *(maddr+SIPCIRESET) = 0;
787 break;
788 case SIJETPCI: /* fall through to JET ISA */
789#endif
790 case SIJETISA:
791 *(maddr+SIJETCONFIG) = 0;
792 break;
793 case SIHOST2:
794 *(maddr+SIPLRESET) = 0;
795 break;
796 case SIHOST:
797 *(maddr+SIRESET) = 0;
798 break;
799 default: /* this should never happen */
800 printf("si%d: unsupported configuration\n", unit);
801 return 0;
802 break;
803 }
804
805 /* OK, now lets download the download code */
806
807 if (SI_ISJET(sc->sc_type)) {
808 DPRINT((0, DBG_DOWNLOAD, "si%d: jet_download: nbytes %d\n",
809 id->id_unit, si3_t225_dsize));
810 si_bcopy(si3_t225_download, maddr + si3_t225_downloadaddr,
811 si3_t225_dsize);
812 DPRINT((0, DBG_DOWNLOAD,
813 "si%d: jet_bootstrap: nbytes %d -> %x\n",
814 id->id_unit, si3_t225_bsize, si3_t225_bootloadaddr));
815 si_bcopy(si3_t225_bootstrap, maddr + si3_t225_bootloadaddr,
816 si3_t225_bsize);
817 } else {
818 DPRINT((0, DBG_DOWNLOAD, "si%d: si_download: nbytes %d\n",
819 id->id_unit, si2_z280_dsize));
820 si_bcopy(si2_z280_download, maddr + si2_z280_downloadaddr,
821 si2_z280_dsize);
822 }
823
824 /* Now start the CPU */
825
826 switch (sc->sc_type) {
827#if NEISA > 0
828 case SIEISA:
829 /* modify the download code to tell it that it's on an EISA */
830 *(maddr + 0x42) = 1;
831 outb(sc->sc_eisa_iobase + 2, (sc->sc_eisa_irq << 4) | 4);
832 (void)inb(sc->sc_eisa_iobase + 3); /* reset interrupt */
833 break;
834#endif
835 case SIPCI:
836 /* modify the download code to tell it that it's on a PCI */
837 *(maddr+0x42) = 1;
838 *(maddr+SIPCIRESET) = 1;
839 *(maddr+SIPCIINTCL) = 0;
840 break;
841 case SIJETPCI:
842 *(maddr+SIJETRESET) = 0;
843 *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN;
844 break;
845 case SIJETISA:
846 *(maddr+SIJETRESET) = 0;
847 switch (sc->sc_irq) {
848 case IRQ9:
849 *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0x90;
850 break;
851 case IRQ10:
852 *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xa0;
853 break;
854 case IRQ11:
855 *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xb0;
856 break;
857 case IRQ12:
858 *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xc0;
859 break;
860 case IRQ15:
861 *(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xf0;
862 break;
863 }
864 break;
865 case SIHOST:
866 *(maddr+SIRESET_CL) = 0;
867 *(maddr+SIINTCL_CL) = 0;
868 break;
869 case SIHOST2:
870 *(maddr+SIPLRESET) = 0x10;
871 switch (sc->sc_irq) {
872 case IRQ11:
873 *(maddr+SIPLIRQ11) = 0x10;
874 break;
875 case IRQ12:
876 *(maddr+SIPLIRQ12) = 0x10;
877 break;
878 case IRQ15:
879 *(maddr+SIPLIRQ15) = 0x10;
880 break;
881 }
882 *(maddr+SIPLIRQCLR) = 0x10;
883 break;
884 default: /* this should _REALLY_ never happen */
885 printf("si%d: Uh, it was supported a second ago...\n", unit);
886 return 0;
887 }
888
889 DELAY(1000000); /* wait around for a second */
890
891 regp = (struct si_reg *)maddr;
892 y = 0;
893 /* wait max of 5 sec for init OK */
894 while (regp->initstat == 0 && y++ < 10) {
895 DELAY(500000);
896 }
897 switch (regp->initstat) {
898 case 0:
899 printf("si%d: startup timeout - aborting\n", unit);
900 sc->sc_type = SIEMPTY;
901 return 0;
902 case 1:
903 if (SI_ISJET(sc->sc_type)) {
904 /* set throttle to 100 times per second */
905 regp->int_count = JET_INT_COUNT;
906 /* rx_intr_count is a NOP in Jet */
907 } else {
908 /* set throttle to 125 times per second */
909 regp->int_count = INT_COUNT;
910 /* rx intr max of 25 times per second */
911 regp->rx_int_count = RXINT_COUNT;
912 }
913 regp->int_pending = 0; /* no intr pending */
914 regp->int_scounter = 0; /* reset counter */
915 break;
916 case 0xff:
917 /*
918 * No modules found, so give up on this one.
919 */
920 printf("si%d: %s - no ports found\n", unit,
921 si_type[sc->sc_type]);
922 return 0;
923 default:
924 printf("si%d: download code version error - initstat %x\n",
925 unit, regp->initstat);
926 return 0;
927 }
928
929 /*
930 * First time around the ports just count them in order
931 * to allocate some memory.
932 */
933 nport = 0;
934 modp = (struct si_module *)(maddr + 0x80);
935 for (;;) {
936 DPRINT((0, DBG_DOWNLOAD, "si%d: ccb addr 0x%x\n", unit, modp));
937 switch (modp->sm_type) {
938 case TA4:
939 DPRINT((0, DBG_DOWNLOAD,
940 "si%d: Found old TA4 module, 4 ports\n",
941 unit));
942 x = 4;
943 break;
944 case TA8:
945 DPRINT((0, DBG_DOWNLOAD,
946 "si%d: Found old TA8 module, 8 ports\n",
947 unit));
948 x = 8;
949 break;
950 case TA4_ASIC:
951 DPRINT((0, DBG_DOWNLOAD,
952 "si%d: Found ASIC TA4 module, 4 ports\n",
953 unit));
954 x = 4;
955 break;
956 case TA8_ASIC:
957 DPRINT((0, DBG_DOWNLOAD,
958 "si%d: Found ASIC TA8 module, 8 ports\n",
959 unit));
960 x = 8;
961 break;
962 case MTA:
963 DPRINT((0, DBG_DOWNLOAD,
964 "si%d: Found CD1400 module, 8 ports\n",
965 unit));
966 x = 8;
967 break;
968 case SXDC:
969 DPRINT((0, DBG_DOWNLOAD,
970 "si%d: Found SXDC module, 8 ports\n",
971 unit));
972 x = 8;
973 break;
974 default:
975 printf("si%d: unknown module type %d\n",
976 unit, modp->sm_type);
977 goto try_next;
978 }
979
980 /* this was limited in firmware and is also a driver issue */
981 if ((nport + x) > SI_MAXPORTPERCARD) {
982 printf("si%d: extra ports ignored\n", unit);
983 goto try_next;
984 }
985
986 nport += x;
987 si_Nports += x;
988 si_Nmodules++;
989
990try_next:
991 if (modp->sm_next == 0)
992 break;
993 modp = (struct si_module *)
994 (maddr + (unsigned)(modp->sm_next & 0x7fff));
995 }
996 sc->sc_ports = (struct si_port *)malloc(sizeof(struct si_port) * nport,
997 M_DEVBUF, M_NOWAIT);
998 if (sc->sc_ports == 0) {
999mem_fail:
1000 printf("si%d: fail to malloc memory for port structs\n",
1001 unit);
1002 return 0;
1003 }
1004 bzero(sc->sc_ports, sizeof(struct si_port) * nport);
1005 sc->sc_nport = nport;
1006
1007 /*
1008 * allocate tty structures for ports
1009 */
1010 tp = (struct tty *)malloc(sizeof(*tp) * nport, M_DEVBUF, M_NOWAIT);
1011 if (tp == 0)
1012 goto mem_fail;
1013 bzero(tp, sizeof(*tp) * nport);
1014 si__tty = tp;
1015
1016 /*
1017 * Scan round the ports again, this time initialising.
1018 */
1019 pp = sc->sc_ports;
1020 nmodule = 0;
1021 modp = (struct si_module *)(maddr + 0x80);
1022 uart_type = 1000; /* arbitary, > uchar_max */
1023 for (;;) {
1024 switch (modp->sm_type) {
1025 case TA4:
1026 nport = 4;
1027 break;
1028 case TA8:
1029 nport = 8;
1030 break;
1031 case TA4_ASIC:
1032 nport = 4;
1033 break;
1034 case TA8_ASIC:
1035 nport = 8;
1036 break;
1037 case MTA:
1038 nport = 8;
1039 break;
1040 case SXDC:
1041 nport = 8;
1042 break;
1043 default:
1044 goto try_next2;
1045 }
1046 nmodule++;
1047 ccbp = (struct si_channel *)((char *)modp + 0x100);
1048 if (uart_type == 1000)
1049 uart_type = ccbp->type;
1050 else if (uart_type != ccbp->type)
1051 printf("si%d: Warning: module %d mismatch! (%d%s != %d%s)\n",
1052 unit, nmodule,
1053 ccbp->type, si_modulename(sc->sc_type, ccbp->type),
1054 uart_type, si_modulename(sc->sc_type, uart_type));
1055
1056 for (x = 0; x < nport; x++, pp++, ccbp++) {
1057 pp->sp_ccb = ccbp; /* save the address */
1058 pp->sp_tty = tp++;
1059 pp->sp_pend = IDLE_CLOSE;
1060 pp->sp_state = 0; /* internal flag */
1061 pp->sp_dtr_wait = 3 * hz;
1062 pp->sp_iin.c_iflag = TTYDEF_IFLAG;
1063 pp->sp_iin.c_oflag = TTYDEF_OFLAG;
1064 pp->sp_iin.c_cflag = TTYDEF_CFLAG;
1065 pp->sp_iin.c_lflag = TTYDEF_LFLAG;
1066 termioschars(&pp->sp_iin);
1067 pp->sp_iin.c_ispeed = pp->sp_iin.c_ospeed =
1068 TTYDEF_SPEED;;
1069 pp->sp_iout = pp->sp_iin;
1070 }
1071try_next2:
1072 if (modp->sm_next == 0) {
1073 printf("si%d: card: %s, ports: %d, modules: %d, type: %d%s\n",
1074 unit,
1075 sc->sc_typename,
1076 sc->sc_nport,
1077 nmodule,
1078 uart_type,
1079 si_modulename(sc->sc_type, uart_type));
1080 break;
1081 }
1082 modp = (struct si_module *)
1083 (maddr + (unsigned)(modp->sm_next & 0x7fff));
1084 }
1085 if (done_chartimes == 0) {
1086 for (spt = chartimes ; spt->sp_speed != -1; spt++) {
1087 if ((spt->sp_code /= hz) == 0)
1088 spt->sp_code = 1;
1089 }
1090 done_chartimes = 1;
1091 }
1092
1093/* path name devsw minor type uid gid perm*/
1094 for (x = 0; x < sc->sc_nport; x++) {
1095 /* sync with the manuals that start at 1 */
1096 y = x + 1 + id->id_unit * (1 << SI_CARDSHIFT);
1097 make_dev(&si_cdevsw, x, 0, 0, 0600, "ttyA%02d", y);
1098 make_dev(&si_cdevsw, x + 0x00080, 0, 0, 0600, "cuaA%02d", y);
1099 make_dev(&si_cdevsw, x + 0x10000, 0, 0, 0600, "ttyiA%02d", y);
1100 make_dev(&si_cdevsw, x + 0x10080, 0, 0, 0600, "cuaiA%02d", y);
1101 make_dev(&si_cdevsw, x + 0x20000, 0, 0, 0600, "ttylA%02d", y);
1102 make_dev(&si_cdevsw, x + 0x20080, 0, 0, 0600, "cualA%02d", y);
1103 }
1104 make_dev(&si_cdevsw, 0x40000, 0, 0, 0600, "si_control");
1105 return (1);
1106}
1107
1108static int
1109siopen(dev, flag, mode, p)
1110 dev_t dev;
1111 int flag, mode;
1112 struct proc *p;
1113{
1114 int oldspl, error;
1115 int card, port;
1116 register struct si_softc *sc;
1117 register struct tty *tp;
1118 volatile struct si_channel *ccbp;
1119 struct si_port *pp;
1120 int mynor = minor(dev);
1121
1122 /* quickly let in /dev/si_control */
1123 if (IS_CONTROLDEV(mynor)) {
1124 if ((error = suser(p)))
1125 return(error);
1126 return(0);
1127 }
1128
1129 card = SI_CARD(mynor);
1130 if (card >= NSI)
1131 return (ENXIO);
1132 sc = &si_softc[card];
1133
1134 if (sc->sc_type == SIEMPTY) {
1135 DPRINT((0, DBG_OPEN|DBG_FAIL, "si%d: type %s??\n",
1136 card, sc->sc_typename));
1137 return(ENXIO);
1138 }
1139
1140 port = SI_PORT(mynor);
1141 if (port >= sc->sc_nport) {
1142 DPRINT((0, DBG_OPEN|DBG_FAIL, "si%d: nports %d\n",
1143 card, sc->sc_nport));
1144 return(ENXIO);
1145 }
1146
1147#ifdef POLL
1148 /*
1149 * We've now got a device, so start the poller.
1150 */
1151 if (init_finished == 0) {
1152 timeout(si_poll, (caddr_t)0L, si_pollrate);
1153 init_finished = 1;
1154 }
1155#endif
1156
1157 /* initial/lock device */
1158 if (IS_STATE(mynor)) {
1159 return(0);
1160 }
1161
1162 pp = sc->sc_ports + port;
1163 tp = pp->sp_tty; /* the "real" tty */
1164 dev->si_tty = tp;
1165 ccbp = pp->sp_ccb; /* Find control block */
1166 DPRINT((pp, DBG_ENTRY|DBG_OPEN, "siopen(%s,%x,%x,%x)\n",
1167 devtoname(dev), flag, mode, p));
1168
1169 oldspl = spltty(); /* Keep others out */
1170 error = 0;
1171
1172open_top:
1173 while (pp->sp_state & SS_DTR_OFF) {
1174 error = tsleep(&pp->sp_dtr_wait, TTIPRI|PCATCH, "sidtr", 0);
1175 if (error != 0)
1176 goto out;
1177 }
1178
1179 if (tp->t_state & TS_ISOPEN) {
1180 /*
1181 * The device is open, so everything has been initialised.
1182 * handle conflicts.
1183 */
1184 if (IS_CALLOUT(mynor)) {
1185 if (!pp->sp_active_out) {
1186 error = EBUSY;
1187 goto out;
1188 }
1189 } else {
1190 if (pp->sp_active_out) {
1191 if (flag & O_NONBLOCK) {
1192 error = EBUSY;
1193 goto out;
1194 }
1195 error = tsleep(&pp->sp_active_out,
1196 TTIPRI|PCATCH, "sibi", 0);
1197 if (error != 0)
1198 goto out;
1199 goto open_top;
1200 }
1201 }
1202 if (tp->t_state & TS_XCLUDE &&
1203 suser(p)) {
1204 DPRINT((pp, DBG_OPEN|DBG_FAIL,
1205 "already open and EXCLUSIVE set\n"));
1206 error = EBUSY;
1207 goto out;
1208 }
1209 } else {
1210 /*
1211 * The device isn't open, so there are no conflicts.
1212 * Initialize it. Avoid sleep... :-)
1213 */
1214 DPRINT((pp, DBG_OPEN, "first open\n"));
1215 tp->t_oproc = si_start;
1165 ccbp = pp->sp_ccb; /* Find control block */
1166 DPRINT((pp, DBG_ENTRY|DBG_OPEN, "siopen(%s,%x,%x,%x)\n",
1167 devtoname(dev), flag, mode, p));
1168
1169 oldspl = spltty(); /* Keep others out */
1170 error = 0;
1171
1172open_top:
1173 while (pp->sp_state & SS_DTR_OFF) {
1174 error = tsleep(&pp->sp_dtr_wait, TTIPRI|PCATCH, "sidtr", 0);
1175 if (error != 0)
1176 goto out;
1177 }
1178
1179 if (tp->t_state & TS_ISOPEN) {
1180 /*
1181 * The device is open, so everything has been initialised.
1182 * handle conflicts.
1183 */
1184 if (IS_CALLOUT(mynor)) {
1185 if (!pp->sp_active_out) {
1186 error = EBUSY;
1187 goto out;
1188 }
1189 } else {
1190 if (pp->sp_active_out) {
1191 if (flag & O_NONBLOCK) {
1192 error = EBUSY;
1193 goto out;
1194 }
1195 error = tsleep(&pp->sp_active_out,
1196 TTIPRI|PCATCH, "sibi", 0);
1197 if (error != 0)
1198 goto out;
1199 goto open_top;
1200 }
1201 }
1202 if (tp->t_state & TS_XCLUDE &&
1203 suser(p)) {
1204 DPRINT((pp, DBG_OPEN|DBG_FAIL,
1205 "already open and EXCLUSIVE set\n"));
1206 error = EBUSY;
1207 goto out;
1208 }
1209 } else {
1210 /*
1211 * The device isn't open, so there are no conflicts.
1212 * Initialize it. Avoid sleep... :-)
1213 */
1214 DPRINT((pp, DBG_OPEN, "first open\n"));
1215 tp->t_oproc = si_start;
1216 tp->t_stop = si_stop;
1216 tp->t_param = siparam;
1217 tp->t_dev = dev;
1218 tp->t_termios = mynor & SI_CALLOUT_MASK
1219 ? pp->sp_iout : pp->sp_iin;
1220
1221 (void) si_modem(pp, SET, TIOCM_DTR|TIOCM_RTS);
1222
1223 ++pp->sp_wopeners; /* in case of sleep in siparam */
1224
1225 error = siparam(tp, &tp->t_termios);
1226
1227 --pp->sp_wopeners;
1228 if (error != 0)
1229 goto out;
1230 /* XXX: we should goto_top if siparam slept */
1231
1232 /* set initial DCD state */
1233 pp->sp_last_hi_ip = ccbp->hi_ip;
1234 if ((pp->sp_last_hi_ip & IP_DCD) || IS_CALLOUT(mynor)) {
1235 (*linesw[tp->t_line].l_modem)(tp, 1);
1236 }
1237 }
1238
1239 /* whoops! we beat the close! */
1240 if (pp->sp_state & SS_CLOSING) {
1241 /* try and stop it from proceeding to bash the hardware */
1242 pp->sp_state &= ~SS_CLOSING;
1243 }
1244
1245 /*
1246 * Wait for DCD if necessary
1247 */
1248 if (!(tp->t_state & TS_CARR_ON) &&
1249 !IS_CALLOUT(mynor) &&
1250 !(tp->t_cflag & CLOCAL) &&
1251 !(flag & O_NONBLOCK)) {
1252 ++pp->sp_wopeners;
1253 DPRINT((pp, DBG_OPEN, "sleeping for carrier\n"));
1254 error = tsleep(TSA_CARR_ON(tp), TTIPRI|PCATCH, "sidcd", 0);
1255 --pp->sp_wopeners;
1256 if (error != 0)
1257 goto out;
1258 goto open_top;
1259 }
1260
1261 error = (*linesw[tp->t_line].l_open)(dev, tp);
1262 si_disc_optim(tp, &tp->t_termios, pp);
1263 if (tp->t_state & TS_ISOPEN && IS_CALLOUT(mynor))
1264 pp->sp_active_out = TRUE;
1265
1266 pp->sp_state |= SS_OPEN; /* made it! */
1267
1268out:
1269 splx(oldspl);
1270
1271 DPRINT((pp, DBG_OPEN, "leaving siopen\n"));
1272
1273 if (!(tp->t_state & TS_ISOPEN) && pp->sp_wopeners == 0)
1274 sihardclose(pp);
1275
1276 return(error);
1277}
1278
1279static int
1280siclose(dev, flag, mode, p)
1281 dev_t dev;
1282 int flag, mode;
1283 struct proc *p;
1284{
1285 register struct si_port *pp;
1286 register struct tty *tp;
1287 int oldspl;
1288 int error = 0;
1289 int mynor = minor(dev);
1290
1291 if (IS_SPECIAL(mynor))
1292 return(0);
1293
1294 oldspl = spltty();
1295
1296 pp = MINOR2PP(mynor);
1297 tp = pp->sp_tty;
1298
1299 DPRINT((pp, DBG_ENTRY|DBG_CLOSE, "siclose(%s,%x,%x,%x) sp_state:%x\n",
1300 devtoname(dev), flag, mode, p, pp->sp_state));
1301
1302 /* did we sleep and loose a race? */
1303 if (pp->sp_state & SS_CLOSING) {
1304 /* error = ESOMETING? */
1305 goto out;
1306 }
1307
1308 /* begin race detection.. */
1309 pp->sp_state |= SS_CLOSING;
1310
1311 si_write_enable(pp, 0); /* block writes for ttywait() */
1312
1313 /* THIS MAY SLEEP IN TTYWAIT!!! */
1314 (*linesw[tp->t_line].l_close)(tp, flag);
1315
1316 si_write_enable(pp, 1);
1317
1318 /* did we sleep and somebody started another open? */
1319 if (!(pp->sp_state & SS_CLOSING)) {
1320 /* error = ESOMETING? */
1321 goto out;
1322 }
1323 /* ok. we are now still on the right track.. nuke the hardware */
1324
1325 if (pp->sp_state & SS_LSTART) {
1326 untimeout(si_lstart, (caddr_t)pp, pp->lstart_ch);
1327 pp->sp_state &= ~SS_LSTART;
1328 }
1329
1217 tp->t_param = siparam;
1218 tp->t_dev = dev;
1219 tp->t_termios = mynor & SI_CALLOUT_MASK
1220 ? pp->sp_iout : pp->sp_iin;
1221
1222 (void) si_modem(pp, SET, TIOCM_DTR|TIOCM_RTS);
1223
1224 ++pp->sp_wopeners; /* in case of sleep in siparam */
1225
1226 error = siparam(tp, &tp->t_termios);
1227
1228 --pp->sp_wopeners;
1229 if (error != 0)
1230 goto out;
1231 /* XXX: we should goto_top if siparam slept */
1232
1233 /* set initial DCD state */
1234 pp->sp_last_hi_ip = ccbp->hi_ip;
1235 if ((pp->sp_last_hi_ip & IP_DCD) || IS_CALLOUT(mynor)) {
1236 (*linesw[tp->t_line].l_modem)(tp, 1);
1237 }
1238 }
1239
1240 /* whoops! we beat the close! */
1241 if (pp->sp_state & SS_CLOSING) {
1242 /* try and stop it from proceeding to bash the hardware */
1243 pp->sp_state &= ~SS_CLOSING;
1244 }
1245
1246 /*
1247 * Wait for DCD if necessary
1248 */
1249 if (!(tp->t_state & TS_CARR_ON) &&
1250 !IS_CALLOUT(mynor) &&
1251 !(tp->t_cflag & CLOCAL) &&
1252 !(flag & O_NONBLOCK)) {
1253 ++pp->sp_wopeners;
1254 DPRINT((pp, DBG_OPEN, "sleeping for carrier\n"));
1255 error = tsleep(TSA_CARR_ON(tp), TTIPRI|PCATCH, "sidcd", 0);
1256 --pp->sp_wopeners;
1257 if (error != 0)
1258 goto out;
1259 goto open_top;
1260 }
1261
1262 error = (*linesw[tp->t_line].l_open)(dev, tp);
1263 si_disc_optim(tp, &tp->t_termios, pp);
1264 if (tp->t_state & TS_ISOPEN && IS_CALLOUT(mynor))
1265 pp->sp_active_out = TRUE;
1266
1267 pp->sp_state |= SS_OPEN; /* made it! */
1268
1269out:
1270 splx(oldspl);
1271
1272 DPRINT((pp, DBG_OPEN, "leaving siopen\n"));
1273
1274 if (!(tp->t_state & TS_ISOPEN) && pp->sp_wopeners == 0)
1275 sihardclose(pp);
1276
1277 return(error);
1278}
1279
1280static int
1281siclose(dev, flag, mode, p)
1282 dev_t dev;
1283 int flag, mode;
1284 struct proc *p;
1285{
1286 register struct si_port *pp;
1287 register struct tty *tp;
1288 int oldspl;
1289 int error = 0;
1290 int mynor = minor(dev);
1291
1292 if (IS_SPECIAL(mynor))
1293 return(0);
1294
1295 oldspl = spltty();
1296
1297 pp = MINOR2PP(mynor);
1298 tp = pp->sp_tty;
1299
1300 DPRINT((pp, DBG_ENTRY|DBG_CLOSE, "siclose(%s,%x,%x,%x) sp_state:%x\n",
1301 devtoname(dev), flag, mode, p, pp->sp_state));
1302
1303 /* did we sleep and loose a race? */
1304 if (pp->sp_state & SS_CLOSING) {
1305 /* error = ESOMETING? */
1306 goto out;
1307 }
1308
1309 /* begin race detection.. */
1310 pp->sp_state |= SS_CLOSING;
1311
1312 si_write_enable(pp, 0); /* block writes for ttywait() */
1313
1314 /* THIS MAY SLEEP IN TTYWAIT!!! */
1315 (*linesw[tp->t_line].l_close)(tp, flag);
1316
1317 si_write_enable(pp, 1);
1318
1319 /* did we sleep and somebody started another open? */
1320 if (!(pp->sp_state & SS_CLOSING)) {
1321 /* error = ESOMETING? */
1322 goto out;
1323 }
1324 /* ok. we are now still on the right track.. nuke the hardware */
1325
1326 if (pp->sp_state & SS_LSTART) {
1327 untimeout(si_lstart, (caddr_t)pp, pp->lstart_ch);
1328 pp->sp_state &= ~SS_LSTART;
1329 }
1330
1330 sistop(tp, FREAD | FWRITE);
1331 si_stop(tp, FREAD | FWRITE);
1331
1332 sihardclose(pp);
1333 ttyclose(tp);
1334 pp->sp_state &= ~SS_OPEN;
1335
1336out:
1337 DPRINT((pp, DBG_CLOSE|DBG_EXIT, "close done, returning\n"));
1338 splx(oldspl);
1339 return(error);
1340}
1341
1342static void
1343sihardclose(pp)
1344 struct si_port *pp;
1345{
1346 int oldspl;
1347 struct tty *tp;
1348 volatile struct si_channel *ccbp;
1349
1350 oldspl = spltty();
1351
1352 tp = pp->sp_tty;
1353 ccbp = pp->sp_ccb; /* Find control block */
1354 if (tp->t_cflag & HUPCL ||
1355 (!pp->sp_active_out &&
1356 !(ccbp->hi_ip & IP_DCD) &&
1357 !(pp->sp_iin.c_cflag && CLOCAL)) ||
1358 !(tp->t_state & TS_ISOPEN)) {
1359
1360 (void) si_modem(pp, BIC, TIOCM_DTR|TIOCM_RTS);
1361 (void) si_command(pp, FCLOSE, SI_NOWAIT);
1362
1363 if (pp->sp_dtr_wait != 0) {
1364 timeout(sidtrwakeup, pp, pp->sp_dtr_wait);
1365 pp->sp_state |= SS_DTR_OFF;
1366 }
1367
1368 }
1369 pp->sp_active_out = FALSE;
1370 wakeup((caddr_t)&pp->sp_active_out);
1371 wakeup(TSA_CARR_ON(tp));
1372
1373 splx(oldspl);
1374}
1375
1376
1377/*
1378 * called at splsoftclock()...
1379 */
1380static void
1381sidtrwakeup(chan)
1382 void *chan;
1383{
1384 struct si_port *pp;
1385 int oldspl;
1386
1387 oldspl = spltty();
1388
1389 pp = (struct si_port *)chan;
1390 pp->sp_state &= ~SS_DTR_OFF;
1391 wakeup(&pp->sp_dtr_wait);
1392
1393 splx(oldspl);
1394}
1395
1396/*
1397 * User level stuff - read and write
1398 */
1399static int
1400siread(dev, uio, flag)
1401 register dev_t dev;
1402 struct uio *uio;
1403 int flag;
1404{
1405 register struct tty *tp;
1406 int mynor = minor(dev);
1407
1408 if (IS_SPECIAL(mynor)) {
1409 DPRINT((0, DBG_ENTRY|DBG_FAIL|DBG_READ, "siread(CONTROLDEV!!)\n"));
1410 return(ENODEV);
1411 }
1412 tp = MINOR2TP(mynor);
1413 DPRINT((TP2PP(tp), DBG_ENTRY|DBG_READ,
1414 "siread(%s,%x,%x)\n", devtoname(dev), uio, flag));
1415 return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
1416}
1417
1418
1419static int
1420siwrite(dev, uio, flag)
1421 dev_t dev;
1422 struct uio *uio;
1423 int flag;
1424{
1425 register struct si_port *pp;
1426 register struct tty *tp;
1427 int error = 0;
1428 int mynor = minor(dev);
1429 int oldspl;
1430
1431 if (IS_SPECIAL(mynor)) {
1432 DPRINT((0, DBG_ENTRY|DBG_FAIL|DBG_WRITE, "siwrite(CONTROLDEV!!)\n"));
1433 return(ENODEV);
1434 }
1435 pp = MINOR2PP(mynor);
1436 tp = pp->sp_tty;
1437 DPRINT((pp, DBG_WRITE, "siwrite(%s,%x,%x)\n", devtoname(dev), uio, flag));
1438
1439 oldspl = spltty();
1440 /*
1441 * If writes are currently blocked, wait on the "real" tty
1442 */
1443 while (pp->sp_state & SS_BLOCKWRITE) {
1444 pp->sp_state |= SS_WAITWRITE;
1445 DPRINT((pp, DBG_WRITE, "in siwrite, wait for SS_BLOCKWRITE to clear\n"));
1446 if ((error = ttysleep(tp, (caddr_t)pp, TTOPRI|PCATCH,
1447 "siwrite", tp->t_timeout))) {
1448 if (error == EWOULDBLOCK)
1449 error = EIO;
1450 goto out;
1451 }
1452 }
1453
1454 error = (*linesw[tp->t_line].l_write)(tp, uio, flag);
1455out:
1456 splx(oldspl);
1457 return (error);
1458}
1459
1460
1332
1333 sihardclose(pp);
1334 ttyclose(tp);
1335 pp->sp_state &= ~SS_OPEN;
1336
1337out:
1338 DPRINT((pp, DBG_CLOSE|DBG_EXIT, "close done, returning\n"));
1339 splx(oldspl);
1340 return(error);
1341}
1342
1343static void
1344sihardclose(pp)
1345 struct si_port *pp;
1346{
1347 int oldspl;
1348 struct tty *tp;
1349 volatile struct si_channel *ccbp;
1350
1351 oldspl = spltty();
1352
1353 tp = pp->sp_tty;
1354 ccbp = pp->sp_ccb; /* Find control block */
1355 if (tp->t_cflag & HUPCL ||
1356 (!pp->sp_active_out &&
1357 !(ccbp->hi_ip & IP_DCD) &&
1358 !(pp->sp_iin.c_cflag && CLOCAL)) ||
1359 !(tp->t_state & TS_ISOPEN)) {
1360
1361 (void) si_modem(pp, BIC, TIOCM_DTR|TIOCM_RTS);
1362 (void) si_command(pp, FCLOSE, SI_NOWAIT);
1363
1364 if (pp->sp_dtr_wait != 0) {
1365 timeout(sidtrwakeup, pp, pp->sp_dtr_wait);
1366 pp->sp_state |= SS_DTR_OFF;
1367 }
1368
1369 }
1370 pp->sp_active_out = FALSE;
1371 wakeup((caddr_t)&pp->sp_active_out);
1372 wakeup(TSA_CARR_ON(tp));
1373
1374 splx(oldspl);
1375}
1376
1377
1378/*
1379 * called at splsoftclock()...
1380 */
1381static void
1382sidtrwakeup(chan)
1383 void *chan;
1384{
1385 struct si_port *pp;
1386 int oldspl;
1387
1388 oldspl = spltty();
1389
1390 pp = (struct si_port *)chan;
1391 pp->sp_state &= ~SS_DTR_OFF;
1392 wakeup(&pp->sp_dtr_wait);
1393
1394 splx(oldspl);
1395}
1396
1397/*
1398 * User level stuff - read and write
1399 */
1400static int
1401siread(dev, uio, flag)
1402 register dev_t dev;
1403 struct uio *uio;
1404 int flag;
1405{
1406 register struct tty *tp;
1407 int mynor = minor(dev);
1408
1409 if (IS_SPECIAL(mynor)) {
1410 DPRINT((0, DBG_ENTRY|DBG_FAIL|DBG_READ, "siread(CONTROLDEV!!)\n"));
1411 return(ENODEV);
1412 }
1413 tp = MINOR2TP(mynor);
1414 DPRINT((TP2PP(tp), DBG_ENTRY|DBG_READ,
1415 "siread(%s,%x,%x)\n", devtoname(dev), uio, flag));
1416 return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
1417}
1418
1419
1420static int
1421siwrite(dev, uio, flag)
1422 dev_t dev;
1423 struct uio *uio;
1424 int flag;
1425{
1426 register struct si_port *pp;
1427 register struct tty *tp;
1428 int error = 0;
1429 int mynor = minor(dev);
1430 int oldspl;
1431
1432 if (IS_SPECIAL(mynor)) {
1433 DPRINT((0, DBG_ENTRY|DBG_FAIL|DBG_WRITE, "siwrite(CONTROLDEV!!)\n"));
1434 return(ENODEV);
1435 }
1436 pp = MINOR2PP(mynor);
1437 tp = pp->sp_tty;
1438 DPRINT((pp, DBG_WRITE, "siwrite(%s,%x,%x)\n", devtoname(dev), uio, flag));
1439
1440 oldspl = spltty();
1441 /*
1442 * If writes are currently blocked, wait on the "real" tty
1443 */
1444 while (pp->sp_state & SS_BLOCKWRITE) {
1445 pp->sp_state |= SS_WAITWRITE;
1446 DPRINT((pp, DBG_WRITE, "in siwrite, wait for SS_BLOCKWRITE to clear\n"));
1447 if ((error = ttysleep(tp, (caddr_t)pp, TTOPRI|PCATCH,
1448 "siwrite", tp->t_timeout))) {
1449 if (error == EWOULDBLOCK)
1450 error = EIO;
1451 goto out;
1452 }
1453 }
1454
1455 error = (*linesw[tp->t_line].l_write)(tp, uio, flag);
1456out:
1457 splx(oldspl);
1458 return (error);
1459}
1460
1461
1461static struct tty *
1462sidevtotty(dev_t dev)
1463{
1464 struct si_port *pp;
1465 int mynor = minor(dev);
1466 struct si_softc *sc = &si_softc[SI_CARD(mynor)];
1467
1468 if (IS_SPECIAL(mynor))
1469 return(NULL);
1470 if (SI_PORT(mynor) >= sc->sc_nport)
1471 return(NULL);
1472 pp = MINOR2PP(mynor);
1473 return (pp->sp_tty);
1474}
1475
1476static int
1477siioctl(dev, cmd, data, flag, p)
1478 dev_t dev;
1479 u_long cmd;
1480 caddr_t data;
1481 int flag;
1482 struct proc *p;
1483{
1484 struct si_port *pp;
1485 register struct tty *tp;
1486 int error;
1487 int mynor = minor(dev);
1488 int oldspl;
1489 int blocked = 0;
1490#if defined(COMPAT_43)
1491 u_long oldcmd;
1492 struct termios term;
1493#endif
1494
1495 if (IS_SI_IOCTL(cmd))
1496 return(si_Sioctl(dev, cmd, data, flag, p));
1497
1498 pp = MINOR2PP(mynor);
1499 tp = pp->sp_tty;
1500
1501 DPRINT((pp, DBG_ENTRY|DBG_IOCTL, "siioctl(%s,%lx,%x,%x)\n",
1502 devtoname(dev), cmd, data, flag));
1503 if (IS_STATE(mynor)) {
1504 struct termios *ct;
1505
1506 switch (mynor & SI_STATE_MASK) {
1507 case SI_INIT_STATE_MASK:
1508 ct = IS_CALLOUT(mynor) ? &pp->sp_iout : &pp->sp_iin;
1509 break;
1510 case SI_LOCK_STATE_MASK:
1511 ct = IS_CALLOUT(mynor) ? &pp->sp_lout : &pp->sp_lin;
1512 break;
1513 default:
1514 return (ENODEV);
1515 }
1516 switch (cmd) {
1517 case TIOCSETA:
1518 error = suser(p);
1519 if (error != 0)
1520 return (error);
1521 *ct = *(struct termios *)data;
1522 return (0);
1523 case TIOCGETA:
1524 *(struct termios *)data = *ct;
1525 return (0);
1526 case TIOCGETD:
1527 *(int *)data = TTYDISC;
1528 return (0);
1529 case TIOCGWINSZ:
1530 bzero(data, sizeof(struct winsize));
1531 return (0);
1532 default:
1533 return (ENOTTY);
1534 }
1535 }
1536 /*
1537 * Do the old-style ioctl compat routines...
1538 */
1539#if defined(COMPAT_43)
1540 term = tp->t_termios;
1541 oldcmd = cmd;
1542 error = ttsetcompat(tp, &cmd, data, &term);
1543 if (error != 0)
1544 return (error);
1545 if (cmd != oldcmd)
1546 data = (caddr_t)&term;
1547#endif
1548 /*
1549 * Do the initial / lock state business
1550 */
1551 if (cmd == TIOCSETA || cmd == TIOCSETAW || cmd == TIOCSETAF) {
1552 int cc;
1553 struct termios *dt = (struct termios *)data;
1554 struct termios *lt = mynor & SI_CALLOUT_MASK
1555 ? &pp->sp_lout : &pp->sp_lin;
1556
1557 dt->c_iflag = (tp->t_iflag & lt->c_iflag) |
1558 (dt->c_iflag & ~lt->c_iflag);
1559 dt->c_oflag = (tp->t_oflag & lt->c_oflag) |
1560 (dt->c_oflag & ~lt->c_oflag);
1561 dt->c_cflag = (tp->t_cflag & lt->c_cflag) |
1562 (dt->c_cflag & ~lt->c_cflag);
1563 dt->c_lflag = (tp->t_lflag & lt->c_lflag) |
1564 (dt->c_lflag & ~lt->c_lflag);
1565 for (cc = 0; cc < NCCS; ++cc)
1566 if (lt->c_cc[cc] != 0)
1567 dt->c_cc[cc] = tp->t_cc[cc];
1568 if (lt->c_ispeed != 0)
1569 dt->c_ispeed = tp->t_ispeed;
1570 if (lt->c_ospeed != 0)
1571 dt->c_ospeed = tp->t_ospeed;
1572 }
1573
1574 /*
1575 * Block user-level writes to give the ttywait()
1576 * a chance to completely drain for commands
1577 * that require the port to be in a quiescent state.
1578 */
1579 switch (cmd) {
1580 case TIOCSETAW:
1581 case TIOCSETAF:
1582 case TIOCDRAIN:
1583#ifdef COMPAT_43
1584 case TIOCSETP:
1585#endif
1586 blocked++; /* block writes for ttywait() and siparam() */
1587 si_write_enable(pp, 0);
1588 }
1589
1590 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
1591 if (error != ENOIOCTL)
1592 goto out;
1593
1594 oldspl = spltty();
1595
1596 error = ttioctl(tp, cmd, data, flag);
1597 si_disc_optim(tp, &tp->t_termios, pp);
1598 if (error != ENOIOCTL) {
1599 splx(oldspl);
1600 goto out;
1601 }
1602
1603 error = 0;
1604 switch (cmd) {
1605 case TIOCSBRK:
1606 si_command(pp, SBREAK, SI_WAIT);
1607 break;
1608 case TIOCCBRK:
1609 si_command(pp, EBREAK, SI_WAIT);
1610 break;
1611 case TIOCSDTR:
1612 (void) si_modem(pp, SET, TIOCM_DTR|TIOCM_RTS);
1613 break;
1614 case TIOCCDTR:
1615 (void) si_modem(pp, SET, 0);
1616 break;
1617 case TIOCMSET:
1618 (void) si_modem(pp, SET, *(int *)data);
1619 break;
1620 case TIOCMBIS:
1621 (void) si_modem(pp, BIS, *(int *)data);
1622 break;
1623 case TIOCMBIC:
1624 (void) si_modem(pp, BIC, *(int *)data);
1625 break;
1626 case TIOCMGET:
1627 *(int *)data = si_modem(pp, GET, 0);
1628 break;
1629 case TIOCMSDTRWAIT:
1630 /* must be root since the wait applies to following logins */
1631 error = suser(p);
1632 if (error == 0)
1633 pp->sp_dtr_wait = *(int *)data * hz / 100;
1634 break;
1635 case TIOCMGDTRWAIT:
1636 *(int *)data = pp->sp_dtr_wait * 100 / hz;
1637 break;
1638 default:
1639 error = ENOTTY;
1640 }
1641 splx(oldspl);
1642
1643out:
1644 DPRINT((pp, DBG_IOCTL|DBG_EXIT, "siioctl ret %d\n", error));
1645 if (blocked)
1646 si_write_enable(pp, 1);
1647 return(error);
1648}
1649
1650/*
1651 * Handle the Specialix ioctls. All MUST be called via the CONTROL device
1652 */
1653static int
1654si_Sioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
1655{
1656 struct si_softc *xsc;
1657 register struct si_port *xpp;
1658 volatile struct si_reg *regp;
1659 struct si_tcsi *dp;
1660 struct si_pstat *sps;
1661 int *ip, error = 0;
1662 int oldspl;
1663 int card, port;
1664 int mynor = minor(dev);
1665
1666 DPRINT((0, DBG_ENTRY|DBG_IOCTL, "si_Sioctl(%s,%lx,%x,%x)\n",
1667 devtoname(dev), cmd, data, flag));
1668
1669#if 1
1670 DPRINT((0, DBG_IOCTL, "TCSI_PORT=%x\n", TCSI_PORT));
1671 DPRINT((0, DBG_IOCTL, "TCSI_CCB=%x\n", TCSI_CCB));
1672 DPRINT((0, DBG_IOCTL, "TCSI_TTY=%x\n", TCSI_TTY));
1673#endif
1674
1675 if (!IS_CONTROLDEV(mynor)) {
1676 DPRINT((0, DBG_IOCTL|DBG_FAIL, "not called from control device!\n"));
1677 return(ENODEV);
1678 }
1679
1680 oldspl = spltty(); /* better safe than sorry */
1681
1682 ip = (int *)data;
1683
1684#define SUCHECK if ((error = suser(p))) goto out
1685
1686 switch (cmd) {
1687 case TCSIPORTS:
1688 *ip = si_Nports;
1689 goto out;
1690 case TCSIMODULES:
1691 *ip = si_Nmodules;
1692 goto out;
1693 case TCSISDBG_ALL:
1694 SUCHECK;
1695 si_debug = *ip;
1696 goto out;
1697 case TCSIGDBG_ALL:
1698 *ip = si_debug;
1699 goto out;
1700 default:
1701 /*
1702 * Check that a controller for this port exists
1703 */
1704
1705 /* may also be a struct si_pstat, a superset of si_tcsi */
1706
1707 dp = (struct si_tcsi *)data;
1708 sps = (struct si_pstat *)data;
1709 card = dp->tc_card;
1710 xsc = &si_softc[card]; /* check.. */
1711 if (card < 0 || card >= NSI || xsc->sc_type == SIEMPTY) {
1712 error = ENOENT;
1713 goto out;
1714 }
1715 /*
1716 * And check that a port exists
1717 */
1718 port = dp->tc_port;
1719 if (port < 0 || port >= xsc->sc_nport) {
1720 error = ENOENT;
1721 goto out;
1722 }
1723 xpp = xsc->sc_ports + port;
1724 regp = (struct si_reg *)xsc->sc_maddr;
1725 }
1726
1727 switch (cmd) {
1728 case TCSIDEBUG:
1729#ifdef SI_DEBUG
1730 SUCHECK;
1731 if (xpp->sp_debug)
1732 xpp->sp_debug = 0;
1733 else {
1734 xpp->sp_debug = DBG_ALL;
1735 DPRINT((xpp, DBG_IOCTL, "debug toggled %s\n",
1736 (xpp->sp_debug&DBG_ALL)?"ON":"OFF"));
1737 }
1738 break;
1739#else
1740 error = ENODEV;
1741 goto out;
1742#endif
1743 case TCSISDBG_LEVEL:
1744 case TCSIGDBG_LEVEL:
1745#ifdef SI_DEBUG
1746 if (cmd == TCSIGDBG_LEVEL) {
1747 dp->tc_dbglvl = xpp->sp_debug;
1748 } else {
1749 SUCHECK;
1750 xpp->sp_debug = dp->tc_dbglvl;
1751 }
1752 break;
1753#else
1754 error = ENODEV;
1755 goto out;
1756#endif
1757 case TCSIGRXIT:
1758 dp->tc_int = regp->rx_int_count;
1759 break;
1760 case TCSIRXIT:
1761 SUCHECK;
1762 regp->rx_int_count = dp->tc_int;
1763 break;
1764 case TCSIGIT:
1765 dp->tc_int = regp->int_count;
1766 break;
1767 case TCSIIT:
1768 SUCHECK;
1769 regp->int_count = dp->tc_int;
1770 break;
1771 case TCSISTATE:
1772 dp->tc_int = xpp->sp_ccb->hi_ip;
1773 break;
1774 /* these next three use a different structure */
1775 case TCSI_PORT:
1776 SUCHECK;
1777 si_bcopy(xpp, &sps->tc_siport, sizeof(sps->tc_siport));
1778 break;
1779 case TCSI_CCB:
1780 SUCHECK;
1781 si_vbcopy(xpp->sp_ccb, &sps->tc_ccb, sizeof(sps->tc_ccb));
1782 break;
1783 case TCSI_TTY:
1784 SUCHECK;
1785 si_bcopy(xpp->sp_tty, &sps->tc_tty, sizeof(sps->tc_tty));
1786 break;
1787 default:
1788 error = EINVAL;
1789 goto out;
1790 }
1791out:
1792 splx(oldspl);
1793 return(error); /* success */
1794}
1795
1796/*
1797 * siparam() : Configure line params
1798 * called at spltty();
1799 * this may sleep, does not flush, nor wait for drain, nor block writes
1800 * caller must arrange this if it's important..
1801 */
1802static int
1803siparam(tp, t)
1804 register struct tty *tp;
1805 register struct termios *t;
1806{
1807 register struct si_port *pp = TP2PP(tp);
1808 volatile struct si_channel *ccbp;
1809 int oldspl, cflag, iflag, oflag, lflag;
1810 int error = 0; /* shutup gcc */
1811 int ispeed = 0; /* shutup gcc */
1812 int ospeed = 0; /* shutup gcc */
1813 BYTE val;
1814
1815 DPRINT((pp, DBG_ENTRY|DBG_PARAM, "siparam(%x,%x)\n", tp, t));
1816 cflag = t->c_cflag;
1817 iflag = t->c_iflag;
1818 oflag = t->c_oflag;
1819 lflag = t->c_lflag;
1820 DPRINT((pp, DBG_PARAM, "OFLAG 0x%x CFLAG 0x%x IFLAG 0x%x LFLAG 0x%x\n",
1821 oflag, cflag, iflag, lflag));
1822
1823 /* XXX - if Jet host and SXDC module, use extended baud rates */
1824
1825 /* if not hung up.. */
1826 if (t->c_ospeed != 0) {
1827 /* translate baud rate to firmware values */
1828 ospeed = ttspeedtab(t->c_ospeed, bdrates);
1829 ispeed = t->c_ispeed ?
1830 ttspeedtab(t->c_ispeed, bdrates) : ospeed;
1831
1832 /* enforce legit baud rate */
1833 if (ospeed < 0 || ispeed < 0)
1834 return (EINVAL);
1835 }
1836
1837 oldspl = spltty();
1838
1839 ccbp = pp->sp_ccb;
1840
1841 /* ========== set hi_break ========== */
1842 val = 0;
1843 if (iflag & IGNBRK) /* Breaks */
1844 val |= BR_IGN;
1845 if (iflag & BRKINT) /* Interrupt on break? */
1846 val |= BR_INT;
1847 if (iflag & PARMRK) /* Parity mark? */
1848 val |= BR_PARMRK;
1849 if (iflag & IGNPAR) /* Ignore chars with parity errors? */
1850 val |= BR_PARIGN;
1851 ccbp->hi_break = val;
1852
1853 /* ========== set hi_csr ========== */
1854 /* if not hung up.. */
1855 if (t->c_ospeed != 0) {
1856 /* Set I/O speeds */
1857 val = (ispeed << 4) | ospeed;
1858 }
1859 ccbp->hi_csr = val;
1860
1861 /* ========== set hi_mr2 ========== */
1862 val = 0;
1863 if (cflag & CSTOPB) /* Stop bits */
1864 val |= MR2_2_STOP;
1865 else
1866 val |= MR2_1_STOP;
1867 /*
1868 * Enable H/W RTS/CTS handshaking. The default TA/MTA is
1869 * a DCE, hence the reverse sense of RTS and CTS
1870 */
1871 /* Output Flow - RTS must be raised before data can be sent */
1872 if (cflag & CCTS_OFLOW)
1873 val |= MR2_RTSCONT;
1874
1875 ccbp->hi_mr2 = val;
1876
1877 /* ========== set hi_mr1 ========== */
1878 val = 0;
1879 if (!(cflag & PARENB)) /* Parity */
1880 val |= MR1_NONE;
1881 else
1882 val |= MR1_WITH;
1883 if (cflag & PARODD)
1884 val |= MR1_ODD;
1885
1886 if ((cflag & CS8) == CS8) { /* 8 data bits? */
1887 val |= MR1_8_BITS;
1888 } else if ((cflag & CS7) == CS7) { /* 7 data bits? */
1889 val |= MR1_7_BITS;
1890 } else if ((cflag & CS6) == CS6) { /* 6 data bits? */
1891 val |= MR1_6_BITS;
1892 } else { /* Must be 5 */
1893 val |= MR1_5_BITS;
1894 }
1895 /*
1896 * Enable H/W RTS/CTS handshaking. The default TA/MTA is
1897 * a DCE, hence the reverse sense of RTS and CTS
1898 */
1899 /* Input Flow - CTS is raised when port is ready to receive data */
1900 if (cflag & CRTS_IFLOW)
1901 val |= MR1_CTSCONT;
1902
1903 ccbp->hi_mr1 = val;
1904
1905 /* ========== set hi_mask ========== */
1906 val = 0xff;
1907 if ((cflag & CS8) == CS8) { /* 8 data bits? */
1908 val &= 0xFF;
1909 } else if ((cflag & CS7) == CS7) { /* 7 data bits? */
1910 val &= 0x7F;
1911 } else if ((cflag & CS6) == CS6) { /* 6 data bits? */
1912 val &= 0x3F;
1913 } else { /* Must be 5 */
1914 val &= 0x1F;
1915 }
1916 if (iflag & ISTRIP)
1917 val &= 0x7F;
1918
1919 ccbp->hi_mask = val;
1920
1921 /* ========== set hi_prtcl ========== */
1922 val = 0;
1923 /* Monitor DCD etc. if a modem */
1924 if (!(cflag & CLOCAL))
1925 val |= SP_DCEN;
1926 if (iflag & IXANY)
1927 val |= SP_TANY;
1928 if (iflag & IXON)
1929 val |= SP_TXEN;
1930 if (iflag & IXOFF)
1931 val |= SP_RXEN;
1932 if (iflag & INPCK)
1933 val |= SP_PAEN;
1934
1935 ccbp->hi_prtcl = val;
1936
1937
1938 /* ========== set hi_{rx|tx}{on|off} ========== */
1939 /* XXX: the card TOTALLY shields us from the flow control... */
1940 ccbp->hi_txon = t->c_cc[VSTART];
1941 ccbp->hi_txoff = t->c_cc[VSTOP];
1942
1943 ccbp->hi_rxon = t->c_cc[VSTART];
1944 ccbp->hi_rxoff = t->c_cc[VSTOP];
1945
1946 /* ========== send settings to the card ========== */
1947 /* potential sleep here */
1948 if (ccbp->hi_stat == IDLE_CLOSE) /* Not yet open */
1949 si_command(pp, LOPEN, SI_WAIT); /* open it */
1950 else
1951 si_command(pp, CONFIG, SI_WAIT); /* change params */
1952
1953 /* ========== set DTR etc ========== */
1954 /* Hangup if ospeed == 0 */
1955 if (t->c_ospeed == 0) {
1956 (void) si_modem(pp, BIC, TIOCM_DTR|TIOCM_RTS);
1957 } else {
1958 /*
1959 * If the previous speed was 0, may need to re-enable
1960 * the modem signals
1961 */
1962 (void) si_modem(pp, SET, TIOCM_DTR|TIOCM_RTS);
1963 }
1964
1965 DPRINT((pp, DBG_PARAM, "siparam, complete: MR1 %x MR2 %x HI_MASK %x PRTCL %x HI_BREAK %x\n",
1966 ccbp->hi_mr1, ccbp->hi_mr2, ccbp->hi_mask, ccbp->hi_prtcl, ccbp->hi_break));
1967
1968 splx(oldspl);
1969 return(error);
1970}
1971
1972/*
1973 * Enable or Disable the writes to this channel...
1974 * "state" -> enabled = 1; disabled = 0;
1975 */
1976static void
1977si_write_enable(pp, state)
1978 register struct si_port *pp;
1979 int state;
1980{
1981 int oldspl;
1982
1983 oldspl = spltty();
1984
1985 if (state) {
1986 pp->sp_state &= ~SS_BLOCKWRITE;
1987 if (pp->sp_state & SS_WAITWRITE) {
1988 pp->sp_state &= ~SS_WAITWRITE;
1989 /* thunder away! */
1990 wakeup((caddr_t)pp);
1991 }
1992 } else {
1993 pp->sp_state |= SS_BLOCKWRITE;
1994 }
1995
1996 splx(oldspl);
1997}
1998
1999/*
2000 * Set/Get state of modem control lines.
2001 * Due to DCE-like behaviour of the adapter, some signals need translation:
2002 * TIOCM_DTR DSR
2003 * TIOCM_RTS CTS
2004 */
2005static int
2006si_modem(pp, cmd, bits)
2007 struct si_port *pp;
2008 enum si_mctl cmd;
2009 int bits;
2010{
2011 volatile struct si_channel *ccbp;
2012 int x;
2013
2014 DPRINT((pp, DBG_ENTRY|DBG_MODEM, "si_modem(%x,%s,%x)\n", pp, si_mctl2str(cmd), bits));
2015 ccbp = pp->sp_ccb; /* Find channel address */
2016 switch (cmd) {
2017 case GET:
2018 x = ccbp->hi_ip;
2019 bits = TIOCM_LE;
2020 if (x & IP_DCD) bits |= TIOCM_CAR;
2021 if (x & IP_DTR) bits |= TIOCM_DTR;
2022 if (x & IP_RTS) bits |= TIOCM_RTS;
2023 if (x & IP_RI) bits |= TIOCM_RI;
2024 return(bits);
2025 case SET:
2026 ccbp->hi_op &= ~(OP_DSR|OP_CTS);
2027 /* fall through */
2028 case BIS:
2029 x = 0;
2030 if (bits & TIOCM_DTR)
2031 x |= OP_DSR;
2032 if (bits & TIOCM_RTS)
2033 x |= OP_CTS;
2034 ccbp->hi_op |= x;
2035 break;
2036 case BIC:
2037 if (bits & TIOCM_DTR)
2038 ccbp->hi_op &= ~OP_DSR;
2039 if (bits & TIOCM_RTS)
2040 ccbp->hi_op &= ~OP_CTS;
2041 }
2042 return 0;
2043}
2044
2045/*
2046 * Handle change of modem state
2047 */
2048static void
2049si_modem_state(pp, tp, hi_ip)
2050 register struct si_port *pp;
2051 register struct tty *tp;
2052 register int hi_ip;
2053{
2054 /* if a modem dev */
2055 if (hi_ip & IP_DCD) {
2056 if (!(pp->sp_last_hi_ip & IP_DCD)) {
2057 DPRINT((pp, DBG_INTR, "modem carr on t_line %d\n",
2058 tp->t_line));
2059 (void)(*linesw[tp->t_line].l_modem)(tp, 1);
2060 }
2061 } else {
2062 if (pp->sp_last_hi_ip & IP_DCD) {
2063 DPRINT((pp, DBG_INTR, "modem carr off\n"));
2064 if ((*linesw[tp->t_line].l_modem)(tp, 0))
2065 (void) si_modem(pp, SET, 0);
2066 }
2067 }
2068 pp->sp_last_hi_ip = hi_ip;
2069
2070}
2071
2072/*
2073 * Poller to catch missed interrupts.
2074 *
2075 * Note that the SYSV Specialix drivers poll at 100 times per second to get
2076 * better response. We could really use a "periodic" version timeout(). :-)
2077 */
2078#ifdef POLL
2079static void
2080si_poll(void *nothing)
2081{
2082 register struct si_softc *sc;
2083 register int i;
2084 volatile struct si_reg *regp;
2085 register struct si_port *pp;
2086 int lost, oldspl, port;
2087
2088 DPRINT((0, DBG_POLL, "si_poll()\n"));
2089 oldspl = spltty();
2090 if (in_intr)
2091 goto out;
2092 lost = 0;
2093 for (i = 0; i < NSI; i++) {
2094 sc = &si_softc[i];
2095 if (sc->sc_type == SIEMPTY)
2096 continue;
2097 regp = (struct si_reg *)sc->sc_maddr;
2098
2099 /*
2100 * See if there has been a pending interrupt for 2 seconds
2101 * or so. The test (int_scounter >= 200) won't correspond
2102 * to 2 seconds if int_count gets changed.
2103 */
2104 if (regp->int_pending != 0) {
2105 if (regp->int_scounter >= 200 &&
2106 regp->initstat == 1) {
2107 printf("si%d: lost intr\n", i);
2108 lost++;
2109 }
2110 } else {
2111 regp->int_scounter = 0;
2112 }
2113
2114 /*
2115 * gripe about no input flow control..
2116 */
2117 pp = sc->sc_ports;
2118 for (port = 0; port < sc->sc_nport; pp++, port++) {
2119 if (pp->sp_delta_overflows > 0) {
2120 printf("si%d: %d tty level buffer overflows\n",
2121 i, pp->sp_delta_overflows);
2122 pp->sp_delta_overflows = 0;
2123 }
2124 }
2125 }
2126 if (lost || si_realpoll)
2127 si_intr(-1); /* call intr with fake vector */
2128out:
2129 splx(oldspl);
2130
2131 timeout(si_poll, (caddr_t)0L, si_pollrate);
2132}
2133#endif /* ifdef POLL */
2134
2135/*
2136 * The interrupt handler polls ALL ports on ALL adapters each time
2137 * it is called.
2138 */
2139
2140static BYTE si_rxbuf[SI_BUFFERSIZE]; /* input staging area */
2141static BYTE si_txbuf[SI_BUFFERSIZE]; /* output staging area */
2142
2143static void
2144si_intr(int unit)
2145{
2146 register struct si_softc *sc;
2147
2148 register struct si_port *pp;
2149 volatile struct si_channel *ccbp;
2150 register struct tty *tp;
2151 volatile caddr_t maddr;
2152 BYTE op, ip;
2153 int x, card, port, n, i, isopen;
2154 volatile BYTE *z;
2155 BYTE c;
2156
2157 DPRINT((0, (unit < 0) ? DBG_POLL:DBG_INTR, "si_intr(%d)\n", unit));
2158 if (in_intr) {
2159 if (unit < 0) /* should never happen */
2160 printf("si%d: Warning poll entered during interrupt\n",
2161 unit);
2162 else
2163 printf("si%d: Warning interrupt handler re-entered\n",
2164 unit);
2165 return;
2166 }
2167 in_intr = 1;
2168
2169 /*
2170 * When we get an int we poll all the channels and do ALL pending
2171 * work, not just the first one we find. This allows all cards to
2172 * share the same vector.
2173 *
2174 * XXX - But if we're sharing the vector with something that's NOT
2175 * a SI/XIO/SX card, we may be making more work for ourselves.
2176 */
2177 for (card = 0; card < NSI; card++) {
2178 sc = &si_softc[card];
2179 if (sc->sc_type == SIEMPTY)
2180 continue;
2181
2182 /*
2183 * First, clear the interrupt
2184 */
2185 switch(sc->sc_type) {
2186 case SIHOST:
2187 maddr = sc->sc_maddr;
2188 ((volatile struct si_reg *)maddr)->int_pending = 0;
2189 /* flag nothing pending */
2190 *(maddr+SIINTCL) = 0x00; /* Set IRQ clear */
2191 *(maddr+SIINTCL_CL) = 0x00; /* Clear IRQ clear */
2192 break;
2193 case SIHOST2:
2194 maddr = sc->sc_maddr;
2195 ((volatile struct si_reg *)maddr)->int_pending = 0;
2196 *(maddr+SIPLIRQCLR) = 0x00;
2197 *(maddr+SIPLIRQCLR) = 0x10;
2198 break;
2199#if NPCI > 0
2200 case SIPCI:
2201 maddr = sc->sc_maddr;
2202 ((volatile struct si_reg *)maddr)->int_pending = 0;
2203 *(maddr+SIPCIINTCL) = 0x0;
2204 break;
2205 case SIJETPCI: /* fall through to JETISA case */
2206#endif
2207 case SIJETISA:
2208 maddr = sc->sc_maddr;
2209 ((volatile struct si_reg *)maddr)->int_pending = 0;
2210 *(maddr+SIJETINTCL) = 0x0;
2211 break;
2212#if NEISA > 0
2213 case SIEISA:
2214 maddr = sc->sc_maddr;
2215 ((volatile struct si_reg *)maddr)->int_pending = 0;
2216 (void)inb(sc->sc_eisa_iobase + 3);
2217 break;
2218#endif
2219 case SIEMPTY:
2220 default:
2221 continue;
2222 }
2223 ((volatile struct si_reg *)maddr)->int_scounter = 0;
2224
2225 /*
2226 * check each port
2227 */
2228 for (pp = sc->sc_ports, port = 0; port < sc->sc_nport;
2229 pp++, port++) {
2230 ccbp = pp->sp_ccb;
2231 tp = pp->sp_tty;
2232
2233 /*
2234 * See if a command has completed ?
2235 */
2236 if (ccbp->hi_stat != pp->sp_pend) {
2237 DPRINT((pp, DBG_INTR,
2238 "si_intr hi_stat = 0x%x, pend = %d\n",
2239 ccbp->hi_stat, pp->sp_pend));
2240 switch(pp->sp_pend) {
2241 case LOPEN:
2242 case MPEND:
2243 case MOPEN:
2244 case CONFIG:
2245 case SBREAK:
2246 case EBREAK:
2247 pp->sp_pend = ccbp->hi_stat;
2248 /* sleeping in si_command */
2249 wakeup(&pp->sp_state);
2250 break;
2251 default:
2252 pp->sp_pend = ccbp->hi_stat;
2253 }
2254 }
2255
2256 /*
2257 * Continue on if it's closed
2258 */
2259 if (ccbp->hi_stat == IDLE_CLOSE) {
2260 continue;
2261 }
2262
2263 /*
2264 * Do modem state change if not a local device
2265 */
2266 si_modem_state(pp, tp, ccbp->hi_ip);
2267
2268 /*
2269 * Check to see if we should 'receive' characters.
2270 */
2271 if (tp->t_state & TS_CONNECTED &&
2272 tp->t_state & TS_ISOPEN)
2273 isopen = 1;
2274 else
2275 isopen = 0;
2276
2277 /*
2278 * Do input break processing
2279 */
2280 if (ccbp->hi_state & ST_BREAK) {
2281 if (isopen) {
2282 (*linesw[tp->t_line].l_rint)(TTY_BI, tp);
2283 }
2284 ccbp->hi_state &= ~ST_BREAK; /* A Bit iffy this */
2285 DPRINT((pp, DBG_INTR, "si_intr break\n"));
2286 }
2287
2288 /*
2289 * Do RX stuff - if not open then dump any characters.
2290 * XXX: This is VERY messy and needs to be cleaned up.
2291 *
2292 * XXX: can we leave data in the host adapter buffer
2293 * when the clists are full? That may be dangerous
2294 * if the user cannot get an interrupt signal through.
2295 */
2296
2297 more_rx: /* XXX Sorry. the nesting was driving me bats! :-( */
2298
2299 if (!isopen) {
2300 ccbp->hi_rxopos = ccbp->hi_rxipos;
2301 goto end_rx;
2302 }
2303
2304 /*
2305 * If the tty input buffers are blocked, stop emptying
2306 * the incoming buffers and let the auto flow control
2307 * assert..
2308 */
2309 if (tp->t_state & TS_TBLOCK) {
2310 goto end_rx;
2311 }
2312
2313 /*
2314 * Process read characters if not skipped above
2315 */
2316 op = ccbp->hi_rxopos;
2317 ip = ccbp->hi_rxipos;
2318 c = ip - op;
2319 if (c == 0) {
2320 goto end_rx;
2321 }
2322
2323 n = c & 0xff;
2324 if (n > 250)
2325 n = 250;
2326
2327 DPRINT((pp, DBG_INTR, "n = %d, op = %d, ip = %d\n",
2328 n, op, ip));
2329
2330 /*
2331 * Suck characters out of host card buffer into the
2332 * "input staging buffer" - so that we dont leave the
2333 * host card in limbo while we're possibly echoing
2334 * characters and possibly flushing input inside the
2335 * ldisc l_rint() routine.
2336 */
2337 if (n <= SI_BUFFERSIZE - op) {
2338
2339 DPRINT((pp, DBG_INTR, "\tsingle copy\n"));
2340 z = ccbp->hi_rxbuf + op;
2341 si_vbcopy(z, si_rxbuf, n);
2342
2343 op += n;
2344 } else {
2345 x = SI_BUFFERSIZE - op;
2346
2347 DPRINT((pp, DBG_INTR, "\tdouble part 1 %d\n", x));
2348 z = ccbp->hi_rxbuf + op;
2349 si_vbcopy(z, si_rxbuf, x);
2350
2351 DPRINT((pp, DBG_INTR, "\tdouble part 2 %d\n",
2352 n - x));
2353 z = ccbp->hi_rxbuf;
2354 si_vbcopy(z, si_rxbuf + x, n - x);
2355
2356 op += n;
2357 }
2358
2359 /* clear collected characters from buffer */
2360 ccbp->hi_rxopos = op;
2361
2362 DPRINT((pp, DBG_INTR, "n = %d, op = %d, ip = %d\n",
2363 n, op, ip));
2364
2365 /*
2366 * at this point...
2367 * n = number of chars placed in si_rxbuf
2368 */
2369
2370 /*
2371 * Avoid the grotesquely inefficient lineswitch
2372 * routine (ttyinput) in "raw" mode. It usually
2373 * takes about 450 instructions (that's without
2374 * canonical processing or echo!). slinput is
2375 * reasonably fast (usually 40 instructions
2376 * plus call overhead).
2377 */
2378 if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
2379
2380 /* block if the driver supports it */
2381 if (tp->t_rawq.c_cc + n >= SI_I_HIGH_WATER &&
2382 (tp->t_cflag & CRTS_IFLOW ||
2383 tp->t_iflag & IXOFF) &&
2384 !(tp->t_state & TS_TBLOCK))
2385 ttyblock(tp);
2386
2387 tk_nin += n;
2388 tk_rawcc += n;
2389 tp->t_rawcc += n;
2390
2391 pp->sp_delta_overflows +=
2392 b_to_q((char *)si_rxbuf, n, &tp->t_rawq);
2393
2394 ttwakeup(tp);
2395 if (tp->t_state & TS_TTSTOP &&
2396 (tp->t_iflag & IXANY ||
2397 tp->t_cc[VSTART] == tp->t_cc[VSTOP])) {
2398 tp->t_state &= ~TS_TTSTOP;
2399 tp->t_lflag &= ~FLUSHO;
2400 si_start(tp);
2401 }
2402 } else {
2403 /*
2404 * It'd be nice to not have to go through the
2405 * function call overhead for each char here.
2406 * It'd be nice to block input it, saving a
2407 * loop here and the call/return overhead.
2408 */
2409 for(x = 0; x < n; x++) {
2410 i = si_rxbuf[x];
2411 if ((*linesw[tp->t_line].l_rint)(i, tp)
2412 == -1) {
2413 pp->sp_delta_overflows++;
2414 }
2415 /*
2416 * doesn't seem to be much point doing
2417 * this here.. this driver has no
2418 * softtty processing! ??
2419 */
2420 if (pp->sp_hotchar && i == pp->sp_hotchar) {
2421 setsofttty();
2422 }
2423 }
2424 }
2425 goto more_rx; /* try for more until RXbuf is empty */
2426
2427 end_rx: /* XXX: Again, sorry about the gotos.. :-) */
2428
2429 /*
2430 * Do TX stuff
2431 */
2432 (*linesw[tp->t_line].l_start)(tp);
2433
2434 } /* end of for (all ports on this controller) */
2435 } /* end of for (all controllers) */
2436
2437 in_intr = 0;
2438 DPRINT((0, (unit < 0) ? DBG_POLL:DBG_INTR, "end si_intr(%d)\n", unit));
2439}
2440
2441/*
2442 * Nudge the transmitter...
2443 *
2444 * XXX: I inherited some funny code here. It implies the host card only
2445 * interrupts when the transmit buffer reaches the low-water-mark, and does
2446 * not interrupt when it's actually hits empty. In some cases, we have
2447 * processes waiting for complete drain, and we need to simulate an interrupt
2448 * about when we think the buffer is going to be empty (and retry if not).
2449 * I really am not certain about this... I *need* the hardware manuals.
2450 */
2451static void
2452si_start(tp)
2453 register struct tty *tp;
2454{
2455 struct si_port *pp;
2456 volatile struct si_channel *ccbp;
2457 register struct clist *qp;
2458 BYTE ipos;
2459 int nchar;
2460 int oldspl, count, n, amount, buffer_full;
2461
2462 oldspl = spltty();
2463
2464 qp = &tp->t_outq;
2465 pp = TP2PP(tp);
2466
2467 DPRINT((pp, DBG_ENTRY|DBG_START,
2468 "si_start(%x) t_state %x sp_state %x t_outq.c_cc %d\n",
2469 tp, tp->t_state, pp->sp_state, qp->c_cc));
2470
2471 if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP))
2472 goto out;
2473
2474 buffer_full = 0;
2475 ccbp = pp->sp_ccb;
2476
2477 count = (int)ccbp->hi_txipos - (int)ccbp->hi_txopos;
2478 DPRINT((pp, DBG_START, "count %d\n", (BYTE)count));
2479
2480 while ((nchar = qp->c_cc) > 0) {
2481 if ((BYTE)count >= 255) {
2482 buffer_full++;
2483 break;
2484 }
2485 amount = min(nchar, (255 - (BYTE)count));
2486 ipos = (unsigned int)ccbp->hi_txipos;
2487 n = q_to_b(&tp->t_outq, si_txbuf, amount);
2488 /* will it fit in one lump? */
2489 if ((SI_BUFFERSIZE - ipos) >= n) {
2490 si_bcopyv(si_txbuf, &ccbp->hi_txbuf[ipos], n);
2491 } else {
2492 si_bcopyv(si_txbuf, &ccbp->hi_txbuf[ipos],
2493 SI_BUFFERSIZE - ipos);
2494 si_bcopyv(si_txbuf + (SI_BUFFERSIZE - ipos),
2495 &ccbp->hi_txbuf[0], n - (SI_BUFFERSIZE - ipos));
2496 }
2497 ccbp->hi_txipos += n;
2498 count = (int)ccbp->hi_txipos - (int)ccbp->hi_txopos;
2499 }
2500
2501 if (count != 0 && nchar == 0) {
2502 tp->t_state |= TS_BUSY;
2503 } else {
2504 tp->t_state &= ~TS_BUSY;
2505 }
2506
2507 /* wakeup time? */
2508 ttwwakeup(tp);
2509
2510 DPRINT((pp, DBG_START, "count %d, nchar %d, tp->t_state 0x%x\n",
2511 (BYTE)count, nchar, tp->t_state));
2512
2513 if (tp->t_state & TS_BUSY)
2514 {
2515 int time;
2516
2517 time = ttspeedtab(tp->t_ospeed, chartimes);
2518
2519 if (time > 0) {
2520 if (time < nchar)
2521 time = nchar / time;
2522 else
2523 time = 2;
2524 } else {
2525 DPRINT((pp, DBG_START,
2526 "bad char time value! %d\n", time));
2527 time = hz/10;
2528 }
2529
2530 if ((pp->sp_state & (SS_LSTART|SS_INLSTART)) == SS_LSTART) {
2531 untimeout(si_lstart, (caddr_t)pp, pp->lstart_ch);
2532 } else {
2533 pp->sp_state |= SS_LSTART;
2534 }
2535 DPRINT((pp, DBG_START, "arming lstart, time=%d\n", time));
2536 pp->lstart_ch = timeout(si_lstart, (caddr_t)pp, time);
2537 }
2538
2539out:
2540 splx(oldspl);
2541 DPRINT((pp, DBG_EXIT|DBG_START, "leave si_start()\n"));
2542}
2543
2544/*
2545 * Note: called at splsoftclock from the timeout code
2546 * This has to deal with two things... cause wakeups while waiting for
2547 * tty drains on last process exit, and call l_start at about the right
2548 * time for protocols like ppp.
2549 */
2550static void
2551si_lstart(void *arg)
2552{
2553 register struct si_port *pp = arg;
2554 register struct tty *tp;
2555 int oldspl;
2556
2557 DPRINT((pp, DBG_ENTRY|DBG_LSTART, "si_lstart(%x) sp_state %x\n",
2558 pp, pp->sp_state));
2559
2560 oldspl = spltty();
2561
2562 if ((pp->sp_state & SS_OPEN) == 0 || (pp->sp_state & SS_LSTART) == 0) {
2563 splx(oldspl);
2564 return;
2565 }
2566 pp->sp_state &= ~SS_LSTART;
2567 pp->sp_state |= SS_INLSTART;
2568
2569 tp = pp->sp_tty;
2570
2571 /* deal with the process exit case */
2572 ttwwakeup(tp);
2573
2574 /* nudge protocols - eg: ppp */
2575 (*linesw[tp->t_line].l_start)(tp);
2576
2577 pp->sp_state &= ~SS_INLSTART;
2578 splx(oldspl);
2579}
2580
2581/*
2582 * Stop output on a line. called at spltty();
2583 */
2584void
1462static int
1463siioctl(dev, cmd, data, flag, p)
1464 dev_t dev;
1465 u_long cmd;
1466 caddr_t data;
1467 int flag;
1468 struct proc *p;
1469{
1470 struct si_port *pp;
1471 register struct tty *tp;
1472 int error;
1473 int mynor = minor(dev);
1474 int oldspl;
1475 int blocked = 0;
1476#if defined(COMPAT_43)
1477 u_long oldcmd;
1478 struct termios term;
1479#endif
1480
1481 if (IS_SI_IOCTL(cmd))
1482 return(si_Sioctl(dev, cmd, data, flag, p));
1483
1484 pp = MINOR2PP(mynor);
1485 tp = pp->sp_tty;
1486
1487 DPRINT((pp, DBG_ENTRY|DBG_IOCTL, "siioctl(%s,%lx,%x,%x)\n",
1488 devtoname(dev), cmd, data, flag));
1489 if (IS_STATE(mynor)) {
1490 struct termios *ct;
1491
1492 switch (mynor & SI_STATE_MASK) {
1493 case SI_INIT_STATE_MASK:
1494 ct = IS_CALLOUT(mynor) ? &pp->sp_iout : &pp->sp_iin;
1495 break;
1496 case SI_LOCK_STATE_MASK:
1497 ct = IS_CALLOUT(mynor) ? &pp->sp_lout : &pp->sp_lin;
1498 break;
1499 default:
1500 return (ENODEV);
1501 }
1502 switch (cmd) {
1503 case TIOCSETA:
1504 error = suser(p);
1505 if (error != 0)
1506 return (error);
1507 *ct = *(struct termios *)data;
1508 return (0);
1509 case TIOCGETA:
1510 *(struct termios *)data = *ct;
1511 return (0);
1512 case TIOCGETD:
1513 *(int *)data = TTYDISC;
1514 return (0);
1515 case TIOCGWINSZ:
1516 bzero(data, sizeof(struct winsize));
1517 return (0);
1518 default:
1519 return (ENOTTY);
1520 }
1521 }
1522 /*
1523 * Do the old-style ioctl compat routines...
1524 */
1525#if defined(COMPAT_43)
1526 term = tp->t_termios;
1527 oldcmd = cmd;
1528 error = ttsetcompat(tp, &cmd, data, &term);
1529 if (error != 0)
1530 return (error);
1531 if (cmd != oldcmd)
1532 data = (caddr_t)&term;
1533#endif
1534 /*
1535 * Do the initial / lock state business
1536 */
1537 if (cmd == TIOCSETA || cmd == TIOCSETAW || cmd == TIOCSETAF) {
1538 int cc;
1539 struct termios *dt = (struct termios *)data;
1540 struct termios *lt = mynor & SI_CALLOUT_MASK
1541 ? &pp->sp_lout : &pp->sp_lin;
1542
1543 dt->c_iflag = (tp->t_iflag & lt->c_iflag) |
1544 (dt->c_iflag & ~lt->c_iflag);
1545 dt->c_oflag = (tp->t_oflag & lt->c_oflag) |
1546 (dt->c_oflag & ~lt->c_oflag);
1547 dt->c_cflag = (tp->t_cflag & lt->c_cflag) |
1548 (dt->c_cflag & ~lt->c_cflag);
1549 dt->c_lflag = (tp->t_lflag & lt->c_lflag) |
1550 (dt->c_lflag & ~lt->c_lflag);
1551 for (cc = 0; cc < NCCS; ++cc)
1552 if (lt->c_cc[cc] != 0)
1553 dt->c_cc[cc] = tp->t_cc[cc];
1554 if (lt->c_ispeed != 0)
1555 dt->c_ispeed = tp->t_ispeed;
1556 if (lt->c_ospeed != 0)
1557 dt->c_ospeed = tp->t_ospeed;
1558 }
1559
1560 /*
1561 * Block user-level writes to give the ttywait()
1562 * a chance to completely drain for commands
1563 * that require the port to be in a quiescent state.
1564 */
1565 switch (cmd) {
1566 case TIOCSETAW:
1567 case TIOCSETAF:
1568 case TIOCDRAIN:
1569#ifdef COMPAT_43
1570 case TIOCSETP:
1571#endif
1572 blocked++; /* block writes for ttywait() and siparam() */
1573 si_write_enable(pp, 0);
1574 }
1575
1576 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
1577 if (error != ENOIOCTL)
1578 goto out;
1579
1580 oldspl = spltty();
1581
1582 error = ttioctl(tp, cmd, data, flag);
1583 si_disc_optim(tp, &tp->t_termios, pp);
1584 if (error != ENOIOCTL) {
1585 splx(oldspl);
1586 goto out;
1587 }
1588
1589 error = 0;
1590 switch (cmd) {
1591 case TIOCSBRK:
1592 si_command(pp, SBREAK, SI_WAIT);
1593 break;
1594 case TIOCCBRK:
1595 si_command(pp, EBREAK, SI_WAIT);
1596 break;
1597 case TIOCSDTR:
1598 (void) si_modem(pp, SET, TIOCM_DTR|TIOCM_RTS);
1599 break;
1600 case TIOCCDTR:
1601 (void) si_modem(pp, SET, 0);
1602 break;
1603 case TIOCMSET:
1604 (void) si_modem(pp, SET, *(int *)data);
1605 break;
1606 case TIOCMBIS:
1607 (void) si_modem(pp, BIS, *(int *)data);
1608 break;
1609 case TIOCMBIC:
1610 (void) si_modem(pp, BIC, *(int *)data);
1611 break;
1612 case TIOCMGET:
1613 *(int *)data = si_modem(pp, GET, 0);
1614 break;
1615 case TIOCMSDTRWAIT:
1616 /* must be root since the wait applies to following logins */
1617 error = suser(p);
1618 if (error == 0)
1619 pp->sp_dtr_wait = *(int *)data * hz / 100;
1620 break;
1621 case TIOCMGDTRWAIT:
1622 *(int *)data = pp->sp_dtr_wait * 100 / hz;
1623 break;
1624 default:
1625 error = ENOTTY;
1626 }
1627 splx(oldspl);
1628
1629out:
1630 DPRINT((pp, DBG_IOCTL|DBG_EXIT, "siioctl ret %d\n", error));
1631 if (blocked)
1632 si_write_enable(pp, 1);
1633 return(error);
1634}
1635
1636/*
1637 * Handle the Specialix ioctls. All MUST be called via the CONTROL device
1638 */
1639static int
1640si_Sioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
1641{
1642 struct si_softc *xsc;
1643 register struct si_port *xpp;
1644 volatile struct si_reg *regp;
1645 struct si_tcsi *dp;
1646 struct si_pstat *sps;
1647 int *ip, error = 0;
1648 int oldspl;
1649 int card, port;
1650 int mynor = minor(dev);
1651
1652 DPRINT((0, DBG_ENTRY|DBG_IOCTL, "si_Sioctl(%s,%lx,%x,%x)\n",
1653 devtoname(dev), cmd, data, flag));
1654
1655#if 1
1656 DPRINT((0, DBG_IOCTL, "TCSI_PORT=%x\n", TCSI_PORT));
1657 DPRINT((0, DBG_IOCTL, "TCSI_CCB=%x\n", TCSI_CCB));
1658 DPRINT((0, DBG_IOCTL, "TCSI_TTY=%x\n", TCSI_TTY));
1659#endif
1660
1661 if (!IS_CONTROLDEV(mynor)) {
1662 DPRINT((0, DBG_IOCTL|DBG_FAIL, "not called from control device!\n"));
1663 return(ENODEV);
1664 }
1665
1666 oldspl = spltty(); /* better safe than sorry */
1667
1668 ip = (int *)data;
1669
1670#define SUCHECK if ((error = suser(p))) goto out
1671
1672 switch (cmd) {
1673 case TCSIPORTS:
1674 *ip = si_Nports;
1675 goto out;
1676 case TCSIMODULES:
1677 *ip = si_Nmodules;
1678 goto out;
1679 case TCSISDBG_ALL:
1680 SUCHECK;
1681 si_debug = *ip;
1682 goto out;
1683 case TCSIGDBG_ALL:
1684 *ip = si_debug;
1685 goto out;
1686 default:
1687 /*
1688 * Check that a controller for this port exists
1689 */
1690
1691 /* may also be a struct si_pstat, a superset of si_tcsi */
1692
1693 dp = (struct si_tcsi *)data;
1694 sps = (struct si_pstat *)data;
1695 card = dp->tc_card;
1696 xsc = &si_softc[card]; /* check.. */
1697 if (card < 0 || card >= NSI || xsc->sc_type == SIEMPTY) {
1698 error = ENOENT;
1699 goto out;
1700 }
1701 /*
1702 * And check that a port exists
1703 */
1704 port = dp->tc_port;
1705 if (port < 0 || port >= xsc->sc_nport) {
1706 error = ENOENT;
1707 goto out;
1708 }
1709 xpp = xsc->sc_ports + port;
1710 regp = (struct si_reg *)xsc->sc_maddr;
1711 }
1712
1713 switch (cmd) {
1714 case TCSIDEBUG:
1715#ifdef SI_DEBUG
1716 SUCHECK;
1717 if (xpp->sp_debug)
1718 xpp->sp_debug = 0;
1719 else {
1720 xpp->sp_debug = DBG_ALL;
1721 DPRINT((xpp, DBG_IOCTL, "debug toggled %s\n",
1722 (xpp->sp_debug&DBG_ALL)?"ON":"OFF"));
1723 }
1724 break;
1725#else
1726 error = ENODEV;
1727 goto out;
1728#endif
1729 case TCSISDBG_LEVEL:
1730 case TCSIGDBG_LEVEL:
1731#ifdef SI_DEBUG
1732 if (cmd == TCSIGDBG_LEVEL) {
1733 dp->tc_dbglvl = xpp->sp_debug;
1734 } else {
1735 SUCHECK;
1736 xpp->sp_debug = dp->tc_dbglvl;
1737 }
1738 break;
1739#else
1740 error = ENODEV;
1741 goto out;
1742#endif
1743 case TCSIGRXIT:
1744 dp->tc_int = regp->rx_int_count;
1745 break;
1746 case TCSIRXIT:
1747 SUCHECK;
1748 regp->rx_int_count = dp->tc_int;
1749 break;
1750 case TCSIGIT:
1751 dp->tc_int = regp->int_count;
1752 break;
1753 case TCSIIT:
1754 SUCHECK;
1755 regp->int_count = dp->tc_int;
1756 break;
1757 case TCSISTATE:
1758 dp->tc_int = xpp->sp_ccb->hi_ip;
1759 break;
1760 /* these next three use a different structure */
1761 case TCSI_PORT:
1762 SUCHECK;
1763 si_bcopy(xpp, &sps->tc_siport, sizeof(sps->tc_siport));
1764 break;
1765 case TCSI_CCB:
1766 SUCHECK;
1767 si_vbcopy(xpp->sp_ccb, &sps->tc_ccb, sizeof(sps->tc_ccb));
1768 break;
1769 case TCSI_TTY:
1770 SUCHECK;
1771 si_bcopy(xpp->sp_tty, &sps->tc_tty, sizeof(sps->tc_tty));
1772 break;
1773 default:
1774 error = EINVAL;
1775 goto out;
1776 }
1777out:
1778 splx(oldspl);
1779 return(error); /* success */
1780}
1781
1782/*
1783 * siparam() : Configure line params
1784 * called at spltty();
1785 * this may sleep, does not flush, nor wait for drain, nor block writes
1786 * caller must arrange this if it's important..
1787 */
1788static int
1789siparam(tp, t)
1790 register struct tty *tp;
1791 register struct termios *t;
1792{
1793 register struct si_port *pp = TP2PP(tp);
1794 volatile struct si_channel *ccbp;
1795 int oldspl, cflag, iflag, oflag, lflag;
1796 int error = 0; /* shutup gcc */
1797 int ispeed = 0; /* shutup gcc */
1798 int ospeed = 0; /* shutup gcc */
1799 BYTE val;
1800
1801 DPRINT((pp, DBG_ENTRY|DBG_PARAM, "siparam(%x,%x)\n", tp, t));
1802 cflag = t->c_cflag;
1803 iflag = t->c_iflag;
1804 oflag = t->c_oflag;
1805 lflag = t->c_lflag;
1806 DPRINT((pp, DBG_PARAM, "OFLAG 0x%x CFLAG 0x%x IFLAG 0x%x LFLAG 0x%x\n",
1807 oflag, cflag, iflag, lflag));
1808
1809 /* XXX - if Jet host and SXDC module, use extended baud rates */
1810
1811 /* if not hung up.. */
1812 if (t->c_ospeed != 0) {
1813 /* translate baud rate to firmware values */
1814 ospeed = ttspeedtab(t->c_ospeed, bdrates);
1815 ispeed = t->c_ispeed ?
1816 ttspeedtab(t->c_ispeed, bdrates) : ospeed;
1817
1818 /* enforce legit baud rate */
1819 if (ospeed < 0 || ispeed < 0)
1820 return (EINVAL);
1821 }
1822
1823 oldspl = spltty();
1824
1825 ccbp = pp->sp_ccb;
1826
1827 /* ========== set hi_break ========== */
1828 val = 0;
1829 if (iflag & IGNBRK) /* Breaks */
1830 val |= BR_IGN;
1831 if (iflag & BRKINT) /* Interrupt on break? */
1832 val |= BR_INT;
1833 if (iflag & PARMRK) /* Parity mark? */
1834 val |= BR_PARMRK;
1835 if (iflag & IGNPAR) /* Ignore chars with parity errors? */
1836 val |= BR_PARIGN;
1837 ccbp->hi_break = val;
1838
1839 /* ========== set hi_csr ========== */
1840 /* if not hung up.. */
1841 if (t->c_ospeed != 0) {
1842 /* Set I/O speeds */
1843 val = (ispeed << 4) | ospeed;
1844 }
1845 ccbp->hi_csr = val;
1846
1847 /* ========== set hi_mr2 ========== */
1848 val = 0;
1849 if (cflag & CSTOPB) /* Stop bits */
1850 val |= MR2_2_STOP;
1851 else
1852 val |= MR2_1_STOP;
1853 /*
1854 * Enable H/W RTS/CTS handshaking. The default TA/MTA is
1855 * a DCE, hence the reverse sense of RTS and CTS
1856 */
1857 /* Output Flow - RTS must be raised before data can be sent */
1858 if (cflag & CCTS_OFLOW)
1859 val |= MR2_RTSCONT;
1860
1861 ccbp->hi_mr2 = val;
1862
1863 /* ========== set hi_mr1 ========== */
1864 val = 0;
1865 if (!(cflag & PARENB)) /* Parity */
1866 val |= MR1_NONE;
1867 else
1868 val |= MR1_WITH;
1869 if (cflag & PARODD)
1870 val |= MR1_ODD;
1871
1872 if ((cflag & CS8) == CS8) { /* 8 data bits? */
1873 val |= MR1_8_BITS;
1874 } else if ((cflag & CS7) == CS7) { /* 7 data bits? */
1875 val |= MR1_7_BITS;
1876 } else if ((cflag & CS6) == CS6) { /* 6 data bits? */
1877 val |= MR1_6_BITS;
1878 } else { /* Must be 5 */
1879 val |= MR1_5_BITS;
1880 }
1881 /*
1882 * Enable H/W RTS/CTS handshaking. The default TA/MTA is
1883 * a DCE, hence the reverse sense of RTS and CTS
1884 */
1885 /* Input Flow - CTS is raised when port is ready to receive data */
1886 if (cflag & CRTS_IFLOW)
1887 val |= MR1_CTSCONT;
1888
1889 ccbp->hi_mr1 = val;
1890
1891 /* ========== set hi_mask ========== */
1892 val = 0xff;
1893 if ((cflag & CS8) == CS8) { /* 8 data bits? */
1894 val &= 0xFF;
1895 } else if ((cflag & CS7) == CS7) { /* 7 data bits? */
1896 val &= 0x7F;
1897 } else if ((cflag & CS6) == CS6) { /* 6 data bits? */
1898 val &= 0x3F;
1899 } else { /* Must be 5 */
1900 val &= 0x1F;
1901 }
1902 if (iflag & ISTRIP)
1903 val &= 0x7F;
1904
1905 ccbp->hi_mask = val;
1906
1907 /* ========== set hi_prtcl ========== */
1908 val = 0;
1909 /* Monitor DCD etc. if a modem */
1910 if (!(cflag & CLOCAL))
1911 val |= SP_DCEN;
1912 if (iflag & IXANY)
1913 val |= SP_TANY;
1914 if (iflag & IXON)
1915 val |= SP_TXEN;
1916 if (iflag & IXOFF)
1917 val |= SP_RXEN;
1918 if (iflag & INPCK)
1919 val |= SP_PAEN;
1920
1921 ccbp->hi_prtcl = val;
1922
1923
1924 /* ========== set hi_{rx|tx}{on|off} ========== */
1925 /* XXX: the card TOTALLY shields us from the flow control... */
1926 ccbp->hi_txon = t->c_cc[VSTART];
1927 ccbp->hi_txoff = t->c_cc[VSTOP];
1928
1929 ccbp->hi_rxon = t->c_cc[VSTART];
1930 ccbp->hi_rxoff = t->c_cc[VSTOP];
1931
1932 /* ========== send settings to the card ========== */
1933 /* potential sleep here */
1934 if (ccbp->hi_stat == IDLE_CLOSE) /* Not yet open */
1935 si_command(pp, LOPEN, SI_WAIT); /* open it */
1936 else
1937 si_command(pp, CONFIG, SI_WAIT); /* change params */
1938
1939 /* ========== set DTR etc ========== */
1940 /* Hangup if ospeed == 0 */
1941 if (t->c_ospeed == 0) {
1942 (void) si_modem(pp, BIC, TIOCM_DTR|TIOCM_RTS);
1943 } else {
1944 /*
1945 * If the previous speed was 0, may need to re-enable
1946 * the modem signals
1947 */
1948 (void) si_modem(pp, SET, TIOCM_DTR|TIOCM_RTS);
1949 }
1950
1951 DPRINT((pp, DBG_PARAM, "siparam, complete: MR1 %x MR2 %x HI_MASK %x PRTCL %x HI_BREAK %x\n",
1952 ccbp->hi_mr1, ccbp->hi_mr2, ccbp->hi_mask, ccbp->hi_prtcl, ccbp->hi_break));
1953
1954 splx(oldspl);
1955 return(error);
1956}
1957
1958/*
1959 * Enable or Disable the writes to this channel...
1960 * "state" -> enabled = 1; disabled = 0;
1961 */
1962static void
1963si_write_enable(pp, state)
1964 register struct si_port *pp;
1965 int state;
1966{
1967 int oldspl;
1968
1969 oldspl = spltty();
1970
1971 if (state) {
1972 pp->sp_state &= ~SS_BLOCKWRITE;
1973 if (pp->sp_state & SS_WAITWRITE) {
1974 pp->sp_state &= ~SS_WAITWRITE;
1975 /* thunder away! */
1976 wakeup((caddr_t)pp);
1977 }
1978 } else {
1979 pp->sp_state |= SS_BLOCKWRITE;
1980 }
1981
1982 splx(oldspl);
1983}
1984
1985/*
1986 * Set/Get state of modem control lines.
1987 * Due to DCE-like behaviour of the adapter, some signals need translation:
1988 * TIOCM_DTR DSR
1989 * TIOCM_RTS CTS
1990 */
1991static int
1992si_modem(pp, cmd, bits)
1993 struct si_port *pp;
1994 enum si_mctl cmd;
1995 int bits;
1996{
1997 volatile struct si_channel *ccbp;
1998 int x;
1999
2000 DPRINT((pp, DBG_ENTRY|DBG_MODEM, "si_modem(%x,%s,%x)\n", pp, si_mctl2str(cmd), bits));
2001 ccbp = pp->sp_ccb; /* Find channel address */
2002 switch (cmd) {
2003 case GET:
2004 x = ccbp->hi_ip;
2005 bits = TIOCM_LE;
2006 if (x & IP_DCD) bits |= TIOCM_CAR;
2007 if (x & IP_DTR) bits |= TIOCM_DTR;
2008 if (x & IP_RTS) bits |= TIOCM_RTS;
2009 if (x & IP_RI) bits |= TIOCM_RI;
2010 return(bits);
2011 case SET:
2012 ccbp->hi_op &= ~(OP_DSR|OP_CTS);
2013 /* fall through */
2014 case BIS:
2015 x = 0;
2016 if (bits & TIOCM_DTR)
2017 x |= OP_DSR;
2018 if (bits & TIOCM_RTS)
2019 x |= OP_CTS;
2020 ccbp->hi_op |= x;
2021 break;
2022 case BIC:
2023 if (bits & TIOCM_DTR)
2024 ccbp->hi_op &= ~OP_DSR;
2025 if (bits & TIOCM_RTS)
2026 ccbp->hi_op &= ~OP_CTS;
2027 }
2028 return 0;
2029}
2030
2031/*
2032 * Handle change of modem state
2033 */
2034static void
2035si_modem_state(pp, tp, hi_ip)
2036 register struct si_port *pp;
2037 register struct tty *tp;
2038 register int hi_ip;
2039{
2040 /* if a modem dev */
2041 if (hi_ip & IP_DCD) {
2042 if (!(pp->sp_last_hi_ip & IP_DCD)) {
2043 DPRINT((pp, DBG_INTR, "modem carr on t_line %d\n",
2044 tp->t_line));
2045 (void)(*linesw[tp->t_line].l_modem)(tp, 1);
2046 }
2047 } else {
2048 if (pp->sp_last_hi_ip & IP_DCD) {
2049 DPRINT((pp, DBG_INTR, "modem carr off\n"));
2050 if ((*linesw[tp->t_line].l_modem)(tp, 0))
2051 (void) si_modem(pp, SET, 0);
2052 }
2053 }
2054 pp->sp_last_hi_ip = hi_ip;
2055
2056}
2057
2058/*
2059 * Poller to catch missed interrupts.
2060 *
2061 * Note that the SYSV Specialix drivers poll at 100 times per second to get
2062 * better response. We could really use a "periodic" version timeout(). :-)
2063 */
2064#ifdef POLL
2065static void
2066si_poll(void *nothing)
2067{
2068 register struct si_softc *sc;
2069 register int i;
2070 volatile struct si_reg *regp;
2071 register struct si_port *pp;
2072 int lost, oldspl, port;
2073
2074 DPRINT((0, DBG_POLL, "si_poll()\n"));
2075 oldspl = spltty();
2076 if (in_intr)
2077 goto out;
2078 lost = 0;
2079 for (i = 0; i < NSI; i++) {
2080 sc = &si_softc[i];
2081 if (sc->sc_type == SIEMPTY)
2082 continue;
2083 regp = (struct si_reg *)sc->sc_maddr;
2084
2085 /*
2086 * See if there has been a pending interrupt for 2 seconds
2087 * or so. The test (int_scounter >= 200) won't correspond
2088 * to 2 seconds if int_count gets changed.
2089 */
2090 if (regp->int_pending != 0) {
2091 if (regp->int_scounter >= 200 &&
2092 regp->initstat == 1) {
2093 printf("si%d: lost intr\n", i);
2094 lost++;
2095 }
2096 } else {
2097 regp->int_scounter = 0;
2098 }
2099
2100 /*
2101 * gripe about no input flow control..
2102 */
2103 pp = sc->sc_ports;
2104 for (port = 0; port < sc->sc_nport; pp++, port++) {
2105 if (pp->sp_delta_overflows > 0) {
2106 printf("si%d: %d tty level buffer overflows\n",
2107 i, pp->sp_delta_overflows);
2108 pp->sp_delta_overflows = 0;
2109 }
2110 }
2111 }
2112 if (lost || si_realpoll)
2113 si_intr(-1); /* call intr with fake vector */
2114out:
2115 splx(oldspl);
2116
2117 timeout(si_poll, (caddr_t)0L, si_pollrate);
2118}
2119#endif /* ifdef POLL */
2120
2121/*
2122 * The interrupt handler polls ALL ports on ALL adapters each time
2123 * it is called.
2124 */
2125
2126static BYTE si_rxbuf[SI_BUFFERSIZE]; /* input staging area */
2127static BYTE si_txbuf[SI_BUFFERSIZE]; /* output staging area */
2128
2129static void
2130si_intr(int unit)
2131{
2132 register struct si_softc *sc;
2133
2134 register struct si_port *pp;
2135 volatile struct si_channel *ccbp;
2136 register struct tty *tp;
2137 volatile caddr_t maddr;
2138 BYTE op, ip;
2139 int x, card, port, n, i, isopen;
2140 volatile BYTE *z;
2141 BYTE c;
2142
2143 DPRINT((0, (unit < 0) ? DBG_POLL:DBG_INTR, "si_intr(%d)\n", unit));
2144 if (in_intr) {
2145 if (unit < 0) /* should never happen */
2146 printf("si%d: Warning poll entered during interrupt\n",
2147 unit);
2148 else
2149 printf("si%d: Warning interrupt handler re-entered\n",
2150 unit);
2151 return;
2152 }
2153 in_intr = 1;
2154
2155 /*
2156 * When we get an int we poll all the channels and do ALL pending
2157 * work, not just the first one we find. This allows all cards to
2158 * share the same vector.
2159 *
2160 * XXX - But if we're sharing the vector with something that's NOT
2161 * a SI/XIO/SX card, we may be making more work for ourselves.
2162 */
2163 for (card = 0; card < NSI; card++) {
2164 sc = &si_softc[card];
2165 if (sc->sc_type == SIEMPTY)
2166 continue;
2167
2168 /*
2169 * First, clear the interrupt
2170 */
2171 switch(sc->sc_type) {
2172 case SIHOST:
2173 maddr = sc->sc_maddr;
2174 ((volatile struct si_reg *)maddr)->int_pending = 0;
2175 /* flag nothing pending */
2176 *(maddr+SIINTCL) = 0x00; /* Set IRQ clear */
2177 *(maddr+SIINTCL_CL) = 0x00; /* Clear IRQ clear */
2178 break;
2179 case SIHOST2:
2180 maddr = sc->sc_maddr;
2181 ((volatile struct si_reg *)maddr)->int_pending = 0;
2182 *(maddr+SIPLIRQCLR) = 0x00;
2183 *(maddr+SIPLIRQCLR) = 0x10;
2184 break;
2185#if NPCI > 0
2186 case SIPCI:
2187 maddr = sc->sc_maddr;
2188 ((volatile struct si_reg *)maddr)->int_pending = 0;
2189 *(maddr+SIPCIINTCL) = 0x0;
2190 break;
2191 case SIJETPCI: /* fall through to JETISA case */
2192#endif
2193 case SIJETISA:
2194 maddr = sc->sc_maddr;
2195 ((volatile struct si_reg *)maddr)->int_pending = 0;
2196 *(maddr+SIJETINTCL) = 0x0;
2197 break;
2198#if NEISA > 0
2199 case SIEISA:
2200 maddr = sc->sc_maddr;
2201 ((volatile struct si_reg *)maddr)->int_pending = 0;
2202 (void)inb(sc->sc_eisa_iobase + 3);
2203 break;
2204#endif
2205 case SIEMPTY:
2206 default:
2207 continue;
2208 }
2209 ((volatile struct si_reg *)maddr)->int_scounter = 0;
2210
2211 /*
2212 * check each port
2213 */
2214 for (pp = sc->sc_ports, port = 0; port < sc->sc_nport;
2215 pp++, port++) {
2216 ccbp = pp->sp_ccb;
2217 tp = pp->sp_tty;
2218
2219 /*
2220 * See if a command has completed ?
2221 */
2222 if (ccbp->hi_stat != pp->sp_pend) {
2223 DPRINT((pp, DBG_INTR,
2224 "si_intr hi_stat = 0x%x, pend = %d\n",
2225 ccbp->hi_stat, pp->sp_pend));
2226 switch(pp->sp_pend) {
2227 case LOPEN:
2228 case MPEND:
2229 case MOPEN:
2230 case CONFIG:
2231 case SBREAK:
2232 case EBREAK:
2233 pp->sp_pend = ccbp->hi_stat;
2234 /* sleeping in si_command */
2235 wakeup(&pp->sp_state);
2236 break;
2237 default:
2238 pp->sp_pend = ccbp->hi_stat;
2239 }
2240 }
2241
2242 /*
2243 * Continue on if it's closed
2244 */
2245 if (ccbp->hi_stat == IDLE_CLOSE) {
2246 continue;
2247 }
2248
2249 /*
2250 * Do modem state change if not a local device
2251 */
2252 si_modem_state(pp, tp, ccbp->hi_ip);
2253
2254 /*
2255 * Check to see if we should 'receive' characters.
2256 */
2257 if (tp->t_state & TS_CONNECTED &&
2258 tp->t_state & TS_ISOPEN)
2259 isopen = 1;
2260 else
2261 isopen = 0;
2262
2263 /*
2264 * Do input break processing
2265 */
2266 if (ccbp->hi_state & ST_BREAK) {
2267 if (isopen) {
2268 (*linesw[tp->t_line].l_rint)(TTY_BI, tp);
2269 }
2270 ccbp->hi_state &= ~ST_BREAK; /* A Bit iffy this */
2271 DPRINT((pp, DBG_INTR, "si_intr break\n"));
2272 }
2273
2274 /*
2275 * Do RX stuff - if not open then dump any characters.
2276 * XXX: This is VERY messy and needs to be cleaned up.
2277 *
2278 * XXX: can we leave data in the host adapter buffer
2279 * when the clists are full? That may be dangerous
2280 * if the user cannot get an interrupt signal through.
2281 */
2282
2283 more_rx: /* XXX Sorry. the nesting was driving me bats! :-( */
2284
2285 if (!isopen) {
2286 ccbp->hi_rxopos = ccbp->hi_rxipos;
2287 goto end_rx;
2288 }
2289
2290 /*
2291 * If the tty input buffers are blocked, stop emptying
2292 * the incoming buffers and let the auto flow control
2293 * assert..
2294 */
2295 if (tp->t_state & TS_TBLOCK) {
2296 goto end_rx;
2297 }
2298
2299 /*
2300 * Process read characters if not skipped above
2301 */
2302 op = ccbp->hi_rxopos;
2303 ip = ccbp->hi_rxipos;
2304 c = ip - op;
2305 if (c == 0) {
2306 goto end_rx;
2307 }
2308
2309 n = c & 0xff;
2310 if (n > 250)
2311 n = 250;
2312
2313 DPRINT((pp, DBG_INTR, "n = %d, op = %d, ip = %d\n",
2314 n, op, ip));
2315
2316 /*
2317 * Suck characters out of host card buffer into the
2318 * "input staging buffer" - so that we dont leave the
2319 * host card in limbo while we're possibly echoing
2320 * characters and possibly flushing input inside the
2321 * ldisc l_rint() routine.
2322 */
2323 if (n <= SI_BUFFERSIZE - op) {
2324
2325 DPRINT((pp, DBG_INTR, "\tsingle copy\n"));
2326 z = ccbp->hi_rxbuf + op;
2327 si_vbcopy(z, si_rxbuf, n);
2328
2329 op += n;
2330 } else {
2331 x = SI_BUFFERSIZE - op;
2332
2333 DPRINT((pp, DBG_INTR, "\tdouble part 1 %d\n", x));
2334 z = ccbp->hi_rxbuf + op;
2335 si_vbcopy(z, si_rxbuf, x);
2336
2337 DPRINT((pp, DBG_INTR, "\tdouble part 2 %d\n",
2338 n - x));
2339 z = ccbp->hi_rxbuf;
2340 si_vbcopy(z, si_rxbuf + x, n - x);
2341
2342 op += n;
2343 }
2344
2345 /* clear collected characters from buffer */
2346 ccbp->hi_rxopos = op;
2347
2348 DPRINT((pp, DBG_INTR, "n = %d, op = %d, ip = %d\n",
2349 n, op, ip));
2350
2351 /*
2352 * at this point...
2353 * n = number of chars placed in si_rxbuf
2354 */
2355
2356 /*
2357 * Avoid the grotesquely inefficient lineswitch
2358 * routine (ttyinput) in "raw" mode. It usually
2359 * takes about 450 instructions (that's without
2360 * canonical processing or echo!). slinput is
2361 * reasonably fast (usually 40 instructions
2362 * plus call overhead).
2363 */
2364 if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
2365
2366 /* block if the driver supports it */
2367 if (tp->t_rawq.c_cc + n >= SI_I_HIGH_WATER &&
2368 (tp->t_cflag & CRTS_IFLOW ||
2369 tp->t_iflag & IXOFF) &&
2370 !(tp->t_state & TS_TBLOCK))
2371 ttyblock(tp);
2372
2373 tk_nin += n;
2374 tk_rawcc += n;
2375 tp->t_rawcc += n;
2376
2377 pp->sp_delta_overflows +=
2378 b_to_q((char *)si_rxbuf, n, &tp->t_rawq);
2379
2380 ttwakeup(tp);
2381 if (tp->t_state & TS_TTSTOP &&
2382 (tp->t_iflag & IXANY ||
2383 tp->t_cc[VSTART] == tp->t_cc[VSTOP])) {
2384 tp->t_state &= ~TS_TTSTOP;
2385 tp->t_lflag &= ~FLUSHO;
2386 si_start(tp);
2387 }
2388 } else {
2389 /*
2390 * It'd be nice to not have to go through the
2391 * function call overhead for each char here.
2392 * It'd be nice to block input it, saving a
2393 * loop here and the call/return overhead.
2394 */
2395 for(x = 0; x < n; x++) {
2396 i = si_rxbuf[x];
2397 if ((*linesw[tp->t_line].l_rint)(i, tp)
2398 == -1) {
2399 pp->sp_delta_overflows++;
2400 }
2401 /*
2402 * doesn't seem to be much point doing
2403 * this here.. this driver has no
2404 * softtty processing! ??
2405 */
2406 if (pp->sp_hotchar && i == pp->sp_hotchar) {
2407 setsofttty();
2408 }
2409 }
2410 }
2411 goto more_rx; /* try for more until RXbuf is empty */
2412
2413 end_rx: /* XXX: Again, sorry about the gotos.. :-) */
2414
2415 /*
2416 * Do TX stuff
2417 */
2418 (*linesw[tp->t_line].l_start)(tp);
2419
2420 } /* end of for (all ports on this controller) */
2421 } /* end of for (all controllers) */
2422
2423 in_intr = 0;
2424 DPRINT((0, (unit < 0) ? DBG_POLL:DBG_INTR, "end si_intr(%d)\n", unit));
2425}
2426
2427/*
2428 * Nudge the transmitter...
2429 *
2430 * XXX: I inherited some funny code here. It implies the host card only
2431 * interrupts when the transmit buffer reaches the low-water-mark, and does
2432 * not interrupt when it's actually hits empty. In some cases, we have
2433 * processes waiting for complete drain, and we need to simulate an interrupt
2434 * about when we think the buffer is going to be empty (and retry if not).
2435 * I really am not certain about this... I *need* the hardware manuals.
2436 */
2437static void
2438si_start(tp)
2439 register struct tty *tp;
2440{
2441 struct si_port *pp;
2442 volatile struct si_channel *ccbp;
2443 register struct clist *qp;
2444 BYTE ipos;
2445 int nchar;
2446 int oldspl, count, n, amount, buffer_full;
2447
2448 oldspl = spltty();
2449
2450 qp = &tp->t_outq;
2451 pp = TP2PP(tp);
2452
2453 DPRINT((pp, DBG_ENTRY|DBG_START,
2454 "si_start(%x) t_state %x sp_state %x t_outq.c_cc %d\n",
2455 tp, tp->t_state, pp->sp_state, qp->c_cc));
2456
2457 if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP))
2458 goto out;
2459
2460 buffer_full = 0;
2461 ccbp = pp->sp_ccb;
2462
2463 count = (int)ccbp->hi_txipos - (int)ccbp->hi_txopos;
2464 DPRINT((pp, DBG_START, "count %d\n", (BYTE)count));
2465
2466 while ((nchar = qp->c_cc) > 0) {
2467 if ((BYTE)count >= 255) {
2468 buffer_full++;
2469 break;
2470 }
2471 amount = min(nchar, (255 - (BYTE)count));
2472 ipos = (unsigned int)ccbp->hi_txipos;
2473 n = q_to_b(&tp->t_outq, si_txbuf, amount);
2474 /* will it fit in one lump? */
2475 if ((SI_BUFFERSIZE - ipos) >= n) {
2476 si_bcopyv(si_txbuf, &ccbp->hi_txbuf[ipos], n);
2477 } else {
2478 si_bcopyv(si_txbuf, &ccbp->hi_txbuf[ipos],
2479 SI_BUFFERSIZE - ipos);
2480 si_bcopyv(si_txbuf + (SI_BUFFERSIZE - ipos),
2481 &ccbp->hi_txbuf[0], n - (SI_BUFFERSIZE - ipos));
2482 }
2483 ccbp->hi_txipos += n;
2484 count = (int)ccbp->hi_txipos - (int)ccbp->hi_txopos;
2485 }
2486
2487 if (count != 0 && nchar == 0) {
2488 tp->t_state |= TS_BUSY;
2489 } else {
2490 tp->t_state &= ~TS_BUSY;
2491 }
2492
2493 /* wakeup time? */
2494 ttwwakeup(tp);
2495
2496 DPRINT((pp, DBG_START, "count %d, nchar %d, tp->t_state 0x%x\n",
2497 (BYTE)count, nchar, tp->t_state));
2498
2499 if (tp->t_state & TS_BUSY)
2500 {
2501 int time;
2502
2503 time = ttspeedtab(tp->t_ospeed, chartimes);
2504
2505 if (time > 0) {
2506 if (time < nchar)
2507 time = nchar / time;
2508 else
2509 time = 2;
2510 } else {
2511 DPRINT((pp, DBG_START,
2512 "bad char time value! %d\n", time));
2513 time = hz/10;
2514 }
2515
2516 if ((pp->sp_state & (SS_LSTART|SS_INLSTART)) == SS_LSTART) {
2517 untimeout(si_lstart, (caddr_t)pp, pp->lstart_ch);
2518 } else {
2519 pp->sp_state |= SS_LSTART;
2520 }
2521 DPRINT((pp, DBG_START, "arming lstart, time=%d\n", time));
2522 pp->lstart_ch = timeout(si_lstart, (caddr_t)pp, time);
2523 }
2524
2525out:
2526 splx(oldspl);
2527 DPRINT((pp, DBG_EXIT|DBG_START, "leave si_start()\n"));
2528}
2529
2530/*
2531 * Note: called at splsoftclock from the timeout code
2532 * This has to deal with two things... cause wakeups while waiting for
2533 * tty drains on last process exit, and call l_start at about the right
2534 * time for protocols like ppp.
2535 */
2536static void
2537si_lstart(void *arg)
2538{
2539 register struct si_port *pp = arg;
2540 register struct tty *tp;
2541 int oldspl;
2542
2543 DPRINT((pp, DBG_ENTRY|DBG_LSTART, "si_lstart(%x) sp_state %x\n",
2544 pp, pp->sp_state));
2545
2546 oldspl = spltty();
2547
2548 if ((pp->sp_state & SS_OPEN) == 0 || (pp->sp_state & SS_LSTART) == 0) {
2549 splx(oldspl);
2550 return;
2551 }
2552 pp->sp_state &= ~SS_LSTART;
2553 pp->sp_state |= SS_INLSTART;
2554
2555 tp = pp->sp_tty;
2556
2557 /* deal with the process exit case */
2558 ttwwakeup(tp);
2559
2560 /* nudge protocols - eg: ppp */
2561 (*linesw[tp->t_line].l_start)(tp);
2562
2563 pp->sp_state &= ~SS_INLSTART;
2564 splx(oldspl);
2565}
2566
2567/*
2568 * Stop output on a line. called at spltty();
2569 */
2570void
2585sistop(tp, rw)
2571si_stop(tp, rw)
2586 register struct tty *tp;
2587 int rw;
2588{
2589 volatile struct si_channel *ccbp;
2590 struct si_port *pp;
2591
2592 pp = TP2PP(tp);
2593 ccbp = pp->sp_ccb;
2594
2572 register struct tty *tp;
2573 int rw;
2574{
2575 volatile struct si_channel *ccbp;
2576 struct si_port *pp;
2577
2578 pp = TP2PP(tp);
2579 ccbp = pp->sp_ccb;
2580
2595 DPRINT((TP2PP(tp), DBG_ENTRY|DBG_STOP, "sistop(%x,%x)\n", tp, rw));
2581 DPRINT((TP2PP(tp), DBG_ENTRY|DBG_STOP, "si_stop(%x,%x)\n", tp, rw));
2596
2597 /* XXX: must check (rw & FWRITE | FREAD) etc flushing... */
2598 if (rw & FWRITE) {
2599 /* what level are we meant to be flushing anyway? */
2600 if (tp->t_state & TS_BUSY) {
2601 si_command(TP2PP(tp), WFLUSH, SI_NOWAIT);
2602 tp->t_state &= ~TS_BUSY;
2603 ttwwakeup(tp); /* Bruce???? */
2604 }
2605 }
2606#if 1 /* XXX: this doesn't work right yet.. */
2607 /* XXX: this may have been failing because we used to call l_rint()
2608 * while we were looping based on these two counters. Now, we collect
2609 * the data and then loop stuffing it into l_rint(), making this
2610 * useless. Should we cause this to blow away the staging buffer?
2611 */
2612 if (rw & FREAD) {
2613 ccbp->hi_rxopos = ccbp->hi_rxipos;
2614 }
2615#endif
2616}
2617
2618/*
2619 * Issue a command to the host card CPU.
2620 */
2621
2622static void
2623si_command(pp, cmd, waitflag)
2624 struct si_port *pp; /* port control block (local) */
2625 int cmd;
2626 int waitflag;
2627{
2628 int oldspl;
2629 volatile struct si_channel *ccbp = pp->sp_ccb;
2630 int x;
2631
2632 DPRINT((pp, DBG_ENTRY|DBG_PARAM, "si_command(%x,%x,%d): hi_stat 0x%x\n",
2633 pp, cmd, waitflag, ccbp->hi_stat));
2634
2635 oldspl = spltty(); /* Keep others out */
2636
2637 /* wait until it's finished what it was doing.. */
2638 /* XXX: sits in IDLE_BREAK until something disturbs it or break
2639 * is turned off. */
2640 while((x = ccbp->hi_stat) != IDLE_OPEN &&
2641 x != IDLE_CLOSE &&
2642 x != IDLE_BREAK &&
2643 x != cmd) {
2644 if (in_intr) { /* Prevent sleep in intr */
2645 DPRINT((pp, DBG_PARAM,
2646 "cmd intr collision - completing %d\trequested %d\n",
2647 x, cmd));
2648 splx(oldspl);
2649 return;
2650 } else if (ttysleep(pp->sp_tty, (caddr_t)&pp->sp_state, TTIPRI|PCATCH,
2651 "sicmd1", 1)) {
2652 splx(oldspl);
2653 return;
2654 }
2655 }
2656 /* it should now be in IDLE_{OPEN|CLOSE|BREAK}, or "cmd" */
2657
2658 /* if there was a pending command, cause a state-change wakeup */
2659 switch(pp->sp_pend) {
2660 case LOPEN:
2661 case MPEND:
2662 case MOPEN:
2663 case CONFIG:
2664 case SBREAK:
2665 case EBREAK:
2666 wakeup(&pp->sp_state);
2667 break;
2668 default:
2669 break;
2670 }
2671
2672 pp->sp_pend = cmd; /* New command pending */
2673 ccbp->hi_stat = cmd; /* Post it */
2674
2675 if (waitflag) {
2676 if (in_intr) { /* If in interrupt handler */
2677 DPRINT((pp, DBG_PARAM,
2678 "attempt to sleep in si_intr - cmd req %d\n",
2679 cmd));
2680 splx(oldspl);
2681 return;
2682 } else while(ccbp->hi_stat != IDLE_OPEN &&
2683 ccbp->hi_stat != IDLE_BREAK) {
2684 if (ttysleep(pp->sp_tty, (caddr_t)&pp->sp_state, TTIPRI|PCATCH,
2685 "sicmd2", 0))
2686 break;
2687 }
2688 }
2689 splx(oldspl);
2690}
2691
2692static void
2693si_disc_optim(tp, t, pp)
2694 struct tty *tp;
2695 struct termios *t;
2696 struct si_port *pp;
2697{
2698 /*
2699 * XXX can skip a lot more cases if Smarts. Maybe
2700 * (IGNCR | ISTRIP | IXON) in c_iflag. But perhaps we
2701 * shouldn't skip if (TS_CNTTB | TS_LNCH) is set in t_state.
2702 */
2703 if (!(t->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR | ISTRIP | IXON)) &&
2704 (!(t->c_iflag & BRKINT) || (t->c_iflag & IGNBRK)) &&
2705 (!(t->c_iflag & PARMRK) ||
2706 (t->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK)) &&
2707 !(t->c_lflag & (ECHO | ICANON | IEXTEN | ISIG | PENDIN)) &&
2708 linesw[tp->t_line].l_rint == ttyinput)
2709 tp->t_state |= TS_CAN_BYPASS_L_RINT;
2710 else
2711 tp->t_state &= ~TS_CAN_BYPASS_L_RINT;
2712 pp->sp_hotchar = linesw[tp->t_line].l_hotchar;
2713 DPRINT((pp, DBG_OPTIM, "bypass: %s, hotchar: %x\n",
2714 (tp->t_state & TS_CAN_BYPASS_L_RINT) ? "on" : "off",
2715 pp->sp_hotchar));
2716}
2717
2718
2719#ifdef SI_DEBUG
2720
2721static void
2722#ifdef __STDC__
2723si_dprintf(struct si_port *pp, int flags, const char *fmt, ...)
2724#else
2725si_dprintf(pp, flags, fmt, va_alist)
2726 struct si_port *pp;
2727 int flags;
2728 char *fmt;
2729#endif
2730{
2731 va_list ap;
2732
2733 if ((pp == NULL && (si_debug&flags)) ||
2734 (pp != NULL && ((pp->sp_debug&flags) || (si_debug&flags)))) {
2735 if (pp != NULL)
2736 printf("%ci%d(%d): ", 's',
2737 (int)SI_CARD(minor(pp->sp_tty->t_dev)),
2738 (int)SI_PORT(minor(pp->sp_tty->t_dev)));
2739 va_start(ap, fmt);
2740 vprintf(fmt, ap);
2741 va_end(ap);
2742 }
2743}
2744
2745static char *
2746si_mctl2str(cmd)
2747 enum si_mctl cmd;
2748{
2749 switch (cmd) {
2750 case GET:
2751 return("GET");
2752 case SET:
2753 return("SET");
2754 case BIS:
2755 return("BIS");
2756 case BIC:
2757 return("BIC");
2758 }
2759 return("BAD");
2760}
2761
2762#endif /* DEBUG */
2763
2764static char *
2765si_modulename(host_type, uart_type)
2766 int host_type, uart_type;
2767{
2768 switch (host_type) {
2769 /* Z280 based cards */
2770#if NEISA > 0
2771 case SIEISA:
2772#endif
2773 case SIHOST2:
2774 case SIHOST:
2775#if NPCI > 0
2776 case SIPCI:
2777#endif
2778 switch (uart_type) {
2779 case 0:
2780 return(" (XIO)");
2781 case 1:
2782 return(" (SI)");
2783 }
2784 break;
2785 /* T225 based hosts */
2786#if NPCI > 0
2787 case SIJETPCI:
2788#endif
2789 case SIJETISA:
2790 switch (uart_type) {
2791 case 0:
2792 return(" (SI)");
2793 case 40:
2794 return(" (XIO)");
2795 case 72:
2796 return(" (SXDC)");
2797 }
2798 break;
2799 }
2800 return("");
2801}
2802
2803static void
2804si_drvinit(void *unused)
2805{
2806
2807 cdevsw_add(&si_cdevsw);
2808}
2809
2810SYSINIT(sidev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,si_drvinit,NULL)
2811
2582
2583 /* XXX: must check (rw & FWRITE | FREAD) etc flushing... */
2584 if (rw & FWRITE) {
2585 /* what level are we meant to be flushing anyway? */
2586 if (tp->t_state & TS_BUSY) {
2587 si_command(TP2PP(tp), WFLUSH, SI_NOWAIT);
2588 tp->t_state &= ~TS_BUSY;
2589 ttwwakeup(tp); /* Bruce???? */
2590 }
2591 }
2592#if 1 /* XXX: this doesn't work right yet.. */
2593 /* XXX: this may have been failing because we used to call l_rint()
2594 * while we were looping based on these two counters. Now, we collect
2595 * the data and then loop stuffing it into l_rint(), making this
2596 * useless. Should we cause this to blow away the staging buffer?
2597 */
2598 if (rw & FREAD) {
2599 ccbp->hi_rxopos = ccbp->hi_rxipos;
2600 }
2601#endif
2602}
2603
2604/*
2605 * Issue a command to the host card CPU.
2606 */
2607
2608static void
2609si_command(pp, cmd, waitflag)
2610 struct si_port *pp; /* port control block (local) */
2611 int cmd;
2612 int waitflag;
2613{
2614 int oldspl;
2615 volatile struct si_channel *ccbp = pp->sp_ccb;
2616 int x;
2617
2618 DPRINT((pp, DBG_ENTRY|DBG_PARAM, "si_command(%x,%x,%d): hi_stat 0x%x\n",
2619 pp, cmd, waitflag, ccbp->hi_stat));
2620
2621 oldspl = spltty(); /* Keep others out */
2622
2623 /* wait until it's finished what it was doing.. */
2624 /* XXX: sits in IDLE_BREAK until something disturbs it or break
2625 * is turned off. */
2626 while((x = ccbp->hi_stat) != IDLE_OPEN &&
2627 x != IDLE_CLOSE &&
2628 x != IDLE_BREAK &&
2629 x != cmd) {
2630 if (in_intr) { /* Prevent sleep in intr */
2631 DPRINT((pp, DBG_PARAM,
2632 "cmd intr collision - completing %d\trequested %d\n",
2633 x, cmd));
2634 splx(oldspl);
2635 return;
2636 } else if (ttysleep(pp->sp_tty, (caddr_t)&pp->sp_state, TTIPRI|PCATCH,
2637 "sicmd1", 1)) {
2638 splx(oldspl);
2639 return;
2640 }
2641 }
2642 /* it should now be in IDLE_{OPEN|CLOSE|BREAK}, or "cmd" */
2643
2644 /* if there was a pending command, cause a state-change wakeup */
2645 switch(pp->sp_pend) {
2646 case LOPEN:
2647 case MPEND:
2648 case MOPEN:
2649 case CONFIG:
2650 case SBREAK:
2651 case EBREAK:
2652 wakeup(&pp->sp_state);
2653 break;
2654 default:
2655 break;
2656 }
2657
2658 pp->sp_pend = cmd; /* New command pending */
2659 ccbp->hi_stat = cmd; /* Post it */
2660
2661 if (waitflag) {
2662 if (in_intr) { /* If in interrupt handler */
2663 DPRINT((pp, DBG_PARAM,
2664 "attempt to sleep in si_intr - cmd req %d\n",
2665 cmd));
2666 splx(oldspl);
2667 return;
2668 } else while(ccbp->hi_stat != IDLE_OPEN &&
2669 ccbp->hi_stat != IDLE_BREAK) {
2670 if (ttysleep(pp->sp_tty, (caddr_t)&pp->sp_state, TTIPRI|PCATCH,
2671 "sicmd2", 0))
2672 break;
2673 }
2674 }
2675 splx(oldspl);
2676}
2677
2678static void
2679si_disc_optim(tp, t, pp)
2680 struct tty *tp;
2681 struct termios *t;
2682 struct si_port *pp;
2683{
2684 /*
2685 * XXX can skip a lot more cases if Smarts. Maybe
2686 * (IGNCR | ISTRIP | IXON) in c_iflag. But perhaps we
2687 * shouldn't skip if (TS_CNTTB | TS_LNCH) is set in t_state.
2688 */
2689 if (!(t->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR | ISTRIP | IXON)) &&
2690 (!(t->c_iflag & BRKINT) || (t->c_iflag & IGNBRK)) &&
2691 (!(t->c_iflag & PARMRK) ||
2692 (t->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK)) &&
2693 !(t->c_lflag & (ECHO | ICANON | IEXTEN | ISIG | PENDIN)) &&
2694 linesw[tp->t_line].l_rint == ttyinput)
2695 tp->t_state |= TS_CAN_BYPASS_L_RINT;
2696 else
2697 tp->t_state &= ~TS_CAN_BYPASS_L_RINT;
2698 pp->sp_hotchar = linesw[tp->t_line].l_hotchar;
2699 DPRINT((pp, DBG_OPTIM, "bypass: %s, hotchar: %x\n",
2700 (tp->t_state & TS_CAN_BYPASS_L_RINT) ? "on" : "off",
2701 pp->sp_hotchar));
2702}
2703
2704
2705#ifdef SI_DEBUG
2706
2707static void
2708#ifdef __STDC__
2709si_dprintf(struct si_port *pp, int flags, const char *fmt, ...)
2710#else
2711si_dprintf(pp, flags, fmt, va_alist)
2712 struct si_port *pp;
2713 int flags;
2714 char *fmt;
2715#endif
2716{
2717 va_list ap;
2718
2719 if ((pp == NULL && (si_debug&flags)) ||
2720 (pp != NULL && ((pp->sp_debug&flags) || (si_debug&flags)))) {
2721 if (pp != NULL)
2722 printf("%ci%d(%d): ", 's',
2723 (int)SI_CARD(minor(pp->sp_tty->t_dev)),
2724 (int)SI_PORT(minor(pp->sp_tty->t_dev)));
2725 va_start(ap, fmt);
2726 vprintf(fmt, ap);
2727 va_end(ap);
2728 }
2729}
2730
2731static char *
2732si_mctl2str(cmd)
2733 enum si_mctl cmd;
2734{
2735 switch (cmd) {
2736 case GET:
2737 return("GET");
2738 case SET:
2739 return("SET");
2740 case BIS:
2741 return("BIS");
2742 case BIC:
2743 return("BIC");
2744 }
2745 return("BAD");
2746}
2747
2748#endif /* DEBUG */
2749
2750static char *
2751si_modulename(host_type, uart_type)
2752 int host_type, uart_type;
2753{
2754 switch (host_type) {
2755 /* Z280 based cards */
2756#if NEISA > 0
2757 case SIEISA:
2758#endif
2759 case SIHOST2:
2760 case SIHOST:
2761#if NPCI > 0
2762 case SIPCI:
2763#endif
2764 switch (uart_type) {
2765 case 0:
2766 return(" (XIO)");
2767 case 1:
2768 return(" (SI)");
2769 }
2770 break;
2771 /* T225 based hosts */
2772#if NPCI > 0
2773 case SIJETPCI:
2774#endif
2775 case SIJETISA:
2776 switch (uart_type) {
2777 case 0:
2778 return(" (SI)");
2779 case 40:
2780 return(" (XIO)");
2781 case 72:
2782 return(" (SXDC)");
2783 }
2784 break;
2785 }
2786 return("");
2787}
2788
2789static void
2790si_drvinit(void *unused)
2791{
2792
2793 cdevsw_add(&si_cdevsw);
2794}
2795
2796SYSINIT(sidev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,si_drvinit,NULL)
2797