summaryrefslogtreecommitdiff
path: root/arch/s390/pci
diff options
context:
space:
mode:
authorNiklas Schnelle <schnelle@linux.ibm.com>2020-09-16 10:52:35 +0200
committerHeiko Carstens <hca@linux.ibm.com>2021-03-22 11:36:04 +0100
commitdee60c0dbc837ddca8abcb868e53ca3e9d11ea4c (patch)
tree6a868d9d075d7ac36a300593e7e8f3fc63019a58 /arch/s390/pci
parenta9045c2210448473a321a8bf266541e5644aaae2 (diff)
s390/pci: add zpci_event_hard_deconfigured()
Extract the handling of PEC 0x0304 into a function and make sure we only attempt to disable the function if it is enabled. Also check for errors returned by zpci_disable_device() and leave the function alone if there are any. 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>
Diffstat (limited to 'arch/s390/pci')
-rw-r--r--arch/s390/pci/pci_event.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c
index ac0c65cdd69d..0474ff8c6dbd 100644
--- a/arch/s390/pci/pci_event.c
+++ b/arch/s390/pci/pci_event.c
@@ -73,10 +73,31 @@ void zpci_event_error(void *data)
__zpci_event_error(data);
}
+static void zpci_event_hard_deconfigured(struct zpci_dev *zdev, u32 fh)
+{
+ enum zpci_state state;
+ int rc;
+
+ zdev->fh = fh;
+ /* Give the driver a hint that the function is
+ * already unusable.
+ */
+ zpci_remove_device(zdev, true);
+ if (zdev_enabled(zdev)) {
+ rc = zpci_disable_device(zdev);
+ if (rc)
+ return;
+ }
+ zdev->state = ZPCI_FN_STATE_STANDBY;
+ if (!clp_get_state(zdev->fid, &state) &&
+ state == ZPCI_FN_STATE_RESERVED) {
+ zpci_zdev_put(zdev);
+ }
+}
+
static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
{
struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
- enum zpci_state state;
struct pci_dev *pdev;
int ret;
@@ -134,20 +155,8 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
break;
case 0x0304: /* Configured -> Standby|Reserved */
- if (!zdev)
- break;
- /* Give the driver a hint that the function is
- * already unusable.
- */
- zpci_remove_device(zdev, true);
-
- zdev->fh = ccdf->fh;
- zpci_disable_device(zdev);
- zdev->state = ZPCI_FN_STATE_STANDBY;
- if (!clp_get_state(ccdf->fid, &state) &&
- state == ZPCI_FN_STATE_RESERVED) {
- zpci_zdev_put(zdev);
- }
+ if (zdev)
+ zpci_event_hard_deconfigured(zdev, ccdf->fh);
break;
case 0x0306: /* 0x308 or 0x302 for multiple devices */
zpci_remove_reserved_devices();