From dee60c0dbc837ddca8abcb868e53ca3e9d11ea4c Mon Sep 17 00:00:00 2001 From: Niklas Schnelle <schnelle@linux.ibm.com> Date: Wed, 16 Sep 2020 10:52:35 +0200 Subject: [PATCH] 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> --- arch/s390/pci/pci_event.c | 39 ++++++++++++++++++++++++--------------- 1 file 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();