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