Deleted Added
full compact
si.c (166091) si.c (179589)
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) 2000, Peter Wemm <peter@netplex.com.au>
7 *
8 * Originally derived from: SunOS 4.x version

--- 19 unchanged lines hidden (view full) ---

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 */
34
35#include <sys/cdefs.h>
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) 2000, Peter Wemm <peter@netplex.com.au>
7 *
8 * Originally derived from: SunOS 4.x version

--- 19 unchanged lines hidden (view full) ---

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 */
34
35#include <sys/cdefs.h>
36__FBSDID("$FreeBSD: head/sys/dev/si/si.c 166091 2007-01-18 13:33:36Z marius $");
36__FBSDID("$FreeBSD: head/sys/dev/si/si.c 179589 2008-06-06 03:21:59Z peter $");
37
38#ifndef lint
39static const char si_copyright1[] = "@(#) Copyright (C) Specialix International, 1990,1992,1998",
40 si_copyright2[] = "@(#) Copyright (C) Andy Rutter 1993",
41 si_copyright3[] = "@(#) Copyright (C) Peter Wemm 2000";
42#endif /* not lint */
43
44#include "opt_compat.h"

--- 33 unchanged lines hidden (view full) ---

78 *
79 * The controller is interfaced to the host via dual port RAM
80 * and an interrupt.
81 *
82 * The code for the Host 1 (very old ISA cards) has not been tested.
83 */
84
85#define POLL /* turn on poller to scan for lost interrupts */
37
38#ifndef lint
39static const char si_copyright1[] = "@(#) Copyright (C) Specialix International, 1990,1992,1998",
40 si_copyright2[] = "@(#) Copyright (C) Andy Rutter 1993",
41 si_copyright3[] = "@(#) Copyright (C) Peter Wemm 2000";
42#endif /* not lint */
43
44#include "opt_compat.h"

--- 33 unchanged lines hidden (view full) ---

78 *
79 * The controller is interfaced to the host via dual port RAM
80 * and an interrupt.
81 *
82 * The code for the Host 1 (very old ISA cards) has not been tested.
83 */
84
85#define POLL /* turn on poller to scan for lost interrupts */
86#if 0
86#define REALPOLL /* on each poll, scan for work regardless */
87#define REALPOLL /* on each poll, scan for work regardless */
88#endif
87#define POLLHZ (hz/10) /* 10 times per second */
88#define SI_I_HIGH_WATER (TTYHOG - 2 * SI_BUFFERSIZE)
89#define INT_COUNT 25000 /* max of 125 ints per second */
90#define JET_INT_COUNT 100 /* max of 100 ints per second */
91#define RXINT_COUNT 1 /* one rxint per 10 milliseconds */
92
93static void si_command(struct si_port *, int, int);
94static int si_Sioctl(struct cdev *, u_long, caddr_t, int, struct thread *);

--- 66 unchanged lines hidden (view full) ---

161 { B4800, 480, },
162 { B9600, 960, },
163 { B19200, 1920, },
164 { B38400, 3840, },
165 { B57600, 5760, },
166 { B115200, 11520, },
167 { -1, -1 },
168};
89#define POLLHZ (hz/10) /* 10 times per second */
90#define SI_I_HIGH_WATER (TTYHOG - 2 * SI_BUFFERSIZE)
91#define INT_COUNT 25000 /* max of 125 ints per second */
92#define JET_INT_COUNT 100 /* max of 100 ints per second */
93#define RXINT_COUNT 1 /* one rxint per 10 milliseconds */
94
95static void si_command(struct si_port *, int, int);
96static int si_Sioctl(struct cdev *, u_long, caddr_t, int, struct thread *);

--- 66 unchanged lines hidden (view full) ---

163 { B4800, 480, },
164 { B9600, 960, },
165 { B19200, 1920, },
166 { B38400, 3840, },
167 { B57600, 5760, },
168 { B115200, 11520, },
169 { -1, -1 },
170};
169static volatile int in_intr = 0; /* Inside interrupt handler? */
170
171#ifdef POLL
172static int si_pollrate; /* in addition to irq */
173static int si_realpoll = 0; /* poll HW on timer */
174
175SYSCTL_INT(_machdep, OID_AUTO, si_pollrate, CTLFLAG_RW, &si_pollrate, 0, "");
176SYSCTL_INT(_machdep, OID_AUTO, si_realpoll, CTLFLAG_RW, &si_realpoll, 0, "");
177

--- 11 unchanged lines hidden (view full) ---

189 "SIMCA", /* FreeBSD does not support Microchannel */
190 "SIHOST2",
191 "SIEISA",
192 "SIPCI",
193 "SXPCI",
194 "SXISA",
195};
196
171
172#ifdef POLL
173static int si_pollrate; /* in addition to irq */
174static int si_realpoll = 0; /* poll HW on timer */
175
176SYSCTL_INT(_machdep, OID_AUTO, si_pollrate, CTLFLAG_RW, &si_pollrate, 0, "");
177SYSCTL_INT(_machdep, OID_AUTO, si_realpoll, CTLFLAG_RW, &si_realpoll, 0, "");
178

--- 11 unchanged lines hidden (view full) ---

