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

1994/1118/pc/ns16552.h (diff list | history)

1994/0902/sys/src/9/pc/ns16552.h:66,801994/1006/sys/src/9/pc/ns16552.h:66,78 (short | long)
Debugging or hw bug fix: don't panic if don't manage to clear all the interrupt bits after 1024 tries.
rsc Fri Mar 4 12:44:25 2005
1994/0902    
 
	USED(ur); 
	mp = arg; 
	for(loops = 0;; loops++){ 
		if(loops > 1024) 
			panic("mp008intr"); 
1994/1006    
	for(loops = 0; loops < 1024; loops++){ 
1994/0902    
		n = ~inb(mp->mem); 
		if(n == 0) 
			return; 
		for(i = 0; n; i++){ 
			if(n & 1) 
				ns16552intrx(ur, uart[mp->first+i]); 
1994/1006    
				ns16552intrx(ur, (void*)(mp->first+i)); 
1994/0902    
			n >>= 1; 
		} 
	} 
1994/1006/sys/src/9/pc/ns16552.h:81,971994/1007/sys/src/9/pc/ns16552.h:81,108 (short | long)
Publish ns16552install. Add console= support for plan9.ini.
rsc Fri Mar 4 12:44:25 2005
1994/0902    
/* 
 *  install the uarts (called by reset) 
 */ 
static void 
1994/1007    
void 
1994/0902    
ns16552install(void) 
{ 
	int i, j, port; 
1994/1007    
	char *p; 
1994/0902    
	Scard *sc; 
1994/1007    
	static int already; 
1994/0902    
 
1994/1007    
	if(already) 
		return; 
	already = 1; 
 
1994/0902    
	/* first two ports are always there and always the normal frequency */ 
	ns16552setup(0x3F8, UartFREQ); 
	setvec(Uart0vec, ns16552intrx, (void*)0); 
	ns16552setup(0x2F8, UartFREQ); 
	setvec(Uart1vec, ns16552intrx, (void*)1); 
1994/1007    
 
	/* set up a serial console */ 
	p = getconf("console"); 
	if(p) 
		ns16552special(atoi(p), 9600, &kbdq, &printq, kbdcr2nl); 
1994/0902    
 
	/* the rest come out of plan9.ini */ 
	for(i = 0; i < Maxcard; i++){ 
1994/1007/sys/src/9/pc/ns16552.h:131,1421994/1106/sys/src/9/pc/ns16552.h:131,144 (short | long)
Add com serial type.
rsc Fri Mar 4 12:44:25 2005
1994/0902    
				ns16552setup(port, sc->freq); 
				port += 8; 
			} 
		} else { 
1994/1106    
		} else if(strcmp(sc->type, "com") == 0 || strcmp(sc->type, "COM") == 0){ 
1994/0902    
			/* 
			 *  port gives base port address for the uart 
			 *  irq is interrupt 
			 *  freq is the baud rate generator frequency 
			 */ 
1994/1106    
			if(sc->freq == 0) 
				sc->freq = UartFREQ; 
1994/0902    
			ns16552setup(sc->port, sc->freq); 
			setvec(Int0vec+sc->irq, ns16552intrx, (void*)(nuart-1)); 
		} 
1994/1106/sys/src/9/pc/ns16552.h:14,201994/1108/sys/src/9/pc/ns16552.h:14,20 (short | long)
Change ns16552setup to add name.
rsc Fri Mar 4 12:44:25 2005
1994/0902    
#define uartwrreg(u,r,v)	outb((u)->port + r, (u)->sticky[r] | (v)) 
#define uartrdreg(u,r)		inb((u)->port + r) 
 
void	ns16552setup(ulong, ulong); 
1994/1108    
void	ns16552setup(ulong, ulong, char*); 
1994/0902    
 
/* 
 *  definition of an optional serial card 
1994/1106/sys/src/9/pc/ns16552.h:87,921994/1108/sys/src/9/pc/ns16552.h:87,93
1994/0902    
	int i, j, port; 
1994/1007    
	char *p; 
1994/0902    
	Scard *sc; 
1994/1108    
	char name[NAMELEN]; 
1994/1007    
	static int already; 
1994/0902    
 
1994/1007    
	if(already) 
1994/1106/sys/src/9/pc/ns16552.h:94,1021994/1108/sys/src/9/pc/ns16552.h:95,103
1994/1007    
	already = 1; 
 
1994/0902    
	/* first two ports are always there and always the normal frequency */ 
	ns16552setup(0x3F8, UartFREQ); 
1994/1108    
	ns16552setup(0x3F8, UartFREQ, "eia0"); 
1994/0902    
	setvec(Uart0vec, ns16552intrx, (void*)0); 
	ns16552setup(0x2F8, UartFREQ); 
1994/1108    
	ns16552setup(0x2F8, UartFREQ, "eia1"); 
1994/0902    
	setvec(Uart1vec, ns16552intrx, (void*)1); 
1994/1007    
 
	/* set up a serial console */ 
1994/1106/sys/src/9/pc/ns16552.h:128,1341994/1108/sys/src/9/pc/ns16552.h:129,136
1994/0902    
			setvec(Int0vec+sc->irq, mp008intr, sc); 
			port = sc->port; 
			for(j=0; j < sc->size; j++){ 
				ns16552setup(port, sc->freq); 
1994/1108    
				sprint(name, "eia%d%2.2d", i, j); 
				ns16552setup(port, sc->freq, name); 
1994/0902    
				port += 8; 
			} 
1994/1106    
		} else if(strcmp(sc->type, "com") == 0 || strcmp(sc->type, "COM") == 0){ 
1994/1106/sys/src/9/pc/ns16552.h:139,1451994/1108/sys/src/9/pc/ns16552.h:141,148
1994/0902    
			 */ 
1994/1106    
			if(sc->freq == 0) 
				sc->freq = UartFREQ; 
1994/0902    
			ns16552setup(sc->port, sc->freq); 
1994/1108    
			sprint(name, "eia%d00", i); 
			ns16552setup(sc->port, sc->freq, name); 
1994/0902    
			setvec(Int0vec+sc->irq, ns16552intrx, (void*)(nuart-1)); 
		} 
	} 
