File:  [Plan 9 NeXT] / lucent / sys / src / 9 / port / portdat.h
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:01:03 2018 UTC (8 years, 1 month ago) by root
Branches: lucent, MAIN
CVS tags: plan9, HEAD
Plan 9 NeXT

typedef struct Alarms	Alarms;
typedef struct Block	Block;
typedef struct Blist	Blist;
typedef struct Chan	Chan;
typedef struct Dev	Dev;
typedef struct Dirtab	Dirtab;
typedef struct Egrp	Egrp;
typedef struct Evalue	Evalue;
typedef struct Etherpkt	Etherpkt;
typedef struct Fgrp	Fgrp;
typedef struct Image	Image;
typedef struct IOQ	IOQ;
typedef struct KIOQ	KIOQ;
typedef struct List	List;
typedef struct Mount	Mount;
typedef struct Mnt	Mnt;
typedef struct Mhead	Mhead;
typedef struct Netinf	Netinf;
typedef struct Netprot	Netprot;
typedef struct Network	Network;
typedef struct Note	Note;
typedef struct Page	Page;
typedef struct Palloc	Palloc;
typedef struct Parallax	Parallax;
typedef struct Pgrps	Pgrps;
typedef struct Pgrp	Pgrp;
typedef struct Physseg	Physseg;
typedef struct Proc	Proc;
typedef struct Pte	Pte;
typedef struct Qinfo	Qinfo;
typedef struct QLock	QLock;
typedef struct Queue	Queue;
typedef struct Ref	Ref;
typedef struct Rendez	Rendez;
typedef struct RWlock	RWlock;
typedef struct Sargs	Sargs;
typedef struct Session	Session;
typedef struct Scsi	Scsi;
typedef struct Scsibuf	Scsibuf;
typedef struct Scsidata	Scsidata;
typedef struct Segment	Segment;
typedef struct Stream	Stream;
typedef struct Talarm	Talarm;
typedef struct Waitq	Waitq;
typedef int    Devgen(Chan*, Dirtab*, int, int, Dir*);
typedef	void   Streamput(Queue*, Block*);
typedef	void   Streamopen(Queue*, Stream*);
typedef	void   Streamclose(Queue*);
typedef	void   Streamreset(void);

#include <auth.h>
#include <fcall.h>

struct Ref
{
	Lock;
	long	ref;
};

struct Rendez
{
	Lock;
	Proc	*p;
};

struct QLock
{
	Lock	use;			/* to access Qlock structure */
	Proc	*head;			/* next process waiting for object */
	Proc	*tail;			/* last process waiting for object */
	int	locked;			/* flag */
};

struct RWlock
{
	Lock;				/* Lock modify lock */
	QLock	x;			/* Mutual exclusion lock */
	QLock	k;			/* Lock for waiting writers held for readers */
	int	readers;		/* Count of readers in lock */
};

struct Talarm
{
	Lock;
	Proc	*list;
};

struct Alarms
{
	QLock;
	Proc	*head;
};

#define MAXSYSARG	5		/* for mount(fd, mpt, flag, arg, srv) */
struct Sargs
{
	ulong	args[MAXSYSARG];
};

/* Block.flags */
#define S_DELIM 0x80
#define S_CLASS 0x07

/* Block.type */
#define M_DATA 0
#define M_CTL 1
#define M_HANGUP 2

struct Block
{
	Block	*next;
	Block	*list;			/* chain of block lists */
	uchar	*rptr;			/* first unconsumed byte */
	uchar	*wptr;			/* first empty byte */
	uchar	*lim;			/* 1 past the end of the buffer */
	uchar	*base;			/* start of the buffer */
	uchar	flags;
	uchar	type;
	ulong	pc;			/* pc of caller */
};

struct Blist
{
	Lock;
	Block	*first;			/* first data block */
	Block	*last;			/* last data block */
	long	len;			/* length of list in bytes */
	int	nb;			/* number of blocks in list */
};

/*
 * Access types in namec
 */
