From pjeremy@gsmx07.alcatel.com.au  Fri Oct  8 03:14:50 2004
Return-Path: <pjeremy@gsmx07.alcatel.com.au>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 0F5DE16A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Fri,  8 Oct 2004 03:14:50 +0000 (GMT)
Received: from alcanet.com.au (mailout2.alcanet.com.au [202.147.43.78])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 7C82D43D39
	for <FreeBSD-gnats-submit@freebsd.org>; Fri,  8 Oct 2004 03:14:48 +0000 (GMT)
	(envelope-from pjeremy@gsmx07.alcatel.com.au)
Received: from gsmx07.alcatel.com.au (IDENT:root@localhost.localdomain [127.0.0.1])
	by alcanet.com.au (8.12.9/8.12.9/Alcanet1.3) with ESMTP id i973BKg6031887;
	Thu, 7 Oct 2004 13:11:20 +1000
Received: from gsmx07.alcatel.com.au (localhost [127.0.0.1])
	by gsmx07.alcatel.com.au (8.12.9p2/8.12.9) with ESMTP id i973BKks034746;
	Thu, 7 Oct 2004 13:11:20 +1000 (EST)
	(envelope-from pjeremy@gsmx07.alcatel.com.au)
Received: (from pjeremy@localhost)
	by gsmx07.alcatel.com.au (8.12.9p2/8.12.9/Submit) id i973BJxM034745;
	Thu, 7 Oct 2004 13:11:19 +1000 (EST)
	(envelope-from pjeremy)
Message-Id: <200410070311.i973BJxM034745@gsmx07.alcatel.com.au>
Date: Thu, 7 Oct 2004 13:11:19 +1000 (EST)
From: Peter.Jeremy@alcatel.com.au
To: FreeBSD-gnats-submit@freebsd.org
Cc: Andrew.Li@alcatel.com.au
Subject: [patch] digi(4) panic's system on open
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         72438
>Category:       kern
>Synopsis:       [patch] digi(4) panic's system on open
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Oct 08 03:20:31 GMT 2004
>Closed-Date:    Fri Oct 08 06:08:26 GMT 2004
>Last-Modified:  Fri Oct 08 06:08:26 GMT 2004
>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:
State-Changed-From-To: open->closed 
State-Changed-By: linimon 
State-Changed-When: Fri Oct 8 06:08:11 GMT 2004 
State-Changed-Why:  
Duplicate of 72436. 

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