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