pci.c revision 77543
1/*
2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
3 * Copyright (c) 2000, Michael Smith <msmith@freebsd.org>
4 * Copyright (c) 2000, BSDi
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice unmodified, this list of conditions, and the following
12 *    disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $FreeBSD: head/sys/dev/pci/pci.c 77543 2001-05-31 21:47:25Z gallatin $
29 *
30 */
31
32#include "opt_bus.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/linker.h>
39#include <sys/fcntl.h>
40#include <sys/conf.h>
41#include <sys/kernel.h>
42#include <sys/queue.h>
43#include <sys/types.h>
44
45#include <vm/vm.h>
46#include <vm/pmap.h>
47#include <vm/vm_extern.h>
48
49#include <sys/bus.h>
50#include <machine/bus.h>
51#include <sys/rman.h>
52#include <machine/resource.h>
53
54#include <sys/pciio.h>
55#include <pci/pcireg.h>
56#include <pci/pcivar.h>
57
58#include "pcib_if.h"
59#include "pci_if.h"
60
61static u_int32_t	pci_mapbase(unsigned mapreg);
62static int		pci_maptype(unsigned mapreg);
63static int		pci_mapsize(unsigned testval);
64static int		pci_maprange(unsigned mapreg);
65static void		pci_fixancient(pcicfgregs *cfg);
66static void		pci_hdrtypedata(device_t pcib, int b, int s, int f,
67					pcicfgregs *cfg);
68static struct pci_devinfo *pci_read_device(device_t pcib, int b, int s, int f);
69static void		pci_read_extcap(device_t pcib, pcicfgregs *cfg);
70
71static void		pci_print_verbose(struct pci_devinfo *dinfo);
72static int		pci_porten(device_t pcib, int b, int s, int f);
73static int		pci_memen(device_t pcib, int b, int s, int f);
74static int		pci_add_map(device_t pcib, int b, int s, int f, int reg,
75				    struct resource_list *rl);
76static void		pci_add_resources(device_t pcib, int b, int s, int f,
77					  device_t dev);
78static void		pci_add_children(device_t dev, int busno);
79static int		pci_probe(device_t dev);
80static int		pci_print_resources(struct resource_list *rl,
81					    const char *name, int type,
82					    const char *format);
83static int		pci_print_child(device_t dev, device_t child);
84static void		pci_probe_nomatch(device_t dev, device_t child);
85static int		pci_describe_parse_line(char **ptr, int *vendor,
86						int *device, char **desc);
87static char		*pci_describe_device(device_t dev);
88static int		pci_read_ivar(device_t dev, device_t child, int which,
89				      uintptr_t *result);
90static int		pci_write_ivar(device_t dev, device_t child, int which,
91				       uintptr_t value);
92static struct resource	*pci_alloc_resource(device_t dev, device_t child,
93					    int type, int *rid, u_long start,
94					    u_long end, u_long count, u_int flags);
95static void		pci_delete_resource(device_t dev, device_t child,
96					    int type, int rid);
97static struct resource_list *pci_get_resource_list (device_t dev, device_t child);
98static u_int32_t	pci_read_config_method(device_t dev, device_t child,
99					       int reg, int width);
100static void		pci_write_config_method(device_t dev, device_t child,
101						int reg, u_int32_t val, int width);
102static void		pci_enable_busmaster_method(device_t dev,
103						    device_t child);
104static void		pci_disable_busmaster_method(device_t dev,
105						     device_t child);
106static void		pci_enable_io_method(device_t dev, device_t child,
107					     int space);
108static void		pci_disable_io_method(device_t dev, device_t child,
109					      int space);
110static int		pci_set_powerstate_method(device_t dev, device_t child,
111						  int state);
112static int		pci_get_powerstate_method(device_t dev, device_t child);
113static int		pci_modevent(module_t mod, int what, void *arg);
114
115static device_method_t pci_methods[] = {
116	/* Device interface */
117	DEVMETHOD(device_probe,		pci_probe),
118	DEVMETHOD(device_attach,	bus_generic_attach),
119	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
120	DEVMETHOD(device_suspend,	bus_generic_suspend),
121	DEVMETHOD(device_resume,	bus_generic_resume),
122
123	/* Bus interface */
124	DEVMETHOD(bus_print_child,	pci_print_child),
125	DEVMETHOD(bus_probe_nomatch,	pci_probe_nomatch),
126	DEVMETHOD(bus_read_ivar,	pci_read_ivar),
127	DEVMETHOD(bus_write_ivar,	pci_write_ivar),
128	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
129	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
130	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
131
132	DEVMETHOD(bus_get_resource_list,pci_get_resource_list),
133	DEVMETHOD(bus_set_resource,	bus_generic_rl_set_resource),
134	DEVMETHOD(bus_get_resource,	bus_generic_rl_get_resource),
135	DEVMETHOD(bus_delete_resource,	pci_delete_resource),
136	DEVMETHOD(bus_alloc_resource,	pci_alloc_resource),
137	DEVMETHOD(bus_release_resource,	bus_generic_rl_release_resource),
138	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
139	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
140
141	/* PCI interface */
142	DEVMETHOD(pci_read_config,	pci_read_config_method),
143	DEVMETHOD(pci_write_config,	pci_write_config_method),
144	DEVMETHOD(pci_enable_busmaster,	pci_enable_busmaster_method),
145	DEVMETHOD(pci_disable_busmaster, pci_disable_busmaster_method),
146	DEVMETHOD(pci_enable_io,	pci_enable_io_method),
147	DEVMETHOD(pci_disable_io,	pci_disable_io_method),
148	DEVMETHOD(pci_get_powerstate,	pci_get_powerstate_method),
149	DEVMETHOD(pci_set_powerstate,	pci_set_powerstate_method),
150
151	{ 0, 0 }
152};
153
154static driver_t pci_driver = {
155	"pci",
156	pci_methods,
157	0,			/* no softc */
158};
159
160static devclass_t	pci_devclass;
161DRIVER_MODULE(pci, pcib, pci_driver, pci_devclass, pci_modevent, 0);
162DRIVER_MODULE(pci, acpi_pcib, pci_driver, pci_devclass, pci_modevent, 0);
163
164static char	*pci_vendordata;
165static size_t	pci_vendordata_size;
166
167
168struct pci_quirk {
169	u_int32_t devid;	/* Vendor/device of the card */
170	int	type;
171#define PCI_QUIRK_MAP_REG	1 /* PCI map register in weird place */
172	int	arg1;
173	int	arg2;
174};
175
176struct pci_quirk pci_quirks[] = {
177	/* The Intel 82371AB has a map register at offset 0x90. */
178	{ 0x71138086, PCI_QUIRK_MAP_REG,	0x90,	 0 },
179	/* As does the Serverworks OSB4 (the SMBus mapping register) */
180	{ 0x02001166, PCI_QUIRK_MAP_REG,	0x90,	 0 },
181
182	{ 0 }
183};
184
185/* map register information */
186#define PCI_MAPMEM	0x01	/* memory map */
187#define PCI_MAPMEMP	0x02	/* prefetchable memory map */
188#define PCI_MAPPORT	0x04	/* port map */
189
190u_int32_t pci_numdevs = 0;
191
192/* return base address of memory or port map */
193
194static u_int32_t
195pci_mapbase(unsigned mapreg)
196{
197	int mask = 0x03;
198	if ((mapreg & 0x01) == 0)
199		mask = 0x0f;
200	return (mapreg & ~mask);
201}
202
203/* return map type of memory or port map */
204
205static int
206pci_maptype(unsigned mapreg)
207{
208	static u_int8_t maptype[0x10] = {
209		PCI_MAPMEM,		PCI_MAPPORT,
210		PCI_MAPMEM,		0,
211		PCI_MAPMEM,		PCI_MAPPORT,
212		0,			0,
213		PCI_MAPMEM|PCI_MAPMEMP,	PCI_MAPPORT,
214		PCI_MAPMEM|PCI_MAPMEMP, 0,
215		PCI_MAPMEM|PCI_MAPMEMP,	PCI_MAPPORT,
216		0,			0,
217	};
218
219	return maptype[mapreg & 0x0f];
220}
221
222/* return log2 of map size decoded for memory or port map */
223
224static int
225pci_mapsize(unsigned testval)
226{
227	int ln2size;
228
229	testval = pci_mapbase(testval);
230	ln2size = 0;
231	if (testval != 0) {
232		while ((testval & 1) == 0)
233		{
234			ln2size++;
235			testval >>= 1;
236		}
237	}
238	return (ln2size);
239}
240
241/* return log2 of address range supported by map register */
242
243static int
244pci_maprange(unsigned mapreg)
245{
246	int ln2range = 0;
247	switch (mapreg & 0x07) {
248	case 0x00:
249	case 0x01:
250	case 0x05:
251		ln2range = 32;
252		break;
253	case 0x02:
254		ln2range = 20;
255		break;
256	case 0x04:
257		ln2range = 64;
258		break;
259	}
260	return (ln2range);
261}
262
263/* adjust some values from PCI 1.0 devices to match 2.0 standards ... */
264
265static void
266pci_fixancient(pcicfgregs *cfg)
267{
268	if (cfg->hdrtype != 0)
269		return;
270
271	/* PCI to PCI bridges use header type 1 */
272	if (cfg->baseclass == PCIC_BRIDGE && cfg->subclass == PCIS_BRIDGE_PCI)
273		cfg->hdrtype = 1;
274}
275
276/* extract header type specific config data */
277
278static void
279pci_hdrtypedata(device_t pcib, int b, int s, int f, pcicfgregs *cfg)
280{
281#define REG(n, w)	PCIB_READ_CONFIG(pcib, b, s, f, n, w)
282	switch (cfg->hdrtype) {
283	case 0:
284		cfg->subvendor      = REG(PCIR_SUBVEND_0, 2);
285		cfg->subdevice      = REG(PCIR_SUBDEV_0, 2);
286		cfg->nummaps	    = PCI_MAXMAPS_0;
287		break;
288	case 1:
289		cfg->subvendor      = REG(PCIR_SUBVEND_1, 2);
290		cfg->subdevice      = REG(PCIR_SUBDEV_1, 2);
291		cfg->nummaps	    = PCI_MAXMAPS_1;
292		break;
293	case 2:
294		cfg->subvendor      = REG(PCIR_SUBVEND_2, 2);
295		cfg->subdevice      = REG(PCIR_SUBDEV_2, 2);
296		cfg->nummaps	    = PCI_MAXMAPS_2;
297		break;
298	}
299#undef REG
300}
301
302/* read configuration header into pcicfgregs structure */
303
304static struct pci_devinfo *
305pci_read_device(device_t pcib, int b, int s, int f)
306{
307#define REG(n, w)	PCIB_READ_CONFIG(pcib, b, s, f, n, w)
308	pcicfgregs *cfg = NULL;
309	struct pci_devinfo *devlist_entry;
310	struct devlist *devlist_head;
311
312	devlist_head = &pci_devq;
313
314	devlist_entry = NULL;
315
316	if (PCIB_READ_CONFIG(pcib, b, s, f, PCIR_DEVVENDOR, 4) != -1) {
317		devlist_entry = malloc(sizeof(struct pci_devinfo),
318				       M_DEVBUF, M_WAITOK | M_ZERO);
319		if (devlist_entry == NULL)
320			return (NULL);
321
322		cfg = &devlist_entry->cfg;
323
324		cfg->bus		= b;
325		cfg->slot		= s;
326		cfg->func		= f;
327		cfg->vendor		= REG(PCIR_VENDOR, 2);
328		cfg->device		= REG(PCIR_DEVICE, 2);
329		cfg->cmdreg		= REG(PCIR_COMMAND, 2);
330		cfg->statreg		= REG(PCIR_STATUS, 2);
331		cfg->baseclass		= REG(PCIR_CLASS, 1);
332		cfg->subclass		= REG(PCIR_SUBCLASS, 1);
333		cfg->progif		= REG(PCIR_PROGIF, 1);
334		cfg->revid		= REG(PCIR_REVID, 1);
335		cfg->hdrtype		= REG(PCIR_HEADERTYPE, 1);
336		cfg->cachelnsz		= REG(PCIR_CACHELNSZ, 1);
337		cfg->lattimer		= REG(PCIR_LATTIMER, 1);
338		cfg->intpin		= REG(PCIR_INTPIN, 1);
339		cfg->intline		= REG(PCIR_INTLINE, 1);
340
341		cfg->mingnt		= REG(PCIR_MINGNT, 1);
342		cfg->maxlat		= REG(PCIR_MAXLAT, 1);
343
344		cfg->mfdev		= (cfg->hdrtype & PCIM_MFDEV) != 0;
345		cfg->hdrtype		&= ~PCIM_MFDEV;
346
347		pci_fixancient(cfg);
348		pci_hdrtypedata(pcib, b, s, f, cfg);
349
350		if (REG(PCIR_STATUS, 2) & PCIM_STATUS_CAPPRESENT)
351			pci_read_extcap(pcib, cfg);
352
353		STAILQ_INSERT_TAIL(devlist_head, devlist_entry, pci_links);
354
355		devlist_entry->conf.pc_sel.pc_bus = cfg->bus;
356		devlist_entry->conf.pc_sel.pc_dev = cfg->slot;
357		devlist_entry->conf.pc_sel.pc_func = cfg->func;
358		devlist_entry->conf.pc_hdr = cfg->hdrtype;
359
360		devlist_entry->conf.pc_subvendor = cfg->subvendor;
361		devlist_entry->conf.pc_subdevice = cfg->subdevice;
362		devlist_entry->conf.pc_vendor = cfg->vendor;
363		devlist_entry->conf.pc_device = cfg->device;
364
365		devlist_entry->conf.pc_class = cfg->baseclass;
366		devlist_entry->conf.pc_subclass = cfg->subclass;
367		devlist_entry->conf.pc_progif = cfg->progif;
368		devlist_entry->conf.pc_revid = cfg->revid;
369
370		pci_numdevs++;
371		pci_generation++;
372	}
373	return (devlist_entry);
374#undef REG
375}
376
377static void
378pci_read_extcap(device_t pcib, pcicfgregs *cfg)
379{
380#define REG(n, w)	PCIB_READ_CONFIG(pcib, cfg->bus, cfg->slot, cfg->func, n, w)
381	int	ptr, nextptr, ptrptr;
382
383	switch (cfg->hdrtype) {
384	case 0:
385		ptrptr = 0x34;
386		break;
387	case 2:
388		ptrptr = 0x14;
389		break;
390	default:
391		return;		/* no extended capabilities support */
392	}
393	nextptr = REG(ptrptr, 1);	/* sanity check? */
394
395	/*
396	 * Read capability entries.
397	 */
398	while (nextptr != 0) {
399		/* Sanity check */
400		if (nextptr > 255) {
401			printf("illegal PCI extended capability offset %d\n",
402			    nextptr);
403			return;
404		}
405		/* Find the next entry */
406		ptr = nextptr;
407		nextptr = REG(ptr + 1, 1);
408
409		/* Process this entry */
410		switch (REG(ptr, 1)) {
411		case 0x01:		/* PCI power management */
412			if (cfg->pp_cap == 0) {
413				cfg->pp_cap = REG(ptr + PCIR_POWER_CAP, 2);
414				cfg->pp_status = ptr + PCIR_POWER_STATUS;
415				cfg->pp_pmcsr = ptr + PCIR_POWER_PMCSR;
416				if ((nextptr - ptr) > PCIR_POWER_DATA)
417					cfg->pp_data = ptr + PCIR_POWER_DATA;
418			}
419			break;
420		default:
421			break;
422		}
423	}
424#undef REG
425}
426
427#if 0
428/* free pcicfgregs structure and all depending data structures */
429
430static int
431pci_freecfg(struct pci_devinfo *dinfo)
432{
433	struct devlist *devlist_head;
434
435	devlist_head = &pci_devq;
436
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/*
453 * PCI power manangement
454 */
455static int
456pci_set_powerstate_method(device_t dev, device_t child, int state)
457{
458	struct pci_devinfo *dinfo = device_get_ivars(child);
459	pcicfgregs *cfg = &dinfo->cfg;
460	u_int16_t status;
461	int result;
462
463	if (cfg->pp_cap != 0) {
464		status = PCI_READ_CONFIG(dev, child, cfg->pp_status, 2) & ~PCIM_PSTAT_DMASK;
465		result = 0;
466		switch (state) {
467		case PCI_POWERSTATE_D0:
468			status |= PCIM_PSTAT_D0;
469			break;
470		case PCI_POWERSTATE_D1:
471			if (cfg->pp_cap & PCIM_PCAP_D1SUPP) {
472				status |= PCIM_PSTAT_D1;
473			} else {
474				result = EOPNOTSUPP;
475			}
476			break;
477		case PCI_POWERSTATE_D2:
478			if (cfg->pp_cap & PCIM_PCAP_D2SUPP) {
479				status |= PCIM_PSTAT_D2;
480			} else {
481				result = EOPNOTSUPP;
482			}
483			break;
484		case PCI_POWERSTATE_D3:
485			status |= PCIM_PSTAT_D3;
486			break;
487		default:
488			result = EINVAL;
489		}
490		if (result == 0)
491			PCI_WRITE_CONFIG(dev, child, cfg->pp_status, status, 2);
492	} else {
493		result = ENXIO;
494	}
495	return(result);
496}
497
498static int
499pci_get_powerstate_method(device_t dev, device_t child)
500{
501	struct pci_devinfo *dinfo = device_get_ivars(child);
502	pcicfgregs *cfg = &dinfo->cfg;
503	u_int16_t status;
504	int result;
505
506	if (cfg->pp_cap != 0) {
507		status = PCI_READ_CONFIG(dev, child, cfg->pp_status, 2);
508		switch (status & PCIM_PSTAT_DMASK) {
509		case PCIM_PSTAT_D0:
510			result = PCI_POWERSTATE_D0;
511			break;
512		case PCIM_PSTAT_D1:
513			result = PCI_POWERSTATE_D1;
514			break;
515		case PCIM_PSTAT_D2:
516			result = PCI_POWERSTATE_D2;
517			break;
518		case PCIM_PSTAT_D3:
519			result = PCI_POWERSTATE_D3;
520			break;
521		default:
522			result = PCI_POWERSTATE_UNKNOWN;
523			break;
524		}
525	} else {
526		/* No support, device is always at D0 */
527		result = PCI_POWERSTATE_D0;
528	}
529	return(result);
530}
531
532/*
533 * Some convenience functions for PCI device drivers.
534 */
535
536static __inline void
537pci_set_command_bit(device_t dev, device_t child, u_int16_t bit)
538{
539    u_int16_t	command;
540
541    command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2);
542    command |= bit;
543    PCI_WRITE_CONFIG(dev, child, PCIR_COMMAND, command, 2);
544}
545
546static __inline void
547pci_clear_command_bit(device_t dev, device_t child, u_int16_t bit)
548{
549    u_int16_t	command;
550
551    command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2);
552    command &= ~bit;
553    PCI_WRITE_CONFIG(dev, child, PCIR_COMMAND, command, 2);
554}
555
556static void
557pci_enable_busmaster_method(device_t dev, device_t child)
558{
559    pci_set_command_bit(dev, child, PCIM_CMD_BUSMASTEREN);
560}
561
562static void
563pci_disable_busmaster_method(device_t dev, device_t child)
564{
565    pci_clear_command_bit(dev, child, PCIM_CMD_BUSMASTEREN);
566}
567
568static void
569pci_enable_io_method(device_t dev, device_t child, int space)
570{
571    switch(space) {
572    case SYS_RES_IOPORT:
573	pci_set_command_bit(dev, child, PCIM_CMD_PORTEN);
574	break;
575    case SYS_RES_MEMORY:
576	pci_set_command_bit(dev, child, PCIM_CMD_MEMEN);
577	break;
578    }
579}
580
581static void
582pci_disable_io_method(device_t dev, device_t child, int space)
583{
584    switch(space) {
585    case SYS_RES_IOPORT:
586	pci_clear_command_bit(dev, child, PCIM_CMD_PORTEN);
587	break;
588    case SYS_RES_MEMORY:
589	pci_clear_command_bit(dev, child, PCIM_CMD_MEMEN);
590	break;
591    }
592}
593
594/*
595 * New style pci driver.  Parent device is either a pci-host-bridge or a
596 * pci-pci-bridge.  Both kinds are represented by instances of pcib.
597 */
598
599static void
600pci_print_verbose(struct pci_devinfo *dinfo)
601{
602	if (bootverbose) {
603		pcicfgregs *cfg = &dinfo->cfg;
604
605		printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n",
606		       cfg->vendor, cfg->device, cfg->revid);
607		printf("\tbus=%d, slot=%d, func=%d\n",
608		       cfg->bus, cfg->slot, cfg->func);
609		printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n",
610		       cfg->baseclass, cfg->subclass, cfg->progif,
611		       cfg->hdrtype, cfg->mfdev);
612#ifdef PCI_DEBUG
613		printf("\tcmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n",
614		       cfg->cmdreg, cfg->statreg, cfg->cachelnsz);
615		printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n",
616		       cfg->lattimer, cfg->lattimer * 30,
617		       cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250);
618#endif /* PCI_DEBUG */
619		if (cfg->intpin > 0)
620			printf("\tintpin=%c, irq=%d\n", cfg->intpin +'a' -1, cfg->intline);
621		if (cfg->pp_cap) {
622			u_int16_t status;
623
624			status = pci_read_config(cfg->dev, cfg->pp_status, 2);
625			printf("\tpowerspec %d  supports D0%s%s D3  current D%d\n",
626			       cfg->pp_cap & PCIM_PCAP_SPEC,
627			       cfg->pp_cap & PCIM_PCAP_D1SUPP ? " D1" : "",
628			       cfg->pp_cap & PCIM_PCAP_D2SUPP ? " D2" : "",
629			       status & PCIM_PSTAT_DMASK);
630		}
631	}
632}
633
634static int
635pci_porten(device_t pcib, int b, int s, int f)
636{
637	return (PCIB_READ_CONFIG(pcib, b, s, f, PCIR_COMMAND, 2)
638		& PCIM_CMD_PORTEN) != 0;
639}
640
641static int
642pci_memen(device_t pcib, int b, int s, int f)
643{
644	return (PCIB_READ_CONFIG(pcib, b, s, f, PCIR_COMMAND, 2)
645		& PCIM_CMD_MEMEN) != 0;
646}
647
648/*
649 * Add a resource based on a pci map register. Return 1 if the map
650 * register is a 32bit map register or 2 if it is a 64bit register.
651 */
652static int
653pci_add_map(device_t pcib, int b, int s, int f, int reg,
654	    struct resource_list *rl)
655{
656	u_int32_t map;
657	u_int64_t base;
658	u_int8_t ln2size;
659	u_int8_t ln2range;
660	u_int32_t testval;
661#ifdef PCI_ENABLE_IO_MODES
662	u_int16_t cmd;
663#endif
664	int type;
665
666	map = PCIB_READ_CONFIG(pcib, b, s, f, reg, 4);
667
668	if (map == 0 || map == 0xffffffff)
669		return 1; /* skip invalid entry */
670
671	PCIB_WRITE_CONFIG(pcib, b, s, f, reg, 0xffffffff, 4);
672	testval = PCIB_READ_CONFIG(pcib, b, s, f, reg, 4);
673	PCIB_WRITE_CONFIG(pcib, b, s, f, reg, map, 4);
674
675	base = pci_mapbase(map);
676	if (pci_maptype(map) & PCI_MAPMEM)
677		type = SYS_RES_MEMORY;
678	else
679		type = SYS_RES_IOPORT;
680	ln2size = pci_mapsize(testval);
681	ln2range = pci_maprange(testval);
682	if (ln2range == 64) {
683		/* Read the other half of a 64bit map register */
684		base |= (u_int64_t) PCIB_READ_CONFIG(pcib, b, s, f, reg + 4, 4) << 32;
685	}
686
687	if (bootverbose) {
688		printf("\tmap[%02x]: type %x, range %2d, base %08x, size %2d",
689		       reg, pci_maptype(map), ln2range,
690		       (unsigned int) base, ln2size);
691		if (type == SYS_RES_IOPORT && !pci_porten(pcib, b, s, f))
692			printf(", port disabled\n");
693		else if (type == SYS_RES_MEMORY && !pci_memen(pcib, b, s, f))
694			printf(", memory disabled\n");
695		else
696			printf(", enabled\n");
697	}
698
699	/*
700	 * This code theoretically does the right thing, but has
701	 * undesirable side effects in some cases where
702	 * peripherals respond oddly to having these bits
703	 * enabled.  Leave them alone by default.
704	 */
705#ifdef PCI_ENABLE_IO_MODES
706	/* Turn on resources that have been left off by a lazy BIOS */
707	if (type == SYS_RES_IOPORT && !pci_porten(pcib, b, s, f)) {
708		cmd = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_COMMAND, 2);
709		cmd |= PCIM_CMD_PORTEN;
710		PCIB_WRITE_CONFIG(pcib, b, s, f, PCIR_COMMAND, cmd, 2);
711	}
712	if (type == SYS_RES_MEMORY && !pci_memen(pcib, b, s, f)) {
713		cmd = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_COMMAND, 2);
714		cmd |= PCIM_CMD_MEMEN;
715		PCIB_WRITE_CONFIG(pcib, b, s, f, PCIR_COMMAND, cmd, 2);
716	}
717#else
718        if (type == SYS_RES_IOPORT && !pci_porten(pcib, b, s, f))
719                return 1;
720        if (type == SYS_RES_MEMORY && !pci_memen(pcib, b, s, f))
721		return 1;
722#endif
723
724	resource_list_add(rl, type, reg,
725			  base, base + (1 << ln2size) - 1,
726			  (1 << ln2size));
727
728	return (ln2range == 64) ? 2 : 1;
729}
730
731static void
732pci_add_resources(device_t pcib, int b, int s, int f, device_t dev)
733{
734	struct pci_devinfo *dinfo = device_get_ivars(dev);
735	pcicfgregs *cfg = &dinfo->cfg;
736	struct resource_list *rl = &dinfo->resources;
737	struct pci_quirk *q;
738	int i;
739
740	for (i = 0; i < cfg->nummaps;) {
741		i += pci_add_map(pcib, b, s, f, PCIR_MAPS + i*4, rl);
742	}
743
744	for (q = &pci_quirks[0]; q->devid; q++) {
745		if (q->devid == ((cfg->device << 16) | cfg->vendor)
746		    && q->type == PCI_QUIRK_MAP_REG)
747			pci_add_map(pcib, b, s, f, q->arg1, rl);
748	}
749
750	if (cfg->intpin > 0 && cfg->intline != 255)
751		resource_list_add(rl, SYS_RES_IRQ, 0,
752				  cfg->intline, cfg->intline, 1);
753}
754
755static void
756pci_add_children(device_t dev, int busno)
757{
758	device_t pcib = device_get_parent(dev);
759	int maxslots;
760	int s, f;
761
762	maxslots = PCIB_MAXSLOTS(pcib);
763
764	for (s = 0; s <= maxslots; s++) {
765		int pcifunchigh = 0;
766		for (f = 0; f <= pcifunchigh; f++) {
767			struct pci_devinfo *dinfo =
768				pci_read_device(pcib, busno, s, f);
769			if (dinfo != NULL) {
770				if (dinfo->cfg.mfdev)
771					pcifunchigh = PCI_FUNCMAX;
772
773				dinfo->cfg.dev = device_add_child(dev, NULL, -1);
774				device_set_ivars(dinfo->cfg.dev, dinfo);
775				pci_add_resources(pcib, busno, s, f,
776						  dinfo->cfg.dev);
777				pci_print_verbose(dinfo);
778			}
779		}
780	}
781}
782
783static int
784pci_probe(device_t dev)
785{
786	static int once, busno;
787	caddr_t vendordata, info;
788
789	device_set_desc(dev, "PCI bus");
790
791	if (bootverbose)
792		device_printf(dev, "physical bus=%d\n", pcib_get_bus(dev));
793
794	/*
795	 * Since there can be multiple independantly numbered PCI
796	 * busses on some large alpha systems, we can't use the unit
797	 * number to decide what bus we are probing. We ask the parent
798	 * pcib what our bus number is.
799	 */
800	busno = pcib_get_bus(dev);
801	if (busno < 0)
802		return ENXIO;
803	pci_add_children(dev, busno);
804
805	if (!once) {
806		make_dev(&pcicdev, 0, UID_ROOT, GID_WHEEL, 0644, "pci");
807		if ((vendordata = preload_search_by_type("pci_vendor_data")) != NULL) {
808			info = preload_search_info(vendordata, MODINFO_ADDR);
809			pci_vendordata = *(char **)info;
810			info = preload_search_info(vendordata, MODINFO_SIZE);
811			pci_vendordata_size = *(size_t *)info;
812			/* terminate the database */
813			pci_vendordata[pci_vendordata_size] = '\n';
814		}
815		once++;
816	}
817
818	return 0;
819}
820
821static int
822pci_print_resources(struct resource_list *rl, const char *name, int type,
823		    const char *format)
824{
825	struct resource_list_entry *rle;
826	int printed, retval;
827
828	printed = 0;
829	retval = 0;
830	/* Yes, this is kinda cheating */
831	SLIST_FOREACH(rle, rl, link) {
832		if (rle->type == type) {
833			if (printed == 0)
834				retval += printf(" %s ", name);
835			else if (printed > 0)
836				retval += printf(",");
837			printed++;
838			retval += printf(format, rle->start);
839			if (rle->count > 1) {
840				retval += printf("-");
841				retval += printf(format, rle->start +
842						 rle->count - 1);
843			}
844		}
845	}
846	return retval;
847}
848
849static int
850pci_print_child(device_t dev, device_t child)
851{
852	struct pci_devinfo *dinfo;
853	struct resource_list *rl;
854	pcicfgregs *cfg;
855	int retval = 0;
856
857	dinfo = device_get_ivars(child);
858	cfg = &dinfo->cfg;
859	rl = &dinfo->resources;
860
861	retval += bus_print_child_header(dev, child);
862
863	retval += pci_print_resources(rl, "port", SYS_RES_IOPORT, "%#lx");
864	retval += pci_print_resources(rl, "mem", SYS_RES_MEMORY, "%#lx");
865	retval += pci_print_resources(rl, "irq", SYS_RES_IRQ, "%ld");
866	if (device_get_flags(dev))
867		retval += printf(" flags %#x", device_get_flags(dev));
868
869	retval += printf(" at device %d.%d", pci_get_slot(child),
870			 pci_get_function(child));
871
872	retval += bus_print_child_footer(dev, child);
873
874	return (retval);
875}
876
877static struct
878{
879	int	class;
880	int	subclass;
881	char	*desc;
882} pci_nomatch_tab[] = {
883	{PCIC_OLD,		-1,			"old"},
884	{PCIC_OLD,		PCIS_OLD_NONVGA,	"non-VGA display device"},
885	{PCIC_OLD,		PCIS_OLD_VGA,		"VGA-compatible display device"},
886	{PCIC_STORAGE,		-1,			"mass storage"},
887	{PCIC_STORAGE,		PCIS_STORAGE_SCSI,	"SCSI"},
888	{PCIC_STORAGE,		PCIS_STORAGE_IDE,	"ATA"},
889	{PCIC_STORAGE,		PCIS_STORAGE_FLOPPY,	"floppy disk"},
890	{PCIC_STORAGE,		PCIS_STORAGE_IPI,	"IPI"},
891	{PCIC_STORAGE,		PCIS_STORAGE_RAID,	"RAID"},
892	{PCIC_NETWORK,		-1,			"network"},
893	{PCIC_NETWORK,		PCIS_NETWORK_ETHERNET,	"ethernet"},
894	{PCIC_NETWORK,		PCIS_NETWORK_TOKENRING,	"token ring"},
895	{PCIC_NETWORK,		PCIS_NETWORK_FDDI,	"fddi"},
896	{PCIC_NETWORK,		PCIS_NETWORK_ATM,	"ATM"},
897	{PCIC_DISPLAY,		-1,			"display"},
898	{PCIC_DISPLAY,		PCIS_DISPLAY_VGA,	"VGA"},
899	{PCIC_DISPLAY,		PCIS_DISPLAY_XGA,	"XGA"},
900	{PCIC_MULTIMEDIA,	-1,			"multimedia"},
901	{PCIC_MULTIMEDIA,	PCIS_MULTIMEDIA_VIDEO,	"video"},
902	{PCIC_MULTIMEDIA,	PCIS_MULTIMEDIA_AUDIO,	"audio"},
903	{PCIC_MEMORY,		-1,			"memory"},
904	{PCIC_MEMORY,		PCIS_MEMORY_RAM,	"RAM"},
905	{PCIC_MEMORY,		PCIS_MEMORY_FLASH,	"flash"},
906	{PCIC_BRIDGE,		-1,			"bridge"},
907	{PCIC_BRIDGE,		PCIS_BRIDGE_HOST,	"HOST-PCI"},
908	{PCIC_BRIDGE,		PCIS_BRIDGE_ISA,	"PCI-ISA"},
909	{PCIC_BRIDGE,		PCIS_BRIDGE_EISA,	"PCI-EISA"},
910	{PCIC_BRIDGE,		PCIS_BRIDGE_MCA,	"PCI-MCA"},
911	{PCIC_BRIDGE,		PCIS_BRIDGE_PCI,	"PCI-PCI"},
912	{PCIC_BRIDGE,		PCIS_BRIDGE_PCMCIA,	"PCI-PCMCIA"},
913	{PCIC_BRIDGE,		PCIS_BRIDGE_NUBUS,	"PCI-NuBus"},
914	{PCIC_BRIDGE,		PCIS_BRIDGE_CARDBUS,	"PCI-CardBus"},
915	{PCIC_BRIDGE,		PCIS_BRIDGE_OTHER,	"PCI-unknown"},
916	{PCIC_SIMPLECOMM,	-1,			"simple comms"},
917	{PCIC_SIMPLECOMM,	PCIS_SIMPLECOMM_UART,	"UART"},	/* could detect 16550 */
918	{PCIC_SIMPLECOMM,	PCIS_SIMPLECOMM_PAR,	"parallel port"},
919	{PCIC_BASEPERIPH,	-1,			"base peripheral"},
920	{PCIC_BASEPERIPH,	PCIS_BASEPERIPH_PIC,	"interrupt controller"},
921	{PCIC_BASEPERIPH,	PCIS_BASEPERIPH_DMA,	"DMA controller"},
922	{PCIC_BASEPERIPH,	PCIS_BASEPERIPH_TIMER,	"timer"},
923	{PCIC_BASEPERIPH,	PCIS_BASEPERIPH_RTC,	"realtime clock"},
924	{PCIC_INPUTDEV,		-1,			"input device"},
925	{PCIC_INPUTDEV,		PCIS_INPUTDEV_KEYBOARD,	"keyboard"},
926	{PCIC_INPUTDEV,		PCIS_INPUTDEV_DIGITIZER,"digitizer"},
927	{PCIC_INPUTDEV,		PCIS_INPUTDEV_MOUSE,	"mouse"},
928	{PCIC_DOCKING,		-1,			"docking station"},
929	{PCIC_PROCESSOR,	-1,			"processor"},
930	{PCIC_SERIALBUS,	-1,			"serial bus"},
931	{PCIC_SERIALBUS,	PCIS_SERIALBUS_FW,	"FireWire"},
932	{PCIC_SERIALBUS,	PCIS_SERIALBUS_ACCESS,	"AccessBus"},
933	{PCIC_SERIALBUS,	PCIS_SERIALBUS_SSA,	"SSA"},
934	{PCIC_SERIALBUS,	PCIS_SERIALBUS_USB,	"USB"},
935	{PCIC_SERIALBUS,	PCIS_SERIALBUS_FC,	"Fibre Channel"},
936	{PCIC_SERIALBUS,	PCIS_SERIALBUS_SMBUS,	"SMBus"},
937	{0, 0,		NULL}
938};
939
940static void
941pci_probe_nomatch(device_t dev, device_t child)
942{
943	int	i;
944	char	*cp, *scp, *device;
945
946	/*
947	 * Look for a listing for this device in a loaded device database.
948	 */
949	if ((device = pci_describe_device(child)) != NULL) {
950		device_printf(dev, "<%s>", device);
951		free(device, M_DEVBUF);
952	} else {
953	    /*
954	     * Scan the class/subclass descriptions for a general description.
955	     */
956	    cp = "unknown";
957	    scp = NULL;
958	    for (i = 0; pci_nomatch_tab[i].desc != NULL; i++) {
959		if (pci_nomatch_tab[i].class == pci_get_class(child)) {
960		    if (pci_nomatch_tab[i].subclass == -1) {
961			cp = pci_nomatch_tab[i].desc;
962		    } else if (pci_nomatch_tab[i].subclass == pci_get_subclass(child)) {
963			scp = pci_nomatch_tab[i].desc;
964		    }
965		}
966	    }
967	    device_printf(dev, "<%s%s%s>",
968			  cp ? : "",
969			  ((cp != NULL) && (scp != NULL)) ? ", " : "",
970			  scp ? : "");
971	}
972	printf(" at %d.%d (no driver attached)\n",
973	       pci_get_slot(child),
974	       pci_get_function(child));
975	return;
976}
977
978/*
979 * Parse the PCI device database, if loaded, and return a pointer to a
980 * description of the device.
981 *
982 * The database is flat text formatted as follows:
983 *
984 * Any line not in a valid format is ignored.
985 * Lines are terminated with newline '\n' characters.
986 *
987 * A VENDOR line consists of the 4 digit (hex) vendor code, a TAB, then
988 * the vendor name.
989 *
990 * A DEVICE line is entered immediately below the corresponding VENDOR ID.
991 * - devices cannot be listed without a corresponding VENDOR line.
992 * A DEVICE line consists of a TAB, the 4 digit (hex) device code,
993 * another TAB, then the device name.
994 */
995
996/*
997 * Assuming (ptr) points to the beginning of a line in the database,
998 * return the vendor or device and description of the next entry.
999 * The value of (vendor) or (device) inappropriate for the entry type
1000 * is set to -1.  Returns nonzero at the end of the database.
1001 *
1002 * Note that this is slightly unrobust in the face of corrupt data;
1003 * we attempt to safeguard against this by spamming the end of the
1004 * database with a newline when we initialise.
1005 */
1006static int
1007pci_describe_parse_line(char **ptr, int *vendor, int *device, char **desc)
1008{
1009	char	*cp = *ptr;
1010	int	left;
1011
1012	*device = -1;
1013	*vendor = -1;
1014	**desc = '\0';
1015	for (;;) {
1016		left = pci_vendordata_size - (cp - pci_vendordata);
1017		if (left <= 0) {
1018			*ptr = cp;
1019			return(1);
1020		}
1021
1022		/* vendor entry? */
1023		if (*cp != '\t' && sscanf(cp, "%x\t%80[^\n]", vendor, *desc) == 2)
1024			break;
1025		/* device entry? */
1026		if (*cp == '\t' && sscanf(cp, "%x\t%80[^\n]", device, *desc) == 2)
1027			break;
1028
1029		/* skip to next line */
1030		while (*cp != '\n' && left > 0) {
1031			cp++;
1032			left--;
1033		}
1034		if (*cp == '\n') {
1035			cp++;
1036			left--;
1037		}
1038	}
1039	/* skip to next line */
1040	while (*cp != '\n' && left > 0) {
1041		cp++;
1042		left--;
1043	}
1044	if (*cp == '\n' && left > 0)
1045		cp++;
1046	*ptr = cp;
1047	return(0);
1048}
1049
1050static char *
1051pci_describe_device(device_t dev)
1052{
1053	int	vendor, device;
1054	char	*desc, *vp, *dp, *line;
1055
1056	desc = vp = dp = NULL;
1057
1058	/*
1059	 * If we have no vendor data, we can't do anything.
1060	 */
1061	if (pci_vendordata == NULL)
1062		goto out;
1063
1064	/*
1065	 * Scan the vendor data looking for this device
1066	 */
1067	line = pci_vendordata;
1068	if ((vp = malloc(80, M_DEVBUF, M_NOWAIT)) == NULL)
1069		goto out;
1070	for (;;) {
1071		if (pci_describe_parse_line(&line, &vendor, &device, &vp))
1072			goto out;
1073		if (vendor == pci_get_vendor(dev))
1074			break;
1075	}
1076	if ((dp = malloc(80, M_DEVBUF, M_NOWAIT)) == NULL)
1077		goto out;
1078	for (;;) {
1079		if (pci_describe_parse_line(&line, &vendor, &device, &dp)) {
1080			*dp = 0;
1081			break;
1082		}
1083		if (vendor != -1) {
1084			*dp = 0;
1085			break;
1086		}
1087		if (device == pci_get_device(dev))
1088			break;
1089	}
1090	if (dp[0] == '\0')
1091		snprintf(dp, 80, "0x%x", pci_get_device(dev));
1092	if ((desc = malloc(strlen(vp) + strlen(dp) + 3, M_DEVBUF, M_NOWAIT)) != NULL)
1093		sprintf(desc, "%s, %s", vp, dp);
1094 out:
1095	if (vp != NULL)
1096		free(vp, M_DEVBUF);
1097	if (dp != NULL)
1098		free(dp, M_DEVBUF);
1099	return(desc);
1100}
1101
1102static int
1103pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
1104{
1105	struct pci_devinfo *dinfo;
1106	pcicfgregs *cfg;
1107
1108	dinfo = device_get_ivars(child);
1109	cfg = &dinfo->cfg;
1110
1111	switch (which) {
1112	case PCI_IVAR_SUBVENDOR:
1113		*result = cfg->subvendor;
1114		break;
1115	case PCI_IVAR_SUBDEVICE:
1116		*result = cfg->subdevice;
1117		break;
1118	case PCI_IVAR_VENDOR:
1119		*result = cfg->vendor;
1120		break;
1121	case PCI_IVAR_DEVICE:
1122		*result = cfg->device;
1123		break;
1124	case PCI_IVAR_DEVID:
1125		*result = (cfg->device << 16) | cfg->vendor;
1126		break;
1127	case PCI_IVAR_CLASS:
1128		*result = cfg->baseclass;
1129		break;
1130	case PCI_IVAR_SUBCLASS:
1131		*result = cfg->subclass;
1132		break;
1133	case PCI_IVAR_PROGIF:
1134		*result = cfg->progif;
1135		break;
1136	case PCI_IVAR_REVID:
1137		*result = cfg->revid;
1138		break;
1139	case PCI_IVAR_INTPIN:
1140		*result = cfg->intpin;
1141		break;
1142	case PCI_IVAR_IRQ:
1143		*result = cfg->intline;
1144		break;
1145	case PCI_IVAR_BUS:
1146		*result = cfg->bus;
1147		break;
1148	case PCI_IVAR_SLOT:
1149		*result = cfg->slot;
1150		break;
1151	case PCI_IVAR_FUNCTION:
1152		*result = cfg->func;
1153		break;
1154	default:
1155		return ENOENT;
1156	}
1157	return 0;
1158}
1159
1160static int
1161pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
1162{
1163	struct pci_devinfo *dinfo;
1164	pcicfgregs *cfg;
1165
1166	dinfo = device_get_ivars(child);
1167	cfg = &dinfo->cfg;
1168
1169	switch (which) {
1170	case PCI_IVAR_SUBVENDOR:
1171	case PCI_IVAR_SUBDEVICE:
1172	case PCI_IVAR_VENDOR:
1173	case PCI_IVAR_DEVICE:
1174	case PCI_IVAR_DEVID:
1175	case PCI_IVAR_CLASS:
1176	case PCI_IVAR_SUBCLASS:
1177	case PCI_IVAR_PROGIF:
1178	case PCI_IVAR_REVID:
1179	case PCI_IVAR_INTPIN:
1180	case PCI_IVAR_IRQ:
1181	case PCI_IVAR_BUS:
1182	case PCI_IVAR_SLOT:
1183	case PCI_IVAR_FUNCTION:
1184		return EINVAL;	/* disallow for now */
1185
1186	default:
1187		return ENOENT;
1188	}
1189	return 0;
1190}
1191
1192static struct resource *
1193pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
1194		   u_long start, u_long end, u_long count, u_int flags)
1195{
1196	struct pci_devinfo *dinfo = device_get_ivars(child);
1197	struct resource_list *rl = &dinfo->resources;
1198	pcicfgregs *cfg = &dinfo->cfg;
1199
1200	/*
1201	 * Perform lazy resource allocation
1202	 *
1203	 * XXX add support here for SYS_RES_IOPORT and SYS_RES_MEMORY
1204	 */
1205	if (device_get_parent(child) == dev) {
1206		/*
1207		 * If device doesn't have an interrupt routed, and is deserving of
1208		 * an interrupt, try to assign it one.
1209		 */
1210		if ((type == SYS_RES_IRQ) && (cfg->intline == 255) && (cfg->intpin != 0)) {
1211			cfg->intline = PCIB_ROUTE_INTERRUPT(device_get_parent(dev), child,
1212							    cfg->intpin);
1213			if (cfg->intline != 255) {
1214				pci_write_config(child, PCIR_INTLINE, cfg->intline, 1);
1215				resource_list_add(rl, SYS_RES_IRQ, 0,
1216						  cfg->intline, cfg->intline, 1);
1217			}
1218		}
1219	}
1220
1221	return resource_list_alloc(rl, dev, child, type, rid,
1222				   start, end, count, flags);
1223}
1224
1225static void
1226pci_delete_resource(device_t dev, device_t child, int type, int rid)
1227{
1228	printf("pci_delete_resource: PCI resources can not be deleted\n");
1229}
1230
1231static struct resource_list *
1232pci_get_resource_list (device_t dev, device_t child)
1233{
1234	struct pci_devinfo *	dinfo = device_get_ivars(child);
1235	struct resource_list *  rl = &dinfo->resources;
1236
1237	if (!rl)
1238		return (NULL);
1239
1240	return (rl);
1241}
1242
1243static u_int32_t
1244pci_read_config_method(device_t dev, device_t child, int reg, int width)
1245{
1246	struct pci_devinfo *dinfo = device_get_ivars(child);
1247	pcicfgregs *cfg = &dinfo->cfg;
1248
1249	return PCIB_READ_CONFIG(device_get_parent(dev),
1250				cfg->bus, cfg->slot, cfg->func,
1251				reg, width);
1252}
1253
1254static void
1255pci_write_config_method(device_t dev, device_t child, int reg,
1256			u_int32_t val, int width)
1257{
1258	struct pci_devinfo *dinfo = device_get_ivars(child);
1259	pcicfgregs *cfg = &dinfo->cfg;
1260
1261	PCIB_WRITE_CONFIG(device_get_parent(dev),
1262			  cfg->bus, cfg->slot, cfg->func,
1263			  reg, val, width);
1264}
1265
1266static int
1267pci_modevent(module_t mod, int what, void *arg)
1268{
1269	switch (what) {
1270	case MOD_LOAD:
1271		STAILQ_INIT(&pci_devq);
1272		pci_generation = 0;
1273		break;
1274
1275	case MOD_UNLOAD:
1276		break;
1277	}
1278
1279	return 0;
1280}
1281