Index: sys/dev/usb/serial/usb_serial.c =================================================================== --- sys/dev/usb/serial/usb_serial.c +++ sys/dev/usb/serial/usb_serial.c @@ -154,7 +154,8 @@ static void ucom_detach_tty(struct ucom_super_softc *, struct ucom_softc *); static void ucom_queue_command(struct ucom_softc *, usb_proc_callback_t *, struct termios *pt, - struct usb_proc_msg *t0, struct usb_proc_msg *t1); + struct usb_proc_msg *t0, struct usb_proc_msg *t1, + bool sync); static void ucom_shutdown(struct ucom_softc *); static void ucom_ring(struct ucom_softc *, uint8_t); static void ucom_break(struct ucom_softc *, uint8_t); @@ -598,7 +599,8 @@ static void ucom_queue_command(struct ucom_softc *sc, usb_proc_callback_t *fn, struct termios *pt, - struct usb_proc_msg *t0, struct usb_proc_msg *t1) + struct usb_proc_msg *t0, struct usb_proc_msg *t1, + bool sync) { struct ucom_super_softc *ssc = sc->sc_super; struct ucom_param_task *task; @@ -629,9 +631,11 @@ task->termios_copy = *pt; /* - * Closing the device should be synchronous. + * Synchronous execution will mostly be used for closing the device or + * param changes. Caller should make that decision, though, rather than + * assuming that here that the caller wants to block on it. */ - if (fn == ucom_cfg_close) + if (sync) usb_proc_mwait(&ssc->sc_tq, t0, t1); /* @@ -789,12 +793,12 @@ ucom_queue_command(sc, ucom_cfg_open, NULL, &sc->sc_open_task[0].hdr, - &sc->sc_open_task[1].hdr); + &sc->sc_open_task[1].hdr, false); /* Queue transfer enable command last */ ucom_queue_command(sc, ucom_cfg_start_transfers, NULL, &sc->sc_start_task[0].hdr, - &sc->sc_start_task[1].hdr); + &sc->sc_start_task[1].hdr, false); ucom_modem(tp, SER_DTR | SER_RTS, 0); @@ -842,7 +846,7 @@ ucom_queue_command(sc, ucom_cfg_close, NULL, &sc->sc_close_task[0].hdr, - &sc->sc_close_task[1].hdr); + &sc->sc_close_task[1].hdr, true); sc->sc_flag &= ~(UCOM_FLAG_HL_READY | UCOM_FLAG_RTS_IFLOW); @@ -1085,7 +1089,7 @@ /* defer driver programming */ ucom_queue_command(sc, ucom_cfg_line_state, NULL, &sc->sc_line_state_task[0].hdr, - &sc->sc_line_state_task[1].hdr); + &sc->sc_line_state_task[1].hdr, false); } static void @@ -1247,7 +1251,7 @@ ucom_queue_command(sc, ucom_cfg_status_change, NULL, &sc->sc_status_task[0].hdr, - &sc->sc_status_task[1].hdr); + &sc->sc_status_task[1].hdr, false); } static void @@ -1322,12 +1326,12 @@ /* Queue baud rate programming command first */ ucom_queue_command(sc, ucom_cfg_param, t, &sc->sc_param_task[0].hdr, - &sc->sc_param_task[1].hdr); + &sc->sc_param_task[1].hdr, true); /* Queue transfer enable command last */ ucom_queue_command(sc, ucom_cfg_start_transfers, NULL, &sc->sc_start_task[0].hdr, - &sc->sc_start_task[1].hdr); + &sc->sc_start_task[1].hdr, false); if (t->c_cflag & CRTS_IFLOW) { sc->sc_flag |= UCOM_FLAG_RTS_IFLOW;