From b17369f2d0992f6f4c03b3fce283e1e18bc149f0 Mon Sep 17 00:00:00 2001 From: nsouch Date: Wed, 2 Sep 1998 20:34:34 +0000 Subject: [PATCH] printing with compatible mode fixed if ECP available + more verbose if bootverbose set --- sys/dev/ppc/ppc.c | 206 +++++++++++++++++++++++++++++++++++---------- sys/i386/isa/ppc.c | 206 +++++++++++++++++++++++++++++++++++---------- sys/isa/ppc.c | 206 +++++++++++++++++++++++++++++++++++---------- 3 files changed, 489 insertions(+), 129 deletions(-) diff --git a/sys/dev/ppc/ppc.c b/sys/dev/ppc/ppc.c index 6828d925e58..ae4646ef754 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.4 1998/08/03 19:14:32 msmith Exp $ + * $Id: ppc.c,v 1.5 1998/08/24 02:28:16 bde Exp $ * */ #include "ppc.h" @@ -126,8 +126,26 @@ static void ppc_ecp_sync(int); static int ppc_exec_microseq(int, struct ppb_microseq *, int *); static int ppc_generic_setmode(int, int); +static int ppc_smclike_setmode(int, int); -static struct ppb_adapter ppc_adapter = { +static struct ppb_adapter ppc_smclike_adapter = { + + 0, /* no intr handler, filled by chipset dependent code */ + + ppc_reset_epp_timeout, ppc_ecp_sync, + + ppc_exec_microseq, + + ppc_smclike_setmode, + + ppc_outsb_epp, ppc_outsw_epp, ppc_outsl_epp, + ppc_insb_epp, ppc_insw_epp, ppc_insl_epp, + + ppc_rdtr, ppc_rstr, ppc_rctr, ppc_repp, ppc_recr, ppc_rfifo, + ppc_wdtr, ppc_wstr, ppc_wctr, ppc_wepp, ppc_wecr, ppc_wfifo +}; + +static struct ppb_adapter ppc_generic_adapter = { 0, /* no intr handler, filled by chipset dependent code */ @@ -179,23 +197,6 @@ ppcintr(int unit) return; } -static void -ppc_ecp_config(struct ppc_data *ppc, int chipset_mode) -{ - /* XXX disable DMA, enable interrupts */ - if (chipset_mode & PPB_EPP) - /* select EPP mode */ - w_ecr(ppc, 0x80); - else if (chipset_mode & PPB_PS2) - /* select PS2 mode with ECP */ - w_ecr(ppc, 0x20); - else - /* keep ECP mode alone, default for NIBBLE */ - w_ecr(ppc, 0x70); - - return; -} - static int ppc_detect_port(struct ppc_data *ppc) { @@ -464,6 +465,9 @@ ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode) /* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */ if (type == SMC_37C666GT) { ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP; + if (bootverbose) + printf(" configuration hardwired, supposing " \ + "ECP+EPP SPP"); } else if ((inb(cio) & SMC_CR1_MODE) == 0) { @@ -474,23 +478,33 @@ ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode) switch (r) { case SMC_SPP: ppc->ppc_avm |= PPB_SPP; + if (bootverbose) + printf(" SPP"); break; case SMC_EPPSPP: ppc->ppc_avm |= PPB_EPP | PPB_SPP; + if (bootverbose) + printf(" EPP SPP"); break; case SMC_ECP: ppc->ppc_avm |= PPB_ECP | PPB_SPP; + if (bootverbose) + printf(" ECP SPP"); break; case SMC_ECPEPP: ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP; + if (bootverbose) + printf(" ECP+EPP SPP"); break; } } else { /* not an extended port mode */ ppc->ppc_avm |= PPB_SPP; + if (bootverbose) + printf(" SPP"); } } else { @@ -504,6 +518,8 @@ ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode) if ((chipset_mode & (PPB_ECP | PPB_EPP)) == 0) { /* do not use ECP when the mode is not forced to */ outb(cio, r | SMC_CR1_MODE); + if (bootverbose) + printf(" SPP"); } else { /* an extended mode is selected */ outb(cio, r & ~SMC_CR1_MODE); @@ -515,12 +531,18 @@ ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode) if (chipset_mode & PPB_ECP) { if (chipset_mode & PPB_EPP) { outb(cio, r | SMC_ECPEPP); + if (bootverbose) + printf(" ECP+EPP"); } else { outb(cio, r | SMC_ECP); + if (bootverbose) + printf(" ECP"); } } else { /* PPB_EPP is set */ outb(cio, r | SMC_EPPSPP); + if (bootverbose) + printf(" EPP SPP"); } } ppc->ppc_avm = chipset_mode; @@ -549,8 +571,8 @@ ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode) /* end config mode */ outb(csr, 0xaa); - if (ppc->ppc_avm & PPB_ECP) - ppc_ecp_config(ppc, chipset_mode); + ppc->ppc_link.adapter = &ppc_smclike_adapter; + ppc_smclike_setmode(ppc->ppc_unit, chipset_mode); return (chipset_mode); } @@ -644,8 +666,11 @@ ppc_w83877f_detect(struct ppc_data *ppc, int chipset_mode) printf("0x%x ", inb(efdr)); } printf("\n"); + printf("ppc%d:", ppc->ppc_unit); } + ppc->ppc_link.adapter = &ppc_generic_adapter; + if (!chipset_mode) { /* autodetect mode */ @@ -669,20 +694,27 @@ ppc_w83877f_detect(struct ppc_data *ppc, int chipset_mode) case WINB_EXT2FDD: case WINB_JOYSTICK: if (bootverbose) - printf("ppc%d: not in parallel port mode\n", - ppc->ppc_unit); + printf(" not in parallel port mode\n"); return (-1); case (WINB_PARALLEL | WINB_EPP_SPP): ppc->ppc_avm |= PPB_EPP | PPB_SPP; + if (bootverbose) + printf(" EPP SPP"); break; case (WINB_PARALLEL | WINB_ECP): ppc->ppc_avm |= PPB_ECP | PPB_SPP; + if (bootverbose) + printf(" ECP SPP"); break; case (WINB_PARALLEL | WINB_ECP_EPP): ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP; + ppc->ppc_link.adapter = &ppc_smclike_adapter; + + if (bootverbose) + printf(" ECP+EPP SPP"); break; default: printf("%s: unknown case (0x%x)!\n", __FUNCTION__, r); @@ -700,22 +732,34 @@ ppc_w83877f_detect(struct ppc_data *ppc, int chipset_mode) outb(efdr, inb(efdr) & ~(WINB_PRTMODS0 | WINB_PRTMODS1)); if (chipset_mode & PPB_ECP) { - if (chipset_mode & PPB_EPP) + if (chipset_mode & PPB_EPP) { outb(efdr, inb(efdr) | WINB_ECP_EPP); - else + if (bootverbose) + printf(" ECP+EPP"); + + ppc->ppc_link.adapter = &ppc_smclike_adapter; + + } else { outb(efdr, inb(efdr) | WINB_ECP); + if (bootverbose) + printf(" ECP"); + } } else { /* select EPP_SPP otherwise */ outb(efdr, inb(efdr) | WINB_EPP_SPP); + if (bootverbose) + printf(" EPP SPP"); } ppc->ppc_avm = chipset_mode; } + + if (bootverbose) + printf("\n"); /* exit configuration mode */ outb(efer, 0xaa); - if (ppc->ppc_avm & PPB_ECP) - ppc_ecp_config(ppc, chipset_mode); + ppc->ppc_link.adapter->setmode(ppc->ppc_unit, chipset_mode); return (chipset_mode); } @@ -728,11 +772,19 @@ ppc_generic_detect(struct ppc_data *ppc, int chipset_mode) { char save_control; + /* default to generic */ + ppc->ppc_link.adapter = &ppc_generic_adapter; + + if (bootverbose) + printf("ppc%d:", ppc->ppc_unit); + if (!chipset_mode) { /* first, check for ECP */ w_ecr(ppc, 0x20); if ((r_ecr(ppc) & 0xe0) == 0x20) { ppc->ppc_avm |= PPB_ECP | PPB_SPP; + if (bootverbose) + printf(" ECP SPP"); /* search for SMC style ECP+EPP mode */ w_ecr(ppc, 0x80); @@ -742,19 +794,36 @@ ppc_generic_detect(struct ppc_data *ppc, int chipset_mode) if (ppc_check_epp_timeout(ppc)) { ppc->ppc_avm |= PPB_EPP; - if (ppc->ppc_avm & PPB_ECP) + if (ppc->ppc_avm & PPB_ECP) { /* SMC like chipset found */ ppc->ppc_type = SMC_LIKE; + ppc->ppc_link.adapter = &ppc_smclike_adapter; + + if (bootverbose) + printf(" ECP+EPP"); + } else { + if (bootverbose) + printf(" EPP"); + } + } else { + /* restore to standard mode */ + w_ecr(ppc, 0x0); } - /* XXX try to detect NIBBLE mode */ + /* XXX try to detect NIBBLE and PS2 modes */ ppc->ppc_avm |= PPB_NIBBLE; - } else + if (bootverbose) + printf(" SPP"); + + } else { ppc->ppc_avm = chipset_mode; + } + + if (bootverbose) + printf("\n"); - if (ppc->ppc_avm & PPB_ECP) - ppc_ecp_config(ppc, chipset_mode); + ppc->ppc_link.adapter->setmode(ppc->ppc_unit, chipset_mode); return (chipset_mode); } @@ -1013,14 +1082,66 @@ ppc_generic_setmode(int unit, int mode) return (EOPNOTSUPP); /* if ECP mode, configure ecr register */ - if (ppc->ppc_avm & PPB_ECP) - ppc_ecp_config(ppc, mode); + if (ppc->ppc_avm & PPB_ECP) { + + /* 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); + else if (mode & PPB_ECP) + /* select ECP mode */ + w_ecr(ppc, 0x60); + else + /* select standard parallel port mode */ + w_ecr(ppc, 0x00); + } ppc->ppc_mode = mode; return (0); } +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); + } + + /* check if mode is available */ + if (!(ppc->ppc_avm & mode)) + return (EOPNOTSUPP); + + /* if ECP mode, configure ecr register */ + if (ppc->ppc_avm & PPB_ECP) { + + /* 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); + else if (mode & PPB_ECP) + /* select ECP mode */ + w_ecr(ppc, 0x60); + else + /* select standard parallel port mode */ + w_ecr(ppc, 0x00); + } + + ppc->ppc_mode = mode; + + + return (0); +} + /* * EPP timeout, according to the PC87332 manual * Semantics of clearing EPP timeout bit. @@ -1082,8 +1203,7 @@ ppcprobe(struct isa_device *dvp) ppc->ppc_epp = (dvp->id_flags & 0x10) >> 4; /* - * XXX - * Try and detect if interrupts are working. + * XXX Try and detect if interrupts are working */ if (!(dvp->id_flags & 0x20)) ppc->ppc_irq = (dvp->id_irq); @@ -1091,6 +1211,13 @@ ppcprobe(struct isa_device *dvp) ppcdata[ppc->ppc_unit] = ppc; nppc ++; + /* + * Link the Parallel Port Chipset (adapter) to + * the future ppbus. Default to a generic chipset + */ + ppc->ppc_link.adapter_unit = ppc->ppc_unit; + ppc->ppc_link.adapter = &ppc_generic_adapter; + /* * Try to detect the chipset and its mode. */ @@ -1112,13 +1239,6 @@ ppcattach(struct isa_device *isdp) struct ppb_data *ppbus; char * mode; - /* - * Link the Parallel Port Chipset (adapter) to - * the future ppbus. - */ - ppc->ppc_link.adapter_unit = ppc->ppc_unit; - ppc->ppc_link.adapter = &ppc_adapter; - printf("ppc%d: %s chipset (%s) in %s mode%s\n", ppc->ppc_unit, ppc_types[ppc->ppc_type], ppc_avms[ppc->ppc_avm], ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ? diff --git a/sys/i386/isa/ppc.c b/sys/i386/isa/ppc.c index 6828d925e58..ae4646ef754 100644 --- a/sys/i386/isa/ppc.c +++ b/sys/i386/isa/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.4 1998/08/03 19:14:32 msmith Exp $ + * $Id: ppc.c,v 1.5 1998/08/24 02:28:16 bde Exp $ * */ #include "ppc.h" @@ -126,8 +126,26 @@ static void ppc_ecp_sync(int); static int ppc_exec_microseq(int, struct ppb_microseq *, int *); static int ppc_generic_setmode(int, int); +static int ppc_smclike_setmode(int, int); -static struct ppb_adapter ppc_adapter = { +static struct ppb_adapter ppc_smclike_adapter = { + + 0, /* no intr handler, filled by chipset dependent code */ + + ppc_reset_epp_timeout, ppc_ecp_sync, + + ppc_exec_microseq, + + ppc_smclike_setmode, + + ppc_outsb_epp, ppc_outsw_epp, ppc_outsl_epp, + ppc_insb_epp, ppc_insw_epp, ppc_insl_epp, + + ppc_rdtr, ppc_rstr, ppc_rctr, ppc_repp, ppc_recr, ppc_rfifo, + ppc_wdtr, ppc_wstr, ppc_wctr, ppc_wepp, ppc_wecr, ppc_wfifo +}; + +static struct ppb_adapter ppc_generic_adapter = { 0, /* no intr handler, filled by chipset dependent code */ @@ -179,23 +197,6 @@ ppcintr(int unit) return; } -static void -ppc_ecp_config(struct ppc_data *ppc, int chipset_mode) -{ - /* XXX disable DMA, enable interrupts */ - if (chipset_mode & PPB_EPP) - /* select EPP mode */ - w_ecr(ppc, 0x80); - else if (chipset_mode & PPB_PS2) - /* select PS2 mode with ECP */ - w_ecr(ppc, 0x20); - else - /* keep ECP mode alone, default for NIBBLE */ - w_ecr(ppc, 0x70); - - return; -} - static int ppc_detect_port(struct ppc_data *ppc) { @@ -464,6 +465,9 @@ ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode) /* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */ if (type == SMC_37C666GT) { ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP; + if (bootverbose) + printf(" configuration hardwired, supposing " \ + "ECP+EPP SPP"); } else if ((inb(cio) & SMC_CR1_MODE) == 0) { @@ -474,23 +478,33 @@ ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode) switch (r) { case SMC_SPP: ppc->ppc_avm |= PPB_SPP; + if (bootverbose) + printf(" SPP"); break; case SMC_EPPSPP: ppc->ppc_avm |= PPB_EPP | PPB_SPP; + if (bootverbose) + printf(" EPP SPP"); break; case SMC_ECP: ppc->ppc_avm |= PPB_ECP | PPB_SPP; + if (bootverbose) + printf(" ECP SPP"); break; case SMC_ECPEPP: ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP; + if (bootverbose) + printf(" ECP+EPP SPP"); break; } } else { /* not an extended port mode */ ppc->ppc_avm |= PPB_SPP; + if (bootverbose) + printf(" SPP"); } } else { @@ -504,6 +518,8 @@ ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode) if ((chipset_mode & (PPB_ECP | PPB_EPP)) == 0) { /* do not use ECP when the mode is not forced to */ outb(cio, r | SMC_CR1_MODE); + if (bootverbose) + printf(" SPP"); } else { /* an extended mode is selected */ outb(cio, r & ~SMC_CR1_MODE); @@ -515,12 +531,18 @@ ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode) if (chipset_mode & PPB_ECP) { if (chipset_mode & PPB_EPP) { outb(cio, r | SMC_ECPEPP); + if (bootverbose) + printf(" ECP+EPP"); } else { outb(cio, r | SMC_ECP); + if (bootverbose) + printf(" ECP"); } } else { /* PPB_EPP is set */ outb(cio, r | SMC_EPPSPP); + if (bootverbose) + printf(" EPP SPP"); } } ppc->ppc_avm = chipset_mode; @@ -549,8 +571,8 @@ ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode) /* end config mode */ outb(csr, 0xaa); - if (ppc->ppc_avm & PPB_ECP) - ppc_ecp_config(ppc, chipset_mode); + ppc->ppc_link.adapter = &ppc_smclike_adapter; + ppc_smclike_setmode(ppc->ppc_unit, chipset_mode); return (chipset_mode); } @@ -644,8 +666,11 @@ ppc_w83877f_detect(struct ppc_data *ppc, int chipset_mode) printf("0x%x ", inb(efdr)); } printf("\n"); + printf("ppc%d:", ppc->ppc_unit); } + ppc->ppc_link.adapter = &ppc_generic_adapter; + if (!chipset_mode) { /* autodetect mode */ @@ -669,20 +694,27 @@ ppc_w83877f_detect(struct ppc_data *ppc, int chipset_mode) case WINB_EXT2FDD: case WINB_JOYSTICK: if (bootverbose) - printf("ppc%d: not in parallel port mode\n", - ppc->ppc_unit); + printf(" not in parallel port mode\n"); return (-1); case (WINB_PARALLEL | WINB_EPP_SPP): ppc->ppc_avm |= PPB_EPP | PPB_SPP; + if (bootverbose) + printf(" EPP SPP"); break; case (WINB_PARALLEL | WINB_ECP): ppc->ppc_avm |= PPB_ECP | PPB_SPP; + if (bootverbose) + printf(" ECP SPP"); break; case (WINB_PARALLEL | WINB_ECP_EPP): ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP; + ppc->ppc_link.adapter = &ppc_smclike_adapter; + + if (bootverbose) + printf(" ECP+EPP SPP"); break; default: printf("%s: unknown case (0x%x)!\n", __FUNCTION__, r); @@ -700,22 +732,34 @@ ppc_w83877f_detect(struct ppc_data *ppc, int chipset_mode) outb(efdr, inb(efdr) & ~(WINB_PRTMODS0 | WINB_PRTMODS1)); if (chipset_mode & PPB_ECP) { - if (chipset_mode & PPB_EPP) + if (chipset_mode & PPB_EPP) { outb(efdr, inb(efdr) | WINB_ECP_EPP); - else + if (bootverbose) + printf(" ECP+EPP"); + + ppc->ppc_link.adapter = &ppc_smclike_adapter; + + } else { outb(efdr, inb(efdr) | WINB_ECP); + if (bootverbose) + printf(" ECP"); + } } else { /* select EPP_SPP otherwise */ outb(efdr, inb(efdr) | WINB_EPP_SPP); + if (bootverbose) + printf(" EPP SPP"); } ppc->ppc_avm = chipset_mode; } + + if (bootverbose) + printf("\n"); /* exit configuration mode */ outb(efer, 0xaa); - if (ppc->ppc_avm & PPB_ECP) - ppc_ecp_config(ppc, chipset_mode); + ppc->ppc_link.adapter->setmode(ppc->ppc_unit, chipset_mode); return (chipset_mode); } @@ -728,11 +772,19 @@ ppc_generic_detect(struct ppc_data *ppc, int chipset_mode) { char save_control; + /* default to generic */ + ppc->ppc_link.adapter = &ppc_generic_adapter; + + if (bootverbose) + printf("ppc%d:", ppc->ppc_unit); + if (!chipset_mode) { /* first, check for ECP */ w_ecr(ppc, 0x20); if ((r_ecr(ppc) & 0xe0) == 0x20) { ppc->ppc_avm |= PPB_ECP | PPB_SPP; + if (bootverbose) + printf(" ECP SPP"); /* search for SMC style ECP+EPP mode */ w_ecr(ppc, 0x80); @@ -742,19 +794,36 @@ ppc_generic_detect(struct ppc_data *ppc, int chipset_mode) if (ppc_check_epp_timeout(ppc)) { ppc->ppc_avm |= PPB_EPP; - if (ppc->ppc_avm & PPB_ECP) + if (ppc->ppc_avm & PPB_ECP) { /* SMC like chipset found */ ppc->ppc_type = SMC_LIKE; + ppc->ppc_link.adapter = &ppc_smclike_adapter; + + if (bootverbose) + printf(" ECP+EPP"); + } else { + if (bootverbose) + printf(" EPP"); + } + } else { + /* restore to standard mode */ + w_ecr(ppc, 0x0); } - /* XXX try to detect NIBBLE mode */ + /* XXX try to detect NIBBLE and PS2 modes */ ppc->ppc_avm |= PPB_NIBBLE; - } else + if (bootverbose) + printf(" SPP"); + + } else { ppc->ppc_avm = chipset_mode; + } + + if (bootverbose) + printf("\n"); - if (ppc->ppc_avm & PPB_ECP) - ppc_ecp_config(ppc, chipset_mode); + ppc->ppc_link.adapter->setmode(ppc->ppc_unit, chipset_mode); return (chipset_mode); } @@ -1013,14 +1082,66 @@ ppc_generic_setmode(int unit, int mode) return (EOPNOTSUPP); /* if ECP mode, configure ecr register */ - if (ppc->ppc_avm & PPB_ECP) - ppc_ecp_config(ppc, mode); + if (ppc->ppc_avm & PPB_ECP) { + + /* 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); + else if (mode & PPB_ECP) + /* select ECP mode */ + w_ecr(ppc, 0x60); + else + /* select standard parallel port mode */ + w_ecr(ppc, 0x00); + } ppc->ppc_mode = mode; return (0); } +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); + } + + /* check if mode is available */ + if (!(ppc->ppc_avm & mode)) + return (EOPNOTSUPP); + + /* if ECP mode, configure ecr register */ + if (ppc->ppc_avm & PPB_ECP) { + + /* 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); + else if (mode & PPB_ECP) + /* select ECP mode */ + w_ecr(ppc, 0x60); + else + /* select standard parallel port mode */ + w_ecr(ppc, 0x00); + } + + ppc->ppc_mode = mode; + + + return (0); +} + /* * EPP timeout, according to the PC87332 manual * Semantics of clearing EPP timeout bit. @@ -1082,8 +1203,7 @@ ppcprobe(struct isa_device *dvp) ppc->ppc_epp = (dvp->id_flags & 0x10) >> 4; /* - * XXX - * Try and detect if interrupts are working. + * XXX Try and detect if interrupts are working */ if (!(dvp->id_flags & 0x20)) ppc->ppc_irq = (dvp->id_irq); @@ -1091,6 +1211,13 @@ ppcprobe(struct isa_device *dvp) ppcdata[ppc->ppc_unit] = ppc; nppc ++; + /* + * Link the Parallel Port Chipset (adapter) to + * the future ppbus. Default to a generic chipset + */ + ppc->ppc_link.adapter_unit = ppc->ppc_unit; + ppc->ppc_link.adapter = &ppc_generic_adapter; + /* * Try to detect the chipset and its mode. */ @@ -1112,13 +1239,6 @@ ppcattach(struct isa_device *isdp) struct ppb_data *ppbus; char * mode; - /* - * Link the Parallel Port Chipset (adapter) to - * the future ppbus. - */ - ppc->ppc_link.adapter_unit = ppc->ppc_unit; - ppc->ppc_link.adapter = &ppc_adapter; - printf("ppc%d: %s chipset (%s) in %s mode%s\n", ppc->ppc_unit, ppc_types[ppc->ppc_type], ppc_avms[ppc->ppc_avm], ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ? diff --git a/sys/isa/ppc.c b/sys/isa/ppc.c index 6828d925e58..ae4646ef754 100644 --- a/sys/isa/ppc.c +++ b/sys/isa/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.4 1998/08/03 19:14:32 msmith Exp $ + * $Id: ppc.c,v 1.5 1998/08/24 02:28:16 bde Exp $ * */ #include "ppc.h" @@ -126,8 +126,26 @@ static void ppc_ecp_sync(int); static int ppc_exec_microseq(int, struct ppb_microseq *, int *); static int ppc_generic_setmode(int, int); +static int ppc_smclike_setmode(int, int); -static struct ppb_adapter ppc_adapter = { +static struct ppb_adapter ppc_smclike_adapter = { + + 0, /* no intr handler, filled by chipset dependent code */ + + ppc_reset_epp_timeout, ppc_ecp_sync, + + ppc_exec_microseq, + + ppc_smclike_setmode, + + ppc_outsb_epp, ppc_outsw_epp, ppc_outsl_epp, + ppc_insb_epp, ppc_insw_epp, ppc_insl_epp, + + ppc_rdtr, ppc_rstr, ppc_rctr, ppc_repp, ppc_recr, ppc_rfifo, + ppc_wdtr, ppc_wstr, ppc_wctr, ppc_wepp, ppc_wecr, ppc_wfifo +}; + +static struct ppb_adapter ppc_generic_adapter = { 0, /* no intr handler, filled by chipset dependent code */ @@ -179,23 +197,6 @@ ppcintr(int unit) return; } -static void -ppc_ecp_config(struct ppc_data *ppc, int chipset_mode) -{ - /* XXX disable DMA, enable interrupts */ - if (chipset_mode & PPB_EPP) - /* select EPP mode */ - w_ecr(ppc, 0x80); - else if (chipset_mode & PPB_PS2) - /* select PS2 mode with ECP */ - w_ecr(ppc, 0x20); - else - /* keep ECP mode alone, default for NIBBLE */ - w_ecr(ppc, 0x70); - - return; -} - static int ppc_detect_port(struct ppc_data *ppc) { @@ -464,6 +465,9 @@ ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode) /* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */ if (type == SMC_37C666GT) { ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP; + if (bootverbose) + printf(" configuration hardwired, supposing " \ + "ECP+EPP SPP"); } else if ((inb(cio) & SMC_CR1_MODE) == 0) { @@ -474,23 +478,33 @@ ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode) switch (r) { case SMC_SPP: ppc->ppc_avm |= PPB_SPP; + if (bootverbose) + printf(" SPP"); break; case SMC_EPPSPP: ppc->ppc_avm |= PPB_EPP | PPB_SPP; + if (bootverbose) + printf(" EPP SPP"); break; case SMC_ECP: ppc->ppc_avm |= PPB_ECP | PPB_SPP; + if (bootverbose) + printf(" ECP SPP"); break; case SMC_ECPEPP: ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP; + if (bootverbose) + printf(" ECP+EPP SPP"); break; } } else { /* not an extended port mode */ ppc->ppc_avm |= PPB_SPP; + if (bootverbose) + printf(" SPP"); } } else { @@ -504,6 +518,8 @@ ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode) if ((chipset_mode & (PPB_ECP | PPB_EPP)) == 0) { /* do not use ECP when the mode is not forced to */ outb(cio, r | SMC_CR1_MODE); + if (bootverbose) + printf(" SPP"); } else { /* an extended mode is selected */ outb(cio, r & ~SMC_CR1_MODE); @@ -515,12 +531,18 @@ ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode) if (chipset_mode & PPB_ECP) { if (chipset_mode & PPB_EPP) { outb(cio, r | SMC_ECPEPP); + if (bootverbose) + printf(" ECP+EPP"); } else { outb(cio, r | SMC_ECP); + if (bootverbose) + printf(" ECP"); } } else { /* PPB_EPP is set */ outb(cio, r | SMC_EPPSPP); + if (bootverbose) + printf(" EPP SPP"); } } ppc->ppc_avm = chipset_mode; @@ -549,8 +571,8 @@ ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode) /* end config mode */ outb(csr, 0xaa); - if (ppc->ppc_avm & PPB_ECP) - ppc_ecp_config(ppc, chipset_mode); + ppc->ppc_link.adapter = &ppc_smclike_adapter; + ppc_smclike_setmode(ppc->ppc_unit, chipset_mode); return (chipset_mode); } @@ -644,8 +666,11 @@ ppc_w83877f_detect(struct ppc_data *ppc, int chipset_mode) printf("0x%x ", inb(efdr)); } printf("\n"); + printf("ppc%d:", ppc->ppc_unit); } + ppc->ppc_link.adapter = &ppc_generic_adapter; + if (!chipset_mode) { /* autodetect mode */ @@ -669,20 +694,27 @@ ppc_w83877f_detect(struct ppc_data *ppc, int chipset_mode) case WINB_EXT2FDD: case WINB_JOYSTICK: if (bootverbose) - printf("ppc%d: not in parallel port mode\n", - ppc->ppc_unit); + printf(" not in parallel port mode\n"); return (-1); case (WINB_PARALLEL | WINB_EPP_SPP): ppc->ppc_avm |= PPB_EPP | PPB_SPP; + if (bootverbose) + printf(" EPP SPP"); break; case (WINB_PARALLEL | WINB_ECP): ppc->ppc_avm |= PPB_ECP | PPB_SPP; + if (bootverbose) + printf(" ECP SPP"); break; case (WINB_PARALLEL | WINB_ECP_EPP): ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP; + ppc->ppc_link.adapter = &ppc_smclike_adapter; + + if (bootverbose) + printf(" ECP+EPP SPP"); break; default: printf("%s: unknown case (0x%x)!\n", __FUNCTION__, r); @@ -700,22 +732,34 @@ ppc_w83877f_detect(struct ppc_data *ppc, int chipset_mode) outb(efdr, inb(efdr) & ~(WINB_PRTMODS0 | WINB_PRTMODS1)); if (chipset_mode & PPB_ECP) { - if (chipset_mode & PPB_EPP) + if (chipset_mode & PPB_EPP) { outb(efdr, inb(efdr) | WINB_ECP_EPP); - else + if (bootverbose) + printf(" ECP+EPP"); + + ppc->ppc_link.adapter = &ppc_smclike_adapter; + + } else { outb(efdr, inb(efdr) | WINB_ECP); + if (bootverbose) + printf(" ECP"); + } } else { /* select EPP_SPP otherwise */ outb(efdr, inb(efdr) | WINB_EPP_SPP); + if (bootverbose) + printf(" EPP SPP"); } ppc->ppc_avm = chipset_mode; } + + if (bootverbose) + printf("\n"); /* exit configuration mode */ outb(efer, 0xaa); - if (ppc->ppc_avm & PPB_ECP) - ppc_ecp_config(ppc, chipset_mode); + ppc->ppc_link.adapter->setmode(ppc->ppc_unit, chipset_mode); return (chipset_mode); } @@ -728,11 +772,19 @@ ppc_generic_detect(struct ppc_data *ppc, int chipset_mode) { char save_control; + /* default to generic */ + ppc->ppc_link.adapter = &ppc_generic_adapter; + + if (bootverbose) + printf("ppc%d:", ppc->ppc_unit); + if (!chipset_mode) { /* first, check for ECP */ w_ecr(ppc, 0x20); if ((r_ecr(ppc) & 0xe0) == 0x20) { ppc->ppc_avm |= PPB_ECP | PPB_SPP; + if (bootverbose) + printf(" ECP SPP"); /* search for SMC style ECP+EPP mode */ w_ecr(ppc, 0x80); @@ -742,19 +794,36 @@ ppc_generic_detect(struct ppc_data *ppc, int chipset_mode) if (ppc_check_epp_timeout(ppc)) { ppc->ppc_avm |= PPB_EPP; - if (ppc->ppc_avm & PPB_ECP) + if (ppc->ppc_avm & PPB_ECP) { /* SMC like chipset found */ ppc->ppc_type = SMC_LIKE; + ppc->ppc_link.adapter = &ppc_smclike_adapter; + + if (bootverbose) + printf(" ECP+EPP"); + } else { + if (bootverbose) + printf(" EPP"); + } + } else { + /* restore to standard mode */ + w_ecr(ppc, 0x0); } - /* XXX try to detect NIBBLE mode */ + /* XXX try to detect NIBBLE and PS2 modes */ ppc->ppc_avm |= PPB_NIBBLE; - } else + if (bootverbose) + printf(" SPP"); + + } else { ppc->ppc_avm = chipset_mode; + } + + if (bootverbose) + printf("\n"); - if (ppc->ppc_avm & PPB_ECP) - ppc_ecp_config(ppc, chipset_mode); + ppc->ppc_link.adapter->setmode(ppc->ppc_unit, chipset_mode); return (chipset_mode); } @@ -1013,14 +1082,66 @@ ppc_generic_setmode(int unit, int mode) return (EOPNOTSUPP); /* if ECP mode, configure ecr register */ - if (ppc->ppc_avm & PPB_ECP) - ppc_ecp_config(ppc, mode); + if (ppc->ppc_avm & PPB_ECP) { + + /* 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); + else if (mode & PPB_ECP) + /* select ECP mode */ + w_ecr(ppc, 0x60); + else + /* select standard parallel port mode */ + w_ecr(ppc, 0x00); + } ppc->ppc_mode = mode; return (0); } +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); + } + + /* check if mode is available */ + if (!(ppc->ppc_avm & mode)) + return (EOPNOTSUPP); + + /* if ECP mode, configure ecr register */ + if (ppc->ppc_avm & PPB_ECP) { + + /* 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); + else if (mode & PPB_ECP) + /* select ECP mode */ + w_ecr(ppc, 0x60); + else + /* select standard parallel port mode */ + w_ecr(ppc, 0x00); + } + + ppc->ppc_mode = mode; + + + return (0); +} + /* * EPP timeout, according to the PC87332 manual * Semantics of clearing EPP timeout bit. @@ -1082,8 +1203,7 @@ ppcprobe(struct isa_device *dvp) ppc->ppc_epp = (dvp->id_flags & 0x10) >> 4; /* - * XXX - * Try and detect if interrupts are working. + * XXX Try and detect if interrupts are working */ if (!(dvp->id_flags & 0x20)) ppc->ppc_irq = (dvp->id_irq); @@ -1091,6 +1211,13 @@ ppcprobe(struct isa_device *dvp) ppcdata[ppc->ppc_unit] = ppc; nppc ++; + /* + * Link the Parallel Port Chipset (adapter) to + * the future ppbus. Default to a generic chipset + */ + ppc->ppc_link.adapter_unit = ppc->ppc_unit; + ppc->ppc_link.adapter = &ppc_generic_adapter; + /* * Try to detect the chipset and its mode. */ @@ -1112,13 +1239,6 @@ ppcattach(struct isa_device *isdp) struct ppb_data *ppbus; char * mode; - /* - * Link the Parallel Port Chipset (adapter) to - * the future ppbus. - */ - ppc->ppc_link.adapter_unit = ppc->ppc_unit; - ppc->ppc_link.adapter = &ppc_adapter; - printf("ppc%d: %s chipset (%s) in %s mode%s\n", ppc->ppc_unit, ppc_types[ppc->ppc_type], ppc_avms[ppc->ppc_avm], ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ? -- 2.45.2