enum
{
	Aaccess,			/* as in access, stat */
	Atodir,				/* as in chdir */
	Aopen,				/* for i/o */
	Amount,				/* to be mounted upon */
	Acreate,			/* file is to be created */
};

/*
 *  Chan.flags
 */
#define	COPEN	1			/* for i/o */
#define	CMSG	2			/* is the message channel for a mount */
#define	CCREATE	4			/* permits creation if c->mnt */
#define	CCEXEC	8			/* close on exec */
#define	CFREE	16			/* not in use */
#define	CRCLOSE	32			/* remove on close */

struct Chan
{
	Ref;
	union{
		Chan	*next;		/* allocation */
		ulong	offset;		/* in file */
	};
	ushort	type;
	ulong	dev;
	ushort	mode;			/* read/write */
	ushort	flag;
	Qid	qid;
	Mount	*mnt;			/* mount point that derived Chan */
	ulong	mountid;
	int	fid;			/* for devmnt */
	Stream	*stream;		/* for stream channels */
	union {
		void	*aux;
		Qid	pgrpid;		/* for #p/notepg */
		Mnt	*mntptr;	/* for devmnt */
	};
	Chan	*mchan;			/* channel to mounted server */
	Qid	mqid;			/* qid of root of mount point */
	Session	*session;
};

struct Dev
{
	void	(*reset)(void);
	void	(*init)(void);
	Chan*	(*attach)(char*);
	Chan*	(*clone)(Chan*, Chan*);
	int	(*walk)(Chan*, char*);
	void	(*stat)(Chan*, char*);
	Chan*	(*open)(Chan*, int);
	void	(*create)(Chan*, char*, int, ulong);
	void	(*close)(Chan*);
	long	(*read)(Chan*, void*, long, ulong);
	long	(*write)(Chan*, void*, long, ulong);
	void	(*remove)(Chan*);
	void	(*wstat)(Chan*, char*);
};

struct Dirtab
{
	char	name[NAMELEN];
	Qid	qid;
	long	length;
	long	perm;
};

/*
 *  Ethernet packet buffers.
 */
struct Etherpkt
{
	uchar	d[6];
	uchar	s[6];
	uchar	type[2];
	uchar	data[1500];
	uchar	crc[4];
};

enum
{
	ETHERMINTU =	64,		/* minimum transmit size */
	ETHERMAXTU =	1514,		/* maximum transmit size */
	ETHERHDRSIZE =	14,		/* size of an ethernet header */
};

/* SCSI devices. */
enum
{
	ScsiTestunit	= 0x00,
	ScsiExtsens	= 0x03,
	ScsiInquiry	= 0x12,
	ScsiModesense	= 0x1a,
	ScsiStartunit	= 0x1B,
	ScsiStopunit	= 0x1B,
	ScsiGetcap	= 0x25,
	ScsiRead	= 0x08,
	ScsiWrite	= 0x0a,
	ScsiExtread	= 0x28,
	ScsiExtwrite	= 0x2a,

	/* data direction */
	ScsiIn		= 1,
	ScsiOut		= 0,
};

struct Scsibuf
{
	void*		virt;
	void*		phys;
	Scsibuf*	next;
};

struct Scsidata
{
	uchar*		base;
	uchar*		lim;
	uchar*		ptr;
};

struct Scsi
{
	QLock;
	int		bus;
	ulong		pid;
	ushort		target;
	ushort		lun;
	ushort		rflag;
	ushort		status;
	Scsidata 	cmd;
	Scsidata 	data;
	Scsibuf*	b;
	uchar*		save;
	uchar		cmdblk[16];
};

/* character based IO (mouse, keyboard, console screen) */
#define NQ	4096
struct IOQ
{
	Lock;
	uchar	buf[NQ];
	uchar	*in;
	uchar	*out;
	int	state;
	Rendez	r;
	union{
		void	(*puts)(IOQ*, void*, int);	/* output */
		int	(*putc)(IOQ*, int);		/* input */
	};
	union{
		int	(*gets)(IOQ*, void*, int);	/* input */
		int	(*getc)(IOQ*);			/* output */
	};
	void	*ptr;
};

