| From | Sent On | Attachments |
|---|---|---|
| John Baldwin | Mar 7, 2011 10:45 am |
| Subject: | PERFORCE change 189677 for review | |
|---|---|---|
| From: | John Baldwin (jh...@FreeBSD.org) | |
| Date: | Mar 7, 2011 10:45:15 am | |
| List: | org.freebsd.p4-projects | |
http://p4web.freebsd.org/@@189677?ac=10
Change 189677 by jhb@jhb_jhbbsd on 2011/03/07 18:45:39
- Properly handle expansion ROM BARs for PCI-PCI bridges (they are at a different config space offset) and for Cardbus bridges (they don't exist). - Various compile fixes.
Affected files ...
.. //depot/projects/pci/sys/dev/pci/pci.c#6 edit .. //depot/projects/pci/sys/dev/pci/pci_private.h#4 edit .. //depot/projects/pci/sys/dev/pci/pci_user.c#4 edit .. //depot/projects/pci/sys/dev/pci/pcireg.h#2 edit .. //depot/projects/pci/sys/dev/pci/pcivar.h#3 edit
Differences ...
==== //depot/projects/pci/sys/dev/pci/pci.c#6 (text+ko) ====
@@ -69,6 +69,11 @@ #include "pcib_if.h" #include "pci_if.h"
+#define PCIR_IS_BIOS(cfg, reg) \ + (((cfg)->hdrtype == PCIM_HDRTYPE_NORMAL && reg == PCIR_BIOS) || \ + ((cfg)->hdrtype == PCIM_HDRTYPE_BRIDGE && reg == PCIR_BIOS_1)) + + static pci_addr_t pci_mapbase(uint64_t mapreg); static const char *pci_maptype(uint64_t mapreg); static int pci_mapsize(uint64_t testval); @@ -2376,6 +2381,7 @@ static void pci_read_bar(device_t dev, int reg, pci_addr_t *mapp, pci_addr_t *testvalp) { + struct pci_devinfo *dinfo; pci_addr_t map, testval; int ln2range; uint16_t cmd; @@ -2385,7 +2391,8 @@ * memory BAR. Bit 0 is special and should not be set when * sizing the BAR. */ - if (reg == PCIR_BIOS) { + dinfo = device_get_ivars(dev); + if (PCIR_IS_BIOS(&dinfo->cfg, reg)) { map = pci_read_config(dev, reg, 4); pci_write_config(dev, reg, 0xfffffffe, 4); testval = pci_read_config(dev, reg, 4); @@ -2438,10 +2445,12 @@ static void pci_write_bar(device_t dev, struct pci_map *pm, pci_addr_t base) { + struct pci_devinfo *dinfo; int ln2range;
/* The device ROM BAR is always a 32-bit memory BAR. */ - if (pm->pm_reg == PCIR_BIOS) + dinfo = device_get_ivars(dev); + if (PCIR_IS_BIOS(&dinfo->cfg, pm->pm_reg)) ln2range = 32; else ln2range = pci_maprange(pm->pm_value); @@ -2461,7 +2470,7 @@
dinfo = device_get_ivars(dev); STAILQ_FOREACH(pm, &dinfo->cfg.maps, pm_link) { - if (pm->pm_reg == bio->pbi_reg) + if (pm->pm_reg == reg) return (pm); } return (NULL); @@ -2470,18 +2479,21 @@ int pci_bar_enabled(device_t dev, struct pci_map *pm) { + struct pci_devinfo *dinfo; uint16_t cmd;
- if (pm->pm_reg == PCIR_BIOS && !(pm->pm_value & PCIM_BIOS_ENABLE)) + dinfo = device_get_ivars(dev); + if (PCIR_IS_BIOS(&dinfo->cfg, pm->pm_reg) && + !(pm->pm_value & PCIM_BIOS_ENABLE)) return (0); cmd = pci_read_config(dev, PCIR_COMMAND, 2); - if (pm->pm_reg == PCIR_BIOS || PCI_BAR_MEM(pm->pm_value)) + if (PCIR_IS_BIOS(&dinfo->cfg, pm->pm_reg) || PCI_BAR_MEM(pm->pm_value)) return ((cmd & PCIM_CMD_MEMEN) != 0); else return ((cmd & PCIM_CMD_PORTEN) != 0); }
-struct pci_map * +static struct pci_map * pci_add_bar(device_t dev, int reg, pci_addr_t value, pci_addr_t size) { struct pci_devinfo *dinfo; @@ -2495,8 +2507,8 @@ STAILQ_FOREACH(prev, &dinfo->cfg.maps, pm_link) { KASSERT(prev->pm_reg != pm->pm_reg, ("duplicate map %02x", reg)); - if (STAILQ_NEXT(prev) == NULL || STAILQ_NEXT(prev)->pm_reg > - pm->pm_reg) + if (STAILQ_NEXT(prev, pm_link) == NULL || + STAILQ_NEXT(prev, pm_link)->pm_reg > pm->pm_reg) break; } if (prev != NULL) @@ -2514,14 +2526,15 @@ int ln2range;
dinfo = device_get_ivars(dev); - STAILQ_FOREACH(prev, &dinfo->cfg.maps, pm_link) { - if (pm->pm_reg == PCIR_BIOS) + STAILQ_FOREACH(pm, &dinfo->cfg.maps, pm_link) { + if (PCIR_IS_BIOS(&dinfo->cfg, pm->pm_reg)) ln2range = 32; else ln2range = pci_maprange(pm->pm_value); pci_write_config(dev, pm->pm_reg, pm->pm_value, 4); if (ln2range == 64) - pci_write_config(dev, pm->pm_reg + 4, pm->pm_value >> 32, 4); + pci_write_config(dev, pm->pm_reg + 4, + pm->pm_value >> 32, 4); } }
@@ -3820,7 +3833,7 @@ * Determine the size of the BAR and ignore BARs with a size * of 0. Device ROM BARs use a different mask value. */ - if (*rid == PCIR_BIOS) + if (PCIR_IS_BIOS(&dinfo->cfg, *rid)) mapsize = pci_romsize(testval); else mapsize = pci_mapsize(testval); @@ -3829,7 +3842,7 @@ pm = pci_add_bar(child, *rid, map, mapsize); }
- if (PCI_BAR_MEM(map) || *rid == PCIR_BIOS) { + if (PCI_BAR_MEM(map) || PCIR_IS_BIOS(&dinfo->cfg, *rid)) { if (type != SYS_RES_MEMORY) { if (bootverbose) device_printf(dev, @@ -3949,6 +3962,7 @@ pci_activate_resource(device_t dev, device_t child, int type, int rid, struct resource *r) { + struct pci_devinfo *dinfo; int error;
error = bus_generic_activate_resource(dev, child, type, rid, r); @@ -3958,8 +3972,9 @@ /* Enable decoding in the command register when activating BARs. */ if (device_get_parent(child) == dev) { /* Device ROMs need their decoding explicitly enabled. */ - if (rid == PCIR_BIOS) - pci_write_bar(child, pci_get_bar(child, PCIR_BIOS), + dinfo = device_get_ivars(child); + if (PCIR_IS_BIOS(&dinfo->cfg, rid)) + pci_write_bar(child, pci_find_bar(child, rid), rman_get_start(r) | PCIM_BIOS_ENABLE); switch (type) { case SYS_RES_IOPORT: @@ -3975,16 +3990,20 @@ pci_deactivate_resource(device_t dev, device_t child, int type, int rid, struct resource *r) { - struct pci_map *pm; + struct pci_devinfo *dinfo; int error;
error = bus_generic_deactivate_resource(dev, child, type, rid, r); if (error) return (error);
- /* Disable decoding for device ROMs. */ - if (rid == PCIR_BIOS) - pci_write_bar(child, pci_get_bar(child, PCIR_BIOS), rman_get_start(r)); + /* Disable decoding for device ROMs. */ + if (device_get_parent(child) == dev) { + dinfo = device_get_ivars(child); + if (PCIR_IS_BIOS(&dinfo->cfg, rid)) + pci_write_bar(child, pci_find_bar(child, rid), + rman_get_start(r)); + } return (0); }
@@ -4062,7 +4081,7 @@ switch (type) { case SYS_RES_IOPORT: case SYS_RES_MEMORY: - pci_write_bar(child, pci_get_bar(child, rid), 0); + pci_write_bar(child, pci_find_bar(child, rid), 0); break; } #endif @@ -4161,7 +4180,9 @@ void pci_cfg_restore(device_t dev, struct pci_devinfo *dinfo) { +#if 0 int i; +#endif
/* * Only do header type 0 devices. Type 1 devices are bridges, @@ -4209,7 +4230,9 @@ void pci_cfg_save(device_t dev, struct pci_devinfo *dinfo, int setstate) { +#if 0 int i; +#endif uint32_t cls; int ps;
==== //depot/projects/pci/sys/dev/pci/pci_private.h#4 (text+ko) ====
@@ -104,8 +104,6 @@ int pci_assign_interrupt_method(device_t dev, device_t child); int pci_resume(device_t dev); int pci_suspend(device_t dev); -struct pci_map *pci_find_bar(device_t dev, int reg); -int pci_bar_enabled(device_t dev, struct pci_map *pm);
/** Restore the config register state. The state must be previously * saved with pci_cfg_save. However, the pci bus driver takes care of
==== //depot/projects/pci/sys/dev/pci/pci_user.c#4 (text+ko) ====
@@ -309,7 +309,6 @@ struct pci_io *io; struct pci_bar_io *bio; struct pci_match_conf *pattern_buf; - struct resource_list_entry *rle; struct pci_map *pm; size_t confsz, iolen, pbufsz; int error, ionum, i, num_patterns; @@ -685,7 +684,7 @@ error = ENODEV; break; } - pm = pci_find_bar(pcidev, reg); + pm = pci_find_bar(pcidev, bio->pbi_reg); if (pm == NULL) { error = EINVAL; break;
==== //depot/projects/pci/sys/dev/pci/pcireg.h#2 (text+ko) ====
@@ -212,6 +212,7 @@ #define PCIM_BRPM_64 0x1 #define PCIM_BRPM_MASK 0xf
+#define PCIR_BIOS_1 0x38 #define PCIR_BRIDGECTL_1 0x3e
/* config registers for header type 2 (CardBus) devices */
==== //depot/projects/pci/sys/dev/pci/pcivar.h#3 (text+ko) ====
@@ -477,4 +477,7 @@ extern struct devlist pci_devq; extern uint32_t pci_generation;
+struct pci_map *pci_find_bar(device_t dev, int reg); +int pci_bar_enabled(device_t dev, struct pci_map *pm); + #endif /* _PCIVAR_H_ */
_______________________________________________ p4-p...@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/p4-projects To unsubscribe, send any mail to "p4-p...@freebsd.org"





