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