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