diff options
Diffstat (limited to 'glcddrivers/port.c')
-rw-r--r-- | glcddrivers/port.c | 53 |
1 files changed, 44 insertions, 9 deletions
diff --git a/glcddrivers/port.c b/glcddrivers/port.c index d6e8e34..cfb4156 100644 --- a/glcddrivers/port.c +++ b/glcddrivers/port.c @@ -6,7 +6,8 @@ * This file is released under the GNU General Public License. Refer * to the COPYING file distributed with this package. * - * (c) 2004 Andreas Regel <andreas.regel AT powarman.de> + * (c) 2004 Andreas Regel <andreas.regel AT powarman.de> + * (c) 2011-2012 Wolfgang Astleitner <mrwastl AT users.sourceforge.net> */ #include <errno.h> @@ -16,6 +17,7 @@ #include <syslog.h> #include <unistd.h> #include <termios.h> +#include <pthread.h> #include <sys/io.h> #include <sys/ioctl.h> #include <linux/ppdev.h> @@ -25,29 +27,42 @@ #include "port.h" +#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__)) + #define __HAS_DIRECTIO__ 1 +#endif + namespace GLCD { +static pthread_mutex_t claimport_mutex; + static inline int port_in(int port) { +#ifdef __HAS_DIRECTIO__ unsigned char value; __asm__ volatile ("inb %1,%0" : "=a" (value) : "d" ((unsigned short) port)); return value; +#else + return 0; +#endif } static inline void port_out(unsigned short int port, unsigned char val) { +#ifdef __HAS_DIRECTIO__ __asm__ volatile ("outb %0,%1\n" : : "a" (val), "d" (port)); +#endif } cParallelPort::cParallelPort() : fd(-1), port(0), - usePPDev(false) + usePPDev(false), + portClaimed(false) { } @@ -57,6 +72,7 @@ cParallelPort::~cParallelPort() int cParallelPort::Open(int portIO) { +#ifdef __HAS_DIRECTIO__ usePPDev = false; port = portIO; @@ -79,6 +95,10 @@ int cParallelPort::Open(int portIO) } } return 0; +#else + syslog(LOG_ERR, "glcd drivers: ERROR: direct IO/parport is not available on this architecture / operating system\n"); + return -1; +#endif } int cParallelPort::Open(const char * device) @@ -93,7 +113,7 @@ int cParallelPort::Open(const char * device) return -1; } - if (ioctl(fd, PPCLAIM, NULL) == -1) + if (!Claim()) { syslog(LOG_ERR, "glcd drivers: ERROR cannot claim %s. Err:%s (cParallelPort::Init)\n", device, strerror(errno)); @@ -102,7 +122,7 @@ int cParallelPort::Open(const char * device) } int mode = PARPORT_MODE_PCSPP; - if (ioctl(fd, PPSETMODE, &mode) == -1) + if (ioctl(fd, PPSETMODE, &mode) != 0) { syslog(LOG_ERR, "glcd drivers: ERROR cannot setmode %s. Err:%s (cParallelPort::Init)\n", device, strerror(errno)); @@ -130,6 +150,7 @@ int cParallelPort::Close() } else { +#ifdef __HAS_DIRECTIO__ if (port < 0x400) { if (ioperm(port, 3, 0) == -1) @@ -144,20 +165,34 @@ int cParallelPort::Close() return -1; } } +#else + return -1; // should never make it until here ... +#endif } return 0; } -void cParallelPort::Claim() +bool cParallelPort::Claim() { - if (usePPDev) - ioctl(fd, PPCLAIM); + if (!IsPortClaimed()) + { + if (usePPDev) + portClaimed = (ioctl(fd, PPCLAIM) == 0); + else + portClaimed = (pthread_mutex_lock(&claimport_mutex) == 0); + } + return IsPortClaimed(); } void cParallelPort::Release() { - if (usePPDev) - ioctl(fd, PPRELEASE); + if (IsPortClaimed()) + { + if (usePPDev) + portClaimed = !(ioctl(fd, PPRELEASE) == 0); + else + portClaimed = !(pthread_mutex_unlock(&claimport_mutex) == 0); + } } void cParallelPort::SetDirection(int direction) |