/*
* Slave Stream Pseudo Terminal Module
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stream.h>
#include <sys/stropts.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <sys/debug.h>
#include <sys/cmn_err.h>
#include <sys/modctl.h>
#include <sys/conf.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
static int ptsopen (queue_t*, dev_t*, int, int, cred_t);
static int ptsclose (queue_t*, int, cred_t*);
static int ptswput (queue_t*, mblk_t*);
static int ptsrsrv (queue_t*);
static int ptswsrv (queue_t*);
static int pts_devinfo(dev_info_t *dip, ddi_info_cmd_t infocmd,
void *arg,void **result);
static struct module_info pts_info = {
0xface,
"pts",
0,
512,
512,
128
};
static struct qinit ptsrint = {
NULL,
ptsrsrv,
ptsopen,
ptsclose,
NULL,
&pts_info,
NULL
};
static struct qinit ptswint = {
ptswput,
ptswsrv,
NULL,
NULL,
NULL,
&pts_info,
NULL
};
static struct streamtab ptsinfo = {
&ptsrint,
&ptswint,
NULL,
NULL
};
static int pts_identify(dev_info_t *devi);
static int pts_attach(dev_info_t *devi, ddi_attach_cmd_t cmd);
static int pts_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
static dev_info_t *pts_dip; /* private copy of devinfo ptr */
extern kmutex_t pt_lock;
extern pt_cnt;
static struct cb_ops cb_pts_ops = {
nulldev, /* cb_open */
nulldev, /* cb_close */
nodev, /* cb_strategy */
nodev, /* cb_print */
nodev, /* cb_dump */
nodev, /* cb_read */
nodev, /* cb_write */
nodev, /* cb_ioctl */
nodev, /* cb_devmap */
nodev, /* cb_mmap */
nodev, /* cb_segmap */
nochpoll, /* cb_chpoll */
ddi_prop_op, /* cb_prop_op */
&ptsinfo, /* cb_stream */
D_MP /* cb_flag */
};
static struct dev_ops pts_ops = {
DEVO_REV, /* devo_rev */
0, /* devo_refcnt */
pts_devinfo, /* devo_getinfo */
pts_identify, /* devo_identify */
nulldev, /* devo_probe */
pts_attach, /* devo_attach */
pts_detach, /* devo_detach */
nodev, /* devo_reset */
&cb_pts_ops, /* devo_cb_ops */
(struct bus_ops*) NULL /* devo_bus_ops */
};
/*
* Module linkage information for the kernel.
*/
static struct modldrv modldrv = {
&mod_driverops, /* Type of module: a pseudo driver */
"Slave Stream Pseudo Terminal driver'pts'",
&pts_ops, /* driver ops */
};
static struct modlinkage modlinkage = {
MODREV_1,
(void *)&modldrv,
NULL
};
int
_init(void)
{
return (mod_install(&modlinkage));
}
int
_fini(void)
{
return (mod_remove(&modlinkage));
}
int
_info(struct modinfo *modinfop)
{
return (mod_info(&modlinkage, modinfop));
}
static int
pts_identify(dev_info_t *devi)
{
if (strcmp(ddi_get_name(devi), "pts") == 0)
return (DDI_IDENTIFIED);
else
return (DDI_NOT_IDENTIFIED);
}
static int
pts_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
{
int i;
char name[5];
if (cmd != DDI_ATTACH)
return (DDI_FAILURE);
for (i = 0; i < pt_cnt; i++) {
(void) sprintf(name, "%d", i);
if (ddi_create_minor_node(devi, name, S_IFCHR, i, NULL, 0)
== DDI_FAILURE) {
ddi_remove_minor_node(devi, NULL);
return (DDI_FAILURE);
}
}
return (DDI_SUCCESS);
}
static int
pts_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
{
ddi_remove_minor_node(devi, NULL);
return (DDI_SUCCESS);
}
static int
pts_devinfo (dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
void **result)
{
int error;
switch (infocmd) {
case DDI_INFO_DEVT2DEVINFO:
if (pts_dip == NULL) {
error = DDI_FAILURE;
} else {
*result = (void *) pts_dip;
error = DDI_SUCCESS;
}
break;
case DDI_INFO_DEVT2INSTANCE:
*result = (void *) 0;
error = DDI_SUCCESS;
break;
default:
error = DDI_FAILURE;
}
return (error);
}
/* the open, close, wput, rsrv, and wsrv routines are presented
* here solely for the sake of showing how they interact with the
* configuration data structures and routines. Therefore, the
* bulk of their code is not included.
*/
static int
ptsopen(rqp, devp, oflag, sflag, credp)
queue_t *rqp; /* pointer to the read side queue */
dev_t *devp; /* pointer to stream tail's dev */
int oflag; /* the user open(2) supplied flags */
int sflag; /* open state flag */
cred_t *credp; /* credentials */
{
qprocson(rqp);
return (0);
}
static int
ptsclose(rqp, flag, credp)
queue_t *rqp;
int flag;
cred_t *credp;
{
qprocsoff(rqp);
return (0);
}
static int
ptswput(qp, mp)
queue_t *qp;
mblk_t *mp;
{
return (0);
}
static int
ptsrsrv(qp)
queue_t *qp;
{
return (0);
}
static int
ptswsrv(qp)
queue_t *qp;
{
return (0);
}
|