pccbb_isa.c revision 133553
168651Skris/*
268651Skris * Copyright (c) 2002-2004 M. Warner Losh.
368651Skris * All rights reserved.
468651Skris *
568651Skris * Redistribution and use in source and binary forms, with or without
668651Skris * modification, are permitted provided that the following conditions
768651Skris * are met:
868651Skris * 1. Redistributions of source code must retain the above copyright
968651Skris *    notice, this list of conditions, and the following disclaimer,
1068651Skris *    without modification, immediately at the beginning of the file.
1168651Skris * 2. Redistributions in binary form must reproduce the above copyright
1268651Skris *    notice, this list of conditions and the following disclaimer in
1368651Skris *    the documentation and/or other materials provided with the
1468651Skris *    distribution.
1568651Skris *
1668651Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1768651Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1876866Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1968651Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
2068651Skris * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2168651Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2268651Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2368651Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2468651Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2568651Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2668651Skris * SUCH DAMAGE.
2768651Skris */
2868651Skris
2968651Skris/*
3068651Skris * Driver for ISA to PCMCIA bridges compliant with the Intel ExCA
3168651Skris * specification.
3268651Skris */
3368651Skris
3468651Skris#include <sys/cdefs.h>
3568651Skris__FBSDID("$FreeBSD: head/sys/dev/pccbb/pccbb_isa.c 133553 2004-08-12 06:50:29Z imp $");
3668651Skris
3768651Skris#include <sys/param.h>
3868651Skris#include <sys/systm.h>
3968651Skris#include <sys/proc.h>
4068651Skris#include <sys/condvar.h>
4168651Skris#include <sys/errno.h>
4268651Skris#include <sys/kernel.h>
4368651Skris#include <sys/lock.h>
4468651Skris#include <sys/malloc.h>
4568651Skris#include <sys/module.h>
4668651Skris#include <sys/mutex.h>
4768651Skris#include <sys/sysctl.h>
4868651Skris#include <sys/kthread.h>
4968651Skris#include <sys/bus.h>
5068651Skris#include <machine/bus.h>
5168651Skris#include <sys/rman.h>
5268651Skris#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