Date: Thu, 26 Jan 2006 15:34:37 -0800 (PST) From: Doug Ambrisko <ambrisko@ambrisko.com> To: Vitaliy Skakun <vit.ska@gmail.com> Cc: hackers@freebsd.org Subject: Re: Comtrol Rocketport UNIVERSAL PCI 32-port Message-ID: <200601262334.k0QNYbuS004173@ambrisko.com> In-Reply-To: <806128ad0601260254u42dfd927k@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Vitaliy Skakun writes: | Hi everybody! | | One problem arised: | | when doing in the shell | echo "~WS" > /dev/cuaR00 | | for several times as quick as I can, I get panic with the following message: | panic: device_unbusy: called for non-busy device rp0 | | same thing when trying to send data to /dev/cuaR00 via JDK File streams ... | :((( | | (Some kind of barcode printers are attached to this multiport card) | | Any help will be kindly accepted. If you want you can try: Index: rp.c =================================================================== RCS file: /home/ncvs/src/sys/dev/rp/rp.c,v retrieving revision 1.71 diff -u -p -r1.71 rp.c --- rp.c 4 Dec 2005 10:06:04 -0000 1.71 +++ rp.c 26 Jan 2006 23:33:19 -0000 @@ -32,20 +32,23 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/rp/rp.c,v 1.71 2005/12/04 10:06:04 ru Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/rp/rp.c,v 1.69 2005/10/16 20:35:05 phk Exp $"); -/* +/* * 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); @@ -752,7 +767,7 @@ static void rp_do_poll(void *not_used) } } if(rp_num_ports_open) - rp_callout_handle = timeout(rp_do_poll, + rp_callout_handle = timeout(rp_do_poll, (void *)NULL, POLL_INTERVAL); } @@ -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); @@ -926,7 +942,7 @@ rpopen(struct tty *tp, struct cdev *dev) ChanStatus = sGetChanStatus(&rp->rp_channel); if(rp_num_ports_open == 1) - rp_callout_handle = timeout(rp_do_poll, + rp_callout_handle = timeout(rp_do_poll, (void *)NULL, POLL_INTERVAL); device_busy(rp->rp_ctlp->dev); @@ -1015,9 +1031,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,6 +1045,18 @@ static struct speedtab baud_table[] = { {-1, -1} }; +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} +}; + static int rpparam(tp, t) struct tty *tp; @@ -1041,7 +1070,6 @@ rpparam(tp, t) int devshift; #endif - rp = tp->t_sc; cp = &rp->rp_channel; oldspl = spltty(); @@ -1058,7 +1086,10 @@ rpparam(tp, t) oflag = t->c_oflag; lflag = t->c_lflag; - ospeed = ttspeedtab(t->c_ispeed, baud_table); + if (cardIsRocketportPlus(rp->rp_ctlp->dev)) + ospeed = ttspeedtab(t->c_ispeed, ab_baud_table); + else + ospeed = ttspeedtab(t->c_ispeed, baud_table); if(ospeed < 0 || t->c_ispeed != t->c_ospeed) return(EINVAL); Index: rp_isa.c =================================================================== RCS file: /home/ncvs/src/sys/dev/rp/rp_isa.c,v retrieving revision 1.8 diff -u -p -r1.8 rp_isa.c --- rp_isa.c 4 Dec 2005 10:06:04 -0000 1.8 +++ rp_isa.c 26 Jan 2006 23:33:19 -0000 @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/rp/rp_isa.c,v 1.8 2005/12/04 10:06:04 ru Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/rp/rp_isa.c,v 1.7 2005/01/06 01:43:11 imp Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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: /home/ncvs/src/sys/dev/rp/rp_pci.c,v retrieving revision 1.13 diff -u -p -r1.13 rp_pci.c --- rp_pci.c 25 Jan 2006 14:55:11 -0000 1.13 +++ rp_pci.c 26 Jan 2006 23:33:19 -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 0x4 #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 0xc /*************************************************************************** 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,37 +304,47 @@ rp_pciattach(device_t dev) } /* 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 | M_ZERO); - ctlp->io = malloc(sizeof(*(ctlp->io)) * ctlp->io_num, M_DEVBUF, M_NOWAIT | M_ZERO); + 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) { 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; - 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); + + ctlp->io[0] = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], RF_ACTIVE); + /*device_printf(dev, "ioaddr (%x) mapping for RocketPort(PCI) is %08x.\n", ctlp->io_rid[0], ctlp->io[0]);*/ 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_device(dev)); + 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) is %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, VenDev); num_ports = 0; for(aiop=0; aiop < num_aiops; aiop++) { @@ -271,14 +417,68 @@ sPCIInitController( CONTROLLER_t *CtlP, int IRQNum, Byte_t Frequency, int PeriodicOnly, - int VendorDevice) + uint16_t VendorDevice) { - int i; + int i, AiopChanCnt, gpio_dat; - CtlP->CtlID = CTLID_0001; /* controller release 1 */ - - sPCIControllerEOI(CtlP); + 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 +490,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: -#ifdef 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 +540,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: /home/ncvs/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 26 Jan 2006 23:33:19 -0000 @@ -60,12 +60,12 @@ typedef unsigned int DWordIO_t; #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_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))) @@ -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: /home/ncvs/src/sys/dev/rp/rpvar.h,v retrieving revision 1.9 diff -u -p -r1.9 rpvar.h --- rpvar.h 4 Dec 2005 10:06:04 -0000 1.9 +++ rpvar.h 26 Jan 2006 23:33:19 -0000 @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/rp/rpvar.h,v 1.9 2005/12/04 10:06:04 ru Exp $ + * $FreeBSD: src/sys/dev/rp/rpvar.h,v 1.8 2005/01/06 01:43:11 imp Exp $ */ /* @@ -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 */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200601262334.k0QNYbuS004173>