plan 9 kernel history: overview | file list | diff list

1997/0109/pc/main.c (diff list | history)

1997/0109/sys/src/9/pc/main.c:6,651997/0327/sys/src/9/pc/main.c:6,103 (short | long | prev | next)
1991/0706    
#include	"io.h" 
1991/0716    
#include	"ureg.h" 
#include	"init.h" 
1992/0918    
#include	<ctype.h> 
1991/0629    
 
1997/0327    
Mach *m; 
1992/0904    
 
1992/0903    
uchar *sp;	/* stack pointer for /boot */ 
1997/0327    
static  uchar *sp;	/* stack pointer for /boot */ 
1992/0903    
 
1992/0923    
extern PCArch nsx20, generic, ncr3170; 
                 
PCArch *arch; 
PCArch *knownarch[] = 
{ 
	&nsx20, 
	&ncr3170, 
	&generic, 
}; 
                 
1993/0330    
/* where b.com leaves configuration info */ 
#define BOOTARGS	((char*)(KZERO|1024)) 
#define	BOOTARGSLEN	1024 
1997/0327    
/* 
 * Where configuration info is left for the loaded programme. 
 * This will turn into a structure as more is done by the boot loader 
 * (e.g. why parse the .ini file twice?). 
 * There are 1024 bytes available at CONFADDR. 
 */ 
#define BOOTLINE	((char *)CONFADDR) 
#define BOOTLINELEN	64 
#define BOOTARGS	((char*)(CONFADDR+BOOTLINELEN)) 
#define	BOOTARGSLEN	(1024-BOOTLINELEN) 
1993/0330    
#define	MAXCONF		32 
 
1993/0915    
char bootdisk[NAMELEN]; 
1994/0607    
char filaddr[NAMELEN]; 
1993/0330    
char *confname[MAXCONF]; 
char *confval[MAXCONF]; 
int nconf; 
 
1993/0915    
/* memory map */ 
1995/0523    
#define MAXMEG 128 
1993/0915    
char mmap[MAXMEG+2]; 
1997/0327    
extern void ns16552install(void);	/* botch: config */ 
1993/0915    
 
1997/0327    
static int isoldbcom; 
 
static void 
bcompatibility(void) 
{ 
	uchar *bda; 
 
	if(strncmp(BOOTARGS, "ZORT 0\r\n", 8) == 0) 
		return; 
	isoldbcom = 1; 
 
	memmove(BOOTARGS, KADDR(1024), BOOTARGSLEN); 
	memmove(BOOTLINE, KADDR(0x100), BOOTLINELEN); 
 
	bda = KADDR(0x400); 
	bda[0x13] = 639; 
	bda[0x14] = 639>>8; 
} 
 
1991/0716    
void 
1991/0702    
main(void) 
1991/0625    
{ 
1991/1210    
	ident(); 
1992/0902    
	i8042a20();		/* enable address lines 20 and up */ 
1997/0327    
	outb(0x3F2, 0x00);		/* botch: turn off the floppy motor */ 
 
	/* 
	 * There is a little leeway here in the ordering but care must be 
	 * taken with dependencies: 
	 *	function		depends on 
	 *	========		========== 
	 *	machinit		m->machno, m->pdb 
	 *	cpuidentify		m 
	 *	memscan			cpuidentify (needs to know processor 
	 *				type for caching, etc.) 
	 *	archinit		memscan (MP config table may be at the 
	 *				top of system physical memory); 
	 *				conf.nmach (not critical, mpinit will check); 
	 *	confinit		meminit 
	 *	arch->intrinit		trapinit 
	 */ 
	conf.nmach = 1; 
	MACHP(0) = (Mach*)CPU0MACH; 
	m->pdb = (void*)CPU0PDB; 
1991/0711    
	machinit(); 
1991/1113    
	active.exiting = 0; 
	active.machs = 1; 
1997/0327    
	active.exiting = 0; 
	cpuidentify(); 
	bcompatibility(); 
	memscan(); 
	archinit(); 
1991/0711    
	confinit(); 
1992/0625    
	xinit(); 
1993/0915    
	dmainit(); 
1997/0327    
	trapinit(); 
1991/0703    
	screeninit(); 
1991/0716    
	printinit(); 
1991/0711    
	mmuinit(); 
1996/01171    
	trapinit(); 
1994/1007    
	ns16552install(); 
1997/0327    
	if(isoldbcom) 
		print("    ****OLD B.COM - UPGRADE****\n"); 
1992/0625    
	pageinit(); 
1997/0327    
	mmuinit(); 
	if(arch->intrinit) 
		arch->intrinit(); 
	ns16552install();			/* botch: config */ 
1991/0906    
	mathinit(); 
1991/0718    
	clockinit(); 
	faultinit(); 
1992/0409    
	kbdinit(); 
1997/0327    
	if(arch->clockenable) 
		arch->clockenable(); 
1991/0716    
	procinit0(); 
	initseg(); 
1994/0302    
	printcpufreq(); 
1997/0327    
	cpuidprint(); 
1995/0329    
	links(); 
1991/0716    
	chandevreset(); 
	swapinit(); 
1997/0109/sys/src/9/pc/main.c:67,981997/0327/sys/src/9/pc/main.c:105,121
1991/0716    
	schedinit(); 
1991/0712    
} 
1991/0706    
 
