[PATCH v0 05/13] PCI: Specify static enumeration on kcmdline

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The user can specify a static enumeration profile via kernel command
line. A future commit will parse those options.

Signed-off-by: Jason Tang <jason.tang2@xxxxxxx>
---
 drivers/pci/Makefile          |    2 ++
 drivers/pci/pci.c             |    2 ++
 drivers/pci/pci.h             |    2 ++
 drivers/pci/pci_static_enum.c |   54 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 60 insertions(+)
 create mode 100644 drivers/pci/pci_static_enum.c

diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 73e4af4..3cacdfc 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -59,5 +59,7 @@ obj-$(CONFIG_OF) += of.o
 
 ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG
 
+obj-$(CONFIG_PCI_STATIC_ENUMERATION) += pci_static_enum.o
+
 # PCI host controller drivers
 obj-y += host/
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 81f06e8..5d8c0e0 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4607,6 +4607,8 @@ static int __init pci_setup(char *str)
 				pcie_bus_config = PCIE_BUS_PEER2PEER;
 			} else if (!strncmp(str, "pcie_scan_all", 13)) {
 				pci_add_flags(PCI_SCAN_ALL_PCIE_DEVS);
+			} else if (!strncmp(str, "enum=", 5)) {
+				pci_static_enum_set_opt(str + 5);
 			} else {
 				printk(KERN_ERR "PCI: Unknown option `%s'\n",
 						str);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 075bd9d..3282b51 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -322,6 +322,7 @@ static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)
 #endif
 
 #ifdef CONFIG_PCI_STATIC_ENUMERATION
+void pci_static_enum_set_opt(const char *str);
 /**
  * pci_bus_subordinate() - return the subordinate bus number assigned
  * to @dev by the static enumeration profile, or 0 if not set
@@ -331,6 +332,7 @@ static inline unsigned char pci_bus_subordinate(struct pci_bus *bus)
 	return bus->subordinate;
 }
 #else
+static inline void pci_static_enum_set_opt(const char *str) { return; }
 static inline unsigned char pci_bus_subordinate(struct pci_bus *bus)
 {
 	return 0;
diff --git a/drivers/pci/pci_static_enum.c b/drivers/pci/pci_static_enum.c
new file mode 100644
index 0000000..a28bd33
--- /dev/null
+++ b/drivers/pci/pci_static_enum.c
@@ -0,0 +1,54 @@
+/*
+ * PCI static enumeration
+ *
+ * Copyright (C) 2015 Northrop Grumman Corporation.  All rights reserved.
+ *                    Jason Tang <jason.tang2@xxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+
+#include <asm/setup.h>
+
+#define PREFIX "PCI ENUM: "
+
+static DEFINE_SPINLOCK(static_enum_lock);
+
+#define PCI_STATIC_ENUM_PARAM_SIZE COMMAND_LINE_SIZE
+static char pci_static_enum_param[PCI_STATIC_ENUM_PARAM_SIZE] = { 0 };
+
+/**
+ * pci_static_enum_set_opt() - set/append the PCI static enumeration
+ * options as given by kernel command line
+ * @str: static enumeration options
+ */
+void __init pci_static_enum_set_opt(const char *str)
+{
+	/*
+	   So why store the options and parse later? The reason is
+	   because the static enumerator is stateful, in that it keeps
+	   track of which devices it has overridden. It cannot call
+	   kmalloc() yet because memory allocation has not been set up
+	   yet when this function is called. The next best thing is
+	   store the options in a statically-allocated string, and then
+	   parse it later, when kmalloc() is legal.
+	 */
+	size_t cur, len;
+
+	spin_lock(&static_enum_lock);
+	cur = strlen(pci_static_enum_param);
+	len = strlen(str);
+	/* use ';' to separate each option */
+	if (cur > 0 && cur < PCI_STATIC_ENUM_PARAM_SIZE - 1)
+		pci_static_enum_param[cur++] = ';';
+	if (len > PCI_STATIC_ENUM_PARAM_SIZE - 1 - cur)
+		len = PCI_STATIC_ENUM_PARAM_SIZE - 1 - cur;
+	strncat(pci_static_enum_param + cur, str, len);
+	spin_unlock(&static_enum_lock);
+}
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux