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