1994/1108/sys/src/9/pc/ns16552.h:84,901994/1118/sys/src/9/pc/ns16552.h:84,90 (short | long)
Bug fix?: allocate cards in order.
rsc Fri Mar 4 12:44:25 2005
1994/1007    
void 
1994/0902    
ns16552install(void) 
{ 
	int i, j, port; 
1994/1118    
	int i, j, port, nscard; 
1994/1007    
	char *p; 
1994/0902    
	Scard *sc; 
1994/1108    
	char name[NAMELEN]; 
1994/1108/sys/src/9/pc/ns16552.h:106,1161994/1118/sys/src/9/pc/ns16552.h:106,118
1994/1007    
		ns16552special(atoi(p), 9600, &kbdq, &printq, kbdcr2nl); 
1994/0902    
 
	/* the rest come out of plan9.ini */ 
1994/1118    
	nscard = 0; 
1994/0902    
	for(i = 0; i < Maxcard; i++){ 
		sc = scard[i] = xalloc(sizeof(Scard)); 
1994/1118    
		sc = scard[nscard] = xalloc(sizeof(Scard)); 
1994/0902    
		if(isaconfig("serial", i, sc) == 0){ 
			xfree(sc); 
			break; 
1994/1118    
			scard[nscard] = 0; 
			continue; 
1994/0902    
		} 
 
		if(strcmp(sc->type, "MP008") == 0 || strcmp(sc->type, "mp008") == 0){ 
1994/1108/sys/src/9/pc/ns16552.h:129,1351994/1118/sys/src/9/pc/ns16552.h:131,137
1994/0902    
			setvec(Int0vec+sc->irq, mp008intr, sc); 
			port = sc->port; 
			for(j=0; j < sc->size; j++){ 
1994/1108    
				sprint(name, "eia%d%2.2d", i, j); 
1994/1118    
				sprint(name, "eia%d%2.2d", nscard, j); 
1994/1108    
				ns16552setup(port, sc->freq, name); 
1994/0902    
				port += 8; 
			} 
1994/1108/sys/src/9/pc/ns16552.h:141,1501994/1118/sys/src/9/pc/ns16552.h:143,154
1994/0902    
			 */ 
1994/1106    
			if(sc->freq == 0) 
				sc->freq = UartFREQ; 
1994/1108    
			sprint(name, "eia%d00", i); 
1994/1118    
			sprint(name, "eia%d00", nscard); 
1994/1108    
			ns16552setup(sc->port, sc->freq, name); 
1994/0902    
			setvec(Int0vec+sc->irq, ns16552intrx, (void*)(nuart-1)); 
		} 
1994/1118    
 
		nscard++; 
1994/0902    
	} 
} 
 
1994/1118/sys/src/9/pc/ns16552.h:115,1211995/0222/sys/src/9/pc/ns16552.h:115,121 (short | long)
Use cistrcmp. Remove iprint.
rsc Fri Mar 4 12:44:25 2005
1994/1118    
			continue; 
