Overhaul ucom serial driver by using generic stuff instead of homerolled

all over the place.
This commit is contained in:
Poul-Henning Kamp 2004-09-17 11:53:45 +00:00
parent e8d3e08098
commit d75207f145
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=135379
5 changed files with 156 additions and 442 deletions

View File

@ -75,6 +75,7 @@ __FBSDID("$FreeBSD$");
#include <sys/ioccom.h>
#include <sys/fcntl.h>
#include <sys/conf.h>
#include <sys/serial.h>
#include <sys/tty.h>
#include <sys/clist.h>
#include <sys/file.h>
@ -116,41 +117,34 @@ SYSCTL_INT(_hw_usb_ucom, OID_AUTO, debug, CTLFLAG_RW,
#define DPRINTFN(n, x)
#endif
Static d_open_t ucomopen;
Static d_close_t ucomclose;
Static d_read_t ucomread;
Static d_write_t ucomwrite;
Static d_ioctl_t ucomioctl;
static struct cdevsw ucom_cdevsw = {
.d_version = D_VERSION,
.d_open = ucomopen,
.d_close = ucomclose,
.d_read = ucomread,
.d_write = ucomwrite,
.d_ioctl = ucomioctl,
.d_open = ttyopen,
.d_close = ttyclose,
.d_name = "ucom",
.d_flags = D_TTY | D_NEEDGIANT,
#if __FreeBSD_version < 500014
.d_bmaj = -1,
#endif
};
Static void ucom_cleanup(struct ucom_softc *);
Static int ucomctl(struct ucom_softc *, int, int);
Static int ucomparam(struct tty *, struct termios *);
Static void ucomstart(struct tty *);
Static void ucomstop(struct tty *, int);
Static void ucom_shutdown(struct ucom_softc *);
Static void ucom_dtr(struct ucom_softc *, int);
Static void ucom_rts(struct ucom_softc *, int);
Static void ucom_break(struct ucom_softc *, int);
Static void ucombreak(struct tty *, int);
Static usbd_status ucomstartread(struct ucom_softc *);
Static void ucomreadcb(usbd_xfer_handle, usbd_private_handle, usbd_status);
Static void ucomwritecb(usbd_xfer_handle, usbd_private_handle, usbd_status);
Static void ucomstopread(struct ucom_softc *);
Static t_open_t ucomopen;
Static t_close_t ucomclose;
Static t_modem_t ucommodem;
Static t_ioctl_t ucomioctl;
devclass_t ucom_devclass;
static moduledata_t ucom_mod = {
@ -171,19 +165,25 @@ ucom_attach(struct ucom_softc *sc)
unit = device_get_unit(sc->sc_dev);
sc->sc_tty = tp = ttymalloc(sc->sc_tty);
tp->t_oproc = ucomstart;
tp->t_param = ucomparam;
tp->t_stop = ucomstop;
DPRINTF(("ucom_attach: tty_attach tp = %p\n", tp));
DPRINTF(("ucom_attach: make_dev: ucom%d\n", unit));
sc->sc_tty = tp = ttyalloc();
sc->dev = make_dev(&ucom_cdevsw, unit | UCOM_CALLOUT_MASK,
UID_UUCP, GID_DIALER, 0660,
"ucom%d", unit);
sc->dev->si_tty = tp;
tp->t_dev = sc->dev;
tp->t_sc = sc;
tp->t_oproc = ucomstart;
tp->t_param = ucomparam;
tp->t_stop = ucomstop;
tp->t_break = ucombreak;
tp->t_open = ucomopen;
tp->t_close = ucomclose;
tp->t_modem = ucommodem;
tp->t_ioctl = ucomioctl;
DPRINTF(("ucom_attach: tty_attach tp = %p\n", tp));
DPRINTF(("ucom_attach: make_dev: ucom%d\n", unit));
return (0);
}
@ -197,6 +197,7 @@ ucom_detach(struct ucom_softc *sc)
DPRINTF(("ucom_detach: sc = %p, tp = %p\n", sc, sc->sc_tty));
sc->sc_dying = 1;
ttygone(sc->sc_tty);
if (sc->sc_bulkin_pipe != NULL)
usbd_abort_pipe(sc->sc_bulkin_pipe);
@ -238,475 +239,201 @@ ucom_shutdown(struct ucom_softc *sc)
* notice even if we immediately open the port again.
*/
if (ISSET(tp->t_cflag, HUPCL)) {
(void)ucomctl(sc, TIOCM_DTR, DMBIC);
(void)ucommodem(tp, 0, SER_DTR);
(void)tsleep(sc, TTIPRI, "ucomsd", hz);
}
}
Static int
ucomopen(struct cdev *dev, int flag, int mode, usb_proc_ptr p)
ucomopen(struct tty *tp, struct cdev *dev)
{
int unit = UCOMUNIT(dev);
struct ucom_softc *sc;
usbd_status err;
struct tty *tp;
int s;
int error;
USB_GET_SC_OPEN(ucom, unit, sc);
sc = tp->t_sc;
if (sc->sc_dying)
return (ENXIO);
tp = sc->sc_tty;
DPRINTF(("%s: ucomopen: tp = %p\n", USBDEVNAME(sc->sc_dev), tp));
if (ISSET(tp->t_state, TS_ISOPEN) &&
ISSET(tp->t_state, TS_XCLUDE) &&
suser(p))
return (EBUSY);
sc->sc_poll = 0;
sc->sc_lsr = sc->sc_msr = sc->sc_mcr = 0;
/*
* Do the following iff this is a first open.
*/
s = spltty();
while (sc->sc_opening)
tsleep(&sc->sc_opening, PRIBIO, "ucomop", 0);
sc->sc_opening = 1;
(void)ucommodem(tp, SER_DTR | SER_RTS, 0);
if (!ISSET(tp->t_state, TS_ISOPEN)) {
struct termios t;
sc->sc_poll = 0;
sc->sc_lsr = sc->sc_msr = sc->sc_mcr = 0;
tp->t_dev = dev;
/*
* Initialize the termios status to the defaults. Add in the
* sticky bits from TIOCSFLAGS.
*/
t.c_ispeed = 0;
t.c_ospeed = TTYDEF_SPEED;
t.c_cflag = TTYDEF_CFLAG;
/* Make sure ucomparam() will do something. */
tp->t_ospeed = 0;
(void)ucomparam(tp, &t);
tp->t_iflag = TTYDEF_IFLAG;
tp->t_oflag = TTYDEF_OFLAG;
tp->t_lflag = TTYDEF_LFLAG;
ttychars(tp);
ttsetwater(tp);
/*
* Turn on DTR. We must always do this, even if carrier is not
* present, because otherwise we'd have to use TIOCSDTR
* immediately after setting CLOCAL, which applications do not
* expect. We always assert DTR while the device is open
* unless explicitly requested to deassert it.
*/
(void)ucomctl(sc, TIOCM_DTR | TIOCM_RTS, DMBIS);
/* Device specific open */
if (sc->sc_callback->ucom_open != NULL) {
error = sc->sc_callback->ucom_open(sc->sc_parent,
sc->sc_portno);
if (error) {
ucom_cleanup(sc);
sc->sc_opening = 0;
wakeup(&sc->sc_opening);
splx(s);
return (error);
}
/* Device specific open */
if (sc->sc_callback->ucom_open != NULL) {
error = sc->sc_callback->ucom_open(sc->sc_parent,
sc->sc_portno);
if (error) {
ucom_cleanup(sc);
splx(s);
return (error);
}
DPRINTF(("ucomopen: open pipes in = %d out = %d\n",
sc->sc_bulkin_no, sc->sc_bulkout_no));
/* Open the bulk pipes */
/* Bulk-in pipe */
err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_no, 0,
&sc->sc_bulkin_pipe);
if (err) {
printf("%s: open bulk in error (addr %d): %s\n",
USBDEVNAME(sc->sc_dev), sc->sc_bulkin_no,
usbd_errstr(err));
error = EIO;
goto fail_0;
}
/* Bulk-out pipe */
err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout_no,
USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe);
if (err) {
printf("%s: open bulk out error (addr %d): %s\n",
USBDEVNAME(sc->sc_dev), sc->sc_bulkout_no,
usbd_errstr(err));
error = EIO;
goto fail_1;
}
/* Allocate a request and an input buffer and start reading. */
sc->sc_ixfer = usbd_alloc_xfer(sc->sc_udev);
if (sc->sc_ixfer == NULL) {
error = ENOMEM;
goto fail_2;
}
sc->sc_ibuf = usbd_alloc_buffer(sc->sc_ixfer,
sc->sc_ibufsizepad);
if (sc->sc_ibuf == NULL) {
error = ENOMEM;
goto fail_3;
}
sc->sc_oxfer = usbd_alloc_xfer(sc->sc_udev);
if (sc->sc_oxfer == NULL) {
error = ENOMEM;
goto fail_3;
}
sc->sc_obuf = usbd_alloc_buffer(sc->sc_oxfer,
sc->sc_obufsize +
sc->sc_opkthdrlen);
if (sc->sc_obuf == NULL) {
error = ENOMEM;
goto fail_4;
}
/*
* Handle initial DCD.
*/
if (ISSET(sc->sc_msr, UMSR_DCD) ||
(minor(dev) & UCOM_CALLOUT_MASK))
ttyld_modem(tp, 1);
ucomstartread(sc);
}
sc->sc_opening = 0;
wakeup(&sc->sc_opening);
splx(s);
DPRINTF(("ucomopen: open pipes in = %d out = %d\n",
sc->sc_bulkin_no, sc->sc_bulkout_no));
error = tty_open(dev, tp);
if (error)
goto bad;
/* Open the bulk pipes */
/* Bulk-in pipe */
err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_no, 0,
&sc->sc_bulkin_pipe);
if (err) {
printf("%s: open bulk in error (addr %d): %s\n",
USBDEVNAME(sc->sc_dev), sc->sc_bulkin_no,
usbd_errstr(err));
error = EIO;
goto fail;
}
/* Bulk-out pipe */
err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout_no,
USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe);
if (err) {
printf("%s: open bulk out error (addr %d): %s\n",
USBDEVNAME(sc->sc_dev), sc->sc_bulkout_no,
usbd_errstr(err));
error = EIO;
goto fail;
}
error = ttyld_open(tp, dev);
if (error)
goto bad;
/* Allocate a request and an input buffer and start reading. */
sc->sc_ixfer = usbd_alloc_xfer(sc->sc_udev);
if (sc->sc_ixfer == NULL) {
error = ENOMEM;
goto fail;
}
ttyldoptim(tp);
sc->sc_ibuf = usbd_alloc_buffer(sc->sc_ixfer,
sc->sc_ibufsizepad);
if (sc->sc_ibuf == NULL) {
error = ENOMEM;
goto fail;
}
DPRINTF(("%s: ucomopen: success\n", USBDEVNAME(sc->sc_dev)));
sc->sc_oxfer = usbd_alloc_xfer(sc->sc_udev);
if (sc->sc_oxfer == NULL) {
error = ENOMEM;
goto fail;
}
sc->sc_obuf = usbd_alloc_buffer(sc->sc_oxfer,
sc->sc_obufsize +
sc->sc_opkthdrlen);
if (sc->sc_obuf == NULL) {
error = ENOMEM;
goto fail;
}
ucomstartread(sc);
sc->sc_poll = 1;
sc->sc_refcnt++;
return (0);
fail_4:
usbd_free_xfer(sc->sc_oxfer);
sc->sc_oxfer = NULL;
fail_3:
usbd_free_xfer(sc->sc_ixfer);
sc->sc_ixfer = NULL;
fail_2:
usbd_close_pipe(sc->sc_bulkout_pipe);
sc->sc_bulkout_pipe = NULL;
fail_1:
usbd_close_pipe(sc->sc_bulkin_pipe);
sc->sc_bulkin_pipe = NULL;
fail_0:
sc->sc_opening = 0;
wakeup(&sc->sc_opening);
fail:
splx(s);
return (error);
bad:
if (!ISSET(tp->t_state, TS_ISOPEN)) {
/*
* We failed to open the device, and nobody else had it opened.
* Clean up the state as appropriate.
*/
ucom_cleanup(sc);
}
DPRINTF(("%s: ucomopen: failed\n", USBDEVNAME(sc->sc_dev)));
ucom_cleanup(sc);
return (error);
}
static int
ucomclose(struct cdev *dev, int flag, int mode, usb_proc_ptr p)
static void
ucomclose(struct tty *tp)
{
struct ucom_softc *sc;
struct tty *tp;
int s;
USB_GET_SC(ucom, UCOMUNIT(dev), sc);
sc = tp->t_sc;
tp = sc->sc_tty;
DPRINTF(("%s: ucomclose \n", USBDEVNAME(sc->sc_dev)));
DPRINTF(("%s: ucomclose: unit = %d\n",
USBDEVNAME(sc->sc_dev), UCOMUNIT(dev)));
if (!ISSET(tp->t_state, TS_ISOPEN))
goto quit;
s = spltty();
ttyld_close(tp, flag);
ttyldoptim(tp);
tty_close(tp);
splx(s);
if (sc->sc_dying)
goto quit;
if (!ISSET(tp->t_state, TS_ISOPEN)) {
/*
* Although we got a last close, the device may still be in
* use; e.g. if this was the dialout node, and there are still
* processes waiting for carrier on the non-dialout node.
*/
ucom_cleanup(sc);
}
ucom_cleanup(sc);
if (sc->sc_callback->ucom_close != NULL)
sc->sc_callback->ucom_close(sc->sc_parent, sc->sc_portno);
quit:
if (--sc->sc_refcnt < 0)
usb_detach_wakeup(USBDEV(sc->sc_dev));
return (0);
}
static int
ucomread(struct cdev *dev, struct uio *uio, int flag)
ucomioctl(struct tty *tp, u_long cmd, void *data, int flag, usb_proc_ptr p)
{
struct ucom_softc *sc;
struct tty *tp;
int error;
USB_GET_SC(ucom, UCOMUNIT(dev), sc);
tp = sc->sc_tty;
DPRINTF(("ucomread: tp = %p, flag = 0x%x\n", tp, flag));
if (sc->sc_dying)
return (EIO);
error = ttyld_read(tp, uio, flag);
DPRINTF(("ucomread: error = %d\n", error));
return (error);
}
static int
ucomwrite(struct cdev *dev, struct uio *uio, int flag)
{
struct ucom_softc *sc;
struct tty *tp;
int error;
USB_GET_SC(ucom, UCOMUNIT(dev), sc);
tp = sc->sc_tty;
DPRINTF(("ucomwrite: tp = %p, flag = 0x%x\n", tp, flag));
if (sc->sc_dying)
return (EIO);
error = ttyld_write(tp, uio, flag);
DPRINTF(("ucomwrite: error = %d\n", error));
return (error);
}
static int
ucomioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
{
struct ucom_softc *sc;
struct tty *tp;
int error;
int s;
int d;
#if defined(COMPAT_43)
u_long oldcmd;
struct termios term;
#endif
USB_GET_SC(ucom, UCOMUNIT(dev), sc);
tp = sc->sc_tty;
sc = tp->t_sc;;
if (sc->sc_dying)
return (EIO);
DPRINTF(("ucomioctl: cmd = 0x%08lx\n", cmd));
#if defined(COMPAT_43)
term = tp->t_termios;
oldcmd = cmd;
error = ttsetcompat(tp, &cmd, data, &term);
if (error != 0)
return (error);
if (cmd != oldcmd)
data = (caddr_t)&term;
#endif
error = ttyioctl(dev, cmd, data, flag, p);
ttyldoptim(tp);
if (error != ENOTTY) {
DPRINTF(("ucomioctl: l_ioctl: error = %d\n", error));
return (error);
}
s = spltty();
if (sc->sc_callback->ucom_ioctl != NULL) {
error = ENOTTY;
if (sc->sc_callback->ucom_ioctl != NULL)
error = sc->sc_callback->ucom_ioctl(sc->sc_parent,
sc->sc_portno,
cmd, data, flag, p);
if (error >= 0)
return (error);
}
error = 0;
DPRINTF(("ucomioctl: our cmd = 0x%08lx\n", cmd));
switch (cmd) {
case TIOCSBRK:
DPRINTF(("ucomioctl: TIOCSBRK\n"));
ucom_break(sc, 1);
break;
case TIOCCBRK:
DPRINTF(("ucomioctl: TIOCCBRK\n"));
ucom_break(sc, 0);
break;
case TIOCSDTR:
DPRINTF(("ucomioctl: TIOCSDTR\n"));
(void)ucomctl(sc, TIOCM_DTR, DMBIS);
break;
case TIOCCDTR:
DPRINTF(("ucomioctl: TIOCCDTR\n"));
(void)ucomctl(sc, TIOCM_DTR, DMBIC);
break;
case TIOCMSET:
d = *(int *)data;
DPRINTF(("ucomioctl: TIOCMSET, 0x%x\n", d));
(void)ucomctl(sc, d, DMSET);
break;
case TIOCMBIS:
d = *(int *)data;
DPRINTF(("ucomioctl: TIOCMBIS, 0x%x\n", d));
(void)ucomctl(sc, d, DMBIS);
break;
case TIOCMBIC:
d = *(int *)data;
DPRINTF(("ucomioctl: TIOCMBIC, 0x%x\n", d));
(void)ucomctl(sc, d, DMBIC);
break;
case TIOCMGET:
d = ucomctl(sc, 0, DMGET);
DPRINTF(("ucomioctl: TIOCMGET, 0x%x\n", d));
*(int *)data = d;
break;
default:
DPRINTF(("ucomioctl: error: our cmd = 0x%08lx\n", cmd));
error = ENOTTY;
break;
}
splx(s);
return (error);
}
Static int
ucomctl(struct ucom_softc *sc, int bits, int how)
ucommodem(struct tty *tp, int sigon, int sigoff)
{
struct ucom_softc *sc;
int mcr;
int msr;
int onoff;
DPRINTF(("ucomctl: bits = 0x%x, how = %d\n", bits, how));
if (how == DMGET) {
SET(bits, TIOCM_LE); /* always set TIOCM_LE bit */
DPRINTF(("ucomctl: DMGET: LE"));
sc = tp->t_sc;
if (sigon == 0 && sigoff == 0) {
mcr = sc->sc_mcr;
if (ISSET(mcr, UMCR_DTR)) {
SET(bits, TIOCM_DTR);
DPRINTF((" DTR"));
}
if (ISSET(mcr, UMCR_RTS)) {
SET(bits, TIOCM_RTS);
DPRINTF((" RTS"));
}
if (ISSET(mcr, SER_DTR))
sigon |= SER_DTR;
if (ISSET(mcr, SER_RTS))
sigon |= SER_RTS;
msr = sc->sc_msr;
if (ISSET(msr, UMSR_CTS)) {
SET(bits, TIOCM_CTS);
DPRINTF((" CTS"));
}
if (ISSET(msr, UMSR_DCD)) {
SET(bits, TIOCM_CD);
DPRINTF((" CD"));
}
if (ISSET(msr, UMSR_DSR)) {
SET(bits, TIOCM_DSR);
DPRINTF((" DSR"));
}
if (ISSET(msr, UMSR_RI)) {
SET(bits, TIOCM_RI);
DPRINTF((" RI"));
}
DPRINTF(("\n"));
return (bits);
if (ISSET(msr, SER_CTS))
sigon |= SER_CTS;
if (ISSET(msr, SER_DCD))
sigon |= SER_DCD;
if (ISSET(msr, SER_DSR))
sigon |= SER_DSR;
if (ISSET(msr, SER_RI))
sigon |= SER_RI;
return (sigon);
}
mcr = 0;
if (ISSET(bits, TIOCM_DTR))
SET(mcr, UMCR_DTR);
if (ISSET(bits, TIOCM_RTS))
SET(mcr, UMCR_RTS);
mcr = sc->sc_mcr;
if (ISSET(sigon, SER_DTR))
mcr |= SER_DTR;
if (ISSET(sigoff, SER_DTR))
mcr &= ~SER_DTR;
if (ISSET(sigon, SER_RTS))
mcr |= SER_RTS;
if (ISSET(sigoff, SER_RTS))
mcr &= ~SER_RTS;
sc->sc_mcr = mcr;
switch (how) {
case DMSET:
sc->sc_mcr = mcr;
break;
case DMBIS:
sc->sc_mcr |= mcr;
break;
case DMBIC:
sc->sc_mcr &= ~mcr;
break;
}
onoff = ISSET(sc->sc_mcr, UMCR_DTR) ? 1 : 0;
onoff = ISSET(sc->sc_mcr, SER_DTR) ? 1 : 0;
ucom_dtr(sc, onoff);
onoff = ISSET(sc->sc_mcr, UMCR_RTS) ? 1 : 0;
onoff = ISSET(sc->sc_mcr, SER_RTS) ? 1 : 0;
ucom_rts(sc, onoff);
return (0);
}
Static void
ucom_break(struct ucom_softc *sc, int onoff)
ucombreak(struct tty *tp, int onoff)
{
DPRINTF(("ucom_break: onoff = %d\n", onoff));
struct ucom_softc *sc;
sc = tp->t_sc;
DPRINTF(("ucombreak: onoff = %d\n", onoff));
if (sc->sc_callback->ucom_set == NULL)
return;
sc->sc_callback->ucom_set(sc->sc_parent, sc->sc_portno,
@ -751,10 +478,10 @@ ucom_status_change(struct ucom_softc *sc)
old_msr = sc->sc_msr;
sc->sc_callback->ucom_get_status(sc->sc_parent, sc->sc_portno,
&sc->sc_lsr, &sc->sc_msr);
if (ISSET((sc->sc_msr ^ old_msr), UMSR_DCD)) {
if (ISSET((sc->sc_msr ^ old_msr), SER_DCD)) {
if (sc->sc_poll == 0)
return;
onoff = ISSET(sc->sc_msr, UMSR_DCD) ? 1 : 0;
onoff = ISSET(sc->sc_msr, SER_DCD) ? 1 : 0;
DPRINTF(("ucom_status_change: DCD changed to %d\n", onoff));
ttyld_modem(tp, onoff);
}
@ -767,7 +494,7 @@ ucomparam(struct tty *tp, struct termios *t)
int error;
usbd_status uerr;
USB_GET_SC(ucom, UCOMUNIT(tp->t_dev), sc);
sc = tp->t_sc;
if (sc->sc_dying)
return (EIO);
@ -815,7 +542,7 @@ ucomparam(struct tty *tp, struct termios *t)
sc->sc_state |= UCS_RTS_IFLOW;
} else if (sc->sc_state & UCS_RTS_IFLOW) {
sc->sc_state &= ~UCS_RTS_IFLOW;
(void)ucomctl(sc, UMCR_RTS, DMBIS);
(void)ucommodem(tp, SER_RTS, 0);
}
ttyldoptim(tp);
@ -837,7 +564,7 @@ ucomstart(struct tty *tp)
u_char *data;
int cnt;
USB_GET_SC(ucom, UCOMUNIT(tp->t_dev), sc);
sc = tp->t_sc;
DPRINTF(("ucomstart: sc = %p\n", sc));
if (sc->sc_dying)
@ -846,17 +573,17 @@ ucomstart(struct tty *tp)
s = spltty();
if (tp->t_state & TS_TBLOCK) {
if (ISSET(sc->sc_mcr, UMCR_RTS) &&
if (ISSET(sc->sc_mcr, SER_RTS) &&
ISSET(sc->sc_state, UCS_RTS_IFLOW)) {
DPRINTF(("ucomstart: clear RTS\n"));
(void)ucomctl(sc, UMCR_RTS, DMBIC);
(void)ucommodem(tp, 0, SER_RTS);
}
} else {
if (!ISSET(sc->sc_mcr, UMCR_RTS) &&
if (!ISSET(sc->sc_mcr, SER_RTS) &&
tp->t_rawq.c_cc <= tp->t_ilowat &&
ISSET(sc->sc_state, UCS_RTS_IFLOW)) {
DPRINTF(("ucomstart: set RTS\n"));
(void)ucomctl(sc, UMCR_RTS, DMBIS);
(void)ucommodem(tp, SER_RTS, 0);
}
}
@ -925,7 +652,7 @@ ucomstop(struct tty *tp, int flag)
struct ucom_softc *sc;
int s;
USB_GET_SC(ucom, UCOMUNIT(tp->t_dev), sc);
sc = tp->t_sc;
DPRINTF(("ucomstop: %d\n", flag));
@ -1109,9 +836,9 @@ ucomreadcb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status)
/* XXX what should we dow now? */
}
if ((sc->sc_state & UCS_RTS_IFLOW) && !ISSET(sc->sc_mcr, UMCR_RTS)
if ((sc->sc_state & UCS_RTS_IFLOW) && !ISSET(sc->sc_mcr, SER_RTS)
&& !(tp->t_state & TS_TBLOCK))
ucomctl(sc, UMCR_RTS, DMBIS);
ucommodem(tp, SER_RTS, 0);
}
Static void

View File

@ -104,10 +104,6 @@ struct ucom_callback {
void (*ucom_write)(void *, int, u_char *, u_char *, u_int32_t *);
};
/* modem control register */
#define UMCR_RTS 0x02 /* Request To Send */
#define UMCR_DTR 0x01 /* Data Terminal Ready */
/* line status register */
#define ULSR_RCV_FIFO 0x80
#define ULSR_TSRE 0x40 /* Transmitter empty: byte sent */
@ -119,17 +115,6 @@ struct ucom_callback {
#define ULSR_RXRDY 0x01 /* Byte ready in Receive Buffer */
#define ULSR_RCV_MASK 0x1f /* Mask for incoming data or error */
/* modem status register */
/* All deltas are from the last read of the MSR. */
#define UMSR_DCD 0x80 /* Current Data Carrier Detect */
#define UMSR_RI 0x40 /* Current Ring Indicator */
#define UMSR_DSR 0x20 /* Current Data Set Ready */
#define UMSR_CTS 0x10 /* Current Clear to Send */
#define UMSR_DDCD 0x08 /* DCD has changed state */
#define UMSR_TERI 0x04 /* RI has toggled low to high */
#define UMSR_DDSR 0x02 /* DSR has changed state */
#define UMSR_DCTS 0x01 /* CTS has changed state */
/* ucom state declarations */
#define UCS_RXSTOP 0x0001 /* Rx stopped */
#define UCS_RTS_IFLOW 0x0008 /* use RTS input flow control */
@ -168,7 +153,6 @@ struct ucom_softc {
u_char sc_msr;
u_char sc_mcr;
u_char sc_opening; /* lock during open */
int sc_refcnt;
u_char sc_dying; /* disconnecting */

View File

@ -85,6 +85,7 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/ioccom.h>
#include <sys/conf.h>
#include <sys/serial.h>
#include <sys/tty.h>
#include <sys/file.h>
#include <sys/select.h>
@ -515,11 +516,11 @@ umodem_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
mstatus = sc->sc_notify_buf.data[0];
if (ISSET(mstatus, UCDC_N_SERIAL_RI))
sc->sc_msr |= UMSR_RI;
sc->sc_msr |= SER_RI;
if (ISSET(mstatus, UCDC_N_SERIAL_DSR))
sc->sc_msr |= UMSR_DSR;
sc->sc_msr |= SER_DSR;
if (ISSET(mstatus, UCDC_N_SERIAL_DCD))
sc->sc_msr |= UMSR_DCD;
sc->sc_msr |= SER_DCD;
ucom_status_change(&sc->sc_ucom);
break;
default:

View File

@ -84,6 +84,7 @@ __FBSDID("$FreeBSD$");
#include <sys/ioccom.h>
#include <sys/fcntl.h>
#include <sys/conf.h>
#include <sys/serial.h>
#include <sys/tty.h>
#include <sys/file.h>
#if __FreeBSD_version >= 500014
@ -799,9 +800,9 @@ uplcom_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
sc->sc_lsr = sc->sc_msr = 0;
pstatus = buf[8];
if (ISSET(pstatus, RSAQ_STATUS_DSR))
sc->sc_msr |= UMSR_DSR;
sc->sc_msr |= SER_DSR;
if (ISSET(pstatus, RSAQ_STATUS_DCD))
sc->sc_msr |= UMSR_DCD;
sc->sc_msr |= SER_DCD;
ucom_status_change(&sc->sc_ucom);
}

View File

@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/fcntl.h>
#include <sys/conf.h>
#include <sys/serial.h>
#include <sys/tty.h>
#include <sys/file.h>
#if defined(__FreeBSD__)
@ -897,11 +898,11 @@ uvscom_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
pstatus = buf[1];
if (ISSET(pstatus, UVSCOM_CTS))
SET(sc->sc_msr, UMSR_CTS);
SET(sc->sc_msr, SER_CTS);
if (ISSET(pstatus, UVSCOM_DSR))
SET(sc->sc_msr, UMSR_DSR);
SET(sc->sc_msr, SER_DSR);
if (ISSET(pstatus, UVSCOM_DCD))
SET(sc->sc_msr, UMSR_DCD);
SET(sc->sc_msr, SER_DCD);
ucom_status_change(&sc->sc_ucom);
}