/* outport.c -- An example of low-level io from userspace */
/* If you are a Certified SSP (TM), you can use this
   program to test your Seating License Manager (TM) prior to connecting
   to our Patent Pending SeatServ (TM) system */

/*
  USAGE:
  ./outport37A 32 (that's 0x20) will set D0-D7 to bidirectional (e.g. for input)
  ./outport37A 0 will set D0-D7 to output
  ./outport37A 16 (that's 0x10) will set pin10 (ack) to be IRQ

  ./outport37A 48 (that's 0x30) will set D0-D7 to inputs and as well as IRQ
*/

/* must gcc -O2 to expand the macros, otherwise won't work if just gcc */

#include <stdio.h>

#include <asm/types.h>   /* headers for architecture specific data types                         */
#include <unistd.h>      /* contains the prototype for i386 specific ioperm functioni            */
#include <asm/io.h>      /* obviously architecture specific (asm directory) for inb, outb macros */

#define LP_ADDR 0x37A

int main(int argc, char **argv) {

	__u8 portdata;

	if(argc < 2) {
		fprintf(stderr, "Must supply a value to send to port...\n");
		exit(1);
	}

	portdata = (__u8) atoi(argv[1]);


	/* let us know the value of portdata */
	printf("Value submitted for sending to hardware: %i\n", portdata);

	/* attempt to reserve region in io space */
	if(ioperm(LP_ADDR, 3, 1) < 0) {
		fprintf(stderr, "Cannot reserve region in io space, aborting...\n");
		exit(1);
	}

	/* send data byte to io port */
	outb(portdata, LP_ADDR);

	/* attempt to release reserved region in io space */
	if(ioperm(LP_ADDR, 3, 0) < 0) {
		fprintf(stderr, "Cannot release region in io space, aborting...\n");
		exit(1);
	}

	return(0);  /* just to be nice ;) */

}


