mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-30 10:52:50 +00:00
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:
parent
6fba331424
commit
1f82d2d70d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=61541
24
etc/MAKEDEV
24
etc/MAKEDEV
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
876
sys/dev/rp/rp.c
876
sys/dev/rp/rp.c
File diff suppressed because it is too large
Load Diff
506
sys/dev/rp/rp_isa.c
Normal file
506
sys/dev/rp/rp_isa.c
Normal 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
371
sys/dev/rp/rp_pci.c
Normal 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);
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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
7
sys/modules/rp/Makefile
Normal 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>
|
Loading…
Reference in New Issue
Block a user