1992/0902    
/* 
1992/0903    
 *  This tries to capture architecture dependencies since things 
1994/0525    
 *  like power management/reseting/mouse are outside the hardware 
1992/0903    
 *  model. 
1992/0902    
 */ 
1991/0716    
void 
1991/1210    
ident(void) 
{ 
	char *id = (char*)(ROMBIOS + 0xFF40); 
1992/0923    
	PCArch **p; 
1991/1210    
                 
1992/0923    
	for(p = knownarch; *p != &generic; p++) 
		if(strncmp((*p)->id, id, strlen((*p)->id)) == 0) 
1992/0918    
			break; 
1992/0923    
	arch = *p; 
1991/1210    
} 
                 
void 
1991/0716    
machinit(void) 
1991/0712    
{ 
1991/0716    
	int n; 
1997/0327    
	int machno; 
	void *pdb; 
1991/0712    
 
1991/0716    
	n = m->machno; 
1997/0327    
	machno = m->machno; 
	pdb = m->pdb; 
1991/0716    
	memset(m, 0, sizeof(Mach)); 
	m->machno = n; 
	m->mmask = 1<<m->machno; 
1997/0327    
	m->machno = machno; 
	m->pdb = pdb; 
1991/0625    
} 
 
1991/0716    
void 
1997/0109/sys/src/9/pc/main.c:119,1251997/0327/sys/src/9/pc/main.c:142,148
1991/0716    
	 * Then early kproc's will have a root and dot. 
	 */ 
1993/0915    
	up->slash = namec("#/", Atodir, 0, 0); 
	up->dot = clone(up->slash, 0); 
1997/0327    
	up->dot = cclone(up->slash, 0); 
1991/0712    
 
1991/0716    
	chandevinit(); 
 
1997/0109/sys/src/9/pc/main.c:128,1371997/0327/sys/src/9/pc/main.c:151,156
1992/0918    
		strcat(tstr, " %s"); 
		ksetterm(tstr); 
1991/0927    
		ksetenv("cputype", "386"); 
1995/1121    
		if(cpuserver) 
			ksetenv("service", "cpu"); 
		else 
			ksetenv("service", "terminal"); 
1993/0915    
		for(i = 0; i < nconf; i++) 
			if(confname[i]) 
				ksetenv(confname[i], confval[i]); 
1997/0109/sys/src/9/pc/main.c:223,2291997/0327/sys/src/9/pc/main.c:242,248
1992/0323    
 
	ac = 0; 
1994/0219    
	av[ac++] = pusharg("/386/9dos"); 
1992/0903    
	cp[64] = 0; 
1997/0327    
	cp[BOOTLINELEN-1] = 0; 
1993/0915    
	buf[0] = 0; 
1992/0903    
	if(strncmp(cp, "fd!", 3) == 0){ 
		sprint(buf, "local!#f/fd%ddisk", atoi(cp+3)); 
1997/0109/sys/src/9/pc/main.c:285,3761997/0327/sys/src/9/pc/main.c:304,327
1993/0915    
	return 0; 
} 
 
1994/0814    
/* 
 *  zero memory to set ECC. 
 *  do a quick memory test also. 
 * 
1994/0815    
 *  if any part of a meg is missing/broken, return -1. 
1994/0814    
 */ 
