Date: Fri, 8 Oct 2004 09:27:09 +1000 (EST) From: PeterJeremy@optushome.com.au To: FreeBSD-gnats-submit@FreeBSD.org Cc: andrew.li@alcatel.com.au Subject: kern/72436: [patch] digi(4) panic's system on open Message-ID: <200410072327.i97NR9jJ031393@cirb503493.alcatel.com.au> Resent-Message-ID: <200410072330.i97NUKKw004806@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 72436 >Category: kern >Synopsis: [patch] digi(4) panic's system on open >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Oct 07 23:30:20 GMT 2004 >Closed-Date: >Last-Modified: >Originator: Peter Jeremy >Release: FreeBSD 5.3-BETA6 i386 >Organization: Alcatel Australia Limited >Environment: System: FreeBSD srpca.alcatel.com.au 5.3-BETA6 FreeBSD 5.3-BETA6 #1: Tue Oct 5 13:52:33 EST 2004 root@srpca.alcatel.com.au:/var/obj/usr/src/sys/GENERIC i386 >Description: The digi(4) driver locally allocates struct tty objects rather than using ttymalloc(9). As a result, the tty object is not initialised as expected by the rest of the TTY subsystem. In particular, the various mutex structures are not initialised and the attempt to use them during the open causes the system to panic. I would appreciate it if this fix was merged into 5.3. >How-To-Repeat: Install a DigiBoard Xem or equivalent. kldload digi stty -a -f /dev/ttyD0.0 [instant panic dereferencing a NULL pointer in knote()] >Fix: Currently, the digi(4) driver allocates {numports} struct tty objects in a single block (digi_softc.ttys) and creates a reference to individual tty objects for each port. This fix removes the 'ttys' field from the digi_softc and initialises the tty reference in each port using ttymalloc(9). Other references to digi_softc.ttys[i] are changed to digi_softc.ports[i].tp and the cleanup code has be changed to call ttyrel(9) instead of just freeing the memory. Index: digi.c =================================================================== RCS file: /usr/ncvs/src/sys/dev/digi/digi.c,v retrieving revision 1.55 diff -u -r1.55 digi.c --- digi.c 28 Jul 2004 21:06:13 -0000 1.55 +++ digi.c 7 Oct 2004 01:49:36 -0000 @@ -538,16 +538,14 @@ device_printf(sc->dev, "%s, %d ports found\n", sc->name, sc->numports); - if (sc->ports) + if (sc->ports) { + for (i = 0; i < sc->numports; i++) + ttyrel(sc->ports[i].tp); free(sc->ports, M_TTYS); + } sc->ports = malloc(sizeof(struct digi_p) * sc->numports, M_TTYS, M_WAITOK | M_ZERO); - if (sc->ttys) - free(sc->ttys, M_TTYS); - sc->ttys = malloc(sizeof(struct tty) * sc->numports, - M_TTYS, M_WAITOK | M_ZERO); - /* * XXX Should read port 0xc90 for an array of 2byte values, 1 per * port. If the value is 0, the port is broken.... @@ -567,7 +565,7 @@ port->pnum = i; port->sc = sc; port->status = ENABLED; - port->tp = sc->ttys + i; + port->tp = ttymalloc(NULL); port->bc = bc; if (sc->model == PCXEVE) { @@ -958,7 +956,7 @@ sc = (struct digi_softc *)devclass_get_softc(digi_devclass, unit); KASSERT(sc, ("digi%d: softc not allocated in digiclose\n", unit)); - tp = &sc->ttys[pnum]; + tp = sc->ports[pnum].tp; error = ttyld_read(tp, uio, flag); DLOG(DIGIDB_READ, (sc->dev, "port %d: read() returns %d\n", @@ -984,7 +982,7 @@ sc = (struct digi_softc *)devclass_get_softc(digi_devclass, unit); KASSERT(sc, ("digi%d: softc not allocated in digiclose\n", unit)); - tp = &sc->ttys[pnum]; + tp = sc->ports[pnum].tp; error = ttyld_write(tp, uio, flag); DLOG(DIGIDB_WRITE, (sc->dev, "port %d: write() returns %d\n", @@ -1829,7 +1827,7 @@ int i; for (i = 0; i < sc->numports; i++) - if (sc->ttys[i].t_state & TS_ISOPEN) { + if (sc->ports[i].tp->t_state & TS_ISOPEN) { DLOG(DIGIDB_INIT, (sc->dev, "port%d: busy\n", i)); return (1); } else if (sc->ports[i].wopeners || sc->ports[i].opencnt) { @@ -1866,11 +1864,10 @@ #endif if (sc->numports) { KASSERT(sc->ports, ("digi%d: Lost my ports ?", sc->res.unit)); - KASSERT(sc->ttys, ("digi%d: Lost my ttys ?", sc->res.unit)); + for (i = 0; i < sc->numports; i++) + ttyrel(sc->ports[i].tp); free(sc->ports, M_TTYS); sc->ports = NULL; - free(sc->ttys, M_TTYS); - sc->ttys = NULL; sc->numports = 0; } Index: digi.h =================================================================== RCS file: /usr/ncvs/src/sys/dev/digi/digi.h,v retrieving revision 1.17 diff -u -r1.17 digi.h --- digi.h 11 Jul 2004 15:18:37 -0000 1.17 +++ digi.h 7 Oct 2004 01:49:42 -0000 @@ -177,7 +177,6 @@ #endif struct digi_p *ports; /* pointer to array of port descriptors */ - struct tty *ttys; /* pointer to array of TTY structures */ volatile struct global_data *gdata; u_char window; /* saved window */ int win_size; >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200410072327.i97NR9jJ031393>