struct KIOQ
{
	QLock;
	IOQ;
	int	repeat;
	int	c;
	int	count;
};

struct Mount
{
	ulong	mountid;
	Mount	*next;
	Mhead	*head;
	Chan	*to;			/* channel replacing underlying channel */
};

struct Mhead
{
	Chan	*from;			/* channel mounted upon */
	Mount	*mount;			/* what's mounted upon it */
	Mhead	*hash;			/* Hash chain */
};

enum
{
	NUser,				/* note provided externally */
	NExit,				/* deliver note quietly */
	NDebug,				/* print debug message */
};

struct Note
{
	char	msg[ERRLEN];
	int	flag;			/* whether system posted it */
};

enum
{
	PG_NOFLUSH	= 0,		/* Fields for cache control of pages */
	PG_TXTFLUSH	= 1,
	PG_DATFLUSH	= 2,
	PG_MOD		= 0x01,		/* Simulated modified and referenced bits */
	PG_REF		= 0x02,
};

struct Page
{
	Lock;
	ulong	pa;			/* Physical address in memory */
	ulong	va;			/* Virtual address for user */
	ulong	daddr;			/* Disc address on swap */
	ushort	ref;			/* Reference count */
	char	modref;			/* Simulated modify/reference bits */
	char	cachectl[MAXMACH];	/* Cache flushing control for putmmu */
	Image	*image;			/* Associated text or swap image */
	Page	*next;			/* Lru free list */
	Page	*prev;
	Page	*hash;			/* Image hash chains */
};

struct Swapalloc
{
	Lock;				/* Free map lock */
	int	free;			/* Number of currently free swap pages */
	uchar	*swmap;			/* Base of swap map in memory */
	uchar	*alloc;			/* Round robin allocator */
	uchar	*last;			/* Speed swap allocation */
	uchar	*top;			/* Top of swap map */
	Rendez	r;			/* Pager kproc idle sleep */
	ulong	highwater;		/* Threshold beyond which we must page */
	ulong	headroom;		/* Space pager keeps free under highwater */
}swapalloc;

struct Image
{
	Ref;
	Chan	*c;			/* Channel associated with running image */
	Qid 	qid;			/* Qid for page cache coherence checks */
	Qid	mqid;
	Chan	*mchan;
	ushort	type;			/* Device type of owning channel */
	Segment *s;			/* TEXT segment for image if running */
	Image	*hash;			/* Qid hash chains */
	Image	*next;			/* Free list */
};

struct Pte
{
	Page	*pages[PTEPERTAB];	/* Page map for this chunk of pte */
	Page	**first;		/* First used entry */
	Page	**last;			/* Last used entry */
	Pte	*next;			/* Free list */
};

/* Segment types */
enum
{
	SG_TYPE		= 07,		/* Mask type of segment */
	SG_TEXT		= 00,
	SG_DATA		= 01,
	SG_BSS		= 02,
	SG_STACK	= 03,
	SG_SHARED	= 04,
	SG_PHYSICAL	= 05,
	SG_SHDATA	= 06,

	SG_RONLY	= 040,		/* Segment is read only */
	SG_CEXEC	= 0100,		/* Detach at exec */
};

#define PG_ONSWAP	1
#define onswap(s)	(((ulong)s)&PG_ONSWAP)
#define pagedout(s)	(((ulong)s)==0 || onswap(s))
#define swapaddr(s)	(((ulong)s)&~PG_ONSWAP)

#define SEGMAXSIZE	(SEGMAPSIZE*PTEMAPMEM)

struct Physseg
{
	ulong	attr;			/* Segment attributes */
	char	*name;			/* Attach name */
	ulong	pa;			/* Physical address */
	ulong	size;			/* Maximum segment size in pages */
	Page	*(*pgalloc)(Segment*, ulong);	/* Allocation if we need it */
	void	(*pgfree)(Page*);
};

