xref: /freebsd/sys/dev/pci/pci.c (revision 380a989b3223d455375b4fae70fd0b9bdd43bafb)
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  * $Id: pci.c,v 1.90 1998/11/03 08:47:29 julian Exp $
27  *
28  */
29 
30 #include "pci.h"
31 #if NPCI > 0
32 
33 #include "opt_devfs.h"
34 #include "opt_simos.h"
35 
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/malloc.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 #include <sys/buf.h>
45 #ifdef DEVFS
46 #include <sys/devfsext.h>
47 #endif /* DEVFS */
48 
49 #include <vm/vm.h>
50 #include <vm/pmap.h>
51 #include <vm/vm_extern.h>
52 
53 #include <pci/pcireg.h>
54 #include <pci/pcivar.h>
55 #include <pci/pci_ioctl.h>
56 
57 #ifdef APIC_IO
58 #include <machine/smp.h>
59 #endif /* APIC_IO */
60 
61 STAILQ_HEAD(devlist, pci_devinfo) pci_devq;
62 u_int32_t pci_numdevs = 0;
63 u_int32_t pci_generation = 0;
64 
65 /* return highest PCI bus number known to be used, or -1 if none */
66 
67 static int
68 pci_bushigh(void)
69 {
70 	if (pci_cfgopen() == 0)
71 		return (-1);
72 	return (0);
73 }
74 
75 /* return base address of memory or port map */
76 
77 static int
78 pci_mapbase(unsigned mapreg)
79 {
80 	int mask = 0x03;
81 	if ((mapreg & 0x01) == 0)
82 		mask = 0x0f;
83 	return (mapreg & ~mask);
84 }
85 
86 /* return map type of memory or port map */
87 
88 static int
89 pci_maptype(unsigned mapreg)
90 {
91 	static u_int8_t maptype[0x10] = {
92 		PCI_MAPMEM,		PCI_MAPPORT,
93 		PCI_MAPMEM,		0,
94 		PCI_MAPMEM,		PCI_MAPPORT,
95 		0,			0,
96 		PCI_MAPMEM|PCI_MAPMEMP,	PCI_MAPPORT,
97 		PCI_MAPMEM|PCI_MAPMEMP, 0,
98 		PCI_MAPMEM|PCI_MAPMEMP,	PCI_MAPPORT,
99 		0,			0,
100 	};
101 
102 	return maptype[mapreg & 0x0f];
103 }
104 
105 /* return log2 of map size decoded for memory or port map */
106 
107 static int
108 pci_mapsize(unsigned testval)
109 {
110 	int ln2size;
111 
112 	testval = pci_mapbase(testval);
113 	ln2size = 0;
114 	if (testval != 0) {
115 		while ((testval & 1) == 0)
116 		{
117 			ln2size++;
118 			testval >>= 1;
119 		}
120 	}
121 	return (ln2size);
122 }
123 
124 /* return log2 of address range supported by map register */
125 
126 static int
127 pci_maprange(unsigned mapreg)
128 {
129 	int ln2range = 0;
130 	switch (mapreg & 0x07) {
131 	case 0x00:
132 	case 0x01:
133 	case 0x05:
134 		ln2range = 32;
135 		break;
136 	case 0x02:
137 		ln2range = 20;
138 		break;
139 	case 0x04:
140 		ln2range = 64;
141 		break;
142 	}
143 	return (ln2range);
144 }
145 
146 /* extract map parameters into newly allocated array of pcimap structures */
147 
148 static pcimap *
149 pci_readmaps(pcicfgregs *cfg, int maxmaps)
150 {
151 	int i, j = 0;
152 	pcimap *map;
153 	int map64 = 0;
154 	int reg = PCIR_MAPS;
155 
156 	for (i = 0; i < maxmaps; i++) {
157 		int reg = PCIR_MAPS + i*4;
158 		u_int32_t base;
159 		u_int32_t ln2range;
160 
161 		base = pci_cfgread(cfg, reg, 4);
162 		ln2range = pci_maprange(base);
163 
164 		if (base == 0 || ln2range == 0 || base == 0xffffffff)
165 			continue; /* skip invalid entry */
166 		else {
167 			j++;
168 			if (ln2range > 32) {
169 				i++;
170 				j++;
171 			}
172 		}
173 	}
174 
175 	map = malloc(j * sizeof (pcimap), M_DEVBUF, M_WAITOK);
176 	if (map != NULL) {
177 		bzero(map, sizeof(pcimap) * j);
178 		cfg->nummaps = j;
179 
180 		for (i = 0, j = 0; i < maxmaps; i++, reg += 4) {
181 			u_int32_t base;
182 			u_int32_t testval;
183 
184 			base = pci_cfgread(cfg, reg, 4);
185 
186 			if (map64 == 0) {
187 				if (base == 0 || base == 0xffffffff)
188 					continue; /* skip invalid entry */
189 				pci_cfgwrite(cfg, reg, 0xffffffff, 4);
190 				testval = pci_cfgread(cfg, reg, 4);
191 				pci_cfgwrite(cfg, reg, base, 4);
192 
193 				map[j].base     = pci_mapbase(base);
194 				map[j].type     = pci_maptype(base);
195 				map[j].ln2size  = pci_mapsize(testval);
196 				map[j].ln2range = pci_maprange(testval);
197 				map64 = map[j].ln2range == 64;
198 			} else {
199 				/* only fill in base, other fields are 0 */
200 				map[j].base     = base;
201 				map64 = 0;
202 			}
203 			j++;
204 		}
205 	}
206 	return (map);
207 }
208 
209 /* adjust some values from PCI 1.0 devices to match 2.0 standards ... */
210 
211 static void
212 pci_fixancient(pcicfgregs *cfg)
213 {
214 	if (cfg->hdrtype != 0)
215 		return;
216 
217 	/* PCI to PCI bridges use header type 1 */
218 	if (cfg->baseclass == PCIC_BRIDGE && cfg->subclass == PCIS_BRIDGE_PCI)
219 		cfg->hdrtype = 1;
220 }
221 
222 /* read config data specific to header type 1 device (PCI to PCI bridge) */
223 
224 static void *
225 pci_readppb(pcicfgregs *cfg)
226 {
227 	pcih1cfgregs *p;
228 
229 	p = malloc(sizeof (pcih1cfgregs), M_DEVBUF, M_WAITOK);
230 	if (p == NULL)
231 		return (NULL);
232 
233 	bzero(p, sizeof *p);
234 
235 	p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_1, 2);
236 	p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_1, 2);
237 
238 	p->seclat = pci_cfgread(cfg, PCIR_SECLAT_1, 1);
239 
240 	p->iobase = PCI_PPBIOBASE (pci_cfgread(cfg, PCIR_IOBASEH_1, 2),
241 				   pci_cfgread(cfg, PCIR_IOBASEL_1, 1));
242 	p->iolimit = PCI_PPBIOLIMIT (pci_cfgread(cfg, PCIR_IOLIMITH_1, 2),
243 				     pci_cfgread(cfg, PCIR_IOLIMITL_1, 1));
244 
245 	p->membase = PCI_PPBMEMBASE (0,
246 				     pci_cfgread(cfg, PCIR_MEMBASE_1, 2));
247 	p->memlimit = PCI_PPBMEMLIMIT (0,
248 				       pci_cfgread(cfg, PCIR_MEMLIMIT_1, 2));
249 
250 	p->pmembase = PCI_PPBMEMBASE (
251 		(pci_addr_t)pci_cfgread(cfg, PCIR_PMBASEH_1, 4),
252 		pci_cfgread(cfg, PCIR_PMBASEL_1, 2));
253 
254 	p->pmemlimit = PCI_PPBMEMLIMIT (
255 		(pci_addr_t)pci_cfgread(cfg, PCIR_PMLIMITH_1, 4),
256 		pci_cfgread(cfg, PCIR_PMLIMITL_1, 2));
257 	return (p);
258 }
259 
260 /* read config data specific to header type 2 device (PCI to CardBus bridge) */
261 
262 static void *
263 pci_readpcb(pcicfgregs *cfg)
264 {
265 	pcih2cfgregs *p;
266 
267 	p = malloc(sizeof (pcih2cfgregs), M_DEVBUF, M_WAITOK);
268 	if (p == NULL)
269 		return (NULL);
270 
271 	bzero(p, sizeof *p);
272 
273 	p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_2, 2);
274 	p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_2, 2);
275 
276 	p->seclat = pci_cfgread(cfg, PCIR_SECLAT_2, 1);
277 
278 	p->membase0 = pci_cfgread(cfg, PCIR_MEMBASE0_2, 4);
279 	p->memlimit0 = pci_cfgread(cfg, PCIR_MEMLIMIT0_2, 4);
280 	p->membase1 = pci_cfgread(cfg, PCIR_MEMBASE1_2, 4);
281 	p->memlimit1 = pci_cfgread(cfg, PCIR_MEMLIMIT1_2, 4);
282 
283 	p->iobase0 = pci_cfgread(cfg, PCIR_IOBASE0_2, 4);
284 	p->iolimit0 = pci_cfgread(cfg, PCIR_IOLIMIT0_2, 4);
285 	p->iobase1 = pci_cfgread(cfg, PCIR_IOBASE1_2, 4);
286 	p->iolimit1 = pci_cfgread(cfg, PCIR_IOLIMIT1_2, 4);
287 
288 	p->pccardif = pci_cfgread(cfg, PCIR_PCCARDIF_2, 4);
289 	return p;
290 }
291 
292 /* extract header type specific config data */
293 
294 static void
295 pci_hdrtypedata(pcicfgregs *cfg)
296 {
297 	switch (cfg->hdrtype) {
298 	case 0:
299 		cfg->subvendor      = pci_cfgread(cfg, PCIR_SUBVEND_0, 2);
300 		cfg->subdevice      = pci_cfgread(cfg, PCIR_SUBDEV_0, 2);
301 		cfg->map            = pci_readmaps(cfg, PCI_MAXMAPS_0);
302 		break;
303 	case 1:
304 		cfg->subvendor      = pci_cfgread(cfg, PCIR_SUBVEND_1, 2);
305 		cfg->subdevice      = pci_cfgread(cfg, PCIR_SUBDEV_1, 2);
306 		cfg->secondarybus   = pci_cfgread(cfg, PCIR_SECBUS_1, 1);
307 		cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_1, 1);
308 		cfg->map            = pci_readmaps(cfg, PCI_MAXMAPS_1);
309 		cfg->hdrspec        = pci_readppb(cfg);
310 		break;
311 	case 2:
312 		cfg->subvendor      = pci_cfgread(cfg, PCIR_SUBVEND_2, 2);
313 		cfg->subdevice      = pci_cfgread(cfg, PCIR_SUBDEV_2, 2);
314 		cfg->secondarybus   = pci_cfgread(cfg, PCIR_SECBUS_2, 1);
315 		cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_2, 1);
316 		cfg->map            = pci_readmaps(cfg, PCI_MAXMAPS_2);
317 		cfg->hdrspec        = pci_readpcb(cfg);
318 		break;
319 	}
320 }
321 
322 /* read configuration header into pcicfgrect structure */
323 
324 static struct pci_devinfo *
325 pci_readcfg(pcicfgregs *probe)
326 {
327 	pcicfgregs *cfg = NULL;
328 	struct pci_devinfo *devlist_entry;
329 	struct devlist *devlist_head;
330 
331 	devlist_head = &pci_devq;
332 
333 	devlist_entry = NULL;
334 
335 	if (pci_cfgread(probe, PCIR_DEVVENDOR, 4) != -1) {
336 		devlist_entry = malloc(sizeof(struct pci_devinfo),
337 				       M_DEVBUF, M_WAITOK);
338 		if (devlist_entry == NULL)
339 			return (NULL);
340 
341 		cfg = &devlist_entry->cfg;
342 
343 		bzero(cfg, sizeof *cfg);
344 
345 		cfg->bus		= probe->bus;
346 		cfg->slot		= probe->slot;
347 		cfg->func		= probe->func;
348 		cfg->vendor		= pci_cfgread(cfg, PCIR_VENDOR, 2);
349 		cfg->device		= pci_cfgread(cfg, PCIR_DEVICE, 2);
350 		cfg->cmdreg		= pci_cfgread(cfg, PCIR_COMMAND, 2);
351 		cfg->statreg		= pci_cfgread(cfg, PCIR_STATUS, 2);
352 		cfg->baseclass		= pci_cfgread(cfg, PCIR_CLASS, 1);
353 		cfg->subclass		= pci_cfgread(cfg, PCIR_SUBCLASS, 1);
354 		cfg->progif		= pci_cfgread(cfg, PCIR_PROGIF, 1);
355 		cfg->revid		= pci_cfgread(cfg, PCIR_REVID, 1);
356 		cfg->hdrtype		= pci_cfgread(cfg, PCIR_HEADERTYPE, 1);
357 		cfg->cachelnsz		= pci_cfgread(cfg, PCIR_CACHELNSZ, 1);
358 		cfg->lattimer		= pci_cfgread(cfg, PCIR_LATTIMER, 1);
359 		cfg->intpin		= pci_cfgread(cfg, PCIR_INTPIN, 1);
360 		cfg->intline		= pci_cfgread(cfg, PCIR_INTLINE, 1);
361 #ifdef __alpha__
362 		alpha_platform_assign_pciintr(cfg);
363 #endif
364 
365 #ifdef APIC_IO
366 		if (cfg->intpin != 0) {
367 			int airq;
368 
369 			airq = pci_apic_irq(cfg->bus, cfg->slot, cfg->intpin);
370 			if (airq >= 0) {
371 				/* PCI specific entry found in MP table */
372 				if (airq != cfg->intline) {
373 					undirect_pci_irq(cfg->intline);
374 					cfg->intline = airq;
375 				}
376 			} else {
377 				/*
378 				 * PCI interrupts might be redirected to the
379 				 * ISA bus according to some MP tables. Use the
380 				 * same methods as used by the ISA devices
381 				 * devices to find the proper IOAPIC int pin.
382 				 */
383 				airq = isa_apic_irq(cfg->intline);
384 				if ((airq >= 0) && (airq != cfg->intline)) {
385 					/* XXX: undirect_pci_irq() ? */
386 					undirect_isa_irq(cfg->intline);
387 					cfg->intline = airq;
388 				}
389 			}
390 		}
391 #endif /* APIC_IO */
392 
393 		cfg->mingnt		= pci_cfgread(cfg, PCIR_MINGNT, 1);
394 		cfg->maxlat		= pci_cfgread(cfg, PCIR_MAXLAT, 1);
395 
396 		cfg->mfdev		= (cfg->hdrtype & PCIM_MFDEV) != 0;
397 		cfg->hdrtype		&= ~PCIM_MFDEV;
398 
399 		pci_fixancient(cfg);
400 		pci_hdrtypedata(cfg);
401 
402 		STAILQ_INSERT_TAIL(devlist_head, devlist_entry, pci_links);
403 
404 		devlist_entry->conf.pc_sel.pc_bus = cfg->bus;
405 		devlist_entry->conf.pc_sel.pc_dev = cfg->slot;
406 		devlist_entry->conf.pc_sel.pc_func = cfg->func;
407 		devlist_entry->conf.pc_hdr = cfg->hdrtype;
408 
409 		devlist_entry->conf.pc_subvendor = cfg->subvendor;
410 		devlist_entry->conf.pc_subdevice = cfg->subdevice;
411 		devlist_entry->conf.pc_vendor = cfg->vendor;
412 		devlist_entry->conf.pc_device = cfg->device;
413 
414 		devlist_entry->conf.pc_class = cfg->baseclass;
415 		devlist_entry->conf.pc_subclass = cfg->subclass;
416 		devlist_entry->conf.pc_progif = cfg->progif;
417 		devlist_entry->conf.pc_revid = cfg->revid;
418 
419 		pci_numdevs++;
420 		pci_generation++;
421 	}
422 	return (devlist_entry);
423 }
424 
425 #if 0
426 /* free pcicfgregs structure and all depending data structures */
427 
428 static int
429 pci_freecfg(struct pci_devinfo *dinfo)
430 {
431 	struct devlist *devlist_head;
432 
433 	devlist_head = &pci_devq;
434 
435 	if (dinfo->cfg.hdrspec != NULL)
436 		free(dinfo->cfg.hdrspec, M_DEVBUF);
437 	if (dinfo->cfg.map != NULL)
438 		free(dinfo->cfg.map, M_DEVBUF);
439 	/* XXX this hasn't been tested */
440 	STAILQ_REMOVE(devlist_head, dinfo, pci_devinfo, pci_links);
441 	free(dinfo, M_DEVBUF);
442 
443 	/* increment the generation count */
444 	pci_generation++;
445 
446 	/* we're losing one device */
447 	pci_numdevs--;
448 	return (0);
449 }
450 #endif
451 
452 static void
453 pci_addcfg(struct pci_devinfo *dinfo)
454 {
455 	if (bootverbose) {
456 		int i;
457 		pcicfgregs *cfg = &dinfo->cfg;
458 
459 		printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n",
460 		       cfg->vendor, cfg->device, cfg->revid);
461 		printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n",
462 		       cfg->baseclass, cfg->subclass, cfg->progif,
463 		       cfg->hdrtype, cfg->mfdev);
464 		printf("\tsubordinatebus=%x \tsecondarybus=%x\n",
465 		       cfg->subordinatebus, cfg->secondarybus);
466 #ifdef PCI_DEBUG
467 		printf("\tcmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n",
468 		       cfg->cmdreg, cfg->statreg, cfg->cachelnsz);
469 		printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n",
470 		       cfg->lattimer, cfg->lattimer * 30,
471 		       cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250);
472 #endif /* PCI_DEBUG */
473 		if (cfg->intpin > 0)
474 			printf("\tintpin=%c, irq=%d\n", cfg->intpin +'a' -1, cfg->intline);
475 
476 		for (i = 0; i < cfg->nummaps; i++) {
477 			pcimap *m = &cfg->map[i];
478 			printf("\tmap[%d]: type %x, range %2d, base %08x, size %2d\n",
479 			       i, m->type, m->ln2range, m->base, m->ln2size);
480 		}
481 	}
482 	pci_drvattach(dinfo); /* XXX currently defined in pci_compat.c */
483 }
484 
485 /* return pointer to device that is a bridge to this bus */
486 
487 static pcicfgregs *
488 pci_bridgeto(int bus)
489 {
490 	return (NULL); /* XXX not yet implemented */
491 }
492 
493 /* scan one PCI bus for devices */
494 
495 static int
496 pci_probebus(int bus)
497 {
498 	pcicfgregs probe;
499 	int bushigh = bus;
500 
501 #ifdef SIMOS
502 #undef PCI_SLOTMAX
503 #define PCI_SLOTMAX 0
504 #endif
505 
506 	bzero(&probe, sizeof probe);
507 	/* XXX KDM */
508 	/* probe.parent = pci_bridgeto(bus); */
509 	probe.bus = bus;
510 	for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) {
511 		int pcifunchigh = 0;
512 		for (probe.func = 0; probe.func <= pcifunchigh; probe.func++) {
513 			struct pci_devinfo *dinfo = pci_readcfg(&probe);
514 			if (dinfo != NULL) {
515 				if (dinfo->cfg.mfdev)
516 					pcifunchigh = 7;
517 				/*
518 				 * XXX: Temporarily move pci_addcfg() up before
519 				 * the use of cfg->subordinatebus. This is
520 				 * necessary, since pci_addcfg() calls the
521 				 * device's probe(), which may read the bus#
522 				 * from some device dependent register of
523 				 * some host to PCI bridges. The probe will
524 				 * eventually be moved to pci_readcfg(), and
525 				 * pci_addcfg() will then be moved back down
526 				 * below the conditional statement ...
527 				 */
528 				pci_addcfg(dinfo);
529 
530 				if (bushigh < dinfo->cfg.subordinatebus)
531 					bushigh = dinfo->cfg.subordinatebus;
532 				if (bushigh < dinfo->cfg.secondarybus)
533 					bushigh = dinfo->cfg.secondarybus;
534 
535 				/* XXX KDM */
536 				/* cfg = NULL; we don't own this anymore ... */
537 			}
538 		}
539 	}
540 	return (bushigh);
541 }
542 
543 /* scan a PCI bus tree reached through one PCI attachment point */
544 
545 int
546 pci_probe(pciattach *parent)
547 {
548 	int bushigh;
549 	int bus = 0;
550 
551 	STAILQ_INIT(&pci_devq);
552 
553 	bushigh = pci_bushigh();
554 	while (bus <= bushigh) {
555 		int newbushigh;
556 
557 		printf("Probing for devices on PCI bus %d:\n", bus);
558 		newbushigh = pci_probebus(bus);
559 
560 		if (bushigh < newbushigh)
561 			bushigh = newbushigh;
562 		bus++;
563 	}
564 	return (bushigh);
565 }
566 
567 /*
568  * This is the user interface to PCI configuration space.
569  */
570 
571 static int
572 pci_open(dev_t dev, int oflags, int devtype, struct proc *p)
573 {
574 	if ((oflags & FWRITE) && securelevel > 0) {
575 		return EPERM;
576 	}
577 	return 0;
578 }
579 
580 static int
581 pci_close(dev_t dev, int flag, int devtype, struct proc *p)
582 {
583 	return 0;
584 }
585 
586 /*
587  * Match a single pci_conf structure against an array of pci_match_conf
588  * structures.  The first argument, 'matches', is an array of num_matches
589  * pci_match_conf structures.  match_buf is a pointer to the pci_conf
590  * structure that will be compared to every entry in the matches array.
591  * This function returns 1 on failure, 0 on success.
592  */
593 static int
594 pci_conf_match(struct pci_match_conf *matches, int num_matches,
595 	       struct pci_conf *match_buf)
596 {
597 	int i;
598 
599 	if ((matches == NULL) || (match_buf == NULL) || (num_matches <= 0))
600 		return(1);
601 
602 	for (i = 0; i < num_matches; i++) {
603 		/*
604 		 * I'm not sure why someone would do this...but...
605 		 */
606 		if (matches[i].flags == PCI_GETCONF_NO_MATCH)
607 			continue;
608 
609 		/*
610 		 * Look at each of the match flags.  If it's set, do the
611 		 * comparison.  If the comparison fails, we don't have a
612 		 * match, go on to the next item if there is one.
613 		 */
614 		if (((matches[i].flags & PCI_GETCONF_MATCH_BUS) != 0)
615 		 && (match_buf->pc_sel.pc_bus != matches[i].pc_sel.pc_bus))
616 			continue;
617 
618 		if (((matches[i].flags & PCI_GETCONF_MATCH_DEV) != 0)
619 		 && (match_buf->pc_sel.pc_dev != matches[i].pc_sel.pc_dev))
620 			continue;
621 
622 		if (((matches[i].flags & PCI_GETCONF_MATCH_FUNC) != 0)
623 		 && (match_buf->pc_sel.pc_func != matches[i].pc_sel.pc_func))
624 			continue;
625 
626 		if (((matches[i].flags & PCI_GETCONF_MATCH_VENDOR) != 0)
627 		 && (match_buf->pc_vendor != matches[i].pc_vendor))
628 			continue;
629 
630 		if (((matches[i].flags & PCI_GETCONF_MATCH_DEVICE) != 0)
631 		 && (match_buf->pc_device != matches[i].pc_device))
632 			continue;
633 
634 		if (((matches[i].flags & PCI_GETCONF_MATCH_CLASS) != 0)
635 		 && (match_buf->pc_class != matches[i].pc_class))
636 			continue;
637 
638 		if (((matches[i].flags & PCI_GETCONF_MATCH_UNIT) != 0)
639 		 && (match_buf->pd_unit != matches[i].pd_unit))
640 			continue;
641 
642 		if (((matches[i].flags & PCI_GETCONF_MATCH_NAME) != 0)
643 		 && (strncmp(matches[i].pd_name, match_buf->pd_name,
644 			     sizeof(match_buf->pd_name)) != 0))
645 			continue;
646 
647 		return(0);
648 	}
649 
650 	return(1);
651 }
652 
653 static int
654 pci_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
655 {
656 	struct pci_io *io;
657 	int error;
658 
659 	if (!(flag & FWRITE))
660 		return EPERM;
661 
662 
663 	switch(cmd) {
664 	case PCIOCGETCONF:
665 		{
666 		struct pci_devinfo *dinfo;
667 		struct pci_conf_io *cio;
668 		struct devlist *devlist_head;
669 		struct pci_match_conf *pattern_buf;
670 		int num_patterns;
671 		size_t iolen;
672 		int ionum, i;
673 
674 		cio = (struct pci_conf_io *)data;
675 
676 		num_patterns = 0;
677 		dinfo = NULL;
678 
679 		/*
680 		 * Hopefully the user won't pass in a null pointer, but it
681 		 * can't hurt to check.
682 		 */
683 		if (cio == NULL) {
684 			error = EINVAL;
685 			break;
686 		}
687 
688 		/*
689 		 * If the user specified an offset into the device list,
690 		 * but the list has changed since they last called this
691 		 * ioctl, tell them that the list has changed.  They will
692 		 * have to get the list from the beginning.
693 		 */
694 		if ((cio->offset != 0)
695 		 && (cio->generation != pci_generation)){
696 			cio->num_matches = 0;
697 			cio->status = PCI_GETCONF_LIST_CHANGED;
698 			error = 0;
699 			break;
700 		}
701 
702 		/*
703 		 * Check to see whether the user has asked for an offset
704 		 * past the end of our list.
705 		 */
706 		if (cio->offset >= pci_numdevs) {
707 			cio->num_matches = 0;
708 			cio->status = PCI_GETCONF_LAST_DEVICE;
709 			error = 0;
710 			break;
711 		}
712 
713 		/* get the head of the device queue */
714 		devlist_head = &pci_devq;
715 
716 		/*
717 		 * Determine how much room we have for pci_conf structures.
718 		 * Round the user's buffer size down to the nearest
719 		 * multiple of sizeof(struct pci_conf) in case the user
720 		 * didn't specify a multiple of that size.
721 		 */
722 		iolen = min(cio->match_buf_len -
723 			    (cio->match_buf_len % sizeof(struct pci_conf)),
724 			    pci_numdevs * sizeof(struct pci_conf));
725 
726 		/*
727 		 * Since we know that iolen is a multiple of the size of
728 		 * the pciconf union, it's okay to do this.
729 		 */
730 		ionum = iolen / sizeof(struct pci_conf);
731 
732 		/*
733 		 * If this test is true, the user wants the pci_conf
734 		 * structures returned to match the supplied entries.
735 		 */
736 		if ((cio->num_patterns > 0)
737 		 && (cio->pat_buf_len > 0)) {
738 			/*
739 			 * pat_buf_len needs to be:
740 			 * num_patterns * sizeof(struct pci_match_conf)
741 			 * While it is certainly possible the user just
742 			 * allocated a large buffer, but set the number of
743 			 * matches correctly, it is far more likely that
744 			 * their kernel doesn't match the userland utility
745 			 * they're using.  It's also possible that the user
746 			 * forgot to initialize some variables.  Yes, this
747 			 * may be overly picky, but I hazard to guess that
748 			 * it's far more likely to just catch folks that
749 			 * updated their kernel but not their userland.
750 			 */
751 			if ((cio->num_patterns *
752 			    sizeof(struct pci_match_conf)) != cio->pat_buf_len){
753 				/* The user made a mistake, return an error*/
754 				cio->status = PCI_GETCONF_ERROR;
755 				printf("pci_ioctl: pat_buf_len %d != "
756 				       "num_patterns (%d) * sizeof(struct "
757 				       "pci_match_conf) (%d)\npci_ioctl: "
758 				       "pat_buf_len should be = %d\n",
759 				       cio->pat_buf_len, cio->num_patterns,
760 				       sizeof(struct pci_match_conf),
761 				       sizeof(struct pci_match_conf) *
762 				       cio->num_patterns);
763 				printf("pci_ioctl: do your headers match your "
764 				       "kernel?\n");
765 				cio->num_matches = 0;
766 				error = EINVAL;
767 				break;
768 			}
769 
770 			/*
771 			 * Check the user's buffer to make sure it's readable.
772 			 */
773 			if ((error = useracc((caddr_t)cio->patterns,
774 			                     cio->pat_buf_len, B_READ)) != 1){
775 				printf("pci_ioctl: pattern buffer %p, "
776 				       "length %u isn't user accessible for"
777 				       " READ\n", cio->patterns,
778 				       cio->pat_buf_len);
779 				error = EACCES;
780 				break;
781 			}
782 			/*
783 			 * Allocate a buffer to hold the patterns.
784 			 */
785 			pattern_buf = malloc(cio->pat_buf_len, M_TEMP,
786 					     M_WAITOK);
787 			error = copyin(cio->patterns, pattern_buf,
788 				       cio->pat_buf_len);
789 			if (error != 0)
790 				break;
791 			num_patterns = cio->num_patterns;
792 
793 		} else if ((cio->num_patterns > 0)
794 			|| (cio->pat_buf_len > 0)) {
795 			/*
796 			 * The user made a mistake, spit out an error.
797 			 */
798 			cio->status = PCI_GETCONF_ERROR;
799 			cio->num_matches = 0;
800 			printf("pci_ioctl: invalid GETCONF arguments\n");
801 			error = EINVAL;
802 			break;
803 		} else
804 			pattern_buf = NULL;
805 
806 		/*
807 		 * Make sure we can write to the match buffer.
808 		 */
809 		if ((error = useracc((caddr_t)cio->matches, cio->match_buf_len,
810 				     B_WRITE)) != 1) {
811 			printf("pci_ioctl: match buffer %p, length %u "
812 			       "isn't user accessible for WRITE\n",
813 			       cio->matches, cio->match_buf_len);
814 			error = EACCES;
815 			break;
816 		}
817 
818 		/*
819 		 * Go through the list of devices and copy out the devices
820 		 * that match the user's criteria.
821 		 */
822 		for (cio->num_matches = 0, error = 0, i = 0,
823 		     dinfo = STAILQ_FIRST(devlist_head);
824 		     (dinfo != NULL) && (cio->num_matches < ionum)
825 		     && (error == 0) && (i < pci_numdevs);
826 		     dinfo = STAILQ_NEXT(dinfo, pci_links), i++) {
827 
828 			if (i < cio->offset)
829 				continue;
830 
831 			if ((pattern_buf == NULL) ||
832 			    (pci_conf_match(pattern_buf, num_patterns,
833 					    &dinfo->conf) == 0)) {
834 
835 				/*
836 				 * If we've filled up the user's buffer,
837 				 * break out at this point.  Since we've
838 				 * got a match here, we'll pick right back
839 				 * up at the matching entry.  We can also
840 				 * tell the user that there are more matches
841 				 * left.
842 				 */
843 				if (cio->num_matches >= ionum)
844 					break;
845 
846 				error = copyout(&dinfo->conf,
847 					        &cio->matches[cio->num_matches],
848 						sizeof(struct pci_conf));
849 				cio->num_matches++;
850 			}
851 		}
852 
853 		/*
854 		 * Set the pointer into the list, so if the user is getting
855 		 * n records at a time, where n < pci_numdevs,
856 		 */
857 		cio->offset = i;
858 
859 		/*
860 		 * Set the generation, the user will need this if they make
861 		 * another ioctl call with offset != 0.
862 		 */
863 		cio->generation = pci_generation;
864 
865 		/*
866 		 * If this is the last device, inform the user so he won't
867 		 * bother asking for more devices.  If dinfo isn't NULL, we
868 		 * know that there are more matches in the list because of
869 		 * the way the traversal is done.
870 		 */
871 		if (dinfo == NULL)
872 			cio->status = PCI_GETCONF_LAST_DEVICE;
873 		else
874 			cio->status = PCI_GETCONF_MORE_DEVS;
875 
876 		if (pattern_buf != NULL)
877 			free(pattern_buf, M_TEMP);
878 
879 		break;
880 		}
881 	case PCIOCREAD:
882 		io = (struct pci_io *)data;
883 		switch(io->pi_width) {
884 			pcicfgregs probe;
885 		case 4:
886 		case 2:
887 		case 1:
888 			probe.bus = io->pi_sel.pc_bus;
889 			probe.slot = io->pi_sel.pc_dev;
890 			probe.func = io->pi_sel.pc_func;
891 			io->pi_data = pci_cfgread(&probe,
892 						  io->pi_reg, io->pi_width);
893 			error = 0;
894 			break;
895 		default:
896 			error = ENODEV;
897 			break;
898 		}
899 		break;
900 
901 	case PCIOCWRITE:
902 		io = (struct pci_io *)data;
903 		switch(io->pi_width) {
904 			pcicfgregs probe;
905 		case 4:
906 		case 2:
907 		case 1:
908 			probe.bus = io->pi_sel.pc_bus;
909 			probe.slot = io->pi_sel.pc_dev;
910 			probe.func = io->pi_sel.pc_func;
911 			pci_cfgwrite(&probe,
912 				    io->pi_reg, io->pi_data, io->pi_width);
913 			error = 0;
914 			break;
915 		default:
916 			error = ENODEV;
917 			break;
918 		}
919 		break;
920 
921 	default:
922 		error = ENOTTY;
923 		break;
924 	}
925 
926 	return (error);
927 }
928 
929 #define	PCI_CDEV	78
930 
931 static struct cdevsw pcicdev = {
932 	pci_open, pci_close, noread, nowrite, pci_ioctl, nostop, noreset,
933 	nodevtotty, seltrue, nommap, nostrategy, "pci", 0, PCI_CDEV
934 };
935 
936 #ifdef DEVFS
937 static void *pci_devfs_token;
938 #endif
939 
940 static void
941 pci_cdevinit(void *dummy)
942 {
943 	dev_t dev;
944 
945 	dev = makedev(PCI_CDEV, 0);
946 	cdevsw_add(&dev, &pcicdev, NULL);
947 #ifdef	DEVFS
948 	pci_devfs_token = devfs_add_devswf(&pcicdev, 0, DV_CHR,
949 					   UID_ROOT, GID_WHEEL, 0644, "pci");
950 #endif
951 }
952 
953 SYSINIT(pcidev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+PCI_CDEV, pci_cdevinit, NULL);
954 
955 #endif /* NPCI > 0 */
956