From PeterJeremy@optushome.com.au  Thu Oct  7 23:27:19 2004
Return-Path: <PeterJeremy@optushome.com.au>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 20EA816A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Thu,  7 Oct 2004 23:27:19 +0000 (GMT)
Received: from mail22.syd.optusnet.com.au (mail22.syd.optusnet.com.au [211.29.133.160])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 54D1843D1D
	for <FreeBSD-gnats-submit@freebsd.org>; Thu,  7 Oct 2004 23:27:18 +0000 (GMT)
	(envelope-from PeterJeremy@optushome.com.au)
Received: from cirb503493.alcatel.com.au (c211-30-75-229.belrs2.nsw.optusnet.com.au [211.30.75.229])
	by mail22.syd.optusnet.com.au (8.12.11/8.12.11) with ESMTP id i97NR9tr018100
	(version=TLSv1/SSLv3 cipher=EDH-RSA-DES-CBC3-SHA bits=168 verify=NO);
	Fri, 8 Oct 2004 09:27:10 +1000
Received: from cirb503493.alcatel.com.au (localhost.alcatel.com.au [127.0.0.1])
	by cirb503493.alcatel.com.au (8.12.10/8.12.10) with ESMTP id i97NR9xP031394;
	Fri, 8 Oct 2004 09:27:09 +1000 (EST)
	(envelope-from pjeremy@cirb503493.alcatel.com.au)
Received: (from pjeremy@localhost)
	by cirb503493.alcatel.com.au (8.12.10/8.12.9/Submit) id i97NR9jJ031393;
	Fri, 8 Oct 2004 09:27:09 +1000 (EST)
	(envelope-from pjeremy)
Message-Id: <200410072327.i97NR9jJ031393@cirb503493.alcatel.com.au>
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, peter.jeremy@alcatel.com.au
Subject: [patch] digi(4) panic's system on open
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         72436
>Category:       kern
>Synopsis:       [patch] digi(4) panic's system on open
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    dwhite
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Oct 07 23:30:20 GMT 2004
>Closed-Date:    Sat Feb 05 23:43:23 GMT 2005
>Last-Modified:  Sat Feb 05 23:43:23 GMT 2005
>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:

From: Doug White <dwhite@gumbysoft.com>
To: freebsd-gnats-submit@FreeBSD.org, PeterJeremy@optushome.com.au
Cc:  
Subject: Re: kern/72436: [patch] digi(4) panic's system on open
Date: Tue, 1 Feb 2005 18:50:06 -0800 (PST)

 I've been trying this patch on my system and it seems to be half right --
 I can see traffic on the ports OK but I can't write anything to them.
 I'll try to research this further...
 
 -- 
 Doug White                    |  FreeBSD: The Power to Serve
 dwhite@gumbysoft.com          |  www.FreeBSD.org

From: Doug White <dwhite@gumbysoft.com>
To: freebsd-gnats-submit@freebsd.org
Cc:  
Subject: kern/72436: commit candidate patch
Date: Thu, 3 Feb 2005 18:29:49 -0800 (PST)

 I plan on committing this patch to RELENG_5 after i've done a build test
 on it.  Checks out on my RELENG_5_3 machine.  This has two lines of
 difference from the patch in this PR that missed the chnage in type
 of the ports array.
 
 http://people.freebsd.org/~dwhite/digi.20041217.patch
 
 -- 
 Doug White                    |  FreeBSD: The Power to Serve
 dwhite@gumbysoft.com          |  www.FreeBSD.org
Responsible-Changed-From-To: freebsd-bugs->dwhite 
Responsible-Changed-By: dwhite 
Responsible-Changed-When: Sat Feb 5 23:37:45 GMT 2005 
Responsible-Changed-Why:  
Grab this since I'm about to commit the fix. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=72436 
State-Changed-From-To: open->closed 
State-Changed-By: dwhite 
State-Changed-When: Sat Feb 5 23:43:04 GMT 2005 
State-Changed-Why:  
Committed. Thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=72436 
>Unformatted:
