#ident "$Id: srcsink.c,v 1.4 1997/10/21 20:48:32 gary Exp $"
/*****************************************************************************
 * Copyright (c) 1988-95 Digi International Inc., All Rights Reserved
 * 
 * This  software  contains  proprietary  and  confidential   information   of
 * Digi International  Inc.   By  accepting  transfer  of this copy, Recipient
 * agrees to retain this software in  confidence,  to  prevent  disclosure  to
 * others,  and  to make no  use of this software other than that for which it
 * was delivered.  This is an unpublished copyright work  Digi   International
 * Inc.    Except   as   permitted   by  federal  law,  17 USC 117, copying is
 * strictly prohibited.
 * 
 * Digi  International  Inc.  CONFIDENTIAL  -   (Digi    International    Inc.
 * Confidential  when   combined   with   the   aggregated  modules  for  this
 * product) OBJECT CODE ONLY SOURCE MATERIALS
 * 
 * (C) COPYRIGHT Digi International Inc. 1995
 * 
 * All Rights Reserved
 * 
 * US   Government   Users   Restricted   Rights   -   Use,   duplication   or
 * disclosure  restricted by GSA ADP Schedule Contract with Digi International
 * Inc.
 * 
 *****************************************************************************/


/******************************************************************
 *
 *  Embedded STREAMS Package
 *
 *  Copyright 1991  Spider Systems Limited
 *
 *  SRCSINK.C
 *
 *  Streams Loopback Driver
 *
 ******************************************************************/

/*
 *	 /usr/projects.old/tcp/PBRAIN/SCCS/pbrainF/dev/embed/sloop/0/s.srcsink.c
 *	@(#)srcsink.c	1.1
 *
 *	Last delta created	14:59:19 2/3/92
 *	This file extracted	20:11:22 6/30/92
 *
 *	Modifications:
 *
 *	GSA	19 Sep 91	New file created
 *
 */


#ifndef NULL
#define NULL 0
#endif

/*#include "sloopinc.h"*/
#include "types.h"
#include "stream.h"
#include "sloop.h"


extern int qenable();

#define BSZ 512

#define DEBUG 1

#define NAME	"scsk"	/* the stream name */
#define HIWAT	0x400	/* Hi water mark */
#define LOWAT	0x100	/* Lo water mark */
#define SLOOP_STID  222	/* Stream driver id */

static struct module_info minfo = {
	SLOOP_STID, NAME, 0, INFPSZ, HIWAT, LOWAT
};

static int scskopen(), scskclose(), scskuwput();
static int scskursrv();

static struct qinit rinit = {
	NULL, scskursrv, scskopen, scskclose, NULL, &minfo, NULL
};

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


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

/*
 * variables set in the space.c file 
 */


/*
 * SLOOPINIT - no-op?
 */
/******************************************************************/
void scskinit()
/******************************************************************/
{
}

/* 
 * SLOOPOPEN - SLOOP device open routine
 */
/******************************************************************/
/* ARGSUSED */
static int scskopen(q, dev, fl, sfl)
/******************************************************************/
queue_t *q;
int dev;
int fl, sfl;
{

#ifdef DEBUG
printf("Scsk open %x %x %x %x\n", q, dev, fl, sfl);
#endif /* DEBUG */

	if ((sfl == MODOPEN) || (sfl == CLONEOPEN))
		return(OPENFAIL);

	dev = minor(dev);

	q->q_ptr = (caddr_t)(dev & 1);
	WR(q)->q_ptr = (caddr_t)(dev & 1);

	if (dev & 1)
		qenable(q);

	return(dev);
}

/* 
 * SLOOPCLOSE - SLOOP device close routine
 */
/******************************************************************/
/* ARGSUSED */
static int scskclose(q,fl)
/******************************************************************/
queue_t *q;
int fl;
{
	return 1;
}


/*
 * SLOOPUWPUT - SLOOP Upper Write Put Procedure
 *
 * Called from Network Module Write Service Procedure or 
 * from the Daemon stream head.
 */
/******************************************************************/
static int scskuwput(q, mp)
/******************************************************************/
queue_t *q;
mblk_t *mp;
{
	struct scskdev *sd = (struct scskdev *)q->q_ptr;
	union scsk_proto *ap ;

#ifdef DEBUG
printf("Scskuwput(%x %x), dev %x\n", q, mp, sd);
#endif /* DEBUG */

	freemsg(mp);

	return 1;
}


/*
 * SLOOPURSRV - SLOOP Upper Read Service Procedure
 */
/******************************************************************/
static int scskursrv(q)
/******************************************************************/
queue_t *q;
{
	struct ip_rx *ir;
	mblk_t *mp;
	static long srvcnt;

#ifdef DEBUG
printf("scskursrv(%x) %d\n", q, srvcnt);
#endif

	while(canput(q->q_next))
	{
		mp = (mblk_t *)allocb(BSZ, BPRI_LO);
		if (!mp)
		{
printf("Bufcalling(%x %x %x:%x %x) %l\n", BSZ, BPRI_LO, qenable, q, srvcnt);
			bufcall(BSZ, BPRI_LO, (PFI) qenable, (caddr_t) q);
			return 1;
		}
		mp->b_wptr += BSZ;
		*(long FAR *)(mp->b_rptr) = srvcnt++;
		putnext(q, mp);
	}
	return 1 ;
}
