From owner-p4-projects@FreeBSD.ORG Mon Mar 7 18:45:46 2011 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B5CB61065672; Mon, 7 Mar 2011 18:45:46 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 78194106566B for ; Mon, 7 Mar 2011 18:45:46 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id 63CEF8FC1B for ; Mon, 7 Mar 2011 18:45:46 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id p27IjkVD049468 for ; Mon, 7 Mar 2011 18:45:46 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id p27Ijk6X049465 for perforce@freebsd.org; Mon, 7 Mar 2011 18:45:46 GMT (envelope-from jhb@freebsd.org) Date: Mon, 7 Mar 2011 18:45:46 GMT Message-Id: <201103071845.p27Ijk6X049465@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 189677 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 07 Mar 2011 18:45:47 -0000 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_ */