Skip site navigation (1)Skip section navigation (2)
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>