1994/0902    
		} 
 
		if(strcmp(sc->type, "MP008") == 0 || strcmp(sc->type, "mp008") == 0){ 
1995/0222    
		if(cistrcmp(sc->type, "MP008") == 0){ 
1994/0902    
			/* 
			 *  port gives base port address for uarts 
			 *  irq is interrupt 
1994/1118/sys/src/9/pc/ns16552.h:135,1411995/0222/sys/src/9/pc/ns16552.h:135,141
1994/1108    
				ns16552setup(port, sc->freq, name); 
1994/0902    
				port += 8; 
			} 
1994/1106    
		} else if(strcmp(sc->type, "com") == 0 || strcmp(sc->type, "COM") == 0){ 
1995/0222    
		} else if(cistrcmp(sc->type, "com") == 0){ 
1994/0902    
			/* 
			 *  port gives base port address for the uart 
			 *  irq is interrupt 
1994/1118/sys/src/9/pc/ns16552.h:147,1651995/0222/sys/src/9/pc/ns16552.h:147,152
1994/1108    
			ns16552setup(sc->port, sc->freq, name); 
1994/0902    
			setvec(Int0vec+sc->irq, ns16552intrx, (void*)(nuart-1)); 
		} 
1994/1118    
                 
		nscard++; 
1994/0902    
	} 
} 
                 
int 
iprint(char *fmt, ...) 
{ 
	char buf[PRINTSIZE]; 
	int n; 
                 
	n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf; 
	screenputs(buf, n); 
                 
	return n; 
} 
1995/0222/sys/src/9/pc/ns16552.h:15,211997/0327/sys/src/9/pc/ns16552.h:15,22 (short | long)
SMP fixes XXX. Add ns16552special, uartclock. Use arch-specific modempower, serialport functions. Anonymize.
rsc Fri Mar 4 12:44:25 2005
1994/0902    
#define uartrdreg(u,r)		inb((u)->port + r) 
 
1994/1108    
void	ns16552setup(ulong, ulong, char*); 
1994/0902    
                 
1997/0327    
void	ns16552special(int, int, Queue**, Queue**, int (*)(Queue*, int)); 
void	uartclock(void); 
1994/0902    
/* 
 *  definition of an optional serial card 
 */ 
1995/0222/sys/src/9/pc/ns16552.h:32,421997/0327/sys/src/9/pc/ns16552.h:33,43
1994/0902    
{ 
	switch(dev){ 
	case Modem: 
		if(modem(onoff) < 0) 
1997/0327    
		if((*arch->modempower)(onoff) < 0) 
1994/0902    
			print("can't turn %s modem speaker\n", onoff?"on":"off"); 
		break; 
	case Serial: 
		if(serial(onoff) < 0) 
1997/0327    
		if((*arch->serialpower)(onoff) < 0) 
1994/0902    
			print("can't turn %s serial port power\n", onoff?"on":"off"); 
		break; 
	} 
1995/0222/sys/src/9/pc/ns16552.h:46,551997/0327/sys/src/9/pc/ns16552.h:47,54
1994/0902    
 *  handle an interrupt to a single uart 
 */ 
static void 
ns16552intrx(Ureg *ur, void *arg) 
1997/0327    
ns16552intrx(Ureg*, void* arg) 
1994/0902    
{ 
	USED(ur); 
                 
	ns16552intr((ulong)arg); 
} 
 
1995/0222/sys/src/9/pc/ns16552.h:58,701997/0327/sys/src/9/pc/ns16552.h:57,68
1994/0902    
 *  tells which of 8 devices interrupted. 
 */ 
static void 
mp008intr(Ureg *ur, void *arg) 
1997/0327    
mp008intr(Ureg* ureg, void* arg) 
1994/0902    
{ 
	int i, loops; 
	uchar n; 
	Scard *mp; 
 
	USED(ur); 
	mp = arg; 
1994/1006    
	for(loops = 0; loops < 1024; loops++){ 
1994/0902    
		n = ~inb(mp->mem); 
1995/0222/sys/src/9/pc/ns16552.h:72,781997/0327/sys/src/9/pc/ns16552.h:70,76
1994/0902    
			return; 
		for(i = 0; n; i++){ 
			if(n & 1) 
1994/1006    
				ns16552intrx(ur, (void*)(mp->first+i)); 
1997/0327    
				ns16552intrx(ureg, (void*)(mp->first+i)); 
1994/0902    
			n >>= 1; 
		} 
	} 
1995/0222/sys/src/9/pc/ns16552.h:85,911997/0327/sys/src/9/pc/ns16552.h:83,89
1994/0902    
ns16552install(void) 
{ 
1994/1118    
	int i, j, port, nscard; 
1994/1007    
	char *p; 
1997/0327    
	char *p, *q; 
1994/0902    
	Scard *sc; 
1994/1108    
	char name[NAMELEN]; 
1994/1007    
	static int already; 
1995/0222/sys/src/9/pc/ns16552.h:96,1091997/0327/sys/src/9/pc/ns16552.h:94,110
1994/1007    
 
1994/0902    
	/* first two ports are always there and always the normal frequency */ 
1994/1108    
	ns16552setup(0x3F8, UartFREQ, "eia0"); 
1994/0902    
	setvec(Uart0vec, ns16552intrx, (void*)0); 
1997/0327    
	intrenable(VectorUART0, ns16552intrx, (void*)0, BUSUNKNOWN); 
1994/1108    
	ns16552setup(0x2F8, UartFREQ, "eia1"); 
1994/0902    
	setvec(Uart1vec, ns16552intrx, (void*)1); 
1997/0327    
	intrenable(VectorUART1, ns16552intrx, (void*)1, BUSUNKNOWN); 
	addclock0link(uartclock); 
1994/1007    
 
	/* set up a serial console */ 
	p = getconf("console"); 
	if(p) 
		ns16552special(atoi(p), 9600, &kbdq, &printq, kbdcr2nl); 
1997/0327    
	if(p = getconf("console")){ 
		port = strtol(p, &q, 0); 
		if(p != q && (port == 0 || port == 1)) 
			ns16552special(port, 9600, &kbdq, &printq, kbdcr2nl); 
	} 
1994/0902    
 
	/* the rest come out of plan9.ini */ 
1994/1118    
	nscard = 0; 
1995/0222/sys/src/9/pc/ns16552.h:128,1341997/0327/sys/src/9/pc/ns16552.h:129,135
1994/0902    
			if(sc->freq == 0) 
				sc->freq = UartFREQ; 
			sc->first = nuart; 
			setvec(Int0vec+sc->irq, mp008intr, sc); 
1997/0327    
			intrenable(VectorPIC+sc->irq, mp008intr, sc, BUSUNKNOWN); 
1994/0902    
			port = sc->port; 
			for(j=0; j < sc->size; j++){ 
1994/1118    
				sprint(name, "eia%d%2.2d", nscard, j); 
1995/0222/sys/src/9/pc/ns16552.h:145,1511997/0327/sys/src/9/pc/ns16552.h:146,152
1994/1106    
				sc->freq = UartFREQ; 
1994/1118    
			sprint(name, "eia%d00", nscard); 
1994/1108    
			ns16552setup(sc->port, sc->freq, name); 
1994/0902    
			setvec(Int0vec+sc->irq, ns16552intrx, (void*)(nuart-1)); 
1997/0327    
			intrenable(VectorPIC+sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN); 
1994/0902    
		} 
1994/1118    
		nscard++; 
1994/0902    
	} 
1997/0327/sys/src/9/pc/ns16552.h:136,1421998/0221/sys/src/9/pc/ns16552.h:136,142 (short | long)
Only use com for non-standard ports.
rsc Fri Mar 4 12:44:25 2005
1994/1108    
				ns16552setup(port, sc->freq, name); 
1994/0902    
				port += 8; 
			} 
1995/0222    
		} else if(cistrcmp(sc->type, "com") == 0){ 
1998/0221    
		} else if(cistrcmp(sc->type, "com") == 0 && sc->port != 0x3F8 && sc->port != 0x2F8){ 
1994/0902    
			/* 
			 *  port gives base port address for the uart 
			 *  irq is interrupt 
1998/0221/sys/src/9/pc/ns16552.h:94,1021998/0910/sys/src/9/pc/ns16552.h:94,102 (short | long)
Change Vector* to Irq*.
rsc Fri Mar 4 12:44:25 2005
1994/1007    
 
1994/0902    
	/* first two ports are always there and always the normal frequency */ 
1994/1108    
	ns16552setup(0x3F8, UartFREQ, "eia0"); 
1997/0327    
	intrenable(VectorUART0, ns16552intrx, (void*)0, BUSUNKNOWN); 
1998/0910    
	intrenable(IrqUART0, ns16552intrx, (void*)0, BUSUNKNOWN); 
1994/1108    
	ns16552setup(0x2F8, UartFREQ, "eia1"); 
1997/0327    
	intrenable(VectorUART1, ns16552intrx, (void*)1, BUSUNKNOWN); 
1998/0910    
	intrenable(IrqUART1, ns16552intrx, (void*)1, BUSUNKNOWN); 
1997/0327    
	addclock0link(uartclock); 
1994/1007    
 
	/* set up a serial console */ 
1998/0910/sys/src/9/pc/ns16552.h:129,1351998/0918/sys/src/9/pc/ns16552.h:129,135 (short | long)
Change Vector* to Irq*.
rsc Fri Mar 4 12:44:25 2005
1994/0902    
			if(sc->freq == 0) 
				sc->freq = UartFREQ; 
			sc->first = nuart; 
1997/0327    
			intrenable(VectorPIC+sc->irq, mp008intr, sc, BUSUNKNOWN); 
1998/0918    
			intrenable(sc->irq, mp008intr, sc, BUSUNKNOWN); 
1994/0902    
			port = sc->port; 
			for(j=0; j < sc->size; j++){ 
1994/1118    
				sprint(name, "eia%d%2.2d", nscard, j); 
1998/0910/sys/src/9/pc/ns16552.h:146,1521998/0918/sys/src/9/pc/ns16552.h:146,152
1994/1106    
				sc->freq = UartFREQ; 
1994/1118    
			sprint(name, "eia%d00", nscard); 
1994/1108    
			ns16552setup(sc->port, sc->freq, name); 
1997/0327    
			intrenable(VectorPIC+sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN); 
1998/0918    
			intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN); 
1994/0902    
		} 
1994/1118    
		nscard++; 
1994/0902    
	} 
1998/0918/sys/src/9/pc/ns16552.h:14,201999/0513/sys/src/9/pc/ns16552.h:14,20 (short | long)
Change ns16552setup to add type.
rsc Fri Mar 4 12:44:25 2005
1994/0902    
#define uartwrreg(u,r,v)	outb((u)->port + r, (u)->sticky[r] | (v)) 
#define uartrdreg(u,r)		inb((u)->port + r) 
 
1994/1108    
void	ns16552setup(ulong, ulong, char*); 
1999/0513    
void	ns16552setup(ulong, ulong, char*, int); 
1997/0327    
void	ns16552special(int, int, Queue**, Queue**, int (*)(Queue*, int)); 
void	uartclock(void); 
1994/0902    
/* 
1998/0918/sys/src/9/pc/ns16552.h:93,1011999/0513/sys/src/9/pc/ns16552.h:93,101
1994/1007    
	already = 1; 
 
1994/0902    
	/* first two ports are always there and always the normal frequency */ 
1994/1108    
	ns16552setup(0x3F8, UartFREQ, "eia0"); 
1999/0513    
	ns16552setup(0x3F8, UartFREQ, "eia0", Ns550); 
1998/0910    
	intrenable(IrqUART0, ns16552intrx, (void*)0, BUSUNKNOWN); 
1994/1108    
	ns16552setup(0x2F8, UartFREQ, "eia1"); 
1999/0513    
	ns16552setup(0x2F8, UartFREQ, "eia1", Ns550); 
1998/0910    
	intrenable(IrqUART1, ns16552intrx, (void*)1, BUSUNKNOWN); 
1997/0327    
	addclock0link(uartclock); 
1994/1007    
 
1998/0918/sys/src/9/pc/ns16552.h:133,1411999/0513/sys/src/9/pc/ns16552.h:133,161
1994/0902    
			port = sc->port; 
			for(j=0; j < sc->size; j++){ 
1994/1118    
				sprint(name, "eia%d%2.2d", nscard, j); 
1994/1108    
				ns16552setup(port, sc->freq, name); 
1999/0513    
				ns16552setup(port, sc->freq, name, Ns550); 
1994/0902    
				port += 8; 
			} 
1999/0513    
		} else if(cistrcmp(sc->type, "turbo650") == 0){ 
			/* 
			 *  port gives base port address for the uart 
			 *  irq is interrupt 
			 *  freq is the baud rate generator frequency 
			 */ 
			if(sc->freq == 0) 
				sc->freq = UartFREQ*4; 
			sprint(name, "eia%d00", nscard); 
			ns16552setup(sc->port, sc->freq, name, Ns650); 
 
			/* 
			 *  multiply clock speed by 4 
			 */ 
			if(sc->mem == 0) 
				outb(0x2c8, 0); 
			else 
				outb(sc->mem, 0); 
 
			intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN); 
