1 /* $OpenBSD: lpt_gsc.c,v 1.12 2011/09/16 17:20:07 miod Exp $ */ 2 3 /* 4 * Copyright (c) 1998 Michael Shalayeff 5 * Copyright (c) 1993, 1994 Charles Hannum. 6 * Copyright (c) 1990 William F. Jolitz, TeleMuse 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This software is a component of "386BSD" developed by 20 * William F. Jolitz, TeleMuse. 21 * 4. Neither the name of the developer nor the name "386BSD" 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS A COMPONENT OF 386BSD DEVELOPED BY WILLIAM F. JOLITZ 26 * AND IS INTENDED FOR RESEARCH AND EDUCATIONAL PURPOSES ONLY. THIS 27 * SOFTWARE SHOULD NOT BE CONSIDERED TO BE A COMMERCIAL PRODUCT. 28 * THE DEVELOPER URGES THAT USERS WHO REQUIRE A COMMERCIAL PRODUCT 29 * NOT MAKE USE OF THIS WORK. 30 * 31 * FOR USERS WHO WISH TO UNDERSTAND THE 386BSD SYSTEM DEVELOPED 32 * BY WILLIAM F. JOLITZ, WE RECOMMEND THE USER STUDY WRITTEN 33 * REFERENCES SUCH AS THE "PORTING UNIX TO THE 386" SERIES 34 * (BEGINNING JANUARY 1991 "DR. DOBBS JOURNAL", USA AND BEGINNING 35 * JUNE 1991 "UNIX MAGAZIN", GERMANY) BY WILLIAM F. JOLITZ AND 36 * LYNNE GREER JOLITZ, AS WELL AS OTHER BOOKS ON UNIX AND THE 37 * ON-LINE 386BSD USER MANUAL BEFORE USE. A BOOK DISCUSSING THE INTERNALS 38 * OF 386BSD ENTITLED "386BSD FROM THE INSIDE OUT" WILL BE AVAILABLE LATE 1992. 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND 41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER BE LIABLE 44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * SUCH DAMAGE. 51 */ 52 53 #include <sys/param.h> 54 #include <sys/systm.h> 55 #include <sys/device.h> 56 57 #include <machine/bus.h> 58 #include <machine/intr.h> 59 #include <machine/iomod.h> 60 #include <machine/autoconf.h> 61 62 #include <dev/ic/lptreg.h> 63 #include <dev/ic/lptvar.h> 64 65 #include <hppa/dev/cpudevs.h> 66 67 #include <hppa/gsc/gscbusvar.h> 68 69 #define LPTGSC_OFFSET 0x800 70 71 int lpt_gsc_probe(struct device *, void *, void *); 72 void lpt_gsc_attach(struct device *, struct device *, void *); 73 74 struct cfattach lpt_gsc_ca = { 75 sizeof(struct lpt_softc), lpt_gsc_probe, lpt_gsc_attach 76 }; 77 78 /* 79 * Logic: 80 * 1) You should be able to write to and read back the same value 81 * to the data port. Do an alternating zeros, alternating ones, 82 * walking zero, and walking one test to check for stuck bits. 83 * 84 * 2) You should be able to write to and read back the same value 85 * to the control port lower 5 bits, the upper 3 bits are reserved 86 * per the IBM PC technical reference manuals and different boards 87 * do different things with them. Do an alternating zeros, alternating 88 * ones, walking zero, and walking one test to check for stuck bits. 89 * 90 * Some printers drag the strobe line down when the are powered off 91 * so this bit has been masked out of the control port test. 92 * 93 * XXX Some printers may not like a fast pulse on init or strobe, I 94 * don't know at this point, if that becomes a problem these bits 95 * should be turned off in the mask byte for the control port test. 96 * 97 * 3) Set the data and control ports to a value of 0 98 */ 99 int 100 lpt_gsc_probe(parent, match, aux) 101 struct device *parent; 102 void *match, *aux; 103 { 104 struct gsc_attach_args *ga = aux; 105 bus_space_handle_t ioh; 106 bus_addr_t base; 107 u_int8_t mask, data; 108 int i, rv; 109 110 if (ga->ga_type.iodc_type != HPPA_TYPE_FIO || 111 ga->ga_type.iodc_sv_model != HPPA_FIO_CENT) 112 return 0; 113 114 #ifdef DEBUG 115 #define ABORT \ 116 do { \ 117 printf("lpt_gsc_probe: mask %x data %x failed\n", mask, \ 118 data); \ 119 return 0; \ 120 } while (0) 121 #else 122 #define ABORT do { \ 123 bus_space_unmap(ga->ga_iot, ioh, LPT_NPORTS); \ 124 return 0; \ 125 } while (0) 126 #endif 127 128 base = ga->ga_hpa + LPTGSC_OFFSET; 129 if (bus_space_map(ga->ga_iot, base, LPT_NPORTS, 0, &ioh)) { 130 printf("lpt_gsc_probe: cannot map io space\n"); 131 return 0; 132 } 133 134 rv = 0; 135 mask = 0xff; 136 137 data = 0x55; /* Alternating zeros */ 138 if (!lpt_port_test(ga->ga_iot, ioh, base, lpt_data, data, mask)) 139 ABORT; 140 141 data = 0xaa; /* Alternating ones */ 142 if (!lpt_port_test(ga->ga_iot, ioh, base, lpt_data, data, mask)) 143 ABORT; 144 145 for (i = 0; i < CHAR_BIT; i++) { /* Walking zero */ 146 data = ~(1 << i); 147 if (!lpt_port_test(ga->ga_iot, ioh, base, lpt_data, data, mask)) 148 ABORT; 149 } 150 151 for (i = 0; i < CHAR_BIT; i++) { /* Walking one */ 152 data = (1 << i); 153 if (!lpt_port_test(ga->ga_iot, ioh, base, lpt_data, data, mask)) 154 ABORT; 155 } 156 157 bus_space_write_1(ga->ga_iot, ioh, lpt_data, 0); 158 bus_space_write_1(ga->ga_iot, ioh, lpt_control, 0); 159 bus_space_unmap(ga->ga_iot, ioh, LPT_NPORTS); 160 161 return 1; 162 } 163 164 void 165 lpt_gsc_attach(parent, self, aux) 166 struct device *parent, *self; 167 void *aux; 168 { 169 struct lpt_softc *sc = (void *)self; 170 struct gsc_attach_args *ga = aux; 171 bus_addr_t base; 172 173 /* sc->sc_flags |= LPT_POLLED; */ 174 175 sc->sc_state = 0; 176 sc->sc_iot = ga->ga_iot; 177 base = ga->ga_hpa + LPTGSC_OFFSET; 178 if (bus_space_map(ga->ga_iot, base, LPT_NPORTS, 0, &sc->sc_ioh)) { 179 printf(": cannot map io space\n"); 180 return; 181 } 182 183 lpt_attach_common(sc); 184 185 sc->sc_ih = gsc_intr_establish((struct gsc_softc *)parent, 186 ga->ga_irq, IPL_TTY, lptintr, sc, sc->sc_dev.dv_xname); 187 } 188