diff mbox series

[4/5] PCI/VPD: Make pci_vpd_wait uninterruptible

Message ID 258bf994-bc2a-2907-9181-2c7a562986d5@gmail.com
State New
Headers show
Series PCI/VPD: Further improvements | expand

Commit Message

Heiner Kallweit May 13, 2021, 8:56 p.m. UTC
Reading/writing 4 bytes should be fast enough even on a slow bus,
therefore pci_vpd_wait() doesn't have to be interruptible.
Making it uninterruptible allows to simplify the code.
In addition make VPD writes uninterruptible in general.
It's about vital data, and allowing writes to be interruptible may
leave the VPD in an inconsistent state.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/pci/vpd.c | 33 +++++++++------------------------
 1 file changed, 9 insertions(+), 24 deletions(-)
diff mbox series

Patch

diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c
index e73a3a55f..76b20a13a 100644
--- a/drivers/pci/vpd.c
+++ b/drivers/pci/vpd.c
@@ -31,7 +31,6 @@  struct pci_vpd {
 	unsigned int	len;
 	u16		flag;
 	u8		cap;
-	unsigned int	busy:1;
 	unsigned int	valid:1;
 };
 
@@ -121,22 +120,14 @@  static int pci_vpd_wait(struct pci_dev *dev)
 	u16 status;
 	int ret;
 
-	if (!vpd->busy)
-		return 0;
-
 	do {
 		ret = pci_user_read_config_word(dev, vpd->cap + PCI_VPD_ADDR,
 						&status);
 		if (ret < 0)
 			return ret;
 
-		if ((status & PCI_VPD_ADDR_F) == vpd->flag) {
-			vpd->busy = 0;
+		if ((status & PCI_VPD_ADDR_F) == vpd->flag)
 			return 0;
-		}
-
-		if (fatal_signal_pending(current))
-			return -EINTR;
 
 		if (time_after(jiffies, timeout))
 			break;
@@ -154,7 +145,7 @@  static ssize_t pci_vpd_read(struct pci_dev *dev, loff_t pos, size_t count,
 			    void *arg)
 {
 	struct pci_vpd *vpd = dev->vpd;
-	int ret;
+	int ret = 0;
 	loff_t end = pos + count;
 	u8 *buf = arg;
 
@@ -180,19 +171,19 @@  static ssize_t pci_vpd_read(struct pci_dev *dev, loff_t pos, size_t count,
 	if (mutex_lock_killable(&vpd->lock))
 		return -EINTR;
 
-	ret = pci_vpd_wait(dev);
-	if (ret < 0)
-		goto out;
-
 	while (pos < end) {
 		u32 val;
 		unsigned int i, skip;
 
+		if (fatal_signal_pending(current)) {
+			ret = -EINTR;
+			break;
+		}
+
 		ret = pci_user_write_config_word(dev, vpd->cap + PCI_VPD_ADDR,
 						 pos & ~3);
 		if (ret < 0)
 			break;
-		vpd->busy = 1;
 		vpd->flag = PCI_VPD_ADDR_F;
 		ret = pci_vpd_wait(dev);
 		if (ret < 0)
@@ -212,7 +203,7 @@  static ssize_t pci_vpd_read(struct pci_dev *dev, loff_t pos, size_t count,
 			val >>= 8;
 		}
 	}
-out:
+
 	mutex_unlock(&vpd->lock);
 	return ret ? ret : count;
 }
@@ -242,10 +233,6 @@  static ssize_t pci_vpd_write(struct pci_dev *dev, loff_t pos, size_t count,
 	if (mutex_lock_killable(&vpd->lock))
 		return -EINTR;
 
-	ret = pci_vpd_wait(dev);
-	if (ret < 0)
-		goto out;
-
 	while (pos < end) {
 		u32 val;
 
@@ -262,7 +249,6 @@  static ssize_t pci_vpd_write(struct pci_dev *dev, loff_t pos, size_t count,
 		if (ret < 0)
 			break;
 
-		vpd->busy = 1;
 		vpd->flag = 0;
 		ret = pci_vpd_wait(dev);
 		if (ret < 0)
@@ -270,7 +256,7 @@  static ssize_t pci_vpd_write(struct pci_dev *dev, loff_t pos, size_t count,
 
 		pos += sizeof(u32);
 	}
-out:
+
 	mutex_unlock(&vpd->lock);
 	return ret ? ret : count;
 }
@@ -333,7 +319,6 @@  void pci_vpd_init(struct pci_dev *dev)
 		vpd->ops = &pci_vpd_ops;
 	mutex_init(&vpd->lock);
 	vpd->cap = cap;
-	vpd->busy = 0;
 	vpd->valid = 0;
 	dev->vpd = vpd;
 }