int 
memclrtest(int meg, int len, long seed) 
{ 
	int j, n; 
	long y; 
	long *lp; 
	                 
	for(j = 0; j < len; j += BY2PG){ 
		lp = mapaddr(KZERO|(meg*MB+j)); 
		for(n = 0; n < BY2PG/BY2WD; n++) 
			lp[n] = seed + n; 
	} 
	for(j = 0; j < len; j += BY2PG){ 
		lp = mapaddr(KZERO|(meg*MB+j)); 
		for(n = 0; n < BY2PG/(2*BY2WD); n++){ 
			y = lp[n]; 
			lp[n] = ~lp[n^((BY2PG/BY2WD)-1)]; 
			lp[n^((BY2PG/BY2WD)-1)] = ~y; 
		} 
	} 
	for(j = 0; j < len; j += BY2PG){ 
		lp = mapaddr(KZERO|(meg*MB+j)); 
		for(n = 0; n < BY2PG/BY2WD; n++) 
			if(lp[n] != ~(seed + (n^((BY2PG/BY2WD)-1)))) 
				return -1; 
1994/1210    
/*		memset(lp, '!', BY2PG);/**/ 
1994/0814    
	} 
	return 0; 
} 
                 
1994/1210    
/* 
 *  look for unused address space in 0xC8000 to 1 meg 
 */ 
1993/0915    
void 
1994/1210    
romscan(void) 
{ 
	uchar *p; 
                 
	p = (uchar*)(KZERO+0xC8000); 
	while(p < (uchar*)(KZERO+0xE0000)){ 
		p[0] = 0x55; 
		p[1] = 0xAA; 
		p[2] = 4; 
1995/1019    
		if(p[0] == 0x55 && p[1] == 0xAA){ 
			p += p[2]*512; 
1994/1210    
			continue; 
		} 
1995/1219    
		p[0] = 0xCC; 
		p[2048-1] = 0xCC; 
		if(p[0] != 0xCC && p[2048-1] != 0xCC) 
1995/1019    
			putisa(PADDR(p), 2048); 
		p += 2048; 
1994/1210    
	} 
                 
	p = (uchar*)(KZERO+0xE0000); 
1995/1019    
	if(p[0] != 0x55 || p[1] != 0xAA){ 
1995/1219    
		p[0] = 0xCC; 
1995/1019    
		p[64*1024-1] = 0xff; 
1995/1219    
		if(p[0] != 0xCC && p[64*1024-1] != 0xCC) 
1995/1019    
			putisa(PADDR(p), 64*1024); 
	} 
1994/1210    
} 
                 
