mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 02:39:48 +00:00
s390/pci: handle FH state mismatch only on disable
Instead of always treating CLP_RC_SETPCIFN_ALRDY as success and blindly updating the function handle restrict this special handling to the disable case by moving it into zpci_disable_device() and still treating it as an error while also updating the function handle such that a subsequent zpci_disable_device() succeeds or the caller can ignore the error when aborting is not an option such as for zPCI event 0x304. Also print this occurrence to the log such that an admin can tell why a disable operation returned an error. A mismatch between the state of the underlying device and our view of it can naturally happen when the device suddenly enters the error state but we haven't gotten the error notification yet, it must not happen on enable though. 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>
This commit is contained in:
parent
f7addcdd52
commit
8256adda1f
3 changed files with 16 additions and 6 deletions
|
@ -219,6 +219,7 @@ int clp_query_pci_fn(struct zpci_dev *zdev);
|
||||||
int clp_enable_fh(struct zpci_dev *, u8);
|
int clp_enable_fh(struct zpci_dev *, u8);
|
||||||
int clp_disable_fh(struct zpci_dev *);
|
int clp_disable_fh(struct zpci_dev *);
|
||||||
int clp_get_state(u32 fid, enum zpci_state *state);
|
int clp_get_state(u32 fid, enum zpci_state *state);
|
||||||
|
int clp_refresh_fh(u32 fid);
|
||||||
|
|
||||||
/* UID */
|
/* UID */
|
||||||
void update_uid_checking(bool new);
|
void update_uid_checking(bool new);
|
||||||
|
|
|
@ -674,12 +674,25 @@ int zpci_enable_device(struct zpci_dev *zdev)
|
||||||
|
|
||||||
int zpci_disable_device(struct zpci_dev *zdev)
|
int zpci_disable_device(struct zpci_dev *zdev)
|
||||||
{
|
{
|
||||||
|
int cc, rc = 0;
|
||||||
|
|
||||||
zpci_dma_exit_device(zdev);
|
zpci_dma_exit_device(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) ? -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -212,7 +212,6 @@ int clp_query_pci_fn(struct zpci_dev *zdev)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int clp_refresh_fh(u32 fid);
|
|
||||||
/**
|
/**
|
||||||
* clp_set_pci_fn() - Execute a command on a PCI function
|
* clp_set_pci_fn() - Execute a command on a PCI function
|
||||||
* @zdev: Function that will be affected
|
* @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) {
|
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) {
|
|
||||||
/* Function is already in desired state - update handle */
|
|
||||||
rc = clp_refresh_fh(zdev->fid);
|
|
||||||
} else {
|
} else {
|
||||||
zpci_err("Set PCI FN:\n");
|
zpci_err("Set PCI FN:\n");
|
||||||
zpci_err_clp(rrb->response.hdr.rsp, rc);
|
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
|
* 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;
|
struct clp_req_rsp_list_pci *rrb;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
Loading…
Reference in a new issue