PERFORCE change 157143 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Wed Feb 4 08:22:29 PST 2009
http://perforce.freebsd.org/chv.cgi?CH=157143
Change 157143 by hselasky at 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 *,
More information about the p4-projects
mailing list