From owner-freebsd-stable@FreeBSD.ORG Thu Sep 7 18:21:55 2006 Return-Path: X-Original-To: freebsd-stable@freebsd.org Delivered-To: freebsd-stable@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0286E16A4E1 for ; Thu, 7 Sep 2006 18:21:55 +0000 (UTC) (envelope-from ambrisko@ambrisko.com) Received: from mail.ambrisko.com (mail.ambrisko.com [64.174.51.43]) by mx1.FreeBSD.org (Postfix) with ESMTP id ACB2843D53 for ; Thu, 7 Sep 2006 18:21:52 +0000 (GMT) (envelope-from ambrisko@ambrisko.com) Received: from server2.ambrisko.com (HELO www.ambrisko.com) ([192.168.1.2]) by mail.ambrisko.com with ESMTP; 07 Sep 2006 11:19:18 -0700 Received: from ambrisko.com (localhost [127.0.0.1]) by www.ambrisko.com (8.13.1/8.12.11) with ESMTP id k87ILqBL033965; Thu, 7 Sep 2006 11:21:52 -0700 (PDT) (envelope-from ambrisko@ambrisko.com) Received: (from ambrisko@localhost) by ambrisko.com (8.13.1/8.13.1/Submit) id k87ILpVt033964; Thu, 7 Sep 2006 11:21:51 -0700 (PDT) (envelope-from ambrisko) From: Doug Ambrisko Message-Id: <200609071821.k87ILpVt033964@ambrisko.com> In-Reply-To: <20060907140056.GB72764@FS.denninger.net> To: Karl Denninger Date: Thu, 7 Sep 2006 11:21:51 -0700 (PDT) X-Mailer: ELM [version 2.4ME+ PL94b (25)] MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII Cc: freebsd-stable@freebsd.org Subject: Re: Comtrol Rocketport driver is severely hosed under 6.x-STABLE X-BeenThere: freebsd-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Production branch of FreeBSD source code List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 07 Sep 2006 18:21:55 -0000 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 #include "opt_compat.h" #include +#include #include #include #include #include #include +#include #include #include #include @@ -57,7 +60,7 @@ __FBSDID("$FreeBSD: src/sys/dev/rp/rp.c, #include #include -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.