struct Segment
{
	Ref;
	QLock	lk;
	ushort	steal;		/* Page stealer lock */
	Segment	*next;		/* free list pointers */
	ushort	type;		/* segment type */
	ulong	base;		/* virtual base */
	ulong	top;		/* virtual top */
	ulong	size;		/* size in pages */
	ulong	fstart;		/* start address in file for demand load */
	ulong	flen;		/* length of segment in file */
	int	flushme;	/* maintain consistent icache for this segment */
	Image	*image;		/* text in file attached to this segment */
	Physseg *pseg;
	Pte	*map[SEGMAPSIZE];	/* segment pte map */
};

enum
{
	RENDHASH =	32,		/* Hash to lookup rendezvous tags */
	MNTHASH	=	32,		/* Hash to walk mount table */
	NFD =		100,		/* Number of per process file descriptors */
	PGHLOG  =	9,
	PGHSIZE	=	1<<PGHLOG,	/* Page hash for image lookup */
};
#define REND(p,s)	((p)->rendhash[(s)%RENDHASH])
#define MOUNTH(p,s)	((p)->mnthash[(s)->qid.path%MNTHASH])

struct Pgrp
{
	Ref;				/* also used as a lock when mounting */
	Pgrp	*next;			/* free list */
	ulong	pgrpid;
	QLock	debug;			/* single access via devproc.c */
	RWlock	ns;			/* Namespace many read/one write lock */
	Mhead	*mnthash[MNTHASH];
	Proc	*rendhash[RENDHASH];	/* Rendezvous tag hash */
};

struct Egrp
{
	Ref;
	QLock;
	Evalue	*entries;
	ulong	path;
};

struct Evalue
{
	char	*name;
	char	*value;
	int	len;
	ulong	path;
	Evalue	*link;
};

struct Fgrp
{
	Ref;
	Chan	*fd[NFD];
	int	maxfd;			/* highest fd in use */
};

struct Palloc
{
	Lock;
	ulong	p0, p1;			/* base of pages in bank 0/1 */
	ulong	np0, np1;		/* number of pages in bank 0/1 */
	Page	*head;			/* most recently used */
	Page	*tail;			/* least recently used */
	ulong	freecount;		/* how many pages on free list now */
	ulong	user;			/* how many user pages */
	Page	*hash[PGHSIZE];
	Lock	hashlock;
	Rendez	r;			/* Sleep for free mem */
	QLock	pwait;			/* Queue of procs waiting for memory */
	int	wanted;			/* Do the wakeup at free */
	ulong	cmembase;		/* Key memory protected from read by devproc */
	ulong	cmemtop;
};

struct Waitq
{
	Waitmsg	w;
	Waitq	*next;
};

enum
{
	RFNAMEG		= (1<<0),
	RFENVG		= (1<<1),
	RFFDG		= (1<<2),
	RFNOTEG		= (1<<3),
	RFPROC		= (1<<4),
	RFMEM		= (1<<5),
	RFNOWAIT	= (1<<6),
	RFCNAMEG	= (1<<10),
	RFCENVG		= (1<<11),
	RFCFDG		= (1<<12)
};

/*
 *  process memory segments - NSEG always last !
 */
enum
{
	SSEG, TSEG, DSEG, BSEG, ESEG, LSEG, SEG1, SEG2, NSEG
};

enum
{
	Dead = 0,		/* Process states */
	Moribund,
	Ready,
	Scheding,
	Running,
	Queueing,
	Wakeme,
	Broken,
	Stopped,
	Rendezvous,

	Proc_stopme = 1, 	/* devproc requests */
	Proc_exitme,
	Proc_traceme,

	TUser = 0, 		/* Proc.time */
	TSys,
	TReal,
	TCUser,
	TCSys,
	TCReal,

	Nrq		= 20,	/* number of scheduler priority levels */
	PriNormal	= 10,	/* base priority for normal processes */
	PriKproc	= 13,	/* base priority for kernel processes */
	PriRoot		= 13,	/* base priority for root processes */
};