1998/0221    
		} else if(cistrcmp(sc->type, "com") == 0 && sc->port != 0x3F8 && sc->port != 0x2F8){ 
1994/0902    
			/* 
			 *  port gives base port address for the uart 
1998/0918/sys/src/9/pc/ns16552.h:145,1511999/0513/sys/src/9/pc/ns16552.h:165,171
1994/1106    
			if(sc->freq == 0) 
				sc->freq = UartFREQ; 
1994/1118    
			sprint(name, "eia%d00", nscard); 
1994/1108    
			ns16552setup(sc->port, sc->freq, name); 
1999/0513    
			ns16552setup(sc->port, sc->freq, name, Ns550); 
1998/0918    
			intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN); 
1994/0902    
		} 
1994/1118    
		nscard++; 
1999/0513/sys/src/9/pc/ns16552.h:93,1001999/0714/sys/src/9/pc/ns16552.h:93,104 (short | long)
Use ioalloc.
rsc Fri Mar 4 12:44:25 2005
1994/1007    
	already = 1; 
 
1994/0902    
	/* first two ports are always there and always the normal frequency */ 
1999/0714    
	if(ioalloc(0x3f8, 8, 0, "eia0") < 0) 
		print("eia0: port %d in use\n", 0x3f8); 
1999/0513    
	ns16552setup(0x3F8, UartFREQ, "eia0", Ns550); 
1998/0910    
	intrenable(IrqUART0, ns16552intrx, (void*)0, BUSUNKNOWN); 
1999/0714    
	if(ioalloc(0x2F8, 8, 0, "eia1") < 0) 
		print("eia1: port %d in use\n", 0x2F8); 
1999/0513    
	ns16552setup(0x2F8, UartFREQ, "eia1", Ns550); 
1998/0910    
	intrenable(IrqUART1, ns16552intrx, (void*)1, BUSUNKNOWN); 
1997/0327    
	addclock0link(uartclock); 
1999/0513/sys/src/9/pc/ns16552.h:129,1341999/0714/sys/src/9/pc/ns16552.h:133,144
1994/0902    
			if(sc->freq == 0) 
				sc->freq = UartFREQ; 
			sc->first = nuart; 
1999/0714    
			if(ioalloc(sc->port, 8*sc->size, 0, "mp008") < 0){ 
				print("mp008: port %lud in use\n", sc->port); 
				xfree(sc); 
				scard[nscard] = 0; 
				continue; 
			} 
1998/0918    
			intrenable(sc->irq, mp008intr, sc, BUSUNKNOWN); 
1994/0902    
			port = sc->port; 
			for(j=0; j < sc->size; j++){ 
1999/0513/sys/src/9/pc/ns16552.h:145,1501999/0714/sys/src/9/pc/ns16552.h:155,166
1999/0513    
			if(sc->freq == 0) 
				sc->freq = UartFREQ*4; 
			sprint(name, "eia%d00", nscard); 
1999/0714    
			if(ioalloc(sc->port, 8, 0, name) < 0){ 
				print("%s: port %lud in use\n", name, sc->port); 
				xfree(sc); 
				scard[nscard] = 0; 
				continue; 
			} 
1999/0513    
			ns16552setup(sc->port, sc->freq, name, Ns650); 
 
			/* 
1999/0513/sys/src/9/pc/ns16552.h:165,1701999/0714/sys/src/9/pc/ns16552.h:181,192
1994/1106    
			if(sc->freq == 0) 
				sc->freq = UartFREQ; 
1994/1118    
			sprint(name, "eia%d00", nscard); 
1999/0714    
			if(ioalloc(sc->port, 8, 0, name) < 0){ 
				print("%s: port %lud in use\n", name, sc->port); 
				xfree(sc); 
				scard[nscard] = 0; 
				continue; 
			} 
1999/0513    
			ns16552setup(sc->port, sc->freq, name, Ns550); 
1998/0918    
			intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN); 
1994/0902    
		} 
1999/0714/sys/src/9/pc/ns16552.h:96,1061999/0819/sys/src/9/pc/ns16552.h:96,106 (short | long)
Add name for intrenable.
rsc Fri Mar 4 12:44:25 2005
1999/0714    
	if(ioalloc(0x3f8, 8, 0, "eia0") < 0) 
		print("eia0: port %d in use\n", 0x3f8); 
1999/0513    
	ns16552setup(0x3F8, UartFREQ, "eia0", Ns550); 
1998/0910    
	intrenable(IrqUART0, ns16552intrx, (void*)0, BUSUNKNOWN); 
1999/0819    
	intrenable(IrqUART0, ns16552intrx, (void*)0, BUSUNKNOWN, "eia0"); 
1999/0714    
	if(ioalloc(0x2F8, 8, 0, "eia1") < 0) 
		print("eia1: port %d in use\n", 0x2F8); 
1999/0513    
	ns16552setup(0x2F8, UartFREQ, "eia1", Ns550); 
1998/0910    
	intrenable(IrqUART1, ns16552intrx, (void*)1, BUSUNKNOWN); 
1999/0819    
	intrenable(IrqUART1, ns16552intrx, (void*)1, BUSUNKNOWN, "eia1"); 
1997/0327    
	addclock0link(uartclock); 
1994/1007    
 
	/* set up a serial console */ 
1999/0714/sys/src/9/pc/ns16552.h:120,1251999/0819/sys/src/9/pc/ns16552.h:120,126
1994/1118    
			continue; 
1994/0902    
		} 
 
1999/0819    
		snprint(name, sizeof name, "eia%d00", nscard); 
1995/0222    
		if(cistrcmp(sc->type, "MP008") == 0){ 
1994/0902    
			/* 
			 *  port gives base port address for uarts 
1999/0714/sys/src/9/pc/ns16552.h:133,1451999/0819/sys/src/9/pc/ns16552.h:134,146
1994/0902    
			if(sc->freq == 0) 
				sc->freq = UartFREQ; 
			sc->first = nuart; 
1999/0714    
			if(ioalloc(sc->port, 8*sc->size, 0, "mp008") < 0){ 
1999/0819    
			if(ioalloc(sc->port, 8*sc->size, 0, name) < 0){ 
1999/0714    
				print("mp008: port %lud in use\n", sc->port); 
				xfree(sc); 
				scard[nscard] = 0; 
				continue; 
			} 
1998/0918    
			intrenable(sc->irq, mp008intr, sc, BUSUNKNOWN); 
1999/0819    
			intrenable(sc->irq, mp008intr, sc, BUSUNKNOWN, name); 
1994/0902    
			port = sc->port; 
			for(j=0; j < sc->size; j++){ 
1994/1118    
				sprint(name, "eia%d%2.2d", nscard, j); 
1999/0714/sys/src/9/pc/ns16552.h:154,1601999/0819/sys/src/9/pc/ns16552.h:155,160
1999/0513    
			 */ 
			if(sc->freq == 0) 
				sc->freq = UartFREQ*4; 
			sprint(name, "eia%d00", nscard); 
1999/0714    
			if(ioalloc(sc->port, 8, 0, name) < 0){ 
				print("%s: port %lud in use\n", name, sc->port); 
				xfree(sc); 
1999/0714/sys/src/9/pc/ns16552.h:171,1771999/0819/sys/src/9/pc/ns16552.h:171,177
1999/0513    
			else 
				outb(sc->mem, 0); 
 
			intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN); 
1999/0819    
			intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN, name); 
1998/0221    
		} else if(cistrcmp(sc->type, "com") == 0 && sc->port != 0x3F8 && sc->port != 0x2F8){ 
1994/0902    
			/* 
			 *  port gives base port address for the uart 
1999/0714/sys/src/9/pc/ns16552.h:180,1861999/0819/sys/src/9/pc/ns16552.h:180,185
1994/0902    
			 */ 
1994/1106    
			if(sc->freq == 0) 
				sc->freq = UartFREQ; 
1994/1118    
			sprint(name, "eia%d00", nscard); 
1999/0714    
			if(ioalloc(sc->port, 8, 0, name) < 0){ 
				print("%s: port %lud in use\n", name, sc->port); 
				xfree(sc); 
1999/0714/sys/src/9/pc/ns16552.h:188,1941999/0819/sys/src/9/pc/ns16552.h:187,193
1999/0714    
				continue; 
			} 
1999/0513    
			ns16552setup(sc->port, sc->freq, name, Ns550); 
1998/0918    
			intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN); 
