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