1 1.19 jmcneill /* $NetBSD: lpt_puc.c,v 1.19 2018/11/30 16:26:59 jmcneill Exp $ */ 2 1.1 cgd 3 1.1 cgd /* 4 1.1 cgd * Copyright (c) 1998 Christopher G. Demetriou. All rights reserved. 5 1.1 cgd * 6 1.1 cgd * Redistribution and use in source and binary forms, with or without 7 1.1 cgd * modification, are permitted provided that the following conditions 8 1.1 cgd * are met: 9 1.1 cgd * 1. Redistributions of source code must retain the above copyright 10 1.1 cgd * notice, this list of conditions and the following disclaimer. 11 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 12 1.1 cgd * notice, this list of conditions and the following disclaimer in the 13 1.1 cgd * documentation and/or other materials provided with the distribution. 14 1.1 cgd * 3. All advertising materials mentioning features or use of this software 15 1.1 cgd * must display the following acknowledgement: 16 1.1 cgd * This product includes software developed by Christopher G. Demetriou 17 1.1 cgd * for the NetBSD Project. 18 1.1 cgd * 4. The name of the author may not be used to endorse or promote products 19 1.1 cgd * derived from this software without specific prior written permission 20 1.1 cgd * 21 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 1.1 cgd * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 1.1 cgd * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 1.1 cgd * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 1.1 cgd * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 1.1 cgd * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 1.1 cgd * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 1.1 cgd * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 1.1 cgd * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 1.1 cgd * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 1.1 cgd */ 32 1.1 cgd 33 1.1 cgd /* 34 1.8 perry * Machine-independent parallel port ('lpt') driver attachment to "PCI 35 1.1 cgd * Universal Communications" controller driver. 36 1.1 cgd * 37 1.1 cgd * Author: Christopher G. Demetriou, May 17, 1998. 38 1.1 cgd */ 39 1.2 lukem 40 1.2 lukem #include <sys/cdefs.h> 41 1.19 jmcneill __KERNEL_RCSID(0, "$NetBSD: lpt_puc.c,v 1.19 2018/11/30 16:26:59 jmcneill Exp $"); 42 1.1 cgd 43 1.1 cgd #include <sys/param.h> 44 1.1 cgd #include <sys/systm.h> 45 1.1 cgd #include <sys/device.h> 46 1.1 cgd 47 1.13 ad #include <sys/bus.h> 48 1.1 cgd 49 1.1 cgd #include <dev/pci/pcivar.h> 50 1.1 cgd #include <dev/pci/pucvar.h> 51 1.1 cgd #include <dev/ic/lptvar.h> 52 1.1 cgd 53 1.9 thorpej static int 54 1.14 cube lpt_puc_probe(device_t parent, cfdata_t match, void *aux) 55 1.1 cgd { 56 1.1 cgd struct puc_attach_args *aa = aux; 57 1.1 cgd 58 1.1 cgd /* 59 1.1 cgd * Locators already matched, just check the type. 60 1.1 cgd */ 61 1.1 cgd if (aa->type != PUC_PORT_TYPE_LPT) 62 1.1 cgd return (0); 63 1.1 cgd 64 1.1 cgd return (1); 65 1.1 cgd } 66 1.1 cgd 67 1.9 thorpej static void 68 1.14 cube lpt_puc_attach(device_t parent, device_t self, void *aux) 69 1.1 cgd { 70 1.14 cube struct lpt_softc *sc = device_private(self); 71 1.1 cgd struct puc_attach_args *aa = aux; 72 1.1 cgd const char *intrstr; 73 1.17 christos char intrbuf[PCI_INTRSTR_LEN]; 74 1.1 cgd 75 1.14 cube sc->sc_dev = self; 76 1.1 cgd sc->sc_iot = aa->t; 77 1.1 cgd sc->sc_ioh = aa->h; 78 1.1 cgd 79 1.19 jmcneill if (aa->poll) { 80 1.19 jmcneill aprint_error(": polling not supported\n"); 81 1.19 jmcneill return; 82 1.19 jmcneill } 83 1.19 jmcneill 84 1.16 soren aprint_naive(": Parallel port"); 85 1.16 soren aprint_normal(": "); 86 1.16 soren 87 1.18 msaitoh intrstr = pci_intr_string(aa->pc, aa->intrhandle, intrbuf, 88 1.18 msaitoh sizeof(intrbuf)); 89 1.18 msaitoh sc->sc_ih = pci_intr_establish_xname(aa->pc, aa->intrhandle, IPL_TTY, 90 1.18 msaitoh lptintr, sc, device_xname(self)); 91 1.1 cgd if (sc->sc_ih == NULL) { 92 1.16 soren aprint_error("couldn't establish interrupt"); 93 1.1 cgd if (intrstr != NULL) 94 1.14 cube aprint_error(" at %s", intrstr); 95 1.14 cube aprint_error("\n"); 96 1.1 cgd return; 97 1.1 cgd } 98 1.1 cgd 99 1.16 soren #if defined(amd64) || defined(i386) 100 1.16 soren /* 101 1.16 soren * Parallel ports are sometimes used for improvised GPIO by 102 1.16 soren * userspace programs which need to know the port's I/O address. 103 1.16 soren * Print the address here so the user doesn't have to dig through 104 1.16 soren * PCI configuration space to find it. 105 1.16 soren */ 106 1.16 soren if (aa->h < 0x10000) 107 1.16 soren aprint_normal("ioaddr 0x%04lx, ", aa->h); 108 1.16 soren #endif 109 1.16 soren aprint_normal("interrupting at %s\n", intrstr); 110 1.15 soren 111 1.15 soren if (!pmf_device_register(self, NULL, NULL)) 112 1.15 soren aprint_error_dev(self, "couldn't establish power handler\n"); 113 1.16 soren 114 1.16 soren lpt_attach_subr(sc); 115 1.1 cgd } 116 1.9 thorpej 117 1.14 cube CFATTACH_DECL_NEW(lpt_puc, sizeof(struct lpt_softc), 118 1.9 thorpej lpt_puc_probe, lpt_puc_attach, NULL, NULL); 119