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