summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2008-04-20 01:46:36 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2008-04-20 01:46:36 +0000
commitd995e3267548d6edd8bfe991418f2cb13c7b7d1e (patch)
tree7397c2d544e031855b616e4d6481e02dbe3f8c85 /sys
parent6b14950b5e986719e0e2a2e5dbf52630d8d57623 (diff)
rewrite the serial port handling to manipulate the hardware directly
rather than relying on calls into the bios to work. this is a result of me getting pissed off with solaris and linux being able to cope the serial bios redirection on dracs, iloms, and ilos. trying to do the same thing with openbsds boot loader caused weird behaviour like machine hangs or no visible output. talking to the serial chips directly is more reliable. tested by many ok sthen@ deraadt@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/amd64/stand/libsa/bioscons.c60
-rw-r--r--sys/arch/i386/stand/libsa/bioscons.c62
2 files changed, 59 insertions, 63 deletions
diff --git a/sys/arch/amd64/stand/libsa/bioscons.c b/sys/arch/amd64/stand/libsa/bioscons.c
index b438a15a2af..d414a4f47ff 100644
--- a/sys/arch/amd64/stand/libsa/bioscons.c
+++ b/sys/arch/amd64/stand/libsa/bioscons.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bioscons.c,v 1.4 2008/01/23 16:37:56 jsing Exp $ */
+/* $OpenBSD: bioscons.c,v 1.5 2008/04/20 01:46:35 dlg Exp $ */
/*
* Copyright (c) 1997-1999 Michael Shalayeff
@@ -131,37 +131,40 @@ com_probe(struct consdev *cn)
}
}
+int com_speed = -1; /* default speed is 9600 baud */
+
void
com_init(struct consdev *cn)
{
- register int unit = minor(cn->cn_dev);
-
- /* let bios do necessary init first, 9600-N-1 */
- __asm __volatile(DOINT(0x14) : : "a" (0xe3), "d" (unit) :
- "%ecx", "cc" );
+ int port = comports[minor(cn->cn_dev)];
+
+ outb(port + com_ier, 0);
+ if (com_speed == -1)
+ comspeed(cn->cn_dev, 9600);
+ outb(port + com_mcr, MCR_DTR | MCR_RTS);
+ outb(port + com_fifo, FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST |
+ FIFO_TRIGGER_1);
+
+ /* drain the input buffer */
+ while (inb(port + com_lsr) & LSR_RXRDY)
+ (void)inb(port + com_data);
}
int
com_getc(dev_t dev)
{
- register int rv;
+ int port = comports[minor(dev & 0x7f)];
- if (dev & 0x80) {
- __asm __volatile(DOINT(0x14) : "=a" (rv) :
- "0" (0x300), "d" (minor(dev&0x7f)) : "%ecx", "cc" );
- return ((rv & 0x100) == 0x100);
- }
+ if (dev & 0x80)
+ return (inb(port + com_lsr) & LSR_RXRDY);
- do
- __asm __volatile(DOINT(0x14) : "=a" (rv) :
- "0" (0x200), "d" (minor(dev)) : "%ecx", "cc" );
- while (rv & 0x8000);
+ while ((inb(port + com_lsr) & LSR_RXRDY) == 0)
+ ;
- return (rv & 0xff);
+ return (inb(port + com_data) & 0xff);
}
/* call with sp == 0 to query the current speed */
-int com_speed = 9600; /* default speed is 9600 baud */
int
comspeed(dev_t dev, int sp)
{
@@ -195,7 +198,8 @@ comspeed(dev_t dev, int sp)
return -1;
#undef divrnd
- if (cn_tab && cn_tab->cn_dev == dev && com_speed != sp) {
+ if (com_speed != -1 && cn_tab && cn_tab->cn_dev == dev &&
+ com_speed != sp) {
printf("com%d: changing speed to %d baud in 5 seconds, "
"change your terminal to match!\n\a",
minor(dev), sp);
@@ -206,7 +210,8 @@ comspeed(dev_t dev, int sp)
outb(comports[minor(dev)] + com_dlbl, newsp);
outb(comports[minor(dev)] + com_dlbh, newsp>>8);
outb(comports[minor(dev)] + com_cfcr, LCR_8BITS);
- printf("\ncom%d: %d baud\n", minor(dev), sp);
+ if (com_speed != -1)
+ printf("\ncom%d: %d baud\n", minor(dev), sp);
newsp = com_speed;
com_speed = sp;
@@ -216,18 +221,11 @@ comspeed(dev_t dev, int sp)
void
com_putc(dev_t dev, int c)
{
- register int rv;
-
- dev = minor(dev) & 0x7f;
+ int port = comports[minor(dev)];
- /* check online (DSR) */
- __asm __volatile(DOINT(0x14) : "=a" (rv) :
- "0" (0x300), "d" (dev) : "%ecx", "cc" );
- if ( !(rv & 0x20) )
- return;
+ while ((inb(port + com_lsr) & LSR_TXRDY) == 0)
+ ;
- /* send character */
- __asm __volatile(DOINT(0x14) : "=a" (rv) :
- "0" (c | 0x100), "d" (dev) : "%ecx", "cc" );
+ outb(port + com_data, c);
}
diff --git a/sys/arch/i386/stand/libsa/bioscons.c b/sys/arch/i386/stand/libsa/bioscons.c
index 2203ae74912..b5d7702e35b 100644
--- a/sys/arch/i386/stand/libsa/bioscons.c
+++ b/sys/arch/i386/stand/libsa/bioscons.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bioscons.c,v 1.30 2008/01/23 16:37:56 jsing Exp $ */
+/* $OpenBSD: bioscons.c,v 1.31 2008/04/20 01:46:35 dlg Exp $ */
/*
* Copyright (c) 1997-1999 Michael Shalayeff
@@ -133,37 +133,40 @@ com_probe(struct consdev *cn)
}
}
+int com_speed = -1;
+
void
com_init(struct consdev *cn)
{
- register int unit = minor(cn->cn_dev);
-
- /* let bios do necessary init first, 9600-N-1 */
- __asm __volatile(DOINT(0x14) : : "a" (0xe3), "d" (unit) :
- "%ecx", "cc" );
+ int port = comports[minor(cn->cn_dev)];
+
+ outb(port + com_ier, 0);
+ if (com_speed == -1)
+ comspeed(cn->cn_dev, 9600); /* default speed is 9600 baud */
+ outb(port + com_mcr, MCR_DTR | MCR_RTS);
+ outb(port + com_fifo, FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST |
+ FIFO_TRIGGER_1);
+
+ /* drain the input buffer */
+ while (inb(port + com_lsr) & LSR_RXRDY)
+ (void)inb(port + com_data);
}
int
com_getc(dev_t dev)
{
- register int rv;
+ int port = comports[minor(dev & 0x7f)];
- if (dev & 0x80) {
- __asm __volatile(DOINT(0x14) : "=a" (rv) :
- "0" (0x300), "d" (minor(dev&0x7f)) : "%ecx", "cc" );
- return ((rv & 0x100) == 0x100);
- }
+ if (dev & 0x80)
+ return (inb(port + com_lsr) & LSR_RXRDY);
- do
- __asm __volatile(DOINT(0x14) : "=a" (rv) :
- "0" (0x200), "d" (minor(dev)) : "%ecx", "cc" );
- while (rv & 0x8000);
+ while ((inb(port + com_lsr) & LSR_RXRDY) == 0)
+ ;
- return (rv & 0xff);
+ return (inb(port + com_data) & 0xff);
}
/* call with sp == 0 to query the current speed */
-int com_speed = 9600; /* default speed is 9600 baud */
int
comspeed(dev_t dev, int sp)
{
@@ -197,7 +200,8 @@ comspeed(dev_t dev, int sp)
return -1;
#undef divrnd
- if (cn_tab && cn_tab->cn_dev == dev && com_speed != sp) {
+ if (com_speed != -1 && cn_tab && cn_tab->cn_dev == dev &&
+ com_speed != sp) {
printf("com%d: changing speed to %d baud in 5 seconds, "
"change your terminal to match!\n\a",
minor(dev), sp);
@@ -208,7 +212,8 @@ comspeed(dev_t dev, int sp)
outb(comports[minor(dev)] + com_dlbl, newsp);
outb(comports[minor(dev)] + com_dlbh, newsp>>8);
outb(comports[minor(dev)] + com_cfcr, LCR_8BITS);
- printf("\ncom%d: %d baud\n", minor(dev), sp);
+ if (com_speed != -1)
+ printf("\ncom%d: %d baud\n", minor(dev), sp);
newsp = com_speed;
com_speed = sp;
@@ -218,17 +223,10 @@ comspeed(dev_t dev, int sp)
void
com_putc(dev_t dev, int c)
{
- register int rv;
-
- dev = minor(dev) & 0x7f;
-
- /* check online (DSR) */
- __asm __volatile(DOINT(0x14) : "=a" (rv) :
- "0" (0x300), "d" (dev) : "%ecx", "cc" );
- if ( (rv & 0x20) == 0)
- return;
+ int port = comports[minor(dev)];
- /* send character */
- __asm __volatile(DOINT(0x14) : "=a" (rv) :
- "0" (c | 0x100), "d" (dev) : "%ecx", "cc" );
+ while ((inb(port + com_lsr) & LSR_TXRDY) == 0)
+ ;
+
+ outb(port + com_data, c);
}