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