summaryrefslogtreecommitdiffstats
path: root/sys/dev/ppbus/ppi.c
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>1998-01-02 09:30:39 +0000
committermsmith <msmith@FreeBSD.org>1998-01-02 09:30:39 +0000
commit8acca4f67741a3c3184d51b61c006cbc02068393 (patch)
treefec1364af06ac8a29802303b9076018889d95b92 /sys/dev/ppbus/ppi.c
parent721b8ddd8c999db0c27807161d66c3859bff41d7 (diff)
downloadFreeBSD-src-8acca4f67741a3c3184d51b61c006cbc02068393.zip
FreeBSD-src-8acca4f67741a3c3184d51b61c006cbc02068393.tar.gz
Actually implement the internals of the 'ppi' device.
It is now possible to control the various parallel port signals from user-space programs without having to resort to opening /dev/io directly.
Diffstat (limited to 'sys/dev/ppbus/ppi.c')
-rw-r--r--sys/dev/ppbus/ppi.c89
1 files changed, 77 insertions, 12 deletions
diff --git a/sys/dev/ppbus/ppi.c b/sys/dev/ppbus/ppi.c
index 7e34cb9..bbc2bdc 100644
--- a/sys/dev/ppbus/ppi.c
+++ b/sys/dev/ppbus/ppi.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1997 Nicolas Souchu
+ * Copyright (c) 1997, 1998 Nicolas Souchu, Michael Smith
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: ppi.c,v 1.4 1997/08/28 10:15:16 msmith Exp $
+ * $Id: ppi.c,v 1.5 1997/09/01 00:51:49 bde Exp $
*
*/
#include "ppi.h"
@@ -35,19 +35,24 @@
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <sys/fcntl.h>
#include <dev/ppbus/ppbconf.h>
+#include <dev/ppbus/ppi.h>
+
struct ppi_data {
- int ppi_unit;
+ int ppi_unit;
+ int ppi_flags;
+#define HAVE_PPBUS (1<<0)
- struct ppb_device ppi_dev;
+ struct ppb_device ppi_dev;
};
-#define MAXPPI 8 /* XXX not much better! */
-static int nppi = 0;
-static struct ppi_data *ppidata[MAXPPI];
+#define MAXPPI 8 /* XXX not much better! */
+static int nppi = 0;
+static struct ppi_data *ppidata[MAXPPI];
/*
* Make ourselves visible as a ppbus driver
@@ -62,7 +67,6 @@ static struct ppb_driver ppidriver = {
};
DATA_SET(ppbdriver_set, ppidriver);
-
static d_open_t ppiopen;
static d_close_t ppiclose;
static d_ioctl_t ppiioctl;
@@ -133,25 +137,86 @@ static int
ppiopen(dev_t dev, int flags, int fmt, struct proc *p)
{
u_int unit = minor(dev);
+ struct ppi_data *ppi = ppidata[unit];
+ int res;
if (unit >= nppi)
return (ENXIO);
- printf("ppi open!\n");
+ if (!(ppi->ppi_flags & HAVE_PPBUS))
+ if ((res = ppb_request_bus(&ppi->ppi_dev, (flags & O_NONBLOCK) ? PPB_DONTWAIT : (PPB_WAIT | PPB_INTR))))
+ return (res);
- return (EOPNOTSUPP);
+ ppi->ppi_flags |= HAVE_PPBUS;
+ return (0);
}
static int
ppiclose(dev_t dev, int flags, int fmt, struct proc *p)
{
- return (EOPNOTSUPP);
+ u_int unit = minor(dev);
+ struct ppi_data *ppi = ppidata[unit];
+
+ if (ppi->ppi_flags & HAVE_PPBUS)
+ ppb_release_bus(&ppi->ppi_dev);
+ ppi->ppi_flags &= ~HAVE_PPBUS;
+ return (0);
}
static int
ppiioctl(dev_t dev, int cmd, caddr_t data, int flags, struct proc *p)
{
- return (EOPNOTSUPP);
+ u_int unit = minor(dev);
+ struct ppi_data *ppi = ppidata[unit];
+ int error = 0;
+ u_int8_t *val = (u_int8_t *)data;
+
+ switch (cmd) {
+
+ case PPIGDATA: /* get data register */
+ *val = ppb_rdtr(&ppi->ppi_dev);
+ break;
+ case PPIGSTATUS: /* get status bits */
+ *val = ppb_rstr(&ppi->ppi_dev);
+ break;
+ case PPIGCTRL: /* get control bits */
+ *val = ppb_rctr(&ppi->ppi_dev);
+ break;
+ case PPIGEPP: /* get EPP bits */
+ *val = ppb_repp(&ppi->ppi_dev);
+ break;
+ case PPIGECR: /* get ECP bits */
+ *val = ppb_recr(&ppi->ppi_dev);
+ break;
+ case PPIGFIFO: /* read FIFO */
+ *val = ppb_rfifo(&ppi->ppi_dev);
+ break;
+
+ case PPISDATA: /* set data register */
+ ppb_wdtr(&ppi->ppi_dev, *val);
+ break;
+ case PPISSTATUS: /* set status bits */
+ ppb_wstr(&ppi->ppi_dev, *val);
+ break;
+ case PPISCTRL: /* set control bits */
+ ppb_wctr(&ppi->ppi_dev, *val);
+ break;
+ case PPISEPP: /* set EPP bits */
+ ppb_wepp(&ppi->ppi_dev, *val);
+ break;
+ case PPISECR: /* set ECP bits */
+ ppb_wecr(&ppi->ppi_dev, *val);
+ break;
+ case PPISFIFO: /* write FIFO */
+ ppb_wfifo(&ppi->ppi_dev, *val);
+ break;
+
+ default:
+ error = ENOTTY;
+ break;
+ }
+
+ return (error);
}
#ifdef PPI_MODULE
OpenPOWER on IntegriCloud