pccbb_isa.c revision 140035
1139749Simp/*- 2133553Simp * Copyright (c) 2002-2004 M. Warner Losh. 3133553Simp * All rights reserved. 4133553Simp * 5133553Simp * Redistribution and use in source and binary forms, with or without 6133553Simp * modification, are permitted provided that the following conditions 7133553Simp * are met: 8133553Simp * 1. Redistributions of source code must retain the above copyright 9140035Simp * notice, this list of conditions and the following disclaimer. 10133553Simp * 2. Redistributions in binary form must reproduce the above copyright 11140035Simp * notice, this list of conditions and the following disclaimer in the 12140035Simp * documentation and/or other materials provided with the distribution. 13133553Simp * 14133553Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15133553Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16133553Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17140035Simp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18140035Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19133553Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20133553Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21133553Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22133553Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23133553Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24133553Simp * SUCH DAMAGE. 25133553Simp */ 26133553Simp 27133553Simp/* 28133553Simp * Driver for ISA to PCMCIA bridges compliant with the Intel ExCA 29133553Simp * specification. 30133553Simp */ 31133553Simp 32133553Simp#include <sys/cdefs.h> 33133553Simp__FBSDID("$FreeBSD: head/sys/dev/pccbb/pccbb_isa.c 140035 2005-01-11 05:33:18Z imp $"); 34133553Simp 35133553Simp#include <sys/param.h> 36133553Simp#include <sys/systm.h> 37133553Simp#include <sys/proc.h> 38133553Simp#include <sys/condvar.h> 39133553Simp#include <sys/errno.h> 40133553Simp#include <sys/kernel.h> 41133553Simp#include <sys/lock.h> 42133553Simp#include <sys/malloc.h> 43133553Simp#include <sys/module.h> 44133553Simp#include <sys/mutex.h> 45133553Simp#include <sys/sysctl.h> 46133553Simp#include <sys/kthread.h> 47133553Simp#include <sys/bus.h> 48133553Simp#include <machine/bus.h> 49133553Simp#include <sys/rman.h> 50133553Simp#include <machine/resource.h> 51133553Simp 52133553Simp#include <isa/isavar.h> 53133553Simp 54133553Simp#include <dev/pccard/pccardreg.h> 55133553Simp#include <dev/pccard/pccardvar.h> 56133553Simp 57133553Simp#include <dev/exca/excareg.h> 58133553Simp#include <dev/exca/excavar.h> 59133553Simp 60133553Simp#include <dev/pccbb/pccbbreg.h> 61133553Simp#include <dev/pccbb/pccbbvar.h> 62133553Simp 63133553Simp#include "power_if.h" 64133553Simp#include "card_if.h" 65133553Simp 66133553Simp/***************************************************************************** 67133553Simp * Configurable parameters. 68133553Simp *****************************************************************************/ 69133553Simp 70133553Simp/* sysctl vars */ 71133553SimpSYSCTL_NODE(_hw, OID_AUTO, pcic, CTLFLAG_RD, 0, "PCIC parameters"); 72133553Simp 73133553Simpstatic int isa_intr_mask = EXCA_INT_MASK_ALLOWED; 74133553SimpTUNABLE_INT("hw.cbb.intr_mask", &isa_intr_mask); 75133553SimpSYSCTL_INT(_hw_pcic, OID_AUTO, intr_mask, CTLFLAG_RD, &isa_intr_mask, 0, 76133553Simp "Mask of allowable interrupts for this laptop. The default is generally\n\ 77133553Simpcorrect, but some laptops do not route all the IRQ pins to the bridge to\n\ 78133553Simpsave wires. Sometimes you need a more restrictive mask because some of the\n\ 79133553Simphardware in your laptop may not have a driver so its IRQ might not be\n\ 80133553Simpallocated."); 81133553Simp 82133553Simp/***************************************************************************** 83133553Simp * End of configurable parameters. 84133553Simp *****************************************************************************/ 85133553Simp 86133553Simp#define DPRINTF(x) do { if (cbb_debug) printf x; } while (0) 87133553Simp#define DEVPRINTF(x) do { if (cbb_debug) device_printf x; } while (0) 88133553Simp 89133553Simpstatic struct isa_pnp_id pcic_ids[] = { 90133553Simp {EXCA_PNP_ACTIONTEC, NULL}, /* AEI0218 */ 91133553Simp {EXCA_PNP_IBM3765, NULL}, /* IBM3765 */ 92133553Simp {EXCA_PNP_82365, NULL}, /* PNP0E00 */ 93133553Simp {EXCA_PNP_CL_PD6720, NULL}, /* PNP0E01 */ 94133553Simp {EXCA_PNP_VLSI_82C146, NULL}, /* PNP0E02 */ 95133553Simp {EXCA_PNP_82365_CARDBUS, NULL}, /* PNP0E03 */ 96133553Simp {EXCA_PNP_SCM_SWAPBOX, NULL}, /* SCM0469 */ 97133553Simp {0} 98133553Simp}; 99133553Simp 100133553Simp/************************************************************************/ 101133553Simp/* Probe/Attach */ 102133553Simp/************************************************************************/ 103133553Simp 104133553Simp#if 0 105133553Simp struct resource *res; 106133553Simp int rid; 107133553Simp int i; 108133553Simp 109133553Simp /* A little bogus, but go ahead and get the irq for CSC events */ 110133553Simp rid = 0; 111133553Simp res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); 112133553Simp if (res == NULL) { 113133553Simp /* 114133553Simp * No IRQ specified, find one. This can be due to the PnP 115133553Simp * data not specifying any IRQ, or the default kernel not 116133553Simp * assinging an IRQ. 117133553Simp */ 118133553Simp for (i = 0; i < 16; i++) { 119133553Simp if (((1 << i) & isa_intr_mask) == 0) 120133553Simp continue; 121133553Simp res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, i, i, 122133553Simp 1, RF_ACTIVE); 123133553Simp if (res != NULL) 124133553Simp break; 125133553Simp } 126133553Simp if (res == NULL) 127133553Simp return (ENXIO); 128133553Simp bus_release_resource(dev, SYS_RES_IRQ, rid, res); 129133553Simp bus_set_resource(dev, SYS_RES_IRQ, 0, i, 1); 130133553Simp } else { 131133553Simp bus_release_resource(dev, SYS_RES_IRQ, rid, res); 132133553Simp } 133133553Simp if (res == NULL) { 134133553Simp device_printf(dev, "Cannot allocate mem\n"); 135133553Simp return (ENOMEM); 136133553Simp } 137133553Simp#endif 138133553Simp 139133553Simpstatic int 140133553Simpcbb_isa_activate(device_t dev) 141133553Simp{ 142133553Simp return (ENOMEM); 143133553Simp} 144133553Simp 145133553Simpstatic void 146133553Simpcbb_isa_deactivate(device_t dev) 147133553Simp{ 148133553Simp} 149133553Simp 150133553Simpstatic int 151133553Simpcbb_isa_probe(device_t dev) 152133553Simp{ 153133553Simp int error; 154133553Simp struct cbb_softc *sc = device_get_softc(dev); 155133553Simp 156133553Simp /* Check isapnp ids */ 157133553Simp error = ISA_PNP_PROBE(device_get_parent(dev), dev, pcic_ids); 158133553Simp if (error != 0 && error != ENOENT) 159133553Simp return (error); 160133553Simp 161133553Simp error = cbb_isa_activate(dev); 162133553Simp if (error != 0) 163133553Simp return (error); 164133553Simp 165133553Simp /* Check to make sure that we have actual hardware */ 166133553Simp error = exca_probe_slots(dev, &sc->exca[0], sc->bst, sc->bsh); 167133553Simp cbb_isa_deactivate(dev); 168133553Simp return (error); 169133553Simp} 170133553Simp 171133553Simpstatic int 172133553Simpcbb_isa_attach(device_t dev) 173133553Simp{ 174133553Simp return (ENOMEM); 175133553Simp} 176133553Simp 177133553Simpstatic device_method_t cbb_methods[] = { 178133553Simp /* Device interface */ 179133553Simp DEVMETHOD(device_probe, cbb_isa_probe), 180133553Simp DEVMETHOD(device_attach, cbb_isa_attach), 181133553Simp DEVMETHOD(device_detach, cbb_detach), 182133553Simp DEVMETHOD(device_shutdown, cbb_shutdown), 183133553Simp DEVMETHOD(device_suspend, cbb_suspend), 184133553Simp DEVMETHOD(device_resume, cbb_resume), 185133553Simp 186133553Simp /* bus methods */ 187133553Simp DEVMETHOD(bus_print_child, bus_generic_print_child), 188133553Simp DEVMETHOD(bus_read_ivar, cbb_read_ivar), 189133553Simp DEVMETHOD(bus_write_ivar, cbb_write_ivar), 190133553Simp DEVMETHOD(bus_alloc_resource, cbb_alloc_resource), 191133553Simp DEVMETHOD(bus_release_resource, cbb_release_resource), 192133553Simp DEVMETHOD(bus_activate_resource, cbb_activate_resource), 193133553Simp DEVMETHOD(bus_deactivate_resource, cbb_deactivate_resource), 194133553Simp DEVMETHOD(bus_driver_added, cbb_driver_added), 195133553Simp DEVMETHOD(bus_child_detached, cbb_child_detached), 196133553Simp DEVMETHOD(bus_setup_intr, cbb_setup_intr), 197133553Simp DEVMETHOD(bus_teardown_intr, cbb_teardown_intr), 198133553Simp DEVMETHOD(bus_child_present, cbb_child_present), 199133553Simp 200133553Simp /* 16-bit card interface */ 201133553Simp DEVMETHOD(card_set_res_flags, cbb_pcic_set_res_flags), 202133553Simp DEVMETHOD(card_set_memory_offset, cbb_pcic_set_memory_offset), 203133553Simp 204133553Simp /* power interface */ 205133553Simp DEVMETHOD(power_enable_socket, cbb_power_enable_socket), 206133553Simp DEVMETHOD(power_disable_socket, cbb_power_disable_socket), 207133553Simp 208133553Simp {0,0} 209133553Simp}; 210133553Simp 211133553Simpstatic driver_t cbb_isa_driver = { 212133553Simp "cbb", 213133553Simp cbb_methods, 214133553Simp sizeof(struct cbb_softc) 215133553Simp}; 216133553Simp 217133553SimpDRIVER_MODULE(cbb, isa, cbb_isa_driver, cbb_devclass, 0, 0); 218133553SimpMODULE_DEPEND(cbb, exca, 1, 1, 1); 219