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