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