190 "SIMCA", /* FreeBSD does not support Microchannel */
191 "SIHOST2",
192 "SIEISA",
193 "SIPCI",
194 "SXPCI",
195 "SXISA",
196};
197
198#ifdef SI_DEBUG
199static char *
200si_cmdname(int cmd)
201{
202 static char buf[32];
203
204 switch (cmd) {
205 case IDLE_OPEN: return("IDLE_OPEN");
206 case LOPEN: return("LOPEN");
207 case MOPEN: return("MOPEN");
208 case MPEND: return("MPEND");
209 case CONFIG: return("CONFIG");
210 case CLOSE: return("CLOSE");
211 case SBREAK: return("SBREAK");
212 case EBREAK: return("EBREAK");
213 case IDLE_CLOSE: return("IDLE_CLOSE");
214 case IDLE_BREAK: return("IDLE_BREAK");
215 case FCLOSE: return("FCLOSE");
216 case RESUME: return("RESUME");
217 case WFLUSH: return("WFLUSH");
218 case RFLUSH: return("RFLUSH");
219 default:
220 sprintf(buf, "?cmd:0x%x?", cmd);
221 return (buf);
222 }
223}
224#endif
225
197/*
198 * We have to make an 8 bit version of bcopy, since some cards can't
199 * deal with 32 bit I/O
200 */
201static void __inline
202si_bcopy(const void *src, void *dst, size_t len)
203{
204 u_char *d;

--- 384 unchanged lines hidden (view full) ---

589 "si_control");
590 return (0);
591}
592
593static int
594siopen(struct tty *tp, struct cdev *dev)
595{
596
226/*
227 * We have to make an 8 bit version of bcopy, since some cards can't
228 * deal with 32 bit I/O
229 */
230static void __inline
231si_bcopy(const void *src, void *dst, size_t len)
232{
233 u_char *d;

--- 384 unchanged lines hidden (view full) ---

618 "si_control");
619 return (0);
620}
621
622static int
623siopen(struct tty *tp, struct cdev *dev)
624{
625
626 mtx_assert(&Giant, MA_OWNED);
597#ifdef POLL
598 /*
599 * We've now got a device, so start the poller.
600 */
601 if (init_finished == 0) {
602 timeout(si_poll, (caddr_t)0L, si_pollrate);
603 init_finished = 1;
604 }
605#endif
606 return(0);
607}
608
609static void
610siclose(struct tty *tp)
611{
612 struct si_port *pp;
613
627#ifdef POLL
628 /*
629 * We've now got a device, so start the poller.
630 */
631 if (init_finished == 0) {
632 timeout(si_poll, (caddr_t)0L, si_pollrate);
633 init_finished = 1;
634 }
635#endif
636 return(0);
637}
638
639static void
640siclose(struct tty *tp)
641{
642 struct si_port *pp;
643
644 mtx_assert(&Giant, MA_OWNED);
614 pp = tp->t_sc;
645 pp = tp->t_sc;
615 (void) si_command(pp, FCLOSE, SI_NOWAIT);
646 (void) si_command(pp, FCLOSE, SI_WAIT);
616}
617
618static void
619sibreak(struct tty *tp, int sig)
620{
621 struct si_port *pp;
622
647}
648
649static void
650sibreak(struct tty *tp, int sig)
651{
652 struct si_port *pp;
653
654 mtx_assert(&Giant, MA_OWNED);
623 pp = tp->t_sc;
624 if (sig)
625 si_command(pp, SBREAK, SI_WAIT);
626 else
627 si_command(pp, EBREAK, SI_WAIT);
628}
629
630

--- 9 unchanged lines hidden (view full) ---

640 struct si_tcsi *dp;
641 struct si_pstat *sps;
642 int *ip, error = 0;
643 int oldspl;
644 int card, port;
645
646 DPRINT((0, DBG_ENTRY|DBG_IOCTL, "si_Sioctl(%s,%lx,%x,%x)\n",
647 devtoname(dev), cmd, data, flag));
655 pp = tp->t_sc;
656 if (sig)
657 si_command(pp, SBREAK, SI_WAIT);
658 else
659 si_command(pp, EBREAK, SI_WAIT);
660}
661
662

--- 9 unchanged lines hidden (view full) ---

672 struct si_tcsi *dp;
673 struct si_pstat *sps;
674 int *ip, error = 0;
675 int oldspl;
676 int card, port;
677
678 DPRINT((0, DBG_ENTRY|DBG_IOCTL, "si_Sioctl(%s,%lx,%x,%x)\n",
679 devtoname(dev), cmd, data, flag));
680 mtx_assert(&Giant, MA_OWNED);
648
649#if 1
650 DPRINT((0, DBG_IOCTL, "TCSI_PORT=%x\n", TCSI_PORT));
651 DPRINT((0, DBG_IOCTL, "TCSI_CCB=%x\n", TCSI_CCB));
652 DPRINT((0, DBG_IOCTL, "TCSI_TTY=%x\n", TCSI_TTY));
653#endif
654
655 oldspl = spltty(); /* better safe than sorry */

--- 125 unchanged lines hidden (view full) ---

781 volatile struct si_channel *ccbp;
782 int oldspl, cflag, iflag, oflag, lflag;
783 int error = 0; /* shutup gcc */
784 int ispeed = 0; /* shutup gcc */
785 int ospeed = 0; /* shutup gcc */
786 BYTE val;
787
788 DPRINT((pp, DBG_ENTRY|DBG_PARAM, "siparam(%x,%x)\n", tp, t));
681
682#if 1
683 DPRINT((0, DBG_IOCTL, "TCSI_PORT=%x\n", TCSI_PORT));
684 DPRINT((0, DBG_IOCTL, "TCSI_CCB=%x\n", TCSI_CCB));
685 DPRINT((0, DBG_IOCTL, "TCSI_TTY=%x\n", TCSI_TTY));
686#endif
687
688 oldspl = spltty(); /* better safe than sorry */

--- 125 unchanged lines hidden (view full) ---

814 volatile struct si_channel *ccbp;
815 int oldspl, cflag, iflag, oflag, lflag;
816 int error = 0; /* shutup gcc */
817 int ispeed = 0; /* shutup gcc */
818 int ospeed = 0; /* shutup gcc */
819 BYTE val;
820
821 DPRINT((pp, DBG_ENTRY|DBG_PARAM, "siparam(%x,%x)\n", tp, t));
822 mtx_assert(&Giant, MA_OWNED);
789 cflag = t->c_cflag;
790 iflag = t->c_iflag;
791 oflag = t->c_oflag;
792 lflag = t->c_lflag;
793 DPRINT((pp, DBG_PARAM, "OFLAG 0x%x CFLAG 0x%x IFLAG 0x%x LFLAG 0x%x\n",
794 oflag, cflag, iflag, lflag));
795
796 /* XXX - if Jet host and SXDC module, use extended baud rates */

