xref: /freebsd/sys/dev/cardbus/cardbus.c (revision 1b6c76a2fe091c74f08427e6c870851025a9cf67)
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  * Cardbus Bus Driver
33  *
34  * much of the bus code was stolen directly from sys/pci/pci.c
35  *   (Copyright (c) 1997, Stefan Esser <se@freebsd.org>)
36  *
37  * Written by Jonathan Chen <jon@freebsd.org>
38  */
39 
40 #define CARDBUS_DEBUG
41 
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/malloc.h>
45 #include <sys/kernel.h>
46 
47 #include <sys/bus.h>
48 #include <machine/bus.h>
49 #include <sys/rman.h>
50 #include <machine/resource.h>
51 
52 #include <pci/pcivar.h>
53 #include <pci/pcireg.h>
54 #include <sys/pciio.h>
55 
56 #include <dev/cardbus/cardbusreg.h>
57 #include <dev/cardbus/cardbusvar.h>
58 #include <dev/cardbus/cardbus_cis.h>
59 
60 #include "power_if.h"
61 #include "card_if.h"
62 #include "pcib_if.h"
63 
64 #if defined CARDBUS_DEBUG
65 #define STATIC
66 #define DPRINTF(a) printf a
67 #define DEVPRINTF(x) device_printf x
68 #else
69 #define STATIC static
70 #define DPRINTF(a)
71 #define DEVPRINTF(x)
72 #endif
73 
74 #if !defined(lint)
75 static const char rcsid[] =
76   "$FreeBSD$";
77 #endif
78 
79 struct cardbus_quirk {
80 	u_int32_t devid;	/* Vendor/device of the card */
81 	int	type;
82 #define CARDBUS_QUIRK_MAP_REG	1 /* PCI map register in weird place */
83 	int	arg1;
84 	int	arg2;
85 };
86 
87 struct cardbus_quirk cardbus_quirks[] = {
88 	{ 0 }
89 };
90 
91 static int cardbus_probe(device_t dev);
92 static int cardbus_attach(device_t dev);
93 static void device_setup_regs(device_t cbdev, int b, int s, int f,
94 			      pcicfgregs *cfg);
95 static int cardbus_attach_card(device_t dev);
96 static int cardbus_detach_card(device_t dev, int flags);
97 static struct cardbus_devinfo *cardbus_read_device(device_t pcib,
98 						   int b, int s, int f);
99 static void cardbus_hdrtypedata(device_t pcib, int b, int s, int f,
100 				pcicfgregs *cfg);
101 static int cardbus_freecfg(struct cardbus_devinfo *dinfo);
102 static void cardbus_print_verbose(struct cardbus_devinfo *dinfo);
103 static int cardbus_set_resource(device_t dev, device_t child, int type,
104 				int rid, u_long start, u_long count);
105 static int cardbus_get_resource(device_t dev, device_t child, int type,
106 				int rid, u_long *startp, u_long *countp);
107 static void cardbus_delete_resource(device_t dev, device_t child, int type,
108 				    int rid);
109 static int cardbus_set_resource_method(device_t dev, device_t child, int type,
110 				       int rid, u_long start, u_long count);
111 static int cardbus_get_resource_method(device_t dev, device_t child, int type,
112 				      int rid, u_long *startp, u_long *countp);
113 static int cardbus_add_map(device_t bdev, device_t dev, pcicfgregs *cfg,
114 			   int reg);
115 static void cardbus_add_resources(device_t dev, pcicfgregs* cfg);
116 static void cardbus_release_all_resources(device_t dev,
117 					  struct resource_list *rl);
118 static struct resource* cardbus_alloc_resource(device_t self, device_t child,
119 					       int type, int* rid,u_long start,
120 					       u_long end, u_long count,
121 					       u_int flags);
122 static int cardbus_release_resource(device_t dev, device_t child, int type,
123 				    int rid, struct resource *r);
124 static int cardbus_print_resources(struct resource_list *rl, const char *name,
125 				   int type, const char *format);
126 static int cardbus_print_child(device_t dev, device_t child);
127 static void cardbus_probe_nomatch(device_t dev, device_t child);
128 static int cardbus_read_ivar(device_t dev, device_t child, int which,
129 			     u_long *result);
130 static int cardbus_write_ivar(device_t dev, device_t child, int which,
131 			      uintptr_t value);
132 static u_int32_t cardbus_read_config_method(device_t dev, device_t child,
133 					    int reg, int width);
134 static void cardbus_write_config_method(device_t dev, device_t child, int reg,
135 					u_int32_t val, int width);
136 
137 /************************************************************************/
138 /* Probe/Attach								*/
139 /************************************************************************/
140 
141 static int
142 cardbus_probe(device_t dev)
143 {
144 	device_set_desc(dev, "Cardbus bus (newcard)");
145 	return 0;
146 }
147 
148 static int
149 cardbus_attach(device_t dev)
150 {
151 	return 0;
152 }
153 
154 static int
155 cardbus_detach(device_t dev)
156 {
157 	cardbus_detach_card(dev, DETACH_FORCE);
158 	return 0;
159 }
160 
161 /************************************************************************/
162 /* Attach/Detach card							*/
163 /************************************************************************/
164 
165 static void
166 device_setup_regs(device_t bdev, int b, int s, int f, pcicfgregs *cfg)
167 {
168 	PCIB_WRITE_CONFIG(bdev, b, s, f, PCIR_INTLINE,
169 			  pci_get_irq(device_get_parent(bdev)), 1);
170 	cfg->intline = PCIB_READ_CONFIG(bdev, b, s, f, PCIR_INTLINE, 1);
171 
172 	PCIB_WRITE_CONFIG(bdev, b, s, f, PCIR_CACHELNSZ, 0x08, 1);
173 	cfg->cachelnsz = PCIB_READ_CONFIG(bdev, b, s, f, PCIR_CACHELNSZ, 1);
174 
175 	PCIB_WRITE_CONFIG(bdev, b, s, f, PCIR_LATTIMER, 0xa8, 1);
176 	cfg->lattimer = PCIB_READ_CONFIG(bdev, b, s, f, PCIR_LATTIMER, 1);
177 
178 	PCIB_WRITE_CONFIG(bdev, b, s, f, PCIR_MINGNT, 0x14, 1);
179 	cfg->mingnt = PCIB_READ_CONFIG(bdev, b, s, f, PCIR_MINGNT, 1);
180 
181 	PCIB_WRITE_CONFIG(bdev, b, s, f, PCIR_MAXLAT, 0x14, 1);
182 	cfg->maxlat = PCIB_READ_CONFIG(bdev, b, s, f, PCIR_MAXLAT, 1);
183 }
184 
185 static int
186 cardbus_attach_card(device_t dev)
187 {
188 	device_t bdev = device_get_parent(dev);
189 	int cardattached = 0;
190 	static int curr_bus_number = 2; /* XXX EVILE BAD (see below) */
191 	int bus, slot, func;
192 
193 	cardbus_detach_card(dev, DETACH_NOWARN); /* detach existing cards */
194 
195 	POWER_ENABLE_SOCKET(bdev, dev);
196 	bus = pcib_get_bus(dev);
197 	if (bus == 0) {
198 		/*
199 		 * XXX EVILE BAD XXX
200 		 * Not all BIOSes initialize the secondary bus number properly,
201 		 * so if the default is bad, we just put one in and hope it
202 		 * works.
203 		 */
204 		bus = curr_bus_number;
205 		pci_write_config (bdev, PCIR_SECBUS_2, curr_bus_number, 1);
206 		pci_write_config (bdev, PCIR_SUBBUS_2, curr_bus_number+2, 1);
207 		curr_bus_number += 3;
208 	}
209 	for (slot = 0; slot <= CARDBUS_SLOTMAX; slot++) {
210 		int cardbusfunchigh = 0;
211 		for (func = 0; func <= cardbusfunchigh; func++) {
212 			struct cardbus_devinfo *dinfo =
213 				cardbus_read_device(bdev, bus, slot, func);
214 
215 			if (dinfo == NULL) continue;
216 			if (dinfo->cfg.mfdev)
217 				cardbusfunchigh = CARDBUS_FUNCMAX;
218 			device_setup_regs(bdev, bus, slot, func, &dinfo->cfg);
219 			cardbus_print_verbose(dinfo);
220 			dinfo->cfg.dev = device_add_child(dev, NULL, -1);
221 			if (!dinfo->cfg.dev) {
222 				DEVPRINTF((dev, "Cannot add child!\n"));
223 				cardbus_freecfg(dinfo);
224 				continue;
225 			}
226 			resource_list_init(&dinfo->resources);
227 			device_set_ivars(dinfo->cfg.dev, dinfo);
228 			cardbus_add_resources(dinfo->cfg.dev, &dinfo->cfg);
229 			cardbus_do_cis(dev, dinfo->cfg.dev);
230 			if (device_probe_and_attach(dinfo->cfg.dev) != 0) {
231 				cardbus_release_all_resources(dinfo->cfg.dev,
232 						      &dinfo->resources);
233 			} else
234 				cardattached++;
235 		}
236 	}
237 
238 	if (cardattached > 0) return 0;
239 	POWER_DISABLE_SOCKET(bdev, dev);
240 	return ENOENT;
241 }
242 
243 static int
244 cardbus_detach_card(device_t dev, int flags)
245 {
246 	int numdevs;
247 	device_t *devlist;
248 	int tmp;
249 	int err=0;
250 
251 	device_get_children(dev, &devlist, &numdevs);
252 
253 	if (numdevs == 0) {
254 		if (!(flags & DETACH_NOWARN)) {
255 			DEVPRINTF((dev, "Detaching card: no cards to detach!\n"));
256 			POWER_DISABLE_SOCKET(device_get_parent(dev), dev);
257 		}
258 		free(devlist, M_TEMP);
259 		return ENOENT;
260 	}
261 
262 	for (tmp = 0; tmp < numdevs; tmp++) {
263 		struct cardbus_devinfo *dinfo = device_get_ivars(devlist[tmp]);
264 		int status = device_get_state(devlist[tmp]);
265 
266 		if (status == DS_ATTACHED || status == DS_BUSY) {
267 			if (device_detach(dinfo->cfg.dev) == 0 ||
268 			    flags & DETACH_FORCE){
269 				cardbus_release_all_resources(dinfo->cfg.dev,
270 							      &dinfo->resources);
271 				device_delete_child(dev, devlist[tmp]);
272 			} else {
273 				err++;
274 			}
275 			cardbus_freecfg(dinfo);
276 		} else {
277 			device_delete_child(dev, devlist[tmp]);
278 		}
279 	}
280 	if (err == 0)
281 		POWER_DISABLE_SOCKET(device_get_parent(dev), dev);
282 	free(devlist, M_TEMP);
283 	return err;
284 }
285 
286 static void
287 cardbus_driver_added(device_t dev, driver_t *driver)
288 {
289 	int numdevs;
290 	device_t *devlist;
291 	device_t bdev = device_get_parent(dev);
292 	int tmp, cardattached;
293 
294 	device_get_children(dev, &devlist, &numdevs);
295 
296 	cardattached = 0;
297 	for (tmp = 0; tmp < numdevs; tmp++) {
298 		if (device_get_state(devlist[tmp]) != DS_NOTPRESENT)
299 			cardattached++;
300 	}
301 
302 	if (cardattached == 0)
303 		POWER_ENABLE_SOCKET(bdev, dev);
304 	DEVICE_IDENTIFY(driver, dev);
305 	for (tmp = 0; tmp < numdevs; tmp++) {
306 		if (device_get_state(devlist[tmp]) == DS_NOTPRESENT){
307 			struct cardbus_devinfo *dinfo;
308 			dinfo = device_get_ivars(devlist[tmp]);
309 			resource_list_init(&dinfo->resources);
310 			cardbus_add_resources(dinfo->cfg.dev, &dinfo->cfg);
311 			cardbus_do_cis(dev, dinfo->cfg.dev);
312 			if (device_probe_and_attach(dinfo->cfg.dev) != 0) {
313 				cardbus_release_all_resources(dinfo->cfg.dev,
314 						      &dinfo->resources);
315 			} else
316 				cardattached++;
317 		}
318 	}
319 
320 	if (cardattached == 0)
321 		POWER_DISABLE_SOCKET(bdev, dev);
322 	free(devlist, M_TEMP);
323 }
324 
325 /************************************************************************/
326 /* PCI-Like config reading (copied from pci.c				*/
327 /************************************************************************/
328 
329 /* read configuration header into pcicfgrect structure */
330 
331 static struct cardbus_devinfo *
332 cardbus_read_device(device_t pcib, int b, int s, int f)
333 {
334 #define REG(n, w)	PCIB_READ_CONFIG(pcib, b, s, f, n, w)
335 	pcicfgregs *cfg = NULL;
336 	struct cardbus_devinfo *devlist_entry = NULL;
337 
338 	if (PCIB_READ_CONFIG(pcib, b, s, f, PCIR_DEVVENDOR, 4) != -1) {
339 		devlist_entry = malloc(sizeof(struct cardbus_devinfo),
340 				       M_DEVBUF, M_WAITOK | M_ZERO);
341 		if (devlist_entry == NULL)
342 			return (NULL);
343 
344 		cfg = &devlist_entry->cfg;
345 
346 		cfg->bus		= b;
347 		cfg->slot		= s;
348 		cfg->func		= f;
349 		cfg->vendor		= REG(PCIR_VENDOR, 2);
350 		cfg->device		= REG(PCIR_DEVICE, 2);
351 		cfg->cmdreg		= REG(PCIR_COMMAND, 2);
352 		cfg->statreg		= REG(PCIR_STATUS, 2);
353 		cfg->baseclass		= REG(PCIR_CLASS, 1);
354 		cfg->subclass		= REG(PCIR_SUBCLASS, 1);
355 		cfg->progif		= REG(PCIR_PROGIF, 1);
356 		cfg->revid		= REG(PCIR_REVID, 1);
357 		cfg->hdrtype		= REG(PCIR_HEADERTYPE, 1);
358 		cfg->cachelnsz		= REG(PCIR_CACHELNSZ, 1);
359 		cfg->lattimer		= REG(PCIR_LATTIMER, 1);
360 		cfg->intpin		= REG(PCIR_INTPIN, 1);
361 		cfg->intline		= REG(PCIR_INTLINE, 1);
362 #ifdef __alpha__
363 		alpha_platform_assign_pciintr(cfg);
364 #endif
365 
366 #ifdef APIC_IO
367 		if (cfg->intpin != 0) {
368 			int airq;
369 
370 			airq = pci_apic_irq(cfg->bus, cfg->slot, cfg->intpin);
371 			if (airq >= 0) {
372 				/* PCI specific entry found in MP table */
373 				if (airq != cfg->intline) {
374 					undirect_pci_irq(cfg->intline);
375 					cfg->intline = airq;
376 				}
377 			} else {
378 				/*
379 				 * PCI interrupts might be redirected to the
380 				 * ISA bus according to some MP tables. Use the
381 				 * same methods as used by the ISA devices
382 				 * devices to find the proper IOAPIC int pin.
383 				 */
384 				airq = isa_apic_irq(cfg->intline);
385 				if ((airq >= 0) && (airq != cfg->intline)) {
386 					/* XXX: undirect_pci_irq() ? */
387 					undirect_isa_irq(cfg->intline);
388 					cfg->intline = airq;
389 				}
390 			}
391 		}
392 #endif /* APIC_IO */
393 
394 		cfg->mingnt		= REG(PCIR_MINGNT, 1);
395 		cfg->maxlat		= REG(PCIR_MAXLAT, 1);
396 
397 		cfg->mfdev		= (cfg->hdrtype & PCIM_MFDEV) != 0;
398 		cfg->hdrtype		&= ~PCIM_MFDEV;
399 
400 		cardbus_hdrtypedata(pcib, b, s, f, cfg);
401 
402 		devlist_entry->conf.pc_sel.pc_bus = cfg->bus;
403 		devlist_entry->conf.pc_sel.pc_dev = cfg->slot;
404 		devlist_entry->conf.pc_sel.pc_func = cfg->func;
405 		devlist_entry->conf.pc_hdr = cfg->hdrtype;
406 
407 		devlist_entry->conf.pc_subvendor = cfg->subvendor;
408 		devlist_entry->conf.pc_subdevice = cfg->subdevice;
409 		devlist_entry->conf.pc_vendor = cfg->vendor;
410 		devlist_entry->conf.pc_device = cfg->device;
411 
412 		devlist_entry->conf.pc_class = cfg->baseclass;
413 		devlist_entry->conf.pc_subclass = cfg->subclass;
414 		devlist_entry->conf.pc_progif = cfg->progif;
415 		devlist_entry->conf.pc_revid = cfg->revid;
416 	}
417 	return (devlist_entry);
418 #undef REG
419 }
420 
421 /* extract header type specific config data */
422 
423 static void
424 cardbus_hdrtypedata(device_t pcib, int b, int s, int f, pcicfgregs *cfg)
425 {
426 #define REG(n, w)	PCIB_READ_CONFIG(pcib, b, s, f, n, w)
427 	switch (cfg->hdrtype) {
428 	case 0:
429 		cfg->subvendor      = REG(PCIR_SUBVEND_0, 2);
430 		cfg->subdevice      = REG(PCIR_SUBDEV_0, 2);
431 		cfg->nummaps	    = PCI_MAXMAPS_0;
432 		break;
433 	case 1:
434 		cfg->subvendor      = REG(PCIR_SUBVEND_1, 2);
435 		cfg->subdevice      = REG(PCIR_SUBDEV_1, 2);
436 		cfg->nummaps	    = PCI_MAXMAPS_1;
437 		break;
438 	case 2:
439 		cfg->subvendor      = REG(PCIR_SUBVEND_2, 2);
440 		cfg->subdevice      = REG(PCIR_SUBDEV_2, 2);
441 		cfg->nummaps	    = PCI_MAXMAPS_2;
442 		break;
443 	}
444 #undef REG
445 }
446 
447 /* free pcicfgregs structure and all depending data structures */
448 
449 static int
450 cardbus_freecfg(struct cardbus_devinfo *dinfo)
451 {
452 	free(dinfo, M_DEVBUF);
453 
454 	return (0);
455 }
456 
457 static void
458 cardbus_print_verbose(struct cardbus_devinfo *dinfo)
459 {
460 	if (bootverbose) {
461 		pcicfgregs *cfg = &dinfo->cfg;
462 
463 		printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n",
464 		       cfg->vendor, cfg->device, cfg->revid);
465 		printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n",
466 		       cfg->baseclass, cfg->subclass, cfg->progif,
467 		       cfg->hdrtype, cfg->mfdev);
468 #ifdef CARDBUS_DEBUG
469 		printf("\tcmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n",
470 		       cfg->cmdreg, cfg->statreg, cfg->cachelnsz);
471 		printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n",
472 		       cfg->lattimer, cfg->lattimer * 30,
473 		       cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250);
474 #endif /* CARDBUS_DEBUG */
475 		if (cfg->intpin > 0)
476 			printf("\tintpin=%c, irq=%d\n", cfg->intpin +'a' -1, cfg->intline);
477 	}
478 }
479 
480 /************************************************************************/
481 /* Resources								*/
482 /************************************************************************/
483 
484 static int
485 cardbus_set_resource(device_t dev, device_t child, int type, int rid,
486 		     u_long start, u_long count)
487 {
488 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
489 	struct resource_list *rl = &dinfo->resources;
490 	resource_list_add(rl, type, rid, start, start + count - 1, count);
491 	if (device_get_parent(child) == dev)
492 		pci_write_config(child, rid, start, 4);
493 	return 0;
494 }
495 
496 static int
497 cardbus_get_resource(device_t dev, device_t child, int type, int rid,
498 		     u_long *startp, u_long *countp)
499 {
500 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
501 	struct resource_list *rl = &dinfo->resources;
502 	struct resource_list_entry *rle;
503 	rle = resource_list_find(rl, type, rid);
504 	if (!rle)
505 		return ENOENT;
506 	if (startp)
507 		*startp = rle->start;
508 	if (countp)
509 		*countp = rle->count;
510 	return 0;
511 }
512 
513 static void
514 cardbus_delete_resource(device_t dev, device_t child, int type, int rid)
515 {
516 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
517 	struct resource_list *rl = &dinfo->resources;
518 	struct resource_list_entry *rle;
519 	rle = resource_list_find(rl, type, rid);
520 	if (rle) {
521 		if (rle->res)
522 			bus_generic_release_resource(dev, child, type, rid,
523 						     rle->res);
524 		resource_list_delete(rl, type, rid);
525 	}
526 	if (device_get_parent(child) == dev)
527 		pci_write_config(child, rid, 0, 4);
528 }
529 
530 static int
531 cardbus_set_resource_method(device_t dev, device_t child, int type, int rid,
532 			    u_long start, u_long count)
533 {
534 	int ret;
535 	ret = cardbus_set_resource(dev, child, type, rid, start, count);
536 	if (ret != 0) return ret;
537 	return BUS_SET_RESOURCE(device_get_parent(dev), child, type, rid,
538 				start, count);
539 }
540 
541 static int
542 cardbus_get_resource_method(device_t dev, device_t child, int type, int rid,
543 			    u_long *startp, u_long *countp)
544 {
545 	int ret;
546 	ret = cardbus_get_resource(dev, child, type, rid, startp, countp);
547 	if (ret != 0) return ret;
548 	return BUS_GET_RESOURCE(device_get_parent(dev), child, type, rid,
549 				startp, countp);
550 }
551 
552 static void
553 cardbus_delete_resource_method(device_t dev, device_t child,
554 					   int type, int rid)
555 {
556 	cardbus_delete_resource(dev, child, type, rid);
557 	BUS_DELETE_RESOURCE(device_get_parent(dev), child, type, rid);
558 }
559 
560 static int
561 cardbus_add_map(device_t cbdev, device_t dev, pcicfgregs *cfg, int reg)
562 {
563 	struct cardbus_devinfo *dinfo = device_get_ivars(dev);
564 	struct resource_list *rl = &dinfo->resources;
565 	struct resource_list_entry *rle;
566 	struct resource *res;
567 	device_t bdev = device_get_parent(cbdev);
568 	u_int32_t size;
569 	u_int32_t testval;
570 	int type;
571 
572 	if (reg == CARDBUS_ROM_REG)
573 		testval = CARDBUS_ROM_ADDRMASK;
574 	else
575 		testval = ~0;
576 
577 	PCIB_WRITE_CONFIG(bdev, cfg->bus, cfg->slot, cfg->func,
578 			  reg, testval, 4);
579 
580 	testval = PCIB_READ_CONFIG(bdev, cfg->bus, cfg->slot, cfg->func,
581 				   reg, 4);
582 	if (testval == ~0 || testval == 0)
583 		return 0;
584 
585 	if ((testval&1) == 0)
586 		type = SYS_RES_MEMORY;
587 	else
588 		type = SYS_RES_IOPORT;
589 
590 	size = CARDBUS_MAPREG_MEM_SIZE(testval);
591 	res = bus_generic_alloc_resource(cbdev, dev, type, &reg, 0, ~0, size,
592 					 rman_make_alignment_flags(size));
593 	if (res) {
594 		u_int32_t start = rman_get_start(res);
595 		u_int32_t end = rman_get_end(res);
596 		cardbus_set_resource(cbdev, dev, type, reg, start,end-start+1);
597 		rle = resource_list_find(rl, type, reg);
598 		rle->res = res;
599 	} else {
600 		device_printf(dev, "Unable to add map %02x\n", reg);
601 		type = 0;
602 	}
603 	return type;
604 }
605 
606 static void
607 cardbus_add_resources(device_t dev, pcicfgregs* cfg)
608 {
609 	device_t cbdev = device_get_parent(dev);
610 	device_t bdev = device_get_parent(cbdev);
611 	struct cardbus_devinfo *dinfo = device_get_ivars(dev);
612 	struct resource_list *rl = &dinfo->resources;
613 	struct cardbus_quirk *q;
614 	struct resource_list_entry *rle;
615 	struct resource *res;
616 	int rid;
617 	u_int command;
618 	int type;
619 	int types;
620 	int i;
621 
622 	types = 0;
623 	for (i = 0; i < cfg->nummaps; i++) {
624 		type = cardbus_add_map(cbdev, dev, cfg, PCIR_MAPS + i*4);
625 		types |= 0x1 << type;
626 	}
627 	type = cardbus_add_map(cbdev, dev, cfg, CARDBUS_ROM_REG);
628 	types |= 0x1 << type;
629 
630 	for (q = &cardbus_quirks[0]; q->devid; q++) {
631 		if (q->devid == ((cfg->device << 16) | cfg->vendor)
632 		    && q->type == CARDBUS_QUIRK_MAP_REG) {
633 			type = cardbus_add_map(cbdev, dev, cfg, q->arg1);
634 			types |= 0x1 << type;
635 		}
636 	}
637 
638 	command = PCIB_READ_CONFIG(bdev, cfg->bus, cfg->slot,
639 				   cfg->func, PCIR_COMMAND, 2);
640 	if ((types & (0x1 << SYS_RES_MEMORY)) != 0)
641 		command |= PCIM_CMD_MEMEN;
642 	if ((types & (0x1 << SYS_RES_IOPORT)) != 0)
643 		command |= PCIM_CMD_PORTEN;
644 	command |= PCIM_CMD_BUSMASTEREN;
645 	PCIB_WRITE_CONFIG(bdev, cfg->bus, cfg->slot, cfg->func,
646 			  PCIR_COMMAND, command, 2);
647 
648 	rid = 0;
649 	res = bus_generic_alloc_resource(cbdev, dev, SYS_RES_IRQ,
650 					 &rid, 0, ~0, 1, RF_SHAREABLE);
651 
652 	if (res == NULL)
653 		panic("Cannot allocate IRQ for card\n");
654 
655 	resource_list_add(rl, SYS_RES_IRQ, rid,
656 			  rman_get_start(res), rman_get_start(res), 1);
657 	rle = resource_list_find(rl, SYS_RES_IRQ, rid);
658 	rle->res = res;
659 }
660 
661 static void
662 cardbus_release_all_resources(device_t dev, struct resource_list *rl)
663 {
664 	struct resource_list_entry *rle;
665 
666 	SLIST_FOREACH(rle, rl, link) {
667 		if (rle->res) {
668 			bus_generic_release_resource(device_get_parent(dev),
669 						     dev, rle->type, rle->rid,
670 						     rle->res);
671 		}
672 	}
673 }
674 
675 static struct resource*
676 cardbus_alloc_resource(device_t self, device_t child, int type,
677 				 int* rid, u_long start, u_long end,
678 				 u_long count, u_int flags)
679 {
680 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
681 	struct resource_list *rl = &dinfo->resources;
682 	struct resource_list_entry *rle = NULL;
683 	struct resource *res;
684 
685 	if (device_get_parent(child) == self || child == self)
686 		rle = resource_list_find(rl, type, *rid);
687 	if (rle) {
688 		if (flags & RF_ACTIVE) {
689 			if (bus_activate_resource(child, rle->type, *rid,
690 						  rle->res)) {
691 				return NULL;
692 			}
693 			if (*rid == CARDBUS_ROM_REG) {
694 				uint32_t rom_reg;
695 
696 				rom_reg = pci_read_config(child, *rid, 4);
697 				rom_reg |= CARDBUS_ROM_ENABLE;
698 				pci_write_config(child, *rid, rom_reg, 4);
699 			}
700 		}
701 		return rle->res; /* XXX: check if range within start/end */
702 	} else {
703 		res = bus_generic_alloc_resource(self, child, type, rid,
704 						 start, end, count, flags);
705 		if (res) {
706 			start = rman_get_start(res);
707 			end = rman_get_end(res);
708 			cardbus_set_resource(self, child, type, *rid, start,
709 					     end-start+1);
710 			rle = resource_list_find(rl, type, *rid);
711 			rle->res = res;
712 			return res;
713 		} else {
714 			device_printf(self, "Resource Allocation Failed!\n");
715 			return NULL;
716 		}
717 	}
718 }
719 
720 static int
721 cardbus_release_resource(device_t dev, device_t child, int type, int rid,
722 			 struct resource *r)
723 {
724 	/*
725 	 * According to the PCI 2.2 spec, devices may share an address
726 	 * decoder between memory mapped ROM access and memory
727 	 * mapped register access.  To be safe, disable ROM access
728 	 * whenever it is released.
729 	 */
730 	if (rid == CARDBUS_ROM_REG) {
731 		uint32_t rom_reg;
732 
733 		rom_reg = pci_read_config(child, rid, 4);
734 		rom_reg &= ~CARDBUS_ROM_ENABLE;
735 		pci_write_config(child, rid, rom_reg, 4);
736 	}
737 
738 	return bus_deactivate_resource(child, type, rid, r);
739 }
740 
741 /************************************************************************/
742 /* Other Bus Methods							*/
743 /************************************************************************/
744 
745 static int
746 cardbus_print_resources(struct resource_list *rl, const char *name,
747 			int type, const char *format)
748 {
749 	struct resource_list_entry *rle;
750 	int printed, retval;
751 
752 	printed = 0;
753 	retval = 0;
754 	/* Yes, this is kinda cheating */
755 	SLIST_FOREACH(rle, rl, link) {
756 		if (rle->type == type) {
757 			if (printed == 0)
758 				retval += printf(" %s ", name);
759 			else if (printed > 0)
760 				retval += printf(",");
761 			printed++;
762 			retval += printf(format, rle->start);
763 			if (rle->count > 1) {
764 				retval += printf("-");
765 				retval += printf(format, rle->start +
766 						 rle->count - 1);
767 			}
768 		}
769 	}
770 	return retval;
771 }
772 
773 static int
774 cardbus_print_child(device_t dev, device_t child)
775 {
776 	struct cardbus_devinfo *dinfo;
777 	struct resource_list *rl;
778 	pcicfgregs *cfg;
779 	int retval = 0;
780 
781 	dinfo = device_get_ivars(child);
782 	cfg = &dinfo->cfg;
783 	rl = &dinfo->resources;
784 
785 	retval += bus_print_child_header(dev, child);
786 
787 	retval += cardbus_print_resources(rl, "port", SYS_RES_IOPORT, "%#lx");
788 	retval += cardbus_print_resources(rl, "mem", SYS_RES_MEMORY, "%#lx");
789 	retval += cardbus_print_resources(rl, "irq", SYS_RES_IRQ, "%ld");
790 	if (device_get_flags(dev))
791 		retval += printf(" flags %#x", device_get_flags(dev));
792 
793 	retval += printf(" at device %d.%d", pci_get_slot(child),
794 			 pci_get_function(child));
795 
796 	retval += bus_print_child_footer(dev, child);
797 
798 	return (retval);
799 }
800 
801 static void cardbus_probe_nomatch(device_t dev, device_t child) {
802 	struct cardbus_devinfo *dinfo;
803 	pcicfgregs *cfg;
804 
805 	dinfo = device_get_ivars(child);
806 	cfg = &dinfo->cfg;
807 	device_printf(dev, "<unknown card>");
808 	printf(" (vendor=0x%04x, dev=0x%04x)", cfg->vendor, cfg->device);
809 	printf(" at %d.%d", pci_get_slot(child), pci_get_function(child));
810 	if (cfg->intpin > 0 && cfg->intline != 255) {
811 		printf(" irq %d", cfg->intline);
812 	}
813 	printf("\n");
814 
815 	return;
816 }
817 
818 static int
819 cardbus_read_ivar(device_t dev, device_t child, int which, u_long *result)
820 {
821 	struct cardbus_devinfo *dinfo;
822 	pcicfgregs *cfg;
823 
824 	dinfo = device_get_ivars(child);
825 	cfg = &dinfo->cfg;
826 
827 	switch (which) {
828 	case PCI_IVAR_SUBVENDOR:
829 		*result = cfg->subvendor;
830 		break;
831 	case PCI_IVAR_SUBDEVICE:
832 		*result = cfg->subdevice;
833 		break;
834 	case PCI_IVAR_VENDOR:
835 		*result = cfg->vendor;
836 		break;
837 	case PCI_IVAR_DEVICE:
838 		*result = cfg->device;
839 		break;
840 	case PCI_IVAR_DEVID:
841 		*result = (cfg->device << 16) | cfg->vendor;
842 		break;
843 	case PCI_IVAR_CLASS:
844 		*result = cfg->baseclass;
845 		break;
846 	case PCI_IVAR_SUBCLASS:
847 		*result = cfg->subclass;
848 		break;
849 	case PCI_IVAR_PROGIF:
850 		*result = cfg->progif;
851 		break;
852 	case PCI_IVAR_REVID:
853 		*result = cfg->revid;
854 		break;
855 	case PCI_IVAR_INTPIN:
856 		*result = cfg->intpin;
857 		break;
858 	case PCI_IVAR_IRQ:
859 		*result = cfg->intline;
860 		break;
861 	case PCI_IVAR_BUS:
862 		*result = cfg->bus;
863 		break;
864 	case PCI_IVAR_SLOT:
865 		*result = cfg->slot;
866 		break;
867 	case PCI_IVAR_FUNCTION:
868 		*result = cfg->func;
869 		break;
870 	default:
871 		return ENOENT;
872 	}
873 	return 0;
874 }
875 
876 static int
877 cardbus_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
878 {
879 	struct cardbus_devinfo *dinfo;
880 	pcicfgregs *cfg;
881 
882 	dinfo = device_get_ivars(child);
883 	cfg = &dinfo->cfg;
884 
885 	switch (which) {
886 	case PCI_IVAR_SUBVENDOR:
887 	case PCI_IVAR_SUBDEVICE:
888 	case PCI_IVAR_VENDOR:
889 	case PCI_IVAR_DEVICE:
890 	case PCI_IVAR_DEVID:
891 	case PCI_IVAR_CLASS:
892 	case PCI_IVAR_SUBCLASS:
893 	case PCI_IVAR_PROGIF:
894 	case PCI_IVAR_REVID:
895 	case PCI_IVAR_INTPIN:
896 	case PCI_IVAR_IRQ:
897 	case PCI_IVAR_BUS:
898 	case PCI_IVAR_SLOT:
899 	case PCI_IVAR_FUNCTION:
900 		return EINVAL;	/* disallow for now */
901 	default:
902 		return ENOENT;
903 	}
904 	return 0;
905 }
906 
907 /************************************************************************/
908 /* Compatibility with PCI bus (XXX: Do we need this?)			*/
909 /************************************************************************/
910 
911 static u_int32_t
912 cardbus_read_config_method(device_t dev, device_t child, int reg, int width)
913 {
914 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
915 	pcicfgregs *cfg = &dinfo->cfg;
916 
917 	return PCIB_READ_CONFIG(device_get_parent(dev),
918 				cfg->bus, cfg->slot, cfg->func,
919 				reg, width);
920 }
921 
922 static void
923 cardbus_write_config_method(device_t dev, device_t child, int reg,
924 			    u_int32_t val, int width)
925 {
926 	struct cardbus_devinfo *dinfo = device_get_ivars(child);
927 	pcicfgregs *cfg = &dinfo->cfg;
928 
929 	PCIB_WRITE_CONFIG(device_get_parent(dev),
930 			  cfg->bus, cfg->slot, cfg->func,
931 			  reg, val, width);
932 }
933 
934 static device_method_t cardbus_methods[] = {
935 	/* Device interface */
936 	DEVMETHOD(device_probe,		cardbus_probe),
937 	DEVMETHOD(device_attach,	cardbus_attach),
938 	DEVMETHOD(device_detach,	cardbus_detach),
939 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
940 	DEVMETHOD(device_suspend,	bus_generic_suspend),
941 	DEVMETHOD(device_resume,	bus_generic_resume),
942 
943 	/* Bus interface */
944 	DEVMETHOD(bus_print_child,	cardbus_print_child),
945 	DEVMETHOD(bus_probe_nomatch,	cardbus_probe_nomatch),
946 	DEVMETHOD(bus_read_ivar,	cardbus_read_ivar),
947 	DEVMETHOD(bus_write_ivar,	cardbus_write_ivar),
948 	DEVMETHOD(bus_driver_added,	cardbus_driver_added),
949 	DEVMETHOD(bus_alloc_resource,	cardbus_alloc_resource),
950 	DEVMETHOD(bus_release_resource,	cardbus_release_resource),
951 	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
952 	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
953 	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
954 	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
955 	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
956 
957 	DEVMETHOD(bus_set_resource,	cardbus_set_resource_method),
958 	DEVMETHOD(bus_get_resource,	cardbus_get_resource_method),
959 	DEVMETHOD(bus_delete_resource,	cardbus_delete_resource_method),
960 
961 	/* Card Interface */
962 	DEVMETHOD(card_attach_card,	cardbus_attach_card),
963 	DEVMETHOD(card_detach_card,	cardbus_detach_card),
964 	DEVMETHOD(card_cis_read,	cardbus_cis_read),
965 	DEVMETHOD(card_cis_free,	cardbus_cis_free),
966 
967 	/* Cardbus/PCI interface */
968 	DEVMETHOD(pci_read_config,	cardbus_read_config_method),
969 	DEVMETHOD(pci_write_config,	cardbus_write_config_method),
970 
971 	{0,0}
972 };
973 
974 static driver_t cardbus_driver = {
975 	"cardbus",
976 	cardbus_methods,
977 	0 /* no softc */
978 };
979 
980 static devclass_t cardbus_devclass;
981 
982 DRIVER_MODULE(cardbus, pccbb, cardbus_driver, cardbus_devclass, 0, 0);
983 /*
984 MODULE_DEPEND(cardbus, pccbb, 1, 1, 1);
985 */
986