summaryrefslogtreecommitdiffstats
path: root/sys/dev/rp
diff options
context:
space:
mode:
authortanimura <tanimura@FreeBSD.org>2000-06-11 06:43:16 +0000
committertanimura <tanimura@FreeBSD.org>2000-06-11 06:43:16 +0000
commit423e9563878f579d365a6cd05d272784bd92edc4 (patch)
treee33f7429f0e830f180f941f90eea41572dfd3a4c /sys/dev/rp
parent4fc801a85706650d7922df5965352e4517d542fd (diff)
downloadFreeBSD-src-423e9563878f579d365a6cd05d272784bd92edc4.zip
FreeBSD-src-423e9563878f579d365a6cd05d272784bd92edc4.tar.gz
1. Update Comtrol RocketPort driver(rp) to version 3.02.
2. Newbusify the driver. 3. Build as a module. 4. Use correct minor numbers when creating device files. 5. Correctly lock control characters. 6. Return ENXIO when device not configured. Submitted by: Tor Egge <Tor.Egge@fast.no> 7. Fix the baud_table. Submitted by: Elliot Dierksen <ebd@oau.org> Note: - the old driver still lives in src/sys/i386/isa, so that you can revert to it if something goes wrong. - The module does not detach very well. Attaching works fine.
Diffstat (limited to 'sys/dev/rp')
-rw-r--r--sys/dev/rp/rp.c880
-rw-r--r--sys/dev/rp/rp_isa.c506
-rw-r--r--sys/dev/rp/rp_pci.c371
-rw-r--r--sys/dev/rp/rpreg.h372
-rw-r--r--sys/dev/rp/rpvar.h14
5 files changed, 1349 insertions, 794 deletions
diff --git a/sys/dev/rp/rp.c b/sys/dev/rp/rp.c
index a858496..0590a72 100644
--- a/sys/dev/rp/rp.c
+++ b/sys/dev/rp/rp.c
@@ -36,33 +36,25 @@
* rp.c - for RocketPort FreeBSD
*/
-#include "opt_compat.h"
-
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/kernel.h>
#include <sys/fcntl.h>
#include <sys/malloc.h>
#include <sys/tty.h>
#include <sys/proc.h>
+#include <sys/dkstat.h>
#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <machine/resource.h>
+#include <machine/bus.h>
#include <sys/bus.h>
-
-#include <i386/isa/isa_device.h>
-
-#include <pci/pcivar.h>
+#include <sys/rman.h>
#define ROCKET_C
-#include <i386/isa/rpreg.h>
-#include <i386/isa/rpvar.h>
+#include <dev/rp/rpreg.h>
+#include <dev/rp/rpvar.h>
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
+static const char RocketPortVersion[] = "3.02";
static Byte_t RData[RDATASIZE] =
{
@@ -103,14 +95,6 @@ static Byte_t RRegData[RREGDATASIZE]=
0x22, 0x09, 0x0a, 0x0a /* 30: Rx FIFO Enable */
};
-static CONTROLLER_T sController[CTL_SIZE] =
-{
- {-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}},
- {-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}},
- {-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}},
- {-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}}
-};
-
#if 0
/* IRQ number to MUDBAC register 2 mapping */
Byte_t sIRQMap[16] =
@@ -119,222 +103,47 @@ Byte_t sIRQMap[16] =
};
#endif
-static Byte_t sBitMapClrTbl[8] =
+Byte_t rp_sBitMapClrTbl[8] =
{
0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f
};
-static Byte_t sBitMapSetTbl[8] =
+Byte_t rp_sBitMapSetTbl[8] =
{
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
};
-/***************************************************************************
-Function: sInitController
-Purpose: Initialization of controller global registers and controller
- structure.
-Call: sInitController(CtlP,CtlNum,MudbacIO,AiopIOList,AiopIOListSize,
- IRQNum,Frequency,PeriodicOnly)
- CONTROLLER_T *CtlP; Ptr to controller structure
- int CtlNum; Controller number
- ByteIO_t MudbacIO; Mudbac base I/O address.
- ByteIO_t *AiopIOList; List of I/O addresses for each AIOP.
- This list must be in the order the AIOPs will be found on the
- controller. Once an AIOP in the list is not found, it is
- assumed that there are no more AIOPs on the controller.
- int AiopIOListSize; Number of addresses in AiopIOList
- int IRQNum; Interrupt Request number. Can be any of the following:
- 0: Disable global interrupts
- 3: IRQ 3
- 4: IRQ 4
- 5: IRQ 5
- 9: IRQ 9
- 10: IRQ 10
- 11: IRQ 11
- 12: IRQ 12
- 15: IRQ 15
- Byte_t Frequency: A flag identifying the frequency
- of the periodic interrupt, can be any one of the following:
- FREQ_DIS - periodic interrupt disabled
- FREQ_137HZ - 137 Hertz
- FREQ_69HZ - 69 Hertz
- FREQ_34HZ - 34 Hertz
- FREQ_17HZ - 17 Hertz
- FREQ_9HZ - 9 Hertz
- FREQ_4HZ - 4 Hertz
- If IRQNum is set to 0 the Frequency parameter is
- overidden, it is forced to a value of FREQ_DIS.
- int PeriodicOnly: TRUE if all interrupts except the periodic
- interrupt are to be blocked.
- FALSE is both the periodic interrupt and
- other channel interrupts are allowed.
- If IRQNum is set to 0 the PeriodicOnly parameter is
- overidden, it is forced to a value of FALSE.
-Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller
- initialization failed.
-
-Comments:
- If periodic interrupts are to be disabled but AIOP interrupts
- are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE.
-
- If interrupts are to be completely disabled set IRQNum to 0.
-
- Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an
- invalid combination.
-
- This function performs initialization of global interrupt modes,
- but it does not actually enable global interrupts. To enable
- and disable global interrupts use functions sEnGlobalInt() and
- sDisGlobalInt(). Enabling of global interrupts is normally not
- done until all other initializations are complete.
-
- Even if interrupts are globally enabled, they must also be
- individually enabled for each channel that is to generate
- interrupts.
-
-Warnings: No range checking on any of the parameters is done.
-
- No context switches are allowed while executing this function.
-
- After this function all AIOPs on the controller are disabled,
- they can be enabled with sEnAiop().
-*/
-int sInitController( CONTROLLER_T *CtlP,
- int CtlNum,
- ByteIO_t MudbacIO,
- ByteIO_t *AiopIOList,
- int AiopIOListSize,
- int IRQNum,
- Byte_t Frequency,
- int PeriodicOnly)
-{
- int i;
- ByteIO_t io;
-
- CtlP->CtlNum = CtlNum;
- CtlP->BusType = isISA;
- CtlP->CtlID = CTLID_0001; /* controller release 1 */
-
- CtlP->MBaseIO = MudbacIO;
- CtlP->MReg1IO = MudbacIO + 1;
- CtlP->MReg2IO = MudbacIO + 2;
- CtlP->MReg3IO = MudbacIO + 3;
-#if 1
- CtlP->MReg2 = 0; /* interrupt disable */
- CtlP->MReg3 = 0; /* no periodic interrupts */
-#else
- if(sIRQMap[IRQNum] == 0) /* interrupts globally disabled */
- {
- CtlP->MReg2 = 0; /* interrupt disable */
- CtlP->MReg3 = 0; /* no periodic interrupts */
- }
- else
- {
- CtlP->MReg2 = sIRQMap[IRQNum]; /* set IRQ number */
- CtlP->MReg3 = Frequency; /* set frequency */
- if(PeriodicOnly) /* periodic interrupt only */
- {
- CtlP->MReg3 |= PERIODIC_ONLY;
- }
- }
-#endif
- sOutB(CtlP->MReg2IO,CtlP->MReg2);
- sOutB(CtlP->MReg3IO,CtlP->MReg3);
- sControllerEOI(CtlP); /* clear EOI if warm init */
-
- /* Init AIOPs */
- CtlP->NumAiop = 0;
- for(i=0; i < AiopIOListSize; i++)
- {
- io = AiopIOList[i];
- CtlP->AiopIO[i] = (WordIO_t)io;
- CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
- sOutB(CtlP->MReg2IO,CtlP->MReg2 | (i & 0x03)); /* AIOP index */
- sOutB(MudbacIO,(Byte_t)(io >> 6)); /* set up AIOP I/O in MUDBAC */
- sEnAiop(CtlP,i); /* enable the AIOP */
-
- CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */
- if(CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */
- {
- sDisAiop(CtlP,i); /* disable AIOP */
- break; /* done looking for AIOPs */
- }
-
- CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t)io); /* num channels in AIOP */
- sOutW((WordIO_t)io + _INDX_ADDR,_CLK_PRE); /* clock prescaler */
- sOutB(io + _INDX_DATA,CLOCK_PRESC);
- CtlP->NumAiop++; /* bump count of AIOPs */
- sDisAiop(CtlP,i); /* disable AIOP */
- }
-
- if(CtlP->NumAiop == 0)
- return(-1);
- else
- return(CtlP->NumAiop);
-}
-
-int sPCIInitController( CONTROLLER_T *CtlP,
- int CtlNum,
- ByteIO_t *AiopIOList,
- int AiopIOListSize,
- int IRQNum,
- Byte_t Frequency,
- int PeriodicOnly)
-{
- int i;
- ByteIO_t io;
-
- CtlP->CtlNum = CtlNum;
- CtlP->BusType = isPCI;
- CtlP->CtlID = CTLID_0001; /* controller release 1 */
- CtlP->PCIIO = (WordIO_t)((ByteIO_t)AiopIOList[0] + _PCI_INT_FUNC);
-
- sPCIControllerEOI(CtlP);
-
- /* Init AIOPs */
- CtlP->NumAiop = 0;
- for(i=0; i < AiopIOListSize; i++)
- {
- io = AiopIOList[i];
- CtlP->AiopIO[i] = (WordIO_t)io;
- CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
-
- CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */
- if(CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */
- {
- break; /* done looking for AIOPs */
- }
-
- CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t)io); /* num channels in AIOP */
- sOutW((WordIO_t)io + _INDX_ADDR,_CLK_PRE); /* clock prescaler */
- sOutB(io + _INDX_DATA,CLOCK_PRESC);
- CtlP->NumAiop++; /* bump count of AIOPs */
- }
-
- if(CtlP->NumAiop == 0)
- return(-1);
- else
- return(CtlP->NumAiop);
-}
+struct termios deftermios = {
+ TTYDEF_IFLAG,
+ TTYDEF_OFLAG,
+ TTYDEF_CFLAG,
+ TTYDEF_LFLAG,
+ { CEOF, CEOL, CEOL, CERASE, CWERASE, CKILL, CREPRINT,
+ _POSIX_VDISABLE, CINTR, CQUIT, CSUSP, CDSUSP, CSTART, CSTOP, CLNEXT,
+ CDISCARD, CMIN, CTIME, CSTATUS, _POSIX_VDISABLE },
+ TTYDEF_SPEED,
+ TTYDEF_SPEED
+};
/***************************************************************************
Function: sReadAiopID
Purpose: Read the AIOP idenfication number directly from an AIOP.
-Call: sReadAiopID(io)
- ByteIO_t io: AIOP base I/O address
+Call: sReadAiopID(CtlP, aiop)
+ CONTROLLER_T *CtlP; Ptr to controller structure
+ int aiop: AIOP index
Return: int: Flag AIOPID_XXXX if a valid AIOP is found, where X
is replace by an identifying number.
Flag AIOPID_NULL if no valid AIOP is found
Warnings: No context switches are allowed while executing this function.
*/
-int sReadAiopID(ByteIO_t io)
+int sReadAiopID(CONTROLLER_T *CtlP, int aiop)
{
Byte_t AiopID; /* ID byte from AIOP */
- sOutB(io + _CMD_REG,RESET_ALL); /* reset AIOP */
- sOutB(io + _CMD_REG,0x0);
- AiopID = sInB(io + _CHN_STAT0) & 0x07;
+ rp_writeaiop1(CtlP, aiop, _CMD_REG, RESET_ALL); /* reset AIOP */
+ rp_writeaiop1(CtlP, aiop, _CMD_REG, 0x0);
+ AiopID = rp_readaiop1(CtlP, aiop, _CHN_STAT0) & 0x07;
if(AiopID == 0x06)
return(1);
else /* AIOP does not exist */
@@ -345,8 +154,9 @@ int sReadAiopID(ByteIO_t io)
Function: sReadAiopNumChan
Purpose: Read the number of channels available in an AIOP directly from
an AIOP.
-Call: sReadAiopNumChan(io)
- WordIO_t io: AIOP base I/O address
+Call: sReadAiopNumChan(CtlP, aiop)
+ CONTROLLER_T *CtlP; Ptr to controller structure
+ int aiop: AIOP index
Return: int: The number of channels available
Comments: The number of channels is determined by write/reads from identical
offsets within the SRAM address spaces for channels 0 and 4.
@@ -354,15 +164,16 @@ Comments: The number of channels is determined by write/reads from identical
AIOP, otherwise it is an 8 channel.
Warnings: No context switches are allowed while executing this function.
*/
-int sReadAiopNumChan(WordIO_t io)
+int sReadAiopNumChan(CONTROLLER_T *CtlP, int aiop)
{
- Word_t x;
-
- sOutDW((DWordIO_t)io + _INDX_ADDR,0x12340000L); /* write to chan 0 SRAM */
- sOutW(io + _INDX_ADDR,0); /* read from SRAM, chan 0 */
- x = sInW(io + _INDX_DATA);
- sOutW(io + _INDX_ADDR,0x4000); /* read from SRAM, chan 4 */
- if(x != sInW(io + _INDX_DATA)) /* if different must be 8 chan */
+ Word_t x, y;
+
+ rp_writeaiop4(CtlP, aiop, _INDX_ADDR,0x12340000L); /* write to chan 0 SRAM */
+ rp_writeaiop2(CtlP, aiop, _INDX_ADDR,0); /* read from SRAM, chan 0 */
+ x = rp_readaiop2(CtlP, aiop, _INDX_DATA);
+ rp_writeaiop2(CtlP, aiop, _INDX_ADDR,0x4000); /* read from SRAM, chan 4 */
+ y = rp_readaiop2(CtlP, aiop, _INDX_DATA);
+ if(x != y) /* if different must be 8 chan */
return(8);
else
return(4);
@@ -388,11 +199,8 @@ int sInitChan( CONTROLLER_T *CtlP,
int AiopNum,
int ChanNum)
{
- int i;
- WordIO_t AiopIO;
- WordIO_t ChIOOff;
+ int i, ChOff;
Byte_t *ChR;
- Word_t ChOff;
static Byte_t R[4];
if(ChanNum >= CtlP->AiopNumChan[AiopNum])
@@ -404,21 +212,6 @@ int sInitChan( CONTROLLER_T *CtlP,
ChP->AiopNum = AiopNum;
ChP->ChanNum = ChanNum;
- /* Global direct addresses */
- AiopIO = CtlP->AiopIO[AiopNum];
- ChP->Cmd = (ByteIO_t)AiopIO + _CMD_REG;
- ChP->IntChan = (ByteIO_t)AiopIO + _INT_CHAN;
- ChP->IntMask = (ByteIO_t)AiopIO + _INT_MASK;
- ChP->IndexAddr = (DWordIO_t)AiopIO + _INDX_ADDR;
- ChP->IndexData = AiopIO + _INDX_DATA;
-
- /* Channel direct addresses */
- ChIOOff = AiopIO + ChP->ChanNum * 2;
- ChP->TxRxData = ChIOOff + _TD0;
- ChP->ChanStat = ChIOOff + _CHN_STAT0;
- ChP->TxRxCount = ChIOOff + _FIFO_CNT0;
- ChP->IntID = (ByteIO_t)AiopIO + ChP->ChanNum + _INT_ID0;
-
/* Initialize the channel from the RData array */
for(i=0; i < RDATASIZE; i+=4)
{
@@ -426,7 +219,7 @@ int sInitChan( CONTROLLER_T *CtlP,
R[1] = RData[i+1] + 0x10 * ChanNum;
R[2] = RData[i+2];
R[3] = RData[i+3];
- sOutDW(ChP->IndexAddr,*((DWord_t *)&R[0]));
+ rp_writech4(ChP,_INDX_ADDR,*((DWord_t *)&R[0]));
}
ChR = ChP->R;
@@ -445,66 +238,66 @@ int sInitChan( CONTROLLER_T *CtlP,
ChP->BaudDiv[1] = (Byte_t)((ChOff + _BAUD) >> 8);
ChP->BaudDiv[2] = (Byte_t)BRD9600;
ChP->BaudDiv[3] = (Byte_t)(BRD9600 >> 8);
- sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->BaudDiv[0]);
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&ChP->BaudDiv[0]);
ChP->TxControl[0] = (Byte_t)(ChOff + _TX_CTRL);
ChP->TxControl[1] = (Byte_t)((ChOff + _TX_CTRL) >> 8);
ChP->TxControl[2] = 0;
ChP->TxControl[3] = 0;
- sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxControl[0]);
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&ChP->TxControl[0]);
ChP->RxControl[0] = (Byte_t)(ChOff + _RX_CTRL);
ChP->RxControl[1] = (Byte_t)((ChOff + _RX_CTRL) >> 8);
ChP->RxControl[2] = 0;
ChP->RxControl[3] = 0;
- sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->RxControl[0]);
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&ChP->RxControl[0]);
ChP->TxEnables[0] = (Byte_t)(ChOff + _TX_ENBLS);
ChP->TxEnables[1] = (Byte_t)((ChOff + _TX_ENBLS) >> 8);
ChP->TxEnables[2] = 0;
ChP->TxEnables[3] = 0;
- sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxEnables[0]);
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&ChP->TxEnables[0]);
ChP->TxCompare[0] = (Byte_t)(ChOff + _TXCMP1);
ChP->TxCompare[1] = (Byte_t)((ChOff + _TXCMP1) >> 8);
ChP->TxCompare[2] = 0;
ChP->TxCompare[3] = 0;
- sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxCompare[0]);
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&ChP->TxCompare[0]);
ChP->TxReplace1[0] = (Byte_t)(ChOff + _TXREP1B1);
ChP->TxReplace1[1] = (Byte_t)((ChOff + _TXREP1B1) >> 8);
ChP->TxReplace1[2] = 0;
ChP->TxReplace1[3] = 0;
- sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxReplace1[0]);
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&ChP->TxReplace1[0]);
ChP->TxReplace2[0] = (Byte_t)(ChOff + _TXREP2);
ChP->TxReplace2[1] = (Byte_t)((ChOff + _TXREP2) >> 8);
ChP->TxReplace2[2] = 0;
ChP->TxReplace2[3] = 0;
- sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxReplace2[0]);
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&ChP->TxReplace2[0]);
ChP->TxFIFOPtrs = ChOff + _TXF_OUTP;
ChP->TxFIFO = ChOff + _TX_FIFO;
- sOutB(ChP->Cmd,(Byte_t)ChanNum | RESTXFCNT); /* apply reset Tx FIFO count */
- sOutB(ChP->Cmd,(Byte_t)ChanNum); /* remove reset Tx FIFO count */
- sOutW((WordIO_t)ChP->IndexAddr,ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */
- sOutW(ChP->IndexData,0);
+ rp_writech1(ChP,_CMD_REG,(Byte_t)ChanNum | RESTXFCNT); /* apply reset Tx FIFO count */
+ rp_writech1(ChP,_CMD_REG,(Byte_t)ChanNum); /* remove reset Tx FIFO count */
+ rp_writech2(ChP,_INDX_ADDR,ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */
+ rp_writech2(ChP,_INDX_DATA,0);
ChP->RxFIFOPtrs = ChOff + _RXF_OUTP;
ChP->RxFIFO = ChOff + _RX_FIFO;
- sOutB(ChP->Cmd,(Byte_t)ChanNum | RESRXFCNT); /* apply reset Rx FIFO count */
- sOutB(ChP->Cmd,(Byte_t)ChanNum); /* remove reset Rx FIFO count */
- sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs); /* clear Rx out ptr */
- sOutW(ChP->IndexData,0);
- sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */
- sOutW(ChP->IndexData,0);
+ rp_writech1(ChP,_CMD_REG,(Byte_t)ChanNum | RESRXFCNT); /* apply reset Rx FIFO count */
+ rp_writech1(ChP,_CMD_REG,(Byte_t)ChanNum); /* remove reset Rx FIFO count */
+ rp_writech2(ChP,_INDX_ADDR,ChP->RxFIFOPtrs); /* clear Rx out ptr */
+ rp_writech2(ChP,_INDX_ADDR,0);
+ rp_writech2(ChP,_INDX_ADDR,ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */
+ rp_writech2(ChP,_INDX_ADDR,0);
ChP->TxPrioCnt = ChOff + _TXP_CNT;
- sOutW((WordIO_t)ChP->IndexAddr,ChP->TxPrioCnt);
- sOutB(ChP->IndexData,0);
+ rp_writech2(ChP,_INDX_ADDR,ChP->TxPrioCnt);
+ rp_writech1(ChP,_INDX_ADDR,0);
ChP->TxPrioPtr = ChOff + _TXP_PNTR;
- sOutW((WordIO_t)ChP->IndexAddr,ChP->TxPrioPtr);
- sOutB(ChP->IndexData,0);
+ rp_writech2(ChP,_INDX_ADDR,ChP->TxPrioPtr);
+ rp_writech1(ChP,_INDX_ADDR,0);
ChP->TxPrioBuf = ChOff + _TXP_BUF;
sEnRxProcessor(ChP); /* start the Rx processor */
@@ -537,7 +330,7 @@ void sStopRxProcessor(CHANNEL_T *ChP)
R[1] = ChP->R[1];
R[2] = 0x0a;
R[3] = ChP->R[3];
- sOutDW(ChP->IndexAddr,*(DWord_t *)&R[0]);
+ rp_writech4(ChP, _INDX_ADDR,*(DWord_t *)&R[0]);
}
/***************************************************************************
@@ -569,16 +362,16 @@ void sFlushRxFIFO(CHANNEL_T *ChP)
RxFIFOEnabled = TRUE;
sDisRxFIFO(ChP); /* disable it */
for(i=0; i < 2000/200; i++) /* delay 2 uS to allow proc to disable FIFO*/
- sInB(ChP->IntChan); /* depends on bus i/o timing */
+ rp_readch1(ChP,_INT_CHAN); /* depends on bus i/o timing */
}
sGetChanStatus(ChP); /* clear any pending Rx errors in chan stat */
Ch = (Byte_t)sGetChanNum(ChP);
- sOutB(ChP->Cmd,Ch | RESRXFCNT); /* apply reset Rx FIFO count */
- sOutB(ChP->Cmd,Ch); /* remove reset Rx FIFO count */
- sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs); /* clear Rx out ptr */
- sOutW(ChP->IndexData,0);
- sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */
- sOutW(ChP->IndexData,0);
+ rp_writech1(ChP,_CMD_REG,Ch | RESRXFCNT); /* apply reset Rx FIFO count */
+ rp_writech1(ChP,_CMD_REG,Ch); /* remove reset Rx FIFO count */
+ rp_writech2(ChP,_INDX_ADDR,ChP->RxFIFOPtrs); /* clear Rx out ptr */
+ rp_writech2(ChP,_INDX_DATA,0);
+ rp_writech2(ChP,_INDX_ADDR,ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */
+ rp_writech2(ChP,_INDX_DATA,0);
if(RxFIFOEnabled)
sEnRxFIFO(ChP); /* enable Rx FIFO */
}
@@ -614,12 +407,12 @@ void sFlushTxFIFO(CHANNEL_T *ChP)
}
sStopRxProcessor(ChP); /* stop Rx processor */
for(i = 0; i < 4000/200; i++) /* delay 4 uS to allow proc to stop */
- sInB(ChP->IntChan); /* depends on bus i/o timing */
+ rp_readch1(ChP,_INT_CHAN); /* depends on bus i/o timing */
Ch = (Byte_t)sGetChanNum(ChP);
- sOutB(ChP->Cmd,Ch | RESTXFCNT); /* apply reset Tx FIFO count */
- sOutB(ChP->Cmd,Ch); /* remove reset Tx FIFO count */
- sOutW((WordIO_t)ChP->IndexAddr,ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */
- sOutW(ChP->IndexData,0);
+ rp_writech1(ChP,_CMD_REG,Ch | RESTXFCNT); /* apply reset Tx FIFO count */
+ rp_writech1(ChP,_CMD_REG,Ch); /* remove reset Tx FIFO count */
+ rp_writech2(ChP,_INDX_ADDR,ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */
+ rp_writech2(ChP,_INDX_DATA,0);
if(TxEnabled)
sEnTransmit(ChP); /* enable transmitter */
sStartRxProcessor(ChP); /* restart Rx processor */
@@ -642,30 +435,28 @@ int sWriteTxPrioByte(CHANNEL_T *ChP, Byte_t Data)
{
Byte_t DWBuf[4]; /* buffer for double word writes */
Word_t *WordPtr; /* must be far because Win SS != DS */
- register DWordIO_t IndexAddr;
if(sGetTxCnt(ChP) > 1) /* write it to Tx priority buffer */
{
- IndexAddr = ChP->IndexAddr;
- sOutW((WordIO_t)IndexAddr,ChP->TxPrioCnt); /* get priority buffer status */
- if(sInB((ByteIO_t)ChP->IndexData) & PRI_PEND) /* priority buffer busy */
+ rp_writech2(ChP,_INDX_ADDR,ChP->TxPrioCnt); /* get priority buffer status */
+ if(rp_readch1(ChP,_INDX_DATA) & PRI_PEND) /* priority buffer busy */
return(0); /* nothing sent */
WordPtr = (Word_t *)(&DWBuf[0]);
*WordPtr = ChP->TxPrioBuf; /* data byte address */
DWBuf[2] = Data; /* data byte value */
- sOutDW(IndexAddr,*((DWord_t *)(&DWBuf[0]))); /* write it out */
+ rp_writech4(ChP,_INDX_ADDR,*((DWord_t *)(&DWBuf[0]))); /* write it out */
*WordPtr = ChP->TxPrioCnt; /* Tx priority count address */
DWBuf[2] = PRI_PEND + 1; /* indicate 1 byte pending */
DWBuf[3] = 0; /* priority buffer pointer */
- sOutDW(IndexAddr,*((DWord_t *)(&DWBuf[0]))); /* write it out */
+ rp_writech4(ChP,_INDX_ADDR,*((DWord_t *)(&DWBuf[0]))); /* write it out */
}
else /* write it to Tx FIFO */
{
- sWriteTxByte(sGetTxRxDataIO(ChP),Data);
+ sWriteTxByte(ChP,sGetTxRxDataIO(ChP),Data);
}
return(1); /* 1 byte sent */
}
@@ -709,16 +500,16 @@ void sEnInterrupts(CHANNEL_T *ChP,Word_t Flags)
ChP->RxControl[2] |=
((Byte_t)Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
- sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->RxControl[0]);
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&ChP->RxControl[0]);
ChP->TxControl[2] |= ((Byte_t)Flags & TXINT_EN);
- sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxControl[0]);
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&ChP->TxControl[0]);
if(Flags & CHANINT_EN)
{
- Mask = sInB(ChP->IntMask) | sBitMapSetTbl[ChP->ChanNum];
- sOutB(ChP->IntMask,Mask);
+ Mask = rp_readch1(ChP,_INT_MASK) | rp_sBitMapSetTbl[ChP->ChanNum];
+ rp_writech1(ChP,_INT_MASK,Mask);
}
}
@@ -753,14 +544,14 @@ void sDisInterrupts(CHANNEL_T *ChP,Word_t Flags)
ChP->RxControl[2] &=
~((Byte_t)Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
- sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->RxControl[0]);
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&ChP->RxControl[0]);
ChP->TxControl[2] &= ~((Byte_t)Flags & TXINT_EN);
- sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxControl[0]);
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&ChP->TxControl[0]);
if(Flags & CHANINT_EN)
{
- Mask = sInB(ChP->IntMask) & sBitMapClrTbl[ChP->ChanNum];
- sOutB(ChP->IntMask,Mask);
+ Mask = rp_readch1(ChP,_INT_MASK) & rp_sBitMapClrTbl[ChP->ChanNum];
+ rp_writech1(ChP,_INT_MASK,Mask);
}
}
@@ -768,51 +559,25 @@ void sDisInterrupts(CHANNEL_T *ChP,Word_t Flags)
Begin FreeBsd-specific driver code
**********************************************************************/
-static int rpprobe __P((struct isa_device *));
-static int rpattach __P((struct isa_device *));
-
-static const char* rp_pciprobe(pcici_t tag, pcidi_t type);
-static void rp_pciattach(pcici_t tag, int unit);
-static u_long rp_pcicount;
-
-static struct pci_device rp_pcidevice = {
- "rp",
- rp_pciprobe,
- rp_pciattach,
- &rp_pcicount,
- NULL
-};
-
-COMPAT_PCI_DRIVER (rp_pci, rp_pcidevice);
-
static timeout_t rpdtrwakeup;
-struct isa_driver rpdriver = {
- INTR_TYPE_TTY,
- rpprobe,
- rpattach,
- "rp"
-};
-COMPAT_ISA_DRIVER(rp, rpdriver);
-
-static char driver_name[] = "rp";
-
static d_open_t rpopen;
static d_close_t rpclose;
+static d_read_t rpread;
static d_write_t rpwrite;
static d_ioctl_t rpioctl;
#define CDEV_MAJOR 81
-static struct cdevsw rp_cdevsw = {
+struct cdevsw rp_cdevsw = {
/* open */ rpopen,
/* close */ rpclose,
- /* read */ ttyread,
+ /* read */ rpread,
/* write */ rpwrite,
/* ioctl */ rpioctl,
/* poll */ ttypoll,
/* mmap */ nommap,
/* strategy */ nostrategy,
- /* name */ driver_name,
+ /* name */ "rp",
/* maj */ CDEV_MAJOR,
/* dump */ nodump,
/* psize */ nopsize,
@@ -820,13 +585,9 @@ static struct cdevsw rp_cdevsw = {
/* bmaj */ -1
};
-static int rp_controller_port = 0;
-static int rp_num_ports_open = 0;
-static int ndevs = 0;
+static int rp_num_ports_open = 0;
+static int rp_ndevs = 0;
static int minor_to_unit[128];
-#if 0
-static struct tty rp_tty[128];
-#endif
static int rp_num_ports[4]; /* Number of ports on each controller */
@@ -860,15 +621,14 @@ static int rpparam __P((struct tty *, struct termios *));
static void rpstart __P((struct tty *));
static void rpstop __P((struct tty *, int));
static void rphardclose __P((struct rp_port *));
-static void rp_disc_optim __P((struct tty *tp, struct termios *t,
- struct rp_port *rp));
+static void rp_disc_optim __P((struct tty *tp, struct termios *t));
static _INLINE_ void rp_do_receive(struct rp_port *rp, struct tty *tp,
CHANNEL_t *cp, unsigned int ChanStatus)
{
int spl;
unsigned int CharNStat;
- int ToRecv, ch;
+ int ToRecv, wRecv, ch, ttynocopy;
ToRecv = sGetRxCnt(cp);
if(ToRecv == 0)
@@ -895,7 +655,7 @@ static _INLINE_ void rp_do_receive(struct rp_port *rp, struct tty *tp,
if(tp->t_state & TS_TBLOCK) {
break;
}
- CharNStat = sInW(sGetTxRxDataIO(cp));
+ CharNStat = rp_readch2(cp,sGetTxRxDataIO(cp));
ch = CharNStat & 0xff;
if((CharNStat & STMBREAK) || (CharNStat & STMFRAMEH))
@@ -912,19 +672,44 @@ static _INLINE_ void rp_do_receive(struct rp_port *rp, struct tty *tp,
After emtying FIFO in status mode, turn off status mode
*/
- if(sGetRxCnt(cp) == 0)
- sDisRxStatusMode(cp);
- }
- else {
- while (ToRecv) {
- if(tp->t_state & TS_TBLOCK) {
- break;
+ if(sGetRxCnt(cp) == 0)
+ sDisRxStatusMode(cp);
+ } else {
+ /*
+ * Avoid the grotesquely inefficient lineswitch routine
+ * (ttyinput) in "raw" mode. It usually takes about 450
+ * instructions (that's without canonical processing or echo!).
+ * slinput is reasonably fast (usually 40 instructions plus
+ * call overhead).
+ */
+ ToRecv = sGetRxCnt(cp);
+ if ( tp->t_state & TS_CAN_BYPASS_L_RINT ) {
+ if ( ToRecv > RXFIFO_SIZE ) {
+ ToRecv = RXFIFO_SIZE;
+ }
+ wRecv = ToRecv >> 1;
+ if ( wRecv ) {
+ rp_readmultich2(cp,sGetTxRxDataIO(cp),(u_int16_t *)rp->RxBuf,wRecv);
+ }
+ if ( ToRecv & 1 ) {
+ rp->RxBuf[(ToRecv-1)] = (u_char) rp_readch1(cp,sGetTxRxDataIO(cp));
+ }
+ tk_nin += ToRecv;
+ tk_rawcc += ToRecv;
+ tp->t_rawcc += ToRecv;
+ ttynocopy = b_to_q((char *)rp->RxBuf, ToRecv, &tp->t_rawq);
+ ttwakeup(tp);
+ } else {
+ while (ToRecv) {
+ if(tp->t_state & TS_TBLOCK) {
+ break;
+ }
+ ch = (u_char) rp_readch1(cp,sGetTxRxDataIO(cp));
+ spl = spltty();
+ (*linesw[tp->t_line].l_rint)(ch, tp);
+ splx(spl);
+ ToRecv--;
}
- ch = (u_char) sInB(sGetTxRxDataIO(cp));
- spl = spltty();
- (*linesw[tp->t_line].l_rint)(ch, tp);
- splx(spl);
- ToRecv--;
}
}
}
@@ -934,7 +719,6 @@ static _INLINE_ void rp_handle_port(struct rp_port *rp)
CHANNEL_t *cp;
struct tty *tp;
unsigned int IntMask, ChanStatus;
- /* int oldcts; */
if(!rp)
return;
@@ -978,13 +762,10 @@ static void rp_do_poll(void *not_used)
int unit, aiop, ch, line, count;
unsigned char CtlMask, AiopMask;
- for(unit = 0; unit <= ndevs; unit++) {
+ for(unit = 0; unit < rp_ndevs; unit++) {
rp = rp_addr(unit);
ctl = rp->rp_ctlp;
- if(ctl->BusType == isPCI)
- CtlMask = sPCIGetControllerIntStatus(ctl);
- else
- CtlMask = sGetControllerIntStatus(ctl);
+ CtlMask = ctl->ctlmask(ctl);
for(aiop=0; CtlMask; CtlMask >>=1, aiop++) {
if(CtlMask & 1) {
AiopMask = sGetAiopIntStatus(ctl, aiop);
@@ -1016,103 +797,30 @@ static void rp_do_poll(void *not_used)
timeout(rp_do_poll, (void *)NULL, POLL_INTERVAL);
}
-static const char*
-rp_pciprobe(pcici_t tag, pcidi_t type)
-{
- int vendor_id;
-
- vendor_id = type & 0xffff;
- switch(vendor_id)
- case 0x11fe:
- return("rp");
- return(NULL);
-}
-
-static
int
-rpprobe(dev)
-struct isa_device *dev;
-{
- int controller, unit;
- int aiop, num_aiops;
- unsigned int aiopio[MAX_AIOPS_PER_BOARD];
- CONTROLLER_t *ctlp;
-
- unit = dev->id_unit;
- if (dev->id_unit >= 4) {
- printf("rpprobe: unit number %d invalid.\n", dev->id_unit);
- return 1;
- }
- printf("probing for RocketPort(ISA) unit %d\n", unit);
- if (rp_controller_port)
- controller = rp_controller_port;
- else {
- controller = dev->id_iobase + 0x40;
- }
-
- for (aiop=0; aiop<MAX_AIOPS_PER_BOARD; aiop++)
- aiopio[aiop]= dev->id_iobase + (aiop * 0x400);
-
- ctlp = sCtlNumToCtlPtr(dev->id_unit);
- num_aiops = sInitController(ctlp, dev->id_unit,
- controller + ((unit-rp_pcicount)*0x400),
- aiopio, MAX_AIOPS_PER_BOARD, 0,
- FREQ_DIS, 0);
- if (num_aiops <= 0) {
- printf("board%d init failed\n", unit);
- return 0;
- }
-
- if (rp_controller_port) {
- dev->id_msize = 64;
- } else {
- dev->id_msize = 68;
- rp_controller_port = controller;
- }
-
- dev->id_irq = 0;
-
- return 1;
-}
-
-static void
-rp_pciattach(pcici_t tag, int unit)
+rp_attachcommon(CONTROLLER_T *ctlp, int num_aiops, int num_ports)
{
- int success, oldspl;
- u_short iobase;
- int num_ports, num_chan, num_aiops;
+ int oldspl, unit;
+ int num_chan;
int aiop, chan, port;
int ChanStatus, line, i, count;
- unsigned int aiopio[MAX_AIOPS_PER_BOARD];
+ int retval;
struct rp_port *rp;
struct tty *tty;
- CONTROLLER_t *ctlp;
+ dev_t *dev_nodes;
- success = pci_map_port(tag, 0x10, &iobase);
- if(!success)
- printf("ioaddr mapping failed for RocketPort(PCI)\n");
+ unit = device_get_unit(ctlp->dev);
- for(aiop=0; aiop < MAX_AIOPS_PER_BOARD; aiop++)
- aiopio[aiop] = iobase + (aiop * 0x40);
-
- ctlp = sCtlNumToCtlPtr(unit);
- num_aiops = sPCIInitController(ctlp, unit,
- aiopio, MAX_AIOPS_PER_BOARD, 0,
- FREQ_DIS, 0);
-
- num_ports = 0;
- for(aiop=0; aiop < num_aiops; aiop++) {
- sResetAiopByNum(ctlp, aiop);
- num_ports += sGetAiopNumChan(ctlp, aiop);
- }
- printf("RocketPort%d = %d ports\n", unit, num_ports);
+ printf("RocketPort%d (Version %s) %d ports.\n", unit,
+ RocketPortVersion, num_ports);
rp_num_ports[unit] = num_ports;
- rp = (struct rp_port *)
+ ctlp->rp = rp = (struct rp_port *)
malloc(sizeof(struct rp_port) * num_ports, M_TTYS, M_NOWAIT);
- if(rp == 0) {
- printf("rp_attach: Could not malloc rp_ports structures\n");
- return;
+ if (rp == NULL) {
+ device_printf(ctlp->dev, "rp_attachcommon: Could not malloc rp_ports structures.\n");
+ retval = ENOMEM;
+ goto nogo;
}
count = unit * 32; /* board times max ports per card SG */
@@ -1120,11 +828,12 @@ rp_pciattach(pcici_t tag, int unit)
minor_to_unit[i] = unit;
bzero(rp, sizeof(struct rp_port) * num_ports);
- tty = (struct tty *)
+ ctlp->tty = tty = (struct tty *)
malloc(sizeof(struct tty) * num_ports, M_TTYS, M_NOWAIT);
- if(tty == 0) {
- printf("rp_attach: Could not malloc tty structures\n");
- return;
+ if(tty == NULL) {
+ device_printf(ctlp->dev, "rp_attachcommon: Could not malloc tty structures.\n");
+ retval = ENOMEM;
+ goto nogo;
}
bzero(tty, sizeof(struct tty) * num_ports);
@@ -1132,7 +841,34 @@ rp_pciattach(pcici_t tag, int unit)
rp_addr(unit) = rp;
splx(oldspl);
- cdevsw_add(&rp_cdevsw);
+ dev_nodes = ctlp->dev_nodes = malloc(sizeof(*(ctlp->dev_nodes)) * rp_num_ports[unit] * 6, M_DEVBUF, M_NOWAIT);
+ if(ctlp->dev_nodes == NULL) {
+ device_printf(ctlp->dev, "rp_attachcommon: Could not malloc device node structures.\n");
+ retval = ENOMEM;
+ goto nogo;
+ }
+ bzero(dev_nodes, sizeof(*(ctlp->dev_nodes)) * rp_num_ports[unit] * 6);
+
+ for (i = 0 ; i < rp_num_ports[unit] ; i++) {
+ *(dev_nodes++) = make_dev(&rp_cdevsw, ((unit + 1) << 16) | i,
+ UID_ROOT, GID_WHEEL, 0666, "ttyR%c",
+ i <= 9 ? '0' + i : 'a' + i - 10);
+ *(dev_nodes++) = make_dev(&rp_cdevsw, ((unit + 1) << 16) | i | 0x20,
+ UID_ROOT, GID_WHEEL, 0666, "ttyiR%c",
+ i <= 9 ? '0' + i : 'a' + i - 10);
+ *(dev_nodes++) = make_dev(&rp_cdevsw, ((unit + 1) << 16) | i | 0x40,
+ UID_ROOT, GID_WHEEL, 0666, "ttylR%c",
+ i <= 9 ? '0' + i : 'a' + i - 10);
+ *(dev_nodes++) = make_dev(&rp_cdevsw, ((unit + 1) << 16) | i | 0x80,
+ UID_ROOT, GID_WHEEL, 0666, "cuaR%c",
+ i <= 9 ? '0' + i : 'a' + i - 10);
+ *(dev_nodes++) = make_dev(&rp_cdevsw, ((unit + 1) << 16) | i | 0xa0,
+ UID_ROOT, GID_WHEEL, 0666, "cuaiR%c",
+ i <= 9 ? '0' + i : 'a' + i - 10);
+ *(dev_nodes++) = make_dev(&rp_cdevsw, ((unit + 1) << 16) | i | 0xc0,
+ UID_ROOT, GID_WHEEL, 0666, "cualR%c",
+ i <= 9 ? '0' + i : 'a' + i - 10);
+ }
port = 0;
for(aiop=0; aiop < num_aiops; aiop++) {
@@ -1161,11 +897,14 @@ rp_pciattach(pcici_t tag, int unit)
rp->rp_intmask = RXF_TRIG | TXFIFO_MT | SRC_INT |
DELTA_CD | DELTA_CTS | DELTA_DSR;
+#if notdef
ChanStatus = sGetChanStatus(&rp->rp_channel);
+#endif /* notdef */
if(sInitChan(ctlp, &rp->rp_channel, aiop, chan) == 0) {
- printf("RocketPort sInitChan(%d, %d, %d) failed
- \n", unit, aiop, chan);
- return;
+ device_printf(ctlp->dev, "RocketPort sInitChan(%d, %d, %d) failed.\n",
+ unit, aiop, chan);
+ retval = ENXIO;
+ goto nogo;
}
ChanStatus = sGetChanStatus(&rp->rp_channel);
rp->rp_cts = (ChanStatus & CTS_ACT) != 0;
@@ -1173,111 +912,45 @@ rp_pciattach(pcici_t tag, int unit)
rp_table(line) = rp;
}
}
-}
-static
-int
-rpattach(dev)
-struct isa_device *dev;
-{
- int iobase, unit, /*rpmajor,*/ oldspl;
- int num_ports, num_chan, num_aiops;
- int aiop, chan, port;
- int ChanStatus, line, i, count;
- unsigned int aiopio[MAX_AIOPS_PER_BOARD];
- struct rp_port *rp;
- struct tty *tty;
- CONTROLLER_t *ctlp;
+ rp_ndevs++;
+ return (0);
- iobase = dev->id_iobase;
- unit = dev->id_unit;
- ndevs = unit;
+nogo:
+ rp_releaseresource(ctlp);
- for(aiop=0; aiop < MAX_AIOPS_PER_BOARD; aiop++)
- aiopio[aiop] = iobase + (aiop * 0x400);
-
- ctlp = sCtlNumToCtlPtr(unit);
- num_aiops = sInitController(ctlp, unit,
- rp_controller_port + ((unit-rp_pcicount) * 0x400),
- aiopio, MAX_AIOPS_PER_BOARD, 0,
- FREQ_DIS, 0);
+ return (retval);
+}
- num_ports = 0;
- for(aiop=0; aiop < num_aiops; aiop++) {
- sResetAiopByNum(ctlp, aiop);
- sEnAiop(ctlp, aiop);
- num_ports += sGetAiopNumChan(ctlp, aiop);
+void
+rp_releaseresource(CONTROLLER_t *ctlp)
+{
+ int i, s, unit;
+
+ unit = device_get_unit(ctlp->dev);
+
+ if (ctlp->rp != NULL) {
+ s = spltty();
+ for (i = 0 ; i < sizeof(p_rp_addr) / sizeof(*p_rp_addr) ; i++)
+ if (p_rp_addr[i] == ctlp->rp)
+ p_rp_addr[i] = NULL;
+ for (i = 0 ; i < sizeof(p_rp_table) / sizeof(*p_rp_table) ; i++)
+ if (p_rp_table[i] == ctlp->rp)
+ p_rp_table[i] = NULL;
+ splx(s);
+ free(ctlp->rp, M_DEVBUF);
+ ctlp->rp = NULL;
}
- printf("RocketPort%d = %d ports\n", unit, num_ports);
- rp_num_ports[unit] = num_ports;
-
- rp = (struct rp_port *)
- malloc(sizeof(struct rp_port) * num_ports, M_TTYS, M_NOWAIT);
- if(rp == 0) {
- printf("rp_attach: Could not malloc rp_ports structures\n");
- return(0);
+ if (ctlp->tty != NULL) {
+ free(ctlp->tty, M_DEVBUF);
+ ctlp->tty = NULL;
}
-
- count = unit * 32; /* board # times max ports per card SG */
- for(i=count;i < (count + rp_num_ports[unit]);i++)
- minor_to_unit[i] = unit;
-
- bzero(rp, sizeof(struct rp_port) * num_ports);
- tty = (struct tty *)
- malloc(sizeof(struct tty) * num_ports, M_TTYS, M_NOWAIT);
- if(tty == 0) {
- printf("rp_attach: Could not malloc tty structures\n");
- return(0);
- }
- bzero(tty, sizeof(struct tty) * num_ports);
-
- oldspl = spltty();
- rp_addr(unit) = rp;
- splx(oldspl);
-
- cdevsw_add(&rp_cdevsw);
-
- port = 0;
- for(aiop=0; aiop < num_aiops; aiop++) {
- num_chan = sGetAiopNumChan(ctlp, aiop);
- for(chan=0; chan < num_chan; chan++, port++, rp++, tty++) {
- rp->rp_tty = tty;
- rp->rp_port = port;
- rp->rp_ctlp = ctlp;
- rp->rp_unit = unit;
- rp->rp_chan = chan;
- rp->rp_aiop = aiop;
-
- tty->t_line = 0;
- /* tty->t_termios = deftermios;
- */
- rp->dtr_wait = 3 * hz;
- rp->it_in.c_iflag = 0;
- rp->it_in.c_oflag = 0;
- rp->it_in.c_cflag = TTYDEF_CFLAG;
- rp->it_in.c_lflag = 0;
- termioschars(&rp->it_in);
- /* termioschars(&tty->t_termios);
- */
- rp->it_in.c_ispeed = rp->it_in.c_ospeed = TTYDEF_SPEED;
- rp->it_out = rp->it_in;
-
- rp->rp_intmask = RXF_TRIG | TXFIFO_MT | SRC_INT |
- DELTA_CD | DELTA_CTS | DELTA_DSR;
- ChanStatus = sGetChanStatus(&rp->rp_channel);
- if(sInitChan(ctlp, &rp->rp_channel, aiop, chan) == 0) {
- printf("RocketPort sInitChan(%d, %d, %d) failed
- \n", unit, aiop, chan);
- return(0);
- }
- ChanStatus = sGetChanStatus(&rp->rp_channel);
- rp->rp_cts = (ChanStatus & CTS_ACT) != 0;
- line = (unit << 5) | (aiop << 3) | chan;
- rp_table(line) = rp;
- }
+ if (ctlp->dev != NULL) {
+ for (i = 0 ; i < rp_num_ports[unit] * 6 ; i++)
+ destroy_dev(ctlp->dev_nodes[i]);
+ free(ctlp->dev_nodes, M_DEVBUF);
+ ctlp->dev = NULL;
}
-
- return(1);
}
int
@@ -1297,6 +970,8 @@ rpopen(dev, flag, mode, p)
port = (minor(dev) & 0x1f); /* SG */
mynor = (port + umynor); /* SG */
unit = minor_to_unit[mynor];
+ if (rp_addr(unit) == NULL)
+ return (ENXIO);
if(IS_CONTROL(dev))
return(0);
rp = rp_addr(unit) + port;
@@ -1333,10 +1008,10 @@ open_top:
goto open_top;
}
}
- if(tp->t_state & TS_XCLUDE &&
- suser(p)) {
+ if(tp->t_state & TS_XCLUDE && suser(p) != 0) {
splx(oldspl);
- return(EBUSY);
+ error = EBUSY;
+ goto out2;
}
}
else {
@@ -1346,13 +1021,16 @@ open_top:
tp->t_stop = rpstop;
tp->t_line = 0;
tp->t_termios = IS_CALLOUT(dev) ? rp->it_out : rp->it_in;
+ tp->t_ififosize = 512;
+ tp->t_ispeedwat = (speed_t)-1;
+ tp->t_ospeedwat = (speed_t)-1;
flags = 0;
flags |= SET_RTS;
flags |= SET_DTR;
rp->rp_channel.TxControl[3] =
((rp->rp_channel.TxControl[3]
& ~(SET_RTS | SET_DTR)) | flags);
- sOutDW(rp->rp_channel.IndexAddr,
+ rp_writech4(&rp->rp_channel,_INDX_ADDR,
*(DWord_t *) &(rp->rp_channel.TxControl[0]));
sSetRxTrigger(&rp->rp_channel, TRIG_1);
sDisRxStatusMode(&rp->rp_channel);
@@ -1416,7 +1094,7 @@ open_top:
}
error = (*linesw[tp->t_line].l_open)(dev, tp);
- rp_disc_optim(tp, &tp->t_termios, rp);
+ rp_disc_optim(tp, &tp->t_termios);
if(tp->t_state & TS_ISOPEN && IS_CALLOUT(dev))
rp->active_out = TRUE;
@@ -1428,6 +1106,9 @@ out:
if(!(tp->t_state & TS_ISOPEN) && rp->wopeners == 0) {
rphardclose(rp);
}
+out2:
+ if (error == 0)
+ device_busy(rp->rp_ctlp->dev);
return(error);
}
@@ -1455,7 +1136,7 @@ rpclose(dev, flag, mode, p)
oldspl = spltty();
(*linesw[tp->t_line].l_close)(tp, flag);
- rp_disc_optim(tp, &tp->t_termios, rp);
+ rp_disc_optim(tp, &tp->t_termios);
rpstop(tp, FREAD | FWRITE);
rphardclose(rp);
@@ -1464,6 +1145,8 @@ rpclose(dev, flag, mode, p)
splx(oldspl);
+ device_unbusy(rp->rp_ctlp->dev);
+
return(0);
}
@@ -1505,6 +1188,30 @@ rphardclose(struct rp_port *rp)
static
int
+rpread(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ struct rp_port *rp;
+ struct tty *tp;
+ int unit, mynor, umynor, port, error = 0; /* SG */
+
+ umynor = (((minor(dev) >> 16) -1) * 32); /* SG */
+ port = (minor(dev) & 0x1f); /* SG */
+ mynor = (port + umynor); /* SG */
+ unit = minor_to_unit[mynor]; /* SG */
+
+ if(IS_CONTROL(dev))
+ return(ENODEV);
+ rp = rp_addr(unit) + port;
+ tp = rp->rp_tty;
+ error = (*linesw[tp->t_line].l_read)(tp, uio, flag);
+ return(error);
+}
+
+static
+int
rpwrite(dev, uio, flag)
dev_t dev;
struct uio *uio;
@@ -1559,8 +1266,7 @@ rpioctl(dev, cmd, data, flag, p)
int oldspl;
int error = 0;
int arg, flags, result, ChanStatus;
- int oldcmd;
- struct termios term, *t;
+ struct termios *t;
umynor = (((minor(dev) >> 16) -1) * 32); /* SG */
port = (minor(dev) & 0x1f); /* SG */
@@ -1630,7 +1336,7 @@ rpioctl(dev, cmd, data, flag, p)
dt->c_lflag = (tp->t_lflag & lt->c_lflag)
| (dt->c_lflag & ~lt->c_lflag);
for(cc = 0; cc < NCCS; ++cc)
- if((lt->c_cc[cc] = tp->t_cc[cc]) != 0)
+ if(lt->c_cc[cc] != 0)
dt->c_cc[cc] = tp->t_cc[cc];
if(lt->c_ispeed != 0)
dt->c_ispeed = tp->t_ispeed;
@@ -1650,7 +1356,7 @@ rpioctl(dev, cmd, data, flag, p)
error = ttioctl(tp, cmd, data, flag);
flags = rp->rp_channel.TxControl[3];
- rp_disc_optim(tp, &tp->t_termios, rp);
+ rp_disc_optim(tp, &tp->t_termios);
if(error != ENOIOCTL) {
splx(oldspl);
return(error);
@@ -1683,7 +1389,7 @@ rpioctl(dev, cmd, data, flag, p)
rp->rp_channel.TxControl[3] =
((rp->rp_channel.TxControl[3]
& ~(SET_RTS | SET_DTR)) | flags);
- sOutDW(rp->rp_channel.IndexAddr,
+ rp_writech4(&rp->rp_channel,_INDX_ADDR,
*(DWord_t *) &(rp->rp_channel.TxControl[0]));
break;
case TIOCMBIS:
@@ -1694,7 +1400,7 @@ rpioctl(dev, cmd, data, flag, p)
if(arg & TIOCM_DTR)
flags |= SET_DTR;
rp->rp_channel.TxControl[3] |= flags;
- sOutDW(rp->rp_channel.IndexAddr,
+ rp_writech4(&rp->rp_channel,_INDX_ADDR,
*(DWord_t *) &(rp->rp_channel.TxControl[0]));
break;
case TIOCMBIC:
@@ -1705,7 +1411,7 @@ rpioctl(dev, cmd, data, flag, p)
if(arg & TIOCM_DTR)
flags |= SET_DTR;
rp->rp_channel.TxControl[3] &= ~flags;
- sOutDW(rp->rp_channel.IndexAddr,
+ rp_writech4(&rp->rp_channel,_INDX_ADDR,
*(DWord_t *) &(rp->rp_channel.TxControl[0]));
break;
@@ -1747,15 +1453,15 @@ rpioctl(dev, cmd, data, flag, p)
}
static struct speedtab baud_table[] = {
- B0, 0, B50, BRD50, B75, BRD75,
- B110, BRD110, B134, BRD134, B150, BRD150,
- B200, BRD200, B300, BRD300, B600, BRD600,
- B1200, BRD1200, B1800, BRD1800, B2400, BRD2400,
- B4800, BRD4800, B9600, BRD9600, B19200, BRD19200,
- B38400, BRD38400, B7200, BRD7200, B14400, BRD14400,
- B57600, BRD57600, B76800, BRD76800,
- B115200, BRD115200, B230400, BRD230400,
- -1, -1
+ {B0, 0}, {B50, BRD50}, {B75, BRD75},
+ {B110, BRD110}, {B134, BRD134}, {B150, BRD150},
+ {B200, BRD200}, {B300, BRD300}, {B600, BRD600},
+ {B1200, BRD1200}, {B1800, BRD1800}, {B2400, BRD2400},
+ {B4800, BRD4800}, {B9600, BRD9600}, {B19200, BRD19200},
+ {B38400, BRD38400}, {B7200, BRD7200}, {B14400, BRD14400},
+ {B57600, BRD57600}, {B76800, BRD76800},
+ {B115200, BRD115200}, {B230400, BRD230400},
+ {-1, -1}
};
static int
@@ -1768,6 +1474,9 @@ rpparam(tp, t)
int unit, mynor, port, umynor; /* SG */
int oldspl, cflag, iflag, oflag, lflag;
int ospeed;
+#ifdef RPCLOCAL
+ int devshift;
+#endif
umynor = (((minor(tp->t_dev) >> 16) -1) * 32); /* SG */
@@ -1780,6 +1489,13 @@ rpparam(tp, t)
oldspl = spltty();
cflag = t->c_cflag;
+#ifdef RPCLOCAL
+ devshift = umynor / 32;
+ devshift = 1 << devshift;
+ if ( devshift & RPCLOCAL ) {
+ cflag |= CLOCAL;
+ }
+#endif
iflag = t->c_iflag;
oflag = t->c_oflag;
lflag = t->c_lflag;
@@ -1860,7 +1576,7 @@ rpparam(tp, t)
} else {
sDisRTSFlowCtl(cp);
}
- rp_disc_optim(tp, t, rp);
+ rp_disc_optim(tp, t);
if((cflag & CLOCAL) || (sGetChanStatusLo(cp) & CD_ACT)) {
tp->t_state |= TS_CARR_ON;
@@ -1880,10 +1596,9 @@ rpparam(tp, t)
}
static void
-rp_disc_optim(tp, t, rp)
+rp_disc_optim(tp, t)
struct tty *tp;
struct termios *t;
-struct rp_port *rp;
{
if(!(t->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR | ISTRIP | IXON))
&&(!(t->c_iflag & BRKINT) || (t->c_iflag & IGNBRK))
@@ -1904,9 +1619,9 @@ rpstart(tp)
CHANNEL_t *cp;
struct clist *qp;
int unit, mynor, port, umynor; /* SG */
- char ch, flags;
+ char flags;
int spl, xmit_fifo_room;
- int count;
+ int count, wcount;
umynor = (((minor(tp->t_dev) >> 16) -1) * 32); /* SG */
@@ -1939,15 +1654,16 @@ rpstart(tp)
}
xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
qp = &tp->t_outq;
- count = 0;
if(xmit_fifo_room > 0 && qp->c_cc > 0) {
tp->t_state |= TS_BUSY;
- }
- while(xmit_fifo_room > 0 && qp->c_cc > 0) {
- ch = getc(qp);
- sOutB(sGetTxRxDataIO(cp), ch);
- xmit_fifo_room--;
- count++;
+ count = q_to_b( qp, rp->TxBuf, xmit_fifo_room );
+ wcount = count >> 1;
+ if ( wcount ) {
+ rp_writemultich2(cp, sGetTxRxDataIO(cp), (u_int16_t *)rp->TxBuf, wcount);
+ }
+ if ( count & 1 ) {
+ rp_writech1(cp, sGetTxRxDataIO(cp), rp->TxBuf[(count-1)]);
+ }
}
rp->rp_restart = (qp->c_cc > 0) ? rp->rp_fifo_lw : 0;
diff --git a/sys/dev/rp/rp_isa.c b/sys/dev/rp/rp_isa.c
new file mode 100644
index 0000000..fdea4a7
--- /dev/null
+++ b/sys/dev/rp/rp_isa.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright (c) Comtrol Corporation <support@comtrol.com>
+ * All rights reserved.
+ *
+ * ISA-specific part separated from:
+ * sys/i386/isa/rp.c,v 1.33 1999/09/28 11:45:27 phk Exp
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted prodived that the follwoing conditions
+ * are met.
+ * 1. Redistributions of source code must retain the above copyright
+ * notive, this list of conditions and the following disclainer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials prodided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Comtrol Corporation.
+ * 4. The name of Comtrol Corporation may not be used to endorse or
+ * promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY COMTROL CORPORATION ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COMTROL CORPORATION BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/fcntl.h>
+#include <sys/malloc.h>
+#include <sys/tty.h>
+#include <sys/proc.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <machine/resource.h>
+#include <machine/bus.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+
+#define ROCKET_C
+#include <dev/rp/rpreg.h>
+#include <dev/rp/rpvar.h>
+
+#include <isa/isavar.h>
+
+/* ISA-specific part of CONTROLLER_t */
+struct ISACONTROLLER_T {
+ int MBaseIO; /* rid of the Mudbac controller for this controller */
+ int MReg0IO; /* offset0 of the Mudbac controller for this controller */
+ int MReg1IO; /* offset1 of the Mudbac controller for this controller */
+ int MReg2IO; /* offset2 of the Mudbac controller for this controller */
+ int MReg3IO; /* offset3 of the Mudbac controller for this controller */
+ Byte_t MReg2;
+ Byte_t MReg3;
+};
+typedef struct ISACONTROLLER_T ISACONTROLLER_t;
+
+#define ISACTL(ctlp) ((ISACONTROLLER_t *)((ctlp)->bus_ctlp))
+
+/***************************************************************************
+Function: sControllerEOI
+Purpose: Strobe the MUDBAC's End Of Interrupt bit.
+Call: sControllerEOI(MudbacCtlP,CtlP)
+ CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure
+ CONTROLLER_T *CtlP; Ptr to controller structure
+*/
+#define sControllerEOI(MudbacCtlP,CtlP) \
+ rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg2IO,ISACTL(CtlP)->MReg2 | INT_STROB)
+
+/***************************************************************************
+Function: sDisAiop
+Purpose: Disable I/O access to an AIOP
+Call: sDisAiop(MudbacCtlP,CtlP)
+ CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure
+ CONTROLLER_T *CtlP; Ptr to controller structure
+ int AiopNum; Number of AIOP on controller
+*/
+#define sDisAiop(MudbacCtlP,CtlP,AIOPNUM) \
+{ \
+ ISACTL(CtlP)->MReg3 &= rp_sBitMapClrTbl[AIOPNUM]; \
+ rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg3IO,ISACTL(CtlP)->MReg3); \
+}
+
+/***************************************************************************
+Function: sEnAiop
+Purpose: Enable I/O access to an AIOP
+Call: sEnAiop(MudbacCtlP,CtlP)
+ CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure
+ CONTROLLER_T *CtlP; Ptr to controller structure
+ int AiopNum; Number of AIOP on controller
+*/
+#define sEnAiop(MudbacCtlP,CtlP,AIOPNUM) \
+{ \
+ ISACTL(CtlP)->MReg3 |= rp_sBitMapSetTbl[AIOPNUM]; \
+ rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg3IO,ISACTL(CtlP)->MReg3); \
+}
+
+/***************************************************************************
+Function: sGetControllerIntStatus
+Purpose: Get the controller interrupt status
+Call: sGetControllerIntStatus(MudbacCtlP,CtlP)
+ CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure
+ CONTROLLER_T *CtlP; Ptr to controller structure
+Return: Byte_t: The controller interrupt status in the lower 4
+ bits. Bits 0 through 3 represent AIOP's 0
+ through 3 respectively. If a bit is set that
+ AIOP is interrupting. Bits 4 through 7 will
+ always be cleared.
+*/
+#define sGetControllerIntStatus(MudbacCtlP,CtlP) \
+ (rp_readio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg1IO) & 0x0f)
+
+static devclass_t rp_devclass;
+static CONTROLLER_t *rp_controller;
+static int rp_nisadevs;
+
+static int rp_probe(device_t dev);
+static int rp_attach(device_t dev);
+static void rp_isareleaseresource(CONTROLLER_t *ctlp);
+static int sInitController(CONTROLLER_T *CtlP,
+ CONTROLLER_T *MudbacCtlP,
+ int AiopNum,
+ int IRQNum,
+ Byte_t Frequency,
+ int PeriodicOnly);
+static rp_aiop2rid_t rp_isa_aiop2rid;
+static rp_aiop2off_t rp_isa_aiop2off;
+static rp_ctlmask_t rp_isa_ctlmask;
+
+static int
+rp_probe(device_t dev)
+{
+ int unit;
+ CONTROLLER_t *controller;
+ int num_aiops;
+ CONTROLLER_t *ctlp;
+ int retval;
+
+ /*
+ * We have no PnP RocketPort cards.
+ * (At least according to LINT)
+ */
+ if (isa_get_logicalid(dev) != 0)
+ return (ENXIO);
+
+ /* We need IO port resource to configure an ISA device. */
+ if (bus_get_resource_count(dev, SYS_RES_IOPORT, 0) == 0)
+ return (ENXIO);
+
+ unit = device_get_unit(dev);
+ if (unit >= 4) {
+ device_printf(dev, "rpprobe: unit number %d invalid.\n", unit);
+ return (ENXIO);
+ }
+ device_printf(dev, "probing for RocketPort(ISA) unit %d.\n", unit);
+
+ ctlp = device_get_softc(dev);
+ bzero(ctlp, sizeof(*ctlp));
+ ctlp->dev = dev;
+ ctlp->aiop2rid = rp_isa_aiop2rid;
+ ctlp->aiop2off = rp_isa_aiop2off;
+ ctlp->ctlmask = rp_isa_ctlmask;
+
+ /* The IO ports of AIOPs for an ISA controller are discrete. */
+ ctlp->io_num = 1;
+ ctlp->io_rid = malloc(sizeof(*(ctlp->io_rid)) * MAX_AIOPS_PER_BOARD, M_DEVBUF, M_NOWAIT);
+ ctlp->io = malloc(sizeof(*(ctlp->io)) * MAX_AIOPS_PER_BOARD, M_DEVBUF, M_NOWAIT);
+ if (ctlp->io_rid == NULL || ctlp->io == NULL) {
+ device_printf(dev, "rp_attach: Out of memory.\n");
+ retval = ENOMEM;
+ goto nogo;
+ }
+ bzero(ctlp->io_rid, sizeof(*(ctlp->io_rid)) * MAX_AIOPS_PER_BOARD);
+ bzero(ctlp->io, sizeof(*(ctlp->io)) * MAX_AIOPS_PER_BOARD);
+
+ ctlp->bus_ctlp = malloc(sizeof(ISACONTROLLER_t) * 1, M_DEVBUF, M_NOWAIT);
+ if (ctlp->bus_ctlp == NULL) {
+ device_printf(dev, "rp_attach: Out of memory.\n");
+ retval = ENOMEM;
+ goto nogo;
+ }
+ bzero(ctlp->bus_ctlp, sizeof(ISACONTROLLER_t) * 1);
+
+ ctlp->io_rid[0] = 0;
+ if (rp_controller != NULL) {
+ controller = rp_controller;
+ ctlp->io[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], 0, ~0, 0x40, RF_ACTIVE);
+ } else {
+ controller = rp_controller = ctlp;
+ ctlp->io[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], 0, ~0, 0x44, RF_ACTIVE);
+ }
+ if (ctlp->io[0] == NULL) {
+ device_printf(dev, "rp_attach: Resource not available.\n");
+ retval = ENXIO;
+ goto nogo;
+ }
+
+ num_aiops = sInitController(ctlp,
+ controller,
+ MAX_AIOPS_PER_BOARD, 0,
+ FREQ_DIS, 0);
+ if (num_aiops <= 0) {
+ device_printf(dev, "board%d init failed.\n", unit);
+ retval = ENXIO;
+ goto nogo;
+ }
+
+ if (rp_controller == NULL)
+ rp_controller = controller;
+ rp_nisadevs++;
+
+ device_set_desc(dev, "RocketPort ISA");
+
+ return (0);
+
+nogo:
+ rp_isareleaseresource(ctlp);
+
+ return (retval);
+}
+
+static int
+rp_attach(device_t dev)
+{
+ int unit;
+ int num_ports, num_aiops;
+ int aiop;
+ CONTROLLER_t *ctlp;
+ int retval;
+
+ unit = device_get_unit(dev);
+
+ ctlp = device_get_softc(dev);
+
+#if notdef
+ num_aiops = sInitController(ctlp,
+ rp_controller,
+ MAX_AIOPS_PER_BOARD, 0,
+ FREQ_DIS, 0);
+#else
+ num_aiops = ctlp->NumAiop;
+#endif /* notdef */
+
+ num_ports = 0;
+ for(aiop=0; aiop < num_aiops; aiop++) {
+ sResetAiopByNum(ctlp, aiop);
+ sEnAiop(rp_controller, ctlp, aiop);
+ num_ports += sGetAiopNumChan(ctlp, aiop);
+ }
+
+ retval = rp_attachcommon(ctlp, num_aiops, num_ports);
+ if (retval != 0)
+ goto nogo;
+
+ return (0);
+
+nogo:
+ rp_isareleaseresource(ctlp);
+
+ return (retval);
+}
+
+static void
+rp_isareleaseresource(CONTROLLER_t *ctlp)
+{
+ int i;
+
+ rp_releaseresource(ctlp);
+
+ if (ctlp == rp_controller)
+ rp_controller = NULL;
+ if (ctlp->io != NULL) {
+ for (i = 0 ; i < MAX_AIOPS_PER_BOARD ; i++)
+ if (ctlp->io[i] != NULL)
+ bus_release_resource(ctlp->dev, SYS_RES_IOPORT, ctlp->io_rid[i], ctlp->io[i]);
+ free(ctlp->io, M_DEVBUF);
+ }
+ if (ctlp->io_rid != NULL)
+ free(ctlp->io_rid, M_DEVBUF);
+ if (rp_controller != NULL && rp_controller->io[ISACTL(ctlp)->MBaseIO] != NULL) {
+ bus_release_resource(rp_controller->dev, SYS_RES_IOPORT, rp_controller->io_rid[ISACTL(ctlp)->MBaseIO], rp_controller->io[ISACTL(ctlp)->MBaseIO]);
+ rp_controller->io[ISACTL(ctlp)->MBaseIO] = NULL;
+ rp_controller->io_rid[ISACTL(ctlp)->MBaseIO] = 0;
+ }
+ if (ctlp->bus_ctlp != NULL)
+ free(ctlp->bus_ctlp, M_DEVBUF);
+}
+
+/***************************************************************************
+Function: sInitController
+Purpose: Initialization of controller global registers and controller
+ structure.
+Call: sInitController(CtlP,MudbacCtlP,AiopNum,
+ IRQNum,Frequency,PeriodicOnly)
+ CONTROLLER_T *CtlP; Ptr to controller structure
+ CONTROLLER_T *MudbacCtlP; Ptr to Mudbac controller structure
+ int AiopNum; Number of Aiops
+ int IRQNum; Interrupt Request number. Can be any of the following:
+ 0: Disable global interrupts
+ 3: IRQ 3
+ 4: IRQ 4
+ 5: IRQ 5
+ 9: IRQ 9
+ 10: IRQ 10
+ 11: IRQ 11
+ 12: IRQ 12
+ 15: IRQ 15
+ Byte_t Frequency: A flag identifying the frequency
+ of the periodic interrupt, can be any one of the following:
+ FREQ_DIS - periodic interrupt disabled
+ FREQ_137HZ - 137 Hertz
+ FREQ_69HZ - 69 Hertz
+ FREQ_34HZ - 34 Hertz
+ FREQ_17HZ - 17 Hertz
+ FREQ_9HZ - 9 Hertz
+ FREQ_4HZ - 4 Hertz
+ If IRQNum is set to 0 the Frequency parameter is
+ overidden, it is forced to a value of FREQ_DIS.
+ int PeriodicOnly: TRUE if all interrupts except the periodic
+ interrupt are to be blocked.
+ FALSE is both the periodic interrupt and
+ other channel interrupts are allowed.
+ If IRQNum is set to 0 the PeriodicOnly parameter is
+ overidden, it is forced to a value of FALSE.
+Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller
+ initialization failed.
+
+Comments:
+ If periodic interrupts are to be disabled but AIOP interrupts
+ are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE.
+
+ If interrupts are to be completely disabled set IRQNum to 0.
+
+ Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an
+ invalid combination.
+
+ This function performs initialization of global interrupt modes,
+ but it does not actually enable global interrupts. To enable
+ and disable global interrupts use functions sEnGlobalInt() and
+ sDisGlobalInt(). Enabling of global interrupts is normally not
+ done until all other initializations are complete.
+
+ Even if interrupts are globally enabled, they must also be
+ individually enabled for each channel that is to generate
+ interrupts.
+
+Warnings: No range checking on any of the parameters is done.
+
+ No context switches are allowed while executing this function.
+
+ After this function all AIOPs on the controller are disabled,
+ they can be enabled with sEnAiop().
+*/
+static int
+sInitController( CONTROLLER_T *CtlP,
+ CONTROLLER_T *MudbacCtlP,
+ int AiopNum,
+ int IRQNum,
+ Byte_t Frequency,
+ int PeriodicOnly)
+{
+ int i;
+ int ctl_base, aiop_base, aiop_size;
+
+ CtlP->CtlID = CTLID_0001; /* controller release 1 */
+
+ ISACTL(CtlP)->MBaseIO = rp_nisadevs;
+ if (MudbacCtlP->io[ISACTL(CtlP)->MBaseIO] != NULL) {
+ ISACTL(CtlP)->MReg0IO = 0x40 + 0;
+ ISACTL(CtlP)->MReg1IO = 0x40 + 1;
+ ISACTL(CtlP)->MReg2IO = 0x40 + 2;
+ ISACTL(CtlP)->MReg3IO = 0x40 + 3;
+ } else {
+ MudbacCtlP->io_rid[ISACTL(CtlP)->MBaseIO] = ISACTL(CtlP)->MBaseIO;
+ ctl_base = rman_get_start(MudbacCtlP->io[0]) + 0x40 + 0x400 * rp_nisadevs;
+ MudbacCtlP->io[ISACTL(CtlP)->MBaseIO] = bus_alloc_resource(MudbacCtlP->dev, SYS_RES_IOPORT, &CtlP->io_rid[ISACTL(CtlP)->MBaseIO], ctl_base, ctl_base + 3, 4, RF_ACTIVE);
+ ISACTL(CtlP)->MReg0IO = 0;
+ ISACTL(CtlP)->MReg1IO = 1;
+ ISACTL(CtlP)->MReg2IO = 2;
+ ISACTL(CtlP)->MReg3IO = 3;
+ }
+#if 1
+ ISACTL(CtlP)->MReg2 = 0; /* interrupt disable */
+ ISACTL(CtlP)->MReg3 = 0; /* no periodic interrupts */
+#else
+ if(sIRQMap[IRQNum] == 0) /* interrupts globally disabled */
+ {
+ ISACTL(CtlP)->MReg2 = 0; /* interrupt disable */
+ ISACTL(CtlP)->MReg3 = 0; /* no periodic interrupts */
+ }
+ else
+ {
+ ISACTL(CtlP)->MReg2 = sIRQMap[IRQNum]; /* set IRQ number */
+ ISACTL(CtlP)->MReg3 = Frequency; /* set frequency */
+ if(PeriodicOnly) /* periodic interrupt only */
+ {
+ ISACTL(CtlP)->MReg3 |= PERIODIC_ONLY;
+ }
+ }
+#endif
+ rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg2IO,ISACTL(CtlP)->MReg2);
+ rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,ISACTL(CtlP)->MReg3IO,ISACTL(CtlP)->MReg3);
+ sControllerEOI(MudbacCtlP,CtlP); /* clear EOI if warm init */
+
+ /* Init AIOPs */
+ CtlP->NumAiop = 0;
+ for(i=0; i < AiopNum; i++)
+ {
+ if (CtlP->io[i] == NULL) {
+ CtlP->io_rid[i] = i;
+ aiop_base = rman_get_start(CtlP->io[0]) + 0x400 * i;
+ if (rp_nisadevs == 0)
+ aiop_size = 0x44;
+ else
+ aiop_size = 0x40;
+ CtlP->io[i] = bus_alloc_resource(CtlP->dev, SYS_RES_IOPORT, &CtlP->io_rid[i], aiop_base, aiop_base + aiop_size - 1, aiop_size, RF_ACTIVE);
+ } else
+ aiop_base = rman_get_start(CtlP->io[i]);
+ rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,
+ ISACTL(CtlP)->MReg2IO,
+ ISACTL(CtlP)->MReg2 | (i & 0x03)); /* AIOP index */
+ rp_writeio1(MudbacCtlP,ISACTL(CtlP)->MBaseIO,
+ ISACTL(CtlP)->MReg0IO,
+ (Byte_t)(aiop_base >> 6)); /* set up AIOP I/O in MUDBAC */
+ sEnAiop(MudbacCtlP,CtlP,i); /* enable the AIOP */
+
+ CtlP->AiopID[i] = sReadAiopID(CtlP, i); /* read AIOP ID */
+ if(CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */
+ {
+ sDisAiop(MudbacCtlP,CtlP,i); /* disable AIOP */
+ bus_release_resource(CtlP->dev, SYS_RES_IOPORT, CtlP->io_rid[i], CtlP->io[i]);
+ CtlP->io[i] = NULL;
+ break; /* done looking for AIOPs */
+ }
+
+ CtlP->AiopNumChan[i] = sReadAiopNumChan(CtlP, i); /* num channels in AIOP */
+ rp_writeaiop2(CtlP,i,_INDX_ADDR,_CLK_PRE); /* clock prescaler */
+ rp_writeaiop1(CtlP,i,_INDX_DATA,CLOCK_PRESC);
+ CtlP->NumAiop++; /* bump count of AIOPs */
+ sDisAiop(MudbacCtlP,CtlP,i); /* disable AIOP */
+ }
+
+ if(CtlP->NumAiop == 0)
+ return(-1);
+ else
+ return(CtlP->NumAiop);
+}
+
+/*
+ * ARGSUSED
+ * Maps (aiop, offset) to rid.
+ */
+static int
+rp_isa_aiop2rid(int aiop, int offset)
+{
+ /* rid equals to aiop for an ISA controller. */
+ return aiop;
+}
+
+/*
+ * ARGSUSED
+ * Maps (aiop, offset) to the offset of resource.
+ */
+static int
+rp_isa_aiop2off(int aiop, int offset)
+{
+ /* Each aiop has its own resource. */
+ return offset;
+}
+
+/* Read the int status for an ISA controller. */
+unsigned char
+rp_isa_ctlmask(CONTROLLER_t *ctlp)
+{
+ return sGetControllerIntStatus(rp_controller,ctlp);
+}
+
+static device_method_t rp_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, rp_probe),
+ DEVMETHOD(device_attach, rp_attach),
+
+ { 0, 0 }
+};
+
+static driver_t rp_driver = {
+ "rp",
+ rp_methods,
+ sizeof(CONTROLLER_t),
+};
+
+/*
+ * rp can be attached to an isa bus.
+ */
+DRIVER_MODULE(rp, isa, rp_driver, rp_devclass, 0, 0);
diff --git a/sys/dev/rp/rp_pci.c b/sys/dev/rp/rp_pci.c
new file mode 100644
index 0000000..2e0b171
--- /dev/null
+++ b/sys/dev/rp/rp_pci.c
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) Comtrol Corporation <support@comtrol.com>
+ * All rights reserved.
+ *
+ * PCI-specific part separated from:
+ * sys/i386/isa/rp.c,v 1.33 1999/09/28 11:45:27 phk Exp
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted prodived that the follwoing conditions
+ * are met.
+ * 1. Redistributions of source code must retain the above copyright
+ * notive, this list of conditions and the following disclainer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials prodided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Comtrol Corporation.
+ * 4. The name of Comtrol Corporation may not be used to endorse or
+ * promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY COMTROL CORPORATION ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COMTROL CORPORATION BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/fcntl.h>
+#include <sys/malloc.h>
+#include <sys/tty.h>
+#include <sys/proc.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <machine/resource.h>
+#include <machine/bus.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+
+#define ROCKET_C
+#include <dev/rp/rpreg.h>
+#include <dev/rp/rpvar.h>
+
+#include <pci/pcireg.h>
+#include <pci/pcivar.h>
+
+/* PCI IDs */
+#define RP_VENDOR_ID 0x11FE
+#define RP_DEVICE_ID_32I 0x0001
+#define RP_DEVICE_ID_8I 0x0002
+#define RP_DEVICE_ID_16I 0x0003
+#define RP_DEVICE_ID_4Q 0x0004
+#define RP_DEVICE_ID_8O 0x0005
+#define RP_DEVICE_ID_8J 0x0006
+#define RP_DEVICE_ID_4J 0x0007
+#define RP_DEVICE_ID_6M 0x000C
+#define RP_DEVICE_ID_4M 0x000D
+
+/**************************************************************************
+ MUDBAC remapped for PCI
+**************************************************************************/
+
+#define _CFG_INT_PCI 0x40
+#define _PCI_INT_FUNC 0x3A
+
+#define PCI_STROB 0x2000
+#define INTR_EN_PCI 0x0010
+
+/***************************************************************************
+Function: sPCIControllerEOI
+Purpose: Strobe the MUDBAC's End Of Interrupt bit.
+Call: sPCIControllerEOI(CtlP)
+ CONTROLLER_T *CtlP; Ptr to controller structure
+*/
+#define sPCIControllerEOI(CtlP) rp_writeio2(CtlP, 0, _PCI_INT_FUNC, PCI_STROB)
+
+/***************************************************************************
+Function: sPCIGetControllerIntStatus
+Purpose: Get the controller interrupt status
+Call: sPCIGetControllerIntStatus(CtlP)
+ CONTROLLER_T *CtlP; Ptr to controller structure
+Return: Byte_t: The controller interrupt status in the lower 4
+ bits. Bits 0 through 3 represent AIOP's 0
+ through 3 respectively. If a bit is set that
+ AIOP is interrupting. Bits 4 through 7 will
+ always be cleared.
+*/
+#define sPCIGetControllerIntStatus(CTLP) ((rp_readio2(CTLP, 0, _PCI_INT_FUNC) >> 8) & 0x1f)
+
+static devclass_t rp_devclass;
+
+static int rp_pciprobe(device_t dev);
+static int rp_pciattach(device_t dev);
+#if notdef
+static int rp_pcidetach(device_t dev);
+static int rp_pcishutdown(device_t dev);
+#endif /* notdef */
+static void rp_pcireleaseresource(CONTROLLER_t *ctlp);
+static int sPCIInitController( CONTROLLER_t *CtlP,
+ int AiopNum,
+ int IRQNum,
+ Byte_t Frequency,
+ int PeriodicOnly,
+ int VendorDevice);
+static rp_aiop2rid_t rp_pci_aiop2rid;
+static rp_aiop2off_t rp_pci_aiop2off;
+static rp_ctlmask_t rp_pci_ctlmask;
+
+/*
+ * The following functions are the pci-specific part
+ * of rp driver.
+ */
+
+static int
+rp_pciprobe(device_t dev)
+{
+ char *s;
+
+ s = NULL;
+ if ((pci_get_devid(dev) & 0xffff) == RP_VENDOR_ID)
+ s = "RocketPort PCI";
+
+ if (s != NULL) {
+ device_set_desc(dev, s);
+ return (0);
+ }
+
+ return (ENXIO);
+}
+
+static int
+rp_pciattach(device_t dev)
+{
+ int num_ports, num_aiops;
+ int aiop;
+ CONTROLLER_t *ctlp;
+ int unit;
+ int retval;
+ u_int32_t stcmd;
+
+ ctlp = device_get_softc(dev);
+ bzero(ctlp, sizeof(*ctlp));
+ ctlp->dev = dev;
+ unit = device_get_unit(dev);
+ ctlp->aiop2rid = rp_pci_aiop2rid;
+ ctlp->aiop2off = rp_pci_aiop2off;
+ ctlp->ctlmask = rp_pci_ctlmask;
+
+ /* Wake up the device. */
+ stcmd = pci_read_config(dev, PCIR_COMMAND, 4);
+ if ((stcmd & PCIM_CMD_PORTEN) == 0) {
+ stcmd |= (PCIM_CMD_PORTEN);
+ pci_write_config(dev, PCIR_COMMAND, 4, stcmd);
+ }
+
+ /* The IO ports of AIOPs for a PCI controller are continuous. */
+ ctlp->io_num = 1;
+ ctlp->io_rid = malloc(sizeof(*(ctlp->io_rid)) * ctlp->io_num, M_DEVBUF, M_NOWAIT);
+ ctlp->io = malloc(sizeof(*(ctlp->io)) * ctlp->io_num, M_DEVBUF, M_NOWAIT);
+ if (ctlp->io_rid == NULL || ctlp->io == NULL) {
+ device_printf(dev, "rp_pciattach: Out of memory.\n");
+ retval = ENOMEM;
+ goto nogo;
+ }
+ bzero(ctlp->io_rid, sizeof(*(ctlp->io_rid)) * ctlp->io_num);
+ bzero(ctlp->io, sizeof(*(ctlp->io)) * ctlp->io_num);
+
+ ctlp->bus_ctlp = NULL;
+
+ ctlp->io_rid[0] = 0x10;
+ ctlp->io[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], 0, ~0, 1, RF_ACTIVE);
+ if(ctlp->io[0] == NULL) {
+ device_printf(dev, "ioaddr mapping failed for RocketPort(PCI).\n");
+ retval = ENXIO;
+ goto nogo;
+ }
+
+ num_aiops = sPCIInitController(ctlp,
+ MAX_AIOPS_PER_BOARD, 0,
+ FREQ_DIS, 0, (pci_get_devid(dev) >> 16) & 0xffff);
+
+ num_ports = 0;
+ for(aiop=0; aiop < num_aiops; aiop++) {
+ sResetAiopByNum(ctlp, aiop);
+ num_ports += sGetAiopNumChan(ctlp, aiop);
+ }
+
+ retval = rp_attachcommon(ctlp, num_aiops, num_ports);
+ if (retval != 0)
+ goto nogo;
+
+ return (0);
+
+nogo:
+ rp_pcireleaseresource(ctlp);
+
+ return (retval);
+}
+
+#if notdef
+static int
+rp_pcidetach(device_t dev)
+{
+ CONTROLLER_t *ctlp;
+
+ if (device_get_state(dev) == DS_BUSY)
+ return (EBUSY);
+
+ ctlp = device_get_softc(dev);
+
+ rp_pcireleaseresource(ctlp);
+
+ return (0);
+}
+
+static int
+rp_pcishutdown(device_t dev)
+{
+ CONTROLLER_t *ctlp;
+
+ if (device_get_state(dev) == DS_BUSY)
+ return (EBUSY);
+
+ ctlp = device_get_softc(dev);
+
+ rp_pcireleaseresource(ctlp);
+
+ return (0);
+}
+#endif /* notdef */
+
+static void
+rp_pcireleaseresource(CONTROLLER_t *ctlp)
+{
+ rp_releaseresource(ctlp);
+
+ if (ctlp->io != NULL) {
+ if (ctlp->io[0] != NULL)
+ bus_release_resource(ctlp->dev, SYS_RES_IOPORT, ctlp->io_rid[0], ctlp->io[0]);
+ free(ctlp->io, M_DEVBUF);
+ }
+ if (ctlp->io_rid != NULL)
+ free(ctlp->io_rid, M_DEVBUF);
+}
+
+static int
+sPCIInitController( CONTROLLER_t *CtlP,
+ int AiopNum,
+ int IRQNum,
+ Byte_t Frequency,
+ int PeriodicOnly,
+ int VendorDevice)
+{
+ int i;
+
+ CtlP->CtlID = CTLID_0001; /* controller release 1 */
+
+ sPCIControllerEOI(CtlP);
+
+ /* Init AIOPs */
+ CtlP->NumAiop = 0;
+ for(i=0; i < AiopNum; i++)
+ {
+ /*device_printf(CtlP->dev, "aiop %d.\n", i);*/
+ CtlP->AiopID[i] = sReadAiopID(CtlP, i); /* read AIOP ID */
+ /*device_printf(CtlP->dev, "ID = %d.\n", CtlP->AiopID[i]);*/
+ if(CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */
+ {
+ break; /* done looking for AIOPs */
+ }
+
+ switch( VendorDevice ) {
+ case RP_DEVICE_ID_4Q:
+ case RP_DEVICE_ID_4J:
+ case RP_DEVICE_ID_4M:
+ CtlP->AiopNumChan[i] = 4;
+ break;
+ case RP_DEVICE_ID_6M:
+ CtlP->AiopNumChan[i] = 6;
+ break;
+ case RP_DEVICE_ID_8O:
+ case RP_DEVICE_ID_8J:
+ case RP_DEVICE_ID_8I:
+ case RP_DEVICE_ID_16I:
+ case RP_DEVICE_ID_32I:
+ CtlP->AiopNumChan[i] = 8;
+ break;
+ default:
+#if notdef
+ CtlP->AiopNumChan[i] = 8;
+#else
+ CtlP->AiopNumChan[i] = sReadAiopNumChan(CtlP, i);
+#endif /* notdef */
+ break;
+ }
+ /*device_printf(CtlP->dev, "%d channels.\n", CtlP->AiopNumChan[i]);*/
+ rp_writeaiop2(CtlP, i, _INDX_ADDR,_CLK_PRE); /* clock prescaler */
+ /*device_printf(CtlP->dev, "configuring clock prescaler.\n");*/
+ rp_writeaiop1(CtlP, i, _INDX_DATA,CLOCK_PRESC);
+ /*device_printf(CtlP->dev, "configured clock prescaler.\n");*/
+ CtlP->NumAiop++; /* bump count of AIOPs */
+ }
+
+ if(CtlP->NumAiop == 0)
+ return(-1);
+ else
+ return(CtlP->NumAiop);
+}
+
+/*
+ * ARGSUSED
+ * Maps (aiop, offset) to rid.
+ */
+static int
+rp_pci_aiop2rid(int aiop, int offset)
+{
+ /* Always return zero for a PCI controller. */
+ return 0;
+}
+
+/*
+ * ARGSUSED
+ * Maps (aiop, offset) to the offset of resource.
+ */
+static int
+rp_pci_aiop2off(int aiop, int offset)
+{
+ /* Each AIOP reserves 0x40 bytes. */
+ return aiop * 0x40 + offset;
+}
+
+/* Read the int status for a PCI controller. */
+unsigned char
+rp_pci_ctlmask(CONTROLLER_t *ctlp)
+{
+ return sPCIGetControllerIntStatus(ctlp);
+}
+
+static device_method_t rp_pcimethods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, rp_pciprobe),
+ DEVMETHOD(device_attach, rp_pciattach),
+#if notdef
+ DEVMETHOD(device_detach, rp_pcidetach),
+ DEVMETHOD(device_shutdown, rp_pcishutdown),
+#endif /* notdef */
+
+ { 0, 0 }
+};
+
+static driver_t rp_pcidriver = {
+ "rp",
+ rp_pcimethods,
+ sizeof(CONTROLLER_t),
+};
+
+/*
+ * rp can be attached to a pci bus.
+ */
+DRIVER_MODULE(rp, pci, rp_pcidriver, rp_devclass, 0, 0);
diff --git a/sys/dev/rp/rpreg.h b/sys/dev/rp/rpreg.h
index 78fff5e..a7cde1b 100644
--- a/sys/dev/rp/rpreg.h
+++ b/sys/dev/rp/rpreg.h
@@ -45,13 +45,77 @@ typedef unsigned int WordIO_t;
typedef unsigned long DWord_t;
typedef unsigned int DWordIO_t;
-#define sOutB(a, b) outb(a, b)
-#define sOutW(a, b) outw(a, b)
-#define sOutDW(a, b) outl(a, b)
-#define sInB(a) (inb(a))
-#define sInW(a) (inw(a))
-#define sOutStrW(port, addr, count) outsw(port, addr, count)
-#define sInStrW(port, addr, count) insw(port, addr, count)
+#define rp_readio(size, ctlp, rid, offset) \
+ (bus_space_read_##size(rman_get_bustag(ctlp->io[rid]), rman_get_bushandle(ctlp->io[rid]), offset))
+#define rp_readmultiio(size, ctlp, rid, offset, addr, count) \
+ (bus_space_read_multi_##size(rman_get_bustag(ctlp->io[rid]), rman_get_bushandle(ctlp->io[rid]), offset, addr, count))
+#define rp_writeio(size, ctlp, rid, offset, data) \
+ (bus_space_write_##size(rman_get_bustag(ctlp->io[rid]), rman_get_bushandle(ctlp->io[rid]), offset, data))
+#define rp_writemultiio(size, ctlp, rid, offset, addr, count) \
+ (bus_space_write_multi_##size(rman_get_bustag(ctlp->io[rid]), rman_get_bushandle(ctlp->io[rid]), offset, addr, count))
+
+#define rp_readio1(ctlp, rid, offset) rp_readio(1, ctlp, rid, offset)
+#define rp_readio2(ctlp, rid, offset) rp_readio(2, ctlp, rid, offset)
+#define rp_readio4(ctlp, rid, offset) rp_readio(4, ctlp, rid, offset)
+#define rp_writeio1(ctlp, rid, offset, data) rp_writeio(1, ctlp, rid, offset, data)
+#define rp_writeio2(ctlp, rid, offset, data) rp_writeio(2, ctlp, rid, offset, data)
+#define rp_writeio4(ctlp, rid, offset, data) rp_writeio(4, ctlp, rid, offset, data)
+#define rp_readmultiio1(ctlp, rid, offset, addr, count) rp_readmultiio(1, ctlp, rid, offset, addr, count)
+#define rp_readmultiio2(ctlp, rid, offset, addr, count) rp_readmultiio(2, ctlp, rid, offset, addr, count)
+#define rp_readmultiio4(ctlp, rid, offset, addr, count) rp_readmultiio(4, ctlp, rid, offset, addr, count)
+#define rp_writemultiio1(ctlp, rid, offset, addr, count) rp_writemultiio(1, ctlp, rid, offset, addr, count)
+#define rp_writemultiio2(ctlp, rid, offset, addr, count) rp_writemultiio(2, ctlp, rid, offset, addr, count)
+#define rp_writemultiio4(ctlp, rid, offset, addr, count) rp_writemultiio(4, ctlp, rid, offset, addr, count)
+
+#define rp_readaiop1(ctlp, aiop, offset) \
+ (rp_readio1((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset)))
+#define rp_readaiop2(ctlp, aiop, offset) \
+ (rp_readio2((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset)))
+#define rp_readaiop4(ctlp, aiop, offset) \
+ (rp_readio4((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset)))
+#define rp_readmultiaiop1(ctlp, aiop, offset, addr, count) \
+ (rp_readmultiio1((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset), addr, count))
+#define rp_readmultiaiop2(ctlp, aiop, offset, addr, count) \
+ (rp_readmultiio2((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset), addr, count))
+#define rp_readmultiaiop4(ctlp, aiop, offset, addr, count) \
+ (rp_readmultiio4((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset), addr, count))
+#define rp_writeaiop1(ctlp, aiop, offset, data) \
+ (rp_writeio1((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset), data))
+#define rp_writeaiop2(ctlp, aiop, offset, data) \
+ (rp_writeio2((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset), data))
+#define rp_writeaiop4(ctlp, aiop, offset, data) \
+ (rp_writeio4((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset), data))
+#define rp_writemultiaiop1(ctlp, aiop, offset, addr, count) \
+ (rp_writemultiio1((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset), addr, count))
+#define rp_writemultiaiop2(ctlp, aiop, offset, addr, count) \
+ (rp_writemultiio2((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset), addr, count))
+#define rp_writemultiaiop4(ctlp, aiop, offset, addr, count) \
+ (rp_writemultiio4((ctlp), (ctlp)->aiop2rid(aiop, offset), (ctlp)->aiop2off(aiop, offset), addr, count))
+
+#define rp_readch1(chp, offset) \
+ (rp_readaiop1((chp)->CtlP, (chp)->AiopNum, offset))
+#define rp_readch2(chp, offset) \
+ (rp_readaiop2((chp)->CtlP, (chp)->AiopNum, offset))
+#define rp_readch4(chp, offset) \
+ (rp_readaiop4((chp)->CtlP, (chp)->AiopNum, offset))
+#define rp_readmultich1(chp, offset, addr, count) \
+ (rp_readmultiaiop1((chp)->CtlP, (chp)->AiopNum, offset, addr, count))
+#define rp_readmultich2(chp, offset, addr, count) \
+ (rp_readmultiaiop2((chp)->CtlP, (chp)->AiopNum, offset, addr, count))
+#define rp_readmultich4(chp, offset, addr, count) \
+ (rp_readmultiaiop4((chp)->CtlP, (chp)->AiopNum, offset, addr, count))
+#define rp_writech1(chp, offset, data) \
+ (rp_writeaiop1((chp)->CtlP, (chp)->AiopNum, offset, data))
+#define rp_writech2(chp, offset, data) \
+ (rp_writeaiop2((chp)->CtlP, (chp)->AiopNum, offset, data))
+#define rp_writech4(chp, offset, data) \
+ (rp_writeaiop4((chp)->CtlP, (chp)->AiopNum, offset, data))
+#define rp_writemultich1(chp, offset, addr, count) \
+ (rp_writemultiaiop1((chp)->CtlP, (chp)->AiopNum, offset, addr, count))
+#define rp_writemultich2(chp, offset, addr, count) \
+ (rp_writemultiaiop2((chp)->CtlP, (chp)->AiopNum, offset, addr, count))
+#define rp_writemultich4(chp, offset, addr, count) \
+ (rp_writemultiaiop4((chp)->CtlP, (chp)->AiopNum, offset, addr, count))
/*
* End of OS-specific defines
@@ -66,22 +130,10 @@ typedef unsigned int DWordIO_t;
#define MAX_AIOPS_PER_BOARD 4
#define MAX_PORTS_PER_BOARD 32
-/* Bus Type ID */
-#define isISA 0
-#define isPCI 1
-#define isMC 2
-
/* Controller ID numbers */
#define CTLID_NULL -1 /* no controller exists */
#define CTLID_0001 0x0001 /* controller release 1 */
-/* PCI IDs */
-#define RP_VENDOR_ID 0x11FE
-#define RP_DEVICE_ID_8OCTA 0x0001
-#define RP_DEVICE_ID_8INTF 0x0002
-#define RP_DEVICE_ID_16INTF 0x0003
-#define RP_DEVICE_ID_32INTF 0x0004
-
/* AIOP ID numbers, identifies AIOP type implementing channel */
#define AIOPID_NULL -1 /* no AIOP or channel exists */
#define AIOPID_0001 0x0001 /* AIOP release 1 */
@@ -267,16 +319,6 @@ Channel Register Offsets - Indexed - Internal - Fixed
#define INTR_EN 0x08 /* allow interrupts to host */
#define INT_STROB 0x04 /* strobe and clear interrupt line (EOI) */
-/**************************************************************************
- MUDBAC remapped for PCI
-**************************************************************************/
-
-#define _CFG_INT_PCI 0x40
-#define _PCI_INT_FUNC 0x3A
-
-#define PCI_STROB 0x2000
-#define INTR_EN_PCI 0x0010
-
#define CHAN3_EN 0x08 /* enable AIOP 3 */
#define CHAN2_EN 0x04 /* enable AIOP 2 */
#define CHAN1_EN 0x02 /* enable AIOP 1 */
@@ -295,47 +337,61 @@ Channel Register Offsets - Indexed - Internal - Fixed
#define RDATASIZE 72
#define RREGDATASIZE 52
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+struct CONTROLLER_str;
+struct CHANNEL_str;
+
+/* The types of bus-specific methods */
+typedef int rp_aiop2rid_t(int, int);
+typedef int rp_aiop2off_t(int, int);
+typedef unsigned char rp_ctlmask_t(struct CONTROLLER_str *);
+
/* Controller level information structure */
-typedef struct
+struct CONTROLLER_str
{
int CtlID;
- int CtlNum;
- int BusType;
- WordIO_t PCIIO;
- ByteIO_t MBaseIO;
- ByteIO_t MReg1IO;
- ByteIO_t MReg2IO;
- ByteIO_t MReg3IO;
- Byte_t MReg2;
- Byte_t MReg3;
int NumAiop;
- WordIO_t AiopIO[AIOP_CTL_SIZE];
- ByteIO_t AiopIntChanIO[AIOP_CTL_SIZE];
int AiopID[AIOP_CTL_SIZE];
int AiopNumChan[AIOP_CTL_SIZE];
-} CONTROLLER_T;
+ /* Device and resource management */
+ device_t dev; /* device */
+ int io_num; /* Number of IO resources */
+ int *io_rid; /* IO resource IDs */
+ struct resource **io; /* IO resources */
+
+ struct rp_port *rp; /* port */
+ struct tty *tty; /* tty */
+
+ /* Device nodes */
+ dev_t *dev_nodes;
+
+ /* Bus-specific properties */
+ void *bus_ctlp;
+
+ /* Bus-specific methods */
+ rp_aiop2rid_t *aiop2rid; /* (aiop, offset) -> rid */
+ rp_aiop2off_t *aiop2off; /* (aiop, offset) -> off */
+ rp_ctlmask_t *ctlmask; /* Int status */
+};
+typedef struct CONTROLLER_str CONTROLLER_T;
typedef CONTROLLER_T CONTROLLER_t;
/* Channel level information structure */
-typedef struct
+struct CHANNEL_str
{
- CONTROLLER_T *CtlP;
+ CONTROLLER_t *CtlP;
int AiopNum;
int ChanID;
int ChanNum;
- ByteIO_t Cmd;
- ByteIO_t IntChan;
- ByteIO_t IntMask;
- DWordIO_t IndexAddr;
- WordIO_t IndexData;
-
- WordIO_t TxRxData;
- WordIO_t ChanStat;
- WordIO_t TxRxCount;
- ByteIO_t IntID;
-
Word_t TxFIFO;
Word_t TxFIFOPtrs;
Word_t RxFIFO;
@@ -353,11 +409,17 @@ typedef struct
Byte_t TxCompare[4];
Byte_t TxReplace1[4];
Byte_t TxReplace2[4];
-} CHANNEL_T;
+};
+typedef struct CHANNEL_str CHANNEL_T;
typedef CHANNEL_T CHANNEL_t;
typedef CHANNEL_T * CHANPTR_T;
+#define CHNOFF_TXRXDATA(chp) ((chp)->ChanNum * 2 + _TD0)
+#define CHNOFF_CHANSTAT(chp) ((chp)->ChanNum * 2 + _CHN_STAT0)
+#define CHNOFF_TXRXCOUNT(chp) ((chp)->ChanNum * 2 + _FIFO_CNT0)
+#define CHNOFF_INTID(chp) ((chp)->ChanNum + _INT_ID0)
+
/***************************************************************************
Function: sClrBreak
Purpose: Stop sending a transmit BREAK signal
@@ -367,7 +429,7 @@ Call: sClrBreak(ChP)
#define sClrBreak(ChP) \
{ \
(ChP)->TxControl[3] &= ~SETBREAK; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->TxControl[0]); \
}
/***************************************************************************
@@ -379,7 +441,7 @@ Call: sClrDTR(ChP)
#define sClrDTR(ChP) \
{ \
(ChP)->TxControl[3] &= ~SET_DTR; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->TxControl[0]); \
}
/***************************************************************************
@@ -391,7 +453,7 @@ Call: sClrRTS(ChP)
#define sClrRTS(ChP) \
{ \
(ChP)->TxControl[3] &= ~SET_RTS; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->TxControl[0]); \
}
/***************************************************************************
@@ -402,47 +464,8 @@ Call: sClrTxXOFF(ChP)
*/
#define sClrTxXOFF(ChP) \
{ \
- sOutB((ChP)->Cmd,TXOVERIDE | (Byte_t)(ChP)->ChanNum); \
- sOutB((ChP)->Cmd,(Byte_t)(ChP)->ChanNum); \
-}
-
-/***************************************************************************
-Function: sCtlNumToCtlPtr
-Purpose: Convert a controller number to controller structure pointer
-Call: sCtlNumToCtlPtr(CtlNum)
- int CtlNum; Controller number
-Return: CONTROLLER_T *: Ptr to controller structure
-*/
-#define sCtlNumToCtlPtr(CTLNUM) &sController[CTLNUM]
-
-/***************************************************************************
-Function: sControllerEOI
-Purpose: Strobe the MUDBAC's End Of Interrupt bit.
-Call: sControllerEOI(CtlP)
- CONTROLLER_T *CtlP; Ptr to controller structure
-*/
-#define sControllerEOI(CTLP) sOutB((CTLP)->MReg2IO,(CTLP)->MReg2 | INT_STROB)
-
-
-/***************************************************************************
-Function: sPCIControllerEOI
-Purpose: Strobe the MUDBAC's End Of Interrupt bit.
-Call: sPCIControllerEOI(CtlP)
- CONTROLLER_T *CtlP; Ptr to controller structure
-*/
-#define sPCIControllerEOI(CTLP) sOutW((CTLP)->PCIIO, PCI_STROB)
-
-/***************************************************************************
-Function: sDisAiop
-Purpose: Disable I/O access to an AIOP
-Call: sDisAiop(CltP)
- CONTROLLER_T *CtlP; Ptr to controller structure
- int AiopNum; Number of AIOP on controller
-*/
-#define sDisAiop(CTLP,AIOPNUM) \
-{ \
- (CTLP)->MReg3 &= sBitMapClrTbl[AIOPNUM]; \
- sOutB((CTLP)->MReg3IO,(CTLP)->MReg3); \
+ rp_writech1(ChP,_CMD_REG,TXOVERIDE | (Byte_t)(ChP)->ChanNum); \
+ rp_writech1(ChP,_CMD_REG,(Byte_t)(ChP)->ChanNum); \
}
/***************************************************************************
@@ -454,7 +477,7 @@ Call: sDisCTSFlowCtl(ChP)
#define sDisCTSFlowCtl(ChP) \
{ \
(ChP)->TxControl[2] &= ~CTSFC_EN; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->TxControl[0]); \
}
/***************************************************************************
@@ -468,7 +491,7 @@ Comments: Function sSetParity() can be used in place of functions sEnParity(),
#define sDisParity(ChP) \
{ \
(ChP)->TxControl[2] &= ~PARITY_EN; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->TxControl[0]); \
}
/***************************************************************************
@@ -480,7 +503,7 @@ Call: sDisRxFIFO(ChP)
#define sDisRxFIFO(ChP) \
{ \
(ChP)->R[0x32] = 0x0a; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0x30]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->R[0x30]); \
}
/***************************************************************************
@@ -492,7 +515,7 @@ Comments: This takes the channel out of the receive status mode. All
subsequent reads of receive data using sReadRxWord() will return
two data bytes.
*/
-#define sDisRxStatusMode(ChP) sOutW((ChP)->ChanStat,0)
+#define sDisRxStatusMode(ChP) rp_writech2(ChP,CHNOFF_CHANSTAT(ChP),0)
/***************************************************************************
Function: sDisTransmit
@@ -507,7 +530,7 @@ Call: sDisTransmit(ChP)
#define sDisTransmit(ChP) \
{ \
(ChP)->TxControl[3] &= ~TX_ENABLE; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->TxControl[0]); \
}
/***************************************************************************
@@ -519,20 +542,7 @@ Call: sDisTxSoftFlowCtl(ChP)
#define sDisTxSoftFlowCtl(ChP) \
{ \
(ChP)->R[0x06] = 0x8a; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0x04]); \
-}
-
-/***************************************************************************
-Function: sEnAiop
-Purpose: Enable I/O access to an AIOP
-Call: sEnAiop(CltP)
- CONTROLLER_T *CtlP; Ptr to controller structure
- int AiopNum; Number of AIOP on controller
-*/
-#define sEnAiop(CTLP,AIOPNUM) \
-{ \
- (CTLP)->MReg3 |= sBitMapSetTbl[AIOPNUM]; \
- sOutB((CTLP)->MReg3IO,(CTLP)->MReg3); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->R[0x04]); \
}
/***************************************************************************
@@ -544,7 +554,7 @@ Call: sEnCTSFlowCtl(ChP)
#define sEnCTSFlowCtl(ChP) \
{ \
(ChP)->TxControl[2] |= CTSFC_EN; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->TxControl[0]); \
}
/***************************************************************************
@@ -561,7 +571,7 @@ Warnings: Before enabling parity odd or even parity should be chosen using
#define sEnParity(ChP) \
{ \
(ChP)->TxControl[2] |= PARITY_EN; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->TxControl[0]); \
}
/***************************************************************************
@@ -572,9 +582,9 @@ Return: void
{ \
(ChP)->TxControl[2] &= ~RTSTOG_EN; \
(ChP)->TxControl[3] &= ~SET_RTS; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->TxControl[0]); \
(ChP)->RxControl[2] |= RTSFC_EN; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->RxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->RxControl[0]); \
}
/***************************************************************************
@@ -584,7 +594,7 @@ Return: void
#define sDisRTSFlowCtl(ChP) \
{ \
(ChP)->RxControl[2] &= ~RTSFC_EN; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->RxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->RxControl[0]); \
}
/***************************************************************************
@@ -596,7 +606,7 @@ Call: sEnRxFIFO(ChP)
#define sEnRxFIFO(ChP) \
{ \
(ChP)->R[0x32] = 0x08; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0x30]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->R[0x30]); \
}
/***************************************************************************
@@ -617,7 +627,7 @@ Warnings: This function must be called after valid microcode has been
#define sEnRxProcessor(ChP) \
{ \
(ChP)->RxControl[2] |= RXPROC_EN; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->RxControl[0]); \
+ rp_writech2(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->RxControl[0]); \
}
/***************************************************************************
@@ -630,7 +640,7 @@ Comments: This places the channel in the receive status mode. All subsequent
in the low word and a status byte in the high word.
*/
-#define sEnRxStatusMode(ChP) sOutW((ChP)->ChanStat,STATMODE)
+#define sEnRxStatusMode(ChP) rp_writech2(ChP,CHNOFF_CHANSTAT(ChP),STATMODE)
/***************************************************************************
Function: sEnTransmit
@@ -641,7 +651,7 @@ Call: sEnTransmit(ChP)
#define sEnTransmit(ChP) \
{ \
(ChP)->TxControl[3] |= TX_ENABLE; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->TxControl[0]); \
}
/***************************************************************************
@@ -654,7 +664,7 @@ Return: Byte_t: The AIOP interrupt status. Bits 0 through 7
represent channels 0 through 7 respectively. If a
bit is set that channel is interrupting.
*/
-#define sGetAiopIntStatus(CTLP,AIOPNUM) sInB((CTLP)->AiopIntChanIO[AIOPNUM])
+#define sGetAiopIntStatus(CtlP,AIOPNUM) rp_readaiop1(CtlP,AIOPNUM,_INT_CHAN)
/***************************************************************************
Function: sGetAiopNumChan
@@ -664,7 +674,7 @@ Call: sGetAiopNumChan(CtlP,AiopNum)
int AiopNum; AIOP number
Return: int: The number of channels supported by the AIOP
*/
-#define sGetAiopNumChan(CTLP,AIOPNUM) (CTLP)->AiopNumChan[AIOPNUM]
+#define sGetAiopNumChan(CtlP,AIOPNUM) CtlP->AiopNumChan[AIOPNUM]
/***************************************************************************
Function: sGetChanIntID
@@ -680,7 +690,7 @@ Return: Byte_t: The channel interrupt ID. Can be any
DELTA_CTS: CTS change interrupt
DELTA_DSR: DSR change interrupt
*/
-#define sGetChanIntID(ChP) (sInB((ChP)->IntID) & (RXF_TRIG | TXFIFO_MT | SRC_INT | DELTA_CD | DELTA_CTS | DELTA_DSR))
+#define sGetChanIntID(ChP) (rp_readch1(ChP,(ChP)->ChanNum+_INT_ID0) & (RXF_TRIG | TXFIFO_MT | SRC_INT | DELTA_CD | DELTA_CTS | DELTA_DSR))
/***************************************************************************
Function: sGetChanNum
@@ -718,7 +728,7 @@ Return: Word_t: The channel status. Can be any combination of
Warnings: This function will clear the high byte flags in the Channel
Status Register.
*/
-#define sGetChanStatus(ChP) sInW((ChP)->ChanStat)
+#define sGetChanStatus(ChP) rp_readch2(ChP,CHNOFF_CHANSTAT(ChP))
/***************************************************************************
Function: sGetChanStatusLo
@@ -734,33 +744,7 @@ Return: Byte_t: The channel status low byte. Can be any combination
TXSHRMT: Tx shift register is empty
RDA: Rx data available
*/
-#define sGetChanStatusLo(ChP) sInB((ByteIO_t)(ChP)->ChanStat)
-
-/***************************************************************************
-Function: sGetControllerIntStatus
-Purpose: Get the controller interrupt status
-Call: sGetControllerIntStatus(CtlP)
- CONTROLLER_T *CtlP; Ptr to controller structure
-Return: Byte_t: The controller interrupt status in the lower 4
- bits. Bits 0 through 3 represent AIOP's 0
- through 3 respectively. If a bit is set that
- AIOP is interrupting. Bits 4 through 7 will
- always be cleared.
-*/
-#define sGetControllerIntStatus(CTLP) (sInB((CTLP)->MReg1IO) & 0x0f)
-
-/***************************************************************************
-Function: sPCIGetControllerIntStatus
-Purpose: Get the controller interrupt status
-Call: sPCIGetControllerIntStatus(CtlP)
- CONTROLLER_T *CtlP; Ptr to controller structure
-Return: Byte_t: The controller interrupt status in the lower 4
- bits. Bits 0 through 3 represent AIOP's 0
- through 3 respectively. If a bit is set that
- AIOP is interrupting. Bits 4 through 7 will
- always be cleared.
-*/
-#define sPCIGetControllerIntStatus(CTLP) ((sInW((CTLP)->PCIIO) >> 8) & 0x1f)
+#define sGetChanStatusLo(ChP) rp_readch1(ChP,CHNOFF_CHANSTAT(ChP))
/***************************************************************************
Function: sGetRxCnt
@@ -771,7 +755,7 @@ Return: int: The number of data bytes in the Rx FIFO.
Comments: Byte read of count register is required to obtain Rx count.
*/
-#define sGetRxCnt(ChP) sInW((ChP)->TxRxCount)
+#define sGetRxCnt(ChP) rp_readch2(ChP,CHNOFF_TXRXCOUNT(ChP))
/***************************************************************************
Function: sGetTxCnt
@@ -782,16 +766,16 @@ Return: Byte_t: The number of data bytes in the Tx FIFO.
Comments: Byte read of count register is required to obtain Tx count.
*/
-#define sGetTxCnt(ChP) sInB((ByteIO_t)(ChP)->TxRxCount)
+#define sGetTxCnt(ChP) rp_readch1(ChP,CHNOFF_TXRXCOUNT(ChP))
/*****************************************************************************
Function: sGetTxRxDataIO
-Purpose: Get the I/O address of a channel's TxRx Data register
+Purpose: Get the offset of a channel's TxRx Data register
Call: sGetTxRxDataIO(ChP)
CHANNEL_T *ChP; Ptr to channel structure
-Return: WordIO_t: I/O address of a channel's TxRx Data register
+Return: WordIO_t: offset of a channel's TxRx Data register
*/
-#define sGetTxRxDataIO(ChP) (ChP)->TxRxData
+#define sGetTxRxDataIO(ChP) CHNOFF_TXRXDATA(ChP)
/***************************************************************************
Function: sInitChanDefaults
@@ -819,8 +803,8 @@ Call: sResetAiopByNum(CTLP,AIOPNUM)
*/
#define sResetAiopByNum(CTLP,AIOPNUM) \
{ \
- sOutB((CTLP)->AiopIO[(AIOPNUM)]+_CMD_REG,RESET_ALL); \
- sOutB((CTLP)->AiopIO[(AIOPNUM)]+_CMD_REG,0x0); \
+ rp_writeaiop1(CTLP,AIOPNUM,_CMD_REG,RESET_ALL); \
+ rp_writeaiop1(CTLP,AIOPNUM,_CMD_REG,0x0); \
}
/***************************************************************************
@@ -832,7 +816,7 @@ Call: sSendBreak(ChP)
#define sSendBreak(ChP) \
{ \
(ChP)->TxControl[3] |= SETBREAK; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->TxControl[0]); \
}
/***************************************************************************
@@ -846,7 +830,7 @@ Call: sSetBaud(ChP,Divisor)
{ \
(ChP)->BaudDiv[2] = (Byte_t)(DIVISOR); \
(ChP)->BaudDiv[3] = (Byte_t)((DIVISOR) >> 8); \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->BaudDiv[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->BaudDiv[0]); \
}
/***************************************************************************
@@ -858,7 +842,7 @@ Call: sSetData7(ChP)
#define sSetData7(ChP) \
{ \
(ChP)->TxControl[2] &= ~DATA8BIT; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->TxControl[0]); \
}
/***************************************************************************
@@ -870,7 +854,7 @@ Call: sSetData8(ChP)
#define sSetData8(ChP) \
{ \
(ChP)->TxControl[2] |= DATA8BIT; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->TxControl[0]); \
}
/***************************************************************************
@@ -882,7 +866,7 @@ Call: sSetDTR(ChP)
#define sSetDTR(ChP) \
{ \
(ChP)->TxControl[3] |= SET_DTR; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->TxControl[0]); \
}
/***************************************************************************
@@ -899,7 +883,7 @@ Warnings: This function has no effect unless parity is enabled with function
#define sSetEvenParity(ChP) \
{ \
(ChP)->TxControl[2] |= EVEN_PAR; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->TxControl[0]); \
}
/***************************************************************************
@@ -916,7 +900,7 @@ Warnings: This function has no effect unless parity is enabled with function
#define sSetOddParity(ChP) \
{ \
(ChP)->TxControl[2] &= ~EVEN_PAR; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->TxControl[0]); \
}
/***************************************************************************
@@ -928,7 +912,7 @@ Call: sSetRTS(ChP)
#define sSetRTS(ChP) \
{ \
(ChP)->TxControl[3] |= SET_RTS; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->TxControl[0]); \
}
/***************************************************************************
@@ -954,7 +938,7 @@ Comments: An interrupt will be generated when the trigger level is reached
{ \
(ChP)->RxControl[2] &= ~TRIG_MASK; \
(ChP)->RxControl[2] |= LEVEL; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->RxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->RxControl[0]); \
}
/***************************************************************************
@@ -966,7 +950,7 @@ Call: sSetStop1(ChP)
#define sSetStop1(ChP) \
{ \
(ChP)->TxControl[2] &= ~STOP2; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->TxControl[0]); \
}
/***************************************************************************
@@ -978,7 +962,7 @@ Call: sSetStop2(ChP)
#define sSetStop2(ChP) \
{ \
(ChP)->TxControl[2] |= STOP2; \
- sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+ rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->TxControl[0]); \
}
/***************************************************************************
@@ -991,38 +975,22 @@ Comments: This function is used to start a Rx processor after it was
will restart both the Rx processor and software input flow control.
*/
-#define sStartRxProcessor(ChP) sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0])
+#define sStartRxProcessor(ChP) rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&(ChP)->R[0])
/***************************************************************************
Function: sWriteTxByte
Purpose: Write a transmit data byte to a channel.
+ CHANNEL_T *ChP; Ptr to channel structure
ByteIO_t io: Channel transmit register I/O address. This can
be obtained with sGetTxRxDataIO().
Byte_t Data; The transmit data byte.
Warnings: This function writes the data byte without checking to see if
sMaxTxSize is exceeded in the Tx FIFO.
*/
-#define sWriteTxByte(IO,DATA) sOutB(IO,DATA)
-
-int sInitController( CONTROLLER_T *CtlP,
- int CtlNum,
- ByteIO_t MudbacIO,
- ByteIO_t *AiopIOList,
- int AiopIOListSize,
- int IRQNum,
- Byte_t Frequency,
- int PeriodicOnly);
-
-int sPCIInitController( CONTROLLER_T *CtlP,
- int CtlNum,
- ByteIO_t *AiopIOList,
- int AiopIOListSize,
- int IRQNum,
- Byte_t Frequency,
- int PeriodicOnly);
-
-int sReadAiopID(ByteIO_t io);
-int sReadAiopNumChan(WordIO_t io);
+#define sWriteTxByte(ChP,IO,DATA) rp_writech1(ChP,IO,DATA)
+
+int sReadAiopID(CONTROLLER_T *CtlP, int aiop);
+int sReadAiopNumChan(CONTROLLER_T *CtlP, int aiop);
int sInitChan( CONTROLLER_T *CtlP,
CHANNEL_T *ChP,
int AiopNum,
@@ -1035,11 +1003,13 @@ void sFlushTxFIFO(CHANNEL_T *ChP);
int sWriteTxPrioByte(CHANNEL_T *ChP, Byte_t Data);
void sEnInterrupts(CHANNEL_T *ChP,Word_t Flags);
void sDisInterrupts(CHANNEL_T *ChP,Word_t Flags);
+int rp_attachcommon(CONTROLLER_T *ctlp, int num_aiops, int num_ports);
+void rp_releaseresource(CONTROLLER_t *ctlp);
#ifndef ROCKET_C
extern Byte_t R[RDATASIZE];
extern CONTROLLER_T sController[CTL_SIZE];
extern Byte_t sIRQMap[16];
-extern Byte_t sBitMapClrTbl[8];
-extern Byte_t sBitMapSetTbl[8];
#endif
+extern Byte_t rp_sBitMapClrTbl[8];
+extern Byte_t rp_sBitMapSetTbl[8];
diff --git a/sys/dev/rp/rpvar.h b/sys/dev/rp/rpvar.h
index a8ca662..ec469f1 100644
--- a/sys/dev/rp/rpvar.h
+++ b/sys/dev/rp/rpvar.h
@@ -77,16 +77,8 @@ struct rp_port {
int rp_xmit_stopped:1;
CONTROLLER_t * rp_ctlp;
CHANNEL_t rp_channel;
+ unsigned char TxBuf[TXFIFO_SIZE];
+ unsigned char RxBuf[RXFIFO_SIZE];
};
-struct termios deftermios = {
- TTYDEF_IFLAG,
- TTYDEF_OFLAG,
- TTYDEF_CFLAG,
- TTYDEF_LFLAG,
- { CEOF, CEOL, CEOL, CERASE, CWERASE, CKILL, CREPRINT,
- _POSIX_VDISABLE, CINTR, CQUIT, CSUSP, CDSUSP, CSTART, CSTOP, CLNEXT,
- CDISCARD, CMIN, CTIME, CSTATUS, _POSIX_VDISABLE },
- TTYDEF_SPEED,
- TTYDEF_SPEED
-};
+extern struct termios deftermios;
OpenPOWER on IntegriCloud