/* $id$ * Low level I/O functions taken from led-stat.txt * Jan 22 95 copyright damianf@wpi.edu * * DOS part (tested only with DOS version of GCC, DJGPP) * by M.Prinke 3/97 * * FreeBSD support by Guillaume Filion and Philip Pokorny, copyright 05/2001 * * NetBSD port by Guillaume Filion, copyright 12/2001 */ /* This file defines 4 static inline functions for port I/O: // Read a byte from port static inline int port_in (unsigned short int port); // Returns the content of the byte. // Write a char(byte) 'val' to port. static inline void port_out (unsigned short int port, unsigned char val); // Returns nothing. // Get access to a specific port static inline int port_access (unsigned short int port); // Returns 0 if successful, -1 if failed // Get access 3 to ports: port (CONTROL), port+1 (STATUS) and port+2 (DATA) static inline int port_access_full (unsigned short int port); // Returns 0 if successful, -1 if failed */ #ifndef PORT_H #define PORT_H #ifdef HAVE_CONFIG_H # include #endif #include // ------------------------------------------------------------- // Use ioperm, inb and outb in (Linux) #if defined HAVE_IOPERM && HAVE_SYS_IO_H #include // Read a byte from port static inline int port_in (unsigned short int port) { return inb(port); } // Write a byte 'val' to port static inline void port_out (unsigned short int port, unsigned char val) { outb(val, port); } // Get access to a specific port static inline int port_access (unsigned short int port) { return ioperm(port, 1, 255); } // Get access to 3 ports: port (CONTROL), port+1 (STATUS) and port+2 (DATA) static inline int port_access_full (unsigned short int port) { return ioperm(port, 3, 255); } // ------------------------------------------------------------- // Use i386_get_ioperm, i386_set_ioperm, inb and outb from (NetBSD) #elif defined HAVE_LIBI386 && defined HAVE_MACHINE_PIO_H && defined HAVE_MACHINE_SYSARCH_H #include #include #include // Read a byte from port static inline int port_in (unsigned short int port) { return inb(port); } // Write a byte 'val' to port static inline void port_out (unsigned short int port, unsigned char val) { outb(port, val); } static inline void setaccess(u_long * map, u_int bit, int allow) { u_int word; u_int shift; u_long mask; word = bit / 32; shift = bit - (word * 32); mask = 0x000000001 << shift; if (allow) map[word] &= ~mask; else map[word] |= mask; } // Get access to a specific port static inline int port_access (unsigned short int port) { u_long iomap[32]; if (i386_get_ioperm(iomap) == -1) return -1; setaccess(iomap, port , 1); if (i386_set_ioperm(iomap) == -1) return -1; return 0; } // Get access to 3 ports: port (CONTROL), port+1 (STATUS) and port+2 (DATA) static inline int port_access_full (unsigned short int port) { u_long iomap[32]; if (i386_get_ioperm(iomap) == -1) return -1; setaccess(iomap, port , 1); setaccess(iomap, port+1, 1); setaccess(iomap, port+2, 1); if (i386_set_ioperm(iomap) == -1) return -1; return 0; } //#endif // defined HAVE_LIBI386 && defined HAVE_SYS_TYPES_H && defined HAVE_MACHINE_PIO_H // ------------------------------------------------------------- // Last chance! Use /dev/io and i386 ASM code (BSD4.3 ?) #else // Read a byte from port static inline int port_in (unsigned short int port) { unsigned char value; __asm__ volatile ("inb %1,%0":"=a" (value) :"d" ((unsigned short) port)); return value; } // Write a byte 'val' to port static inline void port_out (unsigned short int port, unsigned char val) { __asm__ volatile ("outb %0,%1\n"::"a" (val), "d" (port) ); } // Get access to 3 ports: port (CONTROL), port+1 (STATUS) and port+2 (DATA) static inline int port_access_full (unsigned short int port) { static FILE * port_access_handle = NULL ; if( port_access_handle || (port_access_handle = fopen("/dev/io", "rw")) != NULL ) { return( 0 ); // Success } else { return( -1 ); // Failure }; return -1; } // Get access to a specific port static inline int port_access (unsigned short int port) { return port_access_full(port); // /dev/io gives you access to all ports. } #endif /* #else #include static inline int port_in (int port) { unsigned char value; value = inportb ((unsigned short) port); return (int) value; } static inline void port_out (unsigned int port, unsigned char val) { outportb ((unsigned short) port, val); } #endif */ #endif // PORT_H