1999/0819    
			intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN, name); 
1994/0902    
		} 
1994/1118    
		nscard++; 
1994/0902    
	} 
1999/0819/sys/src/9/pc/ns16552.h:77,822000/0613/sys/src/9/pc/ns16552.h:77,104 (short | long)
Add ns16552default to set up default serial ports and allow them to be disabled.
rsc Fri Mar 4 12:44:25 2005
1994/0902    
} 
 
/* 
2000/0613    
 * install a default serial port on a PC unless  
 * name=disabled is set in plan9.ini 
 */ 
void 
ns16552default(char *name, int port, int irq) 
{ 
	char *p; 
 
	if((p = getconf(name)) && strncmp(p, "disabled", 8) == 0) 
		return; 
 
	if(ioalloc(port, 8, 0, name) < 0) { 
		print("%s: port %x in use\n", name, port); 
		return; 
	} 
 
	ns16552setup(port, UartFREQ, name, Ns550); 
	intrenable(irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN, name); 
} 
 
 
/* 
1994/0902    
 *  install the uarts (called by reset) 
 */ 
1994/1007    
void 
1999/0819/sys/src/9/pc/ns16552.h:92,1062000/0613/sys/src/9/pc/ns16552.h:114,123
1994/1007    
		return; 
	already = 1; 
 
