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