s390/pci: fix misleading rc in clp_set_pci_fn()
[ Upstream commit f7addcdd527a6dddfebe20c358b87bdb95624612 ] Currently clp_set_pci_fn() always returns 0 as long as the CLP request itself succeeds even if the operation itself returns a response code other than CLP_RC_OK or CLP_RC_SETPCIFN_ALRDY. This is highly misleading because calling code assumes that a zero rc means that the operation was successful. Fix this by returning the response code or cc on failure with the exception of the special handling for CLP_RC_SETPCIFN_ALRDY. Also let's not assume that the returned function handle for CLP_RC_SETPCIFN_ALRDY is 0, we don't need it anyway. Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com> Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
8b471e72b5
commit
0404bf4a66
@@ -659,9 +659,10 @@ int zpci_enable_device(struct zpci_dev *zdev)
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = clp_enable_fh(zdev, ZPCI_NR_DMA_SPACES);
|
if (clp_enable_fh(zdev, ZPCI_NR_DMA_SPACES)) {
|
||||||
if (rc)
|
rc = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
rc = zpci_dma_init_device(zdev);
|
rc = zpci_dma_init_device(zdev);
|
||||||
if (rc)
|
if (rc)
|
||||||
@@ -684,7 +685,7 @@ int zpci_disable_device(struct zpci_dev *zdev)
|
|||||||
* The zPCI function may already be disabled by the platform, this is
|
* The zPCI function may already be disabled by the platform, this is
|
||||||
* detected in clp_disable_fh() which becomes a no-op.
|
* detected in clp_disable_fh() which becomes a no-op.
|
||||||
*/
|
*/
|
||||||
return clp_disable_fh(zdev);
|
return clp_disable_fh(zdev) ? -EIO : 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(zpci_disable_device);
|
EXPORT_SYMBOL_GPL(zpci_disable_device);
|
||||||
|
|
||||||
|
@@ -213,15 +213,19 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int clp_refresh_fh(u32 fid);
|
static int clp_refresh_fh(u32 fid);
|
||||||
/*
|
/**
|
||||||
* Enable/Disable a given PCI function and update its function handle if
|
* clp_set_pci_fn() - Execute a command on a PCI function
|
||||||
* necessary
|
* @zdev: Function that will be affected
|
||||||
|
* @nr_dma_as: DMA address space number
|
||||||
|
* @command: The command code to execute
|
||||||
|
*
|
||||||
|
* Returns: 0 on success, < 0 for Linux errors (e.g. -ENOMEM), and
|
||||||
|
* > 0 for non-success platform responses
|
||||||
*/
|
*/
|
||||||
static int clp_set_pci_fn(struct zpci_dev *zdev, u8 nr_dma_as, u8 command)
|
static int clp_set_pci_fn(struct zpci_dev *zdev, u8 nr_dma_as, u8 command)
|
||||||
{
|
{
|
||||||
struct clp_req_rsp_set_pci *rrb;
|
struct clp_req_rsp_set_pci *rrb;
|
||||||
int rc, retries = 100;
|
int rc, retries = 100;
|
||||||
u32 fid = zdev->fid;
|
|
||||||
|
|
||||||
rrb = clp_alloc_block(GFP_KERNEL);
|
rrb = clp_alloc_block(GFP_KERNEL);
|
||||||
if (!rrb)
|
if (!rrb)
|
||||||
@@ -245,17 +249,16 @@ static int clp_set_pci_fn(struct zpci_dev *zdev, u8 nr_dma_as, u8 command)
|
|||||||
}
|
}
|
||||||
} while (rrb->response.hdr.rsp == CLP_RC_SETPCIFN_BUSY);
|
} while (rrb->response.hdr.rsp == CLP_RC_SETPCIFN_BUSY);
|
||||||
|
|
||||||
if (rc || rrb->response.hdr.rsp != CLP_RC_OK) {
|
|
||||||
zpci_err("Set PCI FN:\n");
|
|
||||||
zpci_err_clp(rrb->response.hdr.rsp, rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) {
|
if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) {
|
||||||
zdev->fh = rrb->response.fh;
|
zdev->fh = rrb->response.fh;
|
||||||
} else if (!rc && rrb->response.hdr.rsp == CLP_RC_SETPCIFN_ALRDY &&
|
} else if (!rc && rrb->response.hdr.rsp == CLP_RC_SETPCIFN_ALRDY) {
|
||||||
rrb->response.fh == 0) {
|
|
||||||
/* Function is already in desired state - update handle */
|
/* Function is already in desired state - update handle */
|
||||||
rc = clp_refresh_fh(fid);
|
rc = clp_refresh_fh(zdev->fid);
|
||||||
|
} else {
|
||||||
|
zpci_err("Set PCI FN:\n");
|
||||||
|
zpci_err_clp(rrb->response.hdr.rsp, rc);
|
||||||
|
if (!rc)
|
||||||
|
rc = rrb->response.hdr.rsp;
|
||||||
}
|
}
|
||||||
clp_free_block(rrb);
|
clp_free_block(rrb);
|
||||||
return rc;
|
return rc;
|
||||||
@@ -301,17 +304,13 @@ int clp_enable_fh(struct zpci_dev *zdev, u8 nr_dma_as)
|
|||||||
|
|
||||||
rc = clp_set_pci_fn(zdev, nr_dma_as, CLP_SET_ENABLE_PCI_FN);
|
rc = clp_set_pci_fn(zdev, nr_dma_as, CLP_SET_ENABLE_PCI_FN);
|
||||||
zpci_dbg(3, "ena fid:%x, fh:%x, rc:%d\n", zdev->fid, zdev->fh, rc);
|
zpci_dbg(3, "ena fid:%x, fh:%x, rc:%d\n", zdev->fid, zdev->fh, rc);
|
||||||
if (rc)
|
if (!rc && zpci_use_mio(zdev)) {
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (zpci_use_mio(zdev)) {
|
|
||||||
rc = clp_set_pci_fn(zdev, nr_dma_as, CLP_SET_ENABLE_MIO);
|
rc = clp_set_pci_fn(zdev, nr_dma_as, CLP_SET_ENABLE_MIO);
|
||||||
zpci_dbg(3, "ena mio fid:%x, fh:%x, rc:%d\n",
|
zpci_dbg(3, "ena mio fid:%x, fh:%x, rc:%d\n",
|
||||||
zdev->fid, zdev->fh, rc);
|
zdev->fid, zdev->fh, rc);
|
||||||
if (rc)
|
if (rc)
|
||||||
clp_disable_fh(zdev);
|
clp_disable_fh(zdev);
|
||||||
}
|
}
|
||||||
out:
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user