struct Proc
{
	Label	sched;
	Mach	*mach;			/* machine running this proc */
	char	text[NAMELEN];
	char	user[NAMELEN];
	Proc	*rnext;			/* next process in run queue */
	Proc	*qnext;			/* next process on queue for a QLock */
	QLock	*qlock;			/* address of qlock being queued for DEBUG */
	ulong	qlockpc;		/* pc of last call to qlock */
	int	state;
	char	*psstate;		/* What /proc/#/status reports */
	Page	*upage;			/* page from palloc */
	Segment	*seg[NSEG];
	ulong	pid;
	ulong	noteid;			/* Equivalent of note group */

	Lock	exl;			/* Lock count and waitq */
	Waitq	*waitq;			/* Exited processes wait children */
	int	nchild;			/* Number of living children */
	int	nwait;			/* Number of uncollected wait records */
	QLock	qwaitr;
	Rendez	waitr;			/* Place to hang out in wait */
	Proc	*parent;

	Pgrp	*pgrp;			/* Process group for notes and namespace */
	Egrp 	*egrp;			/* Environment group */
	Fgrp	*fgrp;			/* File descriptor group */

	ulong	parentpid;
	ulong	time[6];		/* User, Sys, Real; child U, S, R */
	short	insyscall;
	int	fpstate;

	QLock	debug;			/* to access debugging elements of User */
	Proc	*pdbg;			/* the debugging process */
	ulong	procmode;		/* proc device file mode */
	int	hang;			/* hang at next exec for debug */
	int	procctl;		/* Control for /proc debugging */
	ulong	pc;			/* DEBUG only */

	Rendez	*r;			/* rendezvous point slept on */
	Rendez	sleep;			/* place for syssleep/debug */
	int	notepending;		/* note issued but not acted on */
	int	kp;			/* true if a kernel process */
	Proc	*palarm;		/* Next alarm time */
	ulong	alarm;			/* Time of call */
	int 	hasspin;		/* I hold a spin lock */
	int	newtlb;			/* Pager has touched my tables so I must flush */

	ulong	rendtag;		/* Tag for rendezvous */ 
	ulong	rendval;		/* Value for rendezvous */
	Proc	*rendhash;		/* Hash list for tag values */

	ulong	twhen;
	Rendez	*trend;
	Proc	*tlink;
	int	(*tfn)(void*);

	Mach	*mp;		/* machine this process last ran on */
	ulong	priority;	/* priority level */
	ulong	basepri;	/* base priority level */
	ulong	rt;		/* # ticks used since last blocked */
	ulong	art;		/* avg # ticks used since last blocked */
	ulong	movetime;	/* last time process switched processors */
	ulong	readytime;	/* time process went ready */

	/*
	 *  machine specific MMU
	 */
	PMMU;
};

/*
 *  operations available to a queue
 */
struct Qinfo
{
	Streamput	*iput;		/* input routine */
	Streamput	*oput;		/* output routine */
	Streamopen	*open;
	Streamclose	*close;
	char		*name;
	Streamreset	*reset;		/* initialization */
	char		nodelim;	/* True if stream does not preserve delimiters */
	Qinfo		*next;
};

/* Queue.flag */
enum
{
	QHUNGUP	=	0x1,	/* stream has been hung up */
	QINUSE =	0x2,	/* allocation check */
	QHIWAT =	0x4,	/* queue has gone past the high water mark */	
	QDEBUG =	0x8,
};

struct Queue
{
	Blist;
	int	flag;
	Qinfo	*info;			/* line discipline definition */
	Queue	*other;			/* opposite direction, same line discipline */
	Queue	*next;			/* next queue in the stream */
	void	(*put)(Queue*, Block*);
	QLock	rlock;			/* mutex for processes sleeping at r */
	Rendez	r;			/* standard place to wait for flow control */
	Rendez	*rp;			/* where flow control wakeups go to */
	void	*ptr;			/* private info for the queue */
};

