~kris/9p

9hist

c32088eb1ef2c431cda8f56c6b8c966ec40b63b3 — David du Colombier 24 years ago 6c93b16
Plan 9 from Bell Labs 2001-11-08
5 files changed, 254 insertions(+), 193 deletions(-)

M pc/devlml.c
M pc/devlml.h
M pc/vgamach64xx.c
M port/parse.c
M port/portdat.h
M pc/devlml.c => pc/devlml.c +179 -140
@@ 8,10 8,6 @@

#include	"devlml.h"

static void *		pciPhysBaseAddr;
static ulong		pciBaseAddr;
static Pcidev *		pcidev;

#define DBGREAD	0x01
#define DBGWRIT	0x02
#define DBGINTR	0x04


@@ 23,22 19,43 @@ int debug = 0;

enum{
	Qdir,
	Qjpg,
	Qraw,
	Qctl0,
	Qjpg0,
	Qraw0,
	Qctl1,
	Qjpg1,
	Qraw1,
};

#define	QID(q)		((ulong)(q).path)
#define	QIDLML(q)	((((ulong)(q).path)-1)>>1)

static Dirtab lmldir[]={
	".",		{Qdir, 0, QTDIR},	0,	DMDIR|0555,
	"lmljpg",	{Qjpg},			0,	0444,
	"lmlraw",	{Qraw},			0,	0444,
	".",			{Qdir, 0, QTDIR},	0,	DMDIR|0555,
	"lml0ctl",		{Qctl0},			0,	0666,
	"lml0jpg",		{Qjpg0},			0,	0444,
	"lml0raw",	{Qraw0},			0,	0444,
	"lml1ctl",		{Qctl1},			0,	0666,
	"lml1jpg",		{Qjpg1},			0,	0444,
	"lml1raw",	{Qraw1},			0,	0444,
};

static CodeData *	codeData;
typedef struct LML LML;

static ulong		jpgframeno;
//static ulong		rawframeno;
struct LML {
	// Hardware
	Pcidev *		pcidev;
	ulong		pciBaseAddr;
	// Allocated memory
	CodeData *	codedata;
	// Software state
	ulong		jpgframeno;
	int			frameNo;
	Rendez		sleepjpg;
	int			jpgopens;
} lmls[NLML];

//static FrameHeader	rawheader;
int nlml;

