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