From owner-p4-projects@FreeBSD.ORG Tue Mar 28 19:51:27 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 89D4F16A420; Tue, 28 Mar 2006 19:51:27 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id DB8B216A4DC for ; Tue, 28 Mar 2006 19:51:26 +0000 (UTC) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9DDE5442E0 for ; Tue, 28 Mar 2006 19:25:59 +0000 (GMT) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id k2SJPxKR055037 for ; Tue, 28 Mar 2006 19:25:59 GMT (envelope-from marcel@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id k2SJPxHq055034 for perforce@freebsd.org; Tue, 28 Mar 2006 19:25:59 GMT (envelope-from marcel@freebsd.org) Date: Tue, 28 Mar 2006 19:25:59 GMT Message-Id: <200603281925.k2SJPxHq055034@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to marcel@freebsd.org using -f From: Marcel Moolenaar To: Perforce Change Reviews Cc: Subject: PERFORCE change 94198 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 28 Mar 2006 19:51:28 -0000 http://perforce.freebsd.org/chv.cgi?CH=94198 Change 94198 by marcel@marcel_nfs on 2006/03/28 19:25:52 Have the sysdev methods grab and release the hardware lock. This prevents system console output tos with the hardware when the TTY layer is already doing that. By default there's no mutex associated with the sysdev, but when bus enumation links a sysdev to a softc, the hardware mutex is shared between them. Alternatively: put the mutex in the BAS. Pointed out by: grehan@ Discussed with: grehan@ Affected files ... .. //depot/projects/uart/dev/uart/uart_core.c#47 edit .. //depot/projects/uart/dev/uart/uart_cpu.h#16 edit Differences ... ==== //depot/projects/uart/dev/uart/uart_core.c#47 (text+ko) ==== @@ -205,7 +205,7 @@ if (sc->sc_opened) uart_sched_softih(sc, SER_INT_SIGCHG); - return (0); + return (1); } /* @@ -480,6 +480,9 @@ if (error) goto fail; + if (sc->sc_sysdev != NULL) + sc->sc_sysdev->hwmtx = &sc->sc_hwmtx; + sc->sc_leaving = 0; uart_intr(sc); return (0); @@ -509,6 +512,9 @@ sc->sc_leaving = 1; + if (sc->sc_sysdev != NULL) + sc->sc_sysdev->hwmtx = NULL; + UART_DETACH(sc); if (sc->sc_sysdev != NULL && sc->sc_sysdev->detach != NULL) ==== //depot/projects/uart/dev/uart/uart_cpu.h#16 (text+ko) ==== @@ -29,6 +29,10 @@ #ifndef _DEV_UART_CPU_H_ #define _DEV_UART_CPU_H_ +#include +#include +#include + /* * Low-level operations for use by console and/or debug port support. */ @@ -68,6 +72,7 @@ int (*attach)(struct uart_softc*); int (*detach)(struct uart_softc*); void *cookie; /* Type dependent use. */ + struct mtx *hwmtx; }; int uart_cpu_eqres(struct uart_bas *, struct uart_bas *); @@ -80,41 +85,77 @@ * Operations for low-level access to the UART. Primarily for use * by console and debug port logic. */ + +static __inline void +uart_lock_spin(struct mtx *hwmtx) +{ + if (!kdb_active && hwmtx != NULL) + mtx_lock_spin(hwmtx); +} + +static __inline void +uart_unlock_spin(struct mtx *hwmtx) +{ + if (!kdb_active && hwmtx != NULL) + mtx_unlock_spin(hwmtx); +} + static __inline int uart_probe(struct uart_devinfo *di) { - return (di->ops.probe(&di->bas)); + int res; + + uart_lock_spin(di->hwmtx); + res = di->ops.probe(&di->bas); + uart_unlock_spin(di->hwmtx); + return (res); } static __inline void uart_init(struct uart_devinfo *di) { + uart_lock_spin(di->hwmtx); di->ops.init(&di->bas, di->baudrate, di->databits, di->stopbits, di->parity); + uart_unlock_spin(di->hwmtx); } static __inline void uart_term(struct uart_devinfo *di) { + uart_lock_spin(di->hwmtx); di->ops.term(&di->bas); + uart_unlock_spin(di->hwmtx); } static __inline void uart_putc(struct uart_devinfo *di, int c) { + uart_lock_spin(di->hwmtx); di->ops.putc(&di->bas, c); + uart_unlock_spin(di->hwmtx); } static __inline int uart_poll(struct uart_devinfo *di) { - return (di->ops.poll(&di->bas)); + int res; + + uart_lock_spin(di->hwmtx); + res = di->ops.poll(&di->bas); + uart_unlock_spin(di->hwmtx); + return (res); } static __inline int uart_getc(struct uart_devinfo *di) { - return (di->ops.getc(&di->bas)); + int res; + + uart_lock_spin(di->hwmtx); + res = di->ops.getc(&di->bas); + uart_unlock_spin(di->hwmtx); + return (res); } #endif /* _DEV_UART_CPU_H_ */