summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorGarrett D'Amore <Garrett.Damore@Sun.COM>2009-07-13 23:43:45 -0700
committerGarrett D'Amore <Garrett.Damore@Sun.COM>2009-07-13 23:43:45 -0700
commit349dcea37d1dc6e491c49c864c5e3773a4e3cae6 (patch)
tree4eebdc20eec12c6dcffdb2ee9a2694b75b918d5a /usr
parentf0109389f635b59e47ad74e20059ea4283d73103 (diff)
downloadillumos-gate-349dcea37d1dc6e491c49c864c5e3773a4e3cae6.tar.gz
PSARC/2009/380 STREAMS and Character Device Coexistence
6858144 implement STREAMS/character device coexistence (PSARC 2009/380)
Diffstat (limited to 'usr')
-rw-r--r--usr/src/uts/common/fs/specfs/specsubr.c8
-rw-r--r--usr/src/uts/common/fs/specfs/specvnops.c40
-rw-r--r--usr/src/uts/common/os/driver_lyr.c10
3 files changed, 33 insertions, 25 deletions
diff --git a/usr/src/uts/common/fs/specfs/specsubr.c b/usr/src/uts/common/fs/specfs/specsubr.c
index 9ae689c696..c43b4bd921 100644
--- a/usr/src/uts/common/fs/specfs/specsubr.c
+++ b/usr/src/uts/common/fs/specfs/specsubr.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,8 +37,6 @@
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/t_lock.h>
#include <sys/param.h>
@@ -740,7 +738,7 @@ spec_maxoffset(struct vnode *vp)
struct snode *sp = VTOS(vp);
struct snode *csp = VTOS(sp->s_commonvp);
- if (STREAMSTAB(getmajor(sp->s_dev)))
+ if (vp->v_stream)
return ((offset_t)-1);
else if (csp->s_flag & SANYOFFSET) /* D_U64BIT */
return ((offset_t)-1);
@@ -847,7 +845,7 @@ device_close(struct vnode *vp, int flag, struct cred *cr)
switch (type) {
case VCHR:
- if (STREAMSTAB(getmajor(dev))) {
+ if (vp->v_stream) {
if (cvp->v_stream != NULL)
error = strclose(cvp, flag, cr);
vp->v_stream = NULL;
diff --git a/usr/src/uts/common/fs/specfs/specvnops.c b/usr/src/uts/common/fs/specfs/specvnops.c
index 94183f2f76..de3aae70fa 100644
--- a/usr/src/uts/common/fs/specfs/specvnops.c
+++ b/usr/src/uts/common/fs/specfs/specvnops.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -637,10 +637,21 @@ spec_open(struct vnode **vpp, int flag, struct cred *cr, caller_context_t *cc)
(devopsp[maj]->devo_cb_ops->cb_open == NULL))
return (ENXIO);
- /* split streams .vs. non-streams */
- if (STREAMSTAB(maj))
+ /*
+ * split STREAMS vs. non-STREAMS
+ *
+ * If the device is a dual-personality device, then we might want
+ * to allow for a regular OTYP_BLK open. If however it's strictly
+ * a pure STREAMS device, the cb_open entry point will be
+ * nodev() which returns ENXIO. This does make this failure path
+ * somewhat longer, but such attempts to use OTYP_BLK with STREAMS
+ * devices should be exceedingly rare. (Most of the time they will
+ * be due to programmer error.)
+ */
+ if ((vp->v_type == VCHR) && (STREAMSTAB(maj)))
goto streams_open;
+not_streams:
/*
* Wait for in progress last close to complete. This guarantees
* to the driver writer that we will never be in the drivers
@@ -751,9 +762,6 @@ spec_open(struct vnode **vpp, int flag, struct cred *cr, caller_context_t *cc)
return (error);
streams_open:
- if (vp->v_type != VCHR)
- return (ENXIO);
-
/*
* Lock common snode to prevent any new clone opens on this
* stream while one is in progress. This is necessary since
@@ -846,6 +854,14 @@ streams_open:
SN_RELE(csp);
}
+ /*
+ * Resolution for STREAMS vs. regular character device: If the
+ * STREAMS open(9e) returns ENOSTR, then try an ordinary device
+ * open instead.
+ */
+ if (error == ENOSTR) {
+ goto not_streams;
+ }
return (error);
}
@@ -972,7 +988,7 @@ spec_read(
ASSERT(vp->v_type == VCHR || vp->v_type == VBLK);
- if (STREAMSTAB(getmajor(dev))) { /* stream */
+ if (vp->v_stream) {
ASSERT(vp->v_type == VCHR);
smark(sp, SACC);
return (strread(vp, uiop, cr));
@@ -994,7 +1010,7 @@ spec_read(
if (vp->v_type == VCHR) {
smark(sp, SACC);
- ASSERT(STREAMSTAB(getmajor(dev)) == 0);
+ ASSERT(vp->v_stream == NULL);
return (cdev_read(dev, uiop, cr));
}
@@ -1078,7 +1094,7 @@ spec_write(
ASSERT(vp->v_type == VCHR || vp->v_type == VBLK);
- if (STREAMSTAB(getmajor(dev))) {
+ if (vp->v_stream) {
ASSERT(vp->v_type == VCHR);
smark(sp, SUPD);
return (strwrite(vp, uiop, cr));
@@ -1097,7 +1113,7 @@ spec_write(
if (vp->v_type == VCHR) {
smark(sp, SUPD);
- ASSERT(STREAMSTAB(getmajor(dev)) == 0);
+ ASSERT(vp->v_stream == NULL);
return (cdev_write(dev, uiop, cr));
}
@@ -1258,7 +1274,7 @@ spec_ioctl(struct vnode *vp, int cmd, intptr_t arg, int mode, struct cred *cr,
sp = VTOS(vp);
dev = sp->s_dev;
- if (STREAMSTAB(getmajor(dev))) {
+ if (vp->v_stream) {
error = strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp);
} else {
error = cdev_ioctl(dev, cmd, arg, mode, cr, rvalp);
@@ -2210,7 +2226,7 @@ spec_poll(
else {
ASSERT(vp->v_type == VCHR);
dev = vp->v_rdev;
- if (STREAMSTAB(getmajor(dev))) {
+ if (vp->v_stream) {
ASSERT(vp->v_stream != NULL);
error = strpoll(vp->v_stream, events, anyyet,
reventsp, phpp);
diff --git a/usr/src/uts/common/os/driver_lyr.c b/usr/src/uts/common/os/driver_lyr.c
index 525fd399cc..fafb02ad89 100644
--- a/usr/src/uts/common/os/driver_lyr.c
+++ b/usr/src/uts/common/os/driver_lyr.c
@@ -382,7 +382,7 @@ handle_alloc(vnode_t *vp, struct ldi_ident *ident)
/* set the device type for this handle */
lhp->lh_type = 0;
- if (STREAMSTAB(getmajor(vp->v_rdev))) {
+ if (vp->v_stream) {
ASSERT(vp->v_type == VCHR);
lhp->lh_type |= LH_STREAM;
} else {
@@ -524,11 +524,6 @@ ldi_vp_from_dev(dev_t dev, int otyp, vnode_t **vpp)
if ((dip = e_ddi_hold_devi_by_dev(dev, 0)) == NULL)
return (ENODEV);
- if (STREAMSTAB(getmajor(dev)) && (otyp != OTYP_CHR)) {
- ddi_release_devi(dip); /* from e_ddi_hold_devi_by_dev */
- return (ENXIO);
- }
-
vp = makespecvp(dev, OTYP_TO_VTYP(otyp));
spec_assoc_vp_with_devi(vp, dip);
ddi_release_devi(dip); /* from e_ddi_hold_devi_by_dev */
@@ -3236,8 +3231,7 @@ ldi_ev_register_callbacks(ldi_handle_t lh, ldi_ev_cookie_t cookie,
*/
lecp->lec_lhp = lhp;
lecp->lec_dev = lhp->lh_vp->v_rdev;
- lecp->lec_spec = (lhp->lh_vp->v_type == VCHR) ?
- S_IFCHR : S_IFBLK;
+ lecp->lec_spec = VTYP_TO_STYP(lhp->lh_vp->v_type);
lecp->lec_notify = callb->cb_notify;
lecp->lec_finalize = callb->cb_finalize;
lecp->lec_arg = arg;