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.
This commit is contained in:
Seigo Tanimura 2000-06-11 06:43:16 +00:00
parent 6fba331424
commit 1f82d2d70d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=61541
11 changed files with 1381 additions and 814 deletions

View File

@ -1201,9 +1201,9 @@ ttyR?)
MINOR=$(($BOARD * 65536))
controllers=$(
dmesg | while read first rest; do
case "\$first" in
case "$first" in
RocketPort[0-4])
echo "\$first"
echo "$first"
;;
esac
done
@ -1212,9 +1212,9 @@ ttyR?)
for i in $controllers; do
ndevices=$(
dmesg | while read first bar ports rest; do
case "\$first" in
case "$first" in
$i*)
echo "\$ports"
echo "$ports"
;;
esac
done
@ -1223,8 +1223,8 @@ ttyR?)
dev=0
while [ $dev -lt $ndevices ]; do
mknod /dev/ttyR$Rnum c $major $MINOR
mknod /dev/ttylR$Rnum c $major $(($MINOR + 32))
mknod /dev/ttyiR$Rnum c $major $(($MINOR + 64))
mknod /dev/ttyiR$Rnum c $major $(($MINOR + 32))
mknod /dev/ttylR$Rnum c $major $(($MINOR + 64))
Rnum=$(($Rnum + 1))
MINOR=$(($MINOR + 1))
dev=$(($dev + 1))
@ -1241,9 +1241,9 @@ cuaR?)
MINOR=$(($BOARD * 65536))
controllers=$(
dmesg | while read first rest; do
case "\$first" in
case "$first" in
RocketPort[0-4])
echo "\$first"
echo "$first"
;;
esac
done
@ -1252,9 +1252,9 @@ cuaR?)
for i in $controllers; do
ndevices=$(
dmesg | while read first bar ports rest; do
case "\$first" in
case "$first" in
$i*)
echo "\$ports"
echo "$ports"
;;
esac
done
@ -1263,9 +1263,9 @@ cuaR?)
dev=0
while [ $dev -lt $ndevices ]; do
mknod /dev/cuaR$Rnum c $major $(($MINOR + 128)) uucp:dialer
mknod /dev/cualR$Rnum c $major $(($MINOR + 128 + 32)) \
mknod /dev/cuaiR$Rnum c $major $(($MINOR + 128 + 32)) \
uucp:dialer
mknod /dev/cuaiR$Rnum c $major $(($MINOR + 128 + 64)) \
mknod /dev/cualR$Rnum c $major $(($MINOR + 128 + 64)) \
uucp:dialer
Rnum=$(($Rnum + 1))
MINOR=$(($MINOR + 1))

View File

@ -223,6 +223,9 @@ dev/ppbus/ppi.c optional ppi
dev/ppbus/pps.c optional pps
dev/ppbus/vpo.c optional vpo
dev/ppbus/vpoio.c optional vpo
dev/rp/rp.c optional rp
dev/rp/rp_isa.c optional rp isa
dev/rp/rp_pci.c optional rp pci
dev/si/si.c optional si
dev/si/si2_z280.c optional si
dev/si/si3_t225.c optional si

View File

@ -239,7 +239,7 @@ i386/isa/pcvt/pcvt_sup.c optional vt
i386/isa/pcvt/pcvt_vtf.c optional vt
i386/isa/prof_machdep.c optional profiling-routine
i386/isa/rc.c count rc
i386/isa/rp.c optional rp
#i386/isa/rp.c optional rp
i386/isa/scd.c count scd
i386/isa/sound/ad1848.c optional css
i386/isa/sound/ad1848.c optional gus

File diff suppressed because it is too large Load Diff

506
sys/dev/rp/rp_isa.c Normal file
View File

@ -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);

371
sys/dev/rp/rp_pci.c Normal file
View File

@ -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);

View File

@ -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)
#define sWriteTxByte(ChP,IO,DATA) rp_writech1(ChP,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);
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];

View File

@ -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;

View File

@ -1297,6 +1297,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;
@ -1630,7 +1632,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;
@ -1747,14 +1749,14 @@ 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,
{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
};

View File

@ -5,7 +5,7 @@
SUBDIR= agp aha amr an aue ccd cd9660 coda cue dc fdesc fxp if_disc if_ef if_ppp \
if_sl if_tun ipfilter ipfw joy kernfs kue \
md mfs mii mlx msdos ncp netgraph nfs ntfs nullfs \
nwfs portal procfs rl sf sis sk ste syscons ti tl twe tx \
nwfs portal procfs rl rp sf sis sk ste syscons ti tl twe tx \
udbp ugen uhid ukbd ulpt umapfs umass umodem ums union urio usb \
vinum vn vpo vr wb xl

7
sys/modules/rp/Makefile Normal file
View File

@ -0,0 +1,7 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../dev/rp
KMOD = rp
SRCS = rp.c rp_pci.c device_if.h bus_if.h pci_if.h
.include <bsd.kmod.mk>