summaryrefslogtreecommitdiff
path: root/glcddrivers/port.c
diff options
context:
space:
mode:
Diffstat (limited to 'glcddrivers/port.c')
-rw-r--r--glcddrivers/port.c53
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)