diff options
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/pci/pci_event.c | 39 |
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(); |