1994/0902    
	/* first two ports are always there and always the normal frequency */ 
1999/0714    
	if(ioalloc(0x3f8, 8, 0, "eia0") < 0) 
		print("eia0: port %d in use\n", 0x3f8); 
1999/0513    
	ns16552setup(0x3F8, UartFREQ, "eia0", Ns550); 
1999/0819    
	intrenable(IrqUART0, ns16552intrx, (void*)0, BUSUNKNOWN, "eia0"); 
1999/0714    
	if(ioalloc(0x2F8, 8, 0, "eia1") < 0) 
		print("eia1: port %d in use\n", 0x2F8); 
1999/0513    
	ns16552setup(0x2F8, UartFREQ, "eia1", Ns550); 
1999/0819    
	intrenable(IrqUART1, ns16552intrx, (void*)1, BUSUNKNOWN, "eia1"); 
2000/0613    
	/* first two ports are usually there and always the normal frequency */ 
	ns16552default("eia0", 0x3F8, IrqUART0); 
	ns16552default("eia1", 0x2F8, IrqUART1); 
 
1997/0327    
	addclock0link(uartclock); 
1994/1007    
 
	/* set up a serial console */ 
2000/0613/sys/src/9/pc/ns16552.h:104,1102000/1011/sys/src/9/pc/ns16552.h:104,110 (short | long)
Add baud plan9.ini option.
rsc Fri Mar 4 12:44:25 2005
1994/1007    
void 
1994/0902    
ns16552install(void) 
{ 
1994/1118    
	int i, j, port, nscard; 
2000/1011    
	int i, j, port, nscard, baud; 
1997/0327    
	char *p, *q; 
1994/0902    
	Scard *sc; 
1994/1108    
	char name[NAMELEN]; 
2000/0613/sys/src/9/pc/ns16552.h:123,1302000/1011/sys/src/9/pc/ns16552.h:123,136
1994/1007    
	/* set up a serial console */ 
1997/0327    
	if(p = getconf("console")){ 
		port = strtol(p, &q, 0); 
		if(p != q && (port == 0 || port == 1)) 
			ns16552special(port, 9600, &kbdq, &printq, kbdcr2nl); 
2000/1011    
		if(p != q && (port == 0 || port == 1)) { 
			baud = 0; 
			if(p = getconf("baud")) 
				baud = strtoul(p, 0, 0); 
			if(baud == 0) 
				baud = 9600; 
			ns16552special(port, baud, &kbdq, &printq, kbdcr2nl); 
		} 
1997/0327    
	} 
1994/0902    
 
	/* the rest come out of plan9.ini */ 
2000/1011/sys/src/9/pc/ns16552.h:1,2172001/0527/sys/src/9/pc/ns16552.h:0 (short | long)
Deleted.
rsc Mon Mar 7 10:29:52 2005
1994/0902    
/* 
 *  PC specific code for the ns16552.  It includes support for the 2 built 
 *  in uarts plus up to 5 MP-008 8 uart ISA cards. 
 */ 
enum 
{ 
	Maxcard= 5,		/* max serial cards */ 
	UartFREQ= 1843200, 
                 
	Serial=	0, 
	Modem=	1, 
}; 
                 
#define uartwrreg(u,r,v)	outb((u)->port + r, (u)->sticky[r] | (v)) 
#define uartrdreg(u,r)		inb((u)->port + r) 
                 
1999/0513    
void	ns16552setup(ulong, ulong, char*, int); 
1997/0327    
void	ns16552special(int, int, Queue**, Queue**, int (*)(Queue*, int)); 
void	uartclock(void); 
1994/0902    
/* 
 *  definition of an optional serial card 
 */ 
typedef struct Scard 
{ 
	ISAConf;	/* card configuration */ 
	int	first;	/* number of first port */ 
} Scard; 
static Scard *scard[Maxcard]; 	/* configs for the serial card */ 
                 
/* power management currently only makes sense on the AT&T safari */ 
static void 
uartpower(int dev, int onoff) 
{ 
	switch(dev){ 
	case Modem: 
1997/0327    
		if((*arch->modempower)(onoff) < 0) 
1994/0902    
			print("can't turn %s modem speaker\n", onoff?"on":"off"); 
		break; 
	case Serial: 
1997/0327    
		if((*arch->serialpower)(onoff) < 0) 
1994/0902    
			print("can't turn %s serial port power\n", onoff?"on":"off"); 
		break; 
	} 
} 
                 
/* 
 *  handle an interrupt to a single uart 
 */ 
static void 
1997/0327    
ns16552intrx(Ureg*, void* arg) 
1994/0902    
{ 
	ns16552intr((ulong)arg); 
} 
                 
/* 
 *  interrupts from the multiport card, MP-008.  A polling port 
 *  tells which of 8 devices interrupted. 
 */ 
static void 
1997/0327    
mp008intr(Ureg* ureg, void* arg) 
1994/0902    
{ 
	int i, loops; 
	uchar n; 
	Scard *mp; 
                 
	mp = arg; 
1994/1006    
	for(loops = 0; loops < 1024; loops++){ 
1994/0902    
		n = ~inb(mp->mem); 
		if(n == 0) 
			return; 
		for(i = 0; n; i++){ 
			if(n & 1) 
1997/0327    
				ns16552intrx(ureg, (void*)(mp->first+i)); 
1994/0902    
			n >>= 1; 
		} 
	} 
} 
                 
/* 
2000/0613    
 * install a default serial port on a PC unless  
 * name=disabled is set in plan9.ini 
 */ 
void 
ns16552default(char *name, int port, int irq) 
{ 
	char *p; 
                 
	if((p = getconf(name)) && strncmp(p, "disabled", 8) == 0) 
		return; 
                 
	if(ioalloc(port, 8, 0, name) < 0) { 
		print("%s: port %x in use\n", name, port); 
		return; 
	} 
                 
	ns16552setup(port, UartFREQ, name, Ns550); 
	intrenable(irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN, name); 
} 
                 
                 
/* 
1994/0902    
 *  install the uarts (called by reset) 
 */ 
1994/1007    
void 
1994/0902    
ns16552install(void) 
{ 
2000/1011    
	int i, j, port, nscard, baud; 
1997/0327    
	char *p, *q; 
1994/0902    
	Scard *sc; 
1994/1108    
	char name[NAMELEN]; 
1994/1007    
	static int already; 
1994/0902    
                 
1994/1007    
	if(already) 
		return; 
	already = 1; 
                 
2000/0613    
	/* first two ports are usually there and always the normal frequency */ 
	ns16552default("eia0", 0x3F8, IrqUART0); 
	ns16552default("eia1", 0x2F8, IrqUART1); 
                 
1997/0327    
	addclock0link(uartclock); 
1994/1007    
                 
	/* set up a serial console */ 
1997/0327    
	if(p = getconf("console")){ 
		port = strtol(p, &q, 0); 
2000/1011    
		if(p != q && (port == 0 || port == 1)) { 
			baud = 0; 
			if(p = getconf("baud")) 
				baud = strtoul(p, 0, 0); 
			if(baud == 0) 
				baud = 9600; 
			ns16552special(port, baud, &kbdq, &printq, kbdcr2nl); 
		} 
1997/0327    
	} 
1994/0902    
                 
	/* the rest come out of plan9.ini */ 
1994/1118    
	nscard = 0; 
1994/0902    
	for(i = 0; i < Maxcard; i++){ 
1994/1118    
		sc = scard[nscard] = xalloc(sizeof(Scard)); 
1994/0902    
		if(isaconfig("serial", i, sc) == 0){ 
			xfree(sc); 
1994/1118    
			scard[nscard] = 0; 
			continue; 
1994/0902    
		} 
                 
1999/0819    
		snprint(name, sizeof name, "eia%d00", nscard); 
1995/0222    
		if(cistrcmp(sc->type, "MP008") == 0){ 
1994/0902    
			/* 
			 *  port gives base port address for uarts 
			 *  irq is interrupt 
			 *  mem is the polling port 
			 *  size is the number of serial ports on the same polling port 
			 *  freq is the baud rate generator frequency 
			 */ 
			if(sc->size == 0) 
				sc->size = 8; 
			if(sc->freq == 0) 
				sc->freq = UartFREQ; 
			sc->first = nuart; 
1999/0819    
			if(ioalloc(sc->port, 8*sc->size, 0, name) < 0){ 
1999/0714    
				print("mp008: port %lud in use\n", sc->port); 
				xfree(sc); 
				scard[nscard] = 0; 
				continue; 
			} 
1999/0819    
			intrenable(sc->irq, mp008intr, sc, BUSUNKNOWN, name); 
1994/0902    
			port = sc->port; 
			for(j=0; j < sc->size; j++){ 
1994/1118    
				sprint(name, "eia%d%2.2d", nscard, j); 
1999/0513    
				ns16552setup(port, sc->freq, name, Ns550); 
1994/0902    
				port += 8; 
			} 
1999/0513    
		} else if(cistrcmp(sc->type, "turbo650") == 0){ 
			/* 
			 *  port gives base port address for the uart 
			 *  irq is interrupt 
			 *  freq is the baud rate generator frequency 
			 */ 
			if(sc->freq == 0) 
				sc->freq = UartFREQ*4; 
1999/0714    
			if(ioalloc(sc->port, 8, 0, name) < 0){ 
				print("%s: port %lud in use\n", name, sc->port); 
				xfree(sc); 
				scard[nscard] = 0; 
				continue; 
			} 
1999/0513    
			ns16552setup(sc->port, sc->freq, name, Ns650); 
                 
			/* 
			 *  multiply clock speed by 4 
			 */ 
			if(sc->mem == 0) 
				outb(0x2c8, 0); 
			else 
				outb(sc->mem, 0); 
                 
1999/0819    
			intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN, name); 
1998/0221    
		} else if(cistrcmp(sc->type, "com") == 0 && sc->port != 0x3F8 && sc->port != 0x2F8){ 
1994/0902    
			/* 
			 *  port gives base port address for the uart 
			 *  irq is interrupt 
			 *  freq is the baud rate generator frequency 
			 */ 
1994/1106    
			if(sc->freq == 0) 
				sc->freq = UartFREQ; 
1999/0714    
			if(ioalloc(sc->port, 8, 0, name) < 0){ 
				print("%s: port %lud in use\n", name, sc->port); 
				xfree(sc); 
				scard[nscard] = 0; 
				continue; 
			} 
1999/0513    
			ns16552setup(sc->port, sc->freq, name, Ns550); 
1999/0819    
			intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN, name); 
1994/0902    
		} 
1994/1118    
		nscard++; 
1994/0902    
	} 
} 


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