xref: /freebsd/sys/dev/pci/pci.c (revision a79b71281cd63ad7a6cc43a6d5673a2510b51630)
1 /*
2  * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
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 unmodified, this list of conditions, and the following
10  *    disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  *
28  */
29 
30 #include "opt_bus.h"
31 
32 #include "opt_simos.h"
33 #include "opt_compat_oldpci.h"
34 
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/malloc.h>
38 #include <sys/module.h>
39 #include <sys/fcntl.h>
40 #include <sys/conf.h>
41 #include <sys/kernel.h>
42 #include <sys/queue.h>
43 #include <sys/types.h>
44 
45 #include <vm/vm.h>
46 #include <vm/pmap.h>
47 #include <vm/vm_extern.h>
48 
49 #include <sys/bus.h>
50 #include <machine/bus.h>
51 #include <sys/rman.h>
52 #include <machine/resource.h>
53 #include <machine/md_var.h>		/* For the Alpha */
54 
55 #include <sys/pciio.h>
56 #include <pci/pcireg.h>
57 #include <pci/pcivar.h>
58 
59 #ifdef __alpha__
60 #include <machine/rpb.h>
61 #endif
62 
63 #ifdef APIC_IO
64 #include <machine/smp.h>
65 #endif /* APIC_IO */
66 
67 struct pci_quirk {
68 	u_int32_t devid;	/* Vendor/device of the card */
69 	int	type;
70 #define PCI_QUIRK_MAP_REG	1 /* PCI map register in wierd place */
71 	int	arg1;
72 	int	arg2;
73 };
74 
75 struct pci_quirk pci_quirks[] = {
76 	/*
77 	 * The Intel 82371AB has a map register at offset 0x90.
78 	 */
79 	{ 0x71138086, PCI_QUIRK_MAP_REG,	0x90,	 0 },
80 
81 	{ 0 }
82 };
83 
84 /* map register information */
85 #define PCI_MAPMEM	0x01	/* memory map */
86 #define PCI_MAPMEMP	0x02	/* prefetchable memory map */
87 #define PCI_MAPPORT	0x04	/* port map */
88 
89 static STAILQ_HEAD(devlist, pci_devinfo) pci_devq;
90 u_int32_t pci_numdevs = 0;
91 static u_int32_t pci_generation = 0;
92 
93 /* return base address of memory or port map */
94 
95 static u_int32_t
96 pci_mapbase(unsigned mapreg)
97 {
98 	int mask = 0x03;
99 	if ((mapreg & 0x01) == 0)
100 		mask = 0x0f;
101 	return (mapreg & ~mask);
102 }
103 
104 /* return map type of memory or port map */
105 
106 static int
107 pci_maptype(unsigned mapreg)
108 {
109 	static u_int8_t maptype[0x10] = {
110 		PCI_MAPMEM,		PCI_MAPPORT,
111 		PCI_MAPMEM,		0,
112 		PCI_MAPMEM,		PCI_MAPPORT,
113 		0,			0,
114 		PCI_MAPMEM|PCI_MAPMEMP,	PCI_MAPPORT,
115 		PCI_MAPMEM|PCI_MAPMEMP, 0,
116 		PCI_MAPMEM|PCI_MAPMEMP,	PCI_MAPPORT,
117 		0,			0,
118 	};
119 
120 	return maptype[mapreg & 0x0f];
121 }
122 
123 /* return log2 of map size decoded for memory or port map */
124 
125 static int
126 pci_mapsize(unsigned testval)
127 {
128 	int ln2size;
129 
130 	testval = pci_mapbase(testval);
131 	ln2size = 0;
132 	if (testval != 0) {
133 		while ((testval & 1) == 0)
134 		{
135 			ln2size++;
136 			testval >>= 1;
137 		}
138 	}
139 	return (ln2size);
140 }
141 
142 /* return log2 of address range supported by map register */
143 
144 static int
145 pci_maprange(unsigned mapreg)
146 {
147 	int ln2range = 0;
148 	switch (mapreg & 0x07) {
149 	case 0x00:
150 	case 0x01:
151 	case 0x05:
152 		ln2range = 32;
153 		break;
154 	case 0x02:
155 		ln2range = 20;
156 		break;
157 	case 0x04:
158 		ln2range = 64;
159 		break;
160 	}
161 	return (ln2range);
162 }
163 
164 /* adjust some values from PCI 1.0 devices to match 2.0 standards ... */
165 
166 static void
167 pci_fixancient(pcicfgregs *cfg)
168 {
169 	if (cfg->hdrtype != 0)
170 		return;
171 
172 	/* PCI to PCI bridges use header type 1 */
173 	if (cfg->baseclass == PCIC_BRIDGE && cfg->subclass == PCIS_BRIDGE_PCI)
174 		cfg->hdrtype = 1;
175 }
176 
177 /* read config data specific to header type 1 device (PCI to PCI bridge) */
178 
179 static void *
180 pci_readppb(pcicfgregs *cfg)
181 {
182 	pcih1cfgregs *p;
183 
184 	p = malloc(sizeof (pcih1cfgregs), M_DEVBUF, M_WAITOK);
185 	if (p == NULL)
186 		return (NULL);
187 
188 	bzero(p, sizeof *p);
189 
190 	p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_1, 2);
191 	p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_1, 2);
192 
193 	p->seclat = pci_cfgread(cfg, PCIR_SECLAT_1, 1);
194 
195 	p->iobase = PCI_PPBIOBASE (pci_cfgread(cfg, PCIR_IOBASEH_1, 2),
196 				   pci_cfgread(cfg, PCIR_IOBASEL_1, 1));
197 	p->iolimit = PCI_PPBIOLIMIT (pci_cfgread(cfg, PCIR_IOLIMITH_1, 2),
198 				     pci_cfgread(cfg, PCIR_IOLIMITL_1, 1));
199 
200 	p->membase = PCI_PPBMEMBASE (0,
201 				     pci_cfgread(cfg, PCIR_MEMBASE_1, 2));
202 	p->memlimit = PCI_PPBMEMLIMIT (0,
203 				       pci_cfgread(cfg, PCIR_MEMLIMIT_1, 2));
204 
205 	p->pmembase = PCI_PPBMEMBASE (
206 		(pci_addr_t)pci_cfgread(cfg, PCIR_PMBASEH_1, 4),
207 		pci_cfgread(cfg, PCIR_PMBASEL_1, 2));
208 
209 	p->pmemlimit = PCI_PPBMEMLIMIT (
210 		(pci_addr_t)pci_cfgread(cfg, PCIR_PMLIMITH_1, 4),
211 		pci_cfgread(cfg, PCIR_PMLIMITL_1, 2));
212 	return (p);
213 }
214 
215 /* read config data specific to header type 2 device (PCI to CardBus bridge) */
216 
217 static void *
218 pci_readpcb(pcicfgregs *cfg)
219 {
220 	pcih2cfgregs *p;
221 
222 	p = malloc(sizeof (pcih2cfgregs), M_DEVBUF, M_WAITOK);
223 	if (p == NULL)
224 		return (NULL);
225 
226 	bzero(p, sizeof *p);
227 
228 	p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_2, 2);
229 	p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_2, 2);
230 
231 	p->seclat = pci_cfgread(cfg, PCIR_SECLAT_2, 1);
232 
233 	p->membase0 = pci_cfgread(cfg, PCIR_MEMBASE0_2, 4);
234 	p->memlimit0 = pci_cfgread(cfg, PCIR_MEMLIMIT0_2, 4);
235 	p->membase1 = pci_cfgread(cfg, PCIR_MEMBASE1_2, 4);
236 	p->memlimit1 = pci_cfgread(cfg, PCIR_MEMLIMIT1_2, 4);
237 
238 	p->iobase0 = pci_cfgread(cfg, PCIR_IOBASE0_2, 4);
239 	p->iolimit0 = pci_cfgread(cfg, PCIR_IOLIMIT0_2, 4);
240 	p->iobase1 = pci_cfgread(cfg, PCIR_IOBASE1_2, 4);
241 	p->iolimit1 = pci_cfgread(cfg, PCIR_IOLIMIT1_2, 4);
242 
243 	p->pccardif = pci_cfgread(cfg, PCIR_PCCARDIF_2, 4);
244 	return p;
245 }
246 
247 /* extract header type specific config data */
248 
249 static void
250 pci_hdrtypedata(pcicfgregs *cfg)
251 {
252 	switch (cfg->hdrtype) {
253 	case 0:
254 		cfg->subvendor      = pci_cfgread(cfg, PCIR_SUBVEND_0, 2);
255 		cfg->subdevice      = pci_cfgread(cfg, PCIR_SUBDEV_0, 2);
256 		cfg->nummaps	    = PCI_MAXMAPS_0;
257 		break;
258 	case 1:
259 		cfg->subvendor      = pci_cfgread(cfg, PCIR_SUBVEND_1, 2);
260 		cfg->subdevice      = pci_cfgread(cfg, PCIR_SUBDEV_1, 2);
261 		cfg->secondarybus   = pci_cfgread(cfg, PCIR_SECBUS_1, 1);
262 		cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_1, 1);
263 		cfg->nummaps	    = PCI_MAXMAPS_1;
264 		cfg->hdrspec        = pci_readppb(cfg);
265 		break;
266 	case 2:
267 		cfg->subvendor      = pci_cfgread(cfg, PCIR_SUBVEND_2, 2);
268 		cfg->subdevice      = pci_cfgread(cfg, PCIR_SUBDEV_2, 2);
269 		cfg->secondarybus   = pci_cfgread(cfg, PCIR_SECBUS_2, 1);
270 		cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_2, 1);
271 		cfg->nummaps	    = PCI_MAXMAPS_2;
272 		cfg->hdrspec        = pci_readpcb(cfg);
273 		break;
274 	}
275 }
276 
277 /* read configuration header into pcicfgrect structure */
278 
279 static struct pci_devinfo *
280 pci_readcfg(pcicfgregs *probe)
281 {
282 	pcicfgregs *cfg = NULL;
283 	struct pci_devinfo *devlist_entry;
284 	struct devlist *devlist_head;
285 
286 	devlist_head = &pci_devq;
287 
288 	devlist_entry = NULL;
289 
290 	if (pci_cfgread(probe, PCIR_DEVVENDOR, 4) != -1) {
291 
292 		devlist_entry = malloc(sizeof(struct pci_devinfo),
293 				       M_DEVBUF, M_WAITOK);
294 		if (devlist_entry == NULL)
295 			return (NULL);
296 		bzero(devlist_entry, sizeof *devlist_entry);
297 
298 		cfg = &devlist_entry->cfg;
299 
300 		cfg->hose               = probe->hose;
301 		cfg->bus		= probe->bus;
302 		cfg->slot		= probe->slot;
303 		cfg->func		= probe->func;
304 		cfg->vendor		= pci_cfgread(cfg, PCIR_VENDOR, 2);
305 		cfg->device		= pci_cfgread(cfg, PCIR_DEVICE, 2);
306 		cfg->cmdreg		= pci_cfgread(cfg, PCIR_COMMAND, 2);
307 		cfg->statreg		= pci_cfgread(cfg, PCIR_STATUS, 2);
308 		cfg->baseclass		= pci_cfgread(cfg, PCIR_CLASS, 1);
309 		cfg->subclass		= pci_cfgread(cfg, PCIR_SUBCLASS, 1);
310 		cfg->progif		= pci_cfgread(cfg, PCIR_PROGIF, 1);
311 		cfg->revid		= pci_cfgread(cfg, PCIR_REVID, 1);
312 		cfg->hdrtype		= pci_cfgread(cfg, PCIR_HEADERTYPE, 1);
313 		cfg->cachelnsz		= pci_cfgread(cfg, PCIR_CACHELNSZ, 1);
314 		cfg->lattimer		= pci_cfgread(cfg, PCIR_LATTIMER, 1);
315 		cfg->intpin		= pci_cfgread(cfg, PCIR_INTPIN, 1);
316 		cfg->intline		= pci_cfgread(cfg, PCIR_INTLINE, 1);
317 #ifdef __alpha__
318 		alpha_platform_assign_pciintr(cfg);
319 #endif
320 
321 #ifdef APIC_IO
322 		if (cfg->intpin != 0) {
323 			int airq;
324 
325 			airq = pci_apic_irq(cfg->bus, cfg->slot, cfg->intpin);
326 			if (airq >= 0) {
327 				/* PCI specific entry found in MP table */
328 				if (airq != cfg->intline) {
329 					undirect_pci_irq(cfg->intline);
330 					cfg->intline = airq;
331 				}
332 			} else {
333 				/*
334 				 * PCI interrupts might be redirected to the
335 				 * ISA bus according to some MP tables. Use the
336 				 * same methods as used by the ISA devices
337 				 * devices to find the proper IOAPIC int pin.
338 				 */
339 				airq = isa_apic_irq(cfg->intline);
340 				if ((airq >= 0) && (airq != cfg->intline)) {
341 					/* XXX: undirect_pci_irq() ? */
342 					undirect_isa_irq(cfg->intline);
343 					cfg->intline = airq;
344 				}
345 			}
346 		}
347 #endif /* APIC_IO */
348 
349 		cfg->mingnt		= pci_cfgread(cfg, PCIR_MINGNT, 1);
350 		cfg->maxlat		= pci_cfgread(cfg, PCIR_MAXLAT, 1);
351 
352 		cfg->mfdev		= (cfg->hdrtype & PCIM_MFDEV) != 0;
353 		cfg->hdrtype		&= ~PCIM_MFDEV;
354 
355 		pci_fixancient(cfg);
356 		pci_hdrtypedata(cfg);
357 
358 		STAILQ_INSERT_TAIL(devlist_head, devlist_entry, pci_links);
359 
360 		devlist_entry->conf.pc_sel.pc_bus = cfg->bus;
361 		devlist_entry->conf.pc_sel.pc_dev = cfg->slot;
362 		devlist_entry->conf.pc_sel.pc_func = cfg->func;
363 		devlist_entry->conf.pc_hdr = cfg->hdrtype;
364 
365 		devlist_entry->conf.pc_subvendor = cfg->subvendor;
366 		devlist_entry->conf.pc_subdevice = cfg->subdevice;
367 		devlist_entry->conf.pc_vendor = cfg->vendor;
368 		devlist_entry->conf.pc_device = cfg->device;
369 
370 		devlist_entry->conf.pc_class = cfg->baseclass;
371 		devlist_entry->conf.pc_subclass = cfg->subclass;
372 		devlist_entry->conf.pc_progif = cfg->progif;
373 		devlist_entry->conf.pc_revid = cfg->revid;
374 
375 		pci_numdevs++;
376 		pci_generation++;
377 	}
378 	return (devlist_entry);
379 }
380 
381 #if 0
382 /* free pcicfgregs structure and all depending data structures */
383 
384 static int
385 pci_freecfg(struct pci_devinfo *dinfo)
386 {
387 	struct devlist *devlist_head;
388 
389 	devlist_head = &pci_devq;
390 
391 	if (dinfo->cfg.hdrspec != NULL)
392 		free(dinfo->cfg.hdrspec, M_DEVBUF);
393 	if (dinfo->cfg.map != NULL)
394 		free(dinfo->cfg.map, M_DEVBUF);
395 	/* XXX this hasn't been tested */
396 	STAILQ_REMOVE(devlist_head, dinfo, pci_devinfo, pci_links);
397 	free(dinfo, M_DEVBUF);
398 
399 	/* increment the generation count */
400 	pci_generation++;
401 
402 	/* we're losing one device */
403 	pci_numdevs--;
404 	return (0);
405 }
406 #endif
407 
408 
409 /*
410  * This is the user interface to PCI configuration space.
411  */
412 
413 static int
414 pci_open(dev_t dev, int oflags, int devtype, struct proc *p)
415 {
416 	if ((oflags & FWRITE) && securelevel > 0) {
417 		return EPERM;
418 	}
419 	return 0;
420 }
421 
422 static int
423 pci_close(dev_t dev, int flag, int devtype, struct proc *p)
424 {
425 	return 0;
426 }
427 
428 /*
429  * Match a single pci_conf structure against an array of pci_match_conf
430  * structures.  The first argument, 'matches', is an array of num_matches
431  * pci_match_conf structures.  match_buf is a pointer to the pci_conf
432  * structure that will be compared to every entry in the matches array.
433  * This function returns 1 on failure, 0 on success.
434  */
435 static int
436 pci_conf_match(struct pci_match_conf *matches, int num_matches,
437 	       struct pci_conf *match_buf)
438 {
439 	int i;
440 
441 	if ((matches == NULL) || (match_buf == NULL) || (num_matches <= 0))
442 		return(1);
443 
444 	for (i = 0; i < num_matches; i++) {
445 		/*
446 		 * I'm not sure why someone would do this...but...
447 		 */
448 		if (matches[i].flags == PCI_GETCONF_NO_MATCH)
449 			continue;
450 
451 		/*
452 		 * Look at each of the match flags.  If it's set, do the
453 		 * comparison.  If the comparison fails, we don't have a
454 		 * match, go on to the next item if there is one.
455 		 */
456 		if (((matches[i].flags & PCI_GETCONF_MATCH_BUS) != 0)
457 		 && (match_buf->pc_sel.pc_bus != matches[i].pc_sel.pc_bus))
458 			continue;
459 
460 		if (((matches[i].flags & PCI_GETCONF_MATCH_DEV) != 0)
461 		 && (match_buf->pc_sel.pc_dev != matches[i].pc_sel.pc_dev))
462 			continue;
463 
464 		if (((matches[i].flags & PCI_GETCONF_MATCH_FUNC) != 0)
465 		 && (match_buf->pc_sel.pc_func != matches[i].pc_sel.pc_func))
466 			continue;
467 
468 		if (((matches[i].flags & PCI_GETCONF_MATCH_VENDOR) != 0)
469 		 && (match_buf->pc_vendor != matches[i].pc_vendor))
470 			continue;
471 
472 		if (((matches[i].flags & PCI_GETCONF_MATCH_DEVICE) != 0)
473 		 && (match_buf->pc_device != matches[i].pc_device))
474 			continue;
475 
476 		if (((matches[i].flags & PCI_GETCONF_MATCH_CLASS) != 0)
477 		 && (match_buf->pc_class != matches[i].pc_class))
478 			continue;
479 
480 		if (((matches[i].flags & PCI_GETCONF_MATCH_UNIT) != 0)
481 		 && (match_buf->pd_unit != matches[i].pd_unit))
482 			continue;
483 
484 		if (((matches[i].flags & PCI_GETCONF_MATCH_NAME) != 0)
485 		 && (strncmp(matches[i].pd_name, match_buf->pd_name,
486 			     sizeof(match_buf->pd_name)) != 0))
487 			continue;
488 
489 		return(0);
490 	}
491 
492 	return(1);
493 }
494 
495 /*
496  * Locate the parent of a PCI device by scanning the PCI devlist
497  * and return the entry for the parent.
498  * For devices on PCI Bus 0 (the host bus), this is the PCI Host.
499  * For devices on secondary PCI busses, this is that bus' PCI-PCI Bridge.
500  */
501 
502 pcicfgregs *
503 pci_devlist_get_parent(pcicfgregs *cfg)
504 {
505 	struct devlist *devlist_head;
506 	struct pci_devinfo *dinfo;
507 	pcicfgregs *bridge_cfg;
508 	int i;
509 
510 	dinfo = STAILQ_FIRST(devlist_head = &pci_devq);
511 
512 	/* If the device is on PCI bus 0, look for the host */
513 	if (cfg->bus == 0) {
514 		for (i = 0; (dinfo != NULL) && (i < pci_numdevs);
515 		dinfo = STAILQ_NEXT(dinfo, pci_links), i++) {
516 			bridge_cfg = &dinfo->cfg;
517 			if (bridge_cfg->baseclass == PCIC_BRIDGE
518 				&& bridge_cfg->subclass == PCIS_BRIDGE_HOST
519 		    		&& bridge_cfg->bus == cfg->bus) {
520 				return bridge_cfg;
521 			}
522 		}
523 	}
524 
525 	/* If the device is not on PCI bus 0, look for the PCI-PCI bridge */
526 	if (cfg->bus > 0) {
527 		for (i = 0; (dinfo != NULL) && (i < pci_numdevs);
528 		dinfo = STAILQ_NEXT(dinfo, pci_links), i++) {
529 			bridge_cfg = &dinfo->cfg;
530 			if (bridge_cfg->baseclass == PCIC_BRIDGE
531 				&& bridge_cfg->subclass == PCIS_BRIDGE_PCI
532 				&& bridge_cfg->secondarybus == cfg->bus) {
533 				return bridge_cfg;
534 			}
535 		}
536 	}
537 
538 	return NULL;
539 }
540 
541 static int
542 pci_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
543 {
544 	struct pci_io *io;
545 	const char *name;
546 	int error;
547 
548 	if (!(flag & FWRITE))
549 		return EPERM;
550 
551 
552 	switch(cmd) {
553 	case PCIOCGETCONF:
554 		{
555 		struct pci_devinfo *dinfo;
556 		struct pci_conf_io *cio;
557 		struct devlist *devlist_head;
558 		struct pci_match_conf *pattern_buf;
559 		int num_patterns;
560 		size_t iolen;
561 		int ionum, i;
562 
563 		cio = (struct pci_conf_io *)data;
564 
565 		num_patterns = 0;
566 		dinfo = NULL;
567 
568 		/*
569 		 * Hopefully the user won't pass in a null pointer, but it
570 		 * can't hurt to check.
571 		 */
572 		if (cio == NULL) {
573 			error = EINVAL;
574 			break;
575 		}
576 
577 		/*
578 		 * If the user specified an offset into the device list,
579 		 * but the list has changed since they last called this
580 		 * ioctl, tell them that the list has changed.  They will
581 		 * have to get the list from the beginning.
582 		 */
583 		if ((cio->offset != 0)
584 		 && (cio->generation != pci_generation)){
585 			cio->num_matches = 0;
586 			cio->status = PCI_GETCONF_LIST_CHANGED;
587 			error = 0;
588 			break;
589 		}
590 
591 		/*
592 		 * Check to see whether the user has asked for an offset
593 		 * past the end of our list.
594 		 */
595 		if (cio->offset >= pci_numdevs) {
596 			cio->num_matches = 0;
597 			cio->status = PCI_GETCONF_LAST_DEVICE;
598 			error = 0;
599 			break;
600 		}
601 
602 		/* get the head of the device queue */
603 		devlist_head = &pci_devq;
604 
605 		/*
606 		 * Determine how much room we have for pci_conf structures.
607 		 * Round the user's buffer size down to the nearest
608 		 * multiple of sizeof(struct pci_conf) in case the user
609 		 * didn't specify a multiple of that size.
610 		 */
611 		iolen = min(cio->match_buf_len -
612 			    (cio->match_buf_len % sizeof(struct pci_conf)),
613 			    pci_numdevs * sizeof(struct pci_conf));
614 
615 		/*
616 		 * Since we know that iolen is a multiple of the size of
617 		 * the pciconf union, it's okay to do this.
618 		 */
619 		ionum = iolen / sizeof(struct pci_conf);
620 
621 		/*
622 		 * If this test is true, the user wants the pci_conf
623 		 * structures returned to match the supplied entries.
624 		 */
625 		if ((cio->num_patterns > 0)
626 		 && (cio->pat_buf_len > 0)) {
627 			/*
628 			 * pat_buf_len needs to be:
629 			 * num_patterns * sizeof(struct pci_match_conf)
630 			 * While it is certainly possible the user just
631 			 * allocated a large buffer, but set the number of
632 			 * matches correctly, it is far more likely that
633 			 * their kernel doesn't match the userland utility
634 			 * they're using.  It's also possible that the user
635 			 * forgot to initialize some variables.  Yes, this
636 			 * may be overly picky, but I hazard to guess that
637 			 * it's far more likely to just catch folks that
638 			 * updated their kernel but not their userland.
639 			 */
640 			if ((cio->num_patterns *
641 			    sizeof(struct pci_match_conf)) != cio->pat_buf_len){
642 				/* The user made a mistake, return an error*/
643 				cio->status = PCI_GETCONF_ERROR;
644 				printf("pci_ioctl: pat_buf_len %d != "
645 				       "num_patterns (%d) * sizeof(struct "
646 				       "pci_match_conf) (%d)\npci_ioctl: "
647 				       "pat_buf_len should be = %d\n",
648 				       cio->pat_buf_len, cio->num_patterns,
649 				       (int)sizeof(struct pci_match_conf),
650 				       (int)sizeof(struct pci_match_conf) *
651 				       cio->num_patterns);
652 				printf("pci_ioctl: do your headers match your "
653 				       "kernel?\n");
654 				cio->num_matches = 0;
655 				error = EINVAL;
656 				break;
657 			}
658 
659 			/*
660 			 * Check the user's buffer to make sure it's readable.
661 			 */
662 			if (!useracc((caddr_t)cio->patterns,
663 				    cio->pat_buf_len, VM_PROT_READ)) {
664 				printf("pci_ioctl: pattern buffer %p, "
665 				       "length %u isn't user accessible for"
666 				       " READ\n", cio->patterns,
667 				       cio->pat_buf_len);
668 				error = EACCES;
669 				break;
670 			}
671 			/*
672 			 * Allocate a buffer to hold the patterns.
673 			 */
674 			pattern_buf = malloc(cio->pat_buf_len, M_TEMP,
675 					     M_WAITOK);
676 			error = copyin(cio->patterns, pattern_buf,
677 				       cio->pat_buf_len);
678 			if (error != 0)
679 				break;
680 			num_patterns = cio->num_patterns;
681 
682 		} else if ((cio->num_patterns > 0)
683 			|| (cio->pat_buf_len > 0)) {
684 			/*
685 			 * The user made a mistake, spit out an error.
686 			 */
687 			cio->status = PCI_GETCONF_ERROR;
688 			cio->num_matches = 0;
689 			printf("pci_ioctl: invalid GETCONF arguments\n");
690 			error = EINVAL;
691 			break;
692 		} else
693 			pattern_buf = NULL;
694 
695 		/*
696 		 * Make sure we can write to the match buffer.
697 		 */
698 		if (!useracc((caddr_t)cio->matches,
699 			     cio->match_buf_len, VM_PROT_WRITE)) {
700 			printf("pci_ioctl: match buffer %p, length %u "
701 			       "isn't user accessible for WRITE\n",
702 			       cio->matches, cio->match_buf_len);
703 			error = EACCES;
704 			break;
705 		}
706 
707 		/*
708 		 * Go through the list of devices and copy out the devices
709 		 * that match the user's criteria.
710 		 */
711 		for (cio->num_matches = 0, error = 0, i = 0,
712 		     dinfo = STAILQ_FIRST(devlist_head);
713 		     (dinfo != NULL) && (cio->num_matches < ionum)
714 		     && (error == 0) && (i < pci_numdevs);
715 		     dinfo = STAILQ_NEXT(dinfo, pci_links), i++) {
716 
717 			if (i < cio->offset)
718 				continue;
719 
720 			/* Populate pd_name and pd_unit */
721 			name = NULL;
722 			if (dinfo->cfg.dev && dinfo->conf.pd_name[0] == '\0')
723 				name = device_get_name(dinfo->cfg.dev);
724 			if (name) {
725 				strncpy(dinfo->conf.pd_name, name,
726 					sizeof(dinfo->conf.pd_name));
727 				dinfo->conf.pd_name[PCI_MAXNAMELEN] = 0;
728 				dinfo->conf.pd_unit =
729 					device_get_unit(dinfo->cfg.dev);
730 			}
731 
732 			if ((pattern_buf == NULL) ||
733 			    (pci_conf_match(pattern_buf, num_patterns,
734 					    &dinfo->conf) == 0)) {
735 
736 				/*
737 				 * If we've filled up the user's buffer,
738 				 * break out at this point.  Since we've
739 				 * got a match here, we'll pick right back
740 				 * up at the matching entry.  We can also
741 				 * tell the user that there are more matches
742 				 * left.
743 				 */
744 				if (cio->num_matches >= ionum)
745 					break;
746 
747 				error = copyout(&dinfo->conf,
748 					        &cio->matches[cio->num_matches],
749 						sizeof(struct pci_conf));
750 				cio->num_matches++;
751 			}
752 		}
753 
754 		/*
755 		 * Set the pointer into the list, so if the user is getting
756 		 * n records at a time, where n < pci_numdevs,
757 		 */
758 		cio->offset = i;
759 
760 		/*
761 		 * Set the generation, the user will need this if they make
762 		 * another ioctl call with offset != 0.
763 		 */
764 		cio->generation = pci_generation;
765 
766 		/*
767 		 * If this is the last device, inform the user so he won't
768 		 * bother asking for more devices.  If dinfo isn't NULL, we
769 		 * know that there are more matches in the list because of
770 		 * the way the traversal is done.
771 		 */
772 		if (dinfo == NULL)
773 			cio->status = PCI_GETCONF_LAST_DEVICE;
774 		else
775 			cio->status = PCI_GETCONF_MORE_DEVS;
776 
777 		if (pattern_buf != NULL)
778 			free(pattern_buf, M_TEMP);
779 
780 		break;
781 		}
782 	case PCIOCREAD:
783 		io = (struct pci_io *)data;
784 		switch(io->pi_width) {
785 			pcicfgregs probe;
786 		case 4:
787 		case 2:
788 		case 1:
789 			probe.hose = -1;
790 			probe.bus = io->pi_sel.pc_bus;
791 			probe.slot = io->pi_sel.pc_dev;
792 			probe.func = io->pi_sel.pc_func;
793 			io->pi_data = pci_cfgread(&probe,
794 						  io->pi_reg, io->pi_width);
795 			error = 0;
796 			break;
797 		default:
798 			error = ENODEV;
799 			break;
800 		}
801 		break;
802 
803 	case PCIOCWRITE:
804 		io = (struct pci_io *)data;
805 		switch(io->pi_width) {
806 			pcicfgregs probe;
807 		case 4:
808 		case 2:
809 		case 1:
810 			probe.hose = -1;
811 			probe.bus = io->pi_sel.pc_bus;
812 			probe.slot = io->pi_sel.pc_dev;
813 			probe.func = io->pi_sel.pc_func;
814 			pci_cfgwrite(&probe,
815 				    io->pi_reg, io->pi_data, io->pi_width);
816 			error = 0;
817 			break;
818 		default:
819 			error = ENODEV;
820 			break;
821 		}
822 		break;
823 
824 	default:
825 		error = ENOTTY;
826 		break;
827 	}
828 
829 	return (error);
830 }
831 
832 #define	PCI_CDEV	78
833 
834 static struct cdevsw pcicdev = {
835 	/* open */	pci_open,
836 	/* close */	pci_close,
837 	/* read */	noread,
838 	/* write */	nowrite,
839 	/* ioctl */	pci_ioctl,
840 	/* poll */	nopoll,
841 	/* mmap */	nommap,
842 	/* strategy */	nostrategy,
843 	/* name */	"pci",
844 	/* maj */	PCI_CDEV,
845 	/* dump */	nodump,
846 	/* psize */	nopsize,
847 	/* flags */	0,
848 	/* bmaj */	-1
849 };
850 
851 #include "pci_if.h"
852 
853 
854 /*
855  * New style pci driver.  Parent device is either a pci-host-bridge or a
856  * pci-pci-bridge.  Both kinds are represented by instances of pcib.
857  */
858 
859 static void
860 pci_print_verbose(struct pci_devinfo *dinfo)
861 {
862 	if (bootverbose) {
863 		pcicfgregs *cfg = &dinfo->cfg;
864 
865 		printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n",
866 		       cfg->vendor, cfg->device, cfg->revid);
867 		printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n",
868 		       cfg->baseclass, cfg->subclass, cfg->progif,
869 		       cfg->hdrtype, cfg->mfdev);
870 		printf("\tsubordinatebus=%x \tsecondarybus=%x\n",
871 		       cfg->subordinatebus, cfg->secondarybus);
872 #ifdef PCI_DEBUG
873 		printf("\tcmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n",
874 		       cfg->cmdreg, cfg->statreg, cfg->cachelnsz);
875 		printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n",
876 		       cfg->lattimer, cfg->lattimer * 30,
877 		       cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250);
878 #endif /* PCI_DEBUG */
879 		if (cfg->intpin > 0)
880 			printf("\tintpin=%c, irq=%d\n", cfg->intpin +'a' -1, cfg->intline);
881 	}
882 }
883 
884 static int
885 pci_porten(pcicfgregs *cfg)
886 {
887 	return ((cfg->cmdreg & PCIM_CMD_PORTEN) != 0);
888 }
889 
890 static int
891 pci_memen(pcicfgregs *cfg)
892 {
893 	return ((cfg->cmdreg & PCIM_CMD_MEMEN) != 0);
894 }
895 
896 /*
897  * Add a resource based on a pci map register. Return 1 if the map
898  * register is a 32bit map register or 2 if it is a 64bit register.
899  */
900 static int
901 pci_add_map(device_t dev, pcicfgregs* cfg, int reg)
902 {
903 	struct pci_devinfo *dinfo = device_get_ivars(dev);
904 	struct resource_list *rl = &dinfo->resources;
905 	u_int32_t map;
906 	u_int64_t base;
907 	u_int8_t ln2size;
908 	u_int8_t ln2range;
909 	u_int32_t testval;
910 
911 	int type;
912 
913 	map = pci_cfgread(cfg, reg, 4);
914 
915 	if (map == 0 || map == 0xffffffff)
916 		return 1; /* skip invalid entry */
917 
918 	pci_cfgwrite(cfg, reg, 0xffffffff, 4);
919 	testval = pci_cfgread(cfg, reg, 4);
920 	pci_cfgwrite(cfg, reg, map, 4);
921 
922 	base = pci_mapbase(map);
923 	if (pci_maptype(map) & PCI_MAPMEM)
924 		type = SYS_RES_MEMORY;
925 	else
926 		type = SYS_RES_IOPORT;
927 	ln2size = pci_mapsize(testval);
928 	ln2range = pci_maprange(testval);
929 	if (ln2range == 64) {
930 		/* Read the other half of a 64bit map register */
931 		base |= (u_int64_t) pci_cfgread(cfg, reg + 4, 4) << 32;
932 	}
933 
934 #ifdef __alpha__
935 	/*
936 	 *  XXX: encode hose number in the base addr,
937 	 *  This will go away once the bus_space functions
938 	 *  can deal with multiple hoses
939 	 */
940 
941 	if (cfg->hose) {
942 		u_int32_t mask, shift, maxh;
943 
944 		switch (hwrpb->rpb_type) {
945 		case ST_DEC_4100:
946 			mask = 0xc0000000;
947 			shift = 30;
948 			maxh = 4;	/* not a hose. MCPCIA instance # */
949 			break;
950 		case ST_DEC_21000:
951 			mask = 0xf8000000;
952 			shift = 27;
953 			maxh = 32;
954 			break;
955 		case ST_DEC_6600:
956 			mask = 0x80000000;
957 			shift = 31;
958 			maxh = 2;
959 			break;
960 		default:
961 			mask = 0;
962 			shift = 0;
963 			maxh = 0;
964 			break;
965 		}
966 		if (base & mask) {
967 			printf("base   addr = 0x%llx\n", (long long) base);
968 			printf("mask   addr = 0x%lx\n", (long) mask);
969 			printf("hacked addr = 0x%llx\n", (long long)
970 			       (base | ((u_int64_t)cfg->hose << shift)));
971 			panic("hose encoding hack would clobber base addr");
972 			/* NOTREACHED */
973 		}
974 		if (cfg->hose >= maxh) {
975 			panic("Hose %d - can only encode %d hose(s)",
976 			    cfg->hose, maxh);
977 			/* NOTREACHED */
978 		}
979 		base |= ((u_int64_t)cfg->hose << shift);
980 	}
981 #endif
982 	if (bootverbose) {
983 		printf("\tmap[%02x]: type %x, range %2d, base %08x, size %2d",
984 		       reg, pci_maptype(map), ln2range,
985 		       (unsigned int) base, ln2size);
986 		if (type == SYS_RES_IOPORT && !pci_porten(cfg))
987 			printf(", port disabled\n");
988 		else if (type == SYS_RES_MEMORY && !pci_memen(cfg))
989 			printf(", memory disabled\n");
990 		else
991 			printf(", enabled\n");
992 	}
993 
994 	if (type == SYS_RES_IOPORT && !pci_porten(cfg))
995 		return 1;
996 	if (type == SYS_RES_MEMORY && !pci_memen(cfg))
997 		return 1;
998 
999 	resource_list_add(rl, type, reg,
1000 			  base, base + (1 << ln2size) - 1,
1001 			  (1 << ln2size));
1002 
1003 	return (ln2range == 64) ? 2 : 1;
1004 }
1005 
1006 static void
1007 pci_add_resources(device_t dev, pcicfgregs* cfg)
1008 {
1009 	struct pci_devinfo *dinfo = device_get_ivars(dev);
1010 	struct resource_list *rl = &dinfo->resources;
1011 	struct pci_quirk *q;
1012 	int i;
1013 
1014 	for (i = 0; i < cfg->nummaps;) {
1015 		i += pci_add_map(dev, cfg, PCIR_MAPS + i*4);
1016 	}
1017 
1018 	for (q = &pci_quirks[0]; q->devid; q++) {
1019 		if (q->devid == ((cfg->device << 16) | cfg->vendor)
1020 		    && q->type == PCI_QUIRK_MAP_REG)
1021 			pci_add_map(dev, cfg, q->arg1);
1022 	}
1023 
1024 	if (cfg->intpin > 0 && cfg->intline != 255)
1025 		resource_list_add(rl, SYS_RES_IRQ, 0,
1026 				  cfg->intline, cfg->intline, 1);
1027 }
1028 
1029 static void
1030 pci_add_children(device_t dev, int busno)
1031 {
1032 	pcicfgregs probe;
1033 
1034 #ifdef SIMOS
1035 #undef PCI_SLOTMAX
1036 #define PCI_SLOTMAX 0
1037 #endif
1038 
1039 	bzero(&probe, sizeof probe);
1040 #ifdef __alpha__
1041 	probe.hose = pcib_get_hose(dev);
1042 #endif
1043 #ifdef __i386__
1044 	probe.hose = 0;
1045 #endif
1046 	probe.bus = busno;
1047 
1048 	for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) {
1049 		int pcifunchigh = 0;
1050 		for (probe.func = 0; probe.func <= pcifunchigh; probe.func++) {
1051 			struct pci_devinfo *dinfo = pci_readcfg(&probe);
1052 			if (dinfo != NULL) {
1053 				if (dinfo->cfg.mfdev)
1054 					pcifunchigh = 7;
1055 
1056 				pci_print_verbose(dinfo);
1057 				dinfo->cfg.dev = device_add_child(dev, NULL, -1);
1058 				device_set_ivars(dinfo->cfg.dev, dinfo);
1059 				pci_add_resources(dinfo->cfg.dev, &dinfo->cfg);
1060 			}
1061 		}
1062 	}
1063 }
1064 
1065 static int
1066 pci_new_probe(device_t dev)
1067 {
1068 	static int once;
1069 
1070 	device_set_desc(dev, "PCI bus");
1071 	pci_add_children(dev, device_get_unit(dev));
1072 	if (!once) {
1073 		make_dev(&pcicdev, 0, UID_ROOT, GID_WHEEL, 0644, "pci");
1074 		once++;
1075 	}
1076 
1077 	return 0;
1078 }
1079 
1080 static int
1081 pci_print_resources(struct resource_list *rl, const char *name, int type,
1082 		    const char *format)
1083 {
1084 	struct resource_list_entry *rle;
1085 	int printed, retval;
1086 
1087 	printed = 0;
1088 	retval = 0;
1089 	/* Yes, this is kinda cheating */
1090 	SLIST_FOREACH(rle, rl, link) {
1091 		if (rle->type == type) {
1092 			if (printed == 0)
1093 				retval += printf(" %s ", name);
1094 			else if (printed > 0)
1095 				retval += printf(",");
1096 			printed++;
1097 			retval += printf(format, rle->start);
1098 			if (rle->count > 1) {
1099 				retval += printf("-");
1100 				retval += printf(format, rle->start +
1101 						 rle->count - 1);
1102 			}
1103 		}
1104 	}
1105 	return retval;
1106 }
1107 
1108 static int
1109 pci_print_child(device_t dev, device_t child)
1110 {
1111 	struct pci_devinfo *dinfo;
1112 	struct resource_list *rl;
1113 	pcicfgregs *cfg;
1114 	int retval = 0;
1115 
1116 	dinfo = device_get_ivars(child);
1117 	cfg = &dinfo->cfg;
1118 	rl = &dinfo->resources;
1119 
1120 	retval += bus_print_child_header(dev, child);
1121 
1122 	retval += pci_print_resources(rl, "port", SYS_RES_IOPORT, "%#lx");
1123 	retval += pci_print_resources(rl, "mem", SYS_RES_MEMORY, "%#lx");
1124 	retval += pci_print_resources(rl, "irq", SYS_RES_IRQ, "%ld");
1125 	if (device_get_flags(dev))
1126 		retval += printf(" flags %#x", device_get_flags(dev));
1127 
1128 	retval += printf(" at device %d.%d", pci_get_slot(child),
1129 			 pci_get_function(child));
1130 
1131 	retval += bus_print_child_footer(dev, child);
1132 
1133 	return (retval);
1134 }
1135 
1136 static void
1137 pci_probe_nomatch(device_t dev, device_t child)
1138 {
1139 	struct pci_devinfo *dinfo;
1140 	pcicfgregs *cfg;
1141 	const char *desc;
1142 	int unknown;
1143 
1144 	unknown = 0;
1145 	dinfo = device_get_ivars(child);
1146 	cfg = &dinfo->cfg;
1147 	desc = pci_ata_match(child);
1148 	if (!desc) desc = pci_usb_match(child);
1149 	if (!desc) desc = pci_vga_match(child);
1150 	if (!desc) desc = pci_chip_match(child);
1151 	if (!desc) {
1152 		desc = "unknown card";
1153 		unknown++;
1154 	}
1155 	device_printf(dev, "<%s>", desc);
1156 	if (bootverbose || unknown) {
1157 		printf(" (vendor=0x%04x, dev=0x%04x)",
1158 			cfg->vendor,
1159 			cfg->device);
1160 	}
1161 	printf(" at %d.%d",
1162 		pci_get_slot(child),
1163 		pci_get_function(child));
1164 	if (cfg->intpin > 0 && cfg->intline != 255) {
1165 		printf(" irq %d", cfg->intline);
1166 	}
1167 	printf("\n");
1168 
1169 	return;
1170 }
1171 
1172 static int
1173 pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
1174 {
1175 	struct pci_devinfo *dinfo;
1176 	pcicfgregs *cfg;
1177 
1178 	dinfo = device_get_ivars(child);
1179 	cfg = &dinfo->cfg;
1180 
1181 	switch (which) {
1182 	case PCI_IVAR_SUBVENDOR:
1183 		*result = cfg->subvendor;
1184 		break;
1185 	case PCI_IVAR_SUBDEVICE:
1186 		*result = cfg->subdevice;
1187 		break;
1188 	case PCI_IVAR_VENDOR:
1189 		*result = cfg->vendor;
1190 		break;
1191 	case PCI_IVAR_DEVICE:
1192 		*result = cfg->device;
1193 		break;
1194 	case PCI_IVAR_DEVID:
1195 		*result = (cfg->device << 16) | cfg->vendor;
1196 		break;
1197 	case PCI_IVAR_CLASS:
1198 		*result = cfg->baseclass;
1199 		break;
1200 	case PCI_IVAR_SUBCLASS:
1201 		*result = cfg->subclass;
1202 		break;
1203 	case PCI_IVAR_PROGIF:
1204 		*result = cfg->progif;
1205 		break;
1206 	case PCI_IVAR_REVID:
1207 		*result = cfg->revid;
1208 		break;
1209 	case PCI_IVAR_INTPIN:
1210 		*result = cfg->intpin;
1211 		break;
1212 	case PCI_IVAR_IRQ:
1213 		*result = cfg->intline;
1214 		break;
1215 	case PCI_IVAR_BUS:
1216 		*result = cfg->bus;
1217 		break;
1218 	case PCI_IVAR_SLOT:
1219 		*result = cfg->slot;
1220 		break;
1221 	case PCI_IVAR_FUNCTION:
1222 		*result = cfg->func;
1223 		break;
1224 	case PCI_IVAR_SECONDARYBUS:
1225 		*result = cfg->secondarybus;
1226 		break;
1227 	case PCI_IVAR_SUBORDINATEBUS:
1228 		*result = cfg->subordinatebus;
1229 		break;
1230 	case PCI_IVAR_HOSE:
1231 		/*
1232 		 * Pass up to parent bridge.
1233 		 */
1234 		*result = pcib_get_hose(dev);
1235 		break;
1236 	default:
1237 		return ENOENT;
1238 	}
1239 	return 0;
1240 }
1241 
1242 static int
1243 pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
1244 {
1245 	struct pci_devinfo *dinfo;
1246 	pcicfgregs *cfg;
1247 
1248 	dinfo = device_get_ivars(child);
1249 	cfg = &dinfo->cfg;
1250 
1251 	switch (which) {
1252 	case PCI_IVAR_SUBVENDOR:
1253 	case PCI_IVAR_SUBDEVICE:
1254 	case PCI_IVAR_VENDOR:
1255 	case PCI_IVAR_DEVICE:
1256 	case PCI_IVAR_DEVID:
1257 	case PCI_IVAR_CLASS:
1258 	case PCI_IVAR_SUBCLASS:
1259 	case PCI_IVAR_PROGIF:
1260 	case PCI_IVAR_REVID:
1261 	case PCI_IVAR_INTPIN:
1262 	case PCI_IVAR_IRQ:
1263 	case PCI_IVAR_BUS:
1264 	case PCI_IVAR_SLOT:
1265 	case PCI_IVAR_FUNCTION:
1266 		return EINVAL;	/* disallow for now */
1267 
1268 	case PCI_IVAR_SECONDARYBUS:
1269 		cfg->secondarybus = value;
1270 		break;
1271 	case PCI_IVAR_SUBORDINATEBUS:
1272 		cfg->subordinatebus = value;
1273 		break;
1274 	default:
1275 		return ENOENT;
1276 	}
1277 	return 0;
1278 }
1279 
1280 static struct resource *
1281 pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
1282 		   u_long start, u_long end, u_long count, u_int flags)
1283 {
1284 	struct pci_devinfo *dinfo = device_get_ivars(child);
1285 	struct resource_list *rl = &dinfo->resources;
1286 
1287 	return resource_list_alloc(rl, dev, child, type, rid,
1288 				   start, end, count, flags);
1289 }
1290 
1291 static int
1292 pci_release_resource(device_t dev, device_t child, int type, int rid,
1293 		     struct resource *r)
1294 {
1295 	struct pci_devinfo *dinfo = device_get_ivars(child);
1296 	struct resource_list *rl = &dinfo->resources;
1297 
1298 	return resource_list_release(rl, dev, child, type, rid, r);
1299 }
1300 
1301 static int
1302 pci_set_resource(device_t dev, device_t child, int type, int rid,
1303 		 u_long start, u_long count)
1304 {
1305 	struct pci_devinfo *dinfo = device_get_ivars(child);
1306 	struct resource_list *rl = &dinfo->resources;
1307 
1308 	resource_list_add(rl, type, rid, start, start + count - 1, count);
1309 	return 0;
1310 }
1311 
1312 static int
1313 pci_get_resource(device_t dev, device_t child, int type, int rid,
1314 		 u_long *startp, u_long *countp)
1315 {
1316 	struct pci_devinfo *dinfo = device_get_ivars(child);
1317 	struct resource_list *rl = &dinfo->resources;
1318 	struct resource_list_entry *rle;
1319 
1320 	rle = resource_list_find(rl, type, rid);
1321 	if (!rle)
1322 		return ENOENT;
1323 
1324 	if (startp)
1325 		*startp = rle->start;
1326 	if (countp)
1327 		*countp = rle->count;
1328 
1329 	return 0;
1330 }
1331 
1332 static void
1333 pci_delete_resource(device_t dev, device_t child, int type, int rid)
1334 {
1335 	printf("pci_delete_resource: PCI resources can not be deleted\n");
1336 }
1337 
1338 static u_int32_t
1339 pci_read_config_method(device_t dev, device_t child, int reg, int width)
1340 {
1341 	struct pci_devinfo *dinfo = device_get_ivars(child);
1342 	pcicfgregs *cfg = &dinfo->cfg;
1343 	return pci_cfgread(cfg, reg, width);
1344 }
1345 
1346 static void
1347 pci_write_config_method(device_t dev, device_t child, int reg,
1348 			u_int32_t val, int width)
1349 {
1350 	struct pci_devinfo *dinfo = device_get_ivars(child);
1351 	pcicfgregs *cfg = &dinfo->cfg;
1352 	pci_cfgwrite(cfg, reg, val, width);
1353 }
1354 
1355 static int
1356 pci_modevent(module_t mod, int what, void *arg)
1357 {
1358 	switch (what) {
1359 	case MOD_LOAD:
1360 		STAILQ_INIT(&pci_devq);
1361 		break;
1362 
1363 	case MOD_UNLOAD:
1364 		break;
1365 	}
1366 
1367 	return 0;
1368 }
1369 
1370 static device_method_t pci_methods[] = {
1371 	/* Device interface */
1372 	DEVMETHOD(device_probe,		pci_new_probe),
1373 	DEVMETHOD(device_attach,	bus_generic_attach),
1374 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
1375 	DEVMETHOD(device_suspend,	bus_generic_suspend),
1376 	DEVMETHOD(device_resume,	bus_generic_resume),
1377 
1378 	/* Bus interface */
1379 	DEVMETHOD(bus_print_child,	pci_print_child),
1380 	DEVMETHOD(bus_probe_nomatch,	pci_probe_nomatch),
1381 	DEVMETHOD(bus_read_ivar,	pci_read_ivar),
1382 	DEVMETHOD(bus_write_ivar,	pci_write_ivar),
1383 	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
1384 	DEVMETHOD(bus_alloc_resource,	pci_alloc_resource),
1385 	DEVMETHOD(bus_release_resource,	pci_release_resource),
1386 	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
1387 	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
1388 	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
1389 	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
1390 	DEVMETHOD(bus_set_resource,	pci_set_resource),
1391 	DEVMETHOD(bus_get_resource,	pci_get_resource),
1392 	DEVMETHOD(bus_delete_resource,	pci_delete_resource),
1393 
1394 	/* PCI interface */
1395 	DEVMETHOD(pci_read_config,	pci_read_config_method),
1396 	DEVMETHOD(pci_write_config,	pci_write_config_method),
1397 
1398 	{ 0, 0 }
1399 };
1400 
1401 static driver_t pci_driver = {
1402 	"pci",
1403 	pci_methods,
1404 	1,			/* no softc */
1405 };
1406 static devclass_t	pci_devclass;
1407 DRIVER_MODULE(pci, pcib, pci_driver, pci_devclass, pci_modevent, 0);
1408