Date: Wed, 4 Feb 2009 16:22:26 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 157143 for review Message-ID: <200902041622.n14GMQcj053492@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 *,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200902041622.n14GMQcj053492>