xref: /freebsd/sys/dev/pccbb/pccbb.c (revision 91bd71d2060cd302015f7dd6e7b891014552dba4)
1 /*
2  * Copyright (c) 2000,2001 Jonathan Chen.
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  * $FreeBSD$
29  */
30 
31 /*
32  * Driver for PCI to Cardbus Bridge chips
33  *
34  * References:
35  *  TI Datasheets:
36  *   http://www-s.ti.com/cgi-bin/sc/generic2.cgi?family=PCI+CARDBUS+CONTROLLERS
37  *
38  * Written by Jonathan Chen <jon@freebsd.org>
39  * The author would like to acknowledge:
40  *  * HAYAKAWA Koichi: Author of the NetBSD code for the same thing
41  *  * Warner Losh: Newbus/newcard guru and author of the pccard side of things
42  *  * YAMAMOTO Shigeru: Author of another FreeBSD cardbus driver
43  *  * David Cross: Author of the initial ugly hack for a specific cardbus card
44  */
45 
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/errno.h>
49 #include <sys/kernel.h>
50 #include <sys/kthread.h>
51 #include <sys/lock.h>
52 #include <sys/malloc.h>
53 #include <sys/mutex.h>
54 #include <sys/sysctl.h>
55 
56 #include <sys/bus.h>
57 #include <machine/bus.h>
58 #include <sys/rman.h>
59 #include <machine/resource.h>
60 
61 #include <pci/pcireg.h>
62 #include <pci/pcivar.h>
63 #include <machine/clock.h>
64 
65 #include <dev/pccard/pccardreg.h>
66 #include <dev/pccard/pccardvar.h>
67 
68 #include <dev/exca/excareg.h>
69 #include <dev/exca/excavar.h>
70 
71 #include <dev/pccbb/pccbbreg.h>
72 #include <dev/pccbb/pccbbvar.h>
73 
74 #include "power_if.h"
75 #include "card_if.h"
76 #include "pcib_if.h"
77 
78 #if defined CBB_DEBUG
79 #define	DPRINTF(x) printf x
80 #define	DEVPRINTF(x) device_printf x
81 #else
82 #define	DPRINTF(x)
83 #define	DEVPRINTF(x)
84 #endif
85 
86 #define	PCI_MASK_CONFIG(DEV,REG,MASK,SIZE)				\
87 	pci_write_config(DEV, REG, pci_read_config(DEV, REG, SIZE) MASK, SIZE)
88 #define	PCI_MASK2_CONFIG(DEV,REG,MASK1,MASK2,SIZE)			\
89 	pci_write_config(DEV, REG, (					\
90 		pci_read_config(DEV, REG, SIZE) MASK1) MASK2, SIZE)
91 
92 #define PCCBB_START_MEM	0x84000000
93 #define PCCBB_START_IO 0x1000
94 
95 struct pccbb_sclist {
96 	struct	pccbb_softc *sc;
97 	STAILQ_ENTRY(pccbb_sclist) entries;
98 };
99 
100 static STAILQ_HEAD(, pccbb_sclist) softcs;
101 static int softcs_init = 0;
102 
103 struct yenta_chipinfo {
104 	uint32_t yc_id;
105 	const	char *yc_name;
106 	int	yc_chiptype;
107 	int	yc_flags;
108 } yc_chipsets[] = {
109 	/* Texas Instruments chips */
110 	{PCI_DEVICE_ID_PCIC_TI1031, "TI1031 PCI-PCCard Bridge", CB_TI113X, 0},
111 	{PCI_DEVICE_ID_PCIC_TI1130, "TI1130 PCI-CardBus Bridge", CB_TI113X, 0},
112 	{PCI_DEVICE_ID_PCIC_TI1131, "TI1131 PCI-CardBus Bridge", CB_TI113X, 0},
113 
114 	{PCI_DEVICE_ID_PCIC_TI1210, "TI1210 PCI-CardBus Bridge", CB_TI12XX, 0},
115 	{PCI_DEVICE_ID_PCIC_TI1211, "TI1211 PCI-CardBus Bridge", CB_TI12XX, 0},
116 	{PCI_DEVICE_ID_PCIC_TI1220, "TI1220 PCI-CardBus Bridge", CB_TI12XX, 0},
117 	{PCI_DEVICE_ID_PCIC_TI1221, "TI1221 PCI-CardBus Bridge", CB_TI12XX, 0},
118 	{PCI_DEVICE_ID_PCIC_TI1225, "TI1225 PCI-CardBus Bridge", CB_TI12XX, 0},
119 	{PCI_DEVICE_ID_PCIC_TI1250, "TI1250 PCI-CardBus Bridge", CB_TI12XX, 0},
120 	{PCI_DEVICE_ID_PCIC_TI1251, "TI1251 PCI-CardBus Bridge", CB_TI12XX, 0},
121 	{PCI_DEVICE_ID_PCIC_TI1251B,"TI1251B PCI-CardBus Bridge",CB_TI12XX, 0},
122 	{PCI_DEVICE_ID_PCIC_TI1260, "TI1260 PCI-CardBus Bridge", CB_TI12XX, 0},
123 	{PCI_DEVICE_ID_PCIC_TI1260B, "TI1260B PCI-CardBus Bridge", CB_TI12XX,
124 	    0},
125 	{PCI_DEVICE_ID_PCIC_TI1410, "TI1410 PCI-CardBus Bridge", CB_TI12XX, 0},
126 	{PCI_DEVICE_ID_PCIC_TI1420, "TI1420 PCI-CardBus Bridge", CB_TI12XX, 0},
127 	{PCI_DEVICE_ID_PCIC_TI1421, "TI1421 PCI-CardBus Bridge", CB_TI12XX, 0},
128 	{PCI_DEVICE_ID_PCIC_TI1450, "TI1450 PCI-CardBus Bridge", CB_TI12XX, 0},
129 	{PCI_DEVICE_ID_PCIC_TI1451, "TI1451 PCI-CardBus Bridge", CB_TI12XX, 0},
130 	{PCI_DEVICE_ID_PCIC_TI4410, "TI4410 PCI-CardBus Bridge", CB_TI12XX, 0},
131 	{PCI_DEVICE_ID_PCIC_TI4450, "TI4450 PCI-CardBus Bridge", CB_TI12XX, 0},
132 	{PCI_DEVICE_ID_PCIC_TI4451, "TI4451 PCI-CardBus Bridge", CB_TI12XX, 0},
133 
134 	/* Ricoh chips */
135 	{PCI_DEVICE_ID_RICOH_RL5C465, "RF5C465 PCI-CardBus Bridge",
136 	    CB_RF5C46X, 0},
137 	{PCI_DEVICE_ID_RICOH_RL5C466, "RF5C466 PCI-CardBus Bridge",
138 	    CB_RF5C46X, 0},
139 	{PCI_DEVICE_ID_RICOH_RL5C475, "RF5C475 PCI-CardBus Bridge",
140 	    CB_RF5C47X, 0},
141 	{PCI_DEVICE_ID_RICOH_RL5C476, "RF5C476 PCI-CardBus Bridge",
142 	    CB_RF5C47X, 0},
143 	{PCI_DEVICE_ID_RICOH_RL5C478, "RF5C478 PCI-CardBus Bridge",
144 	    CB_RF5C47X, 0},
145 
146 	/* Toshiba products */
147 	{PCI_DEVICE_ID_TOSHIBA_TOPIC95, "ToPIC95 PCI-CardBus Bridge",
148 	    CB_TOPIC95, 0},
149 	{PCI_DEVICE_ID_TOSHIBA_TOPIC95B, "ToPIC95B PCI-CardBus Bridge",
150 	    CB_TOPIC95B, 0},
151 	{PCI_DEVICE_ID_TOSHIBA_TOPIC97, "ToPIC97 PCI-CardBus Bridge",
152 	    CB_TOPIC97, 0},
153 	{PCI_DEVICE_ID_TOSHIBA_TOPIC100, "ToPIC100 PCI-CardBus Bridge",
154 	    CB_TOPIC97, 0},
155 
156 	/* Cirrus Logic */
157 	{PCI_DEVICE_ID_PCIC_CLPD6832, "CLPD6832 PCI-CardBus Bridge",
158 	    CB_CIRRUS, 0},
159 	{PCI_DEVICE_ID_PCIC_CLPD6833, "CLPD6833 PCI-CardBus Bridge",
160 	    CB_CIRRUS, 0},
161 	{PCI_DEVICE_ID_PCIC_CLPD6834, "CLPD6834 PCI-CardBus Bridge",
162 	    CB_CIRRUS, 0},
163 
164 	/* 02Micro */
165 	{PCI_DEVICE_ID_PCIC_OZ6832, "O2Mirco OZ6832/6833 PCI-CardBus Bridge",
166 	    CB_CIRRUS, 0},
167 	{PCI_DEVICE_ID_PCIC_OZ6860, "O2Mirco OZ6836/6860 PCI-CardBus Bridge",
168 	    CB_CIRRUS, 0},
169 	{PCI_DEVICE_ID_PCIC_OZ6872, "O2Mirco OZ6812/6872 PCI-CardBus Bridge",
170 	    CB_CIRRUS, 0},
171 	{PCI_DEVICE_ID_PCIC_OZ6912, "O2Mirco OZ6912/6972 PCI-CardBus Bridge",
172 	    CB_CIRRUS, 0},
173 	{PCI_DEVICE_ID_PCIC_OZ6922, "O2Mirco OZ6822 PCI-CardBus Bridge",
174 	    CB_CIRRUS, 0},
175 	{PCI_DEVICE_ID_PCIC_OZ6933, "O2Mirco OZ6833 PCI-CardBus Bridge",
176 	    CB_CIRRUS, 0},
177 
178 	/* sentinel */
179 	{0 /* null id */, "unknown",
180 	    CB_UNKNOWN, 0},
181 };
182 
183 /* sysctl vars */
184 SYSCTL_NODE(_hw, OID_AUTO, pccbb, CTLFLAG_RD, 0, "PCCBB parameters");
185 
186 /* There's no way to say TUNEABLE_LONG to get the right types */
187 u_long pccbb_start_mem = PCCBB_START_MEM;
188 TUNABLE_INT("hw.pccbb.start_memory", (int *)&pccbb_start_mem);
189 SYSCTL_ULONG(_hw_pccbb, OID_AUTO, start_mem, CTLFLAG_RD,
190     &pccbb_start_mem, PCCBB_START_MEM,
191     "Starting address for memory allocations");
192 
193 static int	pccbb_chipset(uint32_t pci_id, const char **namep, int *flagp);
194 static int	pccbb_probe(device_t brdev);
195 static void	pccbb_chipinit(struct pccbb_softc *sc);
196 static int	pccbb_attach(device_t brdev);
197 static int	pccbb_detach(device_t brdev);
198 static int	pccbb_shutdown(device_t brdev);
199 static void	pccbb_driver_added(device_t brdev, driver_t *driver);
200 static void	pccbb_child_detached(device_t brdev, device_t child);
201 static int	pccbb_card_reprobe(device_t brdev, device_t busdev);
202 static void	pccbb_event_thread(void *arg);
203 static void	pccbb_create_event_thread(struct pccbb_softc *sc);
204 static void	pccbb_start_threads(void *arg);
205 static void	pccbb_insert(struct pccbb_softc *sc);
206 static void	pccbb_removal(struct pccbb_softc *sc);
207 static void	pccbb_intr(void *arg);
208 static int	pccbb_detect_voltage(device_t brdev);
209 static int	pccbb_power(device_t brdev, int volts);
210 static void	pccbb_cardbus_reset(device_t brdev);
211 static int	pccbb_cardbus_power_enable_socket(device_t brdev,
212 		    device_t child);
213 static void	pccbb_cardbus_power_disable_socket(device_t brdev,
214 		    device_t child);
215 static int	pccbb_cardbus_io_open(device_t brdev, int win, uint32_t start,
216 		    uint32_t end);
217 static int	pccbb_cardbus_mem_open(device_t brdev, int win,
218 		    uint32_t start, uint32_t end);
219 static void	pccbb_cardbus_auto_open(struct pccbb_softc *sc, int type);
220 static int	pccbb_cardbus_activate_resource(device_t brdev, device_t child,
221 		    int type, int rid, struct resource *res);
222 static int	pccbb_cardbus_deactivate_resource(device_t brdev,
223 		    device_t child, int type, int rid, struct resource *res);
224 static struct resource	*pccbb_cardbus_alloc_resource(device_t brdev,
225 		    device_t child, int type, int *rid, u_long start,
226 		    u_long end, u_long count, uint flags);
227 static int	pccbb_cardbus_release_resource(device_t brdev, device_t child,
228 		    int type, int rid, struct resource *res);
229 static int	pccbb_power_enable_socket(device_t brdev, device_t child);
230 static void	pccbb_power_disable_socket(device_t brdev, device_t child);
231 static int	pccbb_activate_resource(device_t brdev, device_t child,
232 		    int type, int rid, struct resource *r);
233 static int	pccbb_deactivate_resource(device_t brdev, device_t child,
234 		    int type, int rid, struct resource *r);
235 static struct resource	*pccbb_alloc_resource(device_t brdev, device_t child,
236 		    int type, int *rid, u_long start, u_long end, u_long count,
237 		    uint flags);
238 static int	pccbb_release_resource(device_t brdev, device_t child,
239 		    int type, int rid, struct resource *r);
240 static int	pccbb_read_ivar(device_t brdev, device_t child, int which,
241 		    uintptr_t *result);
242 static int	pccbb_write_ivar(device_t brdev, device_t child, int which,
243 		    uintptr_t value);
244 static int	pccbb_maxslots(device_t brdev);
245 static uint32_t pccbb_read_config(device_t brdev, int b, int s, int f,
246 		    int reg, int width);
247 static void	pccbb_write_config(device_t brdev, int b, int s, int f,
248 		    int reg, uint32_t val, int width);
249 
250 /*
251  */
252 static __inline void
253 pccbb_set(struct pccbb_softc *sc, uint32_t reg, uint32_t val)
254 {
255 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, reg, val);
256 }
257 
258 static __inline uint32_t
259 pccbb_get(struct pccbb_softc *sc, uint32_t reg)
260 {
261 	return (bus_space_read_4(sc->sc_bst, sc->sc_bsh, reg));
262 }
263 
264 static __inline void
265 pccbb_setb(struct pccbb_softc *sc, uint32_t reg, uint32_t bits)
266 {
267 	pccbb_set(sc, reg, pccbb_get(sc, reg) | bits);
268 }
269 
270 static __inline void
271 pccbb_clrb(struct pccbb_softc *sc, uint32_t reg, uint32_t bits)
272 {
273 	pccbb_set(sc, reg, pccbb_get(sc, reg) & ~bits);
274 }
275 
276 static __inline uint8_t
277 pccbb_pcic_read(struct exca_softc *sc, int reg)
278 {
279 	return (bus_space_read_1(sc->bst, sc->bsh, sc->offset + reg));
280 }
281 
282 static __inline void
283 pccbb_pcic_write(struct exca_softc *sc, int reg, uint8_t val)
284 {
285 	return (bus_space_write_1(sc->bst, sc->bsh, sc->offset + reg, val));
286 }
287 
288 static void
289 pccbb_remove_res(struct pccbb_softc *sc, struct resource *res)
290 {
291 	struct pccbb_reslist *rle;
292 
293 	SLIST_FOREACH(rle, &sc->rl, link) {
294 		if (rle->res == res) {
295 			SLIST_REMOVE(&sc->rl, rle, pccbb_reslist, link);
296 			free(rle, M_DEVBUF);
297 			return;
298 		}
299 	}
300 }
301 
302 static struct resource *
303 pccbb_find_res(struct pccbb_softc *sc, int type, int rid)
304 {
305 	struct pccbb_reslist *rle;
306 
307 	SLIST_FOREACH(rle, &sc->rl, link)
308 		if (SYS_RES_MEMORY == rle->type && rid == rle->rid)
309 			return (rle->res);
310 	return (NULL);
311 }
312 
313 static void
314 pccbb_insert_res(struct pccbb_softc *sc, struct resource *res, int type,
315     int rid)
316 {
317 	struct pccbb_reslist *rle;
318 
319 	/*
320 	 * Need to record allocated resource so we can iterate through
321 	 * it later.
322 	 */
323 	rle = malloc(sizeof(struct pccbb_reslist), M_DEVBUF, M_NOWAIT);
324 	if (!res)
325 		panic("pccbb_cardbus_alloc_resource: can't record entry!");
326 	rle->res = res;
327 	rle->type = type;
328 	rle->rid = rid;
329 	SLIST_INSERT_HEAD(&sc->rl, rle, link);
330 }
331 
332 static void
333 pccbb_destroy_res(struct pccbb_softc *sc)
334 {
335 	struct pccbb_reslist *rle;
336 
337 	while ((rle = SLIST_FIRST(&sc->rl)) != NULL) {
338 		device_printf(sc->sc_dev, "Danger Will Robinson: Resource "
339 		    "left allocated!  This is a bug... "
340 		    "(rid=%x, type=%d, addr=%lx)\n", rle->rid, rle->type,
341 		    rman_get_start(rle->res));
342 		SLIST_REMOVE_HEAD(&sc->rl, link);
343 		free(rle, M_DEVBUF);
344 	}
345 }
346 
347 /************************************************************************/
348 /* Probe/Attach								*/
349 /************************************************************************/
350 
351 static int
352 pccbb_chipset(uint32_t pci_id, const char **namep, int *flagp)
353 {
354 	int loopend = sizeof(yc_chipsets)/sizeof(yc_chipsets[0]);
355 	struct yenta_chipinfo *ycp, *ycend;
356 	ycend = yc_chipsets + loopend;
357 
358 	for (ycp = yc_chipsets; ycp < ycend && pci_id != ycp->yc_id; ++ycp)
359 	    continue;
360 	if (ycp == ycend)
361 		/* not found */
362 		ycp = yc_chipsets + loopend - 1; /* to point the sentinel */
363 	if (namep != NULL)
364 		*namep = ycp->yc_name;
365 	if (flagp != NULL)
366 		*flagp = ycp->yc_flags;
367 	return (ycp->yc_chiptype);
368 }
369 
370 static int
371 pccbb_probe(device_t brdev)
372 {
373 	const char *name;
374 
375 	if (pccbb_chipset(pci_get_devid(brdev), &name, NULL) == CB_UNKNOWN)
376 		return (ENXIO);
377 	device_set_desc(brdev, name);
378 	return (0);
379 }
380 
381 static void
382 pccbb_chipinit(struct pccbb_softc *sc)
383 {
384 	/* Set CardBus latency timer */
385 	if (pci_read_config(sc->sc_dev, PCIR_SECLAT_1, 1) < 0x20)
386 		pci_write_config(sc->sc_dev, PCIR_SECLAT_1, 0x20, 1);
387 
388 	/* Set PCI latency timer */
389 	if (pci_read_config(sc->sc_dev, PCIR_LATTIMER, 1) < 0x20)
390 		pci_write_config(sc->sc_dev, PCIR_LATTIMER, 0x20, 1);
391 
392 	/* Enable memory access */
393 	PCI_MASK_CONFIG(sc->sc_dev, PCIR_COMMAND,
394 	    | PCIM_CMD_MEMEN
395 	    | PCIM_CMD_PORTEN
396 	    | PCIM_CMD_BUSMASTEREN, 2);
397 
398 	/* disable Legacy IO */
399 	switch (sc->sc_chipset) {
400 	case CB_RF5C46X:
401 		PCI_MASK_CONFIG(sc->sc_dev, PCCBBR_BRIDGECTRL,
402 		    & ~(PCCBBM_BRIDGECTRL_RL_3E0_EN |
403 		    PCCBBM_BRIDGECTRL_RL_3E2_EN), 2);
404 		break;
405 	default:
406 		pci_write_config(sc->sc_dev, PCCBBR_LEGACY, 0x0, 4);
407 		break;
408 	}
409 
410 	/* Use PCI interrupt for interrupt routing */
411 	PCI_MASK2_CONFIG(sc->sc_dev, PCCBBR_BRIDGECTRL,
412 	    & ~(PCCBBM_BRIDGECTRL_MASTER_ABORT |
413 	    PCCBBM_BRIDGECTRL_INTR_IREQ_EN),
414 	    | PCCBBM_BRIDGECTRL_WRITE_POST_EN,
415 	    2);
416 
417 	/* XXX this should be a function table, ala OLDCARD. */
418 	switch (sc->sc_chipset) {
419 	case CB_TI113X:
420 		/*
421 		 * The TI 1031, TI 1130 and TI 1131 all require another bit
422 		 * be set to enable PCI routing of interrupts, and then
423 		 * a bit for each of the CSC and Function interrupts we
424 		 * want routed.
425 		 */
426 		PCI_MASK_CONFIG(sc->sc_dev, PCCBBR_CBCTRL,
427 		    | PCCBBM_CBCTRL_113X_PCI_INTR |
428 		    PCCBBM_CBCTRL_113X_PCI_CSC | PCCBBM_CBCTRL_113X_PCI_IRQ_EN,
429 		    1);
430 		PCI_MASK_CONFIG(sc->sc_dev, PCCBBR_DEVCTRL,
431 		    & ~(PCCBBM_DEVCTRL_INT_SERIAL |
432 		    PCCBBM_DEVCTRL_INT_PCI), 1);
433 		exca_write(&sc->exca, EXCA_INTR, EXCA_INTR_ENABLE);
434 		exca_write(&sc->exca, EXCA_CSC_INTR, 0);
435 		break;
436 	case CB_TI12XX:
437 		exca_write(&sc->exca, EXCA_INTR, EXCA_INTR_ENABLE);
438 		exca_write(&sc->exca, EXCA_CSC_INTR, 0);
439 		break;
440 	case CB_TOPIC95B:
441 		PCI_MASK_CONFIG(sc->sc_dev, PCCBBR_TOPIC_SOCKETCTRL,
442 		    | PCCBBM_TOPIC_SOCKETCTRL_SCR_IRQSEL, 4);
443 		PCI_MASK2_CONFIG(sc->sc_dev, PCCBBR_TOPIC_SLOTCTRL,
444 		    | PCCBBM_TOPIC_SLOTCTRL_SLOTON |
445 		    PCCBBM_TOPIC_SLOTCTRL_SLOTEN |
446 		    PCCBBM_TOPIC_SLOTCTRL_ID_LOCK |
447 		    PCCBBM_TOPIC_SLOTCTRL_CARDBUS,
448 		    & ~PCCBBM_TOPIC_SLOTCTRL_SWDETECT, 4);
449 		break;
450 	}
451 
452 	/* close all memory and io windows */
453 	pci_write_config(sc->sc_dev, PCCBBR_MEMBASE0, 0xffffffff, 4);
454 	pci_write_config(sc->sc_dev, PCCBBR_MEMLIMIT0, 0, 4);
455 	pci_write_config(sc->sc_dev, PCCBBR_MEMBASE1, 0xffffffff, 4);
456 	pci_write_config(sc->sc_dev, PCCBBR_MEMLIMIT1, 0, 4);
457 	pci_write_config(sc->sc_dev, PCCBBR_IOBASE0, 0xffffffff, 4);
458 	pci_write_config(sc->sc_dev, PCCBBR_IOLIMIT0, 0, 4);
459 	pci_write_config(sc->sc_dev, PCCBBR_IOBASE1, 0xffffffff, 4);
460 	pci_write_config(sc->sc_dev, PCCBBR_IOLIMIT1, 0, 4);
461 }
462 
463 static int
464 pccbb_attach(device_t brdev)
465 {
466 	struct pccbb_softc *sc = (struct pccbb_softc *)device_get_softc(brdev);
467 	int rid;
468 	uint32_t sockbase;
469 	struct pccbb_sclist *sclist;
470 
471 	if (!softcs_init) {
472 		softcs_init = 1;
473 		STAILQ_INIT(&softcs);
474 	}
475 	mtx_init(&sc->sc_mtx, device_get_nameunit(brdev), MTX_DEF);
476 	sc->sc_chipset = pccbb_chipset(pci_get_devid(brdev), NULL, &sc->sc_flags);
477 	sc->sc_dev = brdev;
478 	sc->sc_cbdev = NULL;
479 	sc->sc_pccarddev = NULL;
480 	sc->sc_secbus = pci_read_config(brdev, PCIR_SECBUS_2, 1);
481 	sc->sc_subbus = pci_read_config(brdev, PCIR_SUBBUS_2, 1);
482 	SLIST_INIT(&sc->rl);
483 
484 	/*
485 	 * The PCI bus code should assign us memory in the absense
486 	 * of the BIOS doing so.  However, 'should' isn't 'is,' so we hack
487 	 * up something here until the PCI code is up to snuff.
488 	 */
489 	rid = PCCBBR_SOCKBASE;
490 	sc->sc_base_res = bus_alloc_resource(brdev, SYS_RES_MEMORY, &rid,
491 	    0, ~0, 1, RF_ACTIVE);
492 	if (!sc->sc_base_res) {
493 		/*
494 		 * XXX EVILE HACK BAD THING! XXX
495 		 * The pci bus device should do this for us.
496 		 * Some BIOSes doesn't assign a memory space properly.
497 		 * So we try to manually put one in...
498 		 */
499 		sockbase = pci_read_config(brdev, rid, 4);
500 		if (sockbase < 0x100000 || sockbase >= 0xfffffff0) {
501 			pci_write_config(brdev, rid, 0xffffffff, 4);
502 			sockbase = pci_read_config(brdev, rid, 4);
503 			sockbase = (sockbase & 0xfffffff0) &
504 			    -(sockbase & 0xfffffff0);
505 			sc->sc_base_res = bus_generic_alloc_resource(
506 			    device_get_parent(brdev), brdev, SYS_RES_MEMORY,
507 			    &rid, pccbb_start_mem, ~0, sockbase,
508 			    RF_ACTIVE|rman_make_alignment_flags(sockbase));
509 			if (!sc->sc_base_res){
510 				device_printf(brdev,
511 				    "Could not grab register memory\n");
512 				mtx_destroy(&sc->sc_mtx);
513 				return (ENOMEM);
514 			}
515 			pci_write_config(brdev, PCCBBR_SOCKBASE,
516 			    rman_get_start(sc->sc_base_res), 4);
517 			DEVPRINTF((brdev, "PCI Memory allocated: %08lx\n",
518 			    rman_get_start(sc->sc_base_res)));
519 		} else {
520 			device_printf(brdev, "Could not map register memory\n");
521 			mtx_destroy(&sc->sc_mtx);
522 			return (ENOMEM);
523 		}
524 	}
525 
526 	sc->sc_bst = rman_get_bustag(sc->sc_base_res);
527 	sc->sc_bsh = rman_get_bushandle(sc->sc_base_res);
528 	exca_init(&sc->exca, brdev, &pccbb_pcic_write, &pccbb_pcic_read,
529 	  sc->sc_bst, sc->sc_bsh, 0x800);
530 	pccbb_chipinit(sc);
531 
532 	/* CSC Interrupt: Card detect interrupt on */
533 	pccbb_setb(sc, PCCBB_SOCKET_MASK, PCCBB_SOCKET_MASK_CD);
534 
535 	/* reset interrupt */
536 	pccbb_set(sc, PCCBB_SOCKET_EVENT, pccbb_get(sc, PCCBB_SOCKET_EVENT));
537 
538 	/* Map and establish the interrupt. */
539 	rid = 0;
540 	sc->sc_irq_res = bus_alloc_resource(brdev, SYS_RES_IRQ, &rid, 0, ~0, 1,
541 	    RF_SHAREABLE | RF_ACTIVE);
542 	if (sc->sc_irq_res == NULL) {
543 		printf("pccbb: Unable to map IRQ...\n");
544 		bus_release_resource(brdev, SYS_RES_MEMORY, PCCBBR_SOCKBASE,
545 		    sc->sc_base_res);
546 		mtx_destroy(&sc->sc_mtx);
547 		return (ENOMEM);
548 	}
549 
550 	/* XXX INTR_TYPE_BIO IS WRONG here */
551 	if (bus_setup_intr(brdev, sc->sc_irq_res, INTR_TYPE_BIO, pccbb_intr, sc,
552 	    &sc->sc_intrhand)) {
553 		device_printf(brdev, "couldn't establish interrupt");
554 		bus_release_resource(brdev, SYS_RES_IRQ, 0, sc->sc_irq_res);
555 		bus_release_resource(brdev, SYS_RES_MEMORY, PCCBBR_SOCKBASE,
556 		    sc->sc_base_res);
557 		mtx_destroy(&sc->sc_mtx);
558 		return (ENOMEM);
559 	}
560 
561 	/* attach children */
562 	sc->sc_cbdev = device_add_child(brdev, "cardbus", -1);
563 	if (sc->sc_cbdev == NULL)
564 		DEVPRINTF((brdev, "WARNING: cannot add cardbus bus.\n"));
565 	else if (device_probe_and_attach(sc->sc_cbdev) != 0) {
566 		DEVPRINTF((brdev, "WARNING: cannot attach cardbus bus!\n"));
567 		sc->sc_cbdev = NULL;
568 	}
569 
570 	sc->sc_pccarddev = device_add_child(brdev, "pccard", -1);
571 	if (sc->sc_pccarddev == NULL)
572 		DEVPRINTF((brdev, "WARNING: cannot add pccard bus.\n"));
573 	else if (device_probe_and_attach(sc->sc_pccarddev) != 0) {
574 		DEVPRINTF((brdev, "WARNING: cannot attach pccard bus.\n"));
575 		sc->sc_pccarddev = NULL;
576 	}
577 
578 	sclist = malloc(sizeof(struct pccbb_sclist), M_DEVBUF, M_WAITOK);
579 	sclist->sc = sc;
580 	STAILQ_INSERT_TAIL(&softcs, sclist, entries);
581 	return (0);
582 }
583 
584 static int
585 pccbb_detach(device_t brdev)
586 {
587 	struct pccbb_softc *sc = device_get_softc(brdev);
588 	int numdevs;
589 	device_t *devlist;
590 	int tmp;
591 	int error;
592 
593 	device_get_children(brdev, &devlist, &numdevs);
594 
595 	error = 0;
596 	for (tmp = 0; tmp < numdevs; tmp++) {
597 		if (device_detach(devlist[tmp]) == 0)
598 			device_delete_child(brdev, devlist[tmp]);
599 		else
600 			error++;
601 	}
602 	free(devlist, M_TEMP);
603 	if (error > 0)
604 		return (ENXIO);
605 
606 	mtx_lock(&sc->sc_mtx);
607 	bus_teardown_intr(brdev, sc->sc_irq_res, sc->sc_intrhand);
608 
609 	sc->sc_flags |= PCCBB_KTHREAD_DONE;
610 	if (sc->sc_flags & PCCBB_KTHREAD_RUNNING) {
611 		wakeup(sc);
612 		mtx_unlock(&sc->sc_mtx);
613 		DEVPRINTF((brdev, "waiting for kthread exit..."));
614 		error = tsleep(sc, PWAIT, "pccbb-detach-wait", 60 * hz);
615 		if (error)
616 			DPRINTF(("timeout\n"));
617 		else
618 			DPRINTF(("done\n"));
619 	} else {
620 		mtx_unlock(&sc->sc_mtx);
621 	}
622 
623 	bus_release_resource(brdev, SYS_RES_IRQ, 0, sc->sc_irq_res);
624 	bus_release_resource(brdev, SYS_RES_MEMORY, PCCBBR_SOCKBASE,
625 	    sc->sc_base_res);
626 	mtx_destroy(&sc->sc_mtx);
627 	return (0);
628 }
629 
630 static int
631 pccbb_shutdown(device_t brdev)
632 {
633 	struct pccbb_softc *sc = (struct pccbb_softc *)device_get_softc(brdev);
634 	/* properly reset everything at shutdown */
635 
636 	PCI_MASK_CONFIG(brdev, PCCBBR_BRIDGECTRL, |PCCBBM_BRIDGECTRL_RESET, 2);
637 	exca_clrb(&sc->exca, EXCA_INTR, EXCA_INTR_RESET);
638 
639 	pccbb_set(sc, PCCBB_SOCKET_MASK, 0);
640 
641 	pccbb_power(brdev, CARD_VCC_0V | CARD_VPP_0V);
642 
643 	exca_write(&sc->exca, EXCA_ADDRWIN_ENABLE, 0);
644 	pci_write_config(brdev, PCCBBR_MEMBASE0, 0, 4);
645 	pci_write_config(brdev, PCCBBR_MEMLIMIT0, 0, 4);
646 	pci_write_config(brdev, PCCBBR_MEMBASE1, 0, 4);
647 	pci_write_config(brdev, PCCBBR_MEMLIMIT1, 0, 4);
648 	pci_write_config(brdev, PCCBBR_IOBASE0, 0, 4);
649 	pci_write_config(brdev, PCCBBR_IOLIMIT0, 0, 4);
650 	pci_write_config(brdev, PCCBBR_IOBASE1, 0, 4);
651 	pci_write_config(brdev, PCCBBR_IOLIMIT1, 0, 4);
652 	pci_write_config(brdev, PCIR_COMMAND, 0, 2);
653 	return (0);
654 }
655 
656 static void
657 pccbb_driver_added(device_t brdev, driver_t *driver)
658 {
659 	struct pccbb_softc *sc = device_get_softc(brdev);
660 	device_t *devlist;
661 	int tmp;
662 	int numdevs;
663 	int wake;
664 	uint32_t sockstate;
665 
666 	DEVICE_IDENTIFY(driver, brdev);
667 	device_get_children(brdev, &devlist, &numdevs);
668 	wake = 0;
669 	sockstate = pccbb_get(sc, PCCBB_SOCKET_STATE);
670 	for (tmp = 0; tmp < numdevs; tmp++) {
671 		if (device_get_state(devlist[tmp]) == DS_NOTPRESENT &&
672 		    device_probe_and_attach(devlist[tmp]) == 0) {
673 			if (devlist[tmp] == NULL)
674 				/* NOTHING */;
675 			else if (strcmp(driver->name, "cardbus") == 0) {
676 				sc->sc_cbdev = devlist[tmp];
677 				if (((sockstate & PCCBB_SOCKET_STAT_CD) == 0) &&
678 				    (sockstate & PCCBB_SOCKET_STAT_CB))
679 					wake++;
680 			} else if (strcmp(driver->name, "pccard") == 0) {
681 				sc->sc_pccarddev = devlist[tmp];
682 				if (((sockstate & PCCBB_SOCKET_STAT_CD) == 0) &&
683 				    (sockstate & PCCBB_SOCKET_STAT_16BIT))
684 					wake++;
685 			} else
686 				device_printf(brdev,
687 				    "Unsupported child bus: %s\n",
688 				    driver->name);
689 		}
690 	}
691 	free(devlist, M_TEMP);
692 
693 	if (wake > 0) {
694 		if ((pccbb_get(sc, PCCBB_SOCKET_STATE) & PCCBB_SOCKET_STAT_CD)
695 		    == 0) {
696 			mtx_lock(&sc->sc_mtx);
697 			wakeup(sc);
698 			mtx_unlock(&sc->sc_mtx);
699 		}
700 	}
701 }
702 
703 static void
704 pccbb_child_detached(device_t brdev, device_t child)
705 {
706 	struct pccbb_softc *sc = device_get_softc(brdev);
707 
708 	if (child == sc->sc_cbdev)
709 		sc->sc_cbdev = NULL;
710 	else if (child == sc->sc_pccarddev)
711 		sc->sc_pccarddev = NULL;
712 	else
713 		device_printf(brdev, "Unknown child detached: %s %p/%p\n",
714 		    device_get_nameunit(child), sc->sc_cbdev, sc->sc_pccarddev);
715 }
716 
717 static int
718 pccbb_card_reprobe(device_t brdev, device_t busdev)
719 {
720 	struct pccbb_softc *sc = device_get_softc(brdev);
721 	int wake = 0;
722 	uint32_t sockstate;
723 
724 	sockstate = pccbb_get(sc, PCCBB_SOCKET_STATE);
725 
726 	if ((sockstate & PCCBB_SOCKET_STAT_CD) == 0) {
727 		if (busdev == sc->sc_cbdev &&
728 		    (sockstate & PCCBB_SOCKET_STAT_CB))
729 			wake++;
730 		else if (busdev == sc->sc_pccarddev &&
731 		    (sockstate & PCCBB_SOCKET_STAT_16BIT))
732 			wake++;
733 
734 		if (wake > 0) {
735 			mtx_lock(&sc->sc_mtx);
736 			wakeup(sc);
737 			mtx_unlock(&sc->sc_mtx);
738 			return (0);
739 		}
740 		return (EBUSY);
741 	}
742 	return (ENOENT);
743 }
744 
745 /************************************************************************/
746 /* Kthreads								*/
747 /************************************************************************/
748 
749 static void
750 pccbb_event_thread(void *arg)
751 {
752 	struct pccbb_softc *sc = arg;
753 	uint32_t status;
754 
755 	mtx_lock(&Giant);
756 	for(;;) {
757 		if (!(sc->sc_flags & PCCBB_KTHREAD_RUNNING)) {
758 			sc->sc_flags |= PCCBB_KTHREAD_RUNNING;
759 		} else {
760 			tsleep (sc, PWAIT, "pccbbev", 0);
761 			/*
762 			 * Delay 1 second, make sure the user is done with
763 			 * whatever he is doing.  We tsleep on sc->sc_flags,
764 			 * which should never be woken up.
765 			 *
766 			 * XXX Note: This can cause problems on card
767 			 * removal.  See OLDCARD's ISR for how you may
768 			 * have to deal with the debouncing problem.  The
769 			 * crux of the issue is interrupts delivered to
770 			 * the card after eject are unstable.
771 			 */
772 			tsleep (&sc->sc_flags, PWAIT, "pccbbev", 1*hz);
773 		}
774 		mtx_lock(&sc->sc_mtx);
775 		if (sc->sc_flags & PCCBB_KTHREAD_DONE)
776 			break;
777 
778 		status = pccbb_get(sc, PCCBB_SOCKET_STATE);
779 		if ((status & PCCBB_SOCKET_STAT_CD) == 0) {
780 			pccbb_insert(sc);
781 		} else {
782 			pccbb_removal(sc);
783 		}
784 		mtx_unlock(&sc->sc_mtx);
785 	}
786 	mtx_unlock(&sc->sc_mtx);
787 	sc->sc_flags &= ~PCCBB_KTHREAD_RUNNING;
788 	wakeup(sc);
789 	kthread_exit(0);
790 }
791 
792 static void
793 pccbb_create_event_thread(struct pccbb_softc *sc)
794 {
795 	if (kthread_create(pccbb_event_thread, sc, &sc->event_thread,
796 	    0, "%s%d", device_get_name(sc->sc_dev),
797 	    device_get_unit(sc->sc_dev))) {
798 		device_printf (sc->sc_dev, "unable to create event thread.\n");
799 		panic ("pccbb_create_event_thread");
800 	}
801 }
802 
803 static void
804 pccbb_start_threads(void *arg)
805 {
806 	struct pccbb_sclist *sclist;
807 
808 	STAILQ_FOREACH(sclist, &softcs, entries) {
809 		pccbb_create_event_thread(sclist->sc);
810 	}
811 }
812 
813 /************************************************************************/
814 /* Insert/removal							*/
815 /************************************************************************/
816 
817 static void
818 pccbb_insert(struct pccbb_softc *sc)
819 {
820 	uint32_t sockevent, sockstate;
821 	int timeout = 30;
822 
823 	do {
824 		sockevent = pccbb_get(sc, PCCBB_SOCKET_EVENT);
825 		sockstate = pccbb_get(sc, PCCBB_SOCKET_STATE);
826 	} while (sockstate & PCCBB_SOCKET_STAT_CD && --timeout > 0);
827 
828 	if (timeout < 0) {
829 		device_printf (sc->sc_dev, "insert timeout");
830 		return;
831 	}
832 
833 	DEVPRINTF((sc->sc_dev, "card inserted: event=0x%08x, state=%08x\n",
834 	    sockevent, sockstate));
835 
836 	if (sockstate & PCCBB_SOCKET_STAT_16BIT && sc->sc_pccarddev != NULL) {
837 		sc->sc_flags |= PCCBB_16BIT_CARD;
838 		if (CARD_ATTACH_CARD(sc->sc_pccarddev) != 0)
839 			device_printf(sc->sc_dev, "card activation failed\n");
840 	} else if (sockstate & PCCBB_SOCKET_STAT_CB && sc->sc_cbdev != NULL) {
841 		sc->sc_flags &= ~PCCBB_16BIT_CARD;
842 		if (CARD_ATTACH_CARD(sc->sc_cbdev) != 0)
843 			device_printf(sc->sc_dev, "card activation failed\n");
844 	} else {
845 		device_printf (sc->sc_dev, "Unsupported card type detected\n");
846 	}
847 }
848 
849 static void
850 pccbb_removal(struct pccbb_softc *sc)
851 {
852 	if (sc->sc_flags & PCCBB_16BIT_CARD && sc->sc_pccarddev != NULL)
853 		CARD_DETACH_CARD(sc->sc_pccarddev, DETACH_FORCE);
854 	else if ((!(sc->sc_flags & PCCBB_16BIT_CARD)) && sc->sc_cbdev != NULL)
855 		CARD_DETACH_CARD(sc->sc_cbdev, DETACH_FORCE);
856 	pccbb_destroy_res(sc);
857 }
858 
859 /************************************************************************/
860 /* Interrupt Handler							*/
861 /************************************************************************/
862 
863 static void
864 pccbb_intr(void *arg)
865 {
866 	struct pccbb_softc *sc = arg;
867 	uint32_t sockevent;
868 
869 	if (!(sockevent = pccbb_get(sc, PCCBB_SOCKET_EVENT))) {
870 		/* not for me. */
871 		return;
872 	}
873 
874 	/* reset bit */
875 	pccbb_setb(sc, PCCBB_SOCKET_EVENT, 0x01);	/* XXXmagic */
876 
877 	if (sockevent & PCCBB_SOCKET_EVENT_CD) {
878 		mtx_lock(&sc->sc_mtx);
879 		wakeup(sc);
880 		mtx_unlock(&sc->sc_mtx);
881 	} else {
882 		if (sockevent & PCCBB_SOCKET_EVENT_CSTS) {
883 			DPRINTF((" cstsevent occures, 0x%08x\n",
884 			    pccbb_get(sc, PCCBB_SOCKET_STATE)));
885 		}
886 		if (sockevent & PCCBB_SOCKET_EVENT_POWER) {
887 			DPRINTF((" pwrevent occures, 0x%08x\n",
888 			    pccbb_get(sc, PCCBB_SOCKET_STATE)));
889 		}
890 	}
891 }
892 
893 /************************************************************************/
894 /* Generic Power functions						*/
895 /************************************************************************/
896 
897 static int
898 pccbb_detect_voltage(device_t brdev)
899 {
900 	struct pccbb_softc *sc = device_get_softc(brdev);
901 	uint32_t psr;
902 	int vol = CARD_UKN_CARD;
903 
904 	psr = pccbb_get(sc, PCCBB_SOCKET_STATE);
905 
906 	if (psr & PCCBB_SOCKET_STAT_5VCARD)
907 		vol |= CARD_5V_CARD;
908 	if (psr & PCCBB_SOCKET_STAT_3VCARD)
909 		vol |= CARD_3V_CARD;
910 	if (psr & PCCBB_SOCKET_STAT_XVCARD)
911 		vol |= CARD_XV_CARD;
912 	if (psr & PCCBB_SOCKET_STAT_YVCARD)
913 		vol |= CARD_YV_CARD;
914 
915 	return (vol);
916 }
917 
918 static int
919 pccbb_power(device_t brdev, int volts)
920 {
921 	uint32_t status, sock_ctrl;
922 	struct pccbb_softc *sc = device_get_softc(brdev);
923 	int timeout;
924 	uint32_t sockevent;
925 
926 	DEVPRINTF((sc->sc_dev, "pccbb_power: %s and %s [%x]\n",
927 	    (volts & CARD_VCCMASK) == CARD_VCC_UC ? "CARD_VCC_UC" :
928 	    (volts & CARD_VCCMASK) == CARD_VCC_5V ? "CARD_VCC_5V" :
929 	    (volts & CARD_VCCMASK) == CARD_VCC_3V ? "CARD_VCC_3V" :
930 	    (volts & CARD_VCCMASK) == CARD_VCC_XV ? "CARD_VCC_XV" :
931 	    (volts & CARD_VCCMASK) == CARD_VCC_YV ? "CARD_VCC_YV" :
932 	    (volts & CARD_VCCMASK) == CARD_VCC_0V ? "CARD_VCC_0V" :
933 	    "VCC-UNKNOWN",
934 	    (volts & CARD_VPPMASK) == CARD_VPP_UC ? "CARD_VPP_UC" :
935 	    (volts & CARD_VPPMASK) == CARD_VPP_12V ? "CARD_VPP_12V" :
936 	    (volts & CARD_VPPMASK) == CARD_VPP_VCC ? "CARD_VPP_VCC" :
937 	    (volts & CARD_VPPMASK) == CARD_VPP_0V ? "CARD_VPP_0V" :
938 	    "VPP-UNKNOWN",
939 	    volts));
940 
941 	status = pccbb_get(sc, PCCBB_SOCKET_STATE);
942 	sock_ctrl = pccbb_get(sc, PCCBB_SOCKET_CONTROL);
943 
944 	switch (volts & CARD_VCCMASK) {
945 	case CARD_VCC_UC:
946 		break;
947 	case CARD_VCC_5V:
948 		if (PCCBB_SOCKET_STAT_5VCARD & status) { /* check 5 V card */
949 			sock_ctrl &= ~PCCBB_SOCKET_CTRL_VCCMASK;
950 			sock_ctrl |= PCCBB_SOCKET_CTRL_VCC_5V;
951 		} else {
952 			device_printf(sc->sc_dev,
953 			    "BAD voltage request: no 5 V card\n");
954 		}
955 		break;
956 	case CARD_VCC_3V:
957 		if (PCCBB_SOCKET_STAT_3VCARD & status) {
958 			sock_ctrl &= ~PCCBB_SOCKET_CTRL_VCCMASK;
959 			sock_ctrl |= PCCBB_SOCKET_CTRL_VCC_3V;
960 		} else {
961 			device_printf(sc->sc_dev,
962 			    "BAD voltage request: no 3.3 V card\n");
963 		}
964 		break;
965 	case CARD_VCC_0V:
966 		sock_ctrl &= ~PCCBB_SOCKET_CTRL_VCCMASK;
967 		break;
968 	default:
969 		return (0);			/* power NEVER changed */
970 		break;
971 	}
972 
973 	switch (volts & CARD_VPPMASK) {
974 	case CARD_VPP_UC:
975 		break;
976 	case CARD_VPP_0V:
977 		sock_ctrl &= ~PCCBB_SOCKET_CTRL_VPPMASK;
978 		break;
979 	case CARD_VPP_VCC:
980 		sock_ctrl &= ~PCCBB_SOCKET_CTRL_VPPMASK;
981 		sock_ctrl |= ((sock_ctrl >> 4) & 0x07);
982 		break;
983 	case CARD_VPP_12V:
984 		sock_ctrl &= ~PCCBB_SOCKET_CTRL_VPPMASK;
985 		sock_ctrl |= PCCBB_SOCKET_CTRL_VPP_12V;
986 		break;
987 	}
988 
989 	if (pccbb_get(sc, PCCBB_SOCKET_CONTROL) == sock_ctrl)
990 		return (1); /* no change necessary */
991 
992 	pccbb_set(sc, PCCBB_SOCKET_CONTROL, sock_ctrl);
993 	status = pccbb_get(sc, PCCBB_SOCKET_STATE);
994 
995 	/*
996 	 * XXX This busy wait is bogus.  We should wait for a power
997 	 * interrupt and then whine if the status is bad.  If we're
998 	 * worried about the card not coming up, then we should also
999 	 * schedule a timeout which we can cacel in the power interrupt.
1000 	 */
1001 	timeout = 20;
1002 	do {
1003 		DELAY(20*1000);
1004 		sockevent = pccbb_get(sc, PCCBB_SOCKET_EVENT);
1005 	} while (!(sockevent & PCCBB_SOCKET_EVENT_POWER) && --timeout > 0);
1006 	/* reset event status */
1007 	/* XXX should only reset EVENT_POWER */
1008 	pccbb_set(sc, PCCBB_SOCKET_EVENT, sockevent);
1009 	if (timeout < 0) {
1010 		printf ("VCC supply failed.\n");
1011 		return (0);
1012 	}
1013 
1014 	/* XXX
1015 	 * delay 400 ms: thgough the standard defines that the Vcc set-up time
1016 	 * is 20 ms, some PC-Card bridge requires longer duration.
1017 	 * XXX Note: We should check the stutus AFTER the delay to give time
1018 	 * for things to stabilize.
1019 	 */
1020 	DELAY(400*1000);
1021 
1022 	if (status & PCCBB_SOCKET_STAT_BADVCC) {
1023 		device_printf(sc->sc_dev,
1024 		    "bad Vcc request. ctrl=0x%x, status=0x%x\n",
1025 		    sock_ctrl ,status);
1026 		printf("pccbb_power: %s and %s [%x]\n",
1027 		    (volts & CARD_VCCMASK) == CARD_VCC_UC ? "CARD_VCC_UC" :
1028 		    (volts & CARD_VCCMASK) == CARD_VCC_5V ? "CARD_VCC_5V" :
1029 		    (volts & CARD_VCCMASK) == CARD_VCC_3V ? "CARD_VCC_3V" :
1030 		    (volts & CARD_VCCMASK) == CARD_VCC_XV ? "CARD_VCC_XV" :
1031 		    (volts & CARD_VCCMASK) == CARD_VCC_YV ? "CARD_VCC_YV" :
1032 		    (volts & CARD_VCCMASK) == CARD_VCC_0V ? "CARD_VCC_0V" :
1033 		    "VCC-UNKNOWN",
1034 		    (volts & CARD_VPPMASK) == CARD_VPP_UC ? "CARD_VPP_UC" :
1035 		    (volts & CARD_VPPMASK) == CARD_VPP_12V ? "CARD_VPP_12V":
1036 		    (volts & CARD_VPPMASK) == CARD_VPP_VCC ? "CARD_VPP_VCC":
1037 		    (volts & CARD_VPPMASK) == CARD_VPP_0V ? "CARD_VPP_0V" :
1038 		    "VPP-UNKNOWN",
1039 		    volts);
1040 		return (0);
1041 	}
1042 	return (1);		/* power changed correctly */
1043 }
1044 
1045 /************************************************************************/
1046 /* Cardbus power functions						*/
1047 /************************************************************************/
1048 
1049 static void
1050 pccbb_cardbus_reset(device_t brdev)
1051 {
1052 	struct pccbb_softc *sc = device_get_softc(brdev);
1053 	int delay_us;
1054 
1055 	delay_us = sc->sc_chipset == CB_RF5C47X ? 400*1000 : 20*1000;
1056 
1057 	PCI_MASK_CONFIG(brdev, PCCBBR_BRIDGECTRL, |PCCBBM_BRIDGECTRL_RESET, 2);
1058 
1059 	DELAY(delay_us);
1060 
1061 	/* If a card exists, unreset it! */
1062 	if ((pccbb_get(sc, PCCBB_SOCKET_STATE) & PCCBB_SOCKET_STAT_CD) == 0) {
1063 		PCI_MASK_CONFIG(brdev, PCCBBR_BRIDGECTRL,
1064 		    &~PCCBBM_BRIDGECTRL_RESET, 2);
1065 		DELAY(delay_us);
1066 	}
1067 }
1068 
1069 static int
1070 pccbb_cardbus_power_enable_socket(device_t brdev, device_t child)
1071 {
1072 	struct pccbb_softc *sc = device_get_softc(brdev);
1073 	int voltage;
1074 
1075 	if ((pccbb_get(sc, PCCBB_SOCKET_STATE) & PCCBB_SOCKET_STAT_CD) ==
1076 	    PCCBB_SOCKET_STAT_CD)
1077 		return (ENODEV);
1078 
1079 	voltage = pccbb_detect_voltage(brdev);
1080 
1081 	pccbb_power(brdev, CARD_VCC_0V | CARD_VPP_0V);
1082 	if (voltage & CARD_5V_CARD)
1083 		pccbb_power(brdev, CARD_VCC_5V | CARD_VPP_VCC);
1084 	else if (voltage & CARD_3V_CARD)
1085 		pccbb_power(brdev, CARD_VCC_3V | CARD_VPP_VCC);
1086 	else {
1087 		device_printf(brdev, "Unknown card voltage\n");
1088 		return (ENXIO);
1089 	}
1090 
1091 	pccbb_cardbus_reset(brdev);
1092 	return (0);
1093 }
1094 
1095 static void
1096 pccbb_cardbus_power_disable_socket(device_t brdev, device_t child)
1097 {
1098 	pccbb_power(brdev, CARD_VCC_0V | CARD_VPP_0V);
1099 	pccbb_cardbus_reset(brdev);
1100 }
1101 
1102 /************************************************************************/
1103 /* Cardbus Resource							*/
1104 /************************************************************************/
1105 
1106 static int
1107 pccbb_cardbus_io_open(device_t brdev, int win, uint32_t start, uint32_t end)
1108 {
1109 	int basereg;
1110 	int limitreg;
1111 
1112 	if ((win < 0) || (win > 1)) {
1113 		DEVPRINTF((brdev,
1114 		    "pccbb_cardbus_io_open: window out of range %d\n", win));
1115 		return (EINVAL);
1116 	}
1117 
1118 	basereg = win*8 + PCCBBR_IOBASE0;
1119 	limitreg = win*8 + PCCBBR_IOLIMIT0;
1120 
1121 	pci_write_config(brdev, basereg, start, 4);
1122 	pci_write_config(brdev, limitreg, end, 4);
1123 	return (0);
1124 }
1125 
1126 static int
1127 pccbb_cardbus_mem_open(device_t brdev, int win, uint32_t start, uint32_t end)
1128 {
1129 	int basereg;
1130 	int limitreg;
1131 
1132 	if ((win < 0) || (win > 1)) {
1133 		DEVPRINTF((brdev,
1134 		    "pccbb_cardbus_mem_open: window out of range %d\n", win));
1135 		return (EINVAL);
1136 	}
1137 
1138 	basereg = win*8 + PCCBBR_MEMBASE0;
1139 	limitreg = win*8 + PCCBBR_MEMLIMIT0;
1140 
1141 	pci_write_config(brdev, basereg, start, 4);
1142 	pci_write_config(brdev, limitreg, end, 4);
1143 	return (0);
1144 }
1145 
1146 /*
1147  * XXX The following function belongs in the pci bus layer.
1148  */
1149 static void
1150 pccbb_cardbus_auto_open(struct pccbb_softc *sc, int type)
1151 {
1152 	uint32_t starts[2];
1153 	uint32_t ends[2];
1154 	struct pccbb_reslist *rle;
1155 	int align;
1156 	int prefetchable[2];
1157 	uint32_t reg;
1158 
1159 	starts[0] = starts[1] = 0xffffffff;
1160 	ends[0] = ends[1] = 0;
1161 
1162 	if (type == SYS_RES_MEMORY)
1163 		align = PCCBB_MEMALIGN;
1164 	else if (type == SYS_RES_IOPORT)
1165 		align = PCCBB_IOALIGN;
1166 	else
1167 		align = 1;
1168 
1169 	SLIST_FOREACH(rle, &sc->rl, link) {
1170 		if (rle->type != type)
1171 			;
1172 		else if (rle->res == NULL) {
1173 			device_printf(sc->sc_dev, "WARNING: Resource not reserved?  "
1174 			    "(type=%d, addr=%lx)\n",
1175 			    rle->type, rman_get_start(rle->res));
1176 		} else if (!(rman_get_flags(rle->res) & RF_ACTIVE)) {
1177 			/* XXX */
1178 		} else if (starts[0] == 0xffffffff) {
1179 			starts[0] = rman_get_start(rle->res);
1180 			ends[0] = rman_get_end(rle->res);
1181 			prefetchable[0] =
1182 			    rman_get_flags(rle->res) & RF_PREFETCHABLE;
1183 		} else if (rman_get_end(rle->res) > ends[0] &&
1184 		    rman_get_start(rle->res) - ends[0] <
1185 		    PCCBB_AUTO_OPEN_SMALLHOLE && prefetchable[0] ==
1186 		    (rman_get_flags(rle->res) & RF_PREFETCHABLE)) {
1187 			ends[0] = rman_get_end(rle->res);
1188 		} else if (rman_get_start(rle->res) < starts[0] &&
1189 		    starts[0] - rman_get_end(rle->res) <
1190 		    PCCBB_AUTO_OPEN_SMALLHOLE && prefetchable[0] ==
1191 		    (rman_get_flags(rle->res) & RF_PREFETCHABLE)) {
1192 			starts[0] = rman_get_start(rle->res);
1193 		} else if (starts[1] == 0xffffffff) {
1194 			starts[1] = rman_get_start(rle->res);
1195 			ends[1] = rman_get_end(rle->res);
1196 			prefetchable[1] =
1197 			    rman_get_flags(rle->res) & RF_PREFETCHABLE;
1198 		} else if (rman_get_end(rle->res) > ends[1] &&
1199 		    rman_get_start(rle->res) - ends[1] <
1200 		    PCCBB_AUTO_OPEN_SMALLHOLE && prefetchable[1] ==
1201 		    (rman_get_flags(rle->res) & RF_PREFETCHABLE)) {
1202 			ends[1] = rman_get_end(rle->res);
1203 		} else if (rman_get_start(rle->res) < starts[1] &&
1204 		    starts[1] - rman_get_end(rle->res) <
1205 		    PCCBB_AUTO_OPEN_SMALLHOLE && prefetchable[1] ==
1206 		    (rman_get_flags(rle->res) & RF_PREFETCHABLE)) {
1207 			starts[1] = rman_get_start(rle->res);
1208 		} else {
1209 			uint32_t diffs[2];
1210 			int win;
1211 
1212 			diffs[0] = diffs[1] = 0xffffffff;
1213 			if (rman_get_start(rle->res) > ends[0])
1214 				diffs[0] = rman_get_start(rle->res) - ends[0];
1215 			else if (rman_get_end(rle->res) < starts[0])
1216 				diffs[0] = starts[0] - rman_get_end(rle->res);
1217 			if (rman_get_start(rle->res) > ends[1])
1218 				diffs[1] = rman_get_start(rle->res) - ends[1];
1219 			else if (rman_get_end(rle->res) < starts[1])
1220 				diffs[1] = starts[1] - rman_get_end(rle->res);
1221 
1222 			win = (diffs[0] <= diffs[1])?0:1;
1223 			if (rman_get_start(rle->res) > ends[win])
1224 				ends[win] = rman_get_end(rle->res);
1225 			else if (rman_get_end(rle->res) < starts[win])
1226 				starts[win] = rman_get_start(rle->res);
1227 			if (!(rman_get_flags(rle->res) & RF_PREFETCHABLE))
1228 				prefetchable[win] = 0;
1229 		}
1230 
1231 		if (starts[0] != 0xffffffff)
1232 			starts[0] -= starts[0] % align;
1233 		if (starts[1] != 0xffffffff)
1234 			starts[1] -= starts[1] % align;
1235 		if (ends[0] % align != 0)
1236 			ends[0] += align - ends[0]%align - 1;
1237 		if (ends[1] % align != 0)
1238 			ends[1] += align - ends[1]%align - 1;
1239 	}
1240 
1241 	if (type == SYS_RES_MEMORY) {
1242 		pccbb_cardbus_mem_open(sc->sc_dev, 0, starts[0], ends[0]);
1243 		pccbb_cardbus_mem_open(sc->sc_dev, 1, starts[1], ends[1]);
1244 		reg = pci_read_config(sc->sc_dev, PCCBBR_BRIDGECTRL, 2);
1245 		reg &= ~(PCCBBM_BRIDGECTRL_PREFETCH_0|
1246 		    PCCBBM_BRIDGECTRL_PREFETCH_1);
1247 		reg |= (prefetchable[0]?PCCBBM_BRIDGECTRL_PREFETCH_0:0)|
1248 		    (prefetchable[1]?PCCBBM_BRIDGECTRL_PREFETCH_1:0);
1249 		pci_write_config(sc->sc_dev, PCCBBR_BRIDGECTRL, reg, 2);
1250 	} else if (type == SYS_RES_IOPORT) {
1251 		pccbb_cardbus_io_open(sc->sc_dev, 0, starts[0], ends[0]);
1252 		pccbb_cardbus_io_open(sc->sc_dev, 1, starts[1], ends[1]);
1253 	}
1254 }
1255 
1256 static int
1257 pccbb_cardbus_activate_resource(device_t brdev, device_t child, int type,
1258     int rid, struct resource *res)
1259 {
1260 	int ret;
1261 
1262 	ret = BUS_ACTIVATE_RESOURCE(device_get_parent(brdev), child,
1263 	    type, rid, res);
1264 	if (ret != 0)
1265 		return (ret);
1266 	pccbb_cardbus_auto_open(device_get_softc(brdev), type);
1267 	return (0);
1268 }
1269 
1270 static int
1271 pccbb_cardbus_deactivate_resource(device_t brdev, device_t child, int type,
1272     int rid, struct resource *res)
1273 {
1274 	int ret;
1275 
1276 	ret = BUS_DEACTIVATE_RESOURCE(device_get_parent(brdev), child,
1277 	    type, rid, res);
1278 	if (ret != 0)
1279 		return (ret);
1280 	pccbb_cardbus_auto_open(device_get_softc(brdev), type);
1281 	return (0);
1282 }
1283 
1284 static struct resource *
1285 pccbb_cardbus_alloc_resource(device_t brdev, device_t child, int type, int *rid,
1286     u_long start, u_long end, u_long count, uint flags)
1287 {
1288 	struct pccbb_softc *sc = device_get_softc(brdev);
1289 	int tmp;
1290 	struct resource *res;
1291 
1292 	switch (type) {
1293 	case SYS_RES_IRQ:
1294 		tmp = rman_get_start(sc->sc_irq_res);
1295 		if (start > tmp || end < tmp || count != 1) {
1296 			device_printf(child, "requested interrupt %ld-%ld,"
1297 			    "count = %ld not supported by pccbb\n",
1298 			    start, end, count);
1299 			return (NULL);
1300 		}
1301 		start = end = tmp;
1302 		break;
1303 	case SYS_RES_IOPORT:
1304 		if (start <= PCCBB_START_IO)
1305 			start = PCCBB_START_IO;
1306 		if (end < start)
1307 			end = start;
1308 		break;
1309 	case SYS_RES_MEMORY:
1310 		if (start <= pccbb_start_mem)
1311 			start = pccbb_start_mem;
1312 		if (end < start)
1313 			end = start;
1314 		break;
1315 	}
1316 
1317 	res = BUS_ALLOC_RESOURCE(device_get_parent(brdev), child, type, rid,
1318 	    start, end, count, flags & ~RF_ACTIVE);
1319 	if (res == NULL) {
1320 		printf("pccbb alloc res fail\n");
1321 		return (NULL);
1322 	}
1323 	pccbb_insert_res(sc, res, type, *rid);
1324 	if (flags & RF_ACTIVE)
1325 		if (bus_activate_resource(child, type, *rid, res) != 0) {
1326 			bus_release_resource(child, type, *rid, res);
1327 			return (NULL);
1328 		}
1329 
1330 	return (res);
1331 }
1332 
1333 static int
1334 pccbb_cardbus_release_resource(device_t brdev, device_t child, int type,
1335     int rid, struct resource *res)
1336 {
1337 	struct pccbb_softc *sc = device_get_softc(brdev);
1338 	int error;
1339 
1340 	if (rman_get_flags(res) & RF_ACTIVE) {
1341 		error = bus_deactivate_resource(child, type, rid, res);
1342 		if (error != 0)
1343 			return (error);
1344 	}
1345 	pccbb_remove_res(sc, res);
1346 	return (BUS_RELEASE_RESOURCE(device_get_parent(brdev), child,
1347 	    type, rid, res));
1348 }
1349 
1350 /************************************************************************/
1351 /* PC Card Power Functions						*/
1352 /************************************************************************/
1353 
1354 static int
1355 pccbb_pcic_power_enable_socket(device_t brdev, device_t child)
1356 {
1357 	struct pccbb_softc *sc = device_get_softc(brdev);
1358 	int voltage;
1359 
1360 	DPRINTF(("pccbb_pcic_socket_enable:\n"));
1361 
1362 	/* power down/up the socket to reset */
1363 	voltage = pccbb_detect_voltage(brdev);
1364 	pccbb_power(brdev, CARD_VCC_0V | CARD_VPP_0V);
1365 	if (voltage & CARD_5V_CARD)
1366 		pccbb_power(brdev, CARD_VCC_5V | CARD_VPP_VCC);
1367 	else if (voltage & CARD_3V_CARD)
1368 		pccbb_power(brdev, CARD_VCC_3V | CARD_VPP_VCC);
1369 	else {
1370 		device_printf(brdev, "Unknown card voltage\n");
1371 		return (ENXIO);
1372 	}
1373 	exca_reset(&sc->exca, child);
1374 
1375 	return (0);
1376 }
1377 
1378 static void
1379 pccbb_pcic_power_disable_socket(device_t brdev, device_t child)
1380 {
1381 	struct pccbb_softc *sc = device_get_softc(brdev);
1382 
1383 	DPRINTF(("pccbb_pcic_socket_disable\n"));
1384 
1385 	/* reset signal asserting... */
1386 	exca_clrb(&sc->exca, EXCA_INTR, EXCA_INTR_RESET);
1387 	DELAY(2*1000);
1388 
1389 	/* power down the socket */
1390 	pccbb_power(brdev, CARD_VCC_0V | CARD_VPP_0V);
1391 	exca_clrb(&sc->exca, EXCA_PWRCTL, EXCA_PWRCTL_OE);
1392 
1393 	/* wait 300ms until power fails (Tpf). */
1394 	DELAY(300 * 1000);
1395 }
1396 
1397 /************************************************************************/
1398 /* POWER methods							*/
1399 /************************************************************************/
1400 
1401 static int
1402 pccbb_power_enable_socket(device_t brdev, device_t child)
1403 {
1404 	struct pccbb_softc *sc = device_get_softc(brdev);
1405 
1406 	if (sc->sc_flags & PCCBB_16BIT_CARD)
1407 		return (pccbb_pcic_power_enable_socket(brdev, child));
1408 	else
1409 		return (pccbb_cardbus_power_enable_socket(brdev, child));
1410 }
1411 
1412 static void
1413 pccbb_power_disable_socket(device_t brdev, device_t child)
1414 {
1415 	struct pccbb_softc *sc = device_get_softc(brdev);
1416 	if (sc->sc_flags & PCCBB_16BIT_CARD)
1417 		pccbb_pcic_power_disable_socket(brdev, child);
1418 	else
1419 		pccbb_cardbus_power_disable_socket(brdev, child);
1420 }
1421 static int
1422 pccbb_pcic_activate_resource(device_t brdev, device_t child, int type, int rid,
1423     struct resource *res)
1424 {
1425 	int err;
1426 	struct pccbb_softc *sc = device_get_softc(brdev);
1427 	if (!(rman_get_flags(res) & RF_ACTIVE)) { /* not already activated */
1428 		switch (type) {
1429 		case SYS_RES_IOPORT:
1430 			err = exca_io_map(&sc->exca, 0, res);
1431 			break;
1432 		case SYS_RES_MEMORY:
1433 			err = exca_mem_map(&sc->exca, 0, res);
1434 			break;
1435 		default:
1436 			err = 0;
1437 			break;
1438 		}
1439 		if (err)
1440 			return (err);
1441 
1442 	}
1443 	return (BUS_ACTIVATE_RESOURCE(device_get_parent(brdev), child,
1444 	    type, rid, res));
1445 }
1446 
1447 static int
1448 pccbb_pcic_deactivate_resource(device_t brdev, device_t child, int type,
1449     int rid, struct resource *res)
1450 {
1451 	struct pccbb_softc *sc = device_get_softc(brdev);
1452 
1453 	if (rman_get_flags(res) & RF_ACTIVE) { /* if activated */
1454 		switch (type) {
1455 		case SYS_RES_IOPORT:
1456 			if (exca_io_unmap_res(&sc->exca, res))
1457 				return (ENOENT);
1458 			break;
1459 		case SYS_RES_MEMORY:
1460 			if (exca_mem_unmap_res(&sc->exca, res))
1461 				return (ENOENT);
1462 			break;
1463 		}
1464 	}
1465 	return (BUS_DEACTIVATE_RESOURCE(device_get_parent(brdev), child,
1466 	    type, rid, res));
1467 }
1468 
1469 static struct resource *
1470 pccbb_pcic_alloc_resource(device_t brdev, device_t child, int type, int *rid,
1471     u_long start, u_long end, u_long count, uint flags)
1472 {
1473 	struct resource *res = NULL;
1474 	struct pccbb_softc *sc = device_get_softc(brdev);
1475 	int tmp;
1476 
1477 	switch (type) {
1478 	case SYS_RES_MEMORY:
1479 		if (start < pccbb_start_mem)
1480 			start = pccbb_start_mem;
1481 		if (end < start)
1482 			end = start;
1483 		flags = (flags & ~RF_ALIGNMENT_MASK) |
1484 		    rman_make_alignment_flags(PCCBB_MEMALIGN);
1485 		break;
1486 	case SYS_RES_IOPORT:
1487 		if (start < 0x100)
1488 			start = 0x100;		/* XXX tweakable? */
1489 		if (end < start)
1490 			end = start;
1491 		break;
1492 	case SYS_RES_IRQ:
1493 		tmp = rman_get_start(sc->sc_irq_res);
1494 		if (start > tmp || end < tmp || count != 1) {
1495 			device_printf(child, "requested interrupt %ld-%ld,"
1496 			    "count = %ld not supported by pccbb\n",
1497 			    start, end, count);
1498 			return (NULL);
1499 		}
1500 		flags |= RF_SHAREABLE;
1501 		start = end = rman_get_start(sc->sc_irq_res);
1502 		break;
1503 	}
1504 	res = BUS_ALLOC_RESOURCE(device_get_parent(brdev), child, type, rid,
1505 	    start, end, count, flags & ~RF_ACTIVE);
1506 	if (res == NULL)
1507 		return (NULL);
1508 	pccbb_insert_res(sc, res, type, *rid);
1509 	if (flags & RF_ACTIVE) {
1510 		if (bus_activate_resource(child, type, *rid, res) != 0) {
1511 			bus_release_resource(child, type, *rid, res);
1512 			return (NULL);
1513 		}
1514 	}
1515 
1516 	return (res);
1517 }
1518 
1519 static int
1520 pccbb_pcic_release_resource(device_t brdev, device_t child, int type,
1521     int rid, struct resource *res)
1522 {
1523 	struct pccbb_softc *sc = device_get_softc(brdev);
1524 	int error;
1525 
1526 	if (rman_get_flags(res) & RF_ACTIVE) {
1527 		error = bus_deactivate_resource(child, type, rid, res);
1528 		if (error != 0)
1529 			return (error);
1530 	}
1531 	pccbb_remove_res(sc, res);
1532 	return (BUS_RELEASE_RESOURCE(device_get_parent(brdev), child,
1533 	    type, rid, res));
1534 }
1535 
1536 /************************************************************************/
1537 /* PC Card methods							*/
1538 /************************************************************************/
1539 
1540 static int
1541 pccbb_pcic_set_res_flags(device_t brdev, device_t child, int type, int rid,
1542     uint32_t flags)
1543 {
1544 	struct pccbb_softc *sc = device_get_softc(brdev);
1545 	struct resource *res;
1546 
1547 	if (type != SYS_RES_MEMORY)
1548 		return (EINVAL);
1549 	res = pccbb_find_res(sc, type, rid);
1550 	if (res == NULL) {
1551 		device_printf(brdev,
1552 		    "set_res_flags: specified rid not found\n");
1553 		return (ENOENT);
1554 	}
1555 	return (exca_mem_set_flags(&sc->exca, res, flags));
1556 }
1557 
1558 static int
1559 pccbb_pcic_set_memory_offset(device_t brdev, device_t child, int rid,
1560     uint32_t cardaddr, uint32_t *deltap)
1561 {
1562 	struct pccbb_softc *sc = device_get_softc(brdev);
1563 	struct resource *res;
1564 
1565 	res = pccbb_find_res(sc, SYS_RES_MEMORY, rid);
1566 	if (res == NULL) {
1567 		device_printf(brdev,
1568 		    "set_memory_offset: specified rid not found\n");
1569 		return (ENOENT);
1570 	}
1571 	return (exca_mem_set_offset(&sc->exca, res, cardaddr, deltap));
1572 }
1573 
1574 /************************************************************************/
1575 /* BUS Methods								*/
1576 /************************************************************************/
1577 
1578 
1579 static int
1580 pccbb_activate_resource(device_t brdev, device_t child, int type, int rid,
1581     struct resource *r)
1582 {
1583 	struct pccbb_softc *sc = device_get_softc(brdev);
1584 
1585 	if (sc->sc_flags & PCCBB_16BIT_CARD)
1586 		return (pccbb_pcic_activate_resource(brdev, child, type, rid, r));
1587 	else
1588 		return (pccbb_cardbus_activate_resource(brdev, child, type, rid,
1589 		    r));
1590 }
1591 
1592 static int
1593 pccbb_deactivate_resource(device_t brdev, device_t child, int type,
1594     int rid, struct resource *r)
1595 {
1596 	struct pccbb_softc *sc = device_get_softc(brdev);
1597 
1598 	if (sc->sc_flags & PCCBB_16BIT_CARD)
1599 		return (pccbb_pcic_deactivate_resource(brdev, child, type,
1600 		    rid, r));
1601 	else
1602 		return (pccbb_cardbus_deactivate_resource(brdev, child, type,
1603 		    rid, r));
1604 }
1605 
1606 static struct resource *
1607 pccbb_alloc_resource(device_t brdev, device_t child, int type, int *rid,
1608     u_long start, u_long end, u_long count, uint flags)
1609 {
1610 	struct pccbb_softc *sc = device_get_softc(brdev);
1611 
1612 	if (sc->sc_flags & PCCBB_16BIT_CARD)
1613 		return (pccbb_pcic_alloc_resource(brdev, child, type, rid,
1614 		    start, end, count, flags));
1615 	else
1616 		return (pccbb_cardbus_alloc_resource(brdev, child, type, rid,
1617 		    start, end, count, flags));
1618 }
1619 
1620 static int
1621 pccbb_release_resource(device_t brdev, device_t child, int type, int rid,
1622     struct resource *r)
1623 {
1624 	struct pccbb_softc *sc = device_get_softc(brdev);
1625 
1626 	if (sc->sc_flags & PCCBB_16BIT_CARD)
1627 		return (pccbb_pcic_release_resource(brdev, child, type,
1628 		    rid, r));
1629 	else
1630 		return (pccbb_cardbus_release_resource(brdev, child, type,
1631 		    rid, r));
1632 }
1633 
1634 static int
1635 pccbb_read_ivar(device_t brdev, device_t child, int which, uintptr_t *result)
1636 {
1637 	struct pccbb_softc *sc = device_get_softc(brdev);
1638 
1639 	switch (which) {
1640 	case PCIB_IVAR_BUS:
1641 		*result = sc->sc_secbus;
1642 		return (0);
1643 	}
1644 	return (ENOENT);
1645 }
1646 
1647 static int
1648 pccbb_write_ivar(device_t brdev, device_t child, int which, uintptr_t value)
1649 {
1650 	struct pccbb_softc *sc = device_get_softc(brdev);
1651 
1652 	switch (which) {
1653 	case PCIB_IVAR_BUS:
1654 		sc->sc_secbus = value;
1655 		break;
1656 	}
1657 	return (ENOENT);
1658 }
1659 
1660 /************************************************************************/
1661 /* PCI compat methods							*/
1662 /************************************************************************/
1663 
1664 static int
1665 pccbb_maxslots(device_t brdev)
1666 {
1667 	return (0);
1668 }
1669 
1670 static uint32_t
1671 pccbb_read_config(device_t brdev, int b, int s, int f, int reg, int width)
1672 {
1673 	/*
1674 	 * Pass through to the next ppb up the chain (i.e. our grandparent).
1675 	 */
1676 	return (PCIB_READ_CONFIG(device_get_parent(device_get_parent(brdev)),
1677 	    b, s, f, reg, width));
1678 }
1679 
1680 static void
1681 pccbb_write_config(device_t brdev, int b, int s, int f, int reg, uint32_t val,
1682     int width)
1683 {
1684 	/*
1685 	 * Pass through to the next ppb up the chain (i.e. our grandparent).
1686 	 */
1687 	PCIB_WRITE_CONFIG(device_get_parent(device_get_parent(brdev)),
1688 	    b, s, f, reg, val, width);
1689 }
1690 
1691 static int
1692 pccbb_suspend(device_t self)
1693 {
1694 	int			error = 0;
1695 	struct pccbb_softc*	sc = device_get_softc(self);
1696 
1697 	bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intrhand);
1698 	error = bus_generic_suspend(self);
1699 	return (error);
1700 }
1701 
1702 static int
1703 pccbb_resume(device_t self)
1704 {
1705 	int	error = 0;
1706 	struct pccbb_softc *sc = (struct pccbb_softc *)device_get_softc(self);
1707 	uint32_t tmp;
1708 
1709 	pci_write_config(self, PCCBBR_SOCKBASE,
1710 	    rman_get_start(sc->sc_base_res), 4);
1711 	DEVPRINTF((self, "PCI Memory allocated: %08lx\n",
1712 	    rman_get_start(sc->sc_base_res)));
1713 
1714 	pccbb_chipinit(sc);
1715 
1716 	/* CSC Interrupt: Card detect interrupt on */
1717 	pccbb_setb(sc, PCCBB_SOCKET_MASK, PCCBB_SOCKET_MASK_CD);
1718 
1719 	/* reset interrupt */
1720 	tmp = pccbb_get(sc, PCCBB_SOCKET_EVENT);
1721 	pccbb_set(sc, PCCBB_SOCKET_EVENT, tmp);
1722 
1723 	/* re-establish the interrupt. */
1724 	/* XXX INTR_TYPE_BIOS IS WRONG here */
1725 	if (bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO, pccbb_intr, sc,
1726 	    &sc->sc_intrhand)) {
1727 		device_printf(self, "couldn't re-establish interrupt");
1728 		bus_release_resource(self, SYS_RES_IRQ, 0, sc->sc_irq_res);
1729 		bus_release_resource(self, SYS_RES_MEMORY, PCCBBR_SOCKBASE,
1730 		    sc->sc_base_res);
1731 		mtx_destroy(&sc->sc_mtx);
1732 		error = ENOMEM;
1733 	}
1734 	bus_generic_resume(self);
1735 
1736 	/* wakeup thread */
1737 	if (!error) {
1738 		mtx_lock(&sc->sc_mtx);
1739 		wakeup(sc);
1740 		mtx_unlock(&sc->sc_mtx);
1741 	}
1742 	return (error);
1743 }
1744 
1745 static device_method_t pccbb_methods[] = {
1746 	/* Device interface */
1747 	DEVMETHOD(device_probe,			pccbb_probe),
1748 	DEVMETHOD(device_attach,		pccbb_attach),
1749 	DEVMETHOD(device_detach,		pccbb_detach),
1750 	DEVMETHOD(device_shutdown,		pccbb_shutdown),
1751 	DEVMETHOD(device_suspend,		pccbb_suspend),
1752 	DEVMETHOD(device_resume,		pccbb_resume),
1753 
1754 	/* bus methods */
1755 	DEVMETHOD(bus_print_child,		bus_generic_print_child),
1756 	DEVMETHOD(bus_read_ivar,		pccbb_read_ivar),
1757 	DEVMETHOD(bus_write_ivar,		pccbb_write_ivar),
1758 	DEVMETHOD(bus_alloc_resource,		pccbb_alloc_resource),
1759 	DEVMETHOD(bus_release_resource,		pccbb_release_resource),
1760 	DEVMETHOD(bus_activate_resource,	pccbb_activate_resource),
1761 	DEVMETHOD(bus_deactivate_resource,	pccbb_deactivate_resource),
1762 	DEVMETHOD(bus_driver_added,		pccbb_driver_added),
1763 	DEVMETHOD(bus_child_detached,		pccbb_child_detached),
1764 	DEVMETHOD(bus_setup_intr,		bus_generic_setup_intr),
1765 	DEVMETHOD(bus_teardown_intr,		bus_generic_teardown_intr),
1766 
1767 	/* 16-bit card interface */
1768 	DEVMETHOD(card_set_res_flags,		pccbb_pcic_set_res_flags),
1769 	DEVMETHOD(card_set_memory_offset,	pccbb_pcic_set_memory_offset),
1770 	DEVMETHOD(card_reprobe_card,		pccbb_card_reprobe),
1771 
1772 	/* power interface */
1773 	DEVMETHOD(power_enable_socket,		pccbb_power_enable_socket),
1774 	DEVMETHOD(power_disable_socket,		pccbb_power_disable_socket),
1775 
1776 	/* pcib compatibility interface */
1777 	DEVMETHOD(pcib_maxslots,		pccbb_maxslots),
1778 	DEVMETHOD(pcib_read_config,		pccbb_read_config),
1779 	DEVMETHOD(pcib_write_config,		pccbb_write_config),
1780 	{0,0}
1781 };
1782 
1783 static driver_t pccbb_driver = {
1784 	"pccbb",
1785 	pccbb_methods,
1786 	sizeof(struct pccbb_softc)
1787 };
1788 
1789 static devclass_t pccbb_devclass;
1790 
1791 DRIVER_MODULE(pccbb, pci, pccbb_driver, pccbb_devclass, 0, 0);
1792 
1793 SYSINIT(pccbb, SI_SUB_KTHREAD_IDLE, SI_ORDER_ANY, pccbb_start_threads, 0);
1794