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