summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2005-01-10 08:17:50 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2005-01-10 08:17:50 +0000
commitb250c4850e56452d320693c95dc898378af9ff01 (patch)
treefa668624fdce6a8a98e7eaefde61f0e2c0102bac
parent23dcb10420287a329736afdb20c21735420d3468 (diff)
add support for calling units (cuaU*)
-rw-r--r--sys/dev/usb/ucom.c198
-rw-r--r--sys/dev/usb/ucomvar.h6
2 files changed, 78 insertions, 126 deletions
diff --git a/sys/dev/usb/ucom.c b/sys/dev/usb/ucom.c
index bcb601a7720..97793f96eb2 100644
--- a/sys/dev/usb/ucom.c
+++ b/sys/dev/usb/ucom.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ucom.c,v 1.21 2004/07/08 22:18:44 deraadt Exp $ */
+/* $OpenBSD: ucom.c,v 1.22 2005/01/10 08:17:49 dlg Exp $ */
/* $NetBSD: ucom.c,v 1.49 2003/01/01 00:10:25 thorpej Exp $ */
/*
@@ -53,12 +53,6 @@
#include <sys/vnode.h>
#include <sys/device.h>
#include <sys/poll.h>
-#if defined(__NetBSD__)
-#include "rnd.h"
-#if NRND > 0
-#include <sys/rnd.h>
-#endif
-#endif
#include <dev/usb/usb.h>
@@ -74,32 +68,20 @@
#if NUCOM > 0
#ifdef UCOM_DEBUG
-#define DPRINTFN(n, x) do { if (ucomdebug > (n)) logprintf x; } while (0)
+#define DPRINTFN(n, x) do { if (ucomdebug > (n)) printf x; } while (0)
int ucomdebug = 0;
#else
#define DPRINTFN(n, x)
#endif
#define DPRINTF(x) DPRINTFN(0, x)
-#if defined(__NetBSD__)
-#define UCOMUNIT_MASK 0x3ffff
-#define UCOMDIALOUT_MASK 0x80000
-#define UCOMCALLUNIT_MASK 0x40000
-
-#define LINESW(tp, func) ((tp)->t_linesw->func)
-#endif
-
-#if defined(__OpenBSD__)
-#define UCOMUNIT_MASK 0x3f
-#define UCOMDIALOUT_MASK 0x80
-#define UCOMCALLUNIT_MASK 0x40
+#define UCOMUNIT_MASK 0x7f
+#define UCOMCUA_MASK 0x80
#define LINESW(tp, func) (linesw[(tp)->t_line].func)
-#endif
#define UCOMUNIT(x) (minor(x) & UCOMUNIT_MASK)
-#define UCOMDIALOUT(x) (minor(x) & UCOMDIALOUT_MASK)
-#define UCOMCALLUNIT(x) (minor(x) & UCOMCALLUNIT_MASK)
+#define UCOMCUA(x) (minor(x) & UCOMCUA_MASK)
struct ucom_softc {
USBBASEDEVICE sc_dev; /* base device */
@@ -134,31 +116,13 @@ struct ucom_softc {
u_char sc_tx_stopped;
int sc_swflags;
+ u_char sc_cua;
+
u_char sc_opening; /* lock during open */
int sc_refcnt;
u_char sc_dying; /* disconnecting */
-
-#if defined(__NetBSD__) && NRND > 0
- rndsource_element_t sc_rndsource; /* random source */
-#endif
};
-#if defined(__NetBSD__)
-dev_type_open(ucomopen);
-dev_type_close(ucomclose);
-dev_type_read(ucomread);
-dev_type_write(ucomwrite);
-dev_type_ioctl(ucomioctl);
-dev_type_stop(ucomstop);
-dev_type_tty(ucomtty);
-dev_type_poll(ucompoll);
-
-const struct cdevsw ucom_cdevsw = {
- ucomopen, ucomclose, ucomread, ucomwrite, ucomioctl,
- ucomstop, ucomtty, ucompoll, nommap, ttykqfilter, D_TTY
-};
-#endif
-
Static void ucom_cleanup(struct ucom_softc *);
Static void ucom_hwiflow(struct ucom_softc *);
Static int ucomparam(struct tty *, struct termios *);
@@ -210,16 +174,7 @@ USB_ATTACH(ucom)
tp->t_oproc = ucomstart;
tp->t_param = ucomparam;
sc->sc_tty = tp;
-
-#ifndef __OpenBSD__
- DPRINTF(("ucom_attach: tty_attach %p\n", tp));
- tty_attach(tp);
-#endif
-
-#if defined(__NetBSD__) && NRND > 0
- rnd_attach_source(&sc->sc_rndsource, USBDEVNAME(sc->sc_dev),
- RND_TYPE_TTY, 0);
-#endif
+ sc->sc_cua = 0;
USB_ATTACH_SUCCESS_RETURN;
}
@@ -254,37 +209,23 @@ USB_DETACH(ucom)
}
splx(s);
-#if defined(__NetBSD__)
- /* locate the major number */
- maj = cdevsw_lookup_major(&ucom_cdevsw);
-#else
/* locate the major number */
for (maj = 0; maj < nchrdev; maj++)
if (cdevsw[maj].d_open == ucomopen)
break;
-#endif
/* Nuke the vnodes for any open instances. */
mn = self->dv_unit;
DPRINTF(("ucom_detach: maj=%d mn=%d\n", maj, mn));
vdevgone(maj, mn, mn, VCHR);
- vdevgone(maj, mn | UCOMDIALOUT_MASK, mn | UCOMDIALOUT_MASK, VCHR);
- vdevgone(maj, mn | UCOMCALLUNIT_MASK, mn | UCOMCALLUNIT_MASK, VCHR);
+ vdevgone(maj, mn | UCOMCUA_MASK, mn | UCOMCUA_MASK, VCHR);
/* Detach and free the tty. */
if (tp != NULL) {
-#ifndef __OpenBSD__
- tty_detach(tp);
-#endif
ttyfree(tp);
sc->sc_tty = NULL;
}
- /* Detach the random source */
-#if defined(__NetBSD__) && NRND > 0
- rnd_detach_source(&sc->sc_rndsource);
-#endif
-
return (0);
}
@@ -329,6 +270,7 @@ ucomopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
usbd_status err;
struct ucom_softc *sc;
struct tty *tp;
+ struct termios t;
int s;
int error;
@@ -345,40 +287,26 @@ ucomopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
return (ENXIO);
tp = sc->sc_tty;
-
DPRINTF(("ucomopen: unit=%d, tp=%p\n", unit, tp));
- if (ISSET(tp->t_state, TS_ISOPEN) &&
- ISSET(tp->t_state, TS_XCLUDE) &&
- p->p_ucred->cr_uid != 0)
- return (EBUSY);
-
- s = spltty();
-
/*
- * Do the following iff this is a first open.
+ * Do the following if this is a first open.
*/
while (sc->sc_opening)
tsleep(&sc->sc_opening, PRIBIO, "ucomop", 0);
if (sc->sc_dying) {
- splx(s);
return (EIO);
}
sc->sc_opening = 1;
-#if defined(__NetBSD__)
- if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
-#else
+ tp->t_dev = dev;
if (!ISSET(tp->t_state, TS_ISOPEN)) {
-#endif
- struct termios t;
-
- tp->t_dev = dev;
+ SET(tp->t_state, TS_WOPEN);
if (sc->sc_methods->ucom_open != NULL) {
error = sc->sc_methods->ucom_open(sc->sc_parent,
- sc->sc_portno);
+ sc->sc_portno);
if (error) {
ucom_cleanup(sc);
sc->sc_opening = 0;
@@ -403,6 +331,7 @@ ucomopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
SET(t.c_cflag, CRTSCTS);
if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF))
SET(t.c_cflag, MDMBUF);
+
/* Make sure ucomparam() will do something. */
tp->t_ospeed = 0;
(void) ucomparam(tp, &t);
@@ -412,6 +341,8 @@ ucomopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
ttychars(tp);
ttsetwater(tp);
+ s = spltty();
+
/*
* Turn on DTR. We must always do this, even if carrier is not
* present, because otherwise we'd have to use TIOCSDTR
@@ -419,7 +350,7 @@ ucomopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
* expect. We always assert DTR while the device is open
* unless explicitly requested to deassert it.
*/
- ucom_dtr(sc, 1);
+ //ucom_dtr(sc, 1);
/* XXX CLR(sc->sc_rx_flags, RX_ANY_BLOCK);*/
ucom_hwiflow(sc);
@@ -476,16 +407,62 @@ ucomopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
}
ucomstartread(sc);
+
+ if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) || UCOMCUA(dev) ||
+ ISSET(sc->sc_msr, UMSR_DCD) || ISSET(tp->t_cflag, MDMBUF))
+ SET(tp->t_state, TS_CARR_ON);
+ else
+ CLR(tp->t_state, TS_CARR_ON);
+
+ } else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0)
+ return (EBUSY);
+ else
+ s = spltty();
+
+ if (UCOMCUA(dev)) {
+ if (ISSET(tp->t_state, TS_ISOPEN)) {
+ /* Someone is already dialed in */
+ splx(s);
+ return (EBUSY);
+ }
+ sc->sc_cua = 1;
+ } else {
+ /* tty (not cua) device, wait for carrier */
+ if (ISSET(flag, O_NONBLOCK)) {
+ if (sc->sc_cua) {
+ splx(s);
+ return (EBUSY);
+ }
+ } else {
+ while (sc->sc_cua || (!ISSET(tp->t_cflag, CLOCAL) &&
+ !ISSET(tp->t_state, TS_CARR_ON))) {
+ SET(tp->t_state, TS_WOPEN);
+ error = ttysleep(tp, &tp->t_rawq,
+ TTIPRI | PCATCH, ttopen, 0);
+ /*
+ * If TS_WOPEN has been reset, that means the
+ * cua device has been closed. We don't want
+ * to fail in that case, so just go around
+ * again.
+ */
+ if (error && ISSET(tp->t_state, TS_WOPEN)) {
+ CLR(tp->t_state, TS_WOPEN);
+ if (!sc->sc_cua &&
+ !ISSET(tp->t_state, TS_ISOPEN))
+ ucom_cleanup(sc);
+ splx(s);
+ return (error);
+ }
+ }
+ }
}
+
sc->sc_opening = 0;
wakeup(&sc->sc_opening);
splx(s);
-#if defined(__NetBSD__)
- error = ttyopen(tp, UCOMDIALOUT(dev), ISSET(flag, O_NONBLOCK));
-#else
- error = ttyopen(UCOMDIALOUT(dev), tp);
-#endif
+
+ error = ttyopen(UCOMUNIT(dev), tp);
if (error)
goto bad;
@@ -514,11 +491,7 @@ fail_0:
return (error);
bad:
-#if defined(__NetBSD__)
- if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
-#else
if (!ISSET(tp->t_state, TS_ISOPEN)) {
-#endif
/*
* We failed to open the device, and nobody else had it opened.
* Clean up the state as appropriate.
@@ -534,6 +507,7 @@ ucomclose(dev_t dev, int flag, int mode, usb_proc_ptr p)
{
struct ucom_softc *sc = ucom_cd.cd_devs[UCOMUNIT(dev)];
struct tty *tp = sc->sc_tty;
+ int s;
DPRINTF(("ucomclose: unit=%d\n", UCOMUNIT(dev)));
if (!ISSET(tp->t_state, TS_ISOPEN))
@@ -542,13 +516,8 @@ ucomclose(dev_t dev, int flag, int mode, usb_proc_ptr p)
sc->sc_refcnt++;
(*LINESW(tp, l_close))(tp, flag);
- ttyclose(tp);
-
-#if defined(__NetBSD__)
- if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
-#else
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
-#endif
+ s = spltty();
+ if (!ISSET(tp->t_state, TS_WOPEN)) {
/*
* 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
@@ -556,6 +525,10 @@ ucomclose(dev_t dev, int flag, int mode, usb_proc_ptr p)
*/
ucom_cleanup(sc);
}
+ CLR(tp->t_state, TS_BUSY | TS_FLUSH);
+ sc->sc_cua = 0;
+ splx(s);
+ ttyclose(tp);
if (sc->sc_methods->ucom_close != NULL)
sc->sc_methods->ucom_close(sc->sc_parent, sc->sc_portno);
@@ -996,11 +969,7 @@ out:
splx(s);
}
-#if defined(__NetBSD__)
-void
-#else
int
-#endif
ucomstop(struct tty *tp, int flag)
{
DPRINTF(("ucomstop: flag=%d\n", flag));
@@ -1017,9 +986,7 @@ ucomstop(struct tty *tp, int flag)
}
splx(s);
#endif
-#if !defined(__NetBSD__)
return (0);
-#endif
}
Static void
@@ -1043,9 +1010,7 @@ ucomwritecb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status)
}
usbd_get_xfer_status(xfer, NULL, NULL, &cc, NULL);
-#if defined(__NetBSD__) && NRND > 0
- rnd_add_uint32(&sc->sc_rndsource, cc);
-#endif
+
DPRINTFN(5,("ucomwritecb: cc=%d\n", cc));
/* convert from USB bytes to tty bytes */
cc -= sc->sc_opkthdrlen;
@@ -1116,9 +1081,6 @@ ucomreadcb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status)
}
usbd_get_xfer_status(xfer, NULL, (void *)&cp, &cc, NULL);
-#if defined(__NetBSD__) && NRND > 0
- rnd_add_uint32(&sc->sc_rndsource, cc);
-#endif
DPRINTFN(5,("ucomreadcb: got %d chars, tp=%p\n", cc, tp));
if (sc->sc_methods->ucom_read != NULL)
sc->sc_methods->ucom_read(sc->sc_parent, sc->sc_portno,
@@ -1185,16 +1147,10 @@ ucomprint(void *aux, const char *pnp)
}
int
-#if defined(__OpenBSD__)
ucomsubmatch(struct device *parent, void *match, void *aux)
-#else
-ucomsubmatch(struct device *parent, struct cfdata *cf, void *aux)
-#endif
{
struct ucom_attach_args *uca = aux;
-#if defined(__OpenBSD__)
struct cfdata *cf = match;
-#endif
if (uca->portno != UCOM_UNK_PORTNO &&
cf->ucomcf_portno != UCOM_UNK_PORTNO &&
diff --git a/sys/dev/usb/ucomvar.h b/sys/dev/usb/ucomvar.h
index da0957ae539..9777b811cd7 100644
--- a/sys/dev/usb/ucomvar.h
+++ b/sys/dev/usb/ucomvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ucomvar.h,v 1.11 2002/07/10 03:09:34 nate Exp $ */
+/* $OpenBSD: ucomvar.h,v 1.12 2005/01/10 08:17:49 dlg Exp $ */
/* $NetBSD: ucomvar.h,v 1.10 2001/12/31 12:15:21 augustss Exp $ */
/*
@@ -110,11 +110,7 @@ struct ucom_attach_args {
void *arg;
};
-#if defined(__NetBSD__)
-int ucomsubmatch(struct device *, struct cfdata *, void *);
-#else
int ucomsubmatch(struct device *, void *, void *);
-#endif
int ucomprint(void *aux, const char *pnp);
void ucom_status_change(struct ucom_softc *);