struct Stream
{
	QLock;				/* structure lock */
	Stream	*next;
	short	inuse;			/* number of processes in stream */
	short	opens;			/* number of processes with stream open */
	ushort	hread;			/* number of reads after hangup */
	ushort	type;			/* correlation with Chan */
	ushort	dev;			/* ... */
	ulong	id;			/* ... */
	QLock	rdlock;			/* read lock */
	Queue	*procq;			/* write queue at process end */
	Queue	*devq;			/* read queue at device end */
	Block	*err;			/* error message from down stream */
	int	flushmsg;		/* flush up till the next delimiter */
};

/*
 *  useful stream macros
 */
#define	RD(q)		((q)->other < (q) ? (q->other) : q)
#define	WR(q)		((q)->other > (q) ? (q->other) : q)
#define STREAMTYPE(x)	((x)&0x1f)
#define STREAMID(x)	(((x)&~CHDIR)>>5)
#define STREAMQID(i,t)	(((i)<<5)|(t))
#define PUTTHIS(q,b)	(*(q)->put)((q), b)
#define PUTNEXT(q,b)	(*(q)->next->put)((q)->next, b)
#define BLEN(b)		((b)->wptr - (b)->rptr)
#define QFULL(q)	((q)->flag & QHIWAT)
#define FLOWCTL(q,b)	{ if(QFULL(q->next)) flowctl(q,b); else PUTNEXT(q,b);}

/*
 *  stream file qid's & high water mark
 */
enum
{
	Shighqid	= STREAMQID(1,0) - 1,
	Sdataqid	= Shighqid,
	Sctlqid		= Sdataqid-1,
	Slowqid		= Sctlqid,
	Streamhi	= (32*1024),	/* byte count high water mark */
	Streambhi	= 128,		/* block count high water mark */
};

/*
 *  a multiplexed network
 */
struct Netprot
{
	int	id;
	Netprot	*next;		/* linked list of protections */
	ulong	mode;
	char	owner[NAMELEN];
};

struct Netinf
{
	char	*name;
	void	(*fill)(Chan*, char*, int);
};

struct Network
{
	Lock;
	char	*name;
	int	nconv;			/* max # of conversations */
	Qinfo	*devp;			/* device end line disc */
	Qinfo	*protop;		/* protocol line disc */
	int	(*listen)(Chan*);
	int	(*clone)(Chan*);
	int	ninfo;
	Netinf	info[5];
	Netprot	*prot;			/* linked list of protections */
};

/*
 *  Parallax for pen pointers
 */
struct Parallax
{
	int	xoff;
	int	xnum;
	int	xdenom;

	int	yoff;
	int	ynum;
	int	ydenom;
};

enum
{
	PRINTSIZE =	256,
	MAXCRYPT = 	127,
	NUMSIZE	=	12,		/* size of formatted number */
	MB =		(1024*1024),
};

extern	Conf	conf;
extern	char*	conffile;
extern	int	cpuserver;
extern	Rune*	devchar;
extern	Dev	devtab[];
extern  char	eve[];
extern	char	hostdomain[];
extern	int	hwcurs;
extern	uchar	initcode[];
extern	FPsave	initfp;
extern  KIOQ	kbdq;
extern  IOQ	lineq;
extern  IOQ	mouseq;
extern  Ref	noteidalloc;
extern	int	nrdy;
extern  IOQ	printq;
extern	char*	statename[];
extern  Image	swapimage;
extern	char	sysname[NAMELEN];
extern	Talarm	talarm;
extern	Palloc 	palloc;
extern	int	cpuserver;
extern	Physseg physseg[];

enum
{
	CHDIR =		0x80000000L,
	CHAPPEND = 	0x40000000L,
	CHEXCL =	0x20000000L,
	CHMOUNT	=	0x10000000L,
};

/*
 * auth messages
 */
enum
{
	FScchal	= 1,
	FSschal,
	FSok,
	FSctick,
	FSstick,
	FSerr,

	RXschal	= 0,
	RXstick	= 1,
};

/*
 *  mouse types
 */
enum
{
	Mouseother=	0,
	Mouseserial=	1,
	MousePS2=	2,
	Mousekurta=	3,
};
extern int mouseshifted;
extern int mousetype;
extern int mouseswap;

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.