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