From 2ad179bbd009efb3d891be7d00f1e4104840c659 Mon Sep 17 00:00:00 2001
From: Maksim Kuleshov mmcx@mail.ru Date: Sat, 30 Mar 2013 21:32:48 +0400 Subject: [PATCH 3/7] add lpt_io_ppdev to lpt_io module
Signed-off-by: Maksim Kuleshov mmcx@mail.ru --- lpt_io.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lpt_io.h | 1 + 2 files changed, 131 insertions(+)
diff --git a/lpt_io.c b/lpt_io.c index e388cd5..b4fe2ab 100644 --- a/lpt_io.c +++ b/lpt_io.c @@ -102,10 +102,140 @@ static int lpt_io_direct_init(lpt_io_context_t * p_context, void *data) } #endif
+#ifdef HAVE_PPDEV_IO +#include <fcntl.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <string.h> +#include <linux/ppdev.h> +#include <linux/parport.h> + +static struct lpt_io_private_ppdev { + int fd; +} lpt_io_private_ppdev; + +static int lpt_io_ppdev_shutdown(void *data) +{ + struct lpt_io_driver *driver = data; + struct lpt_io_private_ppdev *private = driver->private; + + if (private->fd >= 0) { + ioctl(private->fd, PPRELEASE); + close(private->fd); + private->fd = -1; + } + + return 0; +} + +static void lpt_io_ppdev_out_data(lpt_io_context_t context, uint8_t data) +{ + struct lpt_io_driver *driver = context; + struct lpt_io_private_ppdev *private = driver->private; + + if (private->fd >= 0) { + ioctl(private->fd, PPWDATA, &data); + } +} + +static void lpt_io_ppdev_out_control(lpt_io_context_t context, uint8_t data) +{ + struct lpt_io_driver *driver = context; + struct lpt_io_private_ppdev *private = driver->private; + + if (private->fd >= 0) { + ioctl(private->fd, PPWCONTROL, &data); + } +} + +static uint8_t lpt_io_ppdev_in_data(lpt_io_context_t context) +{ + struct lpt_io_driver *driver = context; + struct lpt_io_private_ppdev *private = driver->private; + uint8_t data = 0; + + if (private->fd >= 0) { + ioctl(private->fd, PPRDATA, &data); + } + + return data; +} + +static uint8_t lpt_io_ppdev_in_status(lpt_io_context_t context) +{ + struct lpt_io_driver *driver = context; + struct lpt_io_private_ppdev *private = driver->private; + uint8_t data = 0; + + if (private->fd >= 0) { + ioctl(private->fd, PPRSTATUS, &data); + } + + return data; +} + +static uint8_t lpt_io_ppdev_in_control(lpt_io_context_t context) +{ + struct lpt_io_driver *driver = context; + struct lpt_io_private_ppdev *private = driver->private; + uint8_t data = 0; + + if (private->fd >= 0) { + ioctl(private->fd, PPRCONTROL, &data); + } + + return data; +} + +static int lpt_io_ppdev_init(lpt_io_context_t * p_context, void *data); + +static struct lpt_io_driver lpt_io_driver_ppdev = { + .method = "ppdev", + .init = lpt_io_ppdev_init, + .out_data = lpt_io_ppdev_out_data, + .out_control = lpt_io_ppdev_out_control, + .in_data = lpt_io_ppdev_in_data, + .in_status = lpt_io_ppdev_in_status, + .in_control = lpt_io_ppdev_in_control, + .shutdown = lpt_io_ppdev_shutdown, +}; + +static int lpt_io_ppdev_init(lpt_io_context_t * p_context, void *data) +{ + struct lpt_io_driver *driver = &lpt_io_driver_ppdev; + struct lpt_io_private_ppdev *private = &lpt_io_private_ppdev; + driver->private = (void *)private; + char *ppdev_name = (char *)data; + private->fd = open(ppdev_name, O_RDWR | O_NONBLOCK); + + if (private->fd < 0) { + msg_perr("Error: ppdev=%s not opened (%s)\n", ppdev_name, + strerror(errno)); + return 1; + } + + if (ioctl(private->fd, PPCLAIM) < 0) { + msg_perr("Error: ppdev not claimed (%s)\n", strerror(errno)); + return 1; + } + + if (driver->shutdown) { + register_shutdown(driver->shutdown, driver); + } + + *p_context = (lpt_io_context_t) driver; + return 0; +} +#endif + static struct lpt_io_driver *lpt_io_drivers[] = { #ifdef HAVE_DIRECT_IO &lpt_io_driver_direct, #endif +#ifdef HAVE_PPDEV_IO + &lpt_io_driver_ppdev, +#endif NULL };
diff --git a/lpt_io.h b/lpt_io.h index 5777654..2eb9963 100644 --- a/lpt_io.h +++ b/lpt_io.h @@ -1,3 +1,4 @@ +#define HAVE_PPDEV_IO //FIXME must be defined in Makefile #define HAVE_DIRECT_IO //FIXME must be defined in Makefile #ifndef lpt_io_h_included_ #define lpt_io_h_included_