FreeBSD Bugzilla – Attachment 111033 Details for
Bug 152253
[digi] [patch] Enhancements to digi(4) to prevent interrupt storms
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
file.diff
file.diff (text/plain), 12.30 KB, created by
Peter.Jeremy
on 2010-11-15 00:10:08 UTC
(
hide
)
Description:
file.diff
Filename:
MIME Type:
Creator:
Peter.Jeremy
Created:
2010-11-15 00:10:08 UTC
Size:
12.30 KB
patch
obsolete
>Index: digi.c >=================================================================== >RCS file: /usr/ncvs/src/sys/dev/digi/digi.c,v >retrieving revision 1.63 >diff -u -r1.63 digi.c >--- digi.c 27 Sep 2006 19:56:58 -0000 1.63 >+++ digi.c 18 Jun 2010 01:58:03 -0000 >@@ -46,8 +46,9 @@ > #include <sys/mbuf.h> > #include <sys/malloc.h> > #include <sys/module.h> >-#include <sys/tty.h> >+#include <sys/sysctl.h> > #include <sys/syslog.h> >+#include <sys/tty.h> > #include <sys/fcntl.h> > #include <sys/serial.h> > #include <sys/bus.h> >@@ -75,7 +76,6 @@ > static void digistart(struct tty *tp); > static int digiparam(struct tty *tp, struct termios *t); > static void digiclose(struct tty *tp); >-static void digi_intr(void *); > static int digi_init(struct digi_softc *_sc); > static int digi_loadmoduledata(struct digi_softc *); > static int digi_inuse(struct digi_softc *); >@@ -94,7 +94,14 @@ > static struct con_bios *con_bios_list; > devclass_t digi_devclass; > static char driver_name[] = "digi"; >-unsigned digi_debug = 0; >+ >+#ifdef DEBUG >+unsigned long digi_debug = 0; >+ >+SYSCTL_ULONG(_debug, OID_AUTO, digi_debug, CTLFLAG_RW, &digi_debug, 0, >+ "digi(4) debug flags"); >+TUNABLE_ULONG("debug.digi_debug", &digi_debug); >+#endif > > static struct speedtab digispeedtab[] = { > { 0, 0}, /* old (sysV-like) Bx codes */ >@@ -159,7 +166,7 @@ > /* interrupt OK! */ > return; > } >- log(LOG_ERR, "digi%d: Interrupt didn't work, use polled mode\n", unit); >+ log(LOG_ERR, "digi%d: Interrupt didn't work, use polled mode\n", sc->res.unit); > #endif > sc->callout = timeout(digi_poll, sc, (hz >= 200) ? hz / 100 : 1); > } >@@ -182,7 +189,7 @@ > } > > static int >-digi_bcopy(const void *vfrom, void *vto, size_t sz) >+digi_bcopy(const void *vfrom, void volatile *vto, size_t sz) > { > volatile const char *from = (volatile const char *)vfrom; > volatile char *to = (volatile char *)vto; >@@ -212,7 +219,8 @@ > digi_init(struct digi_softc *sc) > { > int i, cnt, resp; >- u_char *ptr; >+ u_char volatile *ptr; >+ u_char *cptr; > int lowwater; > struct digi_p *port; > volatile struct board_chan *bc; >@@ -302,6 +310,11 @@ > } > DLOG(DIGIDB_INIT, (sc->dev, "Got init reset after %d us\n", i)); > >+ /* Clear POST area */ >+ ptr = sc->setwin(sc, MISCGLOBAL); >+ for (i = 0; i < 16; i++) >+ *(uint8_t volatile *)(ptr + i) = 0; >+ > /* Now upload the BIOS */ > cnt = (sc->bios.size < sc->win_size - BIOSOFFSET) ? > sc->bios.size : sc->win_size - BIOSOFFSET; >@@ -323,10 +336,8 @@ > } > > ptr = sc->setwin(sc, 0); >- vW(ptr + 0) = 0x0401; >- vW(ptr + 2) = 0x0bf0; >- vW(ptr + 4) = 0x0000; >- vW(ptr + 6) = 0x0000; >+ vD(ptr + 0) = 0x0bf00401; >+ vD(ptr + 4) = 0x00000000; > > break; > } >@@ -334,7 +345,7 @@ > DLOG(DIGIDB_INIT, (sc->dev, "BIOS uploaded\n")); > > ptr = sc->setwin(sc, MISCGLOBAL); >- W(ptr) = 0; >+ vW(ptr) = 0; > > if (sc->pcibus) { > PCIPORT = FEPCLR; >@@ -399,7 +410,7 @@ > outb(sc->port, FEPREQ | FEPMEM); > outb(sc->port, FEPCLR | FEPMEM); > >- for (i = 0; W(ptr); i++) { >+ for (i = 0; vW(ptr); i++) { > if (i > hz) { > log(LOG_ERR, "digi%d: FEP/OS move failed\n", > sc->res.unit); >@@ -449,14 +460,12 @@ > DLOG(DIGIDB_INIT, (sc->dev, "FEP/OS loaded\n")); > > ptr = sc->setwin(sc, 0xc30); >- W(ptr + 4) = 0x1004; >- W(ptr + 6) = 0xbfc0; >- W(ptr + 0) = 0x03; >- W(ptr + 2) = 0x00; >+ vD(ptr + 4) = 0xbfc01004; >+ vD(ptr + 0) = 0x00000003; > > /* Clear the confirm word */ > ptr = sc->setwin(sc, FEPSTAT); >- W(ptr + 0) = 0; >+ vW(ptr + 0) = 0; > > if (sc->port) > outb(sc->port, 0); /* XXX necessary ? */ >@@ -469,13 +478,13 @@ > > /* A BIOS request to execute the FEP/OS */ > ptr = sc->setwin(sc, 0xc40); >- W(ptr + 0) = 1; >- W(ptr + 2) = FEPCODE >> 4; >- W(ptr + 4) = 4; >+ vW(ptr + 0) = 1; >+ vW(ptr + 2) = FEPCODE >> 4; >+ vW(ptr + 4) = 4; > > /* Clear the confirm word */ > ptr = sc->setwin(sc, FEPSTAT); >- W(ptr + 0) = 0; >+ vW(ptr + 0) = 0; > > /* Run the BIOS request */ > outb(sc->port, FEPREQ | FEPMEM); /* send interrupt to BIOS */ >@@ -498,8 +507,12 @@ > DLOG(DIGIDB_INIT, (sc->dev, "FEP/OS started after %d iterations\n", i)); > > if (sc->model >= PCXEM) { >+#if 0 >+ /* Interrupt configuration */ > ptr = sc->setwin(sc, 0xe04); > vW(ptr) = 2; >+#endif >+ /* Read number of ports */ > ptr = sc->setwin(sc, 0xc02); > sc->numports = vW(ptr); > } else { >@@ -551,22 +564,23 @@ > tp->t_open = digiopen; > tp->t_close = digiclose; > tp->t_sc = port; >+ cptr = (u_char *)(intptr_t)ptr; > > if (sc->model == PCXEVE) { >- port->txbuf = ptr + >+ port->txbuf = cptr + > (((bc->tseg - sc->mem_seg) << 4) & 0x1fff); >- port->rxbuf = ptr + >+ port->rxbuf = cptr + > (((bc->rseg - sc->mem_seg) << 4) & 0x1fff); > port->txwin = FEPWIN | ((bc->tseg - sc->mem_seg) >> 9); > port->rxwin = FEPWIN | ((bc->rseg - sc->mem_seg) >> 9); > } else if (sc->model == PCXI || sc->model == PCXE) { >- port->txbuf = ptr + ((bc->tseg - sc->mem_seg) << 4); >- port->rxbuf = ptr + ((bc->rseg - sc->mem_seg) << 4); >+ port->txbuf = cptr + ((bc->tseg - sc->mem_seg) << 4); >+ port->rxbuf = cptr + ((bc->rseg - sc->mem_seg) << 4); > port->txwin = port->rxwin = 0; > } else { >- port->txbuf = ptr + >+ port->txbuf = cptr + > (((bc->tseg - sc->mem_seg) << 4) % sc->win_size); >- port->rxbuf = ptr + >+ port->rxbuf = cptr + > (((bc->rseg - sc->mem_seg) << 4) % sc->win_size); > port->txwin = FEPWIN | > (((bc->tseg - sc->mem_seg) << 4) / sc->win_size); >@@ -585,6 +599,7 @@ > fepcmd_w(port, SRXHWATER, (3 * port->rxbufsize) >> 2, 10); > > bc->edelay = 100; >+ bc->idata = 1; /*XXXXXX*/ > > ttyinitmode(tp, 0, 0); > port->send_ring = 1; /* Default action on signal RI */ >@@ -1080,7 +1095,7 @@ > return (0); > } > >-static void >+void > digi_intr(void *vp) > { > struct digi_p *port; >@@ -1113,46 +1128,46 @@ > window = sc->window; > sc->setwin(sc, 0); > >- if (sc->model >= PCXEM && W(sc->vmem + 0xd00)) { >+ if (sc->model >= PCXEM && vW(sc->vmem + 0xd00)) { > struct con_bios *con = con_bios_list; >- register u_char *ptr; >+ register u_char volatile *ptr; > >- ptr = sc->vmem + W(sc->vmem + 0xd00); >+ ptr = sc->vmem + vW(sc->vmem + 0xd00); > while (con) { >- if (ptr[1] && W(ptr + 2) == W(con->bios + 2)) >+ if (ptr[1] && vW(ptr + 2) == vW(con->bios + 2)) > /* Not first block -- exact match */ > break; > >- if (W(ptr + 4) >= W(con->bios + 4) && >- W(ptr + 4) <= W(con->bios + 6)) >+ if (vW(ptr + 4) >= W(con->bios + 4) && >+ vW(ptr + 4) <= W(con->bios + 6)) > /* Initial search concetrator BIOS */ > break; > } > > if (con == NULL) { > log(LOG_ERR, "digi%d: wanted bios LREV = 0x%04x" >- " not found!\n", sc->res.unit, W(ptr + 4)); >- W(ptr + 10) = 0; >- W(sc->vmem + 0xd00) = 0; >+ " not found!\n", sc->res.unit, vW(ptr + 4)); >+ vW(ptr + 10) = 0; >+ vW(sc->vmem + 0xd00) = 0; > goto eoi; > } > cxcon = con->bios; >- W(ptr + 4) = W(cxcon + 4); >- W(ptr + 6) = W(cxcon + 6); >+ vW(ptr + 4) = W(cxcon + 4); >+ vW(ptr + 6) = W(cxcon + 6); > if (ptr[1] == 0) >- W(ptr + 2) = W(cxcon + 2); >- W(ptr + 8) = (ptr[1] << 6) + W(cxcon + 8); >+ vW(ptr + 2) = W(cxcon + 2); >+ vW(ptr + 8) = (ptr[1] << 6) + W(cxcon + 8); > size = W(cxcon + 10) - (ptr[1] << 10); > if (size <= 0) { >- W(ptr + 8) = W(cxcon + 8); >- W(ptr + 10) = 0; >+ vW(ptr + 8) = W(cxcon + 8); >+ vW(ptr + 10) = 0; > } else { > if (size > 1024) > size = 1024; >- W(ptr + 10) = size; >- bcopy(cxcon + (ptr[1] << 10), ptr + 12, size); >+ vW(ptr + 10) = size; >+ bcopy(cxcon + (ptr[1] << 10), (void *)((intptr_t)ptr + 12), size); > } >- W(sc->vmem + 0xd00) = 0; >+ vW(sc->vmem + 0xd00) = 0; > goto eoi; > } > >@@ -1299,6 +1314,10 @@ > } > sc->gdata->eout = etail; > eoi: >+ /* Ack any interrupt */ >+ if (sc->pcibus) >+ (void)sc->vmem[0x200002]; >+ > if (sc->window != 0) > sc->towin(sc, 0); > if (window != 0) >@@ -1403,7 +1422,7 @@ > static void > fepcmd(struct digi_p *port, int cmd, int op1, int ncmds) > { >- u_char *mem; >+ u_char volatile *mem; > unsigned tail, head; > int count, n; > >@@ -1414,7 +1433,7 @@ > head = port->sc->gdata->cin; > mem[head + 0] = cmd; > mem[head + 1] = port->pnum; >- *(u_short *)(mem + head + 2) = op1; >+ *(u_short volatile *)(mem + head + 2) = op1; > > head = (head + 4) & port->sc->gdata->cmax; > port->sc->gdata->cin = head; >@@ -1503,7 +1522,7 @@ > bus_teardown_intr(sc->dev, sc->res.irq, sc->res.irqHandler); > #ifdef DIGI_INTERRUPT > if (sc->res.irq != NULL) { >- bus_release_resource(dev, SYS_RES_IRQ, sc->res.irqrid, >+ bus_release_resource(sc->dev, SYS_RES_IRQ, sc->res.irqrid, > sc->res.irq); > sc->res.irq = NULL; > } >Index: digi.h >=================================================================== >RCS file: /usr/ncvs/src/sys/dev/digi/digi.h,v >retrieving revision 1.19 >diff -u -r1.19 digi.h >--- digi.h 14 Oct 2004 18:37:59 -0000 1.19 >+++ digi.h 18 Jun 2010 01:52:53 -0000 >@@ -40,14 +40,14 @@ > #define CE_NTYPES 3 > #define CE_RECORD(com, errnum) (++(com)->delta_error_counts[errnum]) > >-/*#define DIGI_INTERRUPT*/ >+#define DIGI_INTERRUPT > > #ifndef DEBUG > #define DEBUG > #endif > > #ifdef DEBUG >-extern unsigned digi_debug; >+extern unsigned long digi_debug; > #define DLOG(level, args) if (digi_debug & (level)) device_printf args > #else > #define DLOG(level, args) >@@ -148,8 +148,8 @@ > struct cdev *ctldev; > } res; > >- u_char *vmem; /* virtual memory address */ >- u_char *memcmd; >+ u_char volatile *vmem; /* virtual memory address */ >+ u_char volatile *memcmd; > volatile u_char *memevent; > long pmem; /* physical memory address */ > >@@ -178,7 +178,7 @@ > struct callout_handle inttest; /* int test timeout handle */ > const char *module; > >- u_char *(*setwin)(struct digi_softc *_sc, unsigned _addr); >+ u_char volatile *(*setwin)(struct digi_softc *_sc, unsigned _addr); > void (*hidewin)(struct digi_softc *_sc); > void (*towin)(struct digi_softc *_sc, int _win); > #ifdef DEBUG >@@ -197,3 +197,4 @@ > int digi_shutdown(device_t _dev); > void digi_delay(struct digi_softc *_sc, const char *_txt, > u_long _timo); >+void digi_intr(void *); >Index: digi_isa.c >=================================================================== >RCS file: /usr/ncvs/src/sys/dev/digi/digi_isa.c,v >retrieving revision 1.13 >diff -u -r1.13 digi_isa.c >--- digi_isa.c 30 May 2004 20:08:30 -0000 1.13 >+++ digi_isa.c 18 Jun 2010 01:27:20 -0000 >@@ -70,14 +70,14 @@ > }; > #define DIGI_NVALIDMEM (sizeof(digi_validmem) / sizeof(digi_validmem[0])) > >-static u_char * >+static u_char volatile * > digi_isa_setwin(struct digi_softc *sc, unsigned int addr) > { > outb(sc->wport, sc->window = FEPWIN | (addr >> sc->win_bits)); > return (sc->vmem + (addr % sc->win_size)); > } > >-static u_char * >+static u_char volatile * > digi_xi_setwin(struct digi_softc *sc, unsigned int addr) > { > outb(sc->wport, sc->window = FEPMEM); >@@ -320,7 +320,7 @@ > { > struct digi_softc *sc = device_get_softc(dev); > int i, t, res; >- u_char *ptr; >+ u_char volatile *ptr; > int reset; > u_long msize, iosize; > long scport; >Index: digi_pci.c >=================================================================== >RCS file: /usr/ncvs/src/sys/dev/digi/digi_pci.c,v >retrieving revision 1.12 >diff -u -r1.12 digi_pci.c >--- digi_pci.c 5 Mar 2005 18:30:10 -0000 1.12 >+++ digi_pci.c 18 Jun 2010 01:13:35 -0000 >@@ -49,7 +49,7 @@ > #include <dev/digi/digi.h> > #include <dev/digi/digi_pci.h> > >-static u_char * >+static volatile u_char * > digi_pci_setwin(struct digi_softc *sc, unsigned int addr) > { > return (sc->vmem + addr); >@@ -175,9 +175,11 @@ > return (ENXIO); > } > >- pci_write_config(dev, 0x40, 0, 4); >- pci_write_config(dev, 0x46, 0, 4); >+ pci_write_config(dev, 0x40, 0, 1); >+ pci_write_config(dev, 0x46, 0, 1); > >+ /* Limit burst length to 2 double-words */ >+ pci_write_config(dev, 0x42, 1, 1); > sc->res.mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->res.mrid, > RF_ACTIVE); > >@@ -190,7 +192,8 @@ > return (ENXIO); > } > retVal = bus_setup_intr(dev, sc->res.irq, INTR_TYPE_TTY, >- digiintr, sc, &sc->res.irqHandler); >+ NULL, digi_intr, sc, &sc->res.irqHandler); >+ bus_teardown_intr(sc->dev, sc->res.irq, sc->res.irqHandler); > #else > DLOG(DIGIDB_IRQ, (sc->dev, "Interrupt support compiled out\n")); > #endif >Index: digi_pci.h >=================================================================== >RCS file: /usr/ncvs/src/sys/dev/digi/digi_pci.h,v >retrieving revision 1.1 >diff -u -r1.1 digi_pci.h >--- digi_pci.h 2 May 2001 01:08:04 -0000 1.1 >+++ digi_pci.h 18 Jun 2010 00:31:53 -0000 >@@ -39,4 +39,4 @@ > #define PCI_DEVICE_920_8 0x0027 /* XR-Plus 920 K, 8 port */ > #define PCI_DEVICE_920_2 0x0034 /* XR-Plus 920 K, 2 port */ > >-#define PCIPORT sc->vmem[0x200000] >+#define PCIPORT (((u_char volatile *)(sc->vmem))[0x200000])
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 152253
: 111033