]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/i386/isa/rp.c
This commit was generated by cvs2svn to compensate for changes in r53024,
[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/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,
815         /* bmaj */      -1
816 };
817
818 static int rp_controller_port = 0;
819 static int rp_num_ports_open = 0;
820 static int      ndevs = 0;
821 static int      minor_to_unit[128];
822 #if 0
823 static  struct  tty     rp_tty[128];
824 #endif
825
826 static int rp_num_ports[4];     /* Number of ports on each controller */
827
828 #define _INLINE_ __inline
829 #define POLL_INTERVAL 1
830
831 #define CALLOUT_MASK            0x80
832 #define CONTROL_MASK            0x60
833 #define CONTROL_INIT_STATE      0x20
834 #define CONTROL_LOCK_STATE      0x40
835 #define DEV_UNIT(dev)   (MINOR_TO_UNIT(minor(dev))
836 #define MINOR_MAGIC_MASK        (CALLOUT_MASK | CONTROL_MASK)
837 #define MINOR_MAGIC(dev)        ((minor(dev)) & ~MINOR_MAGIC_MASK)
838 #define IS_CALLOUT(dev)         (minor(dev) & CALLOUT_MASK)
839 #define IS_CONTROL(dev)         (minor(dev) & CONTROL_MASK)
840
841 #define RP_ISMULTIPORT(dev)     ((dev)->id_flags & 0x1)
842 #define RP_MPMASTER(dev)        (((dev)->id_flags >> 8) & 0xff)
843 #define RP_NOTAST4(dev)         ((dev)->id_flags & 0x04)
844
845 static  struct  rp_port *p_rp_addr[4];
846 static  struct  rp_port *p_rp_table[MAX_RP_PORTS];
847 #define rp_addr(unit)   (p_rp_addr[unit])
848 #define rp_table(port)  (p_rp_table[port])
849
850 /*
851  * The top-level routines begin here
852  */
853
854 static  int     rpparam __P((struct tty *, struct termios *));
855 static  void    rpstart __P((struct tty *));
856 static  void    rpstop __P((struct tty *, int));
857 static  void    rphardclose     __P((struct rp_port *));
858 static  void    rp_disc_optim   __P((struct tty *tp, struct termios *t,
859                                                 struct rp_port  *rp));
860
861 static _INLINE_ void rp_do_receive(struct rp_port *rp, struct tty *tp,
862                         CHANNEL_t *cp, unsigned int ChanStatus)
863 {
864         int     spl;
865         unsigned        int     CharNStat;
866         int     ToRecv, ch;
867
868         ToRecv = sGetRxCnt(cp);
869         if(ToRecv == 0)
870                 return;
871
872 /*      If status indicates there are errored characters in the
873         FIFO, then enter status mode (a word in FIFO holds
874         characters and status)
875 */
876
877         if(ChanStatus & (RXFOVERFL | RXBREAK | RXFRAME | RXPARITY)) {
878                 if(!(ChanStatus & STATMODE)) {
879                         ChanStatus |= STATMODE;
880                         sEnRxStatusMode(cp);
881                 }
882         }
883 /*
884         if we previously entered status mode then read down the
885         FIFO one word at a time, pulling apart the character and
886         the status. Update error counters depending on status.
887 */
888         if(ChanStatus & STATMODE) {
889                 while(ToRecv) {
890                         if(tp->t_state & TS_TBLOCK) {
891                                 break;
892                         }
893                         CharNStat = sInW(sGetTxRxDataIO(cp));
894                         ch = CharNStat & 0xff;
895
896                         if((CharNStat & STMBREAK) || (CharNStat & STMFRAMEH))
897                                 ch |= TTY_FE;
898                         else if (CharNStat & STMPARITYH)
899                                 ch |= TTY_PE;
900                         else if (CharNStat & STMRCVROVRH)
901                                 rp->rp_overflows++;
902
903                         (*linesw[tp->t_line].l_rint)(ch, tp);
904                         ToRecv--;
905                 }
906 /*
907         After emtying FIFO in status mode, turn off status mode
908 */
909
910         if(sGetRxCnt(cp) == 0)
911                 sDisRxStatusMode(cp);
912         }
913         else {
914                 while (ToRecv) {
915                         if(tp->t_state & TS_TBLOCK) {
916                                 break;
917                         }
918                         ch = (u_char) sInB(sGetTxRxDataIO(cp));
919                         spl = spltty();
920                         (*linesw[tp->t_line].l_rint)(ch, tp);
921                         splx(spl);
922                         ToRecv--;
923                 }
924         }
925 }
926
927 static _INLINE_ void rp_handle_port(struct rp_port *rp)
928 {
929         CHANNEL_t       *cp;
930         struct  tty     *tp;
931         unsigned        int     IntMask, ChanStatus;
932      /* int     oldcts; */
933
934         if(!rp)
935                 return;
936
937         cp = &rp->rp_channel;
938         tp = rp->rp_tty;
939         IntMask = sGetChanIntID(cp);
940         IntMask = IntMask & rp->rp_intmask;
941         ChanStatus = sGetChanStatus(cp);
942         if(IntMask & RXF_TRIG)
943                 if(!(tp->t_state & TS_TBLOCK) && (tp->t_state & TS_CARR_ON) && (tp->t_state & TS_ISOPEN)) {
944                         rp_do_receive(rp, tp, cp, ChanStatus);
945                 }
946         if(IntMask & DELTA_CD) {
947                 if(ChanStatus & CD_ACT) {
948                         if(!(tp->t_state & TS_CARR_ON) ) {
949                                 (void)(*linesw[tp->t_line].l_modem)(tp, 1);
950                         }
951                 } else {
952                         if((tp->t_state & TS_CARR_ON)) {
953                                 (void)(*linesw[tp->t_line].l_modem)(tp, 0);
954                                 if((*linesw[tp->t_line].l_modem)(tp, 0) == 0) {
955                                         rphardclose(rp);
956                                 }
957                         }
958                 }
959         }
960 /*      oldcts = rp->rp_cts;
961         rp->rp_cts = ((ChanStatus & CTS_ACT) != 0);
962         if(oldcts != rp->rp_cts) {
963                 printf("CTS change (now %s)... on port %d\n", rp->rp_cts ? "on" : "off", rp->rp_port);
964         }
965 */
966 }
967
968 static void rp_do_poll(void *not_used)
969 {
970         CONTROLLER_t    *ctl;
971         struct rp_port  *rp;
972         struct tty      *tp;
973         int     unit, aiop, ch, line, count;
974         unsigned char   CtlMask, AiopMask;
975
976         for(unit = 0; unit <= ndevs; unit++) {
977         rp = rp_addr(unit);
978         ctl = rp->rp_ctlp;
979         if(ctl->BusType == isPCI)
980                 CtlMask = sPCIGetControllerIntStatus(ctl);
981         else
982                 CtlMask = sGetControllerIntStatus(ctl);
983         for(aiop=0; CtlMask; CtlMask >>=1, aiop++) {
984                 if(CtlMask & 1) {
985                         AiopMask = sGetAiopIntStatus(ctl, aiop);
986                         for(ch = 0; AiopMask; AiopMask >>=1, ch++) {
987                                 if(AiopMask & 1) {
988                                         line = (unit << 5) | (aiop << 3) | ch;
989                                         rp = rp_table(line);
990                                         rp_handle_port(rp);
991                                 }
992                         }
993                 }
994         }
995
996         for(line = 0, rp = rp_addr(unit); line < rp_num_ports[unit];
997                         line++, rp++) {
998                 tp = rp->rp_tty;
999                 if((tp->t_state & TS_BUSY) && (tp->t_state & TS_ISOPEN)) {
1000                         count = sGetTxCnt(&rp->rp_channel);
1001                         if(count == 0)
1002                                 tp->t_state &= ~(TS_BUSY);
1003                         if(!(tp->t_state & TS_TTSTOP) &&
1004                                 (count <= rp->rp_restart)) {
1005                                 (*linesw[tp->t_line].l_start)(tp);
1006                         }
1007                 }
1008         }
1009         }
1010         if(rp_num_ports_open)
1011                 timeout(rp_do_poll, (void *)NULL, POLL_INTERVAL);
1012 }
1013
1014 static const char*
1015 rp_pciprobe(pcici_t tag, pcidi_t type)
1016 {
1017         int     vendor_id;
1018
1019         vendor_id = type & 0xffff;
1020         switch(vendor_id)
1021         case 0x11fe:
1022                 return("rp");
1023         return(NULL);
1024 }
1025
1026 static
1027 int
1028 rpprobe(dev)
1029 struct isa_device *dev;
1030 {
1031         int controller, unit;
1032         int aiop, num_aiops;
1033         unsigned int aiopio[MAX_AIOPS_PER_BOARD];
1034         CONTROLLER_t *ctlp;
1035
1036         unit = dev->id_unit;
1037         if (dev->id_unit >= 4) {
1038                 printf("rpprobe: unit number %d invalid.\n", dev->id_unit);
1039                 return 1;
1040         }
1041         printf("probing for RocketPort(ISA) unit %d\n", unit);
1042         if (rp_controller_port)
1043                 controller = rp_controller_port;
1044         else {
1045                 controller = dev->id_iobase + 0x40;
1046         }
1047
1048         for (aiop=0; aiop<MAX_AIOPS_PER_BOARD; aiop++)
1049                 aiopio[aiop]= dev->id_iobase + (aiop * 0x400);
1050
1051         ctlp = sCtlNumToCtlPtr(dev->id_unit);
1052         num_aiops = sInitController(ctlp, dev->id_unit,
1053                                 controller + ((unit-rp_pcicount)*0x400),
1054                                 aiopio, MAX_AIOPS_PER_BOARD, 0,
1055                                 FREQ_DIS, 0);
1056         if (num_aiops <= 0) {
1057                 printf("board%d init failed\n", unit);
1058                 return 0;
1059         }
1060
1061         if (rp_controller_port) {
1062                 dev->id_msize = 64;
1063         } else {
1064                 dev->id_msize = 68;
1065                 rp_controller_port = controller;
1066         }
1067
1068         dev->id_irq = 0;
1069
1070         return 1;
1071 }
1072
1073 static void
1074 rp_pciattach(pcici_t tag, int unit)
1075 {
1076         int     success, oldspl;
1077         u_short iobase;
1078         int     num_ports, num_chan, num_aiops;
1079         int     aiop, chan, port;
1080         int     ChanStatus, line, i, count;
1081         unsigned int    aiopio[MAX_AIOPS_PER_BOARD];
1082         struct  rp_port *rp;
1083         struct  tty     *tty;
1084         CONTROLLER_t    *ctlp;
1085
1086         success = pci_map_port(tag, 0x10, &iobase);
1087         if(!success)
1088                 printf("ioaddr mapping failed for RocketPort(PCI)\n");
1089
1090         for(aiop=0; aiop < MAX_AIOPS_PER_BOARD; aiop++)
1091                 aiopio[aiop] = iobase + (aiop * 0x40);
1092
1093         ctlp = sCtlNumToCtlPtr(unit);
1094         num_aiops = sPCIInitController(ctlp, unit,
1095                                 aiopio, MAX_AIOPS_PER_BOARD, 0,
1096                                 FREQ_DIS, 0);
1097
1098         num_ports = 0;
1099         for(aiop=0; aiop < num_aiops; aiop++) {
1100                 sResetAiopByNum(ctlp, aiop);
1101                 num_ports += sGetAiopNumChan(ctlp, aiop);
1102         }
1103         printf("RocketPort%d = %d ports\n", unit, num_ports);
1104         rp_num_ports[unit] = num_ports;
1105
1106         rp = (struct rp_port *)
1107                 malloc(sizeof(struct rp_port) * num_ports, M_TTYS, M_NOWAIT);
1108         if(rp == 0) {
1109                 printf("rp_attach: Could not malloc rp_ports structures\n");
1110                 return;
1111         }
1112
1113         count = unit * 32;      /* board times max ports per card SG */
1114         for(i=count;i < (count + rp_num_ports[unit]);i++)
1115                 minor_to_unit[i] = unit;
1116
1117         bzero(rp, sizeof(struct rp_port) * num_ports);
1118         tty = (struct tty *)
1119                 malloc(sizeof(struct tty) * num_ports, M_TTYS, M_NOWAIT);
1120         if(tty == 0) {
1121                 printf("rp_attach: Could not malloc tty structures\n");
1122                 return;
1123         }
1124         bzero(tty, sizeof(struct tty) * num_ports);
1125
1126         oldspl = spltty();
1127         rp_addr(unit) = rp;
1128         splx(oldspl);
1129
1130         cdevsw_add(&rp_cdevsw);
1131
1132         port = 0;
1133         for(aiop=0; aiop < num_aiops; aiop++) {
1134                 num_chan = sGetAiopNumChan(ctlp, aiop);
1135                 for(chan=0; chan < num_chan; chan++, port++, rp++, tty++) {
1136                         rp->rp_tty = tty;
1137                         rp->rp_port = port;
1138                         rp->rp_ctlp = ctlp;
1139                         rp->rp_unit = unit;
1140                         rp->rp_chan = chan;
1141                         rp->rp_aiop = aiop;
1142
1143                         tty->t_line = 0;
1144         /*              tty->t_termios = deftermios;
1145         */
1146                         rp->dtr_wait = 3 * hz;
1147                         rp->it_in.c_iflag = 0;
1148                         rp->it_in.c_oflag = 0;
1149                         rp->it_in.c_cflag = TTYDEF_CFLAG;
1150                         rp->it_in.c_lflag = 0;
1151                         termioschars(&rp->it_in);
1152         /*              termioschars(&tty->t_termios);
1153         */
1154                         rp->it_in.c_ispeed = rp->it_in.c_ospeed = TTYDEF_SPEED;
1155                         rp->it_out = rp->it_in;
1156
1157                         rp->rp_intmask = RXF_TRIG | TXFIFO_MT | SRC_INT |
1158                                 DELTA_CD | DELTA_CTS | DELTA_DSR;
1159                         ChanStatus = sGetChanStatus(&rp->rp_channel);
1160                         if(sInitChan(ctlp, &rp->rp_channel, aiop, chan) == 0) {
1161                                 printf("RocketPort sInitChan(%d, %d, %d) failed
1162                                         \n", unit, aiop, chan);
1163                                 return;
1164                         }
1165                         ChanStatus = sGetChanStatus(&rp->rp_channel);
1166                         rp->rp_cts = (ChanStatus & CTS_ACT) != 0;
1167                         line = (unit << 5) | (aiop << 3) | chan;
1168                         rp_table(line) = rp;
1169                 }
1170         }
1171 }
1172
1173 static
1174 int
1175 rpattach(dev)
1176 struct  isa_device      *dev;
1177 {
1178         int     iobase, unit, /*rpmajor,*/ oldspl;
1179         int     num_ports, num_chan, num_aiops;
1180         int     aiop, chan, port;
1181         int     ChanStatus, line, i, count;
1182         unsigned int    aiopio[MAX_AIOPS_PER_BOARD];
1183         struct  rp_port *rp;
1184         struct  tty     *tty;
1185         CONTROLLER_t    *ctlp;
1186
1187         iobase = dev->id_iobase;
1188         unit = dev->id_unit;
1189         ndevs = unit;
1190
1191         for(aiop=0; aiop < MAX_AIOPS_PER_BOARD; aiop++)
1192                 aiopio[aiop] = iobase + (aiop * 0x400);
1193
1194         ctlp = sCtlNumToCtlPtr(unit);
1195         num_aiops = sInitController(ctlp, unit,
1196                                 rp_controller_port + ((unit-rp_pcicount) * 0x400),
1197                                 aiopio, MAX_AIOPS_PER_BOARD, 0,
1198                                 FREQ_DIS, 0);
1199
1200         num_ports = 0;
1201         for(aiop=0; aiop < num_aiops; aiop++) {
1202                 sResetAiopByNum(ctlp, aiop);
1203                 sEnAiop(ctlp, aiop);
1204                 num_ports += sGetAiopNumChan(ctlp, aiop);
1205         }
1206         printf("RocketPort%d = %d ports\n", unit, num_ports);
1207         rp_num_ports[unit] = num_ports;
1208
1209         rp = (struct rp_port *)
1210                 malloc(sizeof(struct rp_port) * num_ports, M_TTYS, M_NOWAIT);
1211         if(rp == 0) {
1212                 printf("rp_attach: Could not malloc rp_ports structures\n");
1213                 return(0);
1214         }
1215
1216         count = unit * 32;    /* board # times max ports per card  SG */
1217         for(i=count;i < (count + rp_num_ports[unit]);i++)
1218                 minor_to_unit[i] = unit;
1219
1220         bzero(rp, sizeof(struct rp_port) * num_ports);
1221         tty = (struct tty *)
1222                 malloc(sizeof(struct tty) * num_ports, M_TTYS, M_NOWAIT);
1223         if(tty == 0) {
1224                 printf("rp_attach: Could not malloc tty structures\n");
1225                 return(0);
1226         }
1227         bzero(tty, sizeof(struct tty) * num_ports);
1228
1229         oldspl = spltty();
1230         rp_addr(unit) = rp;
1231         splx(oldspl);
1232
1233         cdevsw_add(&rp_cdevsw);
1234
1235         port = 0;
1236         for(aiop=0; aiop < num_aiops; aiop++) {
1237                 num_chan = sGetAiopNumChan(ctlp, aiop);
1238                 for(chan=0; chan < num_chan; chan++, port++, rp++, tty++) {
1239                         rp->rp_tty = tty;
1240                         rp->rp_port = port;
1241                         rp->rp_ctlp = ctlp;
1242                         rp->rp_unit = unit;
1243                         rp->rp_chan = chan;
1244                         rp->rp_aiop = aiop;
1245
1246                         tty->t_line = 0;
1247         /*              tty->t_termios = deftermios;
1248         */
1249                         rp->dtr_wait = 3 * hz;
1250                         rp->it_in.c_iflag = 0;
1251                         rp->it_in.c_oflag = 0;
1252                         rp->it_in.c_cflag = TTYDEF_CFLAG;
1253                         rp->it_in.c_lflag = 0;
1254                         termioschars(&rp->it_in);
1255         /*              termioschars(&tty->t_termios);
1256         */
1257                         rp->it_in.c_ispeed = rp->it_in.c_ospeed = TTYDEF_SPEED;
1258                         rp->it_out = rp->it_in;
1259
1260                         rp->rp_intmask = RXF_TRIG | TXFIFO_MT | SRC_INT |
1261                                 DELTA_CD | DELTA_CTS | DELTA_DSR;
1262                         ChanStatus = sGetChanStatus(&rp->rp_channel);
1263                         if(sInitChan(ctlp, &rp->rp_channel, aiop, chan) == 0) {
1264                                 printf("RocketPort sInitChan(%d, %d, %d) failed
1265                                         \n", unit, aiop, chan);
1266                                 return(0);
1267                         }
1268                         ChanStatus = sGetChanStatus(&rp->rp_channel);
1269                         rp->rp_cts = (ChanStatus & CTS_ACT) != 0;
1270                         line = (unit << 5) | (aiop << 3) | chan;
1271                         rp_table(line) = rp;
1272                 }
1273         }
1274
1275         return(1);
1276 }
1277
1278 int
1279 rpopen(dev, flag, mode, p)
1280         dev_t   dev;
1281         int     flag, mode;
1282         struct  proc    *p;
1283 {
1284         struct  rp_port *rp;
1285         int     unit, port, mynor, umynor, flags;  /* SG */
1286         struct  tty     *tp;
1287         int     oldspl, error;
1288         unsigned int    IntMask, ChanStatus;
1289
1290
1291    umynor = (((minor(dev) >> 16) -1) * 32);    /* SG */
1292         port  = (minor(dev) & 0x1f);                /* SG */
1293         mynor = (port + umynor);                    /* SG */
1294         unit = minor_to_unit[mynor];
1295         if(IS_CONTROL(dev))
1296                 return(0);
1297         rp = rp_addr(unit) + port;
1298 /*      rp->rp_tty = &rp_tty[rp->rp_port];
1299 */
1300         tp = rp->rp_tty;
1301         dev->si_tty = tp;
1302
1303         oldspl = spltty();
1304
1305 open_top:
1306         while(rp->state & ~SET_DTR) {
1307                 error = tsleep(&rp->dtr_wait, TTIPRI | PCATCH, "rpdtr", 0);
1308                 if(error != 0)
1309                         goto out;
1310         }
1311
1312         if(tp->t_state & TS_ISOPEN) {
1313                 if(IS_CALLOUT(dev)) {
1314                         if(!rp->active_out) {
1315                                 error = EBUSY;
1316                                 goto out;
1317                         }
1318                 } else {
1319                         if(rp->active_out) {
1320                                 if(flag & O_NONBLOCK) {
1321                                         error = EBUSY;
1322                                         goto out;
1323                                 }
1324                                 error = tsleep(&rp->active_out,
1325                                         TTIPRI | PCATCH, "rpbi", 0);
1326                                 if(error != 0)
1327                                         goto out;
1328                                 goto open_top;
1329                         }
1330                 }
1331                 if(tp->t_state & TS_XCLUDE &&
1332                     suser(p)) {
1333                         splx(oldspl);
1334                         return(EBUSY);
1335                 }
1336         }
1337         else {
1338                 tp->t_dev = dev;
1339                 tp->t_param = rpparam;
1340                 tp->t_oproc = rpstart;
1341                 tp->t_stop = rpstop;
1342                 tp->t_line = 0;
1343                 tp->t_termios = IS_CALLOUT(dev) ? rp->it_out : rp->it_in;
1344                 flags = 0;
1345                 flags |= SET_RTS;
1346                 flags |= SET_DTR;
1347                 rp->rp_channel.TxControl[3] =
1348                         ((rp->rp_channel.TxControl[3]
1349                         & ~(SET_RTS | SET_DTR)) | flags);
1350                 sOutDW(rp->rp_channel.IndexAddr,
1351                         *(DWord_t *) &(rp->rp_channel.TxControl[0]));
1352                 sSetRxTrigger(&rp->rp_channel, TRIG_1);
1353                 sDisRxStatusMode(&rp->rp_channel);
1354                 sFlushRxFIFO(&rp->rp_channel);
1355                 sFlushTxFIFO(&rp->rp_channel);
1356
1357                 sEnInterrupts(&rp->rp_channel,
1358                         (TXINT_EN|MCINT_EN|RXINT_EN|SRCINT_EN|CHANINT_EN));
1359                 sSetRxTrigger(&rp->rp_channel, TRIG_1);
1360
1361                 sDisRxStatusMode(&rp->rp_channel);
1362                 sClrTxXOFF(&rp->rp_channel);
1363
1364 /*              sDisRTSFlowCtl(&rp->rp_channel);
1365                 sDisCTSFlowCtl(&rp->rp_channel);
1366 */
1367                 sDisTxSoftFlowCtl(&rp->rp_channel);
1368
1369                 sStartRxProcessor(&rp->rp_channel);
1370
1371                 sEnRxFIFO(&rp->rp_channel);
1372                 sEnTransmit(&rp->rp_channel);
1373
1374 /*              sSetDTR(&rp->rp_channel);
1375                 sSetRTS(&rp->rp_channel);
1376 */
1377
1378                 ++rp->wopeners;
1379                 error = rpparam(tp, &tp->t_termios);
1380                 --rp->wopeners;
1381                 if(error != 0) {
1382                         splx(oldspl);
1383                         return(error);
1384                 }
1385
1386                 rp_num_ports_open++;
1387
1388                 IntMask = sGetChanIntID(&rp->rp_channel);
1389                 IntMask = IntMask & rp->rp_intmask;
1390                 ChanStatus = sGetChanStatus(&rp->rp_channel);
1391                 if((IntMask & DELTA_CD) || IS_CALLOUT(dev)) {
1392                         if((ChanStatus & CD_ACT) || IS_CALLOUT(dev)) {
1393                                         (void)(*linesw[tp->t_line].l_modem)(tp, 1);
1394                         }
1395                 }
1396
1397         if(rp_num_ports_open == 1)
1398                 timeout(rp_do_poll, (void *)NULL, POLL_INTERVAL);
1399
1400         }
1401
1402         if(!(flag&O_NONBLOCK) && !(tp->t_cflag&CLOCAL) &&
1403                 !(tp->t_state & TS_CARR_ON) && !(IS_CALLOUT(dev))) {
1404                 ++rp->wopeners;
1405                 error = tsleep(TSA_CARR_ON(tp), TTIPRI | PCATCH,
1406                                 "rpdcd", 0);
1407                 --rp->wopeners;
1408                 if(error != 0)
1409                         goto out;
1410                 goto open_top;
1411         }
1412         error = (*linesw[tp->t_line].l_open)(dev, tp);
1413
1414         rp_disc_optim(tp, &tp->t_termios, rp);
1415         if(tp->t_state & TS_ISOPEN && IS_CALLOUT(dev))
1416                 rp->active_out = TRUE;
1417
1418 /*      if(rp_num_ports_open == 1)
1419                 timeout(rp_do_poll, (void *)NULL, POLL_INTERVAL);
1420 */
1421 out:
1422         splx(oldspl);
1423         if(!(tp->t_state & TS_ISOPEN) && rp->wopeners == 0) {
1424                 rphardclose(rp);
1425         }
1426         return(error);
1427 }
1428
1429 int
1430 rpclose(dev, flag, mode, p)
1431         dev_t   dev;
1432         int     flag, mode;
1433         struct  proc    *p;
1434 {
1435         int     oldspl, unit, mynor, umynor, port; /* SG */
1436         struct  rp_port *rp;
1437         struct  tty     *tp;
1438         CHANNEL_t       *cp;
1439
1440    umynor = (((minor(dev) >> 16) -1) * 32);    /* SG */
1441         port  = (minor(dev) & 0x1f);                /* SG */
1442         mynor = (port + umynor);                    /* SG */
1443    unit = minor_to_unit[mynor];                /* SG */
1444
1445         if(IS_CONTROL(dev))
1446                 return(0);
1447         rp = rp_addr(unit) + port;
1448         cp = &rp->rp_channel;
1449         tp = rp->rp_tty;
1450
1451         oldspl = spltty();
1452         (*linesw[tp->t_line].l_close)(tp, flag);
1453         rp_disc_optim(tp, &tp->t_termios, rp);
1454         rpstop(tp, FREAD | FWRITE);
1455         rphardclose(rp);
1456
1457         tp->t_state &= ~TS_BUSY;
1458         ttyclose(tp);
1459
1460         splx(oldspl);
1461
1462         return(0);
1463 }
1464
1465 static void
1466 rphardclose(struct rp_port *rp)
1467 {
1468         int     mynor;
1469         struct  tty     *tp;
1470         CHANNEL_t       *cp;
1471
1472         cp = &rp->rp_channel;
1473         tp = rp->rp_tty;
1474         mynor = MINOR_MAGIC(tp->t_dev);
1475
1476         sFlushRxFIFO(cp);
1477         sFlushTxFIFO(cp);
1478         sDisTransmit(cp);
1479         sDisInterrupts(cp, TXINT_EN|MCINT_EN|RXINT_EN|SRCINT_EN|CHANINT_EN);
1480         sDisRTSFlowCtl(cp);
1481         sDisCTSFlowCtl(cp);
1482         sDisTxSoftFlowCtl(cp);
1483         sClrTxXOFF(cp);
1484
1485         if(tp->t_cflag&HUPCL || !(tp->t_state&TS_ISOPEN) || !rp->active_out) {
1486                 sClrDTR(cp);
1487         }
1488         if(IS_CALLOUT(tp->t_dev)) {
1489                 sClrDTR(cp);
1490         }
1491         if(rp->dtr_wait != 0) {
1492                 timeout(rpdtrwakeup, rp, rp->dtr_wait);
1493                 rp->state |= ~SET_DTR;
1494         }
1495
1496         rp->active_out = FALSE;
1497         wakeup(&rp->active_out);
1498         wakeup(TSA_CARR_ON(tp));
1499 }
1500
1501 static
1502 int
1503 rpwrite(dev, uio, flag)
1504         dev_t   dev;
1505         struct  uio     *uio;
1506         int     flag;
1507 {
1508         struct  rp_port *rp;
1509         struct  tty     *tp;
1510         int     unit, mynor, port, umynor, error = 0; /* SG */
1511
1512    umynor = (((minor(dev) >> 16) -1) * 32);    /* SG */
1513         port  = (minor(dev) & 0x1f);                /* SG */
1514         mynor = (port + umynor);                    /* SG */
1515    unit = minor_to_unit[mynor];                /* SG */
1516
1517         if(IS_CONTROL(dev))
1518                 return(ENODEV);
1519         rp = rp_addr(unit) + port;
1520         tp = rp->rp_tty;
1521         while(rp->rp_disable_writes) {
1522                 rp->rp_waiting = 1;
1523                 error = ttysleep(tp, (caddr_t)rp, TTOPRI|PCATCH, "rp_write", 0);
1524                 if (error)
1525                         return(error);
1526         }
1527
1528         error = (*linesw[tp->t_line].l_write)(tp, uio, flag);
1529         return error;
1530 }
1531
1532 static void
1533 rpdtrwakeup(void *chan)
1534 {
1535         struct  rp_port *rp;
1536
1537         rp = (struct rp_port *)chan;
1538         rp->state &= SET_DTR;
1539         wakeup(&rp->dtr_wait);
1540 }
1541
1542 int
1543 rpioctl(dev, cmd, data, flag, p)
1544         dev_t   dev;
1545         u_long  cmd;
1546         caddr_t data;
1547         int     flag;
1548         struct  proc    *p;
1549 {
1550         struct rp_port  *rp;
1551         CHANNEL_t       *cp;
1552         struct tty      *tp;
1553         int     unit, mynor, port, umynor;            /* SG */
1554         int     oldspl;
1555         int     error = 0;
1556         int     arg, flags, result, ChanStatus;
1557         int     oldcmd;
1558         struct  termios term, *t;
1559
1560    umynor = (((minor(dev) >> 16) -1) * 32);    /* SG */
1561         port  = (minor(dev) & 0x1f);                /* SG */
1562         mynor = (port + umynor);                    /* SG */
1563         unit = minor_to_unit[mynor];
1564         rp = rp_addr(unit) + port;
1565
1566         if(IS_CONTROL(dev)) {
1567                 struct  termios *ct;
1568
1569                 switch (IS_CONTROL(dev)) {
1570                 case CONTROL_INIT_STATE:
1571                         ct =  IS_CALLOUT(dev) ? &rp->it_out : &rp->it_in;
1572                         break;
1573                 case CONTROL_LOCK_STATE:
1574                         ct =  IS_CALLOUT(dev) ? &rp->lt_out : &rp->lt_in;
1575                         break;
1576                 default:
1577                         return(ENODEV);         /* /dev/nodev */
1578                 }
1579                 switch (cmd) {
1580                 case TIOCSETA:
1581                         error = suser(p);
1582                         if(error != 0)
1583                                 return(error);
1584                         *ct = *(struct termios *)data;
1585                         return(0);
1586                 case TIOCGETA:
1587                         *(struct termios *)data = *ct;
1588                         return(0);
1589                 case TIOCGETD:
1590                         *(int *)data = TTYDISC;
1591                         return(0);
1592                 case TIOCGWINSZ:
1593                         bzero(data, sizeof(struct winsize));
1594                         return(0);
1595                 default:
1596                         return(ENOTTY);
1597                 }
1598         }
1599
1600         tp = rp->rp_tty;
1601         cp = &rp->rp_channel;
1602
1603 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1604         term = tp->t_termios;
1605         oldcmd = cmd;
1606         error = ttsetcompat(tp, &cmd, data, &term);
1607         if(error != 0)
1608                 return(error);
1609         if(cmd != oldcmd) {
1610                 data = (caddr_t)&term;
1611         }
1612 #endif
1613         if((cmd == TIOCSETA) || (cmd == TIOCSETAW) || (cmd == TIOCSETAF)) {
1614                 int     cc;
1615                 struct  termios *dt = (struct termios *)data;
1616                 struct  termios *lt = IS_CALLOUT(dev)
1617                                         ? &rp->lt_out : &rp->lt_in;
1618
1619                 dt->c_iflag = (tp->t_iflag & lt->c_iflag)
1620                                 | (dt->c_iflag & ~lt->c_iflag);
1621                 dt->c_oflag = (tp->t_oflag & lt->c_oflag)
1622                                 | (dt->c_oflag & ~lt->c_oflag);
1623                 dt->c_cflag = (tp->t_cflag & lt->c_cflag)
1624                                 | (dt->c_cflag & ~lt->c_cflag);
1625                 dt->c_lflag = (tp->t_lflag & lt->c_lflag)
1626                                 | (dt->c_lflag & ~lt->c_lflag);
1627                 for(cc = 0; cc < NCCS; ++cc)
1628                         if((lt->c_cc[cc] = tp->t_cc[cc]) != 0)
1629                                 dt->c_cc[cc] = tp->t_cc[cc];
1630                 if(lt->c_ispeed != 0)
1631                         dt->c_ispeed = tp->t_ispeed;
1632                 if(lt->c_ospeed != 0)
1633                         dt->c_ospeed = tp->t_ospeed;
1634         }
1635
1636         t = &tp->t_termios;
1637
1638         error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
1639         if(error != ENOIOCTL) {
1640                 return(error);
1641         }
1642         oldspl = spltty();
1643
1644         flags = rp->rp_channel.TxControl[3];
1645
1646         error = ttioctl(tp, cmd, data, flag);
1647         flags = rp->rp_channel.TxControl[3];
1648         rp_disc_optim(tp, &tp->t_termios, rp);
1649         if(error != ENOIOCTL) {
1650                 splx(oldspl);
1651                 return(error);
1652         }
1653         switch(cmd) {
1654         case TIOCSBRK:
1655                 sSendBreak(&rp->rp_channel);
1656                 break;
1657
1658         case TIOCCBRK:
1659                 sClrBreak(&rp->rp_channel);
1660                 break;
1661
1662         case TIOCSDTR:
1663                 sSetDTR(&rp->rp_channel);
1664                 sSetRTS(&rp->rp_channel);
1665                 break;
1666
1667         case TIOCCDTR:
1668                 sClrDTR(&rp->rp_channel);
1669                 break;
1670
1671         case TIOCMSET:
1672                 arg = *(int *) data;
1673                 flags = 0;
1674                 if(arg & TIOCM_RTS)
1675                         flags |= SET_RTS;
1676                 if(arg & TIOCM_DTR)
1677                         flags |= SET_DTR;
1678                 rp->rp_channel.TxControl[3] =
1679                         ((rp->rp_channel.TxControl[3]
1680                         & ~(SET_RTS | SET_DTR)) | flags);
1681                 sOutDW(rp->rp_channel.IndexAddr,
1682                         *(DWord_t *) &(rp->rp_channel.TxControl[0]));
1683                 break;
1684         case TIOCMBIS:
1685                 arg = *(int *) data;
1686                 flags = 0;
1687                 if(arg & TIOCM_RTS)
1688                         flags |= SET_RTS;
1689                 if(arg & TIOCM_DTR)
1690                         flags |= SET_DTR;
1691                         rp->rp_channel.TxControl[3] |= flags;
1692                 sOutDW(rp->rp_channel.IndexAddr,
1693                         *(DWord_t *) &(rp->rp_channel.TxControl[0]));
1694                 break;
1695         case TIOCMBIC:
1696                 arg = *(int *) data;
1697                 flags = 0;
1698                 if(arg & TIOCM_RTS)
1699                         flags |= SET_RTS;
1700                 if(arg & TIOCM_DTR)
1701                         flags |= SET_DTR;
1702                 rp->rp_channel.TxControl[3] &= ~flags;
1703                 sOutDW(rp->rp_channel.IndexAddr,
1704                         *(DWord_t *) &(rp->rp_channel.TxControl[0]));
1705                 break;
1706
1707
1708         case TIOCMGET:
1709                 ChanStatus = sGetChanStatusLo(&rp->rp_channel);
1710                 flags = rp->rp_channel.TxControl[3];
1711                 result = TIOCM_LE; /* always on while open for some reason */
1712                 result |= (((flags & SET_DTR) ? TIOCM_DTR : 0)
1713                         | ((flags & SET_RTS) ? TIOCM_RTS : 0)
1714                         | ((ChanStatus & CD_ACT) ? TIOCM_CAR : 0)
1715                         | ((ChanStatus & DSR_ACT) ? TIOCM_DSR : 0)
1716                         | ((ChanStatus & CTS_ACT) ? TIOCM_CTS : 0));
1717
1718                 if(rp->rp_channel.RxControl[2] & RTSFC_EN)
1719                 {
1720                         result |= TIOCM_RTS;
1721                 }
1722
1723                 *(int *)data = result;
1724                 break;
1725         case TIOCMSDTRWAIT:
1726                 error = suser(p);
1727                 if(error != 0) {
1728                         splx(oldspl);
1729                         return(error);
1730                 }
1731                 rp->dtr_wait = *(int *)data * hz/100;
1732                 break;
1733         case TIOCMGDTRWAIT:
1734                 *(int *)data = rp->dtr_wait * 100/hz;
1735                 break;
1736         default:
1737                 splx(oldspl);
1738                 return ENOTTY;
1739         }
1740         splx(oldspl);
1741         return(0);
1742 }
1743
1744 static struct speedtab baud_table[] = {
1745         B0,     0,              B50,    BRD50,          B75,    BRD75,
1746         B110,   BRD110,         B134,   BRD134,         B150,   BRD150,
1747         B200,   BRD200,         B300,   BRD300,         B600,   BRD600,
1748         B1200,  BRD1200,        B1800,  BRD1800,        B2400,  BRD2400,
1749         B4800,  BRD4800,        B9600,  BRD9600,        B19200, BRD19200,
1750         B38400, BRD38400,       B7200,  BRD7200,        B14400, BRD14400,
1751                                 B57600, BRD57600,       B76800, BRD76800,
1752         B115200, BRD115200,     B230400, BRD230400,
1753         -1,     -1
1754 };
1755
1756 static int
1757 rpparam(tp, t)
1758         struct tty *tp;
1759         struct termios *t;
1760 {
1761         struct rp_port  *rp;
1762         CHANNEL_t       *cp;
1763         int     unit, mynor, port, umynor;               /* SG */
1764         int     oldspl, cflag, iflag, oflag, lflag;
1765         int     ospeed;
1766
1767
1768    umynor = (((minor(tp->t_dev) >> 16) -1) * 32);    /* SG */
1769         port  = (minor(tp->t_dev) & 0x1f);                /* SG */
1770         mynor = (port + umynor);                          /* SG */
1771
1772         unit = minor_to_unit[mynor];
1773         rp = rp_addr(unit) + port;
1774         cp = &rp->rp_channel;
1775         oldspl = spltty();
1776
1777         cflag = t->c_cflag;
1778         iflag = t->c_iflag;
1779         oflag = t->c_oflag;
1780         lflag = t->c_lflag;
1781
1782         ospeed = ttspeedtab(t->c_ispeed, baud_table);
1783         if(ospeed < 0 || t->c_ispeed != t->c_ospeed)
1784                 return(EINVAL);
1785
1786         tp->t_ispeed = t->c_ispeed;
1787         tp->t_ospeed = t->c_ospeed;
1788         tp->t_cflag = cflag;
1789         tp->t_iflag = iflag;
1790         tp->t_oflag = oflag;
1791         tp->t_lflag = lflag;
1792
1793         if(t->c_ospeed == 0) {
1794                 sClrDTR(cp);
1795                 return(0);
1796         }
1797         rp->rp_fifo_lw = ((t->c_ospeed*2) / 1000) +1;
1798
1799         /* Set baud rate ----- we only pay attention to ispeed */
1800         sSetDTR(cp);
1801         sSetRTS(cp);
1802         sSetBaud(cp, ospeed);
1803
1804         if(cflag & CSTOPB) {
1805                 sSetStop2(cp);
1806         } else {
1807                 sSetStop1(cp);
1808         }
1809
1810         if(cflag & PARENB) {
1811                 sEnParity(cp);
1812                 if(cflag & PARODD) {
1813                         sSetOddParity(cp);
1814                 } else {
1815                         sSetEvenParity(cp);
1816                 }
1817         }
1818         else {
1819                 sDisParity(cp);
1820         }
1821         if((cflag & CSIZE) == CS8) {
1822                 sSetData8(cp);
1823                 rp->rp_imask = 0xFF;
1824         } else {
1825                 sSetData7(cp);
1826                 rp->rp_imask = 0x7F;
1827         }
1828
1829         if(iflag & ISTRIP) {
1830                 rp->rp_imask &= 0x7F;
1831         }
1832
1833         if(cflag & CLOCAL) {
1834                 rp->rp_intmask &= ~DELTA_CD;
1835         } else {
1836                 rp->rp_intmask |= DELTA_CD;
1837         }
1838
1839         /* Put flow control stuff here */
1840
1841         if(cflag & CCTS_OFLOW) {
1842                 sEnCTSFlowCtl(cp);
1843         } else {
1844                 sDisCTSFlowCtl(cp);
1845         }
1846
1847         if(cflag & CRTS_IFLOW) {
1848                 rp->rp_rts_iflow = 1;
1849         } else {
1850                 rp->rp_rts_iflow = 0;
1851         }
1852
1853         if(cflag & CRTS_IFLOW) {
1854                 sEnRTSFlowCtl(cp);
1855         } else {
1856                 sDisRTSFlowCtl(cp);
1857         }
1858         rp_disc_optim(tp, t, rp);
1859
1860         if((cflag & CLOCAL) || (sGetChanStatusLo(cp) & CD_ACT)) {
1861                 tp->t_state |= TS_CARR_ON;
1862                 wakeup(TSA_CARR_ON(tp));
1863         }
1864
1865 /*      tp->t_state |= TS_CAN_BYPASS_L_RINT;
1866         flags = rp->rp_channel.TxControl[3];
1867         if(flags & SET_DTR)
1868         else
1869         if(flags & SET_RTS)
1870         else
1871 */
1872         splx(oldspl);
1873
1874         return(0);
1875 }
1876
1877 static void
1878 rp_disc_optim(tp, t, rp)
1879 struct  tty     *tp;
1880 struct  termios *t;
1881 struct  rp_port *rp;
1882 {
1883         if(!(t->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR | ISTRIP | IXON))
1884                 &&(!(t->c_iflag & BRKINT) || (t->c_iflag & IGNBRK))
1885                 &&(!(t->c_iflag & PARMRK)
1886                   ||(t->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK))
1887                 && !(t->c_lflag & (ECHO | ICANON | IEXTEN | ISIG | PENDIN))
1888                 && linesw[tp->t_line].l_rint == ttyinput)
1889                 tp->t_state |= TS_CAN_BYPASS_L_RINT;
1890         else
1891                 tp->t_state &= ~TS_CAN_BYPASS_L_RINT;
1892 }
1893
1894 static void
1895 rpstart(tp)
1896         struct tty *tp;
1897 {
1898         struct rp_port  *rp;
1899         CHANNEL_t       *cp;
1900         struct  clist   *qp;
1901         int     unit, mynor, port, umynor;               /* SG */
1902         char    ch, flags;
1903         int     spl, xmit_fifo_room;
1904         int     count;
1905
1906
1907    umynor = (((minor(tp->t_dev) >> 16) -1) * 32);    /* SG */
1908         port  = (minor(tp->t_dev) & 0x1f);                /* SG */
1909         mynor = (port + umynor);                          /* SG */
1910         unit = minor_to_unit[mynor];
1911         rp = rp_addr(unit) + port;
1912         cp = &rp->rp_channel;
1913         flags = rp->rp_channel.TxControl[3];
1914         spl = spltty();
1915
1916         if(tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
1917                 ttwwakeup(tp);
1918                 splx(spl);
1919                 return;
1920         }
1921         if(rp->rp_xmit_stopped) {
1922                 sEnTransmit(cp);
1923                 rp->rp_xmit_stopped = 0;
1924         }
1925         count = sGetTxCnt(cp);
1926
1927         if(tp->t_outq.c_cc == 0) {
1928                 if((tp->t_state & TS_BUSY) && (count == 0)) {
1929                         tp->t_state &= ~TS_BUSY;
1930                 }
1931                 ttwwakeup(tp);
1932                 splx(spl);
1933                 return;
1934         }
1935         xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
1936         qp = &tp->t_outq;
1937         count = 0;
1938         if(xmit_fifo_room > 0 && qp->c_cc > 0) {
1939                 tp->t_state |= TS_BUSY;
1940         }
1941         while(xmit_fifo_room > 0 && qp->c_cc > 0) {
1942                 ch = getc(qp);
1943                 sOutB(sGetTxRxDataIO(cp), ch);
1944                 xmit_fifo_room--;
1945                 count++;
1946         }
1947         rp->rp_restart = (qp->c_cc > 0) ? rp->rp_fifo_lw : 0;
1948
1949         ttwwakeup(tp);
1950         splx(spl);
1951 }
1952
1953 static
1954 void
1955 rpstop(tp, flag)
1956         register struct tty *tp;
1957         int     flag;
1958 {
1959         struct rp_port  *rp;
1960         CHANNEL_t       *cp;
1961         int     unit, mynor, port, umynor;                  /* SG */
1962         int     spl;
1963
1964    umynor = (((minor(tp->t_dev) >> 16) -1) * 32);    /* SG */
1965         port  = (minor(tp->t_dev) & 0x1f);                /* SG */
1966         mynor = (port + umynor);                          /* SG */
1967         unit = minor_to_unit[mynor];
1968         rp = rp_addr(unit) + port;
1969         cp = &rp->rp_channel;
1970
1971         spl = spltty();
1972
1973         if(tp->t_state & TS_BUSY) {
1974                 if((tp->t_state&TS_TTSTOP) == 0) {
1975                         sFlushTxFIFO(cp);
1976                 } else {
1977                         if(rp->rp_xmit_stopped == 0) {
1978                                 sDisTransmit(cp);
1979                                 rp->rp_xmit_stopped = 1;
1980                         }
1981                 }
1982         }
1983         splx(spl);
1984         rpstart(tp);
1985 }