--- 152 unchanged lines hidden (view full) ---

949simodem(struct tty *tp, int sigon, int sigoff)
950{
951 struct si_port *pp;
952 volatile struct si_channel *ccbp;
953 int x;
954
955 pp = tp->t_sc;
956 DPRINT((pp, DBG_ENTRY|DBG_MODEM, "simodem(%x,%x)\n", sigon, sigoff));
823 cflag = t->c_cflag;
824 iflag = t->c_iflag;
825 oflag = t->c_oflag;
826 lflag = t->c_lflag;
827 DPRINT((pp, DBG_PARAM, "OFLAG 0x%x CFLAG 0x%x IFLAG 0x%x LFLAG 0x%x\n",
828 oflag, cflag, iflag, lflag));
829
830 /* XXX - if Jet host and SXDC module, use extended baud rates */

--- 152 unchanged lines hidden (view full) ---

983simodem(struct tty *tp, int sigon, int sigoff)
984{
985 struct si_port *pp;
986 volatile struct si_channel *ccbp;
987 int x;
988
989 pp = tp->t_sc;
990 DPRINT((pp, DBG_ENTRY|DBG_MODEM, "simodem(%x,%x)\n", sigon, sigoff));
991 mtx_assert(&Giant, MA_OWNED);
957 ccbp = pp->sp_ccb; /* Find channel address */
958 if (sigon == 0 && sigoff == 0) {
959 x = ccbp->hi_ip;
960 /*
961 * XXX: not sure this is correct, should it be CTS&DSR ?
962 * XXX: or do we (just) miss CTS & DSR ?
963 */
964 if (x & IP_DCD) sigon |= SER_DCD;

--- 18 unchanged lines hidden (view full) ---

983
984/*
985 * Handle change of modem state
986 */
987static void
988si_modem_state(struct si_port *pp, struct tty *tp, int hi_ip)
989{
990 /* if a modem dev */
992 ccbp = pp->sp_ccb; /* Find channel address */
993 if (sigon == 0 && sigoff == 0) {
994 x = ccbp->hi_ip;
995 /*
996 * XXX: not sure this is correct, should it be CTS&DSR ?
997 * XXX: or do we (just) miss CTS & DSR ?
998 */
999 if (x & IP_DCD) sigon |= SER_DCD;

--- 18 unchanged lines hidden (view full) ---

1018
1019/*
1020 * Handle change of modem state
1021 */
1022static void
1023si_modem_state(struct si_port *pp, struct tty *tp, int hi_ip)
1024{
1025 /* if a modem dev */
1026 mtx_assert(&Giant, MA_OWNED);
991 if (hi_ip & IP_DCD) {
992 if (!(pp->sp_last_hi_ip & IP_DCD)) {
993 DPRINT((pp, DBG_INTR, "modem carr on t_line %d\n",
994 tp->t_line));
995 (void)ttyld_modem(tp, 1);
996 }
997 } else {
998 if (pp->sp_last_hi_ip & IP_DCD) {

--- 19 unchanged lines hidden (view full) ---

1018 struct si_softc *sc;
1019 int i;
1020 volatile struct si_reg *regp;
1021 struct si_port *pp;
1022 int lost, oldspl, port;
1023
1024 DPRINT((0, DBG_POLL, "si_poll()\n"));
1025 oldspl = spltty();
1027 if (hi_ip & IP_DCD) {
1028 if (!(pp->sp_last_hi_ip & IP_DCD)) {
1029 DPRINT((pp, DBG_INTR, "modem carr on t_line %d\n",
1030 tp->t_line));
1031 (void)ttyld_modem(tp, 1);
1032 }
1033 } else {
1034 if (pp->sp_last_hi_ip & IP_DCD) {

--- 19 unchanged lines hidden (view full) ---

1054 struct si_softc *sc;
1055 int i;
1056 volatile struct si_reg *regp;
1057 struct si_port *pp;
1058 int lost, oldspl, port;
1059
1060 DPRINT((0, DBG_POLL, "si_poll()\n"));
1061 oldspl = spltty();
1026 if (in_intr)
1027 goto out;
1062 mtx_assert(&Giant, MA_OWNED);
1028 lost = 0;
1029 for (i = 0; i < si_numunits; i++) {
1030 sc = devclass_get_softc(si_devclass, i);
1031 if (sc == NULL || sc->sc_type == SIEMPTY)
1032 continue;
1033 regp = (struct si_reg *)sc->sc_maddr;
1034
1035 /*

--- 20 unchanged lines hidden (view full) ---

1056 printf("si%d: %d tty level buffer overflows\n",
1057 i, pp->sp_delta_overflows);
1058 pp->sp_delta_overflows = 0;
1059 }
1060 }
1061 }
1062 if (lost || si_realpoll)
1063 si_intr(NULL); /* call intr with fake vector */
1063 lost = 0;
1064 for (i = 0; i < si_numunits; i++) {
1065 sc = devclass_get_softc(si_devclass, i);
1066 if (sc == NULL || sc->sc_type == SIEMPTY)
1067 continue;
1068 regp = (struct si_reg *)sc->sc_maddr;
1069
1070 /*

--- 20 unchanged lines hidden (view full) ---

1091 printf("si%d: %d tty level buffer overflows\n",
1092 i, pp->sp_delta_overflows);
1093 pp->sp_delta_overflows = 0;
1094 }
1095 }
1096 }
1097 if (lost || si_realpoll)
1098 si_intr(NULL); /* call intr with fake vector */
1064out:
1065 splx(oldspl);
1066
1067 timeout(si_poll, (caddr_t)0L, si_pollrate);
1068}
1069#endif /* ifdef POLL */
1070
1071/*
1072 * The interrupt handler polls ALL ports on ALL adapters each time

--- 12 unchanged lines hidden (view full) ---

1085 struct tty *tp;
1086 volatile caddr_t maddr;
1087 BYTE op, ip;
1088 int x, card, port, n, i, isopen;
1089 volatile BYTE *z;
1090 BYTE c;
1091
1092 sc = arg;
1099 splx(oldspl);
1100
1101 timeout(si_poll, (caddr_t)0L, si_pollrate);
1102}
1103#endif /* ifdef POLL */
1104
1105/*
1106 * The interrupt handler polls ALL ports on ALL adapters each time

--- 12 unchanged lines hidden (view full) ---

1119 struct tty *tp;
1120 volatile caddr_t maddr;
1121 BYTE op, ip;
1122 int x, card, port, n, i, isopen;
1123 volatile BYTE *z;
1124 BYTE c;
1125
1126 sc = arg;
1127 mtx_assert(&Giant, MA_OWNED);
1093
1094 DPRINT((0, arg == NULL ? DBG_POLL:DBG_INTR, "si_intr\n"));
1128
1129 DPRINT((0, arg == NULL ? DBG_POLL:DBG_INTR, "si_intr\n"));
1095 if (in_intr)
1096 return;
1097 in_intr = 1;
1098
1099 /*
1100 * When we get an int we poll all the channels and do ALL pending
1101 * work, not just the first one we find. This allows all cards to
1102 * share the same vector.
1103 *
1104 * XXX - But if we're sharing the vector with something that's NOT
1105 * a SI/XIO/SX card, we may be making more work for ourselves.

--- 52 unchanged lines hidden (view full) ---

1158 ccbp = pp->sp_ccb;
1159 tp = pp->sp_tty;
1160
1161 /*
1162 * See if a command has completed ?
1163 */
1164 if (ccbp->hi_stat != pp->sp_pend) {
1165 DPRINT((pp, DBG_INTR,
1130
1131 /*
1132 * When we get an int we poll all the channels and do ALL pending
1133 * work, not just the first one we find. This allows all cards to
1134 * share the same vector.
1135 *
1136 * XXX - But if we're sharing the vector with something that's NOT
1137 * a SI/XIO/SX card, we may be making more work for ourselves.

--- 52 unchanged lines hidden (view full) ---

1190 ccbp = pp->sp_ccb;
1191 tp = pp->sp_tty;
1192
1193 /*
1194 * See if a command has completed ?
1195 */
1196 if (ccbp->hi_stat != pp->sp_pend) {
1197 DPRINT((pp, DBG_INTR,
1166 "si_intr hi_stat = 0x%x, pend = %d\n",
1167 ccbp->hi_stat, pp->sp_pend));
1198 "si_intr hi_stat = %s, pend = %s\n",
1199 si_cmdname(ccbp->hi_stat),
1200 si_cmdname(pp->sp_pend)));
1168 switch(pp->sp_pend) {
1169 case LOPEN:
1170 case MPEND:
1171 case MOPEN:
1201 switch(pp->sp_pend) {
1202 case LOPEN:
1203 case MPEND:
1204 case MOPEN:
1205 case FCLOSE:
1172 case CONFIG:
1173 case SBREAK:
1174 case EBREAK:
1206 case CONFIG:
1207 case SBREAK:
1208 case EBREAK:
1175 pp->sp_pend = ccbp->hi_stat;
1176 /* sleeping in si_command */
1209 /* sleeping in si_command */
1210 DPRINT((pp, DBG_INTR, "do wakeup\n"));
1177 wakeup(&pp->sp_state);
1178 break;
1211 wakeup(&pp->sp_state);
1212 break;
1179 default:
1180 pp->sp_pend = ccbp->hi_stat;
1181 }
1213 }
1214 pp->sp_pend = ccbp->hi_stat;
1182 }
1183
1184 /*
1185 * Continue on if it's closed
1186 */
1215 }
1216
1217 /*
1218 * Continue on if it's closed
1219 */
1187 if (ccbp->hi_stat == IDLE_CLOSE) {
1220 if (ccbp->hi_stat == IDLE_CLOSE)
1188 continue;
1221 continue;
1189 }
1190
1191 /*
1192 * Do modem state change if not a local device
1193 */
1194 si_modem_state(pp, tp, ccbp->hi_ip);
1195
1196 /*
1197 * Check to see if we should 'receive' characters.
1198 */
1199 if (tp->t_state & TS_CONNECTED &&
1200 tp->t_state & TS_ISOPEN)
1201 isopen = 1;
1202 else
1203 isopen = 0;
1204
1205 /*
1206 * Do input break processing
1207 */
1208 if (ccbp->hi_state & ST_BREAK) {
1222
1223 /*
1224 * Do modem state change if not a local device
1225 */
1226 si_modem_state(pp, tp, ccbp->hi_ip);
1227
1228 /*
1229 * Check to see if we should 'receive' characters.
1230 */
1231 if (tp->t_state & TS_CONNECTED &&
1232 tp->t_state & TS_ISOPEN)
1233 isopen = 1;
1234 else
1235 isopen = 0;
1236
1237 /*
1238 * Do input break processing
1239 */
1240 if (ccbp->hi_state & ST_BREAK) {
1209 if (isopen) {
1241 if (isopen)
1210 ttyld_rint(tp, TTY_BI);
1242 ttyld_rint(tp, TTY_BI);
1211 }
1212 ccbp->hi_state &= ~ST_BREAK; /* A Bit iffy this */
1213 DPRINT((pp, DBG_INTR, "si_intr break\n"));
1214 }
1215
1216 /*
1217 * Do RX stuff - if not open then dump any characters.
1218 * XXX: This is VERY messy and needs to be cleaned up.
1219 *
1220 * XXX: can we leave data in the host adapter buffer
1221 * when the clists are full? That may be dangerous
1222 * if the user cannot get an interrupt signal through.
1223 */
1224
1243 ccbp->hi_state &= ~ST_BREAK; /* A Bit iffy this */
1244 DPRINT((pp, DBG_INTR, "si_intr break\n"));
1245 }
1246
1247 /*
1248 * Do RX stuff - if not open then dump any characters.
1249 * XXX: This is VERY messy and needs to be cleaned up.
1250 *
1251 * XXX: can we leave data in the host adapter buffer
1252 * when the clists are full? That may be dangerous
1253 * if the user cannot get an interrupt signal through.
1254 */
1255
1225 more_rx: /* XXX Sorry. the nesting was driving me bats! :-( */
1256 more_rx:
1226
1227 if (!isopen) {
1228 ccbp->hi_rxopos = ccbp->hi_rxipos;
1229 goto end_rx;
1230 }
1231
1232 /*
1233 * If the tty input buffers are blocked, stop emptying
1234 * the incoming buffers and let the auto flow control
1235 * assert..
1236 */
1257
1258 if (!isopen) {
1259 ccbp->hi_rxopos = ccbp->hi_rxipos;
1260 goto end_rx;
1261 }
1262
1263 /*
1264 * If the tty input buffers are blocked, stop emptying
1265 * the incoming buffers and let the auto flow control
1266 * assert..
1267 */
1237 if (tp->t_state & TS_TBLOCK) {
1268 if (tp->t_state & TS_TBLOCK)
1238 goto end_rx;
1269 goto end_rx;
1239 }
1240
1241 /*
1242 * Process read characters if not skipped above
1243 */
1244 op = ccbp->hi_rxopos;
1245 ip = ccbp->hi_rxipos;
1246 c = ip - op;
1270
1271 /*
1272 * Process read characters if not skipped above
1273 */
1274 op = ccbp->hi_rxopos;
1275 ip = ccbp->hi_rxipos;
1276 c = ip - op;
1247 if (c == 0) {
1277 if (c == 0)
1248 goto end_rx;
1278 goto end_rx;
1249 }
1250
1251 n = c & 0xff;
1252 if (n > 250)
1253 n = 250;
1254
1255 DPRINT((pp, DBG_INTR, "n = %d, op = %d, ip = %d\n",
1256 n, op, ip));
1257
1258 /*
1259 * Suck characters out of host card buffer into the
1260 * "input staging buffer" - so that we dont leave the
1261 * host card in limbo while we're possibly echoing
1262 * characters and possibly flushing input inside the
1263 * ldisc l_rint() routine.
1264 */
1265 if (n <= SI_BUFFERSIZE - op) {
1266
1279
1280 n = c & 0xff;
1281 if (n > 250)
1282 n = 250;
1283
1284 DPRINT((pp, DBG_INTR, "n = %d, op = %d, ip = %d\n",
1285 n, op, ip));
1286
1287 /*
1288 * Suck characters out of host card buffer into the
1289 * "input staging buffer" - so that we dont leave the
1290 * host card in limbo while we're possibly echoing
1291 * characters and possibly flushing input inside the
1292 * ldisc l_rint() routine.
1293 */
1294 if (n <= SI_BUFFERSIZE - op) {
1295
1267 DPRINT((pp, DBG_INTR, "\tsingle copy\n"));
1268 z = ccbp->hi_rxbuf + op;
1269 si_vbcopy(z, si_rxbuf, n);
1270
1271 op += n;
1272 } else {
1273 x = SI_BUFFERSIZE - op;
1274
1296 z = ccbp->hi_rxbuf + op;
1297 si_vbcopy(z, si_rxbuf, n);
1298
1299 op += n;
1300 } else {
1301 x = SI_BUFFERSIZE - op;
1302
1275 DPRINT((pp, DBG_INTR, "\tdouble part 1 %d\n", x));
1276 z = ccbp->hi_rxbuf + op;
1277 si_vbcopy(z, si_rxbuf, x);
1278
1303 z = ccbp->hi_rxbuf + op;
1304 si_vbcopy(z, si_rxbuf, x);
1305
1279 DPRINT((pp, DBG_INTR, "\tdouble part 2 %d\n",
1280 n - x));
1281 z = ccbp->hi_rxbuf;
1282 si_vbcopy(z, si_rxbuf + x, n - x);
1283
1284 op += n;
1285 }
1286
1287 /* clear collected characters from buffer */
1288 ccbp->hi_rxopos = op;

--- 42 unchanged lines hidden (view full) ---

1331 /*
1332 * It'd be nice to not have to go through the
1333 * function call overhead for each char here.
1334 * It'd be nice to block input it, saving a
1335 * loop here and the call/return overhead.
1336 */
1337 for(x = 0; x < n; x++) {
1338 i = si_rxbuf[x];
1306 z = ccbp->hi_rxbuf;
1307 si_vbcopy(z, si_rxbuf + x, n - x);
1308
1309 op += n;
1310 }
1311
1312 /* clear collected characters from buffer */
1313 ccbp->hi_rxopos = op;

--- 42 unchanged lines hidden (view full) ---

1356 /*
1357 * It'd be nice to not have to go through the
1358 * function call overhead for each char here.
1359 * It'd be nice to block input it, saving a
1360 * loop here and the call/return overhead.
1361 */
1362 for(x = 0; x < n; x++) {
1363 i = si_rxbuf[x];
1339 if (ttyld_rint(tp, i)
1340 == -1) {
1364 if (ttyld_rint(tp, i) == -1)
1341 pp->sp_delta_overflows++;
1365 pp->sp_delta_overflows++;
1342 }
1343 }
1344 }
1345 goto more_rx; /* try for more until RXbuf is empty */
1346
1366 }
1367 }
1368 goto more_rx; /* try for more until RXbuf is empty */
1369
1347 end_rx: /* XXX: Again, sorry about the gotos.. :-) */
1370 end_rx:
1348
1349 /*
1350 * Do TX stuff
1351 */
1352 ttyld_start(tp);
1353
1354 } /* end of for (all ports on this controller) */
1355 } /* end of for (all controllers) */
1356
1371
1372 /*
1373 * Do TX stuff
1374 */
1375 ttyld_start(tp);
1376
1377 } /* end of for (all ports on this controller) */
1378 } /* end of for (all controllers) */
1379
1357 in_intr = 0;
1358 DPRINT((0, arg == NULL ? DBG_POLL:DBG_INTR, "end si_intr\n"));
1359}
1360
1361/*
1362 * Nudge the transmitter...
1363 *
1364 * XXX: I inherited some funny code here. It implies the host card only
1365 * interrupts when the transmit buffer reaches the low-water-mark, and does

--- 5 unchanged lines hidden (view full) ---

1371static void
1372si_start(struct tty *tp)
1373{
1374 struct si_port *pp;
1375 volatile struct si_channel *ccbp;
1376 struct clist *qp;
1377 BYTE ipos;
1378 int nchar;
1380 DPRINT((0, arg == NULL ? DBG_POLL:DBG_INTR, "end si_intr\n"));
1381}
1382
1383/*
1384 * Nudge the transmitter...
1385 *
1386 * XXX: I inherited some funny code here. It implies the host card only
1387 * interrupts when the transmit buffer reaches the low-water-mark, and does

--- 5 unchanged lines hidden (view full) ---

1393static void
1394si_start(struct tty *tp)
1395{
1396 struct si_port *pp;
1397 volatile struct si_channel *ccbp;
1398 struct clist *qp;
1399 BYTE ipos;
1400 int nchar;
1379 int oldspl, count, n, amount, buffer_full;
1401 int oldspl, count, n, amount;
1380
1381 oldspl = spltty();
1402
1403 oldspl = spltty();
1404 mtx_assert(&Giant, MA_OWNED);
1382
1383 qp = &tp->t_outq;
1384 pp = tp->t_sc;
1385
1386 DPRINT((pp, DBG_ENTRY|DBG_START,
1387 "si_start(%x) t_state %x sp_state %x t_outq.c_cc %d\n",
1388 tp, tp->t_state, pp->sp_state, qp->c_cc));
1389
1390 if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP))
1391 goto out;
1392
1405
1406 qp = &tp->t_outq;
1407 pp = tp->t_sc;
1408
1409 DPRINT((pp, DBG_ENTRY|DBG_START,
1410 "si_start(%x) t_state %x sp_state %x t_outq.c_cc %d\n",
1411 tp, tp->t_state, pp->sp_state, qp->c_cc));
1412
1413 if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP))
1414 goto out;
1415
1393 buffer_full = 0;
1394 ccbp = pp->sp_ccb;
1395
1396 count = (int)ccbp->hi_txipos - (int)ccbp->hi_txopos;
1397 DPRINT((pp, DBG_START, "count %d\n", (BYTE)count));
1398
1399 while ((nchar = qp->c_cc) > 0) {
1416 ccbp = pp->sp_ccb;
1417
1418 count = (int)ccbp->hi_txipos - (int)ccbp->hi_txopos;
1419 DPRINT((pp, DBG_START, "count %d\n", (BYTE)count));
1420
1421 while ((nchar = qp->c_cc) > 0) {
1400 if ((BYTE)count >= 255) {
1401 buffer_full++;
1422 if ((BYTE)count >= 255)
1402 break;
1423 break;
1403 }
1404 amount = min(nchar, (255 - (BYTE)count));
1405 ipos = (unsigned int)ccbp->hi_txipos;
1406 n = q_to_b(&tp->t_outq, si_txbuf, amount);
1407 /* will it fit in one lump? */
1408 if ((SI_BUFFERSIZE - ipos) >= n) {
1409 si_bcopyv(si_txbuf, &ccbp->hi_txbuf[ipos], n);
1410 } else {
1411 si_bcopyv(si_txbuf, &ccbp->hi_txbuf[ipos],
1412 SI_BUFFERSIZE - ipos);
1413 si_bcopyv(si_txbuf + (SI_BUFFERSIZE - ipos),
1414 &ccbp->hi_txbuf[0], n - (SI_BUFFERSIZE - ipos));
1415 }
1416 ccbp->hi_txipos += n;
1417 count = (int)ccbp->hi_txipos - (int)ccbp->hi_txopos;
1418 }
1419
1424 amount = min(nchar, (255 - (BYTE)count));
1425 ipos = (unsigned int)ccbp->hi_txipos;
1426 n = q_to_b(&tp->t_outq, si_txbuf, amount);
1427 /* will it fit in one lump? */
1428 if ((SI_BUFFERSIZE - ipos) >= n) {
1429 si_bcopyv(si_txbuf, &ccbp->hi_txbuf[ipos], n);
1430 } else {
1431 si_bcopyv(si_txbuf, &ccbp->hi_txbuf[ipos],
1432 SI_BUFFERSIZE - ipos);
1433 si_bcopyv(si_txbuf + (SI_BUFFERSIZE - ipos),
1434 &ccbp->hi_txbuf[0], n - (SI_BUFFERSIZE - ipos));
1435 }
1436 ccbp->hi_txipos += n;
1437 count = (int)ccbp->hi_txipos - (int)ccbp->hi_txopos;
1438 }
1439
1420 if (count != 0 && nchar == 0) {
1440 if (count != 0 && nchar == 0)
1421 tp->t_state |= TS_BUSY;
1441 tp->t_state |= TS_BUSY;
1422 } else {
1442 else
1423 tp->t_state &= ~TS_BUSY;
1443 tp->t_state &= ~TS_BUSY;
1424 }
1425
1426 /* wakeup time? */
1427 ttwwakeup(tp);
1428
1429 DPRINT((pp, DBG_START, "count %d, nchar %d, tp->t_state 0x%x\n",
1430 (BYTE)count, nchar, tp->t_state));
1431
1444
1445 /* wakeup time? */
1446 ttwwakeup(tp);
1447
1448 DPRINT((pp, DBG_START, "count %d, nchar %d, tp->t_state 0x%x\n",
1449 (BYTE)count, nchar, tp->t_state));
1450
1432 if (tp->t_state & TS_BUSY)
1433 {
1451 if (tp->t_state & TS_BUSY) {
1434 int time;
1435
1436 time = ttspeedtab(tp->t_ospeed, chartimes);
1437
1438 if (time > 0) {
1439 if (time < nchar)
1440 time = nchar / time;
1441 else
1442 time = 2;
1443 } else {
1444 DPRINT((pp, DBG_START,
1445 "bad char time value! %d\n", time));
1446 time = hz/10;
1447 }
1448
1452 int time;
1453
1454 time = ttspeedtab(tp->t_ospeed, chartimes);
1455
1456 if (time > 0) {
1457 if (time < nchar)
1458 time = nchar / time;
1459 else
1460 time = 2;
1461 } else {
1462 DPRINT((pp, DBG_START,
1463 "bad char time value! %d\n", time));
1464 time = hz/10;
1465 }
1466
1449 if ((pp->sp_state & (SS_LSTART|SS_INLSTART)) == SS_LSTART) {
1467 if ((pp->sp_state & SS_LSTART) != 0)
1450 untimeout(si_lstart, (caddr_t)pp, pp->lstart_ch);
1468 untimeout(si_lstart, (caddr_t)pp, pp->lstart_ch);
1451 } else {
1452 pp->sp_state |= SS_LSTART;
1453 }
1454 DPRINT((pp, DBG_START, "arming lstart, time=%d\n", time));
1469 DPRINT((pp, DBG_START, "arming lstart, time=%d\n", time));
1470 pp->sp_state |= SS_LSTART;
1455 pp->lstart_ch = timeout(si_lstart, (caddr_t)pp, time);
1456 }
1457
1458out:
1459 splx(oldspl);
1460 DPRINT((pp, DBG_EXIT|DBG_START, "leave si_start()\n"));
1461}
1462

--- 9 unchanged lines hidden (view full) ---

1472 struct si_port *pp = arg;
1473 struct tty *tp;
1474 int oldspl;
1475
1476 DPRINT((pp, DBG_ENTRY|DBG_LSTART, "si_lstart(%x) sp_state %x\n",
1477 pp, pp->sp_state));
1478
1479 oldspl = spltty();
1471 pp->lstart_ch = timeout(si_lstart, (caddr_t)pp, time);
1472 }
1473
1474out:
1475 splx(oldspl);
1476 DPRINT((pp, DBG_EXIT|DBG_START, "leave si_start()\n"));
1477}
1478

