[comp.unix.xenix] Xenix/286 outb ???

phile@lgnp1.LS.COM (Phil Eschallier) (12/22/88)

hey out there ...

i am looking for info on outb (output to a port) for xenix/286.  i cannot
seems to find anything in the manuals.

the motivation for this is an article posted to comp.unix.microport 5 or
so weeks back that was a short program to turn on the FIFO queue for a
16550 chip.  i would like to do this under xenix.

any help, whether w/ an outb function or ioctl usage writing to /dev/mem,
would be greatly appreciated.  please respond via e-mail.

merry xmas ...

phil eschallier
phile@lgnp1

chip@vector.UUCP (Chip Rosenthal) (12/25/88)

In article <522@lgnp1.LS.COM> phile@lgnp1.LS.COM (Phil Eschallier) writes:
>i am looking for info on outb (output to a port) for xenix/286.  i cannot
>seems to find anything in the manuals.

This seems to come up from time to time...

You can't find an outb() for good reason.  The OUTB instruction is not
available in protected mode.  There is such a thing, obviously, for device
drivers, but not for user programs.

There is an undocumented hook, though.  Do a:

	mknod /dev/port c 4 3

For protection, I suggest you follow with:

	chmod 600 /dev/port
	chown sysinfo /dev/port
	chgrp sysinfo /dev/port

You will end up with:

	crw-------   1 sysinfo  sysinfo    4,  3 Dec 17 02:58 /dev/port

This gives you access to the I/O space, just as /dev/mem gives you access
to the physical memory.  The general idea is to lseek() the port address
and then read() or write() one byte.  I have attached an example below
which uses this device.  (I haven't tested the code, so no guarantees.)

With all that said and done ... this is all quite dangerous and in poor
taste.  I used this trick for some programs I wrote which talk to a board
through the PC's LPT port.  The final product was to run under MSDOS, but
I wanted to do the development under XENIX.  I need to write another one
of these programs, and I'm really considering writing a device driver
which treats the parallel port as a digital I/O device rather than a
printer port.

The example follows.  Use with care.  Remeber, if this example is broke
or you do something wrong, you can wreak havoc on your system.

------------------------------------------------------------------------------

#include <fcntl.h>
#define PORTDEV	"/dev/port"
static int	portfd = -1;
extern int	errno;
extern char	*sys_errlist[];
#define errmssg(PROC) \
	fprintf(stderr,"%s: %s error - %s\n", PORTDEV, PROC, sys_errlist[errno])

int outp(addr,data)
int addr;
int data;
{
    unsigned char cdata = (unsigned char) data;
    if ( portfd <= 0 && (portfd=open(PORTDEV,O_RDWR)) <= 0 )
	errmssg("open()");
    else if ( lseek(portfd,(long)addr,0) < 0 )
	errmssg("lseek()");
    else if ( write(portfd,&cdata,1) != 1 )
	errmssg("write()");
    else
	return 0;
    return -1;
}

int inp(addr)
int addr;
{
    unsigned char data;
    if ( portfd <= 0 && (portfd=open(PORTDEV,O_RDWR)) <= 0 )
	errmssg("open()");
    else if ( lseek(portfd,(long)addr,0) < 0 )
	errmssg("lseek()");
    else if ( read(portfd,&data,1) != 1 )
	errmssg("read()");
    else
	return data;
    return -1;
}

-- 
Chip Rosenthal     chip@vector.UUCP    |      Choke me in the shallow water
Dallas Semiconductor   214-450-5337    |         before I get too deep.