mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
umodem(4): Clear stall at every open.
Some controllers like the XHCI(4) loose track of the data toggle value when USB receive transfers are cancelled at close. This in turn can lead to to data loss after the next open. To avoid data loss, make sure both the receive and transmit data toggles get reset, before trying to read or write any data. Differential Revision: https://reviews.freebsd.org/D36391 Submitted by: Dave Baukus <daveb@spectralogic.com> MFC after: 1 week Sponsored by: NVIDIA Networking
This commit is contained in:
parent
c00605751e
commit
40e43b056d
1 changed files with 14 additions and 8 deletions
|
|
@ -218,6 +218,7 @@ static void umodem_cfg_get_status(struct ucom_softc *, uint8_t *,
|
|||
uint8_t *);
|
||||
static int umodem_pre_param(struct ucom_softc *, struct termios *);
|
||||
static void umodem_cfg_param(struct ucom_softc *, struct termios *);
|
||||
static void umodem_cfg_open(struct ucom_softc *);
|
||||
static int umodem_ioctl(struct ucom_softc *, uint32_t, caddr_t, int,
|
||||
struct thread *);
|
||||
static void umodem_cfg_set_dtr(struct ucom_softc *, uint8_t);
|
||||
|
|
@ -283,6 +284,7 @@ static const struct ucom_callback umodem_callback = {
|
|||
.ucom_cfg_set_break = &umodem_cfg_set_break,
|
||||
.ucom_cfg_param = &umodem_cfg_param,
|
||||
.ucom_pre_param = &umodem_pre_param,
|
||||
.ucom_cfg_open = &umodem_cfg_open,
|
||||
.ucom_ioctl = &umodem_ioctl,
|
||||
.ucom_start_read = &umodem_start_read,
|
||||
.ucom_stop_read = &umodem_stop_read,
|
||||
|
|
@ -447,14 +449,6 @@ umodem_attach(device_t dev)
|
|||
goto detach;
|
||||
}
|
||||
|
||||
/* clear stall at first run, if USB host mode */
|
||||
if (uaa->usb_mode == USB_MODE_HOST) {
|
||||
mtx_lock(&sc->sc_mtx);
|
||||
usbd_xfer_set_stall(sc->sc_xfer[UMODEM_BULK_WR]);
|
||||
usbd_xfer_set_stall(sc->sc_xfer[UMODEM_BULK_RD]);
|
||||
mtx_unlock(&sc->sc_mtx);
|
||||
}
|
||||
|
||||
ucom_set_usb_mode(&sc->sc_super_ucom, uaa->usb_mode);
|
||||
|
||||
error = ucom_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
|
||||
|
|
@ -633,6 +627,18 @@ umodem_cfg_param(struct ucom_softc *ucom, struct termios *t)
|
|||
&req, &ls, 0, 1000);
|
||||
}
|
||||
|
||||
static void
|
||||
umodem_cfg_open(struct ucom_softc *ucom)
|
||||
{
|
||||
struct umodem_softc *sc = ucom->sc_parent;
|
||||
|
||||
/* clear stall, if in USB host mode */
|
||||
if ((sc->sc_super_ucom.sc_flag & UCOM_FLAG_DEVICE_MODE) == 0) {
|
||||
usbd_xfer_set_stall(sc->sc_xfer[UMODEM_BULK_WR]);
|
||||
usbd_xfer_set_stall(sc->sc_xfer[UMODEM_BULK_RD]);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
umodem_ioctl(struct ucom_softc *ucom, uint32_t cmd, caddr_t data,
|
||||
int flag, struct thread *td)
|
||||
|
|
|
|||
Loading…
Reference in a new issue