pccbb_isa.c revision 133553
1/* 2 * Copyright (c) 2002-2004 M. Warner Losh. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions, and the following disclaimer, 10 * without modification, immediately at the beginning of the file. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29/* 30 * Driver for ISA to PCMCIA bridges compliant with the Intel ExCA 31 * specification. 32 */ 33 34#include <sys/cdefs.h> 35__FBSDID("$FreeBSD: head/sys/dev/pccbb/pccbb_isa.c 133553 2004-08-12 06:50:29Z imp $"); 36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/proc.h> 40#include <sys/condvar.h> 41#include <sys/errno.h> 42#include <sys/kernel.h> 43#include <sys/lock.h> 44#include <sys/malloc.h> 45#include <sys/module.h> 46#include <sys/mutex.h> 47#include <sys/sysctl.h> 48#include <sys/kthread.h> 49#include <sys/bus.h> 50#include <machine/bus.h> 51#include <sys/rman.h> 52#include <machine/resource.h> 53 54#include <isa/isavar.h> 55 56#include <dev/pccard/pccardreg.h> 57#include <dev/pccard/pccardvar.h> 58 59#include <dev/exca/excareg.h> 60#include <dev/exca/excavar.h> 61 62#include <dev/pccbb/pccbbreg.h> 63#include <dev/pccbb/pccbbvar.h> 64 65#include "power_if.h" 66#include "card_if.h" 67 68/***************************************************************************** 69 * Configurable parameters. 70 *****************************************************************************/ 71 72/* sysctl vars */ 73SYSCTL_NODE(_hw, OID_AUTO, pcic, CTLFLAG_RD, 0, "PCIC parameters"); 74 75static int isa_intr_mask = EXCA_INT_MASK_ALLOWED; 76TUNABLE_INT("hw.cbb.intr_mask", &isa_intr_mask); 77SYSCTL_INT(_hw_pcic, OID_AUTO, intr_mask, CTLFLAG_RD, &isa_intr_mask, 0, 78 "Mask of allowable interrupts for this laptop. The default is generally\n\ 79correct, but some laptops do not route all the IRQ pins to the bridge to\n\ 80save wires. Sometimes you need a more restrictive mask because some of the\n\ 81hardware in your laptop may not have a driver so its IRQ might not be\n\ 82allocated."); 83 84/***************************************************************************** 85 * End of configurable parameters. 86 *****************************************************************************/ 87 88#define DPRINTF(x) do { if (cbb_debug) printf x; } while (0) 89#define DEVPRINTF(x) do { if (cbb_debug) device_printf x; } while (0) 90 91static struct isa_pnp_id pcic_ids[] = { 92 {EXCA_PNP_ACTIONTEC, NULL}, /* AEI0218 */ 93 {EXCA_PNP_IBM3765, NULL}, /* IBM3765 */ 94 {EXCA_PNP_82365, NULL}, /* PNP0E00 */ 95 {EXCA_PNP_CL_PD6720, NULL}, /* PNP0E01 */ 96 {EXCA_PNP_VLSI_82C146, NULL}, /* PNP0E02 */ 97 {EXCA_PNP_82365_CARDBUS, NULL}, /* PNP0E03 */ 98 {EXCA_PNP_SCM_SWAPBOX, NULL}, /* SCM0469 */ 99 {0} 100}; 101 102/************************************************************************/ 103/* Probe/Attach */ 104/************************************************************************/ 105 106#if 0 107 struct resource *res; 108 int rid; 109 int i; 110 111 /* A little bogus, but go ahead and get the irq for CSC events */ 112 rid = 0; 113 res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); 114 if (res == NULL) { 115 /* 116 * No IRQ specified, find one. This can be due to the PnP 117 * data not specifying any IRQ, or the default kernel not 118 * assinging an IRQ. 119 */ 120 for (i = 0; i < 16; i++) { 121 if (((1 << i) & isa_intr_mask) == 0) 122 continue; 123 res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, i, i, 124 1, RF_ACTIVE); 125 if (res != NULL) 126 break; 127 } 128 if (res == NULL) 129 return (ENXIO); 130 bus_release_resource(dev, SYS_RES_IRQ, rid, res); 131 bus_set_resource(dev, SYS_RES_IRQ, 0, i, 1); 132 } else { 133 bus_release_resource(dev, SYS_RES_IRQ, rid, res); 134 } 135 if (res == NULL) { 136 device_printf(dev, "Cannot allocate mem\n"); 137 return (ENOMEM); 138 } 139#endif 140 141static int 142cbb_isa_activate(device_t dev) 143{ 144 return (ENOMEM); 145} 146 147static void 148cbb_isa_deactivate(device_t dev) 149{ 150} 151 152static int 153cbb_isa_probe(device_t dev) 154{ 155 int error; 156 struct cbb_softc *sc = device_get_softc(dev); 157 158 /* Check isapnp ids */ 159 error = ISA_PNP_PROBE(device_get_parent(dev), dev, pcic_ids); 160 if (error != 0 && error != ENOENT) 161 return (error); 162 163 error = cbb_isa_activate(dev); 164 if (error != 0) 165 return (error); 166 167 /* Check to make sure that we have actual hardware */ 168 error = exca_probe_slots(dev, &sc->exca[0], sc->bst, sc->bsh); 169 cbb_isa_deactivate(dev); 170 return (error); 171} 172 173static int 174cbb_isa_attach(device_t dev) 175{ 176 return (ENOMEM); 177} 178 179static device_method_t cbb_methods[] = { 180 /* Device interface */ 181 DEVMETHOD(device_probe, cbb_isa_probe), 182 DEVMETHOD(device_attach, cbb_isa_attach), 183 DEVMETHOD(device_detach, cbb_detach), 184 DEVMETHOD(device_shutdown, cbb_shutdown), 185 DEVMETHOD(device_suspend, cbb_suspend), 186 DEVMETHOD(device_resume, cbb_resume), 187 188 /* bus methods */ 189 DEVMETHOD(bus_print_child, bus_generic_print_child), 190 DEVMETHOD(bus_read_ivar, cbb_read_ivar), 191 DEVMETHOD(bus_write_ivar, cbb_write_ivar), 192 DEVMETHOD(bus_alloc_resource, cbb_alloc_resource), 193 DEVMETHOD(bus_release_resource, cbb_release_resource), 194 DEVMETHOD(bus_activate_resource, cbb_activate_resource), 195 DEVMETHOD(bus_deactivate_resource, cbb_deactivate_resource), 196 DEVMETHOD(bus_driver_added, cbb_driver_added), 197 DEVMETHOD(bus_child_detached, cbb_child_detached), 198 DEVMETHOD(bus_setup_intr, cbb_setup_intr), 199 DEVMETHOD(bus_teardown_intr, cbb_teardown_intr), 200 DEVMETHOD(bus_child_present, cbb_child_present), 201 202 /* 16-bit card interface */ 203 DEVMETHOD(card_set_res_flags, cbb_pcic_set_res_flags), 204 DEVMETHOD(card_set_memory_offset, cbb_pcic_set_memory_offset), 205 206 /* power interface */ 207 DEVMETHOD(power_enable_socket, cbb_power_enable_socket), 208 DEVMETHOD(power_disable_socket, cbb_power_disable_socket), 209 210 {0,0} 211}; 212 213static driver_t cbb_isa_driver = { 214 "cbb", 215 cbb_methods, 216 sizeof(struct cbb_softc) 217}; 218 219DRIVER_MODULE(cbb, isa, cbb_isa_driver, cbb_devclass, 0, 0); 220MODULE_VERSION(cbb, 1); 221MODULE_DEPEND(cbb, exca, 1, 1, 1); 222