static FrameHeader	jpgheader = {
	MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8,


@@ 46,25 63,19 @@ static FrameHeader	jpgheader = {
	-1, 0, 0,  0
};

int		frameNo;
Rendez	sleepjpg;
//Rendez		sleepraw;
int		singleFrame;
int		jpgopens;
int		jpgmode;
//int		rawopens;

#define writel(v, a) *(ulong *)(a) = (v)
#define readl(a) *(ulong*)(a)

static int
getbuffer(void *){
getbuffer(void *x){
	static last = NBUF-1;
	int l = last;
	LML *lml;

	lml = x;
	for (;;) {
		last = (last+1) % NBUF;
		if (codeData->statCom[last] & STAT_BIT)
		if (lml->codedata->statCom[last] & STAT_BIT)
			return last + 1;
		if (last == l)
			return 0;


@@ 73,18 84,18 @@ getbuffer(void *){
}

static long
jpgread(Chan *, void *va, long nbytes, vlong, int dosleep) {
jpgread(LML *lml, void *va, long nbytes, vlong, int dosleep) {
	int bufno;
	FrameHeader *jpgheader;

	
	// reads should be of size 1 or sizeof(FrameHeader)
	// Frameno is the number of the buffer containing the data
	while ((bufno = getbuffer(nil)) == 0 && dosleep)
		sleep(&sleepjpg, getbuffer, 0);
	while ((bufno = getbuffer(lml)) == 0 && dosleep)
		sleep(&lml->sleepjpg, getbuffer, lml);
	if (--bufno < 0)
		return 0;

	jpgheader = (FrameHeader*)(codeData->frag[bufno].hdr+2);
	jpgheader = (FrameHeader*)(lml->codedata->frag[bufno].hdr+2);
	if (nbytes == sizeof(FrameHeader)) {
		memmove(va, jpgheader, sizeof(FrameHeader));
		return sizeof(FrameHeader);


@@ 99,15 110,15 @@ jpgread(Chan *, void *va, long nbytes, vlong, int dosleep) {
static void lmlintr(Ureg *, void *);

static void
prepbuf(void) {
prepbuf(LML *lml) {
	int i;

	for (i = 0; i < NBUF; i++) {
		codeData->statCom[i] = PADDR(&(codeData->fragdesc[i]));
		codeData->fragdesc[i].addr = PADDR(codeData->frag[i].fb);
		lml->codedata->statCom[i] = PADDR(&(lml->codedata->fragdesc[i]));
		lml->codedata->fragdesc[i].addr = PADDR(lml->codedata->frag[i].fb);
		// Length is in double words, in position 1..20
		codeData->fragdesc[i].leng = (FRAGSIZE >> 1) | FRAGM_FINAL_B;
		memmove(codeData->frag[i].hdr+2, &jpgheader, sizeof(FrameHeader)-2);
		lml->codedata->fragdesc[i].leng = (FRAGSIZE >> 1) | FRAGM_FINAL_B;
		memmove(lml->codedata->frag[i].hdr+2, &jpgheader, sizeof(FrameHeader)-2);
	}
}



@@ 115,92 126,70 @@ static void
lmlreset(void)
{
	Physseg segbuf;
	Physseg segreg;
	Physseg seggrab;
	ulong regpa;
	ulong cdsize;
	void *grabbuf;
	ulong grablen;
	ISAConf isa;
	char name[32];
	Pcidev *pcidev;
	LML *lml;

	if(isaconfig("lml", 0, &isa) == 0) {
		if (debug) print("lml not in plan9.ini\n");
		return;
	}
	pcidev = pcimatch(nil, PCI_VENDOR_ZORAN, PCI_DEVICE_ZORAN_36067);
	if (pcidev == nil) {
		return;
	}

	cdsize = CODEDATASIZE;
	codeData = (CodeData*)(((ulong)xalloc(cdsize+ BY2PG) + BY2PG-1) & ~(BY2PG-1));
	if (codeData == nil) {
		print("devlml: xalloc(%lux, %ux, 0)\n", cdsize, BY2PG);
		return;
	}

	grablen = GRABDATASIZE;
	grabbuf = (void*)(((ulong)xalloc(grablen+ BY2PG) + BY2PG-1) & ~(BY2PG-1));
	if (grabbuf == nil) {
		print("devlml: xalloc(%lux, %ux, 0)\n", grablen, BY2PG);
		return;
	}

	print("Installing Motion JPEG driver %s, irq %d\n", MJPG_VERSION, pcidev->intl); 
	print("MJPG buffer at 0x%.8lux, size 0x%.8lux\n", codeData, cdsize); 
	print("Grab buffer at 0x%.8lux, size 0x%.8lux\n", grabbuf, grablen); 
	pcidev = nil;
	
	for (nlml = 0; nlml < NLML && (pcidev = pcimatch(pcidev, VENDOR_ZORAN, ZORAN_36067)); nlml++){
		if(isaconfig("lml", nlml, &isa) == 0) {
			if (debug) print("lml %d not in plan9.ini\n", nlml);
			break;
		}
		lml = &lmls[nlml];
		lml->pcidev = pcidev;
		lml->codedata = (CodeData*)(((ulong)xalloc(Codedatasize+ BY2PG) + BY2PG-1) & ~(BY2PG-1));
		if (lml->codedata == nil) {
			print("devlml: xalloc(%ux, %ux, 0)\n", Codedatasize, BY2PG);
			return;
		}

	// Get access to DMA memory buffer
	codeData->pamjpg = PADDR(codeData->statCom);
	codeData->pagrab = PADDR(grabbuf);
		print("Installing Motion JPEG driver %s, irq %d\n", MJPG_VERSION, pcidev->intl); 
		print("MJPG buffer at 0x%.8lux, size 0x%.8ux\n", lml->codedata, Codedatasize); 

	prepbuf();
		// Get access to DMA memory buffer
		lml->codedata->pamjpg = PADDR(lml->codedata->statCom);

	pciPhysBaseAddr = (void *)(pcidev->mem[0].bar & ~0x0F);
		prepbuf(lml);

	print("zr36067 found at 0x%.8lux", pciPhysBaseAddr);
		print("zr36067 found at 0x%.8lux", pcidev->mem[0].bar & ~0x0F);

	regpa = upamalloc(pcidev->mem[0].bar & ~0x0F, pcidev->mem[0].size, 0);
	if (regpa == 0) {
		print("lml: failed to map registers\n");
		return;
	}
	pciBaseAddr = (ulong)KADDR(regpa);
	print(", mapped at 0x%.8lux\n", pciBaseAddr);

	memset(&segbuf, 0, sizeof(segbuf));
	segbuf.attr = SG_PHYSICAL;
	kstrdup(&segbuf.name, "lmlmjpg");
	segbuf.pa = PADDR(codeData);
	segbuf.size = cdsize;
	if (addphysseg(&segbuf) == -1) {
		print("lml: physsegment: lmlmjpg\n");
		return;
	}
		regpa = upamalloc(pcidev->mem[0].bar & ~0x0F, pcidev->mem[0].size, 0);
		if (regpa == 0) {
			print("lml: failed to map registers\n");
			return;
		}
		lml->pciBaseAddr = (ulong)KADDR(regpa);
		print(", mapped at 0x%.8lux\n", lml->pciBaseAddr);

		memset(&segbuf, 0, sizeof(segbuf));
		segbuf.attr = SG_PHYSICAL;
		sprint(name, "lml%d.mjpg", nlml);
		kstrdup(&segbuf.name, name);
		segbuf.pa = PADDR(lml->codedata);
		segbuf.size = Codedatasize;
		if (addphysseg(&segbuf) == -1) {
			print("lml: physsegment: %s\n", name);
			return;
		}

	memset(&segreg, 0, sizeof(segreg));
	segreg.attr = SG_PHYSICAL;
	kstrdup(&segreg.name, "lmlregs");
	segreg.pa = (ulong)regpa;
	segreg.size = pcidev->mem[0].size;
	if (addphysseg(&segreg) == -1) {
		print("lml: physsegment: lmlregs\n");
		return;
	}
		memset(&segbuf, 0, sizeof(segbuf));
		segbuf.attr = SG_PHYSICAL;
		sprint(name, "lml%d.regs", nlml);
		kstrdup(&segbuf.name, name);
		segbuf.pa = (ulong)regpa;
		segbuf.size = pcidev->mem[0].size;
		if (addphysseg(&segbuf) == -1) {
			print("lml: physsegment: %s\n", name);
			return;
		}

	memset(&seggrab, 0, sizeof(seggrab));
	seggrab.attr = SG_PHYSICAL;
	kstrdup(&seggrab.name, "lmlgrab");
	seggrab.pa = PADDR(grabbuf);
	seggrab.size = grablen;
	if (addphysseg(&seggrab) == -1) {
		print("lml: physsegment: lmlgrab\n");
		return;
		// Interrupt handler
		intrenable(pcidev->intl, lmlintr, lml, pcidev->tbdf, "lml");
	}

	// Interrupt handler
	intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf, "lml");

	return;
}



@@ 224,18 213,34 @@ lmlstat(Chan *c, uchar *db, int n)

static Chan*
lmlopen(Chan *c, int omode) {
	int i;
	LML *lml;

	if (omode != OREAD)
		error(Eperm);
	c->aux = 0;
	i = 0;
	switch((ulong)c->qid.path){
	case Qjpg:
	case Qraw:
	case Qctl1:
		i++;
	case Qctl0:
		if (i >= nlml)
			error(Eio);
		break;
	case Qjpg1:
	case Qraw1:
		i++;
	case Qjpg0:
	case Qraw0:
		// allow one open
		if (jpgopens)
		if (i >= nlml)
			error(Eio);
		lml = lmls+i;
		if (lml->jpgopens)
			error(Einuse);
		jpgopens = 1;
		jpgframeno = 0;
		jpgmode = omode;
		prepbuf();
		lml->jpgopens = 1;
		lml->jpgframeno = 0;
		prepbuf(lml);
		break;
	}
	return devopen(c, omode, lmldir, nelem(lmldir), devgen);


@@ 243,27 248,61 @@ lmlopen(Chan *c, int omode) {

static void
lmlclose(Chan *c) {
	int i;

	i = 0;
	switch((ulong)c->qid.path){
	case Qjpg:
	case Qraw:
		jpgopens = 0;
	case Qjpg1:
	case Qraw1:
		i++;
	case Qjpg0:
	case Qraw0:
		lmls[i].jpgopens = 0;
		break;
	}
}

static long
lmlread(Chan *c, void *va, long n, vlong voff) {
	int i;
	uchar *buf = va;
	long off = voff;
	LML *lml;
	static char lmlinfo[1024];
	int len;

	i = 0;
	switch((ulong)c->qid.path){
	case Qdir:
		return devdirread(c, (char *)buf, n, lmldir, nelem(lmldir), devgen);
	case Qjpg:
		return jpgread(c, buf, n, off, 1);
	case Qraw:
		return jpgread(c, buf, n, off, 0);
	case Qctl1:
		i++;
	case Qctl0:
		if (i >= nlml)
			error(Eio);
		lml = lmls+i;
		len = snprint(lmlinfo, sizeof lmlinfo, "lml%djpg	lml%draw\nlml%d.regs	0x%lux	0x%ux\nlml%d.mjpg	0x%lux	0x%ux\n",
			i, i,
			i, lml->pcidev->mem[0].bar & ~0x0F, lml->pcidev->mem[0].size,
			i, PADDR(lml->codedata), Codedatasize);
		if (voff > len)
			return 0;
		if (n > len - voff)
			n = len - voff;
		memmove(va, lmlinfo+voff, n);
		return n;
	case Qjpg1:
		i++;
	case Qjpg0:
		if (i >= nlml)
			error(Eio);
		return jpgread(lmls+i, buf, n, off, 1);
	case Qraw1:
		i++;
	case Qraw0:
		if (i >= nlml)
			error(Eio);
		return jpgread(lmls+i, buf, n, off, 0);
	}
}



@@ 295,24 334,26 @@ Dev lmldevtab = {
};

static void
lmlintr(Ureg *, void *) {
	ulong fstart, fno;
	ulong flags = readl(pciBaseAddr+INTR_STAT);
lmlintr(Ureg *, void *x) {
	FrameHeader *jpgheader;
	
	ulong fstart, fno, flags, statcom;
	LML *lml;

	lml = x;
	flags = readl(lml->pciBaseAddr+INTR_STAT);
	// Reset all interrupts from 067
	writel(0xff000000, pciBaseAddr + INTR_STAT);
	writel(0xff000000, lml->pciBaseAddr + INTR_STAT);

	if(flags & INTR_JPEGREP) {

		if(debug&(DBGINTR))
			print("MjpgDrv_intrHandler stat=0x%.8lux\n", flags);

		fstart = jpgframeno & 0x00000003;
		fstart = lml->jpgframeno & 0x00000003;
		for (;;) {
			jpgframeno++;
			fno = jpgframeno & 0x00000003;
			if (codeData->statCom[fno] & STAT_BIT)
			lml->jpgframeno++;
			fno = lml->jpgframeno & 0x00000003;
			if (lml->codedata->statCom[fno] & STAT_BIT)
				break;
			if (fno == fstart) {
				if (debug & DBGINTR)


@@ 320,15 361,13 @@ lmlintr(Ureg *, void *) {
				return;
			}
		}
		if (jpgopens && jpgmode == OREAD){
			jpgheader = (FrameHeader *)(codeData->frag[fno].hdr+2);
			jpgheader->frameNo = jpgframeno;
			jpgheader->ftime  = todget(nil);
			jpgheader->frameSize =
				(codeData->statCom[fno] & 0x00ffffff) >> 1;
			jpgheader->frameSeqNo = codeData->statCom[fno] >> 24;
		}
		wakeup(&sleepjpg);
		statcom = lml->codedata->statCom[fno];
		jpgheader = (FrameHeader *)(lml->codedata->frag[fno].hdr+2);
		jpgheader->frameNo = lml->jpgframeno;
		jpgheader->ftime  = todget(nil);
		jpgheader->frameSize = (statcom & 0x00ffffff) >> 1;
		jpgheader->frameSeqNo = statcom >> 24;
		wakeup(&lml->sleepjpg);
	}
	return;
}

M pc/devlml.h => pc/devlml.h +10 -6
@@ 1,6 1,7 @@
// Lml 22 driver

#define MJPG_VERSION "LML33 v0.2"
#define NLML 2

// The following values can be modified to tune/set default behaviour of the
// driver.


@@ 42,9 43,9 @@ typedef struct {

// The PCI vendor and device ids of the zoran chipset on the dc30
// these really belong in pci.h
#define PCI_VENDOR_ZORAN		0x11de
#define PCI_DEVICE_ZORAN_36057		0x6057
#define PCI_DEVICE_ZORAN_36067		PCI_DEVICE_ZORAN_36057
#define VENDOR_ZORAN		0x11de
#define ZORAN_36057		0x6057
#define ZORAN_36067		ZORAN_36057

#define BT819Addr 0x8a
#define BT856Addr 0x88


@@ 73,7 74,8 @@ struct FrameHeader {	// Don't modify this struct, used by h/w
	ushort frameNo;
	vlong ftime;
	ulong frameSize;
	ulong frameSeqNo;
	ushort frameSeqNo;
	ushort SOIfiller;
};

#define FRAGSIZE (128*1024)


@@ 101,8 103,10 @@ struct CodeData {	// Don't modify this struct, used by h/w
	HdrFragment	frag[4];
};

#define CODEDATASIZE ((sizeof(CodeData) + BY2PG - 1) & ~(BY2PG - 1))
#define GRABDATASIZE ((730 * 568 * 2 * 2 + BY2PG - 1) & ~(BY2PG - 1))
enum{
	Codedatasize = (sizeof(CodeData) + BY2PG - 1) & ~(BY2PG - 1),
	Grabdatasize = (730 * 568 * 2 * 2 + BY2PG - 1) & ~(BY2PG - 1),
};

#define POST_OFFICE		0x200
#define POST_PEND		0x02000000

M pc/vgamach64xx.c => pc/vgamach64xx.c +51 -40
@@ 108,35 108,36 @@ enum {
typedef struct {
	ushort 	m64_id;			/* Chip ID */
	int 		m64_vtgt;		/* Is this a VT or GT chipset? */
	double	m64_ovlclock;		/* Max. overlay clock frequency */
	ulong	m64_ovlclock;		/* Max. overlay clock frequency */
	int		m64_pro;			/* Is this a PRO? */
} mach64types;

static double mach64refclock;
static ulong mach64refclock;
static mach64types *mach64type;
static int mach64revb;			/* Revision B or greater? */
static ulong mach64overlay;		/* Overlay buffer */

static mach64types mach64s[] = {
	('C'<<8)|'T',	0,	0.,		0,	/* 4354: CT */
	('E'<<8)|'T',	0,	0.,		0,	/* 4554: ET */
	('G'<<8)|'B',	1,	125.,		1, 	/* 4742: 264GT PRO */
	('G'<<8)|'D',	1,	125.,		1, 	/* 4744: 264GT PRO */
	('G'<<8)|'I',	1,	125.,		1, 	/* 4749: 264GT PRO */
	('G'<<8)|'M',	0,	135.,		0,	/* 474D: Rage XL */
	('G'<<8)|'P',	1,	125.,		1, 	/* 4750: 264GT PRO */
	('G'<<8)|'Q',	1,	125.,		1,	/* 4751: 264GT PRO */
	('G'<<8)|'T',	1,	80.,		0,	/* 4754: 264GT[B] */
	('G'<<8)|'U',	1,	100.,		0,	/* 4755: 264GT DVD */
	('G'<<8)|'V',	1,	100.,		0,	/* 4756: Rage2C */
	('G'<<8)|'Z',	1,	100.,		0,	/* 475A: Rage2C */
	('V'<<8)|'T',	1,	80.,		0,	/* 5654: 264VT/GT/VTB */
	('V'<<8)|'U',	1,	80.,		0,	/* 5655: 264VT3 */
	('V'<<8)|'V',	1,	100.,		0,	/* 5656: 264VT4 */
	('L'<<8)|'B',	0,	135.,		1,	/* 4C42: Rage LTPro AGP */
	('L'<<8)|'I',		0,	135.,		0,	/* 4C49: Rage LTPro AGP */
	('L'<<8)|'M',	0,	135.,		0,	/* 4C4D: Rage Mobility */
	('L'<<8)|'P',	0,	135.,		1,	/* 4C50: 264LT PRO */
	('C'<<8)|'T',	0,	0,		0,	/* 4354: CT */
	('E'<<8)|'T',	0,	0,		0,	/* 4554: ET */
	('G'<<8)|'B',	1,	1250000,		1, 	/* 4742: 264GT PRO */
	('G'<<8)|'D',	1,	1250000,		1, 	/* 4744: 264GT PRO */
	('G'<<8)|'I',	1,	1250000,		1, 	/* 4749: 264GT PRO */
	('G'<<8)|'M',	0,	1350000,		0,	/* 474D: Rage XL */
	('G'<<8)|'P',	1,	1250000,		1, 	/* 4750: 264GT PRO */
	('G'<<8)|'Q',	1,	1250000,		1,	/* 4751: 264GT PRO */
	('G'<<8)|'R',	1,	1250000,		1,	/* 4752: */
	('G'<<8)|'T',	1,	800000,		0,	/* 4754: 264GT[B] */
	('G'<<8)|'U',	1,	1000000,		0,	/* 4755: 264GT DVD */
	('G'<<8)|'V',	1,	1000000,		0,	/* 4756: Rage2C */
	('G'<<8)|'Z',	1,	1000000,		0,	/* 475A: Rage2C */
	('V'<<8)|'T',	1,	800000,		0,	/* 5654: 264VT/GT/VTB */
	('V'<<8)|'U',	1,	800000,		0,	/* 5655: 264VT3 */
	('V'<<8)|'V',	1,	1000000,		0,	/* 5656: 264VT4 */
	('L'<<8)|'B',	0,	1350000,		1,	/* 4C42: Rage LTPro AGP */
	('L'<<8)|'I',		0,	1350000,		0,	/* 4C49: Rage LTPro AGP */
	('L'<<8)|'M',	0,	1350000,		0,	/* 4C4D: Rage Mobility */
	('L'<<8)|'P',	0,	1350000,		1,	/* 4C50: 264LT PRO */
};




@@ 692,7 693,7 @@ init_overlayclock(VGAscr *scr)
	uchar *cc, save, pll_ref_div, pll_vclk_cntl, vclk_post_div, 
			vclk_fb_div, ecp_div;
	int i;
	double dotclock;
	ulong dotclock;

	/* Taken from GLX */
	/* Get monitor dotclock, check for Overlay Scaler clock limit */


@@ 703,7 704,7 @@ init_overlayclock(VGAscr *scr)
  	cc[1] = 6<<2; vclk_post_div = (cc[2]>>(i+i)) & 3;
  	cc[1] = (7+i)<<2; vclk_fb_div = cc[2];

  	dotclock = 2.0 * mach64refclock * vclk_fb_div / 
	dotclock = 2 * mach64refclock * vclk_fb_div / 
			(pll_ref_div * (1 << vclk_post_div));
	/* ecp_div: 0=dotclock, 1=dotclock/2, 2=dotclock/4 */
  	ecp_div = dotclock / mach64type->m64_ovlclock;


@@ 711,7 712,8 @@ init_overlayclock(VGAscr *scr)

  	/* Force a scaler clock factor of 1 if refclock *
   	  * is unknown (VCLK_SRC not PLLVCLK)  */
  	if ((pll_vclk_cntl & 0x03) != 0x03) dotclock = ecp_div = 0;
  	if ((pll_vclk_cntl & 0x03) != 0x03) 
		ecp_div = 0;
  	if ((pll_vclk_cntl & 0x30) != ecp_div<<4) {
    		cc[1] = (5<<2)|2;
    		cc[2] = (pll_vclk_cntl&0xCF) | (ecp_div<<4);


@@ 792,18 794,18 @@ initengine(VGAscr *scr)
	table = *(ushort *)(bios + table + 0x10);
	switch (*(ushort *)(bios + table + 0x08)) {
      	case 2700: 
		mach64refclock = 27.0; 
		mach64refclock = 270000; 
		break;
      	case 2863: 
      	case 2864: 
		mach64refclock = 28.63636; 
		mach64refclock = 286363; 
		break;
      	case 2950: 
		mach64refclock = 29.498928713; 
		mach64refclock = 294989; 
		break;
    	case 1432: 
	default:
		mach64refclock = 14.31818; 
		mach64refclock = 143181; 
		break ;	
	}
	


@@ 1010,13 1012,15 @@ ovl_configure(VGAscr *scr, Chan *c, int nfields, char **field)
	int w, h;
	char *format;

	if (nfields != 4) error(Ebadarg);
	if (nfields != 4) 
		error(Ebadarg);

	w = (int)strtol(field[1], nil, 0);
	h = (int)strtol(field[2], nil, 0);
	format = field[3];

	if (c != ovl_chan) error(Einuse);
	if (c != ovl_chan) 
		error(Einuse);
	if (strcmp(format, "YUYV"))
		error(Eunsupportedformat);
	


@@ 1072,7 1076,8 @@ ovl_enable(VGAscr *scr, Chan *c, int nfields, char **field)
	int x, y, w, h;
	long h_inc, v_inc;

	if (nfields != 5) error(Ebadarg);
	if (nfields != 5) 
		error(Ebadarg);

	x = (int)strtol(field[1], nil, 0);
	y = (int)strtol(field[2], nil, 0);


@@ 1083,7 1088,8 @@ ovl_enable(VGAscr *scr, Chan *c, int nfields, char **field)
	     y < 0 || y + h > physgscreenr.max.y)
		error(Ebadarg);

	if (c != ovl_chan) error(Einuse);
	if (c != ovl_chan) 
		error(Einuse);
	if (scr->mmio[mmoffset[CrtcGenCntl]] & 1) {	/* double scan enable */
		y *= 2;
		h *= 2;


@@ 1110,15 1116,16 @@ ovl_enable(VGAscr *scr, Chan *c, int nfields, char **field)
static void
ovl_status(VGAscr *scr, Chan *, int nfields, char **field)
{
	if (nfields != 1) error(Ebadarg);
	if (nfields != 1) 
		error(Ebadarg);

	pprint("%s: %s %.4uX, VT/GT %s, PRO %s, ovlclock %d, rev B %s, refclock %d\n",
	pprint("%s: %s %.4uX, VT/GT %s, PRO %s, ovlclock %d, rev B %s, refclock %ld\n",
		   scr->dev->name, field[0], mach64type->m64_id,
		   mach64type->m64_vtgt? "yes": "no",
		   mach64type->m64_pro? "yes": "no",
		   (int)(mach64type->m64_ovlclock  * 10000.),
		   mach64type->m64_ovlclock,
		   mach64revb? "yes": "no",
		   (int)(mach64refclock * 10000.));
		   mach64refclock);
	pprint("%s: storage @%.8luX, aperture @%8.ulX, ovl buf @%.8ulX\n",
		   scr->dev->name, scr->storage, scr->aperture,
		   mach64overlay);


@@ 1127,8 1134,10 @@ ovl_status(VGAscr *scr, Chan *, int nfields, char **field)
static void
ovl_openctl(VGAscr *, Chan *c, int nfields, char **)
{
	if (nfields != 1) error(Ebadarg);
	if (ovl_chan) error(Einuse);
	if (nfields != 1) 
		error(Ebadarg);
	if (ovl_chan) 
		error(Einuse);
	ovl_chan = c;
}



@@ 1162,10 1171,12 @@ mach64xxovlctl(VGAscr *scr, Chan *c, void *a, int)
	char *field[MAXARGS];
	int nfields, i;

	if (!mach64type->m64_vtgt) error(Enodev);
	if (!mach64type->m64_vtgt) 
		error(Enodev);

	nfields = getfields(a, field, nelem(field), 1, "\t\n\r ");
	if (nfields < 1) error(Ebadarg);
	if (nfields < 1) 
		error(Ebadarg);

	for (i = 0; i != nelem(ovl_cmds); i++)
		if (!strcmp(field[0], ovl_cmds[i].ovl_command))

M port/parse.c => port/parse.c +12 -5
@@ 12,11 12,16 @@ Cmdbuf*
parsecmd(char *p, int n)
{
	Cmdbuf *volatile cb;
	int nf;
	char *sp;

	cb = smalloc(sizeof(*cb));
	
	if(n > sizeof(cb->buf)-1)
		n = sizeof(cb->buf)-1;
	/* count fields and allocate a big enough cmdbuf */
	for(nf = 1, sp = p; sp != nil && *sp; nf++, sp = strchr(sp+1, ' '))
		;
	sp = smalloc(sizeof(*cb) + n + 1 + nf*sizeof(char*));
	cb = (Cmdbuf*)sp;
	cb->buf = sp+sizeof(*cb);
	cb->f = (char**)(cb->buf + n + 1);

	if(up!=nil && waserror()){
		free(cb);


@@ 26,10 31,12 @@ parsecmd(char *p, int n)
	if(up != nil)
		poperror();

	/* dump new line and null terminate */
	if(n > 0 && cb->buf[n-1] == '\n')
		n--;
	cb->buf[n] = '\0';
	cb->nf = getfields(cb->buf, cb->f, nelem(cb->f), 1, " ");

	cb->nf = getfields(cb->buf, cb->f, nf, 1, " ");
	return cb;
}


M port/portdat.h => port/portdat.h +2 -2
@@ 712,8 712,8 @@ struct Logflag {

struct Cmdbuf
{
	char	buf[256];
	char	*f[16];
	char	*buf;
	char	**f;
	int	nf;
};