pccbb_isa.c revision 139749
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 139749 2005-01-06 01:43:34Z 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_DEPEND(cbb, exca, 1, 1, 1);
221