--- 9 unchanged lines hidden (view full) ---

1488 struct si_port *pp = arg;
1489 struct tty *tp;
1490 int oldspl;
1491
1492 DPRINT((pp, DBG_ENTRY|DBG_LSTART, "si_lstart(%x) sp_state %x\n",
1493 pp, pp->sp_state));
1494
1495 oldspl = spltty();
1496 mtx_assert(&Giant, MA_OWNED);
1497 pp->sp_state &= ~SS_LSTART;
1480 tp = pp->sp_tty;
1481
1498 tp = pp->sp_tty;
1499
1482 if ((tp->t_state & TS_ISOPEN) == 0 ||
1483 (pp->sp_state & SS_LSTART) == 0) {
1500 if ((tp->t_state & TS_ISOPEN) == 0) {
1484 splx(oldspl);
1485 return;
1486 }
1501 splx(oldspl);
1502 return;
1503 }
1487 pp->sp_state &= ~SS_LSTART;
1488 pp->sp_state |= SS_INLSTART;
1489
1504
1490
1491 /* deal with the process exit case */
1492 ttwwakeup(tp);
1493
1494 /* nudge protocols - eg: ppp */
1495 ttyld_start(tp);
1496
1505 /* deal with the process exit case */
1506 ttwwakeup(tp);
1507
1508 /* nudge protocols - eg: ppp */
1509 ttyld_start(tp);
1510
1497 pp->sp_state &= ~SS_INLSTART;
1498 splx(oldspl);
1499}
1500
1501/*
1502 * Stop output on a line. called at spltty();
1503 */
1504static void
1505si_stop(struct tty *tp, int rw)
1506{
1507 volatile struct si_channel *ccbp;
1508 struct si_port *pp;
1509
1511 splx(oldspl);
1512}
1513
1514/*
1515 * Stop output on a line. called at spltty();
1516 */
1517static void
1518si_stop(struct tty *tp, int rw)
1519{
1520 volatile struct si_channel *ccbp;
1521 struct si_port *pp;
1522
1523 mtx_assert(&Giant, MA_OWNED);
1510 pp = tp->t_sc;
1511 ccbp = pp->sp_ccb;
1512
1513 DPRINT((pp, DBG_ENTRY|DBG_STOP, "si_stop(%x,%x)\n", tp, rw));
1514
1515 /* XXX: must check (rw & FWRITE | FREAD) etc flushing... */
1516 if (rw & FWRITE) {
1517 /* what level are we meant to be flushing anyway? */

--- 21 unchanged lines hidden (view full) ---

1539
1540static void
1541si_command(struct si_port *pp, int cmd, int waitflag)
1542{
1543 int oldspl;
1544 volatile struct si_channel *ccbp = pp->sp_ccb;
1545 int x;
1546
1524 pp = tp->t_sc;
1525 ccbp = pp->sp_ccb;
1526
1527 DPRINT((pp, DBG_ENTRY|DBG_STOP, "si_stop(%x,%x)\n", tp, rw));
1528
1529 /* XXX: must check (rw & FWRITE | FREAD) etc flushing... */
1530 if (rw & FWRITE) {
1531 /* what level are we meant to be flushing anyway? */

--- 21 unchanged lines hidden (view full) ---

1553
1554static void
1555si_command(struct si_port *pp, int cmd, int waitflag)
1556{
1557 int oldspl;
1558 volatile struct si_channel *ccbp = pp->sp_ccb;
1559 int x;
1560
1547 DPRINT((pp, DBG_ENTRY|DBG_PARAM, "si_command(%x,%x,%d): hi_stat 0x%x\n",
1548 pp, cmd, waitflag, ccbp->hi_stat));
1561 DPRINT((pp, DBG_ENTRY|DBG_PARAM, "si_command(%x,%s,%d): hi_stat %s, sp_pend: %s\n",
1562 pp, si_cmdname(cmd), waitflag, si_cmdname(ccbp->hi_stat),
1563 si_cmdname(pp->sp_pend)));
1549
1550 oldspl = spltty(); /* Keep others out */
1564
1565 oldspl = spltty(); /* Keep others out */
1566 mtx_assert(&Giant, MA_OWNED);
1551
1552 /* wait until it's finished what it was doing.. */
1553 /* XXX: sits in IDLE_BREAK until something disturbs it or break
1554 * is turned off. */
1555 while((x = ccbp->hi_stat) != IDLE_OPEN &&
1556 x != IDLE_CLOSE &&
1557 x != IDLE_BREAK &&
1558 x != cmd) {
1567
1568 /* wait until it's finished what it was doing.. */
1569 /* XXX: sits in IDLE_BREAK until something disturbs it or break
1570 * is turned off. */
1571 while((x = ccbp->hi_stat) != IDLE_OPEN &&
1572 x != IDLE_CLOSE &&
1573 x != IDLE_BREAK &&
1574 x != cmd) {
1559 if (in_intr) { /* Prevent sleep in intr */
1560 DPRINT((pp, DBG_PARAM,
1561 "cmd intr collision - completing %d\trequested %d\n",
1562 x, cmd));
1575 if (ttysleep(pp->sp_tty, (caddr_t)&pp->sp_state, TTIPRI|PCATCH,
1576 "sicmd1", hz/4)) {
1577 DPRINT((pp, DBG_PARAM, "sicmd1 timeout: hi_stat (%s)\n",
1578 si_cmdname(ccbp->hi_stat)));
1579 /* This is very very bad. The card has crashed. */
1580 /* XXX the driver breaks at this point */
1563 splx(oldspl);
1564 return;
1581 splx(oldspl);
1582 return;
1565 } else if (ttysleep(pp->sp_tty, (caddr_t)&pp->sp_state, TTIPRI|PCATCH,
1566 "sicmd1", 1)) {
1567 splx(oldspl);
1568 return;
1569 }
1570 }
1571 /* it should now be in IDLE_{OPEN|CLOSE|BREAK}, or "cmd" */
1572
1573 /* if there was a pending command, cause a state-change wakeup */
1574 switch(pp->sp_pend) {
1575 case LOPEN:
1576 case MPEND:
1577 case MOPEN:
1583 }
1584 }
1585 /* it should now be in IDLE_{OPEN|CLOSE|BREAK}, or "cmd" */
1586
1587 /* if there was a pending command, cause a state-change wakeup */
1588 switch(pp->sp_pend) {
1589 case LOPEN:
1590 case MPEND:
1591 case MOPEN:
1592 case FCLOSE:
1578 case CONFIG:
1579 case SBREAK:
1580 case EBREAK:
1593 case CONFIG:
1594 case SBREAK:
1595 case EBREAK:
1596 DPRINT((pp, DBG_PARAM, "si_command: sp_pend %s\n", si_cmdname(pp->sp_pend)));
1581 wakeup(&pp->sp_state);
1582 break;
1583 default:
1584 break;
1585 }
1586
1587 pp->sp_pend = cmd; /* New command pending */
1588 ccbp->hi_stat = cmd; /* Post it */
1589
1590 if (waitflag) {
1597 wakeup(&pp->sp_state);
1598 break;
1599 default:
1600 break;
1601 }
1602
1603 pp->sp_pend = cmd; /* New command pending */
1604 ccbp->hi_stat = cmd; /* Post it */
1605
1606 if (waitflag) {
1591 if (in_intr) { /* If in interrupt handler */
1592 DPRINT((pp, DBG_PARAM,
1593 "attempt to sleep in si_intr - cmd req %d\n",
1594 cmd));
1595 splx(oldspl);
1596 return;
1597 } else while(ccbp->hi_stat != IDLE_OPEN &&
1598 ccbp->hi_stat != IDLE_BREAK) {
1607 while((x = ccbp->hi_stat) != IDLE_OPEN &&
1608 x != IDLE_CLOSE &&
1609 x != IDLE_BREAK) {
1599 if (ttysleep(pp->sp_tty, (caddr_t)&pp->sp_state, TTIPRI|PCATCH,
1600 "sicmd2", 0))
1601 break;
1602 }
1603 }
1604 splx(oldspl);
1605}
1606

--- 53 unchanged lines hidden ---
1610 if (ttysleep(pp->sp_tty, (caddr_t)&pp->sp_state, TTIPRI|PCATCH,
1611 "sicmd2", 0))
1612 break;
1613 }
1614 }
1615 splx(oldspl);
1616}
1617

--- 53 unchanged lines hidden ---