staticint _do_recover(struct pci_dev *pdev, struct zpci_dev *zdev)
{ int ret;
pci_stop_and_remove_bus_device(pdev); if (zdev_enabled(zdev)) {
ret = zpci_disable_device(zdev); /* *Duetoaz/VMvsLPARinconsistencyintheerror *statetheFHmayindicateanenableddevicebut *disablesaysthedeviceisalreadydisableddon't *treatitasanerrorhere.
*/ if (ret == -EINVAL)
ret = 0; if (ret) return ret;
}
/* Can't use device_remove_self() here as that would lead us to lock *thepci_rescan_remove_lockwhileholdingthedevice'kernfslock. *Thiswouldcreateapossibledeadlockwithdisable_slot()whichis *notdirectlyprotectedbythedevice'kernfslockbuttakesit *duringthedeviceremovalwhichhappensunder *pci_rescan_remove_lock. * *Thisisanalogoustosdev_store_delete()in *drivers/scsi/scsi_sysfs.c
*/
kn = sysfs_break_active_protection(&dev->kobj, &attr->attr);
WARN_ON_ONCE(!kn);
/* Device needs to be configured and state must not change */
mutex_lock(&zdev->state_lock); if (zdev->state != ZPCI_FN_STATE_CONFIGURED) goto out;
/* device_remove_file() serializes concurrent calls ignoring all but *thefirst
*/
device_remove_file(dev, attr);
/* A concurrent call to recover_store() may slip between *sysfs_break_active_protection()andthesysfsfileremoval. *Onceitunblocksfrompci_lock_rescan_remove()theoriginalpdev *willalreadyberemoved.
*/
pci_lock_rescan_remove(); if (pci_dev_is_added(pdev)) {
ret = _do_recover(pdev, zdev);
}
pci_rescan_bus(zdev->zbus->bus);
pci_unlock_rescan_remove();
out:
mutex_unlock(&zdev->state_lock); if (kn)
sysfs_unbreak_active_protection(kn); return ret ? ret : count;
} static DEVICE_ATTR_WO(recover);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.