Karl Denninger
2006-Sep-07 14:01 UTC
Comtrol Rocketport driver is severely hosed under 6.x-STABLE
There is a severe problem (or set of problmes) with the Comtrol Rocketport driver under FreeBSD 6.x, to the point that the driver is basically unusable. The driver is returning duplicate input frames and otherwise misbehaving badly. There were no problems under FreeBSD 5.x. Does anyone know what has changed in the tty subsystem between 5.x and 6.x, or, alternatively if there is no update on this, is there a KNOWN WORKING PROPERLY multiport serial board under 6.x? This has totally hosed a number of my field installations when they attempted to go from the 5.x operating environment to 6.x! Thanks in advance.... -- -- Karl Denninger (karl@denninger.net) Internet Consultant & Kids Rights Activist http://www.denninger.net My home on the net - links to everything I do! http://scubaforum.org Your UNCENSORED place to talk about DIVING! http://genesis3.blogspot.com Musings Of A Sentient Mind
Doug Ambrisko
2006-Sep-07 18:22 UTC
Comtrol Rocketport driver is severely hosed under 6.x-STABLE
Karl Denninger writes: | | There is a severe problem (or set of problmes) with the Comtrol Rocketport | driver under FreeBSD 6.x, to the point that the driver is basically unusable. | | The driver is returning duplicate input frames and otherwise misbehaving | badly. There were no problems under FreeBSD 5.x. | | Does anyone know what has changed in the tty subsystem between 5.x and 6.x, | or, alternatively if there is no update on this, is there a KNOWN WORKING | PROPERLY multiport serial board under 6.x? | | This has totally hosed a number of my field installations when they attempted | to go from the 5.x operating environment to 6.x! | | Thanks in advance.... Try this for 6.1 in /sys/dev/rp: Index: rp.c ==================================================================RCS file: /usr/local/cvsroot/freebsd/src/sys/dev/rp/rp.c,v retrieving revision 1.67.2.1 diff -u -p -r1.67.2.1 rp.c --- rp.c 8 Nov 2005 15:35:27 -0000 1.67.2.1 +++ rp.c 7 Sep 2006 18:19:44 -0000 @@ -37,15 +37,18 @@ __FBSDID("$FreeBSD: src/sys/dev/rp/rp.c, /* * rp.c - for RocketPort FreeBSD */ +#include <sys/cdefs.h> #include "opt_compat.h" #include <sys/param.h> +#include <sys/proc.h> #include <sys/systm.h> #include <sys/fcntl.h> #include <sys/malloc.h> #include <sys/serial.h> #include <sys/tty.h> +#include <sys/dkstat.h> #include <sys/conf.h> #include <sys/kernel.h> #include <machine/resource.h> @@ -57,7 +60,7 @@ __FBSDID("$FreeBSD: src/sys/dev/rp/rp.c, #include <dev/rp/rpreg.h> #include <dev/rp/rpvar.h> -static const char RocketPortVersion[] = "3.02"; +static const char RocketPortVersion[] = "1.0"; static Byte_t RData[RDATASIZE] { @@ -116,6 +119,8 @@ Byte_t rp_sBitMapSetTbl[8] 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 }; +int next_unit_number = 0; +int num_devices_found = 0; /*************************************************************************** Function: sReadAiopID Purpose: Read the AIOP idenfication number directly from an AIOP. @@ -587,6 +592,9 @@ static void rp_do_receive(struct rp_port unsigned int CharNStat; int ToRecv, wRecv, ch, ttynocopy; + if (tp->t_state & TS_TBLOCK) + return; + ToRecv = sGetRxCnt(cp); if(ToRecv == 0) return; @@ -615,7 +623,7 @@ static void rp_do_receive(struct rp_port CharNStat = rp_readch2(cp,sGetTxRxDataIO(cp)); ch = CharNStat & 0xff; - if((CharNStat & STMBREAK) || (CharNStat & STMFRAMEH)) + if((CharNStat & STMBREAKH) || (CharNStat & STMFRAMEH)) ch |= TTY_FE; else if (CharNStat & STMPARITYH) ch |= TTY_PE; @@ -645,6 +653,12 @@ static void rp_do_receive(struct rp_port if ( ToRecv > RXFIFO_SIZE ) { ToRecv = RXFIFO_SIZE; } + if ((tp->t_rawq.c_cc + ToRecv > tp->t_ihiwat) && + ((tp->t_cflag & CRTS_IFLOW) || + (tp->t_iflag & IXOFF)) && + !(tp->t_state & TS_TBLOCK)) + ttyblock(tp); + wRecv = ToRecv >> 1; if ( wRecv ) { rp_readmultich2(cp,sGetTxRxDataIO(cp),(u_int16_t *)rp->RxBuf,wRecv); @@ -686,6 +700,7 @@ static void rp_handle_port(struct rp_por IntMask = sGetChanIntID(cp); IntMask = IntMask & rp->rp_intmask; ChanStatus = sGetChanStatus(cp); + if(IntMask & RXF_TRIG) if(!(tp->t_state & TS_TBLOCK) && (tp->t_state & TS_CARR_ON) && (tp->t_state & TS_ISOPEN)) { rp_do_receive(rp, tp, cp, ChanStatus); @@ -769,22 +784,23 @@ rp_attachcommon(CONTROLLER_T *ctlp, int unit = device_get_unit(ctlp->dev); - printf("RocketPort%d (Version %s) %d ports.\n", unit, - RocketPortVersion, num_ports); + printf("RocketPort%d = %d ports.\n", unit, num_ports); rp_num_ports[unit] = num_ports; callout_handle_init(&rp_callout_handle); ctlp->rp = rp = (struct rp_port *) - malloc(sizeof(struct rp_port) * num_ports, M_TTYS, M_NOWAIT | M_ZERO); + malloc(sizeof(struct rp_port) * (num_ports+1), M_TTYS, M_NOWAIT | M_ZERO); if (rp == NULL) { device_printf(ctlp->dev, "rp_attachcommon: Could not malloc rp_ports structures.\n"); retval = ENOMEM; goto nogo; } - +/* else { + device_printf(ctlp->dev, "malloc'd rp_ports structures=%08x.\n", rp); + }*/ count = unit * 32; /* board times max ports per card SG */ - bzero(rp, sizeof(struct rp_port) * num_ports); + bzero(rp, sizeof(struct rp_port) * (num_ports+1)); oldspl = spltty(); rp_addr(unit) = rp; splx(oldspl); @@ -1016,9 +1032,10 @@ rpmodem(struct tty *tp, int sigon, int s } return (0); } - +#define B460800 460800 +#define B921600 921600 static struct speedtab baud_table[] = { - {B0, 0}, {B50, BRD50}, {B75, BRD75}, + {B0, BRD0}, {B50, BRD50}, {B75, BRD75}, {B110, BRD110}, {B134, BRD134}, {B150, BRD150}, {B200, BRD200}, {B300, BRD300}, {B600, BRD600}, {B1200, BRD1200}, {B1800, BRD1800}, {B2400, BRD2400}, @@ -1028,7 +1045,19 @@ static struct speedtab baud_table[] = { {B115200, BRD115200}, {B230400, BRD230400}, {-1, -1} }; - +#ifdef DJA +static struct speedtab ab_baud_table[] = { + {B0, AB_BRD0}, {B50, AB_BRD50}, {B75, AB_BRD75}, + {B110, AB_BRD110}, {B134, AB_BRD134}, {B150, AB_BRD150}, + {B200, AB_BRD200}, {B300, AB_BRD300}, {B600, AB_BRD600}, + {B1200, AB_BRD1200}, {B1800, AB_BRD1800}, {B2400, AB_BRD2400}, + {B4800, AB_BRD4800}, {B9600, AB_BRD9600}, {B19200, AB_BRD19200}, + {B38400, AB_BRD38400}, {B7200, AB_BRD7200}, {B14400, AB_BRD14400}, + {B57600, AB_BRD57600}, {B76800, AB_BRD76800}, {B115200, AB_BRD115200}, + {B230400,AB_BRD230400}, {B460800,AB_BRD460800}, {B921600, AB_BRD921600}, + {-1, -1} +}; +#endif static int rpparam(tp, t) struct tty *tp; @@ -1042,7 +1071,6 @@ rpparam(tp, t) int devshift; #endif - rp = tp->t_sc; cp = &rp->rp_channel; oldspl = spltty(); @@ -1059,7 +1087,12 @@ rpparam(tp, t) oflag = t->c_oflag; lflag = t->c_lflag; - ospeed = ttspeedtab(t->c_ispeed, baud_table); +#if DJA + if (cardIsRocketportPlus(ctl->dev)) + ospeed = ttspeedtab(t->c_ispeed, ab_baud_table); + else +#endif + ospeed = ttspeedtab(t->c_ispeed, baud_table); if(ospeed < 0 || t->c_ispeed != t->c_ospeed) return(EINVAL); Index: rp_isa.c ==================================================================RCS file: /usr/local/cvsroot/freebsd/src/sys/dev/rp/rp_isa.c,v retrieving revision 1.7 diff -u -p -r1.7 rp_isa.c --- rp_isa.c 6 Jan 2005 01:43:11 -0000 1.7 +++ rp_isa.c 7 Sep 2006 18:19:44 -0000 @@ -63,8 +63,8 @@ struct ISACONTROLLER_T { 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; + unsigned char MReg2; + unsigned char MReg3; }; typedef struct ISACONTROLLER_T ISACONTROLLER_t; @@ -140,6 +140,12 @@ static rp_aiop2rid_t rp_isa_aiop2rid; static rp_aiop2off_t rp_isa_aiop2off; static rp_ctlmask_t rp_isa_ctlmask; +/* +struct isa_driver rpdriver = { + rpprobe, rpattach, "rp" + }; +*/ + static int rp_probe(device_t dev) { @@ -149,6 +155,9 @@ rp_probe(device_t dev) CONTROLLER_t *ctlp; int retval; + if (num_devices_found >= 4) + return (ENXIO); + /* * We have no PnP RocketPort cards. * (At least according to LINT) @@ -156,8 +165,8 @@ rp_probe(device_t dev) 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) + /* We need IO port resource to configure an ISA device. */ + if (bus_get_resource_start(dev, SYS_RES_IOPORT, 0) == 0) return (ENXIO); unit = device_get_unit(dev); @@ -176,20 +185,23 @@ rp_probe(device_t dev) /* 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 | M_ZERO); - ctlp->io = malloc(sizeof(*(ctlp->io)) * MAX_AIOPS_PER_BOARD, M_DEVBUF, M_NOWAIT | M_ZERO); + ctlp->io_rid = malloc(sizeof(*(ctlp->io_rid)) * MAX_AIOPS_PER_BOARD, M_DEVBUF, M_NOWAIT/* | M_ZERO*/); + ctlp->io = malloc(sizeof(*(ctlp->io)) * MAX_AIOPS_PER_BOARD, M_DEVBUF, M_NOWAIT/* | M_ZERO*/); 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 | M_ZERO); + ctlp->bus_ctlp = malloc(sizeof(ISACONTROLLER_t) * 1, M_DEVBUF, M_NOWAIT/* | M_ZERO*/); 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) { @@ -218,6 +230,7 @@ rp_probe(device_t dev) if (rp_controller == NULL) rp_controller = controller; rp_nisadevs++; + num_devices_found++; device_set_desc(dev, "RocketPort ISA"); @@ -416,7 +429,7 @@ sInitController( CONTROLLER_T *CtlP, CtlP->NumAiop = 0; for(i=0; i < AiopNum; i++) { - if (CtlP->io[i] == NULL) { + if (i > 0 /*CtlP->io[i] == NULL*/) { CtlP->io_rid[i] = i; aiop_base = rman_get_start(CtlP->io[0]) + 0x400 * i; if (rp_nisadevs == 0) Index: rp_pci.c ==================================================================RCS file: /usr/local/cvsroot/freebsd/src/sys/dev/rp/rp_pci.c,v retrieving revision 1.11.2.1 diff -u -p -r1.11.2.1 rp_pci.c --- rp_pci.c 14 Feb 2006 23:09:10 -0000 1.11.2.1 +++ rp_pci.c 7 Sep 2006 18:19:44 -0000 @@ -67,8 +67,19 @@ __FBSDID("$FreeBSD: src/sys/dev/rp/rp_pc #define RP_DEVICE_ID_4J 0x0007 #define RP_DEVICE_ID_6M 0x000C #define RP_DEVICE_ID_4M 0x000D -#define RP_DEVICE_ID_UPCI_32 0x0801 -#define RP_DEVICE_ID_UPCI_8O 0x0805 +#define RP_DEVICE_ID_PL4 0x000A +#define RP_DEVICE_ID_PL8 0x000B +#define RP_DEVICE_ID_PL2 0x000E +#define RP_DEVICE_ID_U32 0x0801 +#define RP_DEVICE_ID_U8PL 0x0802 +#define RP_DEVICE_ID_U16 0x0803 +#define RP_DEVICE_ID_U8QO 0x0805 +#define RP_DEVICE_ID_UP8QO 0x080B +#define RP_DEVICE_ID_UP2 0x080E +#define RP_DEVICE_ID_UP2SMPTE 0x080F +#define RP_DEVICE_ID_UP4J 0x0810 +#define RP_DEVICE_ID_UP8J 0x0811 +#define RP_DEVICE_ID_UP422QO 0x0812 /************************************************************************** MUDBAC remapped for PCI @@ -76,9 +87,20 @@ __FBSDID("$FreeBSD: src/sys/dev/rp/rp_pc #define _CFG_INT_PCI 0x40 #define _PCI_INT_FUNC 0x3A +#define _UPCI_INT_FUNC 0x4C #define PCI_STROB 0x2000 +#define UPCI_STROB_C 0x0000 +#define UPCI_STROB_S 0x0001 + #define INTR_EN_PCI 0x0010 +#define INTR_EN_UPCI 0x0081 + +#define _UPCI_GPIO 0x54 +#define _UPCI_QUAD_IN 0x0000 +#define _UPCI_OCTAL_IN 0x4000 + +#define _UPCI_RING_IND 0xc0 /*************************************************************************** Function: sPCIControllerEOI @@ -101,6 +123,40 @@ Return: Byte_t: The controller interru */ #define sPCIGetControllerIntStatus(CTLP) ((rp_readio2(CTLP, 0, _PCI_INT_FUNC) >> 8) & 0x1f) +/*************************************************************************** + * Returns the state of RI. The following products have RI: + * UPCI 4/8 port, RP Plus 4/8 port, RP Plus 2 port 232/422. + * For all other devices, this function returns 0. + * + * Returns: 1 if RI is set, else 0. + */ +int sGetChanRI(CHANNEL_T * ChP) +{ + CONTROLLER_t *CtlP = ChP->CtlP; + int ChanNum = ChP->ChanNum; + int RingInd; + + switch (pci_get_device(CtlP->dev)) { + case RP_DEVICE_ID_U32: + case RP_DEVICE_ID_U8PL: + case RP_DEVICE_ID_U16: + case RP_DEVICE_ID_U8QO: + RingInd = !(rp_readio1(CtlP, 0, _UPCI_RING_IND) & rp_sBitMapSetTbl[ChanNum]); + break; + case RP_DEVICE_ID_PL4: + case RP_DEVICE_ID_PL8: + case RP_DEVICE_ID_PL2: + case RP_DEVICE_ID_UP8QO: + case RP_DEVICE_ID_UP2: + RingInd = rp_readch1(ChP, ((ChanNum * 2) + (_CHN_STAT0 + 8))) & DSR_ACT; + break; + default: + RingInd = 0; + } + + return RingInd; +} + static devclass_t rp_devclass; static int rp_pciprobe(device_t dev); @@ -115,7 +171,7 @@ static int sPCIInitController( CONTROLLE int IRQNum, Byte_t Frequency, int PeriodicOnly, - int VendorDevice); + uint16_t VendorDevice); static rp_aiop2rid_t rp_pci_aiop2rid; static rp_aiop2off_t rp_pci_aiop2off; static rp_ctlmask_t rp_pci_ctlmask; @@ -129,12 +185,88 @@ static int rp_pciprobe(device_t dev) { char *s; + uint16_t VenDev; - s = NULL; - if (pci_get_vendor(dev) == RP_VENDOR_ID) - s = "RocketPort PCI"; + if (num_devices_found >= 4) + return ENXIO; + s = NULL; + if (pci_get_vendor(dev) == RP_VENDOR_ID) { + VenDev = pci_get_device(dev); + switch( VenDev ) { + case RP_DEVICE_ID_4Q: + s = "RocketPort PCI Quad"; + break; + case RP_DEVICE_ID_4J: + s = "RocketPort PCI 4J"; + break; + case RP_DEVICE_ID_4M: + s = "RocketModem II PCI 4"; + break; + case RP_DEVICE_ID_PL4: + s = "RocketPort Plus PCI Quad"; + break; + case RP_DEVICE_ID_6M: + s = "RocketModem II PCI 6"; + break; + case RP_DEVICE_ID_8O: + s = "RocketPort PCI Octa"; + break; + case RP_DEVICE_ID_8J: + s = "RocketPort PCI 8J"; + break; + case RP_DEVICE_ID_8I: + s = "RocketPort PCI 8"; + break; + case RP_DEVICE_ID_U8PL: + s = "RocketPort Universal PCI 8 Low Profile"; + break; + case RP_DEVICE_ID_U8QO: + s = "RocketPort Universal PCI Quad/Octa"; + break; + case RP_DEVICE_ID_16I: + s = "RocketPort PCI 16"; + break; + case RP_DEVICE_ID_U16: + s = "RocketPort Universal PCI 16"; + break; + case RP_DEVICE_ID_32I: + s = "RocketPort PCI 32"; + break; + case RP_DEVICE_ID_U32: + s = "RocketPort Universal PCI 32"; + break; + case RP_DEVICE_ID_PL8: + s = "RocketPort Plus PCI Octa"; + break; + case RP_DEVICE_ID_PL2: + s = "RocketPort Plus PCI 2"; + break; + case RP_DEVICE_ID_UP8QO: + s = "RocketPort Plus Universal PCI Quad/Octa"; + break; + case RP_DEVICE_ID_UP2: + s = "RocketPort Plus Universal PCI 2"; + break; + case RP_DEVICE_ID_UP2SMPTE: + s = "RocketPort Plus Universal PCI 2 SMPTE"; + break; + case RP_DEVICE_ID_UP4J: + s = "RocketPort Plus Universal PCI 4J"; + break; + case RP_DEVICE_ID_UP8J: + s = "RocketPort Plus Universal PCI 8J"; + break; + case RP_DEVICE_ID_UP422QO: + s = "RocketPort Plus Universal PCI 422 Quad/Octa"; + break; + default: + s = NULL; + break; + } + } if (s != NULL) { + num_devices_found++; device_set_desc(dev, s); return (BUS_PROBE_DEFAULT); } @@ -150,10 +282,14 @@ rp_pciattach(device_t dev) CONTROLLER_t *ctlp; int unit; int retval; - u_int32_t stcmd; - + uint32_t stcmd; + uint16_t VenDev; + + VenDev = pci_get_device(dev); ctlp = device_get_softc(dev); bzero(ctlp, sizeof(*ctlp)); + + ctlp->CtlID = CTLID_0001; /* controller type 1 */ ctlp->dev = dev; unit = device_get_unit(dev); ctlp->aiop2rid = rp_pci_aiop2rid; @@ -168,7 +304,11 @@ rp_pciattach(device_t dev) } /* The IO ports of AIOPs for a PCI controller are continuous. */ - ctlp->io_num = 1; + if (cardIsUPCI(ctlp->dev)) /* if RocketPort UPCI with PLX chip */ + ctlp->io_num = 2; /* then setup two base addresses */ + else + ctlp->io_num = 1; /* or just setup one base address */ + ctlp->io_rid = malloc(sizeof(*(ctlp->io_rid)) * ctlp->io_num, M_DEVBUF, M_NOWAIT | M_ZERO); ctlp->io = malloc(sizeof(*(ctlp->io)) * ctlp->io_num, M_DEVBUF, M_NOWAIT | M_ZERO); if (ctlp->io_rid == NULL || ctlp->io == NULL) { @@ -179,15 +319,14 @@ rp_pciattach(device_t dev) ctlp->bus_ctlp = NULL; - switch (pci_get_device(dev)) { - case RP_DEVICE_ID_UPCI_32: - case RP_DEVICE_ID_UPCI_8O: - ctlp->io_rid[0] = PCIR_BAR(2); - break; - default: - ctlp->io_rid[0] = PCIR_BAR(0); - break; + if (cardIsUPCI(ctlp->dev)) { /* if RocketPort UPCI with PLX chip */ + ctlp->io_rid[0] = 0x18; /* then setup two base addresses */ + ctlp->io_rid[1] = 0x14; } + else { + ctlp->io_rid[0] = 0x10; /* or just setup one base address */ + } + ctlp->io[0] = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], RF_ACTIVE); if(ctlp->io[0] == NULL) { @@ -195,7 +334,16 @@ rp_pciattach(device_t dev) retval = ENXIO; goto nogo; } - + if (cardIsUPCI(ctlp->dev)) { /* if RocketPort UPCI with PLX chip */ + ctlp->io[1] = bus_alloc_resource(dev, SYS_RES_IOPORT, &ctlp->io_rid[1], 0, ~0, 1, RF_ACTIVE); + /*device_printf(dev, "ioaddr (%x) mapping for RocketPort(UPCI) i +s %08x.\n", ctlp->io_rid[1], ctlp->io[1]);*/ + if(ctlp->io[1] == NULL) { + device_printf(dev, "ioaddr mapping failed for RocketPort (UPCI).\n"); + retval = ENXIO; + goto nogo; + } + } num_aiops = sPCIInitController(ctlp, MAX_AIOPS_PER_BOARD, 0, FREQ_DIS, 0, pci_get_device(dev)); @@ -265,20 +413,74 @@ rp_pcireleaseresource(CONTROLLER_t *ctlp rp_releaseresource(ctlp); } -static int +static int sPCIInitController( CONTROLLER_t *CtlP, int AiopNum, int IRQNum, Byte_t Frequency, int PeriodicOnly, - int VendorDevice) + uint16_t VendorDevice) { - int i; - - CtlP->CtlID = CTLID_0001; /* controller release 1 */ - - sPCIControllerEOI(CtlP); + int i, AiopChanCnt, gpio_dat; + if (cardIsUPCI(CtlP->dev)) /* if RocketPort UPCI with PLX chip */ + rp_writeio2(CtlP, 1, _UPCI_INT_FUNC, 0x0000); /* disable ints */ + else + sPCIControllerEOI(CtlP); + + switch( VendorDevice ) { + case RP_DEVICE_ID_4Q: + case RP_DEVICE_ID_4J: + case RP_DEVICE_ID_4M: + case RP_DEVICE_ID_PL4: + case RP_DEVICE_ID_UP4J: + AiopChanCnt = 4; + AiopNum = 1; + break; + case RP_DEVICE_ID_6M: + AiopChanCnt = 6; + AiopNum = 1; + break; + case RP_DEVICE_ID_8O: + case RP_DEVICE_ID_8J: + case RP_DEVICE_ID_8I: + case RP_DEVICE_ID_U8PL: + case RP_DEVICE_ID_U8QO: + AiopNum = 1; + AiopChanCnt = 8; + break; + case RP_DEVICE_ID_16I: + case RP_DEVICE_ID_U16: + AiopNum = 2; + AiopChanCnt = 8; + break; + case RP_DEVICE_ID_32I: + case RP_DEVICE_ID_U32: + AiopNum = 4; + AiopChanCnt = 8; + break; + case RP_DEVICE_ID_PL8: + case RP_DEVICE_ID_UP8J: + case RP_DEVICE_ID_UP8QO: + case RP_DEVICE_ID_UP422QO: + AiopNum = 2; + AiopChanCnt = 4; + break; + case RP_DEVICE_ID_PL2: + case RP_DEVICE_ID_UP2: + case RP_DEVICE_ID_UP2SMPTE: + AiopNum = 1; + AiopChanCnt = 2; + break; + default: + AiopNum = 1; +#if notdef + AiopChanCnt = 8; +#else + AiopChanCnt = sReadAiopNumChan(CtlP, 0); +#endif /* notdef */ + break; + } /* Init AIOPs */ CtlP->NumAiop = 0; for(i=0; i < AiopNum; i++) @@ -290,39 +492,24 @@ sPCIInitController( CONTROLLER_t *CtlP, { 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; - } + if (VendorDevice == RP_DEVICE_ID_U8QO) { /* if UPCI QUAD/OCTAL board */ + gpio_dat = rp_readio2(CtlP, 1, _UPCI_GPIO); /* read GPIO reg */ + if (!(gpio_dat & _UPCI_OCTAL_IN)) /* if quad cable attached, */ + AiopChanCnt = 4; /* set for only four channels */ + } + CtlP->AiopNumChan[i] = AiopChanCnt; /*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");*/ + if (cardIsRocketportPlus(CtlP->dev)) { + rp_writeaiop1(CtlP, i, _INDX_DATA, AB_CLOCK_PRESC); + /*device_printf(CtlP->dev, "configured clock prescaler (%04x = %02x).\n",_CLK_PRE, AB_CLOCK_PRESC);*/ + } + else { + rp_writeaiop1(CtlP, i, _INDX_DATA, CLOCK_PRESC); + /*device_printf(CtlP->dev, "configured clock prescaler (%04x = %02x).\n",_CLK_PRE, CLOCK_PRESC);*/ + } CtlP->NumAiop++; /* bump count of AIOPs */ } - if(CtlP->NumAiop == 0) return(-1); else @@ -355,7 +542,80 @@ rp_pci_aiop2off(int aiop, int offset) static unsigned char rp_pci_ctlmask(CONTROLLER_t *ctlp) { - return sPCIGetControllerIntStatus(ctlp); + int cmsk; + unsigned char cret=0; + + if (cardIsUPCI(ctlp->dev)) { /* if RocketPort UPCI with PLX chip */ + cmsk = rp_readio2(ctlp, 1, _UPCI_GPIO); + if (cmsk & UINTSTAT0) /* convert PLX int bits to AIOPIC int bits */ + cret |= INTSTAT0; + if (cmsk & UINTSTAT1) + cret |= INTSTAT1; + if (cmsk & UINTSTAT2) + cret |= INTSTAT2; + if (cmsk & UINTSTAT3) + cret |= INTSTAT3; + cmsk = rp_readio2(ctlp, 1, _UPCI_INT_FUNC); /* get int active bit */ + if (cmsk & UINTACT) + cret |= 0x10; + return cret; + } + else { + return sPCIGetControllerIntStatus(ctlp); + } +} +int +cardIsUPCI(device_t dev) +{ + uint16_t VenDev; + int upci_fnd; + + upci_fnd = FALSE; + VenDev = pci_get_device(dev); + switch( VenDev ) { + case RP_DEVICE_ID_U8PL: + case RP_DEVICE_ID_U8QO: + case RP_DEVICE_ID_U16: + case RP_DEVICE_ID_U32: + case RP_DEVICE_ID_UP8QO: + case RP_DEVICE_ID_UP2: + case RP_DEVICE_ID_UP2SMPTE: + case RP_DEVICE_ID_UP4J: + case RP_DEVICE_ID_UP8J: + case RP_DEVICE_ID_UP422QO: + upci_fnd = TRUE; /* controller with PLX9030 chip */ + break; + default: + upci_fnd = FALSE; + break; + } + return(upci_fnd); +} +int +cardIsRocketportPlus(device_t dev) +{ + uint16_t VenDev; + int rpl_fnd; + + rpl_fnd = FALSE; + VenDev = pci_get_device(dev); + switch( VenDev ) { + case RP_DEVICE_ID_PL4: + case RP_DEVICE_ID_PL8: + case RP_DEVICE_ID_PL2: + case RP_DEVICE_ID_UP8QO: + case RP_DEVICE_ID_UP2: + case RP_DEVICE_ID_UP2SMPTE: + case RP_DEVICE_ID_UP4J: + case RP_DEVICE_ID_UP8J: + case RP_DEVICE_ID_UP422QO: + rpl_fnd = TRUE; /* RocketPort Plus board */ + break; + default: + rpl_fnd = FALSE; + break; + } + return(rpl_fnd); } static device_method_t rp_pcimethods[] = { Index: rpreg.h ==================================================================RCS file: /usr/local/cvsroot/freebsd/src/sys/dev/rp/rpreg.h,v retrieving revision 1.7 diff -u -p -r1.7 rpreg.h --- rpreg.h 6 Jan 2005 01:43:11 -0000 1.7 +++ rpreg.h 7 Sep 2006 18:19:44 -0000 @@ -133,6 +133,8 @@ typedef unsigned int DWordIO_t; /* Controller ID numbers */ #define CTLID_NULL -1 /* no controller exists */ #define CTLID_0001 0x0001 /* controller release 1 */ +#define CTLID_0002 0x0002 /* controller with PLX9030 chip */ +#define CTLID_0003 0x0003 /* Rocketport Plus board */ /* AIOP ID numbers, identifies AIOP type implementing channel */ #define AIOPID_NULL -1 /* no AIOP or channel exists */ @@ -213,8 +215,11 @@ Channel Register Offsets - Indexed - Int #define _BAUD 0xFF4 /* Baud Rate 16 Write */ #define _CLK_PRE 0xFF6 /* Clock Prescaler 8 Write */ +/************************************************************************ + Baud rate divisors using mod 9 clock prescaler and 36.873 clock +************************************************************************/ #define CLOCK_PRESC 0x19 /* mod 9 (divide by 10) prescale */ - +#define BRD0 3 /* tps remapped for 57.6KB */ #define BRD50 4607 #define BRD75 3071 #define BRD110 2094 @@ -238,6 +243,35 @@ Channel Register Offsets - Indexed - Int #define BRD76800 2 #define BRD115200 1 #define BRD230400 0 +/************************************************************************ + Baud rate divisors using mod 2 clock prescaler and 44.2368 clock +************************************************************************/ +#define AB_CLOCK_PRESC 0x12 /* mod 2 prescale */ +#define AB_BRD0 3 /* tps remapped for 57.6KB */ +#define AB_BRD50 18431 +#define AB_BRD75 12287 +#define AB_BRD110 8377 +#define AB_BRD134 6852 +#define AB_BRD150 6143 +#define AB_BRD200 4607 +#define AB_BRD300 3071 +#define AB_BRD600 1535 +#define AB_BRD1200 767 +#define AB_BRD1800 511 +#define AB_BRD2400 383 +#define AB_BRD4800 191 +#define AB_BRD7200 127 +#define AB_BRD9600 95 +#define AB_BRD14400 63 +#define AB_BRD19200 47 +#define AB_BRD28800 31 +#define AB_BRD38400 23 +#define AB_BRD57600 15 +#define AB_BRD76800 11 +#define AB_BRD115200 7 +#define AB_BRD230400 3 +#define AB_BRD460800 2 +#define AB_BRD921600 0 #define STMBREAK 0x08 /* BREAK */ #define STMFRAME 0x04 /* framing error */ @@ -316,6 +350,12 @@ Channel Register Offsets - Indexed - Int #define INTSTAT2 0x04 /* AIOP 2 interrupt status */ #define INTSTAT3 0x08 /* AIOP 3 interrupt status */ +#define UINTACT 0x04 /* UPCI AIOP Interrupt active */ +#define UINTSTAT0 0x04 /* UPCI AIOP 0 interrupt status */ +#define UINTSTAT1 0x20 /* UPCI AIOP 1 interrupt status */ +#define UINTSTAT2 0x100 /* UPCI AIOP 2 interrupt status */ +#define UINTSTAT3 0x800 /* UPCI AIOP 3 interrupt status */ + #define INTR_EN 0x08 /* allow interrupts to host */ #define INT_STROB 0x04 /* strobe and clear interrupt line (EOI) */ @@ -1004,7 +1044,12 @@ void sEnInterrupts(CHANNEL_T *ChP,Word_t 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); +int cardIsUPCI(device_t dev); +int cardIsRocketportPlus(device_t dev); +int sGetChanRI(CHANNEL_T * ChP); void rp_untimeout(void); +extern int next_unit_number; +extern int num_devices_found; #ifndef ROCKET_C extern Byte_t R[RDATASIZE]; Index: rpvar.h ==================================================================RCS file: /usr/local/cvsroot/freebsd/src/sys/dev/rp/rpvar.h,v retrieving revision 1.8 diff -u -p -r1.8 rpvar.h --- rpvar.h 6 Jan 2005 01:43:11 -0000 1.8 +++ rpvar.h 7 Sep 2006 18:19:44 -0000 @@ -63,8 +63,8 @@ struct rp_port { int rp_xmit_stopped:1; CONTROLLER_t * rp_ctlp; CHANNEL_t rp_channel; - unsigned short TxBuf[TXFIFO_SIZE/2 +1]; - unsigned short RxBuf[RXFIFO_SIZE/2 +1]; + unsigned short TxBuf[TXFIFO_SIZE/2 + 1]; + unsigned short RxBuf[RXFIFO_SIZE/2 + 1]; }; /* Actually not used */ This works for me and supports more HW. Doug A.