From owner-freebsd-stable@FreeBSD.ORG Thu Sep 7 20:31:44 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 0B8BA16A4DD for ; Thu, 7 Sep 2006 20:31:44 +0000 (UTC) (envelope-from karl@FS.denninger.net) Received: from FS.denninger.net (wsip-70-169-168-7.pn.at.cox.net [70.169.168.7]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6AD5E43D82 for ; Thu, 7 Sep 2006 20:31:30 +0000 (GMT) (envelope-from karl@FS.denninger.net) Received: from fs.denninger.net (localhost [127.0.0.1]) by FS.denninger.net (8.13.6/8.13.1) with SMTP id k87KUvOx006132 for ; Thu, 7 Sep 2006 15:30:57 -0500 (CDT) (envelope-from karl@FS.denninger.net) Received: from fs.denninger.net [127.0.0.1] by Spamblock-sys (LOCAL); Thu Sep 7 15:30:57 2006 Received: (from karl@localhost) by FS.denninger.net (8.13.6/8.13.1/Submit) id k87KUufH006129; Thu, 7 Sep 2006 15:30:56 -0500 (CDT) (envelope-from karl) Date: Thu, 7 Sep 2006 15:30:56 -0500 From: Karl Denninger To: Doug Ambrisko Message-ID: <20060907203056.GA6029@FS.denninger.net> Mail-Followup-To: Doug Ambrisko , Karl Denninger , freebsd-stable@freebsd.org References: <20060907140056.GB72764@FS.denninger.net> <200609071821.k87ILpVt033964@ambrisko.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <200609071821.k87ILpVt033964@ambrisko.com> User-Agent: Mutt/1.4.2.1i Organization: Karl's Sushi and Packet Smashers X-Die-Spammers: Spammers cheerfully broiled for supper and served with ketchup! Cc: freebsd-stable@freebsd.org, Karl Denninger 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 20:31:44 -0000 Nope - still got the same issues. I have an application that does heavy serial I/O in non-canonical mode and uses raw I/O termios (Vmin, Vtime, etc) heavily. It works perfectly under 5.x and has worked properly under previous versions back to 4.x under both the Comtrol and Digiboard drivers. With or without these patches, its screwed on 6.x. I'm getting double, triple, sometimes even more copies of frames into the read buffer - returns from SELECT which are reporting data already read (and it can be read(2) again!), etc. Not good... Here's a boot dmesg of one of the machines that's misbehaving... I'm going to shut off SMP in this kernel (all these machines ARE hyperthreaded CPUs) and see if that helps, but the patches appear to make no difference. Copyright (c) 1992-2006 The FreeBSD Project. Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 The Regents of the University of California. All rights reserved. FreeBSD 6.1-STABLE #2: Thu Sep 7 14:48:03 CDT 2006 karl@FS.denninger.net:/usr/obj/usr/src/sys/KSD-SMP Timecounter "i8254" frequency 1193182 Hz quality 0 CPU: Intel(R) Pentium(R) 4 CPU 2.40GHz (2394.01-MHz 686-class CPU) Origin = "GenuineIntel" Id = 0xf29 Stepping = 9 Features=0xbfebfbff Features2=0x4400> Logical CPUs per core: 2 real memory = 267862016 (255 MB) avail memory = 252432384 (240 MB) ACPI APIC Table: FreeBSD/SMP: Multiprocessor System Detected: 2 CPUs cpu0 (BSP): APIC ID: 0 cpu1 (AP): APIC ID: 1 ioapic0: Changing APIC ID to 2 ioapic0 irqs 0-23 on motherboard kbd1 at kbdmux0 ath_hal: 0.9.17.2 (AR5210, AR5211, AR5212, RF5111, RF5112, RF2413, RF5413) acpi0: on motherboard acpi0: Power Button (fixed) Timecounter "ACPI-fast" frequency 3579545 Hz quality 1000 acpi_timer0: <24-bit timer at 3.579545MHz> port 0x808-0x80b on acpi0 cpu0: on acpi0 cpu1: on acpi0 acpi_button0: on acpi0 pcib0: port 0xcf8-0xcff on acpi0 pci0: on pcib0 agp0: mem 0xe8000000-0xefffffff at device 0.0 on pci0 pcib1: at device 1.0 on pci0 pci1: on pcib1 pci1: at device 0.0 (no driver attached) uhci0: port 0xff80-0xff9f irq 16 at device 29.0 on pci0 uhci0: [GIANT-LOCKED] usb0: on uhci0 usb0: USB revision 1.0 uhub0: Intel UHCI root hub, class 9/0, rev 1.00/1.00, addr 1 uhub0: 2 ports with 2 removable, self powered uhci1: port 0xff60-0xff7f irq 19 at device 29.1 on pci0 uhci1: [GIANT-LOCKED] usb1: on uhci1 usb1: USB revision 1.0 uhub1: Intel UHCI root hub, class 9/0, rev 1.00/1.00, addr 1 uhub1: 2 ports with 2 removable, self powered uhci2: port 0xff40-0xff5f irq 18 at device 29.2 on pci0 uhci2: [GIANT-LOCKED] usb2: on uhci2 usb2: USB revision 1.0 uhub2: Intel UHCI root hub, class 9/0, rev 1.00/1.00, addr 1 uhub2: 2 ports with 2 removable, self powered uhci3: port 0xff20-0xff3f irq 16 at device 29.3 on pci0 uhci3: [GIANT-LOCKED] usb3: on uhci3 usb3: USB revision 1.0 uhub3: Intel UHCI root hub, class 9/0, rev 1.00/1.00, addr 1 uhub3: 2 ports with 2 removable, self powered ehci0: mem 0xffa80800-0xffa80bff irq 23 at device 29.7 on pci0 ehci0: [GIANT-LOCKED] usb4: EHCI version 1.0 usb4: companion controllers, 2 ports each: usb0 usb1 usb2 usb3 usb4: on ehci0 usb4: USB revision 2.0 uhub4: Intel EHCI root hub, class 9/0, rev 2.00/1.00, addr 1 uhub4: 8 ports with 8 removable, self powered pcib2: at device 30.0 on pci0 pci2: on pcib2 twe0: <3ware Storage Controller. Driver version 1.50.01.002> port 0xcef0-0xceff mem 0xfe000000-0xfe7fffff irq 22 at device 1.0 on pci2 twe0: [GIANT-LOCKED] twe0: 2 ports, Firmware FE8S 1.05.00.068, BIOS BE7X 1.08.00.048 rp0: port 0xcf00-0xcf3f irq 17 at device 2.0 on pci2 RocketPort0 = 4 ports. pcib3: at device 3.0 on pci2 pci3: on pcib3 fxp0: port 0xbf80-0xbf9f mem 0xf8001000-0xf8001fff,0xfdc00000-0xfdcfffff irq 19 at device 4.0 on pci3 miibus0: on fxp0 inphy0: on miibus0 inphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto fxp0: Ethernet address: 00:d0:b7:6f:ce:e8 fxp1: port 0xbfe0-0xbfff mem 0xf8000000-0xf8000fff,0xfdd00000-0xfddfffff irq 18 at device 5.0 on pci3 miibus1: on fxp1 inphy1: on miibus1 inphy1: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto fxp1: Ethernet address: 00:d0:b7:6f:ce:e9 em0: port 0xcf40-0xcf7f mem 0xfdfe0000-0xfdffffff irq 18 at device 12.0 on pci2 em0: Ethernet address: 00:0c:f1:c9:df:c5 em0: [FAST] isab0: at device 31.0 on pci0 isa0: on isab0 atapci0: port 0x1f0-0x1f7,0x3f6,0x170-0x177,0x376,0xffa0-0xffaf mem 0xfebffc00-0xfebfffff irq 18 at device 31.1 on pci0 ata0: on atapci0 ata1: on atapci0 atapci1: port 0xfe00-0xfe07,0xfe10-0xfe13,0xfe20-0xfe27,0xfe30-0xfe33,0xfea0-0xfeaf irq 18 at device 31.2 on pci0 ata2: on atapci1 ata3: on atapci1 pci0: at device 31.3 (no driver attached) pcm0: port 0xee00-0xeeff,0xedc0-0xedff mem 0xfebffa00-0xfebffbff,0xfebff900-0xfebff9ff irq 17 at device 31.5 on pci0 pcm0: primary codec not ready! pcm0: fdc0: port 0x3f0-0x3f5,0x3f7 irq 6 drq 2 on acpi0 fdc0: [FAST] fd0: <1440-KB 3.5" drive> on fdc0 drive 0 atkbdc0: port 0x60,0x64 irq 1 on acpi0 atkbd0: irq 1 on atkbdc0 kbd0 at atkbd0 atkbd0: [GIANT-LOCKED] sio0: <16550A-compatible COM port> port 0x3f8-0x3ff irq 4 flags 0x10 on acpi0 sio0: type 16550A sio1: <16550A-compatible COM port> port 0x2f8-0x2ff irq 3 on acpi0 sio1: type 16550A pmtimer0 on isa0 orm0: at iomem 0xc0000-0xcafff,0xcb000-0xcbfff,0xcc000-0xcc7ff,0xcc800-0xcdfff,0xce000-0xcffff on isa0 ppc0: parallel port not found. sc0: at flags 0x100 on isa0 sc0: VGA <16 virtual consoles, flags=0x300> vga0: at port 0x3c0-0x3df iomem 0xa0000-0xbffff on isa0 Timecounters tick every 1.000 msec ipfw2 (+ipv6) initialized, divert loadable, rule-based forwarding disabled, default to deny, logging disabled acd0: CDROM at ata1-master UDMA33 ad4: 476940MB at ata2-master SATA150 ad6: 476940MB at ata3-master SATA150 twed0: on twe0 twed0: 476940MB (976773168 sectors) twed1: on twe0 twed1: 476940MB (976773168 sectors) SMP: AP CPU #1 Launched! GEOM_MIRROR: Device b500 created (id=1654021267). GEOM_MIRROR: Device b500: provider ad4s1 detected. GEOM_MIRROR: Device b500: provider ad6s1 detected. GEOM_MIRROR: Device b500: provider ad6s1 activated. GEOM_MIRROR: Device b500: provider ad4s1 activated. GEOM_MIRROR: Device b500: provider mirror/b500 launched. Trying to mount root from ufs:/dev/mirror/b500a em0: link state changed to UP -- -- 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 On Thu, Sep 07, 2006 at 11:21:51AM -0700, Doug Ambrisko wrote: > 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. > _______________________________________________ > freebsd-stable@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-stable > To unsubscribe, send any mail to "freebsd-stable-unsubscribe@freebsd.org" > > > %SPAMBLOCK-SYS: Matched [@freebsd.org+], message ok