Date: Sun, 1 Mar 2015 00:39:34 +0000 (UTC) From: Ryan Stone <rstone@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r279442 - head/sys/dev/pci Message-ID: <201503010039.t210dYTB089960@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rstone Date: Sun Mar 1 00:39:33 2015 New Revision: 279442 URL: https://svnweb.freebsd.org/changeset/base/279442 Log: Refactor PCI resource allocation Refactor PCI resource allocation code to allow a request for a memory-mapped I/O window that is a multiple of a requested size. This is needed by the SR-IOV code because the VF BARs are all allocated contiguously. We can't just allocate a resource that is a multiple of a single VF BAR because the size of an allocation implies its alignment requirement. Differential Revision: https://reviews.freebsd.org/D71 Reviewed by: jhb MFC after: 1 month Sponsored by: Sandvine Inc. Modified: head/sys/dev/pci/pci.c head/sys/dev/pci/pci_private.h Modified: head/sys/dev/pci/pci.c ============================================================================== --- head/sys/dev/pci/pci.c Sun Mar 1 00:39:26 2015 (r279441) +++ head/sys/dev/pci/pci.c Sun Mar 1 00:39:33 2015 (r279442) @@ -78,7 +78,6 @@ __FBSDID("$FreeBSD$"); static int pci_has_quirk(uint32_t devid, int quirk); static pci_addr_t pci_mapbase(uint64_t mapreg); static const char *pci_maptype(uint64_t mapreg); -static int pci_mapsize(uint64_t testval); static int pci_maprange(uint64_t mapreg); static pci_addr_t pci_rombase(uint64_t mapreg); static int pci_romsize(uint64_t testval); @@ -487,7 +486,7 @@ pci_maptype(uint64_t mapreg) /* return log2 of map size decoded for memory or port map */ -static int +int pci_mapsize(uint64_t testval) { int ln2size; @@ -2620,8 +2619,9 @@ pci_memen(device_t dev) return (pci_read_config(dev, PCIR_COMMAND, 2) & PCIM_CMD_MEMEN) != 0; } -static void -pci_read_bar(device_t dev, int reg, pci_addr_t *mapp, pci_addr_t *testvalp) +void +pci_read_bar(device_t dev, int reg, pci_addr_t *mapp, pci_addr_t *testvalp, + int *bar64) { struct pci_devinfo *dinfo; pci_addr_t map, testval; @@ -2641,6 +2641,8 @@ pci_read_bar(device_t dev, int reg, pci_ pci_write_config(dev, reg, map, 4); *mapp = map; *testvalp = testval; + if (bar64 != NULL) + *bar64 = 0; return; } @@ -2682,6 +2684,8 @@ pci_read_bar(device_t dev, int reg, pci_ *mapp = map; *testvalp = testval; + if (bar64 != NULL) + *bar64 = (ln2range == 64); } static void @@ -2736,7 +2740,7 @@ pci_bar_enabled(device_t dev, struct pci return ((cmd & PCIM_CMD_PORTEN) != 0); } -static struct pci_map * +struct pci_map * pci_add_bar(device_t dev, int reg, pci_addr_t value, pci_addr_t size) { struct pci_devinfo *dinfo; @@ -2807,7 +2811,7 @@ pci_add_map(device_t bus, device_t dev, return (barlen); } - pci_read_bar(dev, reg, &map, &testval); + pci_read_bar(dev, reg, &map, &testval, NULL); if (PCI_BAR_MEM(map)) { type = SYS_RES_MEMORY; if (map & PCIM_BAR_MEM_PREFETCH) @@ -4463,7 +4467,7 @@ DB_SHOW_COMMAND(pciregs, db_pci_dump) static struct resource * pci_reserve_map(device_t dev, device_t child, int type, int *rid, - u_long start, u_long end, u_long count, u_int flags) + u_long start, u_long end, u_long count, u_int num, u_int flags) { struct pci_devinfo *dinfo = device_get_ivars(child); struct resource_list *rl = &dinfo->resources; @@ -4487,7 +4491,7 @@ pci_reserve_map(device_t dev, device_t c * have a atapci device in legacy mode and it fails * here, that other code is broken. */ - pci_read_bar(child, *rid, &map, &testval); + pci_read_bar(child, *rid, &map, &testval, NULL); /* * Determine the size of the BAR and ignore BARs with a size @@ -4529,7 +4533,7 @@ pci_reserve_map(device_t dev, device_t c * situation where we might allocate the excess to * another driver, which won't work. */ - count = (pci_addr_t)1 << mapsize; + count = ((pci_addr_t)1 << mapsize) * num; if (RF_ALIGNMENT(flags) < mapsize) flags = (flags & ~RF_ALIGNMENT_MASK) | RF_ALIGNMENT_LOG2(mapsize); if (PCI_BAR_MEM(map) && (map & PCIM_BAR_MEM_PREFETCH)) @@ -4560,8 +4564,8 @@ out: } struct resource * -pci_alloc_resource(device_t dev, device_t child, int type, int *rid, - u_long start, u_long end, u_long count, u_int flags) +pci_alloc_multi_resource(device_t dev, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_long num, u_int flags) { struct pci_devinfo *dinfo; struct resource_list *rl; @@ -4569,10 +4573,6 @@ pci_alloc_resource(device_t dev, device_ struct resource *res; pcicfgregs *cfg; - if (device_get_parent(child) != dev) - return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, - type, rid, start, end, count, flags)); - /* * Perform lazy resource allocation */ @@ -4629,7 +4629,7 @@ pci_alloc_resource(device_t dev, device_ rle = resource_list_find(rl, type, *rid); if (rle == NULL) { res = pci_reserve_map(dev, child, type, rid, start, end, - count, flags); + count, num, flags); if (res == NULL) return (NULL); } @@ -4638,6 +4638,19 @@ pci_alloc_resource(device_t dev, device_ start, end, count, flags)); } +struct resource * +pci_alloc_resource(device_t dev, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + + if (device_get_parent(child) != dev) + return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, + type, rid, start, end, count, flags)); + + return (pci_alloc_multi_resource(dev, child, type, rid, start, end, + count, 1, flags)); +} + int pci_release_resource(device_t dev, device_t child, int type, int rid, struct resource *r) Modified: head/sys/dev/pci/pci_private.h ============================================================================== --- head/sys/dev/pci/pci_private.h Sun Mar 1 00:39:26 2015 (r279441) +++ head/sys/dev/pci/pci_private.h Sun Mar 1 00:39:33 2015 (r279442) @@ -140,4 +140,14 @@ void pci_cfg_restore(device_t, struct p */ void pci_cfg_save(device_t, struct pci_devinfo *, int); +int pci_mapsize(uint64_t testval); +void pci_read_bar(device_t dev, int reg, pci_addr_t *mapp, + pci_addr_t *testvalp, int *bar64); +struct pci_map *pci_add_bar(device_t dev, int reg, pci_addr_t value, + pci_addr_t size); + +struct resource *pci_alloc_multi_resource(device_t dev, device_t child, + int type, int *rid, u_long start, u_long end, u_long count, + u_long num, u_int flags); + #endif /* _PCI_PRIVATE_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201503010039.t210dYTB089960>