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 --- |