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