xref: /freebsd/sys/dev/cardbus/cardbus.c (revision c0b9f4fe659b6839541970eb5675e57f4d814969)
1 /*-
2  * Copyright (c) 2003 M. Warner Losh.  All Rights Reserved.
3  * Copyright (c) 2000,2001 Jonathan Chen.  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  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/malloc.h>
33 #include <sys/module.h>
34 #include <sys/kernel.h>
35 #include <sys/sysctl.h>
36 
37 #include <sys/bus.h>
38 #include <machine/bus.h>
39 #include <sys/rman.h>
40 #include <machine/resource.h>
41 
42 #include <sys/pciio.h>
43 #include <dev/pci/pcivar.h>
44 #include <dev/pci/pcireg.h>
45 #include <dev/pci/pci_private.h>
46 
47 #include <dev/cardbus/cardbusreg.h>
48 #include <dev/cardbus/cardbusvar.h>
49 #include <dev/cardbus/cardbus_cis.h>
50 #include <dev/pccard/pccard_cis.h>
51 #include <dev/pccard/pccardvar.h>
52 
53 #include "power_if.h"
54 #include "pcib_if.h"
55 
56 /* sysctl vars */
57 SYSCTL_NODE(_hw, OID_AUTO, cardbus, CTLFLAG_RD, 0, "CardBus parameters");
58 
59 int    cardbus_debug = 0;
60 TUNABLE_INT("hw.cardbus.debug", &cardbus_debug);
61 SYSCTL_INT(_hw_cardbus, OID_AUTO, debug, CTLFLAG_RW,
62     &cardbus_debug, 0,
63   "CardBus debug");
64 
65 int    cardbus_cis_debug = 0;
66 TUNABLE_INT("hw.cardbus.cis_debug", &cardbus_cis_debug);
67 SYSCTL_INT(_hw_cardbus, OID_AUTO, cis_debug, CTLFLAG_RW,
68     &cardbus_cis_debug, 0,
69   "CardBus CIS debug");
70 
71 #define	DPRINTF(a) if (cardbus_debug) printf a
72 #define	DEVPRINTF(x) if (cardbus_debug) device_printf x
73 
74 
75 static void	cardbus_add_map(device_t cbdev, device_t child, int reg);
76 static int	cardbus_alloc_resources(device_t cbdev, device_t child);
77 static int	cardbus_attach(device_t cbdev);
78 static int	cardbus_attach_card(device_t cbdev);
79 static int	cardbus_barsort(const void *a, const void *b);
80 static int	cardbus_detach(device_t cbdev);
81 static int	cardbus_detach_card(device_t cbdev);
82 static void	cardbus_device_setup_regs(device_t brdev, int b, int s, int f,
83 		    pcicfgregs *cfg);
84 static void	cardbus_driver_added(device_t cbdev, driver_t *driver);
85 static void	cardbus_pickup_maps(device_t cbdev, device_t child);
86 static int	cardbus_probe(device_t cbdev);
87 static int	cardbus_read_ivar(device_t cbdev, device_t child, int which,
88 		    uintptr_t *result);
89 static void	cardbus_release_all_resources(device_t cbdev,
90 		    struct cardbus_devinfo *dinfo);
91 static int	cardbus_write_ivar(device_t cbdev, device_t child, int which,
92 		    uintptr_t value);
93 
94 /*
95  * Resource allocation
96  */
97 /*
98  * Adding a memory/io resource (sans CIS)
99  */
100 
101 static void
102 cardbus_add_map(device_t cbdev, device_t child, int reg)
103 {
104 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
105 	struct resource_list_entry *rle;
106 	uint32_t size;
107 	uint32_t testval;
108 	int type;
109 
110 	STAILQ_FOREACH(rle, &dinfo->pci.resources, link) {
111 		if (rle->rid == reg)
112 			return;
113 	}
114 
115 	if (reg == PCIR_BIOS)
116 		testval = PCIM_BIOS_ADDR_MASK;
117 	else
118 		testval = ~0;
119 
120 	pci_write_config(child, reg, testval, 4);
121 	testval = pci_read_config(child, reg, 4);
122 
123 	if (testval == ~0 || testval == 0)
124 		return;
125 
126 	if ((testval & 1) == 0)
127 		type = SYS_RES_MEMORY;
128 	else
129 		type = SYS_RES_IOPORT;
130 
131 	size = CARDBUS_MAPREG_MEM_SIZE(testval);
132 	device_printf(cbdev, "Resource not specified in CIS: id=%x, size=%x\n",
133 	    reg, size);
134 	resource_list_add(&dinfo->pci.resources, type, reg, 0UL, ~0UL, size);
135 }
136 
137 static void
138 cardbus_pickup_maps(device_t cbdev, device_t child)
139 {
140 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
141 	int reg;
142 
143 	/*
144 	 * Try to pick up any resources that was not specified in CIS.
145 	 * Maybe this isn't any longer necessary now that we have fixed
146 	 * CIS parsing and we should filter things here?  XXX
147 	 */
148 	for (reg = 0; reg < dinfo->pci.cfg.nummaps; reg++)
149 		cardbus_add_map(cbdev, child, PCIR_BAR(reg));
150 }
151 
152 static int
153 cardbus_barsort(const void *a, const void *b)
154 {
155 	return ((*(const struct resource_list_entry * const *)b)->count -
156 	    (*(const struct resource_list_entry * const *)a)->count);
157 }
158 
159 /* XXX this function is too long */
160 static int
161 cardbus_alloc_resources(device_t cbdev, device_t child)
162 {
163 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
164 	int count;
165 	struct resource_list_entry *rle;
166 	struct resource_list_entry **barlist;
167 	int tmp;
168 	uint32_t mem_psize = 0, mem_nsize = 0, io_size = 0;
169 	struct resource *res;
170 	uint32_t start,end;
171 	int rid, flags;
172 
173 	count = 0;
174 	STAILQ_FOREACH(rle, &dinfo->pci.resources, link) {
175 		count++;
176 	}
177 	if (count == 0)
178 		return (0);
179 	barlist = malloc(sizeof(struct resource_list_entry*) * count, M_DEVBUF,
180 	    M_WAITOK);
181 	count = 0;
182 	STAILQ_FOREACH(rle, &dinfo->pci.resources, link) {
183 		barlist[count] = rle;
184 		if (rle->type == SYS_RES_IOPORT) {
185 			io_size += rle->count;
186 		} else if (rle->type == SYS_RES_MEMORY) {
187 			if (dinfo->mprefetchable & BARBIT(rle->rid))
188 				mem_psize += rle->count;
189 			else
190 				mem_nsize += rle->count;
191 		}
192 		count++;
193 	}
194 
195 	/*
196 	 * We want to allocate the largest resource first, so that our
197 	 * allocated memory is packed.
198 	 */
199 	qsort(barlist, count, sizeof(struct resource_list_entry *),
200 	    cardbus_barsort);
201 
202 	/* Allocate prefetchable memory */
203 	flags = 0;
204 	for (tmp = 0; tmp < count; tmp++) {
205 		rle = barlist[tmp];
206 		if (rle->res == NULL &&
207 		    rle->type == SYS_RES_MEMORY &&
208 		    dinfo->mprefetchable & BARBIT(rle->rid)) {
209 			flags = rman_make_alignment_flags(rle->count);
210 			break;
211 		}
212 	}
213 	if (flags > 0) { /* If any prefetchable memory is requested... */
214 		/*
215 		 * First we allocate one big space for all resources of this
216 		 * type.  We do this because our parent, pccbb, needs to open
217 		 * a window to forward all addresses within the window, and
218 		 * it would be best if nobody else has resources allocated
219 		 * within the window.
220 		 * (XXX: Perhaps there might be a better way to do this?)
221 		 */
222 		rid = 0;
223 		res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
224 		    (dinfo->mprefetchable & dinfo->mbelow1mb)?0xFFFFF:~0UL,
225 		    mem_psize, flags);
226 		if (res == NULL) {
227 			device_printf(cbdev,
228 			    "Can't get memory for prefetch mem\n");
229 			free(barlist, M_DEVBUF);
230 			return (EIO);
231 		}
232 		start = rman_get_start(res);
233 		end = rman_get_end(res);
234 		DEVPRINTF((cbdev, "Prefetchable memory at %x-%x\n", start, end));
235 		/*
236 		 * Now that we know the region is free, release it and hand it
237 		 * out piece by piece.
238 		 */
239 		bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
240 		for (tmp = 0; tmp < count; tmp++) {
241 			rle = barlist[tmp];
242 			if (rle->type == SYS_RES_MEMORY &&
243 			    dinfo->mprefetchable & BARBIT(rle->rid)) {
244 				rle->res = bus_alloc_resource(cbdev,
245 				    rle->type, &rle->rid, start, end,
246 				    rle->count,
247 				    rman_make_alignment_flags(rle->count));
248 				if (rle->res != NULL) {
249 					rle->start = rman_get_start(rle->res);
250 					rle->end = rman_get_end(rle->res);
251 					pci_write_config(child,
252 					    rle->rid, rle->start, 4);
253 				}
254 			}
255 		}
256 	}
257 
258 	/* Allocate non-prefetchable memory */
259 	flags = 0;
260 	for (tmp = 0; tmp < count; tmp++) {
261 		rle = barlist[tmp];
262 		if (rle->type == SYS_RES_MEMORY &&
263 		    (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) {
264 			flags = rman_make_alignment_flags(rle->count);
265 			break;
266 		}
267 	}
268 	if (flags > 0) { /* If any non-prefetchable memory is requested... */
269 		/*
270 		 * First we allocate one big space for all resources of this
271 		 * type.  We do this because our parent, pccbb, needs to open
272 		 * a window to forward all addresses within the window, and
273 		 * it would be best if nobody else has resources allocated
274 		 * within the window.
275 		 * (XXX: Perhaps there might be a better way to do this?)
276 		 */
277 		rid = 0;
278 		res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
279 		    ((~dinfo->mprefetchable) & dinfo->mbelow1mb)?0xFFFFF:~0UL,
280 		    mem_nsize, flags);
281 		if (res == NULL) {
282 			device_printf(cbdev,
283 			    "Can't get memory for non-prefetch mem\n");
284 			free(barlist, M_DEVBUF);
285 			return (EIO);
286 		}
287 		start = rman_get_start(res);
288 		end = rman_get_end(res);
289 		DEVPRINTF((cbdev, "Non-prefetchable memory at %x-%x\n",
290 		    start, end));
291 		/*
292 		 * Now that we know the region is free, release it and hand it
293 		 * out piece by piece.
294 		 */
295 		bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
296 		for (tmp = 0; tmp < count; tmp++) {
297 			rle = barlist[tmp];
298 			if (rle->type == SYS_RES_MEMORY &&
299 			    (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) {
300 				rle->res = bus_alloc_resource(cbdev,
301 				    rle->type, &rle->rid, start, end,
302 				    rle->count,
303 				    rman_make_alignment_flags(rle->count));
304 				if (rle->res == NULL) {
305 					DEVPRINTF((cbdev, "Cannot pre-allocate "
306 					    "memory for cardbus device\n"));
307 					free(barlist, M_DEVBUF);
308 					return (ENOMEM);
309 				}
310 				rle->start = rman_get_start(rle->res);
311 				rle->end = rman_get_end(rle->res);
312 				pci_write_config(child,
313 				    rle->rid, rle->start, 4);
314 			}
315 		}
316 	}
317 
318 	/* Allocate IO ports */
319 	flags = 0;
320 	for (tmp = 0; tmp < count; tmp++) {
321 		rle = barlist[tmp];
322 		if (rle->type == SYS_RES_IOPORT) {
323 			flags = rman_make_alignment_flags(rle->count);
324 			break;
325 		}
326 	}
327 	if (flags > 0) { /* If any IO port is requested... */
328 		/*
329 		 * First we allocate one big space for all resources of this
330 		 * type.  We do this because our parent, pccbb, needs to open
331 		 * a window to forward all addresses within the window, and
332 		 * it would be best if nobody else has resources allocated
333 		 * within the window.
334 		 * (XXX: Perhaps there might be a better way to do this?)
335 		 */
336 		rid = 0;
337 		res = bus_alloc_resource(cbdev, SYS_RES_IOPORT, &rid, 0,
338 		    (dinfo->ibelow1mb)?0xFFFFF:~0UL, io_size, flags);
339 		if (res == NULL) {
340 			device_printf(cbdev,
341 			    "Can't get memory for IO ports\n");
342 			free(barlist, M_DEVBUF);
343 			return (EIO);
344 		}
345 		start = rman_get_start(res);
346 		end = rman_get_end(res);
347 		DEVPRINTF((cbdev, "IO port at %x-%x\n", start, end));
348 		/*
349 		 * Now that we know the region is free, release it and hand it
350 		 * out piece by piece.
351 		 */
352 		bus_release_resource(cbdev, SYS_RES_IOPORT, rid, res);
353 		for (tmp = 0; tmp < count; tmp++) {
354 			rle = barlist[tmp];
355 			if (rle->type == SYS_RES_IOPORT) {
356 				rle->res = bus_alloc_resource(cbdev,
357 				    rle->type, &rle->rid, start, end,
358 				    rle->count,
359 				    rman_make_alignment_flags(rle->count));
360 				if (rle->res == NULL) {
361 					DEVPRINTF((cbdev, "Cannot pre-allocate "
362 					    "IO port for cardbus device\n"));
363 					free(barlist, M_DEVBUF);
364 					return (ENOMEM);
365 				}
366 				rle->start = rman_get_start(rle->res);
367 				rle->end = rman_get_end(rle->res);
368 				pci_write_config(child,
369 				    rle->rid, rle->start, 4);
370 			}
371 		}
372 	}
373 
374 	/* Allocate IRQ */
375 	rid = 0;
376 	res = bus_alloc_resource_any(cbdev, SYS_RES_IRQ, &rid, RF_SHAREABLE);
377 	if (res == NULL) {
378 		device_printf(cbdev, "Can't get memory for irq\n");
379 		free(barlist, M_DEVBUF);
380 		return (EIO);
381 	}
382 	start = rman_get_start(res);
383 	end = rman_get_end(res);
384 	resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid, start, end,
385 	    1);
386 	rle = resource_list_find(&dinfo->pci.resources, SYS_RES_IRQ, rid);
387 	rle->res = res;
388 	dinfo->pci.cfg.intline = start;
389 	pci_write_config(child, PCIR_INTLINE, start, 1);
390 
391 	free(barlist, M_DEVBUF);
392 	return (0);
393 }
394 
395 /************************************************************************/
396 /* Probe/Attach								*/
397 /************************************************************************/
398 
399 static int
400 cardbus_probe(device_t cbdev)
401 {
402 	device_set_desc(cbdev, "CardBus bus");
403 	return 0;
404 }
405 
406 static int
407 cardbus_attach(device_t cbdev)
408 {
409 	struct cardbus_softc *sc = device_get_softc(cbdev);
410 
411 	sc->sc_dev = cbdev;
412 	cardbus_device_create(sc);
413 	return 0;
414 }
415 
416 static int
417 cardbus_detach(device_t cbdev)
418 {
419 	struct cardbus_softc *sc = device_get_softc(cbdev);
420 
421 	cardbus_detach_card(cbdev);
422 	cardbus_device_destroy(sc);
423 	return 0;
424 }
425 
426 static int
427 cardbus_suspend(device_t self)
428 {
429 	cardbus_detach_card(self);
430 	return (0);
431 }
432 
433 static int
434 cardbus_resume(device_t self)
435 {
436 	return (0);
437 }
438 
439 /************************************************************************/
440 /* Attach/Detach card							*/
441 /************************************************************************/
442 
443 static void
444 cardbus_device_setup_regs(device_t brdev, int b, int s, int f, pcicfgregs *cfg)
445 {
446 	PCIB_WRITE_CONFIG(brdev, b, s, f, PCIR_INTLINE,
447 	    pci_get_irq(device_get_parent(brdev)), 1);
448 	cfg->intline = PCIB_READ_CONFIG(brdev, b, s, f, PCIR_INTLINE, 1);
449 
450 	PCIB_WRITE_CONFIG(brdev, b, s, f, PCIR_CACHELNSZ, 0x08, 1);
451 	cfg->cachelnsz = PCIB_READ_CONFIG(brdev, b, s, f, PCIR_CACHELNSZ, 1);
452 
453 	PCIB_WRITE_CONFIG(brdev, b, s, f, PCIR_LATTIMER, 0xa8, 1);
454 	cfg->lattimer = PCIB_READ_CONFIG(brdev, b, s, f, PCIR_LATTIMER, 1);
455 
456 	PCIB_WRITE_CONFIG(brdev, b, s, f, PCIR_MINGNT, 0x14, 1);
457 	cfg->mingnt = PCIB_READ_CONFIG(brdev, b, s, f, PCIR_MINGNT, 1);
458 
459 	PCIB_WRITE_CONFIG(brdev, b, s, f, PCIR_MAXLAT, 0x14, 1);
460 	cfg->maxlat = PCIB_READ_CONFIG(brdev, b, s, f, PCIR_MAXLAT, 1);
461 }
462 
463 static int
464 cardbus_attach_card(device_t cbdev)
465 {
466 	device_t brdev = device_get_parent(cbdev);
467 	device_t child;
468 	int cardattached = 0;
469 	int bus, slot, func;
470 	int cardbusfunchigh = 0;
471 
472 	cardbus_detach_card(cbdev); /* detach existing cards */
473 	POWER_ENABLE_SOCKET(brdev, cbdev);
474 	bus = pcib_get_bus(cbdev);
475 	slot = 0;
476 	/* For each function, set it up and try to attach a driver to it */
477 	for (func = 0; func <= cardbusfunchigh; func++) {
478 		struct cardbus_devinfo *dinfo;
479 
480 		dinfo = (struct cardbus_devinfo *)
481 		    pci_read_device(brdev, bus, slot, func,
482 			sizeof(struct cardbus_devinfo));
483 		if (dinfo == NULL)
484 			continue;
485 		if (dinfo->pci.cfg.mfdev)
486 			cardbusfunchigh = PCI_FUNCMAX;
487 
488 		cardbus_device_setup_regs(brdev, bus, slot, func,
489 		    &dinfo->pci.cfg);
490 		child = device_add_child(cbdev, NULL, -1);
491 		if (child == NULL) {
492 			DEVPRINTF((cbdev, "Cannot add child!\n"));
493 			pci_freecfg((struct pci_devinfo *)dinfo);
494 			continue;
495 		}
496 		dinfo->pci.cfg.dev = child;
497 		resource_list_init(&dinfo->pci.resources);
498 		device_set_ivars(child, dinfo);
499 		if (cardbus_do_cis(cbdev, child) != 0) {
500 			DEVPRINTF((cbdev, "Can't parse cis\n"));
501 			pci_freecfg((struct pci_devinfo *)dinfo);
502 			continue;
503 		}
504 		cardbus_pickup_maps(cbdev, child);
505 		cardbus_alloc_resources(cbdev, child);
506 		pci_print_verbose(&dinfo->pci);
507 		if (device_probe_and_attach(child) != 0)
508 			cardbus_release_all_resources(cbdev, dinfo);
509 		else
510 			cardattached++;
511 	}
512 	if (cardattached > 0)
513 		return (0);
514 	POWER_DISABLE_SOCKET(brdev, cbdev);
515 	return (ENOENT);
516 }
517 
518 static int
519 cardbus_detach_card(device_t cbdev)
520 {
521 	int numdevs;
522 	device_t *devlist;
523 	int tmp;
524 	int err = 0;
525 
526 	device_get_children(cbdev, &devlist, &numdevs);
527 
528 	if (numdevs == 0) {
529 		free(devlist, M_TEMP);
530 		return (ENOENT);
531 	}
532 
533 	for (tmp = 0; tmp < numdevs; tmp++) {
534 		struct cardbus_devinfo *dinfo = device_get_ivars(devlist[tmp]);
535 		int status = device_get_state(devlist[tmp]);
536 
537 		if (dinfo->pci.cfg.dev != devlist[tmp])
538 			device_printf(cbdev, "devinfo dev mismatch\n");
539 		if (status == DS_ATTACHED || status == DS_BUSY)
540 			device_detach(devlist[tmp]);
541 		cardbus_release_all_resources(cbdev, dinfo);
542 		device_delete_child(cbdev, devlist[tmp]);
543 		pci_freecfg((struct pci_devinfo *)dinfo);
544 	}
545 	POWER_DISABLE_SOCKET(device_get_parent(cbdev), cbdev);
546 	free(devlist, M_TEMP);
547 	return (err);
548 }
549 
550 static void
551 cardbus_driver_added(device_t cbdev, driver_t *driver)
552 {
553 	int numdevs;
554 	device_t *devlist;
555 	device_t dev;
556 	int i;
557 	struct cardbus_devinfo *dinfo;
558 
559 	DEVICE_IDENTIFY(driver, cbdev);
560 	device_get_children(cbdev, &devlist, &numdevs);
561 	/*
562 	 * If there are no drivers attached, but there are children,
563 	 * then power the card up.
564 	 */
565 	for (i = 0; i < numdevs; i++) {
566 		dev = devlist[i];
567 		if (device_get_state(dev) != DS_NOTPRESENT)
568 		    break;
569 	}
570 	if (i > 0 && i == numdevs)
571 		POWER_ENABLE_SOCKET(device_get_parent(cbdev), cbdev);
572 	for (i = 0; i < numdevs; i++) {
573 		dev = devlist[i];
574 		if (device_get_state(dev) != DS_NOTPRESENT)
575 			continue;
576 		dinfo = device_get_ivars(dev);
577 		pci_print_verbose(&dinfo->pci);
578 		resource_list_init(&dinfo->pci.resources);
579 		cardbus_do_cis(cbdev, dev);
580 		cardbus_pickup_maps(cbdev, dev);
581 		cardbus_alloc_resources(cbdev, dev);
582 		if (device_probe_and_attach(dev) != 0)
583 			cardbus_release_all_resources(cbdev, dinfo);
584 	}
585 	free(devlist, M_TEMP);
586 }
587 
588 static void
589 cardbus_release_all_resources(device_t cbdev, struct cardbus_devinfo *dinfo)
590 {
591 	struct resource_list_entry *rle;
592 
593 	/* Free all allocated resources */
594 	STAILQ_FOREACH(rle, &dinfo->pci.resources, link) {
595 		if (rle->res) {
596 			if (rman_get_device(rle->res) != cbdev)
597 				device_printf(cbdev, "release_all_resource: "
598 				    "Resource still owned by child, oops. "
599 				    "(type=%d, rid=%d, addr=%lx)\n",
600 				    rle->type, rle->rid,
601 				    rman_get_start(rle->res));
602 			BUS_RELEASE_RESOURCE(device_get_parent(cbdev),
603 			    cbdev, rle->type, rle->rid, rle->res);
604 			rle->res = NULL;
605 			/*
606 			 * zero out config so the card won't acknowledge
607 			 * access to the space anymore
608 			 */
609 			pci_write_config(dinfo->pci.cfg.dev, rle->rid, 0, 4);
610 		}
611 	}
612 	resource_list_free(&dinfo->pci.resources);
613 }
614 
615 /************************************************************************/
616 /* Other Bus Methods							*/
617 /************************************************************************/
618 
619 static int
620 cardbus_read_ivar(device_t cbdev, device_t child, int which, uintptr_t *result)
621 {
622 	struct cardbus_devinfo *dinfo;
623 	pcicfgregs *cfg;
624 
625 	dinfo = device_get_ivars(child);
626 	cfg = &dinfo->pci.cfg;
627 
628 	switch (which) {
629 	case PCI_IVAR_ETHADDR:
630 		/*
631 		 * The generic accessor doesn't deal with failure, so
632 		 * we set the return value, then return an error.
633 		 */
634 		if (dinfo->fepresent & (1 << PCCARD_TPLFE_TYPE_LAN_NID)) {
635 			*((uint8_t **) result) = dinfo->funce.lan.nid;
636 			break;
637 		}
638 		*((uint8_t **) result) = NULL;
639 		return (EINVAL);
640 	default:
641 		return (pci_read_ivar(cbdev, child, which, result));
642 	}
643 	return 0;
644 }
645 
646 static int
647 cardbus_write_ivar(device_t cbdev, device_t child, int which, uintptr_t value)
648 {
649 	return(pci_write_ivar(cbdev, child, which, value));
650 }
651 
652 static device_method_t cardbus_methods[] = {
653 	/* Device interface */
654 	DEVMETHOD(device_probe,		cardbus_probe),
655 	DEVMETHOD(device_attach,	cardbus_attach),
656 	DEVMETHOD(device_detach,	cardbus_detach),
657 	DEVMETHOD(device_suspend,	cardbus_suspend),
658 	DEVMETHOD(device_resume,	cardbus_resume),
659 
660 	/* Bus interface */
661 	DEVMETHOD(bus_read_ivar,	cardbus_read_ivar),
662 	DEVMETHOD(bus_write_ivar,	cardbus_write_ivar),
663 	DEVMETHOD(bus_driver_added,	cardbus_driver_added),
664 
665 	/* Card Interface */
666 	DEVMETHOD(card_attach_card,	cardbus_attach_card),
667 	DEVMETHOD(card_detach_card,	cardbus_detach_card),
668 
669 	{0,0}
670 };
671 
672 DECLARE_CLASS(pci_driver);
673 DEFINE_CLASS_1(cardbus, cardbus_driver, cardbus_methods,
674     sizeof(struct cardbus_softc), pci_driver);
675 
676 static devclass_t cardbus_devclass;
677 
678 DRIVER_MODULE(cardbus, cbb, cardbus_driver, cardbus_devclass, 0, 0);
679 MODULE_VERSION(cardbus, 1);
680