summaryrefslogtreecommitdiffstats
path: root/sys/dev/ppc
diff options
context:
space:
mode:
authornsouch <nsouch@FreeBSD.org>1999-01-10 12:04:56 +0000
committernsouch <nsouch@FreeBSD.org>1999-01-10 12:04:56 +0000
commit88ae26fef69887203a871fca927f456a66c2cad4 (patch)
tree9e8c963e572bd5f141fcfc50127d8185cf16e87c /sys/dev/ppc
parent44bde66cb074ad8bc5cdb36460c6ef9f4628ea69 (diff)
downloadFreeBSD-src-88ae26fef69887203a871fca927f456a66c2cad4.zip
FreeBSD-src-88ae26fef69887203a871fca927f456a66c2cad4.tar.gz
Major ppbus commit with:
+ ECP parallel port chipset FIFO detection + DMA+FIFO parallel I/O handled as chipset specific + nlpt updated in order to use the above enhanced parallel I/O. Use 'lptcontrol -e' to use enhanced I/O + Various options documented in LINT + Full IEEE1284 NIBBLE and BYTE modes support. See ppbus(4) for an overview of the IEEE1284 standard + Detection of PnP parallel devices at boot + Read capability added to nlpt driver to get IEEE1284 compliant printer status with a simple 'cat /dev/lpt0' + IEEE1284 peripheral emulation added to BYTE mode. Two computers may dialog according to IEEE1284 signaling method. See PERIPH_1284 option and /sys/dev/ppbus/ppi.c All this code is supposed to provide basic functions for IEEE1284 programming. ppi.c and nlpt.c may act as examples.
Diffstat (limited to 'sys/dev/ppc')
-rw-r--r--sys/dev/ppc/ppc.c483
-rw-r--r--sys/dev/ppc/ppcreg.h55
2 files changed, 486 insertions, 52 deletions
diff --git a/sys/dev/ppc/ppc.c b/sys/dev/ppc/ppc.c
index e351688..d2bc7a1 100644
--- a/sys/dev/ppc/ppc.c
+++ b/sys/dev/ppc/ppc.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: ppc.c,v 1.12 1998/12/07 21:58:22 archie Exp $
+ * $Id: ppc.c,v 1.13 1998/12/30 00:37:42 hoek Exp $
*
*/
#include "ppc.h"
@@ -49,6 +49,11 @@
#include <i386/isa/ppcreg.h>
+#include "opt_ppc.h"
+
+#define LOG_PPC(function, ppc, string) \
+ if (bootverbose) printf("%s: %s\n", function, string)
+
static int ppcprobe(struct isa_device *);
static int ppcattach(struct isa_device *);
@@ -130,6 +135,9 @@ static int ppc_exec_microseq(int, struct ppb_microseq **);
static int ppc_generic_setmode(int, int);
static int ppc_smclike_setmode(int, int);
+static int ppc_read(int, char *, int, int);
+static int ppc_write(int, char *, int, int);
+
static struct ppb_adapter ppc_smclike_adapter = {
0, /* no intr handler, filled by chipset dependent code */
@@ -138,7 +146,7 @@ static struct ppb_adapter ppc_smclike_adapter = {
ppc_exec_microseq,
- ppc_smclike_setmode,
+ ppc_smclike_setmode, ppc_read, ppc_write,
ppc_outsb_epp, ppc_outsw_epp, ppc_outsl_epp,
ppc_insb_epp, ppc_insw_epp, ppc_insl_epp,
@@ -155,7 +163,7 @@ static struct ppb_adapter ppc_generic_adapter = {
ppc_exec_microseq,
- ppc_generic_setmode,
+ ppc_generic_setmode, ppc_read, ppc_write,
ppc_outsb_epp, ppc_outsw_epp, ppc_outsl_epp,
ppc_insb_epp, ppc_insw_epp, ppc_insl_epp,
@@ -173,8 +181,11 @@ ppc_ecp_sync(int unit) {
struct ppc_data *ppc = ppcdata[unit];
int i, r;
+ if (!(ppc->ppc_avm & PPB_ECP))
+ return;
+
r = r_ecr(ppc);
- if ((r & 0xe0) != 0x80)
+ if ((r & 0xe0) != PPC_ECR_EPP)
return;
for (i = 0; i < 100; i++) {
@@ -190,13 +201,115 @@ ppc_ecp_sync(int unit) {
return;
}
-static void
-ppcintr(int unit)
+/*
+ * ppc_detect_fifo()
+ *
+ * Detect parallel port FIFO
+ */
+static int
+ppc_detect_fifo(struct ppc_data *ppc)
{
- /* call directly upper code */
- ppb_intr(&ppcdata[unit]->ppc_link);
+ char ecr_sav;
+ char ctr_sav, ctr, cc;
+ short i;
+
+ /* save registers */
+ ecr_sav = r_ecr(ppc);
+ ctr_sav = r_ctr(ppc);
- return;
+ /* enter ECP configuration mode, no interrupt, no DMA */
+ w_ecr(ppc, 0xf4);
+
+ /* read PWord size - transfers in FIFO mode must be PWord aligned */
+ ppc->ppc_pword = (r_cnfgA(ppc) & PPC_PWORD_MASK);
+
+ /* XXX 16 and 32 bits implementations not supported */
+ if (ppc->ppc_pword != PPC_PWORD_8) {
+ LOG_PPC(__FUNCTION__, ppc, "PWord not supported");
+ goto error;
+ }
+
+ w_ecr(ppc, 0x34); /* byte mode, no interrupt, no DMA */
+ ctr = r_ctr(ppc);
+ w_ctr(ppc, ctr | PCD); /* set direction to 1 */
+
+ /* enter ECP test mode, no interrupt, no DMA */
+ w_ecr(ppc, 0xd4);
+
+ /* flush the FIFO */
+ for (i=0; i<1024; i++) {
+ if (r_ecr(ppc) & PPC_FIFO_EMPTY)
+ break;
+ cc = r_fifo(ppc);
+ }
+
+ if (i >= 1024) {
+ LOG_PPC(__FUNCTION__, ppc, "can't flush FIFO");
+ goto error;
+ }
+
+ /* enable interrupts, no DMA */
+ w_ecr(ppc, 0xd0);
+
+ /* determine readIntrThreshold
+ * fill the FIFO until serviceIntr is set
+ */
+ for (i=0; i<1024; i++) {
+ w_fifo(ppc, (char)i);
+ if (!ppc->ppc_rthr && (r_ecr(ppc) & PPC_SERVICE_INTR)) {
+ /* readThreshold reached */
+ ppc->ppc_rthr = i+1;
+ }
+ if (r_ecr(ppc) & PPC_FIFO_FULL) {
+ ppc->ppc_fifo = i+1;
+ break;
+ }
+ }
+
+ if (i >= 1024) {
+ LOG_PPC(__FUNCTION__, ppc, "can't fill FIFO");
+ goto error;
+ }
+
+ w_ecr(ppc, 0xd4); /* test mode, no interrupt, no DMA */
+ w_ctr(ppc, ctr & ~PCD); /* set direction to 0 */
+ w_ecr(ppc, 0xd0); /* enable interrupts */
+
+ /* determine writeIntrThreshold
+ * empty the FIFO until serviceIntr is set
+ */
+ for (i=ppc->ppc_fifo; i>0; i--) {
+ if (r_fifo(ppc) != (char)(ppc->ppc_fifo-i)) {
+ LOG_PPC(__FUNCTION__, ppc, "invalid data in FIFO");
+ goto error;
+ }
+ if (r_ecr(ppc) & PPC_SERVICE_INTR) {
+ /* writeIntrThreshold reached */
+ ppc->ppc_wthr = ppc->ppc_fifo - i+1;
+ }
+ /* if FIFO empty before the last byte, error */
+ if (i>1 && (r_ecr(ppc) & PPC_FIFO_EMPTY)) {
+ LOG_PPC(__FUNCTION__, ppc, "data lost in FIFO");
+ goto error;
+ }
+ }
+
+ /* FIFO must be empty after the last byte */
+ if (!(r_ecr(ppc) & PPC_FIFO_EMPTY)) {
+ LOG_PPC(__FUNCTION__, ppc, "can't empty the FIFO");
+ goto error;
+ }
+
+ w_ctr(ppc, ctr_sav);
+ w_ecr(ppc, ecr_sav);
+
+ return (0);
+
+error:
+ w_ctr(ppc, ctr_sav);
+ w_ecr(ppc, ecr_sav);
+
+ return (EINVAL);
}
static int
@@ -654,6 +767,13 @@ config:
ppc->ppc_avm = chipset_mode;
}
+ /* set FIFO threshold to 16 */
+ if (ppc->ppc_avm & PPB_ECP) {
+ /* select CRA */
+ outb(csr, 0xa);
+ outb(cio, 16);
+ }
+
end_detect:
if (bootverbose)
@@ -884,14 +1004,14 @@ ppc_generic_detect(struct ppc_data *ppc, int chipset_mode)
if (!chipset_mode) {
/* first, check for ECP */
- w_ecr(ppc, 0x20);
- if ((r_ecr(ppc) & 0xe0) == 0x20) {
+ w_ecr(ppc, PPC_ECR_PS2);
+ if ((r_ecr(ppc) & 0xe0) == PPC_ECR_PS2) {
ppc->ppc_avm |= PPB_ECP | PPB_SPP;
if (bootverbose)
printf(" ECP SPP");
/* search for SMC style ECP+EPP mode */
- w_ecr(ppc, 0x80);
+ w_ecr(ppc, PPC_ECR_EPP);
}
/* try to reset EPP timeout bit */
@@ -911,7 +1031,7 @@ ppc_generic_detect(struct ppc_data *ppc, int chipset_mode)
}
} else {
/* restore to standard mode */
- w_ecr(ppc, 0x0);
+ w_ecr(ppc, PPC_ECR_STD);
}
/* XXX try to detect NIBBLE and PS2 modes */
@@ -978,6 +1098,10 @@ ppc_detect(struct ppc_data *ppc, int chipset_mode) {
}
}
+ /* configure/detect ECP FIFO */
+ if ((ppc->ppc_avm & PPB_ECP) && !(ppc->ppc_flags & 0x80))
+ ppc_detect_fifo(ppc);
+
return (0);
}
@@ -1202,6 +1326,244 @@ ppc_exec_microseq(int unit, struct ppb_microseq **p_msq)
/* unreached */
}
+static void
+ppcintr(int unit)
+{
+ struct ppc_data *ppc = ppcdata[unit];
+ char ctr, ecr;
+
+ ctr = r_ctr(ppc);
+ ecr = r_ecr(ppc);
+
+#ifdef PPC_DEBUG
+ printf("!");
+#endif
+
+ /* don't use ecp mode with IRQENABLE set */
+ if (ctr & IRQENABLE) {
+ /* call upper code */
+ ppb_intr(&ppc->ppc_link);
+ return;
+ }
+
+ if (ctr & nFAULT) {
+ if (ppc->ppc_irqstat & PPC_IRQ_nFAULT) {
+
+ w_ecr(ppc, ecr | PPC_nFAULT_INTR);
+ ppc->ppc_irqstat &= ~PPC_IRQ_nFAULT;
+ } else {
+ /* call upper code */
+ ppb_intr(&ppc->ppc_link);
+ return;
+ }
+ }
+
+ if (ppc->ppc_irqstat & PPC_IRQ_DMA) {
+ /* disable interrupts (should be done by hardware though) */
+ w_ecr(ppc, ecr | PPC_SERVICE_INTR);
+ ppc->ppc_irqstat &= ~PPC_IRQ_DMA;
+ ecr = r_ecr(ppc);
+
+ /* check if DMA completed */
+ if ((ppc->ppc_avm & PPB_ECP) && (ecr & PPC_ENABLE_DMA)) {
+#ifdef PPC_DEBUG
+ printf("a");
+#endif
+ /* stop DMA */
+ w_ecr(ppc, ecr & ~PPC_ENABLE_DMA);
+ ecr = r_ecr(ppc);
+
+ if (ppc->ppc_dmastat == PPC_DMA_STARTED) {
+#ifdef PPC_DEBUG
+ printf("d");
+#endif
+ isa_dmadone(
+ ppc->ppc_dmaflags,
+ ppc->ppc_dmaddr,
+ ppc->ppc_dmacnt,
+ ppc->ppc_dmachan);
+
+ ppc->ppc_dmastat = PPC_DMA_COMPLETE;
+
+ /* wakeup the waiting process */
+ wakeup((caddr_t)ppc);
+ }
+ }
+ } else if (ppc->ppc_irqstat & PPC_IRQ_FIFO) {
+
+ /* classic interrupt I/O */
+ ppc->ppc_irqstat &= ~PPC_IRQ_FIFO;
+
+ }
+
+ return;
+}
+
+static int
+ppc_read(int unit, char *buf, int len, int mode)
+{
+ return (EINVAL);
+}
+
+/*
+ * Call this function if you want to send data in any advanced mode
+ * of your parallel port: FIFO, DMA
+ *
+ * If what you want is not possible (no ECP, no DMA...),
+ * EINVAL is returned
+ */
+static int
+ppc_write(int unit, char *buf, int len, int how)
+{
+ struct ppc_data *ppc = ppcdata[unit];
+ char ecr, ecr_sav, ctr, ctr_sav;
+ int s, error = 0;
+ int spin;
+
+#ifdef PPC_DEBUG
+ printf("w");
+#endif
+
+ ecr_sav = r_ecr(ppc);
+ ctr_sav = r_ctr(ppc);
+
+ /*
+ * Send buffer with DMA, FIFO and interrupts
+ */
+ if (ppc->ppc_avm & PPB_ECP) {
+
+ if (ppc->ppc_dmachan >= 0) {
+
+ /* byte mode, no intr, no DMA, dir=0, flush fifo
+ */
+ ecr = PPC_ECR_STD | PPC_DISABLE_INTR;
+ w_ecr(ppc, ecr);
+
+ /* disable nAck interrupts */
+ ctr = r_ctr(ppc);
+ ctr &= ~IRQENABLE;
+ w_ctr(ppc, ctr);
+
+ ppc->ppc_dmaflags = 0;
+ ppc->ppc_dmaddr = (caddr_t)buf;
+ ppc->ppc_dmacnt = (u_int)len;
+
+ switch (ppc->ppc_mode) {
+ case PPB_COMPATIBLE:
+ /* compatible mode with FIFO, no intr, DMA, dir=0 */
+ ecr = PPC_ECR_FIFO | PPC_DISABLE_INTR | PPC_ENABLE_DMA;
+ break;
+ case PPB_ECP:
+ ecr = PPC_ECR_ECP | PPC_DISABLE_INTR | PPC_ENABLE_DMA;
+ break;
+ default:
+ error = EINVAL;
+ goto error;
+ }
+
+ w_ecr(ppc, ecr);
+ ecr = r_ecr(ppc);
+
+ /* enter splhigh() not to be preempted
+ * by the dma interrupt, we may miss
+ * the wakeup otherwise
+ */
+ s = splhigh();
+
+ ppc->ppc_dmastat = PPC_DMA_INIT;
+
+ /* enable interrupts */
+ ecr &= ~PPC_SERVICE_INTR;
+ ppc->ppc_irqstat = PPC_IRQ_DMA;
+ w_ecr(ppc, ecr);
+
+ isa_dmastart(
+ ppc->ppc_dmaflags,
+ ppc->ppc_dmaddr,
+ ppc->ppc_dmacnt,
+ ppc->ppc_dmachan);
+#ifdef PPC_DEBUG
+ printf("s%d", ppc->ppc_dmacnt);
+#endif
+ ppc->ppc_dmastat = PPC_DMA_STARTED;
+
+ /* Wait for the DMA completed interrupt. We hope we won't
+ * miss it, otherwise a signal will be necessary to unlock the
+ * process.
+ */
+ do {
+ /* release CPU */
+ error = tsleep((caddr_t)ppc,
+ PPBPRI | PCATCH, "ppcdma", 0);
+
+ } while (error == EWOULDBLOCK);
+
+ splx(s);
+
+ if (error) {
+#ifdef PPC_DEBUG
+ printf("i");
+#endif
+ /* stop DMA */
+ isa_dmadone(
+ ppc->ppc_dmaflags, ppc->ppc_dmaddr,
+ ppc->ppc_dmacnt, ppc->ppc_dmachan);
+
+ /* no dma, no interrupt, flush the fifo */
+ w_ecr(ppc, PPC_ECR_RESET);
+
+ ppc->ppc_dmastat = PPC_DMA_INTERRUPTED;
+ goto error;
+ }
+
+ /* wait for an empty fifo */
+ while (!(r_ecr(ppc) & PPC_FIFO_EMPTY)) {
+
+ for (spin=100; spin; spin--)
+ if (r_ecr(ppc) & PPC_FIFO_EMPTY)
+ goto fifo_empty;
+#ifdef PPC_DEBUG
+ printf("Z");
+#endif
+ error = tsleep((caddr_t)ppc, PPBPRI | PCATCH, "ppcfifo", hz/100);
+ if (error != EWOULDBLOCK) {
+#ifdef PPC_DEBUG
+ printf("I");
+#endif
+ /* no dma, no interrupt, flush the fifo */
+ w_ecr(ppc, PPC_ECR_RESET);
+
+ ppc->ppc_dmastat = PPC_DMA_INTERRUPTED;
+ error = EINTR;
+ goto error;
+ }
+ }
+
+fifo_empty:
+ /* no dma, no interrupt, flush the fifo */
+ w_ecr(ppc, PPC_ECR_RESET);
+
+ } else
+ error = EINVAL; /* XXX we should FIFO and
+ * interrupts */
+ } else
+ error = EINVAL;
+
+error:
+
+ /* PDRQ must be kept unasserted until nPDACK is
+ * deasserted for a minimum of 350ns (SMC datasheet)
+ *
+ * Consequence may be a FIFO that never empty
+ */
+ DELAY(1);
+
+ w_ecr(ppc, ecr_sav);
+ w_ctr(ppc, ctr_sav);
+
+ return (error);
+}
+
/*
* Configure current operating mode
*/
@@ -1209,32 +1571,34 @@ static int
ppc_generic_setmode(int unit, int mode)
{
struct ppc_data *ppc = ppcdata[unit];
-
- /* back to compatible mode, XXX don't know yet what to do here */
- if (mode == 0) {
- ppc->ppc_mode = PPB_COMPATIBLE;
- return (0);
- }
+ u_char ecr = 0;
/* check if mode is available */
- if (!(ppc->ppc_avm & mode))
- return (EOPNOTSUPP);
+ if (mode && !(ppc->ppc_avm & mode))
+ return (EINVAL);
/* if ECP mode, configure ecr register */
if (ppc->ppc_avm & PPB_ECP) {
+ /* return to byte mode (keeping direction bit),
+ * no interrupt, no DMA to be able to change to
+ * ECP
+ */
+ w_ecr(ppc, PPC_ECR_RESET);
+ ecr = PPC_DISABLE_INTR;
- /* XXX disable DMA, enable interrupts */
if (mode & PPB_EPP)
- return (EOPNOTSUPP);
- else if (mode & PPB_PS2)
- /* select PS2 mode with ECP */
- w_ecr(ppc, 0x20);
+ return (EINVAL);
else if (mode & PPB_ECP)
/* select ECP mode */
- w_ecr(ppc, 0x60);
+ ecr |= PPC_ECR_ECP;
+ else if (mode & PPB_PS2)
+ /* select PS2 mode with ECP */
+ ecr |= PPC_ECR_PS2;
else
- /* select standard parallel port mode */
- w_ecr(ppc, 0x00);
+ /* select COMPATIBLE/NIBBLE mode */
+ ecr |= PPC_ECR_STD;
+
+ w_ecr(ppc, ecr);
}
ppc->ppc_mode = mode;
@@ -1242,42 +1606,50 @@ ppc_generic_setmode(int unit, int mode)
return (0);
}
+/*
+ * The ppc driver is free to choose options like FIFO or DMA
+ * if ECP mode is available.
+ *
+ * The 'RAW' option allows the upper drivers to force the ppc mode
+ * even with FIFO, DMA available.
+ */
int
ppc_smclike_setmode(int unit, int mode)
{
struct ppc_data *ppc = ppcdata[unit];
-
- /* back to compatible mode, XXX don't know yet what to do here */
- if (mode == 0) {
- ppc->ppc_mode = PPB_COMPATIBLE;
- return (0);
- }
+ u_char ecr = 0;
/* check if mode is available */
- if (!(ppc->ppc_avm & mode))
- return (EOPNOTSUPP);
+ if (mode && !(ppc->ppc_avm & mode))
+ return (EINVAL);
/* if ECP mode, configure ecr register */
if (ppc->ppc_avm & PPB_ECP) {
+ /* return to byte mode (keeping direction bit),
+ * no interrupt, no DMA to be able to change to
+ * ECP or EPP mode
+ */
+ w_ecr(ppc, PPC_ECR_RESET);
+ ecr = PPC_DISABLE_INTR;
- /* XXX disable DMA, enable interrupts */
if (mode & PPB_EPP)
/* select EPP mode */
- w_ecr(ppc, 0x80);
- else if (mode & PPB_PS2)
- /* select PS2 mode with ECP */
- w_ecr(ppc, 0x20);
+ ecr |= PPC_ECR_EPP;
else if (mode & PPB_ECP)
/* select ECP mode */
- w_ecr(ppc, 0x60);
+ ecr |= PPC_ECR_ECP;
+ else if (mode & PPB_PS2)
+ /* select PS2 mode with ECP */
+ ecr |= PPC_ECR_PS2;
else
- /* select standard parallel port mode */
- w_ecr(ppc, 0x00);
+ /* select COMPATIBLE/NIBBLE mode */
+ ecr |= PPC_ECR_STD;
+
+ w_ecr(ppc, ecr);
}
ppc->ppc_mode = mode;
-
return (0);
}
@@ -1314,8 +1686,9 @@ ppcprobe(struct isa_device *dvp)
if((next_bios_ppc < BIOS_MAX_PPC) &&
(*(BIOS_PORTS+next_bios_ppc) != 0) ) {
dvp->id_iobase = *(BIOS_PORTS+next_bios_ppc++);
- printf("ppc: parallel port found at 0x%x\n",
- dvp->id_iobase);
+ if (bootverbose)
+ printf("ppc: parallel port found at 0x%x\n",
+ dvp->id_iobase);
} else
return (0);
}
@@ -1351,6 +1724,8 @@ ppcprobe(struct isa_device *dvp)
if (!(dvp->id_flags & 0x20))
ppc->ppc_irq = ffs(dvp->id_irq) - 1;
+ ppc->ppc_dmachan = dvp->id_drq;
+
ppcdata[ppc->ppc_unit] = ppc;
nppc ++;
@@ -1384,6 +1759,11 @@ ppcattach(struct isa_device *isdp)
ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ?
ppc_epp_protocol[ppc->ppc_epp] : "");
+ if (ppc->ppc_fifo)
+ printf("ppc%d: FIFO with %d/%d/%d bytes threshold\n",
+ ppc->ppc_unit, ppc->ppc_fifo, ppc->ppc_wthr,
+ ppc->ppc_rthr);
+
isdp->id_ointr = ppcintr;
/*
@@ -1397,6 +1777,13 @@ ppcattach(struct isa_device *isdp)
ppc->ppc_link.ppbus = ppbus;
ppbus->ppb_link = &ppc->ppc_link;
+ if ((ppc->ppc_avm & PPB_ECP) && (ppc->ppc_dmachan > 0)) {
+
+ /* acquire the DMA channel forever */
+ isa_dma_acquire(ppc->ppc_dmachan);
+ isa_dmainit(ppc->ppc_dmachan, 1024); /* nlpt.BUFSIZE */
+ }
+
/*
* Probe the ppbus and attach devices found.
*/
diff --git a/sys/dev/ppc/ppcreg.h b/sys/dev/ppc/ppcreg.h
index af8c9db..829bfd1 100644
--- a/sys/dev/ppc/ppcreg.h
+++ b/sys/dev/ppc/ppcreg.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: ppcreg.h,v 1.4 1998/09/13 18:26:44 nsouch Exp $
+ * $Id: ppcreg.h,v 1.5 1998/10/31 11:37:09 nsouch Exp $
*
*/
#ifndef __PPCREG_H
@@ -55,6 +55,34 @@ struct ppc_data {
int ppc_mode; /* chipset current mode */
int ppc_avm; /* chipset available modes */
+#define PPC_IRQ_NONE 0x0
+#define PPC_IRQ_nACK 0x1
+#define PPC_IRQ_DMA 0x2
+#define PPC_IRQ_FIFO 0x4
+#define PPC_IRQ_nFAULT 0x8
+ int ppc_irqstat; /* remind irq settings */
+
+#define PPC_DMA_INIT 0x01
+#define PPC_DMA_STARTED 0x02
+#define PPC_DMA_COMPLETE 0x03
+#define PPC_DMA_INTERRUPTED 0x04
+#define PPC_DMA_ERROR 0x05
+ int ppc_dmastat; /* dma state */
+ int ppc_dmachan; /* dma channel */
+ int ppc_dmaflags; /* dma transfer flags */
+ caddr_t ppc_dmaddr; /* buffer address */
+ u_int ppc_dmacnt; /* count of bytes sent with dma */
+
+#define PPC_PWORD_MASK 0x30
+#define PPC_PWORD_16 0x00
+#define PPC_PWORD_8 0x10
+#define PPC_PWORD_32 0x20
+ char ppc_pword; /* PWord size */
+ short ppc_fifo; /* FIFO threshold */
+
+ short ppc_wthr; /* writeIntrThresold */
+ short ppc_rthr; /* readIntrThresold */
+
#define ppc_base ppc_link.base
#define ppc_epp ppc_link.epp_protocol
#define ppc_irq ppc_link.id_irq
@@ -71,25 +99,44 @@ struct ppc_data {
* Parallel Port Chipset registers.
*/
#define PPC_SPP_DTR 0 /* SPP data register */
+#define PPC_ECP_A_FIFO 0 /* ECP Address fifo register */
#define PPC_SPP_STR 1 /* SPP status register */
#define PPC_SPP_CTR 2 /* SPP control register */
#define PPC_EPP_DATA 4 /* EPP data register (8, 16 or 32 bit) */
-#define PPC_ECP_FIFO 0x400 /* ECP fifo register */
+#define PPC_ECP_D_FIFO 0x400 /* ECP Data fifo register */
+#define PPC_ECP_CNFGA 0x400 /* Configuration register A */
+#define PPC_ECP_CNFGB 0x401 /* Configuration register B */
#define PPC_ECP_ECR 0x402 /* ECP extended control register */
+#define PPC_FIFO_EMPTY 0x1 /* ecr register - bit 0 */
+#define PPC_FIFO_FULL 0x2 /* ecr register - bit 1 */
+#define PPC_SERVICE_INTR 0x4 /* ecr register - bit 2 */
+#define PPC_ENABLE_DMA 0x8 /* ecr register - bit 3 */
+#define PPC_nFAULT_INTR 0x10 /* ecr register - bit 4 */
+#define PPC_ECR_STD 0x0
+#define PPC_ECR_PS2 0x20
+#define PPC_ECR_FIFO 0x40
+#define PPC_ECR_ECP 0x60
+#define PPC_ECR_EPP 0x80
+
+#define PPC_DISABLE_INTR (PPC_SERVICE_INTR | PPC_nFAULT_INTR)
+#define PPC_ECR_RESET (PPC_ECR_PS2 | PPC_DISABLE_INTR)
+
#define r_dtr(ppc) ((char)inb((ppc)->ppc_base + PPC_SPP_DTR))
#define r_str(ppc) ((char)inb((ppc)->ppc_base + PPC_SPP_STR))
#define r_ctr(ppc) ((char)inb((ppc)->ppc_base + PPC_SPP_CTR))
#define r_epp(ppc) ((char)inb((ppc)->ppc_base + PPC_EPP_DATA))
+#define r_cnfgA(ppc) ((char)inb((ppc)->ppc_base + PPC_ECP_CNFGA))
+#define r_cnfgB(ppc) ((char)inb((ppc)->ppc_base + PPC_ECP_CNFGB))
#define r_ecr(ppc) ((char)inb((ppc)->ppc_base + PPC_ECP_ECR))
-#define r_fifo(ppc) ((char)inb((ppc)->ppc_base + PPC_ECP_FIFO))
+#define r_fifo(ppc) ((char)inb((ppc)->ppc_base + PPC_ECP_D_FIFO))
#define w_dtr(ppc,byte) outb((ppc)->ppc_base + PPC_SPP_DTR, byte)
#define w_str(ppc,byte) outb((ppc)->ppc_base + PPC_SPP_STR, byte)
#define w_ctr(ppc,byte) outb((ppc)->ppc_base + PPC_SPP_CTR, byte)
#define w_epp(ppc,byte) outb((ppc)->ppc_base + PPC_EPP_DATA, byte)
#define w_ecr(ppc,byte) outb((ppc)->ppc_base + PPC_ECP_ECR, byte)
-#define w_fifo(ppc,byte) outb((ppc)->ppc_base + PPC_ECP_FIFO, byte)
+#define w_fifo(ppc,byte) outb((ppc)->ppc_base + PPC_ECP_D_FIFO, byte)
/*
* Register defines for the PC873xx parts
OpenPOWER on IntegriCloud