Coherent4.2.10/conf/echo/src/echo.c

Compare this file to the similar file:
Show the results in this format:

/*
 * Trivial echo driver for STREAMS testing.
 */

#define	_DDI_DKI	1
#define	_SYSV4		1

#include <common/ccompat.h>
#include <sys/types.h>
#include <sys/stream.h>
#include <sys/stropts.h>
#include <sys/cred.h>
#include <stddef.h>


static struct module_info minfo = {
	0x1821, "echo", 0, INFPSZ, 512, 128
};

static	int	echoopen	__PROTO ((queue_t * q, dev_t * devp, int flag,
					  int sflag, cred_t * credp));
static	int	echoclose	__PROTO ((queue_t * q, int flag,
					  cred_t * credp));
static	void	echowput	__PROTO ((queue_t * q, mblk_t * mp));
static	void	echowsrv	__PROTO ((queue_t * q));
static	void	echorsrv	__PROTO ((queue_t * q));

static struct qinit rinit = {
	NULL, echorsrv, echoopen, echoclose, NULL, & minfo, NULL
};

static struct qinit winit = {
	echowput, echowsrv, NULL, NULL, NULL, & minfo, NULL
};

struct streamtab echoinfo = { & rinit, & winit, NULL, NULL };

int	echodevflag = 0;


#if	__USE_PROTO__
int echoopen (queue_t * q, dev_t * __NOTUSED (devp), int __NOTUSED (flag),
	      int __NOTUSED (sflag), cred_t * __NOTUSED (credp))
#else
int
echoopen (q, devp, flag, sflag, credp)
queue_t	      *	q;
dev_t	      *	devp;
int		flag;
int		sflag;
cred_t	      *	credp;
#endif
{
	/*
	 * Enable put and service routines for this queue pair.
	 */

	qprocson (q);
	return 0;
}


#if	__USE_PROTO__
void echowput (queue_t * q, mblk_t * mp)
#else
void
echowput (q, mp)
queue_t	      *	q;
mblk_t	      *	mp;
#endif
{
	switch (mp->b_datap->db_type) {

	case M_IOCTL:
		/*
		 * Invalid ioctl (). Setting "ioc_error" causes the
		 * ioctl () call to return that particular errno. By
		 * default, ioctl () will return EINVAL on failure.
		 */

		mp->b_datap->db_type = M_IOCNAK;
		qreply (q, mp);
		break;

	case M_FLUSH:
		/*
		 * Canonical driver flush processing.
		 */

		if ((* mp->b_rptr & FLUSHW) != 0)
			flushq (q, FLUSHALL);

		if ((* mp->b_rptr & FLUSHR) != 0)
			flushq (RD (q), FLUSHALL);

		* mp->b_rptr &= ~ FLUSHW;

		if ((* mp->b_rptr & FLUSHR) != 0)
			qreply (RD (q), mp);
		else
			freemsg (mp);
		break;

	case M_DATA:
	case M_PROTO:
	case M_PCPROTO:
		putq (q, mp);
		break;

	default:
		/*
		 * Discard unrecognized messages.
		 */

		freemsg (mp);
		break;
	}
}


#if	__USE_PROTO__
void echowsrv (queue_t * q)
#else
void
echowsrv (q)
queue_t	      *	q;
#endif
{
	mblk_t	      *	mp;

	while ((mp = getq (q)) != NULL) {
		/*
		 * If the read side becomes full, keep the messages on this
		 * side to exert back-pressure upstream.
		 */

		if (! pcmsg (mp->b_datap->db_type) && ! canputnext (RD (q))) {

			putbq (q, mp);
			break;
		}

		putnext (RD (q), mp);
	}
}


#if	__USE_PROTO__
void echorsrv (queue_t * q)
#else
void
echorsrv (q)
queue_t	      *	q;
#endif
{
	/*
	 * Deal with being back-enabled by flow control by enabling the write
	 * side service procedure to retry sending the messages backed up
	 * there.
	 */

	qenable (WR (q));
}


#if	__USE_PROTO__
int echoclose (queue_t * q, int __NOTUSED (flag), cred_t * __NOTUSED (credp))
#else
int
echoclose (q, flag, credp)
queue_t	      *	q;
int		flag;
cred_t	      *	credp;
#endif
{
	/*
	 * Disable put and service routines for the queue pair.
	 */

	qprocsoff (q);
	return 0;
}