Пример #1
0
static int
lx_ptm_read(dev_t dev, struct uio *uiop, cred_t *credp)
{
	int		pktio = lx_ptm_lh_pktio_get(DEVT_TO_INDEX(dev));
	int		err, loop;
	struct uio	uio;
	struct iovec	iovp;

	ASSERT(uiop->uio_iovcnt > 0);

	/*
	 * If packet mode has been enabled (via TIOCPKT) we need to pad
	 * all read requests with a leading byte that indicates any
	 * relevant control status information.
	 */
	if (pktio != 0) {
		/*
		 * We'd like to write the control information into
		 * the current buffer but we can't yet.  We don't
		 * want to modify userspace memory here only to have
		 * the read operation fail later.  So instead
		 * what we'll do here is read one character from the
		 * beginning of the memory pointed to by the uio
		 * structure.  This will advance the output pointer
		 * by one.  Then when the read completes successfully
		 * we can update the byte that we passed over.  Before
		 * we do the read make a copy of the current uiop and
		 * iovec structs so we can write to them later.
		 */
		uio = *uiop;
		iovp = *uiop->uio_iov;
		uio.uio_iov = &iovp;

		if (uwritec(uiop) == -1)
			return (EFAULT);
	}

	do {
		/*
		 * Before we actually attempt a read operation we need
		 * to make sure there's some buffer space to actually
		 * read in some data.  We do this because if we're in
		 * pktio mode and the caller only requested one byte,
		 * then we've already used up that one byte and we
		 * don't want to pass this read request.  Doing a 0
		 * byte read (unless there is a problem with the stream
		 * head) always returns succcess.  Normally when a streams
		 * read returns 0 bytes we interpret that as an EOF on
		 * the stream (ie, the slave side has been opened and
		 * closed) and we ignore it and re-try the read operation.
		 * So if we pass on a 0 byte read here lx_ptm_read_loop()
		 * will tell us to loop around and we'll end up in an
		 * infinite loop.
		 */
		if (uiop->uio_resid == 0)
			break;

		/*
		 * Serialize all reads.  We need to do this so that we can
		 * properly emulate the behavior of master terminals on Linux.
		 * In reality this serializaion should not pose any kind of
		 * performance problem since it would be very strange to have
		 * multiple threads trying to read from the same master
		 * terminal device concurrently.
		 */
		if (lx_ptm_read_start(dev) != 0)
			return (EINTR);

		err = lx_ptm_read_loop(dev, uiop, credp, &loop);
		lx_ptm_read_end(dev);
		if (err != 0)
			return (err);
	} while (loop != 0);

	if (pktio != 0) {
		uint8_t		pktio_data = TIOCPKT_DATA;

		/*
		 * Note that the control status information we
		 * pass back is faked up in the sense that we
		 * don't actually report any events, we always
		 * report a status of 0.
		 */
		if (uiomove(&pktio_data, 1, UIO_READ, &uio) != 0)
			return (EFAULT);
	}

	return (0);
}
Пример #2
0
lowinit()
{
#if !defined(GPROF)
	caddr_t cp;
#endif
	extern int dumpmag;
	extern int rthashsize;
	extern int arptab_size;
	extern int dk_ndrive;
	extern struct domain unixdomain;
#ifdef INET
	extern struct domain inetdomain;
#endif
#include "imp.h"
#if NIMP > 0
	extern struct domain impdomain;
#endif
#ifdef NS
	extern struct domain nsdomain;
#endif

	/* cpp messes these up for lint so put them here */
	unixdomain.dom_next = domains;
	domains = &unixdomain;
#ifdef INET
	inetdomain.dom_next = domains;
	domains = &inetdomain;
#endif
#if NIMP > 0
	impdomain.dom_next = domains;
	domains = &impdomain;
#endif
#ifdef NS
	nsdomain.dom_next = domains;
	domains = &nsdomain;
#endif
	dumpmag = 0;			/* used only by savecore */
	rthashsize = rthashsize;	/* used by netstat, etc. */
	arptab_size = arptab_size;	/* used by arp command */
	dk_ndrive = dk_ndrive;		/* used by vmstat, iostat, etc. */

	/*
	 * Pseudo-uses of globals.
	 */
	lowinit();
	intstack[0] = intstack[1];
	maxmem = physmem = freemem = 0;
	u = u;
	fixctlrmask();
	main(0);
	Xustray();

	/*
	 * Routines called from interrupt vectors.
	 */
	panic("Machine check");
	printf("Write timeout");
	consdin();
	consdout();
	hardclock((caddr_t)0, 0);
	softclock((caddr_t)0, 0);
	trap((unsigned)0, (unsigned)0, (unsigned)0, (unsigned)0);
	memerr();

	/*
	 * Miscellaneous routines called from configurable
	 * drivers.
	 */
	disksort((struct buf *)0, (struct buf *)0);
	(void) uwritec((struct uio *)0);
	(void) todr();
	if (vmemall((struct pte *)0, 0, (struct proc *)0, 0))
		return;		/* use value */
	boothowto = 0;
	dumpflag = 0; dumpflag = dumpflag;
#ifdef KADB
	bootesym = 0; bootesym = bootesym;
#endif
#if !defined(GPROF)
	cp = (caddr_t)&etext;
	cp = cp;
#endif
}