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