1102714Sphk/* $NetBSD: puc.c,v 1.7 2000/07/29 17:43:38 jlam Exp $ */ 2102714Sphk 3102714Sphk/*- 4102714Sphk * Copyright (c) 2002 JF Hay. All rights reserved. 5102714Sphk * Copyright (c) 2000 M. Warner Losh. All rights reserved. 6102714Sphk * 7102714Sphk * Redistribution and use in source and binary forms, with or without 8102714Sphk * modification, are permitted provided that the following conditions 9102714Sphk * are met: 10102714Sphk * 1. Redistributions of source code must retain the above copyright 11140040Simp * notice, this list of conditions and the following disclaimer. 12102714Sphk * 2. Redistributions in binary form must reproduce the above copyright 13102714Sphk * notice, this list of conditions and the following disclaimer in the 14102714Sphk * documentation and/or other materials provided with the distribution. 15102714Sphk * 16140040Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17140040Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18140040Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19140040Simp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20140040Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21140040Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22140040Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23140040Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24140040Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25140040Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26140040Simp * SUCH DAMAGE. 27102714Sphk */ 28102714Sphk 29139749Simp/*- 30102714Sphk * Copyright (c) 1996, 1998, 1999 31102714Sphk * Christopher G. Demetriou. All rights reserved. 32102714Sphk * 33102714Sphk * Redistribution and use in source and binary forms, with or without 34102714Sphk * modification, are permitted provided that the following conditions 35102714Sphk * are met: 36102714Sphk * 1. Redistributions of source code must retain the above copyright 37102714Sphk * notice, this list of conditions and the following disclaimer. 38102714Sphk * 2. Redistributions in binary form must reproduce the above copyright 39102714Sphk * notice, this list of conditions and the following disclaimer in the 40102714Sphk * documentation and/or other materials provided with the distribution. 41102714Sphk * 3. All advertising materials mentioning features or use of this software 42102714Sphk * must display the following acknowledgement: 43102714Sphk * This product includes software developed by Christopher G. Demetriou 44102714Sphk * for the NetBSD Project. 45102714Sphk * 4. The name of the author may not be used to endorse or promote products 46102714Sphk * derived from this software without specific prior written permission 47102714Sphk * 48102714Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 49102714Sphk * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 50102714Sphk * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 51102714Sphk * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 52102714Sphk * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 53102714Sphk * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 54102714Sphk * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 55102714Sphk * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 56102714Sphk * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 57102714Sphk * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 58102714Sphk */ 59102714Sphk 60102714Sphk#include <sys/cdefs.h> 61102714Sphk__FBSDID("$FreeBSD$"); 62102714Sphk 63102714Sphk#include <sys/param.h> 64102714Sphk#include <sys/systm.h> 65102714Sphk#include <sys/kernel.h> 66129879Sphk#include <sys/module.h> 67102714Sphk#include <sys/bus.h> 68102714Sphk#include <sys/conf.h> 69102714Sphk#include <sys/malloc.h> 70263109Srstone#include <sys/sysctl.h> 71102714Sphk 72102714Sphk#include <machine/bus.h> 73102714Sphk#include <machine/resource.h> 74102714Sphk#include <sys/rman.h> 75102714Sphk 76102714Sphk#include <dev/pci/pcireg.h> 77102714Sphk#include <dev/pci/pcivar.h> 78102714Sphk 79160030Sobrien#include <dev/puc/puc_cfg.h> 80158124Smarcel#include <dev/puc/puc_bfe.h> 81102714Sphk 82263109Srstonestatic int puc_msi_disable; 83267992ShselaskySYSCTL_INT(_hw_puc, OID_AUTO, msi_disable, CTLFLAG_RDTUN, 84263109Srstone &puc_msi_disable, 0, "Disable use of MSI interrupts by puc(9)"); 85263109Srstone 86158124Smarcelstatic const struct puc_cfg * 87158124Smarcelpuc_pci_match(device_t dev, const struct puc_cfg *desc) 88119814Smarcel{ 89172617Sdes uint16_t vendor, device; 90172617Sdes uint16_t subvendor, subdevice; 91119814Smarcel 92158124Smarcel vendor = pci_get_vendor(dev); 93158124Smarcel device = pci_get_device(dev); 94172617Sdes subvendor = pci_get_subvendor(dev); 95172617Sdes subdevice = pci_get_subdevice(dev); 96172617Sdes 97172617Sdes while (desc->vendor != 0xffff) { 98172617Sdes if (desc->vendor == vendor && desc->device == device) { 99172617Sdes /* exact match */ 100172617Sdes if (desc->subvendor == subvendor && 101172617Sdes desc->subdevice == subdevice) 102172617Sdes return (desc); 103172617Sdes /* wildcard match */ 104172617Sdes if (desc->subvendor == 0xffff) 105172617Sdes return (desc); 106172617Sdes } 107158124Smarcel desc++; 108172617Sdes } 109172617Sdes 110172617Sdes /* no match */ 111172617Sdes return (NULL); 112119814Smarcel} 113119814Smarcel 114102714Sphkstatic int 115102714Sphkpuc_pci_probe(device_t dev) 116102714Sphk{ 117158124Smarcel const struct puc_cfg *desc; 118102714Sphk 119119539Sjhb if ((pci_read_config(dev, PCIR_HDRTYPE, 1) & PCIM_HDRTYPE) != 0) 120102714Sphk return (ENXIO); 121102714Sphk 122158124Smarcel desc = puc_pci_match(dev, puc_pci_devices); 123102714Sphk if (desc == NULL) 124102714Sphk return (ENXIO); 125158124Smarcel return (puc_bfe_probe(dev, desc)); 126102714Sphk} 127102714Sphk 128263109Srstonestatic int 129263109Srstonepuc_pci_attach(device_t dev) 130263109Srstone{ 131263109Srstone struct puc_softc *sc; 132263109Srstone int error, count; 133263109Srstone 134263109Srstone sc = device_get_softc(dev); 135263109Srstone 136263109Srstone if (!puc_msi_disable) { 137263109Srstone count = 1; 138263109Srstone 139263109Srstone if (pci_alloc_msi(dev, &count) == 0) { 140263109Srstone sc->sc_msi = 1; 141263109Srstone sc->sc_irid = 1; 142263109Srstone } 143263109Srstone } 144263109Srstone 145263109Srstone error = puc_bfe_attach(dev); 146263109Srstone 147263109Srstone if (error != 0 && sc->sc_msi) 148263109Srstone pci_release_msi(dev); 149263109Srstone 150263109Srstone return (error); 151263109Srstone} 152263109Srstone 153263109Srstonestatic int 154263109Srstonepuc_pci_detach(device_t dev) 155263109Srstone{ 156263109Srstone struct puc_softc *sc; 157263109Srstone int error; 158263109Srstone 159263109Srstone sc = device_get_softc(dev); 160263109Srstone 161263109Srstone error = puc_bfe_detach(dev); 162263109Srstone 163263109Srstone if (error != 0) 164263109Srstone return (error); 165263109Srstone 166263109Srstone if (sc->sc_msi) 167263109Srstone error = pci_release_msi(dev); 168263109Srstone 169263109Srstone return (error); 170263109Srstone} 171263109Srstone 172263109Srstone 173102714Sphkstatic device_method_t puc_pci_methods[] = { 174102714Sphk /* Device interface */ 175102714Sphk DEVMETHOD(device_probe, puc_pci_probe), 176263109Srstone DEVMETHOD(device_attach, puc_pci_attach), 177263109Srstone DEVMETHOD(device_detach, puc_pci_detach), 178102714Sphk 179158124Smarcel DEVMETHOD(bus_alloc_resource, puc_bus_alloc_resource), 180158124Smarcel DEVMETHOD(bus_release_resource, puc_bus_release_resource), 181158124Smarcel DEVMETHOD(bus_get_resource, puc_bus_get_resource), 182158124Smarcel DEVMETHOD(bus_read_ivar, puc_bus_read_ivar), 183158124Smarcel DEVMETHOD(bus_setup_intr, puc_bus_setup_intr), 184158124Smarcel DEVMETHOD(bus_teardown_intr, puc_bus_teardown_intr), 185223091Sjhb DEVMETHOD(bus_print_child, puc_bus_print_child), 186223091Sjhb DEVMETHOD(bus_child_pnpinfo_str, puc_bus_child_pnpinfo_str), 187223091Sjhb DEVMETHOD(bus_child_location_str, puc_bus_child_location_str), 188227843Smarius 189227843Smarius DEVMETHOD_END 190102714Sphk}; 191102714Sphk 192102714Sphkstatic driver_t puc_pci_driver = { 193158124Smarcel puc_driver_name, 194102714Sphk puc_pci_methods, 195102714Sphk sizeof(struct puc_softc), 196102714Sphk}; 197102714Sphk 198102714SphkDRIVER_MODULE(puc, pci, puc_pci_driver, puc_devclass, 0, 0); 199