]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/i386/isa/rp.c
In ascpoll, return revents, not 0.
[FreeBSD/FreeBSD.git] / sys / i386 / isa / rp.c
1 /* 
2  * Copyright (c) Comtrol Corporation <support@comtrol.com>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted prodived that the follwoing conditions
7  * are met.
8  * 1. Redistributions of source code must retain the above copyright 
9  *    notive, this list of conditions and the following disclainer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials prodided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *       This product includes software developed by Comtrol Corporation.
16  * 4. The name of Comtrol Corporation may not be used to endorse or 
17  *    promote products derived from this software without specific 
18  *    prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY COMTROL CORPORATION ``AS IS'' AND ANY
21  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL COMTROL CORPORATION BE LIABLE FOR
24  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * $FreeBSD$
33  */
34
35 /* 
36  * rp.c - for RocketPort FreeBSD
37  */
38
39 #include "opt_compat.h"
40
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/kernel.h>
44 #include <sys/fcntl.h>
45 #include <sys/malloc.h>
46 #include <sys/tty.h>
47 #include <sys/proc.h>
48 #include <sys/conf.h>
49 #include <sys/bus.h>
50
51 #include <i386/isa/isa_device.h>
52
53 #include <pci/pcivar.h>
54
55 #define ROCKET_C
56 #include <i386/isa/rpreg.h>
57 #include <i386/isa/rpvar.h>
58
59 #ifndef TRUE
60 #define TRUE 1
61 #endif
62
63 #ifndef FALSE
64 #define FALSE 0
65 #endif
66
67 static Byte_t RData[RDATASIZE] =
68 {
69    0x00, 0x09, 0xf6, 0x82,
70    0x02, 0x09, 0x86, 0xfb,
71    0x04, 0x09, 0x00, 0x0a,
72    0x06, 0x09, 0x01, 0x0a,
73    0x08, 0x09, 0x8a, 0x13,
74    0x0a, 0x09, 0xc5, 0x11,
75    0x0c, 0x09, 0x86, 0x85,
76    0x0e, 0x09, 0x20, 0x0a,
77    0x10, 0x09, 0x21, 0x0a,
78    0x12, 0x09, 0x41, 0xff,
79    0x14, 0x09, 0x82, 0x00,
80    0x16, 0x09, 0x82, 0x7b,
81    0x18, 0x09, 0x8a, 0x7d,
82    0x1a, 0x09, 0x88, 0x81,
83    0x1c, 0x09, 0x86, 0x7a,
84    0x1e, 0x09, 0x84, 0x81,
85    0x20, 0x09, 0x82, 0x7c,
86    0x22, 0x09, 0x0a, 0x0a
87 };
88
89 static Byte_t RRegData[RREGDATASIZE]=
90 {
91    0x00, 0x09, 0xf6, 0x82,             /* 00: Stop Rx processor */
92    0x08, 0x09, 0x8a, 0x13,             /* 04: Tx software flow control */
93    0x0a, 0x09, 0xc5, 0x11,             /* 08: XON char */
94    0x0c, 0x09, 0x86, 0x85,             /* 0c: XANY */
95    0x12, 0x09, 0x41, 0xff,             /* 10: Rx mask char */
96    0x14, 0x09, 0x82, 0x00,             /* 14: Compare/Ignore #0 */
97    0x16, 0x09, 0x82, 0x7b,             /* 18: Compare #1 */
98    0x18, 0x09, 0x8a, 0x7d,             /* 1c: Compare #2 */
99    0x1a, 0x09, 0x88, 0x81,             /* 20: Interrupt #1 */
100    0x1c, 0x09, 0x86, 0x7a,             /* 24: Ignore/Replace #1 */
101    0x1e, 0x09, 0x84, 0x81,             /* 28: Interrupt #2 */
102    0x20, 0x09, 0x82, 0x7c,             /* 2c: Ignore/Replace #2 */
103    0x22, 0x09, 0x0a, 0x0a              /* 30: Rx FIFO Enable */
104 };
105
106 static CONTROLLER_T sController[CTL_SIZE] =
107 {
108    {-1,-1,0,0,0,0,0,0,0,0,0,{0,0,0,0},{0,0,0,0},{-1,-1,-1,-1},{0,0,0,0}},
109    {-1,-1,0,0,0,0,0,0,0,0,0,{0,0,0,0},{0,0,0,0},{-1,-1,-1,-1},{0,0,0,0}},
110    {-1,-1,0,0,0,0,0,0,0,0,0,{0,0,0,0},{0,0,0,0},{-1,-1,-1,-1},{0,0,0,0}},
111    {-1,-1,0,0,0,0,0,0,0,0,0,{0,0,0,0},{0,0,0,0},{-1,-1,-1,-1},{0,0,0,0}}
112 };
113
114 #if 0
115 /* IRQ number to MUDBAC register 2 mapping */
116 Byte_t sIRQMap[16] =
117 {
118    0,0,0,0x10,0x20,0x30,0,0,0,0x40,0x50,0x60,0x70,0,0,0x80
119 };
120 #endif
121
122 static Byte_t sBitMapClrTbl[8] =
123 {
124    0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f
125 };
126
127 static Byte_t sBitMapSetTbl[8] =
128 {
129    0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
130 };
131
132 /***************************************************************************
133 Function: sInitController
134 Purpose:  Initialization of controller global registers and controller
135           structure.
136 Call:     sInitController(CtlP,CtlNum,MudbacIO,AiopIOList,AiopIOListSize,
137                           IRQNum,Frequency,PeriodicOnly)
138           CONTROLLER_T *CtlP; Ptr to controller structure
139           int CtlNum; Controller number
140           ByteIO_t MudbacIO; Mudbac base I/O address.
141           ByteIO_t *AiopIOList; List of I/O addresses for each AIOP.
142              This list must be in the order the AIOPs will be found on the
143              controller.  Once an AIOP in the list is not found, it is
144              assumed that there are no more AIOPs on the controller.
145           int AiopIOListSize; Number of addresses in AiopIOList
146           int IRQNum; Interrupt Request number.  Can be any of the following:
147                          0: Disable global interrupts
148                          3: IRQ 3
149                          4: IRQ 4
150                          5: IRQ 5
151                          9: IRQ 9
152                          10: IRQ 10
153                          11: IRQ 11
154                          12: IRQ 12
155                          15: IRQ 15
156           Byte_t Frequency: A flag identifying the frequency
157                    of the periodic interrupt, can be any one of the following:
158                       FREQ_DIS - periodic interrupt disabled
159                       FREQ_137HZ - 137 Hertz
160                       FREQ_69HZ - 69 Hertz
161                       FREQ_34HZ - 34 Hertz
162                       FREQ_17HZ - 17 Hertz
163                       FREQ_9HZ - 9 Hertz
164                       FREQ_4HZ - 4 Hertz
165                    If IRQNum is set to 0 the Frequency parameter is
166                    overidden, it is forced to a value of FREQ_DIS.
167           int PeriodicOnly: TRUE if all interrupts except the periodic
168                                interrupt are to be blocked.
169                             FALSE is both the periodic interrupt and
170                                other channel interrupts are allowed.
171                             If IRQNum is set to 0 the PeriodicOnly parameter is
172                                overidden, it is forced to a value of FALSE.
173 Return:   int: Number of AIOPs on the controller, or CTLID_NULL if controller
174                initialization failed.
175
176 Comments:
177           If periodic interrupts are to be disabled but AIOP interrupts
178           are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE.
179
180           If interrupts are to be completely disabled set IRQNum to 0.
181
182           Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an
183           invalid combination.
184
185           This function performs initialization of global interrupt modes,
186           but it does not actually enable global interrupts.  To enable
187           and disable global interrupts use functions sEnGlobalInt() and
188           sDisGlobalInt().  Enabling of global interrupts is normally not
189           done until all other initializations are complete.
190
191           Even if interrupts are globally enabled, they must also be
192           individually enabled for each channel that is to generate
193           interrupts.
194
195 Warnings: No range checking on any of the parameters is done.
196
197           No context switches are allowed while executing this function.
198
199           After this function all AIOPs on the controller are disabled,
200           they can be enabled with sEnAiop().
201 */
202 int sInitController(    CONTROLLER_T *CtlP,
203                         int CtlNum,
204                         ByteIO_t MudbacIO,
205                         ByteIO_t *AiopIOList,
206                         int AiopIOListSize,
207                         int IRQNum,
208                         Byte_t Frequency,
209                         int PeriodicOnly)
210 {
211         int             i;
212         ByteIO_t        io;
213
214    CtlP->CtlNum = CtlNum;
215    CtlP->BusType = isISA;
216    CtlP->CtlID = CTLID_0001;        /* controller release 1 */
217
218    CtlP->MBaseIO = MudbacIO;
219    CtlP->MReg1IO = MudbacIO + 1;
220    CtlP->MReg2IO = MudbacIO + 2;
221    CtlP->MReg3IO = MudbacIO + 3;
222 #if 1
223    CtlP->MReg2 = 0;                 /* interrupt disable */
224    CtlP->MReg3 = 0;                 /* no periodic interrupts */
225 #else
226    if(sIRQMap[IRQNum] == 0)            /* interrupts globally disabled */
227    {
228       CtlP->MReg2 = 0;                 /* interrupt disable */
229       CtlP->MReg3 = 0;                 /* no periodic interrupts */
230    }
231    else
232    {
233       CtlP->MReg2 = sIRQMap[IRQNum];   /* set IRQ number */
234       CtlP->MReg3 = Frequency;         /* set frequency */
235       if(PeriodicOnly)                 /* periodic interrupt only */
236       {
237          CtlP->MReg3 |= PERIODIC_ONLY;
238       }
239    }
240 #endif
241    sOutB(CtlP->MReg2IO,CtlP->MReg2);
242    sOutB(CtlP->MReg3IO,CtlP->MReg3);
243    sControllerEOI(CtlP);               /* clear EOI if warm init */
244
245    /* Init AIOPs */
246    CtlP->NumAiop = 0;
247    for(i=0; i < AiopIOListSize; i++)
248    {
249       io = AiopIOList[i];
250       CtlP->AiopIO[i] = (WordIO_t)io;
251       CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
252       sOutB(CtlP->MReg2IO,CtlP->MReg2 | (i & 0x03)); /* AIOP index */
253       sOutB(MudbacIO,(Byte_t)(io >> 6));        /* set up AIOP I/O in MUDBAC */
254       sEnAiop(CtlP,i);                         /* enable the AIOP */
255
256       CtlP->AiopID[i] = sReadAiopID(io);       /* read AIOP ID */
257       if(CtlP->AiopID[i] == AIOPID_NULL)       /* if AIOP does not exist */
258       {
259          sDisAiop(CtlP,i);                     /* disable AIOP */
260          break;                                /* done looking for AIOPs */
261       }
262
263       CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t)io); /* num channels in AIOP */
264       sOutW((WordIO_t)io + _INDX_ADDR,_CLK_PRE);      /* clock prescaler */
265       sOutB(io + _INDX_DATA,CLOCK_PRESC);
266       CtlP->NumAiop++;                         /* bump count of AIOPs */
267       sDisAiop(CtlP,i);                        /* disable AIOP */
268    }
269
270    if(CtlP->NumAiop == 0)
271       return(-1);
272    else
273       return(CtlP->NumAiop);
274 }
275
276 int sPCIInitController( CONTROLLER_T *CtlP,
277                         int CtlNum,
278                         ByteIO_t *AiopIOList,
279                         int AiopIOListSize,
280                         int IRQNum,
281                         Byte_t Frequency,
282                         int PeriodicOnly)
283 {
284         int             i;
285         ByteIO_t        io;
286
287    CtlP->CtlNum = CtlNum;
288    CtlP->BusType = isPCI;
289    CtlP->CtlID = CTLID_0001;        /* controller release 1 */
290    CtlP->PCIIO = (WordIO_t)((ByteIO_t)AiopIOList[0] + _PCI_INT_FUNC);
291
292    sPCIControllerEOI(CtlP);
293
294    /* Init AIOPs */
295    CtlP->NumAiop = 0;
296    for(i=0; i < AiopIOListSize; i++)
297    {
298       io = AiopIOList[i];
299       CtlP->AiopIO[i] = (WordIO_t)io;
300       CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
301
302       CtlP->AiopID[i] = sReadAiopID(io);       /* read AIOP ID */
303       if(CtlP->AiopID[i] == AIOPID_NULL)       /* if AIOP does not exist */
304       {
305          break;                                /* done looking for AIOPs */
306       }
307
308       CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t)io); /* num channels in AIOP */
309       sOutW((WordIO_t)io + _INDX_ADDR,_CLK_PRE);      /* clock prescaler */
310       sOutB(io + _INDX_DATA,CLOCK_PRESC);
311       CtlP->NumAiop++;                         /* bump count of AIOPs */
312    }
313
314    if(CtlP->NumAiop == 0)
315       return(-1);
316    else
317       return(CtlP->NumAiop);
318 }
319
320 /***************************************************************************
321 Function: sReadAiopID
322 Purpose:  Read the AIOP idenfication number directly from an AIOP.
323 Call:     sReadAiopID(io)
324           ByteIO_t io: AIOP base I/O address
325 Return:   int: Flag AIOPID_XXXX if a valid AIOP is found, where X
326                  is replace by an identifying number.
327           Flag AIOPID_NULL if no valid AIOP is found
328 Warnings: No context switches are allowed while executing this function.
329
330 */
331 int sReadAiopID(ByteIO_t io)
332 {
333    Byte_t AiopID;               /* ID byte from AIOP */
334
335    sOutB(io + _CMD_REG,RESET_ALL);     /* reset AIOP */
336    sOutB(io + _CMD_REG,0x0);
337    AiopID = sInB(io + _CHN_STAT0) & 0x07;
338    if(AiopID == 0x06)
339       return(1);
340    else                                /* AIOP does not exist */
341       return(-1);
342 }
343
344 /***************************************************************************
345 Function: sReadAiopNumChan
346 Purpose:  Read the number of channels available in an AIOP directly from
347           an AIOP.
348 Call:     sReadAiopNumChan(io)
349           WordIO_t io: AIOP base I/O address
350 Return:   int: The number of channels available
351 Comments: The number of channels is determined by write/reads from identical
352           offsets within the SRAM address spaces for channels 0 and 4.
353           If the channel 4 space is mirrored to channel 0 it is a 4 channel
354           AIOP, otherwise it is an 8 channel.
355 Warnings: No context switches are allowed while executing this function.
356 */
357 int sReadAiopNumChan(WordIO_t io)
358 {
359    Word_t x;
360
361    sOutDW((DWordIO_t)io + _INDX_ADDR,0x12340000L); /* write to chan 0 SRAM */
362    sOutW(io + _INDX_ADDR,0);       /* read from SRAM, chan 0 */
363    x = sInW(io + _INDX_DATA);
364    sOutW(io + _INDX_ADDR,0x4000);  /* read from SRAM, chan 4 */
365    if(x != sInW(io + _INDX_DATA))  /* if different must be 8 chan */
366       return(8);
367    else
368       return(4);
369 }
370
371 /***************************************************************************
372 Function: sInitChan
373 Purpose:  Initialization of a channel and channel structure
374 Call:     sInitChan(CtlP,ChP,AiopNum,ChanNum)
375           CONTROLLER_T *CtlP; Ptr to controller structure
376           CHANNEL_T *ChP; Ptr to channel structure
377           int AiopNum; AIOP number within controller
378           int ChanNum; Channel number within AIOP
379 Return:   int: TRUE if initialization succeeded, FALSE if it fails because channel
380                number exceeds number of channels available in AIOP.
381 Comments: This function must be called before a channel can be used.
382 Warnings: No range checking on any of the parameters is done.
383
384           No context switches are allowed while executing this function.
385 */
386 int sInitChan(  CONTROLLER_T *CtlP,
387                 CHANNEL_T *ChP,
388                 int AiopNum,
389                 int ChanNum)
390 {
391    int i;
392    WordIO_t AiopIO;
393    WordIO_t ChIOOff;
394    Byte_t *ChR;
395    Word_t ChOff;
396    static Byte_t R[4];
397
398    if(ChanNum >= CtlP->AiopNumChan[AiopNum])
399       return(FALSE);                   /* exceeds num chans in AIOP */
400
401    /* Channel, AIOP, and controller identifiers */
402    ChP->CtlP = CtlP;
403    ChP->ChanID = CtlP->AiopID[AiopNum];
404    ChP->AiopNum = AiopNum;
405    ChP->ChanNum = ChanNum;
406
407    /* Global direct addresses */
408    AiopIO = CtlP->AiopIO[AiopNum];
409    ChP->Cmd = (ByteIO_t)AiopIO + _CMD_REG;
410    ChP->IntChan = (ByteIO_t)AiopIO + _INT_CHAN;
411    ChP->IntMask = (ByteIO_t)AiopIO + _INT_MASK;
412    ChP->IndexAddr = (DWordIO_t)AiopIO + _INDX_ADDR;
413    ChP->IndexData = AiopIO + _INDX_DATA;
414
415    /* Channel direct addresses */
416    ChIOOff = AiopIO + ChP->ChanNum * 2;
417    ChP->TxRxData = ChIOOff + _TD0;
418    ChP->ChanStat = ChIOOff + _CHN_STAT0;
419    ChP->TxRxCount = ChIOOff + _FIFO_CNT0;
420    ChP->IntID = (ByteIO_t)AiopIO + ChP->ChanNum + _INT_ID0;
421
422    /* Initialize the channel from the RData array */
423    for(i=0; i < RDATASIZE; i+=4)
424    {
425       R[0] = RData[i];
426       R[1] = RData[i+1] + 0x10 * ChanNum;
427       R[2] = RData[i+2];
428       R[3] = RData[i+3];
429       sOutDW(ChP->IndexAddr,*((DWord_t *)&R[0]));
430    }
431
432    ChR = ChP->R;
433    for(i=0; i < RREGDATASIZE; i+=4)
434    {
435       ChR[i] = RRegData[i];
436       ChR[i+1] = RRegData[i+1] + 0x10 * ChanNum;
437       ChR[i+2] = RRegData[i+2];
438       ChR[i+3] = RRegData[i+3];
439    }
440
441    /* Indexed registers */
442    ChOff = (Word_t)ChanNum * 0x1000;
443
444    ChP->BaudDiv[0] = (Byte_t)(ChOff + _BAUD);
445    ChP->BaudDiv[1] = (Byte_t)((ChOff + _BAUD) >> 8);
446    ChP->BaudDiv[2] = (Byte_t)BRD9600;
447    ChP->BaudDiv[3] = (Byte_t)(BRD9600 >> 8);
448    sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->BaudDiv[0]);
449
450    ChP->TxControl[0] = (Byte_t)(ChOff + _TX_CTRL);
451    ChP->TxControl[1] = (Byte_t)((ChOff + _TX_CTRL) >> 8);
452    ChP->TxControl[2] = 0;
453    ChP->TxControl[3] = 0;
454    sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxControl[0]);
455
456    ChP->RxControl[0] = (Byte_t)(ChOff + _RX_CTRL);
457    ChP->RxControl[1] = (Byte_t)((ChOff + _RX_CTRL) >> 8);
458    ChP->RxControl[2] = 0;
459    ChP->RxControl[3] = 0;
460    sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->RxControl[0]);
461
462    ChP->TxEnables[0] = (Byte_t)(ChOff + _TX_ENBLS);
463    ChP->TxEnables[1] = (Byte_t)((ChOff + _TX_ENBLS) >> 8);
464    ChP->TxEnables[2] = 0;
465    ChP->TxEnables[3] = 0;
466    sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxEnables[0]);
467
468    ChP->TxCompare[0] = (Byte_t)(ChOff + _TXCMP1);
469    ChP->TxCompare[1] = (Byte_t)((ChOff + _TXCMP1) >> 8);
470    ChP->TxCompare[2] = 0;
471    ChP->TxCompare[3] = 0;
472    sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxCompare[0]);
473
474    ChP->TxReplace1[0] = (Byte_t)(ChOff + _TXREP1B1);
475    ChP->TxReplace1[1] = (Byte_t)((ChOff + _TXREP1B1) >> 8);
476    ChP->TxReplace1[2] = 0;
477    ChP->TxReplace1[3] = 0;
478    sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxReplace1[0]);
479
480    ChP->TxReplace2[0] = (Byte_t)(ChOff + _TXREP2);
481    ChP->TxReplace2[1] = (Byte_t)((ChOff + _TXREP2) >> 8);
482    ChP->TxReplace2[2] = 0;
483    ChP->TxReplace2[3] = 0;
484    sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxReplace2[0]);
485
486    ChP->TxFIFOPtrs = ChOff + _TXF_OUTP;
487    ChP->TxFIFO = ChOff + _TX_FIFO;
488
489    sOutB(ChP->Cmd,(Byte_t)ChanNum | RESTXFCNT); /* apply reset Tx FIFO count */
490    sOutB(ChP->Cmd,(Byte_t)ChanNum);  /* remove reset Tx FIFO count */
491    sOutW((WordIO_t)ChP->IndexAddr,ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */
492    sOutW(ChP->IndexData,0);
493    ChP->RxFIFOPtrs = ChOff + _RXF_OUTP;
494    ChP->RxFIFO = ChOff + _RX_FIFO;
495
496    sOutB(ChP->Cmd,(Byte_t)ChanNum | RESRXFCNT); /* apply reset Rx FIFO count */
497    sOutB(ChP->Cmd,(Byte_t)ChanNum);  /* remove reset Rx FIFO count */
498    sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs); /* clear Rx out ptr */
499    sOutW(ChP->IndexData,0);
500    sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */
501    sOutW(ChP->IndexData,0);
502    ChP->TxPrioCnt = ChOff + _TXP_CNT;
503    sOutW((WordIO_t)ChP->IndexAddr,ChP->TxPrioCnt);
504    sOutB(ChP->IndexData,0);
505    ChP->TxPrioPtr = ChOff + _TXP_PNTR;
506    sOutW((WordIO_t)ChP->IndexAddr,ChP->TxPrioPtr);
507    sOutB(ChP->IndexData,0);
508    ChP->TxPrioBuf = ChOff + _TXP_BUF;
509    sEnRxProcessor(ChP);                /* start the Rx processor */
510
511    return(TRUE);
512 }
513
514 /***************************************************************************
515 Function: sStopRxProcessor
516 Purpose:  Stop the receive processor from processing a channel.
517 Call:     sStopRxProcessor(ChP)
518           CHANNEL_T *ChP; Ptr to channel structure
519
520 Comments: The receive processor can be started again with sStartRxProcessor().
521           This function causes the receive processor to skip over the
522           stopped channel.  It does not stop it from processing other channels.
523
524 Warnings: No context switches are allowed while executing this function.
525
526           Do not leave the receive processor stopped for more than one
527           character time.
528
529           After calling this function a delay of 4 uS is required to ensure
530           that the receive processor is no longer processing this channel.
531 */
532 void sStopRxProcessor(CHANNEL_T *ChP)
533 {
534    Byte_t R[4];
535
536    R[0] = ChP->R[0];
537    R[1] = ChP->R[1];
538    R[2] = 0x0a;
539    R[3] = ChP->R[3];
540    sOutDW(ChP->IndexAddr,*(DWord_t *)&R[0]);
541 }
542
543 /***************************************************************************
544 Function: sFlushRxFIFO
545 Purpose:  Flush the Rx FIFO
546 Call:     sFlushRxFIFO(ChP)
547           CHANNEL_T *ChP; Ptr to channel structure
548 Return:   void
549 Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
550           while it is being flushed the receive processor is stopped
551           and the transmitter is disabled.  After these operations a
552           4 uS delay is done before clearing the pointers to allow
553           the receive processor to stop.  These items are handled inside
554           this function.
555 Warnings: No context switches are allowed while executing this function.
556 */
557 void sFlushRxFIFO(CHANNEL_T *ChP)
558 {
559    int i;
560    Byte_t Ch;                   /* channel number within AIOP */
561    int RxFIFOEnabled;                  /* TRUE if Rx FIFO enabled */
562
563    if(sGetRxCnt(ChP) == 0)             /* Rx FIFO empty */
564       return;                          /* don't need to flush */
565
566    RxFIFOEnabled = FALSE;
567    if(ChP->R[0x32] == 0x08) /* Rx FIFO is enabled */
568    {
569       RxFIFOEnabled = TRUE;
570       sDisRxFIFO(ChP);                 /* disable it */
571       for(i=0; i < 2000/200; i++)       /* delay 2 uS to allow proc to disable FIFO*/
572          sInB(ChP->IntChan);            /* depends on bus i/o timing */
573    }
574    sGetChanStatus(ChP);          /* clear any pending Rx errors in chan stat */
575    Ch = (Byte_t)sGetChanNum(ChP);
576    sOutB(ChP->Cmd,Ch | RESRXFCNT);     /* apply reset Rx FIFO count */
577    sOutB(ChP->Cmd,Ch);                 /* remove reset Rx FIFO count */
578    sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs); /* clear Rx out ptr */
579    sOutW(ChP->IndexData,0);
580    sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */
581    sOutW(ChP->IndexData,0);
582    if(RxFIFOEnabled)
583       sEnRxFIFO(ChP);                  /* enable Rx FIFO */
584 }
585
586 /***************************************************************************
587 Function: sFlushTxFIFO
588 Purpose:  Flush the Tx FIFO
589 Call:     sFlushTxFIFO(ChP)
590           CHANNEL_T *ChP; Ptr to channel structure
591 Return:   void
592 Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
593           while it is being flushed the receive processor is stopped
594           and the transmitter is disabled.  After these operations a
595           4 uS delay is done before clearing the pointers to allow
596           the receive processor to stop.  These items are handled inside
597           this function.
598 Warnings: No context switches are allowed while executing this function.
599 */
600 void sFlushTxFIFO(CHANNEL_T *ChP)
601 {
602    int i;
603    Byte_t Ch;                   /* channel number within AIOP */
604    int TxEnabled;                      /* TRUE if transmitter enabled */
605
606    if(sGetTxCnt(ChP) == 0)             /* Tx FIFO empty */
607       return;                          /* don't need to flush */
608
609    TxEnabled = FALSE;
610    if(ChP->TxControl[3] & TX_ENABLE)
611    {
612       TxEnabled = TRUE;
613       sDisTransmit(ChP);               /* disable transmitter */
614    }
615    sStopRxProcessor(ChP);              /* stop Rx processor */
616    for(i = 0; i < 4000/200; i++)         /* delay 4 uS to allow proc to stop */
617       sInB(ChP->IntChan);       /* depends on bus i/o timing */
618    Ch = (Byte_t)sGetChanNum(ChP);
619    sOutB(ChP->Cmd,Ch | RESTXFCNT);     /* apply reset Tx FIFO count */
620    sOutB(ChP->Cmd,Ch);                 /* remove reset Tx FIFO count */
621    sOutW((WordIO_t)ChP->IndexAddr,ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */
622    sOutW(ChP->IndexData,0);
623    if(TxEnabled)
624       sEnTransmit(ChP);                /* enable transmitter */
625    sStartRxProcessor(ChP);             /* restart Rx processor */
626 }
627
628 /***************************************************************************
629 Function: sWriteTxPrioByte
630 Purpose:  Write a byte of priority transmit data to a channel
631 Call:     sWriteTxPrioByte(ChP,Data)
632           CHANNEL_T *ChP; Ptr to channel structure
633           Byte_t Data; The transmit data byte
634
635 Return:   int: 1 if the bytes is successfully written, otherwise 0.
636
637 Comments: The priority byte is transmitted before any data in the Tx FIFO.
638
639 Warnings: No context switches are allowed while executing this function.
640 */
641 int sWriteTxPrioByte(CHANNEL_T *ChP, Byte_t Data)
642 {
643    Byte_t DWBuf[4];             /* buffer for double word writes */
644    Word_t *WordPtr;          /* must be far because Win SS != DS */
645    register DWordIO_t IndexAddr;
646
647    if(sGetTxCnt(ChP) > 1)              /* write it to Tx priority buffer */
648    {
649       IndexAddr = ChP->IndexAddr;
650       sOutW((WordIO_t)IndexAddr,ChP->TxPrioCnt); /* get priority buffer status */
651       if(sInB((ByteIO_t)ChP->IndexData) & PRI_PEND) /* priority buffer busy */
652          return(0);                    /* nothing sent */
653
654       WordPtr = (Word_t *)(&DWBuf[0]);
655       *WordPtr = ChP->TxPrioBuf;       /* data byte address */
656
657       DWBuf[2] = Data;                 /* data byte value */
658       sOutDW(IndexAddr,*((DWord_t *)(&DWBuf[0]))); /* write it out */
659
660       *WordPtr = ChP->TxPrioCnt;       /* Tx priority count address */
661
662       DWBuf[2] = PRI_PEND + 1;         /* indicate 1 byte pending */
663       DWBuf[3] = 0;                    /* priority buffer pointer */
664       sOutDW(IndexAddr,*((DWord_t *)(&DWBuf[0]))); /* write it out */
665    }
666    else                                /* write it to Tx FIFO */
667    {
668       sWriteTxByte(sGetTxRxDataIO(ChP),Data);
669    }
670    return(1);                          /* 1 byte sent */
671 }
672
673 /***************************************************************************
674 Function: sEnInterrupts
675 Purpose:  Enable one or more interrupts for a channel
676 Call:     sEnInterrupts(ChP,Flags)
677           CHANNEL_T *ChP; Ptr to channel structure
678           Word_t Flags: Interrupt enable flags, can be any combination
679              of the following flags:
680                 TXINT_EN:   Interrupt on Tx FIFO empty
681                 RXINT_EN:   Interrupt on Rx FIFO at trigger level (see
682                             sSetRxTrigger())
683                 SRCINT_EN:  Interrupt on SRC (Special Rx Condition)
684                 MCINT_EN:   Interrupt on modem input change
685                 CHANINT_EN: Allow channel interrupt signal to the AIOP's
686                             Interrupt Channel Register.
687 Return:   void
688 Comments: If an interrupt enable flag is set in Flags, that interrupt will be
689           enabled.  If an interrupt enable flag is not set in Flags, that
690           interrupt will not be changed.  Interrupts can be disabled with
691           function sDisInterrupts().
692
693           This function sets the appropriate bit for the channel in the AIOP's
694           Interrupt Mask Register if the CHANINT_EN flag is set.  This allows
695           this channel's bit to be set in the AIOP's Interrupt Channel Register.
696
697           Interrupts must also be globally enabled before channel interrupts
698           will be passed on to the host.  This is done with function
699           sEnGlobalInt().
700
701           In some cases it may be desirable to disable interrupts globally but
702           enable channel interrupts.  This would allow the global interrupt
703           status register to be used to determine which AIOPs need service.
704 */
705 void sEnInterrupts(CHANNEL_T *ChP,Word_t Flags)
706 {
707    Byte_t Mask;                 /* Interrupt Mask Register */
708
709    ChP->RxControl[2] |=
710       ((Byte_t)Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
711
712    sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->RxControl[0]);
713
714    ChP->TxControl[2] |= ((Byte_t)Flags & TXINT_EN);
715
716    sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxControl[0]);
717
718    if(Flags & CHANINT_EN)
719    {
720       Mask = sInB(ChP->IntMask) | sBitMapSetTbl[ChP->ChanNum];
721       sOutB(ChP->IntMask,Mask);
722    }
723 }
724
725 /***************************************************************************
726 Function: sDisInterrupts
727 Purpose:  Disable one or more interrupts for a channel
728 Call:     sDisInterrupts(ChP,Flags)
729           CHANNEL_T *ChP; Ptr to channel structure
730           Word_t Flags: Interrupt flags, can be any combination
731              of the following flags:
732                 TXINT_EN:   Interrupt on Tx FIFO empty
733                 RXINT_EN:   Interrupt on Rx FIFO at trigger level (see
734                             sSetRxTrigger())
735                 SRCINT_EN:  Interrupt on SRC (Special Rx Condition)
736                 MCINT_EN:   Interrupt on modem input change
737                 CHANINT_EN: Disable channel interrupt signal to the
738                             AIOP's Interrupt Channel Register.
739 Return:   void
740 Comments: If an interrupt flag is set in Flags, that interrupt will be
741           disabled.  If an interrupt flag is not set in Flags, that
742           interrupt will not be changed.  Interrupts can be enabled with
743           function sEnInterrupts().
744
745           This function clears the appropriate bit for the channel in the AIOP's
746           Interrupt Mask Register if the CHANINT_EN flag is set.  This blocks
747           this channel's bit from being set in the AIOP's Interrupt Channel
748           Register.
749 */
750 void sDisInterrupts(CHANNEL_T *ChP,Word_t Flags)
751 {
752    Byte_t Mask;                 /* Interrupt Mask Register */
753
754    ChP->RxControl[2] &=
755          ~((Byte_t)Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
756    sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->RxControl[0]);
757    ChP->TxControl[2] &= ~((Byte_t)Flags & TXINT_EN);
758    sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxControl[0]);
759
760    if(Flags & CHANINT_EN)
761    {
762       Mask = sInB(ChP->IntMask) & sBitMapClrTbl[ChP->ChanNum];
763       sOutB(ChP->IntMask,Mask);
764    }
765 }
766
767 /*********************************************************************
768   Begin FreeBsd-specific driver code
769 **********************************************************************/
770
771 static int rpprobe __P((struct isa_device *));
772 static int rpattach __P((struct isa_device *));
773
774 static const char* rp_pciprobe(pcici_t tag, pcidi_t type);
775 static void rp_pciattach(pcici_t tag, int unit);
776 static u_long   rp_pcicount;
777
778 static struct pci_device rp_pcidevice = {
779         "rp",
780         rp_pciprobe,
781         rp_pciattach,
782         &rp_pcicount,
783         NULL
784 };
785
786 COMPAT_PCI_DRIVER (rp_pci, rp_pcidevice);
787
788 static timeout_t rpdtrwakeup;
789
790 struct isa_driver rpdriver = {
791         INTR_TYPE_TTY,
792         rpprobe,
793         rpattach,
794         "rp"
795 };
796 COMPAT_ISA_DRIVER(rp, rpdriver);
797
798 static  char    driver_name[] = "rp";
799
800 static  d_open_t        rpopen;
801 static  d_close_t       rpclose;
802 static  d_write_t       rpwrite;
803 static  d_ioctl_t       rpioctl;
804
805 #define CDEV_MAJOR      81
806 static struct cdevsw rp_cdevsw = {
807         /* open */      rpopen,
808         /* close */     rpclose,
809         /* read */      ttyread,
810         /* write */     rpwrite,
811         /* ioctl */     rpioctl,
812         /* poll */      ttypoll,
813         /* mmap */      nommap,
814         /* strategy */  nostrategy,
815         /* name */      driver_name,
816         /* maj */       CDEV_MAJOR,
817         /* dump */      nodump,
818         /* psize */     nopsize,
819         /* flags */     D_TTY | D_KQFILTER,
820         /* bmaj */      -1,
821         /* kqfilter */  ttykqfilter,
822 };
823
824 static int rp_controller_port = 0;
825 static int rp_num_ports_open = 0;
826 static int      ndevs = 0;
827 static int      minor_to_unit[128];
828 #if 0
829 static  struct  tty     rp_tty[128];
830 #endif
831
832 static int rp_num_ports[4];     /* Number of ports on each controller */
833
834 #define _INLINE_ __inline
835 #define POLL_INTERVAL 1
836
837 #define CALLOUT_MASK            0x80
838 #define CONTROL_MASK            0x60
839 #define CONTROL_INIT_STATE      0x20
840 #define CONTROL_LOCK_STATE      0x40
841 #define DEV_UNIT(dev)   (MINOR_TO_UNIT(minor(dev))
842 #define MINOR_MAGIC_MASK        (CALLOUT_MASK | CONTROL_MASK)
843 #define MINOR_MAGIC(dev)        ((minor(dev)) & ~MINOR_MAGIC_MASK)
844 #define IS_CALLOUT(dev)         (minor(dev) & CALLOUT_MASK)
845 #define IS_CONTROL(dev)         (minor(dev) & CONTROL_MASK)
846
847 #define RP_ISMULTIPORT(dev)     ((dev)->id_flags & 0x1)
848 #define RP_MPMASTER(dev)        (((dev)->id_flags >> 8) & 0xff)
849 #define RP_NOTAST4(dev)         ((dev)->id_flags & 0x04)
850
851 static  struct  rp_port *p_rp_addr[4];
852 static  struct  rp_port *p_rp_table[MAX_RP_PORTS];
853 #define rp_addr(unit)   (p_rp_addr[unit])
854 #define rp_table(port)  (p_rp_table[port])
855
856 /*
857  * The top-level routines begin here
858  */
859
860 static  int     rpparam __P((struct tty *, struct termios *));
861 static  void    rpstart __P((struct tty *));
862 static  void    rpstop __P((struct tty *, int));
863 static  void    rphardclose     __P((struct rp_port *));
864 static  void    rp_disc_optim   __P((struct tty *tp, struct termios *t,
865                                                 struct rp_port  *rp));
866
867 static _INLINE_ void rp_do_receive(struct rp_port *rp, struct tty *tp,
868                         CHANNEL_t *cp, unsigned int ChanStatus)
869 {
870         int     spl;
871         unsigned        int     CharNStat;
872         int     ToRecv, ch;
873
874         ToRecv = sGetRxCnt(cp);
875         if(ToRecv == 0)
876                 return;
877
878 /*      If status indicates there are errored characters in the
879         FIFO, then enter status mode (a word in FIFO holds
880         characters and status)
881 */
882
883         if(ChanStatus & (RXFOVERFL | RXBREAK | RXFRAME | RXPARITY)) {
884                 if(!(ChanStatus & STATMODE)) {
885                         ChanStatus |= STATMODE;
886                         sEnRxStatusMode(cp);
887                 }
888         }
889 /*
890         if we previously entered status mode then read down the
891         FIFO one word at a time, pulling apart the character and
892         the status. Update error counters depending on status.
893 */
894         if(ChanStatus & STATMODE) {
895                 while(ToRecv) {
896                         if(tp->t_state & TS_TBLOCK) {
897                                 break;
898                         }
899                         CharNStat = sInW(sGetTxRxDataIO(cp));
900                         ch = CharNStat & 0xff;
901
902                         if((CharNStat & STMBREAK) || (CharNStat & STMFRAMEH))
903                                 ch |= TTY_FE;
904                         else if (CharNStat & STMPARITYH)
905                                 ch |= TTY_PE;
906                         else if (CharNStat & STMRCVROVRH)
907                                 rp->rp_overflows++;
908
909                         (*linesw[tp->t_line].l_rint)(ch, tp);
910                         ToRecv--;
911                 }
912 /*
913         After emtying FIFO in status mode, turn off status mode
914 */
915
916         if(sGetRxCnt(cp) == 0)
917                 sDisRxStatusMode(cp);
918         }
919         else {
920                 while (ToRecv) {
921                         if(tp->t_state & TS_TBLOCK) {
922                                 break;
923                         }
924                         ch = (u_char) sInB(sGetTxRxDataIO(cp));
925                         spl = spltty();
926                         (*linesw[tp->t_line].l_rint)(ch, tp);
927                         splx(spl);
928                         ToRecv--;
929                 }
930         }
931 }
932
933 static _INLINE_ void rp_handle_port(struct rp_port *rp)
934 {
935         CHANNEL_t       *cp;
936         struct  tty     *tp;
937         unsigned        int     IntMask, ChanStatus;
938      /* int     oldcts; */
939
940         if(!rp)
941                 return;
942
943         cp = &rp->rp_channel;
944         tp = rp->rp_tty;
945         IntMask = sGetChanIntID(cp);
946         IntMask = IntMask & rp->rp_intmask;
947         ChanStatus = sGetChanStatus(cp);
948         if(IntMask & RXF_TRIG)
949                 if(!(tp->t_state & TS_TBLOCK) && (tp->t_state & TS_CARR_ON) && (tp->t_state & TS_ISOPEN)) {
950                         rp_do_receive(rp, tp, cp, ChanStatus);
951                 }
952         if(IntMask & DELTA_CD) {
953                 if(ChanStatus & CD_ACT) {
954                         if(!(tp->t_state & TS_CARR_ON) ) {
955                                 (void)(*linesw[tp->t_line].l_modem)(tp, 1);
956                         }
957                 } else {
958                         if((tp->t_state & TS_CARR_ON)) {
959                                 (void)(*linesw[tp->t_line].l_modem)(tp, 0);
960                                 if((*linesw[tp->t_line].l_modem)(tp, 0) == 0) {
961                                         rphardclose(rp);
962                                 }
963                         }
964                 }
965         }
966 /*      oldcts = rp->rp_cts;
967         rp->rp_cts = ((ChanStatus & CTS_ACT) != 0);
968         if(oldcts != rp->rp_cts) {
969                 printf("CTS change (now %s)... on port %d\n", rp->rp_cts ? "on" : "off", rp->rp_port);
970         }
971 */
972 }
973
974 static void rp_do_poll(void *not_used)
975 {
976         CONTROLLER_t    *ctl;
977         struct rp_port  *rp;
978         struct tty      *tp;
979         int     unit, aiop, ch, line, count;
980         unsigned char   CtlMask, AiopMask;
981
982         for(unit = 0; unit <= ndevs; unit++) {
983         rp = rp_addr(unit);
984         ctl = rp->rp_ctlp;
985         if(ctl->BusType == isPCI)
986                 CtlMask = sPCIGetControllerIntStatus(ctl);
987         else
988                 CtlMask = sGetControllerIntStatus(ctl);
989         for(aiop=0; CtlMask; CtlMask >>=1, aiop++) {
990                 if(CtlMask & 1) {
991                         AiopMask = sGetAiopIntStatus(ctl, aiop);
992                         for(ch = 0; AiopMask; AiopMask >>=1, ch++) {
993                                 if(AiopMask & 1) {
994                                         line = (unit << 5) | (aiop << 3) | ch;
995                                         rp = rp_table(line);
996                                         rp_handle_port(rp);
997                                 }
998                         }
999                 }
1000         }
1001
1002         for(line = 0, rp = rp_addr(unit); line < rp_num_ports[unit];
1003                         line++, rp++) {
1004                 tp = rp->rp_tty;
1005                 if((tp->t_state & TS_BUSY) && (tp->t_state & TS_ISOPEN)) {
1006                         count = sGetTxCnt(&rp->rp_channel);
1007                         if(count == 0)
1008                                 tp->t_state &= ~(TS_BUSY);
1009                         if(!(tp->t_state & TS_TTSTOP) &&
1010                                 (count <= rp->rp_restart)) {
1011                                 (*linesw[tp->t_line].l_start)(tp);
1012                         }
1013                 }
1014         }
1015         }
1016         if(rp_num_ports_open)
1017                 timeout(rp_do_poll, (void *)NULL, POLL_INTERVAL);
1018 }
1019
1020 static const char*
1021 rp_pciprobe(pcici_t tag, pcidi_t type)
1022 {
1023         int     vendor_id;
1024
1025         vendor_id = type & 0xffff;
1026         switch(vendor_id)
1027         case 0x11fe:
1028                 return("rp");
1029         return(NULL);
1030 }
1031
1032 static
1033 int
1034 rpprobe(dev)
1035 struct isa_device *dev;
1036 {
1037         int controller, unit;
1038         int aiop, num_aiops;
1039         unsigned int aiopio[MAX_AIOPS_PER_BOARD];
1040         CONTROLLER_t *ctlp;
1041
1042         unit = dev->id_unit;
1043         if (dev->id_unit >= 4) {
1044                 printf("rpprobe: unit number %d invalid.\n", dev->id_unit);
1045                 return 1;
1046         }
1047         printf("probing for RocketPort(ISA) unit %d\n", unit);
1048         if (rp_controller_port)
1049                 controller = rp_controller_port;
1050         else {
1051                 controller = dev->id_iobase + 0x40;
1052         }
1053
1054         for (aiop=0; aiop<MAX_AIOPS_PER_BOARD; aiop++)
1055                 aiopio[aiop]= dev->id_iobase + (aiop * 0x400);
1056
1057         ctlp = sCtlNumToCtlPtr(dev->id_unit);
1058         num_aiops = sInitController(ctlp, dev->id_unit,
1059                                 controller + ((unit-rp_pcicount)*0x400),
1060                                 aiopio, MAX_AIOPS_PER_BOARD, 0,
1061                                 FREQ_DIS, 0);
1062         if (num_aiops <= 0) {
1063                 printf("board%d init failed\n", unit);
1064                 return 0;
1065         }
1066
1067         if (rp_controller_port) {
1068                 dev->id_msize = 64;
1069         } else {
1070                 dev->id_msize = 68;
1071                 rp_controller_port = controller;
1072         }
1073
1074         dev->id_irq = 0;
1075
1076         return 1;
1077 }
1078
1079 static void
1080 rp_pciattach(pcici_t tag, int unit)
1081 {
1082         int     success, oldspl;
1083         u_short iobase;
1084         int     num_ports, num_chan, num_aiops;
1085         int     aiop, chan, port;
1086         int     ChanStatus, line, i, count;
1087         unsigned int    aiopio[MAX_AIOPS_PER_BOARD];
1088         struct  rp_port *rp;
1089         struct  tty     *tty;
1090         CONTROLLER_t    *ctlp;
1091
1092         success = pci_map_port(tag, 0x10, &iobase);
1093         if(!success)
1094                 printf("ioaddr mapping failed for RocketPort(PCI)\n");
1095
1096         for(aiop=0; aiop < MAX_AIOPS_PER_BOARD; aiop++)
1097                 aiopio[aiop] = iobase + (aiop * 0x40);
1098
1099         ctlp = sCtlNumToCtlPtr(unit);
1100         num_aiops = sPCIInitController(ctlp, unit,
1101                                 aiopio, MAX_AIOPS_PER_BOARD, 0,
1102                                 FREQ_DIS, 0);
1103
1104         num_ports = 0;
1105         for(aiop=0; aiop < num_aiops; aiop++) {
1106                 sResetAiopByNum(ctlp, aiop);
1107                 num_ports += sGetAiopNumChan(ctlp, aiop);
1108         }
1109         printf("RocketPort%d = %d ports\n", unit, num_ports);
1110         rp_num_ports[unit] = num_ports;
1111
1112         rp = (struct rp_port *)
1113             malloc(sizeof(struct rp_port) * num_ports, M_TTYS, M_NOWAIT|M_ZERO);
1114         if(rp == 0) {
1115                 printf("rp_attach: Could not malloc rp_ports structures\n");
1116                 return;
1117         }
1118
1119         count = unit * 32;      /* board times max ports per card SG */
1120         for(i=count;i < (count + rp_num_ports[unit]);i++)
1121                 minor_to_unit[i] = unit;
1122
1123         tty = (struct tty *)
1124             malloc(sizeof(struct tty) * num_ports, M_TTYS, M_NOWAIT|M_ZERO);
1125         if(tty == 0) {
1126                 printf("rp_attach: Could not malloc tty structures\n");
1127                 return;
1128         }
1129
1130         oldspl = spltty();
1131         rp_addr(unit) = rp;
1132         splx(oldspl);
1133
1134         cdevsw_add(&rp_cdevsw);
1135
1136         port = 0;
1137         for(aiop=0; aiop < num_aiops; aiop++) {
1138                 num_chan = sGetAiopNumChan(ctlp, aiop);
1139                 for(chan=0; chan < num_chan; chan++, port++, rp++, tty++) {
1140                         rp->rp_tty = tty;
1141                         rp->rp_port = port;
1142                         rp->rp_ctlp = ctlp;
1143                         rp->rp_unit = unit;
1144                         rp->rp_chan = chan;
1145                         rp->rp_aiop = aiop;
1146
1147                         tty->t_line = 0;
1148         /*              tty->t_termios = deftermios;
1149         */
1150                         rp->dtr_wait = 3 * hz;
1151                         rp->it_in.c_iflag = 0;
1152                         rp->it_in.c_oflag = 0;
1153                         rp->it_in.c_cflag = TTYDEF_CFLAG;
1154                         rp->it_in.c_lflag = 0;
1155                         termioschars(&rp->it_in);
1156         /*              termioschars(&tty->t_termios);
1157         */
1158                         rp->it_in.c_ispeed = rp->it_in.c_ospeed = TTYDEF_SPEED;
1159                         rp->it_out = rp->it_in;
1160
1161                         rp->rp_intmask = RXF_TRIG | TXFIFO_MT | SRC_INT |
1162                                 DELTA_CD | DELTA_CTS | DELTA_DSR;
1163                         ChanStatus = sGetChanStatus(&rp->rp_channel);
1164                         if(sInitChan(ctlp, &rp->rp_channel, aiop, chan) == 0) {
1165                                 printf("RocketPort sInitChan(%d, %d, %d) failed
1166                                         \n", unit, aiop, chan);
1167                                 return;
1168                         }
1169                         ChanStatus = sGetChanStatus(&rp->rp_channel);
1170                         rp->rp_cts = (ChanStatus & CTS_ACT) != 0;
1171                         line = (unit << 5) | (aiop << 3) | chan;
1172                         rp_table(line) = rp;
1173                 }
1174         }
1175 }
1176
1177 static
1178 int
1179 rpattach(dev)
1180 struct  isa_device      *dev;
1181 {
1182         int     iobase, unit, /*rpmajor,*/ oldspl;
1183         int     num_ports, num_chan, num_aiops;
1184         int     aiop, chan, port;
1185         int     ChanStatus, line, i, count;
1186         unsigned int    aiopio[MAX_AIOPS_PER_BOARD];
1187         struct  rp_port *rp;
1188         struct  tty     *tty;
1189         CONTROLLER_t    *ctlp;
1190
1191         iobase = dev->id_iobase;
1192         unit = dev->id_unit;
1193         ndevs = unit;
1194
1195         for(aiop=0; aiop < MAX_AIOPS_PER_BOARD; aiop++)
1196                 aiopio[aiop] = iobase + (aiop * 0x400);
1197
1198         ctlp = sCtlNumToCtlPtr(unit);
1199         num_aiops = sInitController(ctlp, unit,
1200                                 rp_controller_port + ((unit-rp_pcicount) * 0x400),
1201                                 aiopio, MAX_AIOPS_PER_BOARD, 0,
1202                                 FREQ_DIS, 0);
1203
1204         num_ports = 0;
1205         for(aiop=0; aiop < num_aiops; aiop++) {
1206                 sResetAiopByNum(ctlp, aiop);
1207                 sEnAiop(ctlp, aiop);
1208                 num_ports += sGetAiopNumChan(ctlp, aiop);
1209         }
1210         printf("RocketPort%d = %d ports\n", unit, num_ports);
1211         rp_num_ports[unit] = num_ports;
1212
1213         rp = (struct rp_port *)
1214             malloc(sizeof(struct rp_port) * num_ports, M_TTYS, M_NOWAIT|M_ZERO);
1215         if(rp == 0) {
1216                 printf("rp_attach: Could not malloc rp_ports structures\n");
1217                 return(0);
1218         }
1219
1220         count = unit * 32;    /* board # times max ports per card  SG */
1221         for(i=count;i < (count + rp_num_ports[unit]);i++)
1222                 minor_to_unit[i] = unit;
1223
1224         tty = (struct tty *)
1225             malloc(sizeof(struct tty) * num_ports, M_TTYS, M_NOWAIT|M_ZERO);
1226         if(tty == 0) {
1227                 printf("rp_attach: Could not malloc tty structures\n");
1228                 return(0);
1229         }
1230
1231         oldspl = spltty();
1232         rp_addr(unit) = rp;
1233         splx(oldspl);
1234
1235         cdevsw_add(&rp_cdevsw);
1236
1237         port = 0;
1238         for(aiop=0; aiop < num_aiops; aiop++) {
1239                 num_chan = sGetAiopNumChan(ctlp, aiop);
1240                 for(chan=0; chan < num_chan; chan++, port++, rp++, tty++) {
1241                         rp->rp_tty = tty;
1242                         rp->rp_port = port;
1243                         rp->rp_ctlp = ctlp;
1244                         rp->rp_unit = unit;
1245                         rp->rp_chan = chan;
1246                         rp->rp_aiop = aiop;
1247
1248                         tty->t_line = 0;
1249         /*              tty->t_termios = deftermios;
1250         */
1251                         rp->dtr_wait = 3 * hz;
1252                         rp->it_in.c_iflag = 0;
1253                         rp->it_in.c_oflag = 0;
1254                         rp->it_in.c_cflag = TTYDEF_CFLAG;
1255                         rp->it_in.c_lflag = 0;
1256                         termioschars(&rp->it_in);
1257         /*              termioschars(&tty->t_termios);
1258         */
1259                         rp->it_in.c_ispeed = rp->it_in.c_ospeed = TTYDEF_SPEED;
1260                         rp->it_out = rp->it_in;
1261
1262                         rp->rp_intmask = RXF_TRIG | TXFIFO_MT | SRC_INT |
1263                                 DELTA_CD | DELTA_CTS | DELTA_DSR;
1264                         ChanStatus = sGetChanStatus(&rp->rp_channel);
1265                         if(sInitChan(ctlp, &rp->rp_channel, aiop, chan) == 0) {
1266                                 printf("RocketPort sInitChan(%d, %d, %d) failed
1267                                         \n", unit, aiop, chan);
1268                                 return(0);
1269                         }
1270                         ChanStatus = sGetChanStatus(&rp->rp_channel);
1271                         rp->rp_cts = (ChanStatus & CTS_ACT) != 0;
1272                         line = (unit << 5) | (aiop << 3) | chan;
1273                         rp_table(line) = rp;
1274                 }
1275         }
1276
1277         return(1);
1278 }
1279
1280 int
1281 rpopen(dev, flag, mode, p)
1282         dev_t   dev;
1283         int     flag, mode;
1284         struct  proc    *p;
1285 {
1286         struct  rp_port *rp;
1287         int     unit, port, mynor, umynor, flags;  /* SG */
1288         struct  tty     *tp;
1289         int     oldspl, error;
1290         unsigned int    IntMask, ChanStatus;
1291
1292
1293    umynor = (((minor(dev) >> 16) -1) * 32);    /* SG */
1294         port  = (minor(dev) & 0x1f);                /* SG */
1295         mynor = (port + umynor);                    /* SG */
1296         unit = minor_to_unit[mynor];
1297         if (rp_addr(unit) == NULL)
1298                 return (ENXIO);
1299         if(IS_CONTROL(dev))
1300                 return(0);
1301         rp = rp_addr(unit) + port;
1302 /*      rp->rp_tty = &rp_tty[rp->rp_port];
1303 */
1304         tp = rp->rp_tty;
1305         dev->si_tty = tp;
1306
1307         oldspl = spltty();
1308
1309 open_top:
1310         while(rp->state & ~SET_DTR) {
1311                 error = tsleep(&rp->dtr_wait, TTIPRI | PCATCH, "rpdtr", 0);
1312                 if(error != 0)
1313                         goto out;
1314         }
1315
1316         if(tp->t_state & TS_ISOPEN) {
1317                 if(IS_CALLOUT(dev)) {
1318                         if(!rp->active_out) {
1319                                 error = EBUSY;
1320                                 goto out;
1321                         }
1322                 } else {
1323                         if(rp->active_out) {
1324                                 if(flag & O_NONBLOCK) {
1325                                         error = EBUSY;
1326                                         goto out;
1327                                 }
1328                                 error = tsleep(&rp->active_out,
1329                                         TTIPRI | PCATCH, "rpbi", 0);
1330                                 if(error != 0)
1331                                         goto out;
1332                                 goto open_top;
1333                         }
1334                 }
1335                 if(tp->t_state & TS_XCLUDE &&
1336                     suser(p)) {
1337                         splx(oldspl);
1338                         return(EBUSY);
1339                 }
1340         }
1341         else {
1342                 tp->t_dev = dev;
1343                 tp->t_param = rpparam;
1344                 tp->t_oproc = rpstart;
1345                 tp->t_stop = rpstop;
1346                 tp->t_line = 0;
1347                 tp->t_termios = IS_CALLOUT(dev) ? rp->it_out : rp->it_in;
1348                 flags = 0;
1349                 flags |= SET_RTS;
1350                 flags |= SET_DTR;
1351                 rp->rp_channel.TxControl[3] =
1352                         ((rp->rp_channel.TxControl[3]
1353                         & ~(SET_RTS | SET_DTR)) | flags);
1354                 sOutDW(rp->rp_channel.IndexAddr,
1355                         *(DWord_t *) &(rp->rp_channel.TxControl[0]));
1356                 sSetRxTrigger(&rp->rp_channel, TRIG_1);
1357                 sDisRxStatusMode(&rp->rp_channel);
1358                 sFlushRxFIFO(&rp->rp_channel);
1359                 sFlushTxFIFO(&rp->rp_channel);
1360
1361                 sEnInterrupts(&rp->rp_channel,
1362                         (TXINT_EN|MCINT_EN|RXINT_EN|SRCINT_EN|CHANINT_EN));
1363                 sSetRxTrigger(&rp->rp_channel, TRIG_1);
1364
1365                 sDisRxStatusMode(&rp->rp_channel);
1366                 sClrTxXOFF(&rp->rp_channel);
1367
1368 /*              sDisRTSFlowCtl(&rp->rp_channel);
1369                 sDisCTSFlowCtl(&rp->rp_channel);
1370 */
1371                 sDisTxSoftFlowCtl(&rp->rp_channel);
1372
1373                 sStartRxProcessor(&rp->rp_channel);
1374
1375                 sEnRxFIFO(&rp->rp_channel);
1376                 sEnTransmit(&rp->rp_channel);
1377
1378 /*              sSetDTR(&rp->rp_channel);
1379                 sSetRTS(&rp->rp_channel);
1380 */
1381
1382                 ++rp->wopeners;
1383                 error = rpparam(tp, &tp->t_termios);
1384                 --rp->wopeners;
1385                 if(error != 0) {
1386                         splx(oldspl);
1387                         return(error);
1388                 }
1389
1390                 rp_num_ports_open++;
1391
1392                 IntMask = sGetChanIntID(&rp->rp_channel);
1393                 IntMask = IntMask & rp->rp_intmask;
1394                 ChanStatus = sGetChanStatus(&rp->rp_channel);
1395                 if((IntMask & DELTA_CD) || IS_CALLOUT(dev)) {
1396                         if((ChanStatus & CD_ACT) || IS_CALLOUT(dev)) {
1397                                         (void)(*linesw[tp->t_line].l_modem)(tp, 1);
1398                         }
1399                 }
1400
1401         if(rp_num_ports_open == 1)
1402                 timeout(rp_do_poll, (void *)NULL, POLL_INTERVAL);
1403
1404         }
1405
1406         if(!(flag&O_NONBLOCK) && !(tp->t_cflag&CLOCAL) &&
1407                 !(tp->t_state & TS_CARR_ON) && !(IS_CALLOUT(dev))) {
1408                 ++rp->wopeners;
1409                 error = tsleep(TSA_CARR_ON(tp), TTIPRI | PCATCH,
1410                                 "rpdcd", 0);
1411                 --rp->wopeners;
1412                 if(error != 0)
1413                         goto out;
1414                 goto open_top;
1415         }
1416         error = (*linesw[tp->t_line].l_open)(dev, tp);
1417
1418         rp_disc_optim(tp, &tp->t_termios, rp);
1419         if(tp->t_state & TS_ISOPEN && IS_CALLOUT(dev))
1420                 rp->active_out = TRUE;
1421
1422 /*      if(rp_num_ports_open == 1)
1423                 timeout(rp_do_poll, (void *)NULL, POLL_INTERVAL);
1424 */
1425 out:
1426         splx(oldspl);
1427         if(!(tp->t_state & TS_ISOPEN) && rp->wopeners == 0) {
1428                 rphardclose(rp);
1429         }
1430         return(error);
1431 }
1432
1433 int
1434 rpclose(dev, flag, mode, p)
1435         dev_t   dev;
1436         int     flag, mode;
1437         struct  proc    *p;
1438 {
1439         int     oldspl, unit, mynor, umynor, port; /* SG */
1440         struct  rp_port *rp;
1441         struct  tty     *tp;
1442         CHANNEL_t       *cp;
1443
1444    umynor = (((minor(dev) >> 16) -1) * 32);    /* SG */
1445         port  = (minor(dev) & 0x1f);                /* SG */
1446         mynor = (port + umynor);                    /* SG */
1447    unit = minor_to_unit[mynor];                /* SG */
1448
1449         if(IS_CONTROL(dev))
1450                 return(0);
1451         rp = rp_addr(unit) + port;
1452         cp = &rp->rp_channel;
1453         tp = rp->rp_tty;
1454
1455         oldspl = spltty();
1456         (*linesw[tp->t_line].l_close)(tp, flag);
1457         rp_disc_optim(tp, &tp->t_termios, rp);
1458         rpstop(tp, FREAD | FWRITE);
1459         rphardclose(rp);
1460
1461         tp->t_state &= ~TS_BUSY;
1462         ttyclose(tp);
1463
1464         splx(oldspl);
1465
1466         return(0);
1467 }
1468
1469 static void
1470 rphardclose(struct rp_port *rp)
1471 {
1472         int     mynor;
1473         struct  tty     *tp;
1474         CHANNEL_t       *cp;
1475
1476         cp = &rp->rp_channel;
1477         tp = rp->rp_tty;
1478         mynor = MINOR_MAGIC(tp->t_dev);
1479
1480         sFlushRxFIFO(cp);
1481         sFlushTxFIFO(cp);
1482         sDisTransmit(cp);
1483         sDisInterrupts(cp, TXINT_EN|MCINT_EN|RXINT_EN|SRCINT_EN|CHANINT_EN);
1484         sDisRTSFlowCtl(cp);
1485         sDisCTSFlowCtl(cp);
1486         sDisTxSoftFlowCtl(cp);
1487         sClrTxXOFF(cp);
1488
1489         if(tp->t_cflag&HUPCL || !(tp->t_state&TS_ISOPEN) || !rp->active_out) {
1490                 sClrDTR(cp);
1491         }
1492         if(IS_CALLOUT(tp->t_dev)) {
1493                 sClrDTR(cp);
1494         }
1495         if(rp->dtr_wait != 0) {
1496                 timeout(rpdtrwakeup, rp, rp->dtr_wait);
1497                 rp->state |= ~SET_DTR;
1498         }
1499
1500         rp->active_out = FALSE;
1501         wakeup(&rp->active_out);
1502         wakeup(TSA_CARR_ON(tp));
1503 }
1504
1505 static
1506 int
1507 rpwrite(dev, uio, flag)
1508         dev_t   dev;
1509         struct  uio     *uio;
1510         int     flag;
1511 {
1512         struct  rp_port *rp;
1513         struct  tty     *tp;
1514         int     unit, mynor, port, umynor, error = 0; /* SG */
1515
1516    umynor = (((minor(dev) >> 16) -1) * 32);    /* SG */
1517         port  = (minor(dev) & 0x1f);                /* SG */
1518         mynor = (port + umynor);                    /* SG */
1519    unit = minor_to_unit[mynor];                /* SG */
1520
1521         if(IS_CONTROL(dev))
1522                 return(ENODEV);
1523         rp = rp_addr(unit) + port;
1524         tp = rp->rp_tty;
1525         while(rp->rp_disable_writes) {
1526                 rp->rp_waiting = 1;
1527                 error = ttysleep(tp, (caddr_t)rp, TTOPRI|PCATCH, "rp_write", 0);
1528                 if (error)
1529                         return(error);
1530         }
1531
1532         error = (*linesw[tp->t_line].l_write)(tp, uio, flag);
1533         return error;
1534 }
1535
1536 static void
1537 rpdtrwakeup(void *chan)
1538 {
1539         struct  rp_port *rp;
1540
1541         rp = (struct rp_port *)chan;
1542         rp->state &= SET_DTR;
1543         wakeup(&rp->dtr_wait);
1544 }
1545
1546 int
1547 rpioctl(dev, cmd, data, flag, p)
1548         dev_t   dev;
1549         u_long  cmd;
1550         caddr_t data;
1551         int     flag;
1552         struct  proc    *p;
1553 {
1554         struct rp_port  *rp;
1555         CHANNEL_t       *cp;
1556         struct tty      *tp;
1557         int     unit, mynor, port, umynor;            /* SG */
1558         int     oldspl;
1559         int     error = 0;
1560         int     arg, flags, result, ChanStatus;
1561         int     oldcmd;
1562         struct  termios term, *t;
1563
1564    umynor = (((minor(dev) >> 16) -1) * 32);    /* SG */
1565         port  = (minor(dev) & 0x1f);                /* SG */
1566         mynor = (port + umynor);                    /* SG */
1567         unit = minor_to_unit[mynor];
1568         rp = rp_addr(unit) + port;
1569
1570         if(IS_CONTROL(dev)) {
1571                 struct  termios *ct;
1572
1573                 switch (IS_CONTROL(dev)) {
1574                 case CONTROL_INIT_STATE:
1575                         ct =  IS_CALLOUT(dev) ? &rp->it_out : &rp->it_in;
1576                         break;
1577                 case CONTROL_LOCK_STATE:
1578                         ct =  IS_CALLOUT(dev) ? &rp->lt_out : &rp->lt_in;
1579                         break;
1580                 default:
1581                         return(ENODEV);         /* /dev/nodev */
1582                 }
1583                 switch (cmd) {
1584                 case TIOCSETA:
1585                         error = suser(p);
1586                         if(error != 0)
1587                                 return(error);
1588                         *ct = *(struct termios *)data;
1589                         return(0);
1590                 case TIOCGETA:
1591                         *(struct termios *)data = *ct;
1592                         return(0);
1593                 case TIOCGETD:
1594                         *(int *)data = TTYDISC;
1595                         return(0);
1596                 case TIOCGWINSZ:
1597                         bzero(data, sizeof(struct winsize));
1598                         return(0);
1599                 default:
1600                         return(ENOTTY);
1601                 }
1602         }
1603
1604         tp = rp->rp_tty;
1605         cp = &rp->rp_channel;
1606
1607 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1608         term = tp->t_termios;
1609         oldcmd = cmd;
1610         error = ttsetcompat(tp, &cmd, data, &term);
1611         if(error != 0)
1612                 return(error);
1613         if(cmd != oldcmd) {
1614                 data = (caddr_t)&term;
1615         }
1616 #endif
1617         if((cmd == TIOCSETA) || (cmd == TIOCSETAW) || (cmd == TIOCSETAF)) {
1618                 int     cc;
1619                 struct  termios *dt = (struct termios *)data;
1620                 struct  termios *lt = IS_CALLOUT(dev)
1621                                         ? &rp->lt_out : &rp->lt_in;
1622
1623                 dt->c_iflag = (tp->t_iflag & lt->c_iflag)
1624                                 | (dt->c_iflag & ~lt->c_iflag);
1625                 dt->c_oflag = (tp->t_oflag & lt->c_oflag)
1626                                 | (dt->c_oflag & ~lt->c_oflag);
1627                 dt->c_cflag = (tp->t_cflag & lt->c_cflag)
1628                                 | (dt->c_cflag & ~lt->c_cflag);
1629                 dt->c_lflag = (tp->t_lflag & lt->c_lflag)
1630                                 | (dt->c_lflag & ~lt->c_lflag);
1631                 for(cc = 0; cc < NCCS; ++cc)
1632                         if(lt->c_cc[cc] != 0)
1633                                 dt->c_cc[cc] = tp->t_cc[cc];
1634                 if(lt->c_ispeed != 0)
1635                         dt->c_ispeed = tp->t_ispeed;
1636                 if(lt->c_ospeed != 0)
1637                         dt->c_ospeed = tp->t_ospeed;
1638         }
1639
1640         t = &tp->t_termios;
1641
1642         error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
1643         if(error != ENOIOCTL) {
1644                 return(error);
1645         }
1646         oldspl = spltty();
1647
1648         flags = rp->rp_channel.TxControl[3];
1649
1650         error = ttioctl(tp, cmd, data, flag);
1651         flags = rp->rp_channel.TxControl[3];
1652         rp_disc_optim(tp, &tp->t_termios, rp);
1653         if(error != ENOIOCTL) {
1654                 splx(oldspl);
1655                 return(error);
1656         }
1657         switch(cmd) {
1658         case TIOCSBRK:
1659                 sSendBreak(&rp->rp_channel);
1660                 break;
1661
1662         case TIOCCBRK:
1663                 sClrBreak(&rp->rp_channel);
1664                 break;
1665
1666         case TIOCSDTR:
1667                 sSetDTR(&rp->rp_channel);
1668                 sSetRTS(&rp->rp_channel);
1669                 break;
1670
1671         case TIOCCDTR:
1672                 sClrDTR(&rp->rp_channel);
1673                 break;
1674
1675         case TIOCMSET:
1676                 arg = *(int *) data;
1677                 flags = 0;
1678                 if(arg & TIOCM_RTS)
1679                         flags |= SET_RTS;
1680                 if(arg & TIOCM_DTR)
1681                         flags |= SET_DTR;
1682                 rp->rp_channel.TxControl[3] =
1683                         ((rp->rp_channel.TxControl[3]
1684                         & ~(SET_RTS | SET_DTR)) | flags);
1685                 sOutDW(rp->rp_channel.IndexAddr,
1686                         *(DWord_t *) &(rp->rp_channel.TxControl[0]));
1687                 break;
1688         case TIOCMBIS:
1689                 arg = *(int *) data;
1690                 flags = 0;
1691                 if(arg & TIOCM_RTS)
1692                         flags |= SET_RTS;
1693                 if(arg & TIOCM_DTR)
1694                         flags |= SET_DTR;
1695                         rp->rp_channel.TxControl[3] |= flags;
1696                 sOutDW(rp->rp_channel.IndexAddr,
1697                         *(DWord_t *) &(rp->rp_channel.TxControl[0]));
1698                 break;
1699         case TIOCMBIC:
1700                 arg = *(int *) data;
1701                 flags = 0;
1702                 if(arg & TIOCM_RTS)
1703                         flags |= SET_RTS;
1704                 if(arg & TIOCM_DTR)
1705                         flags |= SET_DTR;
1706                 rp->rp_channel.TxControl[3] &= ~flags;
1707                 sOutDW(rp->rp_channel.IndexAddr,
1708                         *(DWord_t *) &(rp->rp_channel.TxControl[0]));
1709                 break;
1710
1711
1712         case TIOCMGET:
1713                 ChanStatus = sGetChanStatusLo(&rp->rp_channel);
1714                 flags = rp->rp_channel.TxControl[3];
1715                 result = TIOCM_LE; /* always on while open for some reason */
1716                 result |= (((flags & SET_DTR) ? TIOCM_DTR : 0)
1717                         | ((flags & SET_RTS) ? TIOCM_RTS : 0)
1718                         | ((ChanStatus & CD_ACT) ? TIOCM_CAR : 0)
1719                         | ((ChanStatus & DSR_ACT) ? TIOCM_DSR : 0)
1720                         | ((ChanStatus & CTS_ACT) ? TIOCM_CTS : 0));
1721
1722                 if(rp->rp_channel.RxControl[2] & RTSFC_EN)
1723                 {
1724                         result |= TIOCM_RTS;
1725                 }
1726
1727                 *(int *)data = result;
1728                 break;
1729         case TIOCMSDTRWAIT:
1730                 error = suser(p);
1731                 if(error != 0) {
1732                         splx(oldspl);
1733                         return(error);
1734                 }
1735                 rp->dtr_wait = *(int *)data * hz/100;
1736                 break;
1737         case TIOCMGDTRWAIT:
1738                 *(int *)data = rp->dtr_wait * 100/hz;
1739                 break;
1740         default:
1741                 splx(oldspl);
1742                 return ENOTTY;
1743         }
1744         splx(oldspl);
1745         return(0);
1746 }
1747
1748 static struct speedtab baud_table[] = {
1749         {B0,    0},             {B50,   BRD50},         {B75,   BRD75},
1750         {B110,  BRD110},        {B134,  BRD134},        {B150,  BRD150},
1751         {B200,  BRD200},        {B300,  BRD300},        {B600,  BRD600},
1752         {B1200, BRD1200},       {B1800, BRD1800},       {B2400, BRD2400},
1753         {B4800, BRD4800},       {B9600, BRD9600},       {B19200, BRD19200},
1754         {B38400, BRD38400},     {B7200, BRD7200},       {B14400, BRD14400},
1755                                 {B57600, BRD57600},     {B76800, BRD76800},
1756         {B115200, BRD115200},   {B230400, BRD230400},
1757         -1,     -1
1758 };
1759
1760 static int
1761 rpparam(tp, t)
1762         struct tty *tp;
1763         struct termios *t;
1764 {
1765         struct rp_port  *rp;
1766         CHANNEL_t       *cp;
1767         int     unit, mynor, port, umynor;               /* SG */
1768         int     oldspl, cflag, iflag, oflag, lflag;
1769         int     ospeed;
1770
1771
1772    umynor = (((minor(tp->t_dev) >> 16) -1) * 32);    /* SG */
1773         port  = (minor(tp->t_dev) & 0x1f);                /* SG */
1774         mynor = (port + umynor);                          /* SG */
1775
1776         unit = minor_to_unit[mynor];
1777         rp = rp_addr(unit) + port;
1778         cp = &rp->rp_channel;
1779         oldspl = spltty();
1780
1781         cflag = t->c_cflag;
1782         iflag = t->c_iflag;
1783         oflag = t->c_oflag;
1784         lflag = t->c_lflag;
1785
1786         ospeed = ttspeedtab(t->c_ispeed, baud_table);
1787         if(ospeed < 0 || t->c_ispeed != t->c_ospeed)
1788                 return(EINVAL);
1789
1790         tp->t_ispeed = t->c_ispeed;
1791         tp->t_ospeed = t->c_ospeed;
1792         tp->t_cflag = cflag;
1793         tp->t_iflag = iflag;
1794         tp->t_oflag = oflag;
1795         tp->t_lflag = lflag;
1796
1797         if(t->c_ospeed == 0) {
1798                 sClrDTR(cp);
1799                 return(0);
1800         }
1801         rp->rp_fifo_lw = ((t->c_ospeed*2) / 1000) +1;
1802
1803         /* Set baud rate ----- we only pay attention to ispeed */
1804         sSetDTR(cp);
1805         sSetRTS(cp);
1806         sSetBaud(cp, ospeed);
1807
1808         if(cflag & CSTOPB) {
1809                 sSetStop2(cp);
1810         } else {
1811                 sSetStop1(cp);
1812         }
1813
1814         if(cflag & PARENB) {
1815                 sEnParity(cp);
1816                 if(cflag & PARODD) {
1817                         sSetOddParity(cp);
1818                 } else {
1819                         sSetEvenParity(cp);
1820                 }
1821         }
1822         else {
1823                 sDisParity(cp);
1824         }
1825         if((cflag & CSIZE) == CS8) {
1826                 sSetData8(cp);
1827                 rp->rp_imask = 0xFF;
1828         } else {
1829                 sSetData7(cp);
1830                 rp->rp_imask = 0x7F;
1831         }
1832
1833         if(iflag & ISTRIP) {
1834                 rp->rp_imask &= 0x7F;
1835         }
1836
1837         if(cflag & CLOCAL) {
1838                 rp->rp_intmask &= ~DELTA_CD;
1839         } else {
1840                 rp->rp_intmask |= DELTA_CD;
1841         }
1842
1843         /* Put flow control stuff here */
1844
1845         if(cflag & CCTS_OFLOW) {
1846                 sEnCTSFlowCtl(cp);
1847         } else {
1848                 sDisCTSFlowCtl(cp);
1849         }
1850
1851         if(cflag & CRTS_IFLOW) {
1852                 rp->rp_rts_iflow = 1;
1853         } else {
1854                 rp->rp_rts_iflow = 0;
1855         }
1856
1857         if(cflag & CRTS_IFLOW) {
1858                 sEnRTSFlowCtl(cp);
1859         } else {
1860                 sDisRTSFlowCtl(cp);
1861         }
1862         rp_disc_optim(tp, t, rp);
1863
1864         if((cflag & CLOCAL) || (sGetChanStatusLo(cp) & CD_ACT)) {
1865                 tp->t_state |= TS_CARR_ON;
1866                 wakeup(TSA_CARR_ON(tp));
1867         }
1868
1869 /*      tp->t_state |= TS_CAN_BYPASS_L_RINT;
1870         flags = rp->rp_channel.TxControl[3];
1871         if(flags & SET_DTR)
1872         else
1873         if(flags & SET_RTS)
1874         else
1875 */
1876         splx(oldspl);
1877
1878         return(0);
1879 }
1880
1881 static void
1882 rp_disc_optim(tp, t, rp)
1883 struct  tty     *tp;
1884 struct  termios *t;
1885 struct  rp_port *rp;
1886 {
1887         if(!(t->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR | ISTRIP | IXON))
1888                 &&(!(t->c_iflag & BRKINT) || (t->c_iflag & IGNBRK))
1889                 &&(!(t->c_iflag & PARMRK)
1890                   ||(t->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK))
1891                 && !(t->c_lflag & (ECHO | ICANON | IEXTEN | ISIG | PENDIN))
1892                 && linesw[tp->t_line].l_rint == ttyinput)
1893                 tp->t_state |= TS_CAN_BYPASS_L_RINT;
1894         else
1895                 tp->t_state &= ~TS_CAN_BYPASS_L_RINT;
1896 }
1897
1898 static void
1899 rpstart(tp)
1900         struct tty *tp;
1901 {
1902         struct rp_port  *rp;
1903         CHANNEL_t       *cp;
1904         struct  clist   *qp;
1905         int     unit, mynor, port, umynor;               /* SG */
1906         char    ch, flags;
1907         int     spl, xmit_fifo_room;
1908         int     count;
1909
1910
1911    umynor = (((minor(tp->t_dev) >> 16) -1) * 32);    /* SG */
1912         port  = (minor(tp->t_dev) & 0x1f);                /* SG */
1913         mynor = (port + umynor);                          /* SG */
1914         unit = minor_to_unit[mynor];
1915         rp = rp_addr(unit) + port;
1916         cp = &rp->rp_channel;
1917         flags = rp->rp_channel.TxControl[3];
1918         spl = spltty();
1919
1920         if(tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
1921                 ttwwakeup(tp);
1922                 splx(spl);
1923                 return;
1924         }
1925         if(rp->rp_xmit_stopped) {
1926                 sEnTransmit(cp);
1927                 rp->rp_xmit_stopped = 0;
1928         }
1929         count = sGetTxCnt(cp);
1930
1931         if(tp->t_outq.c_cc == 0) {
1932                 if((tp->t_state & TS_BUSY) && (count == 0)) {
1933                         tp->t_state &= ~TS_BUSY;
1934                 }
1935                 ttwwakeup(tp);
1936                 splx(spl);
1937                 return;
1938         }
1939         xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
1940         qp = &tp->t_outq;
1941         count = 0;
1942         if(xmit_fifo_room > 0 && qp->c_cc > 0) {
1943                 tp->t_state |= TS_BUSY;
1944         }
1945         while(xmit_fifo_room > 0 && qp->c_cc > 0) {
1946                 ch = getc(qp);
1947                 sOutB(sGetTxRxDataIO(cp), ch);
1948                 xmit_fifo_room--;
1949                 count++;
1950         }
1951         rp->rp_restart = (qp->c_cc > 0) ? rp->rp_fifo_lw : 0;
1952
1953         ttwwakeup(tp);
1954         splx(spl);
1955 }
1956
1957 static
1958 void
1959 rpstop(tp, flag)
1960         register struct tty *tp;
1961         int     flag;
1962 {
1963         struct rp_port  *rp;
1964         CHANNEL_t       *cp;
1965         int     unit, mynor, port, umynor;                  /* SG */
1966         int     spl;
1967
1968    umynor = (((minor(tp->t_dev) >> 16) -1) * 32);    /* SG */
1969         port  = (minor(tp->t_dev) & 0x1f);                /* SG */
1970         mynor = (port + umynor);                          /* SG */
1971         unit = minor_to_unit[mynor];
1972         rp = rp_addr(unit) + port;
1973         cp = &rp->rp_channel;
1974
1975         spl = spltty();
1976
1977         if(tp->t_state & TS_BUSY) {
1978                 if((tp->t_state&TS_TTSTOP) == 0) {
1979                         sFlushTxFIFO(cp);
1980                 } else {
1981                         if(rp->rp_xmit_stopped == 0) {
1982                                 sDisTransmit(cp);
1983                                 rp->rp_xmit_stopped = 1;
1984                         }
1985                 }
1986         }
1987         splx(spl);
1988         rpstart(tp);
1989 }