From owner-p4-projects@FreeBSD.ORG Wed Feb 4 16:22:27 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 6529C1065676; Wed, 4 Feb 2009 16:22:27 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1CE511065673 for ; Wed, 4 Feb 2009 16:22:27 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 0B3288FC1C for ; Wed, 4 Feb 2009 16:22:27 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n14GMQoi053494 for ; Wed, 4 Feb 2009 16:22:26 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n14GMQcj053492 for perforce@freebsd.org; Wed, 4 Feb 2009 16:22:26 GMT (envelope-from hselasky@FreeBSD.org) Date: Wed, 4 Feb 2009 16:22:26 GMT Message-Id: <200902041622.n14GMQcj053492@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 157143 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: Wed, 04 Feb 2009 16:22:29 -0000 http://perforce.freebsd.org/chv.cgi?CH=157143 Change 157143 by hselasky@hselasky_laptop001 on 2009/02/04 16:22:19 USB serial: Simplify line state programming, reduce memory requirement. Affected files ... .. //depot/projects/usb/src/sys/dev/usb2/serial/usb2_serial.c#25 edit .. //depot/projects/usb/src/sys/dev/usb2/serial/usb2_serial.h#14 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb2/serial/usb2_serial.c#25 (text+ko) ==== @@ -95,12 +95,7 @@ static usb2_proc_callback_t usb2_com_cfg_start_transfers; static usb2_proc_callback_t usb2_com_cfg_open; static usb2_proc_callback_t usb2_com_cfg_close; -static usb2_proc_callback_t usb2_com_cfg_break_on; -static usb2_proc_callback_t usb2_com_cfg_break_off; -static usb2_proc_callback_t usb2_com_cfg_dtr_on; -static usb2_proc_callback_t usb2_com_cfg_dtr_off; -static usb2_proc_callback_t usb2_com_cfg_rts_on; -static usb2_proc_callback_t usb2_com_cfg_rts_off; +static usb2_proc_callback_t usb2_com_cfg_line_state; static usb2_proc_callback_t usb2_com_cfg_status_change; static usb2_proc_callback_t usb2_com_cfg_param; @@ -543,6 +538,11 @@ sc->sc_msr = 0; sc->sc_mcr = 0; + /* reset programmed line state */ + sc->sc_pls_curr = 0; + sc->sc_pls_set = 0; + sc->sc_pls_clr = 0; + usb2_com_queue_command(sc, usb2_com_cfg_open, NULL, &sc->sc_open_task[0].hdr, &sc->sc_open_task[1].hdr); @@ -703,165 +703,119 @@ } static void -usb2_com_cfg_break_on(struct usb2_proc_msg *_task) +usb2_com_cfg_line_state(struct usb2_proc_msg *_task) { struct usb2_com_cfg_task *task = (struct usb2_com_cfg_task *)_task; struct usb2_com_softc *sc = task->sc; + uint8_t notch_bits; + uint8_t any_bits; + uint8_t prev_value; + uint8_t last_value; + uint8_t mask; if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) { return; } - DPRINTF("\n"); + + mask = 0; + /* compute callback mask */ + if (sc->sc_callback->usb2_com_cfg_set_dtr) + mask |= UCOM_LS_DTR; + if (sc->sc_callback->usb2_com_cfg_set_rts) + mask |= UCOM_LS_RTS; + if (sc->sc_callback->usb2_com_cfg_set_break) + mask |= UCOM_LS_BREAK; - if (sc->sc_callback->usb2_com_cfg_set_break) { - (sc->sc_callback->usb2_com_cfg_set_break) (sc, 1); - } -} + /* compute the bits we are to program */ + notch_bits = (sc->sc_pls_set & sc->sc_pls_clr) & mask; + any_bits = (sc->sc_pls_set | sc->sc_pls_clr) & mask; + prev_value = sc->sc_pls_curr ^ notch_bits; + last_value = sc->sc_pls_curr; -static void -usb2_com_cfg_break_off(struct usb2_proc_msg *_task) -{ - struct usb2_com_cfg_task *task = - (struct usb2_com_cfg_task *)_task; - struct usb2_com_softc *sc = task->sc; + /* reset programmed line state */ + sc->sc_pls_curr = 0; + sc->sc_pls_set = 0; + sc->sc_pls_clr = 0; - if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) { - return; - } - DPRINTF("\n"); + /* ensure that we don't loose any levels */ + if (notch_bits & UCOM_LS_DTR) + sc->sc_callback->usb2_com_cfg_set_dtr(sc, + (prev_value & UCOM_LS_DTR) ? 1 : 0); + if (notch_bits & UCOM_LS_RTS) + sc->sc_callback->usb2_com_cfg_set_rts(sc, + (prev_value & UCOM_LS_RTS) ? 1 : 0); + if (notch_bits & UCOM_LS_BREAK) + sc->sc_callback->usb2_com_cfg_set_break(sc, + (prev_value & UCOM_LS_BREAK) ? 1 : 0); - if (sc->sc_callback->usb2_com_cfg_set_break) { - (sc->sc_callback->usb2_com_cfg_set_break) (sc, 0); - } + /* set last value */ + if (any_bits & UCOM_LS_DTR) + sc->sc_callback->usb2_com_cfg_set_dtr(sc, + (last_value & UCOM_LS_DTR) ? 1 : 0); + if (any_bits & UCOM_LS_RTS) + sc->sc_callback->usb2_com_cfg_set_rts(sc, + (last_value & UCOM_LS_RTS) ? 1 : 0); + if (any_bits & UCOM_LS_BREAK) + sc->sc_callback->usb2_com_cfg_set_break(sc, + (last_value & UCOM_LS_BREAK) ? 1 : 0); } static void -usb2_com_break(struct usb2_com_softc *sc, uint8_t onoff) +usb2_com_line_state(struct usb2_com_softc *sc, + uint8_t set_bits, uint8_t clear_bits) { mtx_assert(sc->sc_mtx, MA_OWNED); if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) { return; } - DPRINTF("onoff = %d\n", onoff); - if (onoff) - usb2_com_queue_command(sc, usb2_com_cfg_break_on, NULL, - &sc->sc_break_on_task[0].hdr, - &sc->sc_break_on_task[1].hdr); - else - usb2_com_queue_command(sc, usb2_com_cfg_break_off, NULL, - &sc->sc_break_off_task[0].hdr, - &sc->sc_break_off_task[1].hdr); -} + DPRINTF("on=0x%02x, off=0x%02x\n", set_bits, clear_bits); -static void -usb2_com_cfg_dtr_on(struct usb2_proc_msg *_task) -{ - struct usb2_com_cfg_task *task = - (struct usb2_com_cfg_task *)_task; - struct usb2_com_softc *sc = task->sc; + /* update current programmed line state */ + sc->sc_pls_curr |= set_bits; + sc->sc_pls_curr &= ~clear_bits; + sc->sc_pls_set |= set_bits; + sc->sc_pls_clr |= clear_bits; - if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) { - return; - } - DPRINTF("\n"); - - if (sc->sc_callback->usb2_com_cfg_set_dtr) { - (sc->sc_callback->usb2_com_cfg_set_dtr) (sc, 1); - } + /* defer driver programming */ + usb2_com_queue_command(sc, usb2_com_cfg_line_state, NULL, + &sc->sc_line_state_task[0].hdr, + &sc->sc_line_state_task[1].hdr); } static void -usb2_com_cfg_dtr_off(struct usb2_proc_msg *_task) +usb2_com_break(struct usb2_com_softc *sc, uint8_t onoff) { - struct usb2_com_cfg_task *task = - (struct usb2_com_cfg_task *)_task; - struct usb2_com_softc *sc = task->sc; + DPRINTF("onoff = %d\n", onoff); - if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) { - return; - } - DPRINTF("\n"); - - if (sc->sc_callback->usb2_com_cfg_set_dtr) { - (sc->sc_callback->usb2_com_cfg_set_dtr) (sc, 0); - } + if (onoff) + usb2_com_line_state(sc, UCOM_LS_BREAK, 0); + else + usb2_com_line_state(sc, 0, UCOM_LS_BREAK); } static void usb2_com_dtr(struct usb2_com_softc *sc, uint8_t onoff) { - mtx_assert(sc->sc_mtx, MA_OWNED); - - if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) { - return; - } DPRINTF("onoff = %d\n", onoff); if (onoff) - usb2_com_queue_command(sc, usb2_com_cfg_dtr_on, NULL, - &sc->sc_dtr_on_task[0].hdr, - &sc->sc_dtr_on_task[1].hdr); + usb2_com_line_state(sc, UCOM_LS_DTR, 0); else - usb2_com_queue_command(sc, usb2_com_cfg_dtr_off, NULL, - &sc->sc_dtr_off_task[0].hdr, - &sc->sc_dtr_off_task[1].hdr); + usb2_com_line_state(sc, 0, UCOM_LS_DTR); } static void -usb2_com_cfg_rts_on(struct usb2_proc_msg *_task) -{ - struct usb2_com_cfg_task *task = - (struct usb2_com_cfg_task *)_task; - struct usb2_com_softc *sc = task->sc; - - DPRINTF("\n"); - - if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) { - return; - } - if (sc->sc_callback->usb2_com_cfg_set_rts) { - (sc->sc_callback->usb2_com_cfg_set_rts) (sc, 1); - } -} - -static void -usb2_com_cfg_rts_off(struct usb2_proc_msg *_task) -{ - struct usb2_com_cfg_task *task = - (struct usb2_com_cfg_task *)_task; - struct usb2_com_softc *sc = task->sc; - - DPRINTF("\n"); - - if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) { - return; - } - if (sc->sc_callback->usb2_com_cfg_set_rts) { - (sc->sc_callback->usb2_com_cfg_set_rts) (sc, 0); - } -} - -static void usb2_com_rts(struct usb2_com_softc *sc, uint8_t onoff) { - mtx_assert(sc->sc_mtx, MA_OWNED); - - if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) { - return; - } DPRINTF("onoff = %d\n", onoff); if (onoff) - usb2_com_queue_command(sc, usb2_com_cfg_rts_on, NULL, - &sc->sc_rts_on_task[0].hdr, - &sc->sc_rts_on_task[1].hdr); + usb2_com_line_state(sc, UCOM_LS_RTS, 0); else - usb2_com_queue_command(sc, usb2_com_cfg_rts_off, NULL, - &sc->sc_rts_off_task[0].hdr, - &sc->sc_rts_off_task[1].hdr); + usb2_com_line_state(sc, 0, UCOM_LS_RTS); } static void ==== //depot/projects/usb/src/sys/dev/usb2/serial/usb2_serial.h#14 (text+ko) ==== @@ -148,12 +148,7 @@ struct usb2_com_cfg_task sc_start_task[2]; struct usb2_com_cfg_task sc_open_task[2]; struct usb2_com_cfg_task sc_close_task[2]; - struct usb2_com_cfg_task sc_break_on_task[2]; - struct usb2_com_cfg_task sc_dtr_on_task[2]; - struct usb2_com_cfg_task sc_rts_on_task[2]; - struct usb2_com_cfg_task sc_break_off_task[2]; - struct usb2_com_cfg_task sc_dtr_off_task[2]; - struct usb2_com_cfg_task sc_rts_off_task[2]; + struct usb2_com_cfg_task sc_line_state_task[2]; struct usb2_com_cfg_task sc_status_task[2]; struct usb2_com_param_task sc_param_task[2]; struct cv sc_cv; @@ -177,6 +172,13 @@ uint8_t sc_msr; uint8_t sc_mcr; uint8_t sc_ttyfreed; /* set when TTY has been freed */ + /* programmed line state bits */ + uint8_t sc_pls_set; /* set bits */ + uint8_t sc_pls_clr; /* cleared bits */ + uint8_t sc_pls_curr; /* last state */ +#define UCOM_LS_DTR 0x01 +#define UCOM_LS_RTS 0x02 +#define UCOM_LS_BREAK 0x04 }; int usb2_com_attach(struct usb2_com_super_softc *,