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