1996/0203    
static int 
getcfields(char *lp, char **fields, int n, char sep) 
1997/0327    
getcfields(char* lp, char** fields, int n, char* sep) 
1996/0203    
{ 
	int i; 
 
	for(i=0; lp && *lp && i<n; i++){ 
		while(*lp == sep) 
			*lp++=0; 
1997/0327    
	for(i = 0; lp && *lp && i < n; i++){ 
		while(*lp && strchr(sep, *lp) != 0) 
			*lp++ = 0; 
1996/0203    
		if(*lp == 0) 
			break; 
		fields[i]=lp; 
		while(*lp && *lp != sep){ 
1997/0327    
		fields[i] = lp; 
		while(*lp && strchr(sep, *lp) == 0){ 
1996/0203    
			if(*lp == '\\' && *(lp+1) == '\n') 
				*lp++ = ' '; 
			lp++; 
		} 
	} 
1997/0327    
 
1996/0203    
	return i; 
} 
 
1997/0109/sys/src/9/pc/main.c:377,3901997/0327/sys/src/9/pc/main.c:328,339
1994/1210    
void 
1991/0711    
confinit(void) 
{ 
1994/0814    
	long x, i, j, n; 
1997/0327    
	long i, j, n; 
1992/1002    
	int pcnt; 
1992/0715    
	ulong ktop; 
1996/0203    
	char *cp, *line[MAXCONF], *p, *q; 
1997/0327    
	char *cp; 
	char *line[MAXCONF], *p, *q; 
1994/0513    
	extern int defmaxmsg; 
1991/0711    
 
1993/0416    
	pcnt = 0; 
                 
1991/0711    
	/* 
1993/1113    
	 *  parse configuration args from dos file plan9.ini 
1993/0416    
	 */ 
1997/0109/sys/src/9/pc/main.c:404,4101997/0327/sys/src/9/pc/main.c:353,360
1996/0203    
	} 
	*p = 0; 
 
	n = getcfields(cp, line, MAXCONF, '\n'); 
1997/0327    
	pcnt = 0; 
	n = getcfields(cp, line, MAXCONF, "\n"); 
1993/0416    
	for(j = 0; j < n; j++){ 
1996/0203    
		if(*line[j] == '#') 
			continue; 
1997/0109/sys/src/9/pc/main.c:416,5221997/0327/sys/src/9/pc/main.c:366,384
1993/0416    
			*(line[j]+NAMELEN-1) = 0; 
		confname[nconf] = line[j]; 
		confval[nconf] = cp; 
		if(strcmp(confname[nconf], "kernelpercent") == 0) 
1997/0327    
		if(cistrcmp(confname[nconf], "kernelpercent") == 0) 
1993/0416    
			pcnt = 100 - atoi(confval[nconf]); 
1994/0513    
		if(strcmp(confname[nconf], "defmaxmsg") == 0){ 
1997/0327    
		if(cistrcmp(confname[nconf], "defmaxmsg") == 0){ 
1994/0513    
			i = atoi(confval[nconf]); 
			if(i < defmaxmsg && i >=128) 
				defmaxmsg = i; 
		} 
1994/0607    
		if(strcmp(confname[nconf], "filaddr") == 0) 
			strcpy(filaddr, confval[nconf]); 
1993/0416    
		nconf++; 
	} 
1994/0814    
 
1993/0416    
	/* 
1993/0915    
	 *  size memory above 1 meg. Kernel sits at 1 meg.  We 
	 *  only recognize MB size chunks. 
1991/0711    
	 */ 
1993/0915    
	memset(mmap, ' ', sizeof(mmap)); 
1991/0711    
	x = 0x12345678; 
1993/0915    
	for(i = 1; i <= MAXMEG; i++){ 
1991/0711    
		/* 
1993/0915    
		 *  write the first & last word in a megabyte of memory 
1991/0711    
		 */ 
1993/0915    
		*mapaddr(KZERO|(i*MB)) = x; 
		*mapaddr(KZERO|((i+1)*MB-BY2WD)) = x; 
1997/0327    
	meminit(); 
1993/0915    
 
1991/0711    
		/* 
1993/0915    
		 *  write the first and last word in all previous megs to 
		 *  handle address wrap around 
1991/0711    
		 */ 
1992/1019    
		for(j = 1; j < i; j++){ 
1993/0915    
			*mapaddr(KZERO|(j*MB)) = ~x; 
			*mapaddr(KZERO|((j+1)*MB-BY2WD)) = ~x; 
1991/0711    
		} 
1993/0915    
                 
1991/0711    
		/* 
1993/0915    
		 *  check for correct value 
1991/0711    
		 */ 
1994/0815    
		if(*mapaddr(KZERO|(i*MB)) == x) 
			if(*mapaddr(KZERO|((i+1)*MB-BY2WD)) == x) 
				mmap[i] = 'x'; 
1994/0814    
		x += 0x3141526; 
	} 
                 
	/* 
1994/0817    
	 *  zero and clear all except first 2 meg. 
1994/0814    
	 */ 
	x = 0x12345678; 
	for(i = MAXMEG; i > 1; i--){ 
		if(mmap[i] != 'x') 
			continue; 
1995/0523    
/* 
1994/0817    
		if(memclrtest(i, MB, x) < 0) 
1994/0814    
			mmap[i] = ' '; 
1995/0523    
 */ 
1991/0711    
		x += 0x3141526; 
	} 
1994/0814    
                 
1993/0915    
	/* 
	 *  bank0 usually goes from the end of kernel bss to the end of memory 
	 */ 
	ktop = PGROUND((ulong)end); 
	ktop = PADDR(ktop); 
	conf.base0 = ktop; 
	for(i = 1; mmap[i] == 'x'; i++) 
		; 
1994/0814    
	conf.npage0 = (i*MB - ktop)/BY2PG; 
1993/0915    
	conf.topofmem = i*MB; 
                 
	/* 
1994/0814    
	 *  bank1 usually goes from the end of BOOTARGS to 640k 
1993/0915    
	 */ 
1994/0813    
	conf.base1 = (ulong)(BOOTARGS + BOOTARGSLEN); 
1993/0915    
	conf.base1 = PGROUND(conf.base1); 
	conf.base1 = PADDR(conf.base1); 
1994/0813    
	conf.npage1 = (640*1024 - conf.base1)/BY2PG; 
1993/0915    
                 
	/* 
1994/0814    
	 *  if there is a hole in memory (e.g. due to a shadow BIOS) make the 
1993/0915    
	 *  memory after the hole be bank 1. The memory from 0 to 640k 
	 *  is lost. 
	 */ 
	for(; i <= MAXMEG; i++) 
		if(mmap[i] == 'x'){ 
			conf.base1 = i*MB; 
			for(j = i+1; mmap[j] == 'x'; j++) 
				; 
			conf.npage1 = (j - i)*MB/BY2PG; 
			conf.topofmem = j*MB; 
			break; 
		} 
1994/1210    
                 
	/* 
 	 *  add address space holes holes under 16 meg to available 
	 *  isa space. 
	 */ 
	romscan(); 
	if(conf.topofmem < 16*MB) 
		putisa(conf.topofmem, 16*MB - conf.topofmem); 
1993/0915    
                 
1991/0711    
	conf.npage = conf.npage0 + conf.npage1; 
1992/1113    
	conf.ldepth = 0; 
1993/0416    
	if(pcnt < 10) 
		pcnt = 70; 
1992/1014    
	conf.upages = (conf.npage*pcnt)/100; 
1997/0109/sys/src/9/pc/main.c:525,5361997/0327/sys/src/9/pc/main.c:387,396
1994/0923    
	conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5; 
1996/0612    
	if(cpuserver) 
1997/0109    
		conf.nproc *= 3; 
1993/0401    
	conf.monitor = 1; 
1997/0327    
	if(conf.nproc > 2000) 
		conf.nproc = 2000; 
1993/0401    
	conf.nswap = conf.nproc*80; 
	conf.nimage = 50; 
	conf.nfloppy = 2; 
	conf.nhard = 2; 
1993/0413    
	conf.nmach = 1; 
1997/0327    
	conf.nimage = 200; 
1991/0711    
} 
 
1991/0913    
char *mathmsg[] = 
1997/0109/sys/src/9/pc/main.c:549,5551997/0327/sys/src/9/pc/main.c:409,415
1991/0912    
 *  math coprocessor error 
 */ 
void 
1993/1124    
matherror(Ureg *ur, void *arg) 
1997/0327    
matherror(Ureg *ur, void*) 
1991/0912    
{ 
1991/0913    
	ulong status; 
	int i; 
1997/0109/sys/src/9/pc/main.c:556,5631997/0327/sys/src/9/pc/main.c:416,421
1991/0913    
	char *msg; 
	char note[ERRLEN]; 
 
1993/1124    
	USED(arg); 
                 
1991/0913    
	/* 
	 *  a write cycle to port 0xF0 clears the interrupt latch attached 
	 *  to the error# line from the 387 
1997/0109/sys/src/9/pc/main.c:591,5991997/0327/sys/src/9/pc/main.c:449,456
1991/0906    
 *  math coprocessor emulation fault 
 */ 
void 
1993/1124    
mathemu(Ureg *ur, void *arg) 
1997/0327    
mathemu(Ureg*, void*) 
1991/0906    
{ 
1993/1124    
	USED(ur, arg); 
1993/0915    
	switch(up->fpstate){ 
1991/0906    
	case FPinit: 
		fpinit(); 
1997/0109/sys/src/9/pc/main.c:613,6221997/0327/sys/src/9/pc/main.c:470,477
1991/0906    
 *  math coprocessor segment overrun 
 */ 
void 
1993/1124    
mathover(Ureg *ur, void *arg) 
1997/0327    
mathover(Ureg*, void*) 
1991/0906    
{ 
1993/1124    
	USED(ur, arg); 
1993/0915    
print("sys: fp: math overrun pc 0x%lux pid %d\n", ur->pc, up->pid); 
1992/0805    
	pexit("math overrun", 0); 
1991/0906    
} 
 
1997/0109/sys/src/9/pc/main.c:623,6321997/0327/sys/src/9/pc/main.c:478,488
1991/0906    
void 
mathinit(void) 
{ 
1993/1124    
	setvec(Matherr1vec, matherror, 0); 
	setvec(Matherr2vec, matherror, 0); 
	setvec(Mathemuvec, mathemu, 0); 
	setvec(Mathovervec, mathover, 0); 
1997/0327    
	intrenable(VectorCERR, matherror, 0, BUSUNKNOWN); 
	if(X86FAMILY(m->cpuidax) == 3) 
		intrenable(VectorIRQ13, matherror, 0, BUSUNKNOWN); 
	intrenable(VectorCNA, mathemu, 0, BUSUNKNOWN); 
	intrenable(VectorCSO, mathover, 0, BUSUNKNOWN); 
1991/0906    
} 
 
/* 
1997/0109/sys/src/9/pc/main.c:654,7781997/0327/sys/src/9/pc/main.c:510,552
1991/0906    
	} 
1991/0712    
} 
 
/* 
1991/0716    
 *  Restore what procsave() saves 
1991/0712    
 */ 
1991/0716    
void 
1992/0122    
procrestore(Proc *p) 
1997/0327    
exit(int ispanic) 
1991/0712    
{ 
1992/0711    
	USED(p); 
1991/0712    
} 
1997/0327    
	int ms, once; 
1991/0712    
 
1991/0906    
/* 
1991/1210    
 *  the following functions all are slightly different from 
 *  PC to PC. 
1991/0803    
 */ 
1997/0327    
	lock(&active); 
	if(ispanic) 
		active.ispanic = ispanic; 
	else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0) 
		active.ispanic = 0; 
	once = active.machs & (1<<m->machno); 
	active.machs &= ~(1<<m->machno); 
	active.exiting = 1; 
	unlock(&active); 
1991/0803    
 
void 
1992/0812    
exit(int ispanic) 
1991/0803    
{ 
1993/1013    
	up = 0; 
1996/0202    
	active.machs = 0; 
1991/0803    
	print("exiting\n"); 
1997/0327    
	if(once) 
		print("cpu%d: exiting\n", m->machno); 
1996/01171    
	spllo(); 
1993/0915    
	if(ispanic){ 
1997/0327    
	for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){ 
		delay(TK2MS(2)); 
		if(active.machs == 0 && consactive() == 0) 
			break; 
	} 
 
	if(active.ispanic && m->machno == 0){ 
1993/1113    
		if(cpuserver) 
1993/0915    
			delay(10000); 
		else 
			for(;;); 
1996/01171    
	} else 
1997/0327    
	} 
	else 
1996/01171    
		delay(1000); 
1992/0903    
 
1992/0923    
	(*arch->reset)(); 
1997/0327    
	arch->reset(); 
1991/0803    
} 
 
/* 
1991/1210    
 *  set cpu speed 
 *	0 == low speed 
 *	1 == high speed 
1991/0803    
 */ 
1991/1210    
int 
cpuspeed(int speed) 
1991/0803    
{ 
1992/0923    
	if(arch->cpuspeed) 
		return (*arch->cpuspeed)(speed); 
	else 
1991/1210    
		return 0; 
1991/0803    
} 
                 
/* 
1991/1210    
 *  f == frequency (Hz) 
 *  d == duration (ms) 
1991/0803    
 */ 
1991/1210    
void 
buzz(int f, int d) 
1991/0803    
{ 
1992/0923    
	if(arch->buzz) 
		(*arch->buzz)(f, d); 
1991/0803    
} 
                 
/* 
1991/1210    
 *  each bit in val stands for a light 
1991/0803    
 */ 
1991/1210    
void 
lights(int val) 
1991/0803    
{ 
1992/0923    
	if(arch->lights) 
		(*arch->lights)(val); 
1991/0803    
} 
                 
/* 
1991/0913    
 *  power to serial port 
1991/1210    
 *	onoff == 1 means on 
 *	onoff == 0 means off 
1991/0803    
 */ 
int 
serial(int onoff) 
{ 
1992/0923    
	if(arch->serialpower) 
		return (*arch->serialpower)(onoff); 
	else 
1991/1210    
		return 0; 
1991/0803    
} 
                 
1991/1001    
/* 
 *  power to modem 
1991/1210    
 *	onoff == 1 means on 
 *	onoff == 0 means off 
1991/1001    
 */ 
int 
modem(int onoff) 
{ 
1992/0923    
	if(arch->modempower) 
		return (*arch->modempower)(onoff); 
	else 
1991/1210    
		return 0; 
1993/0915    
} 
                 
static int 
parseether(uchar *to, char *from) 
{ 
	char nip[4]; 
	char *p; 
	int i; 
                 
	p = from; 
	for(i = 0; i < 6; i++){ 
		if(*p == 0) 
			return -1; 
		nip[0] = *p++; 
		if(*p == 0) 
			return -1; 
		nip[1] = *p++; 
		nip[2] = 0; 
		to[i] = strtoul(nip, 0, 16); 
		if(*p == ':') 
			p++; 
	} 
	return 0; 
} 
                 
int 
isaconfig(char *class, int ctlrno, ISAConf *isa) 
{ 
1995/0920    
	char cc[NAMELEN], *p, *q, *r; 
1997/0109/sys/src/9/pc/main.c:780,7861997/0327/sys/src/9/pc/main.c:554,560
1993/0915    
 
	sprint(cc, "%s%d", class, ctlrno); 
	for(n = 0; n < nconf; n++){ 
		if(strncmp(confname[n], cc, NAMELEN)) 
1997/0327    
		if(cistrncmp(confname[n], cc, NAMELEN)) 
1993/0915    
			continue; 
1995/0920    
		isa->nopt = 0; 
1993/0915    
		p = confval[n]; 
1997/0109/sys/src/9/pc/main.c:789,7951997/0327/sys/src/9/pc/main.c:563,569
1993/0915    
				p++; 
			if(*p == '\0') 
				break; 
			if(strncmp(p, "type=", 5) == 0){ 
1997/0327    
			if(cistrncmp(p, "type=", 5) == 0){ 
1993/0915    
				p += 5; 
				for(q = isa->type; q < &isa->type[NAMELEN-1]; q++){ 
					if(*p == '\0' || *p == ' ' || *p == '\t') 
1997/0109/sys/src/9/pc/main.c:798,8191997/0327/sys/src/9/pc/main.c:572,589
1993/0915    
				} 
				*q = '\0'; 
			} 
			else if(strncmp(p, "port=", 5) == 0) 
1997/0327    
			else if(cistrncmp(p, "port=", 5) == 0) 
1993/0915    
				isa->port = strtoul(p+5, &p, 0); 
			else if(strncmp(p, "irq=", 4) == 0) 
1997/0327    
			else if(cistrncmp(p, "irq=", 4) == 0) 
1993/0915    
				isa->irq = strtoul(p+4, &p, 0); 
1995/0803    
			else if(strncmp(p, "dma=", 4) == 0) 
1997/0327    
			else if(cistrncmp(p, "dma=", 4) == 0) 
1996/0425    
				isa->dma = strtoul(p+4, &p, 0); 
1993/0915    
			else if(strncmp(p, "mem=", 4) == 0) 
1997/0327    
			else if(cistrncmp(p, "mem=", 4) == 0) 
1993/0915    
				isa->mem = strtoul(p+4, &p, 0); 
			else if(strncmp(p, "size=", 5) == 0) 
1997/0327    
			else if(cistrncmp(p, "size=", 5) == 0) 
1993/0915    
				isa->size = strtoul(p+5, &p, 0); 
1994/0823    
			else if(strncmp(p, "freq=", 5) == 0) 
1997/0327    
			else if(cistrncmp(p, "freq=", 5) == 0) 
1994/0823    
				isa->freq = strtoul(p+5, &p, 0); 
1995/0920    
			else if(strncmp(p, "ea=", 3) == 0){ 
				if(parseether(isa->ea, p+3) == -1) 
					memset(isa->ea, 0, 6); 
			} 
			else if(isa->nopt < NISAOPT){ 
				r = isa->opt[isa->nopt]; 
				while(*p && *p != ' ' && *p != '\t'){ 
1997/0109/sys/src/9/pc/main.c:867,8711997/0327/sys/src/9/pc/main.c:637,666
1995/0222    
		if(bc == 0) 
			break; 
	} 
1997/0327    
	return 0; 
} 
 
int 
cistrncmp(char *a, char *b, int n) 
{ 
	unsigned ac, bc; 
 
	while(n > 0){ 
		ac = *a++; 
		bc = *b++; 
		n--; 
 
		if(ac >= 'A' && ac <= 'Z') 
			ac = 'a' + (ac - 'A'); 
		if(bc >= 'A' && bc <= 'Z') 
			bc = 'a' + (bc - 'A'); 
 
		ac -= bc; 
		if(ac) 
			return ac; 
		if(bc == 0) 
			break; 
	} 
 
1995/0222    
	return 0; 
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)