00001 #include <conio.h>
00002 #include <sys/_devdrvr.h>
00003 #include <sys/trace.h>
00004 #include <sys/tracecod.h>
00005 #include "struct.h"
00006
00007
00008
00009
00010
00011 #pragma off (check_stack);
00012
00013 extern pid_t (far *tti)(int, int, unsigned);
00014 extern unsigned tti_ds;
00015
00016 extern struct dev_entry *dev_list[];
00017 extern struct driver_ctrl drv_ctrl;
00018 extern int num_asyncs;
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 static void test_tx(struct dev_entry *dev, unsigned char lsr) {
00033 if(dev->tx_pending == 0)
00034 return;
00035 if((lsr & 0x20) == 0)
00036 return;
00037 outp(dev->iobase+1, 0x0f);
00038 return;
00039 }
00040
00041
00042
00043
00044
00045 static pid_t process_lsr(struct dev_entry *dev, unsigned char lsr) {
00046 unsigned key = 0;
00047
00048 if((lsr & 0x1e) == 0)
00049 return(0);
00050
00051
00052
00053
00054
00055
00056 key = inp(dev->iobase);
00057
00058 if(lsr & 0x10) {
00059 Trace1( (long)_TRACE_DEV_SER_HUP+1, _TRACE_TRANSIENT, dev->iobase );
00060 key |= RCV_BREAK;
00061 }
00062 else {
00063 if(lsr & 0x04) {
00064 key |= RCV_PARITY;
00065 Trace1( (long)_TRACE_DEV_SER_PARITY, _TRACE_TRANSIENT, dev->iobase );
00066 }
00067 if(lsr & 0x08) {
00068 key |= RCV_FRAME;
00069 Trace1( (long)_TRACE_DEV_SER_FRAME, _TRACE_TRANSIENT, dev->iobase );
00070 }
00071 }
00072
00073 if(lsr & 0x02) {
00074 key |= RCV_OVERRUN;
00075 Trace1( (long)_TRACE_DEV_SER_OVERRUN, _TRACE_TRANSIENT, dev->iobase );
00076 }
00077 return( (*tti) (key, dev->tty, tti_ds) );
00078 }
00079
00080
00081
00082
00083
00084 pid_t far async_irq0() { return(async_int(0)); }
00085 pid_t far async_irq1() { return(async_int(1)); }
00086 pid_t far async_irq2() { return(async_int(2)); }
00087 pid_t far async_irq3() { return(async_int(3)); }
00088 pid_t far async_irq4() { return(async_int(4)); }
00089 pid_t far async_irq5() { return(async_int(5)); }
00090 pid_t far async_irq6() { return(async_int(6)); }
00091 pid_t far async_irq7() { return(async_int(7)); }
00092 pid_t far async_irq8() { return(async_int(8)); }
00093 pid_t far async_irq9() { return(async_int(9)); }
00094 pid_t far async_irq10() { return(async_int(10)); }
00095 pid_t far async_irq11() { return(async_int(11)); }
00096 pid_t far async_irq12() { return(async_int(12)); }
00097 pid_t far async_irq13() { return(async_int(13)); }
00098 pid_t far async_irq14() { return(async_int(14)); }
00099 pid_t far async_irq15() { return(async_int(15)); }
00100
00101
00102 pid_t async_int(int irq) {
00103 pid_t status = 0;
00104 int nothing;
00105 struct dev_entry *dev;
00106 unsigned char iir;
00107 unsigned char lsr;
00108 unsigned char msr;
00109
00110 while(1) {
00111 nothing = 1;
00112 for(dev = dev_list[irq]; dev != 0; dev = dev->link) {
00113 if(dev->iobase == 0)
00114 continue;
00115 iir = inp(dev->iobase+2);
00116 if((iir & 0x01) != 0)
00117 continue;
00118
00119
00120
00121 nothing = 0;
00122 iir &= 7;
00123 if(iir == 4) {
00124
00125
00126
00127 while(1) {
00128 status |= (*tti) (inp(dev->iobase), dev->tty, tti_ds);
00129 ++dev->rx_count;
00130 lsr = inp(dev->iobase+5);
00131 status |= process_lsr(dev, lsr);
00132 if((lsr & 0x01) == 0) {
00133 test_tx(dev, lsr);
00134 break;
00135 }
00136 }
00137 }
00138 else if(iir == 2) {
00139
00140
00141
00142 dev->tx_pending = 0;
00143 status |= tto(dev, dev->obuf);
00144 ++dev->tx_count;
00145 }
00146 else if(iir == 0) {
00147
00148
00149
00150 msr = inp(dev->iobase+6);
00151 dev->modem_status = (dev->modem_status & 0x0F) | (msr & 0xF0);
00152
00153 if(dev->mode & MODE_PKT)
00154 status |= (*tti) (RCV_PKT_SPECIAL, dev->tty, tti_ds);
00155
00156 if((msr & 0x08) != 0 && (dev->mode & MODE_NOHUP) == 0) {
00157 if(msr & 0x80) {
00158 status |= (*tti) (RCV_CARRIER, dev->tty, tti_ds);
00159 Trace1( _TRACE_DEV_SER_CARRIER, _TRACE_EXPECTED, dev->iobase );
00160 }
00161 else {
00162 status |= (*tti) (RCV_HNGUP, dev->tty, tti_ds);
00163 Trace1( _TRACE_DEV_SER_HUP, _TRACE_EXPECTED, dev->iobase );
00164 }
00165 }
00166
00167
00168 if(dev->mode & MODE_SPLIT) {
00169 if(msr & 0x01) {
00170
00171
00172
00173 if(msr & 0x10)
00174 status |= (*tti) (RCV_HW_ON, dev->tty, tti_ds);
00175 else
00176 status |= (*tti) (RCV_HW_OFF, dev->tty, tti_ds);
00177 }
00178 }
00179 else {
00180 if(msr & 0x03) {
00181
00182
00183
00184
00185 if((msr & 0x30) == 0x30)
00186 status |= (*tti) (RCV_HW_ON, dev->tty, tti_ds);
00187 else
00188 status |= (*tti) (RCV_HW_OFF, dev->tty, tti_ds);
00189 }
00190 }
00191 }
00192 else {
00193
00194
00195
00196 lsr = inp(dev->iobase+5);
00197 status |= process_lsr(dev, lsr);
00198 test_tx(dev, lsr);
00199 }
00200 }
00201 if(nothing)
00202 break;
00203 }
00204 return(status);
00205 }
00206
00207 #pragma on (check_stack);