summary refs log tree commit diff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/include/asm/pci.h1
-rw-r--r--arch/s390/pci/pci.c15
-rw-r--r--arch/s390/pci/pci_clp.c6
3 files changed, 16 insertions, 6 deletions
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index 5509b224c2ec..a5eec4410421 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -219,6 +219,7 @@ int clp_query_pci_fn(struct zpci_dev *zdev);
 int clp_enable_fh(struct zpci_dev *, u8);
 int clp_disable_fh(struct zpci_dev *);
 int clp_get_state(u32 fid, enum zpci_state *state);
+int clp_refresh_fh(u32 fid);
 
 /* UID */
 void update_uid_checking(bool new);
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 4eafa8160184..6be5ee320194 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -674,12 +674,25 @@ out:
 
 int zpci_disable_device(struct zpci_dev *zdev)
 {
+	int cc, rc = 0;
+
 	zpci_dma_exit_device(zdev);
 	/*
 	 * The zPCI function may already be disabled by the platform, this is
 	 * detected in clp_disable_fh() which becomes a no-op.
 	 */
-	return clp_disable_fh(zdev) ? -EIO : 0;
+	cc = clp_disable_fh(zdev);
+	if (cc == CLP_RC_SETPCIFN_ALRDY) {
+		pr_info("Disabling PCI function %08x had no effect as it was already disabled\n",
+			zdev->fid);
+		/* Function is already disabled - update handle */
+		rc = clp_refresh_fh(zdev->fid);
+		if (!rc)
+			rc = -EINVAL;
+	} else if (cc) {
+		rc = -EIO;
+	}
+	return rc;
 }
 
 /**
diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c
index 0a0e8b8293be..04147f28d159 100644
--- a/arch/s390/pci/pci_clp.c
+++ b/arch/s390/pci/pci_clp.c
@@ -212,7 +212,6 @@ out:
 	return rc;
 }
 
-static int clp_refresh_fh(u32 fid);
 /**
  * clp_set_pci_fn() - Execute a command on a PCI function
  * @zdev: Function that will be affected
@@ -251,9 +250,6 @@ static int clp_set_pci_fn(struct zpci_dev *zdev, u8 nr_dma_as, u8 command)
 
 	if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) {
 		zdev->fh = rrb->response.fh;
-	} else if (!rc && rrb->response.hdr.rsp == CLP_RC_SETPCIFN_ALRDY) {
-		/* Function is already in desired state - update handle */
-		rc = clp_refresh_fh(zdev->fid);
 	} else {
 		zpci_err("Set PCI FN:\n");
 		zpci_err_clp(rrb->response.hdr.rsp, rc);
@@ -409,7 +405,7 @@ static void __clp_refresh_fh(struct clp_fh_list_entry *entry, void *data)
 /*
  * Refresh the function handle of the function matching @fid
  */
-static int clp_refresh_fh(u32 fid)
+int clp_refresh_fh(u32 fid)
 {
 	struct clp_req_rsp_list_pci *rrb;
 	int rc;