if (has_attention_file(slot))
sysfs_remove_file(&pci_slot->kobj,
&hotplug_slot_attr_attention.attr);
if (has_latch_file(slot))
sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_latch.attr);
if (has_adapter_file(slot))
sysfs_remove_file(&pci_slot->kobj,
&hotplug_slot_attr_presence.attr);
if (has_test_file(slot))
sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_test.attr);
sysfs_remove_link(&pci_slot->kobj, "module");
}
/** * __pci_hp_register - register a hotplug_slot with the PCI hotplug subsystem * @slot: pointer to the &struct hotplug_slot to register * @bus: bus this slot is on * @devnr: device number * @name: name registered with kobject core * @owner: caller module owner * @mod_name: caller module name * * Prepares a hotplug slot for in-kernel use and immediately publishes it to * user space in one go. Drivers may alternatively carry out the two steps * separately by invoking pci_hp_initialize() and pci_hp_add(). * * Returns 0 if successful, anything else for an error.
*/ int __pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, int devnr, constchar *name, struct module *owner, constchar *mod_name)
{ int result;
result = __pci_hp_initialize(slot, bus, devnr, name, owner, mod_name); if (result) return result;
result = pci_hp_add(slot); if (result)
pci_hp_destroy(slot);
/** * __pci_hp_initialize - prepare hotplug slot for in-kernel use * @slot: pointer to the &struct hotplug_slot to initialize * @bus: bus this slot is on * @devnr: slot number * @name: name registered with kobject core * @owner: caller module owner * @mod_name: caller module name * * Allocate and fill in a PCI slot for use by a hotplug driver. Once this has * been called, the driver may invoke hotplug_slot_name() to get the slot's * unique name. The driver must be prepared to handle a ->reset_slot callback * from this point on. * * Returns 0 on success or a negative int on error.
*/ int __pci_hp_initialize(struct hotplug_slot *slot, struct pci_bus *bus, int devnr, constchar *name, struct module *owner, constchar *mod_name)
{ struct pci_slot *pci_slot;
if (slot == NULL) return -ENODEV; if (slot->ops == NULL) return -EINVAL;
slot->owner = owner;
slot->mod_name = mod_name;
/* * No problems if we call this interface from both ACPI_PCI_SLOT * driver and call it here again. If we've already created the * pci_slot, the interface will simply bump the refcount.
*/
pci_slot = pci_create_slot(bus, devnr, name, slot); if (IS_ERR(pci_slot)) return PTR_ERR(pci_slot);
/** * pci_hp_add - publish hotplug slot to user space * @slot: pointer to the &struct hotplug_slot to publish * * Make a hotplug slot's sysfs interface available and inform user space of its * addition by sending a uevent. The hotplug driver must be prepared to handle * all &struct hotplug_slot_ops callbacks from this point on. * * Returns 0 on success or a negative int on error.
*/ int pci_hp_add(struct hotplug_slot *slot)
{ struct pci_slot *pci_slot; int result;
if (WARN_ON(!slot)) return -EINVAL;
pci_slot = slot->pci_slot;
result = fs_add_slot(slot, pci_slot); if (result) return result;
/** * pci_hp_deregister - deregister a hotplug_slot with the PCI hotplug subsystem * @slot: pointer to the &struct hotplug_slot to deregister * * The @slot must have been registered with the pci hotplug subsystem * previously with a call to pci_hp_register().
*/ void pci_hp_deregister(struct hotplug_slot *slot)
{
pci_hp_del(slot);
pci_hp_destroy(slot);
}
EXPORT_SYMBOL_GPL(pci_hp_deregister);
/** * pci_hp_del - unpublish hotplug slot from user space * @slot: pointer to the &struct hotplug_slot to unpublish * * Remove a hotplug slot's sysfs interface.
*/ void pci_hp_del(struct hotplug_slot *slot)
{ if (WARN_ON(!slot)) return;
/** * pci_hp_destroy - remove hotplug slot from in-kernel use * @slot: pointer to the &struct hotplug_slot to destroy * * Destroy a PCI slot used by a hotplug driver. Once this has been called, * the driver may no longer invoke hotplug_slot_name() to get the slot's * unique name. The driver no longer needs to handle a ->reset_slot callback * from this point on.
*/ void pci_hp_destroy(struct hotplug_slot *slot)
{ struct pci_slot *pci_slot = slot->pci_slot;
/** * pci_hp_ignore_link_change - begin code section causing spurious link changes * @pdev: PCI hotplug bridge * * Mark the beginning of a code section causing spurious link changes on the * Secondary Bus of @pdev, e.g. as a side effect of a Secondary Bus Reset, * D3cold transition, firmware update or FPGA reconfiguration. * * Hotplug drivers can thus check whether such a code section is executing * concurrently, await it with pci_hp_spurious_link_change() and ignore the * resulting link change events. * * Must be paired with pci_hp_unignore_link_change(). May be called both * from the PCI core and from Endpoint drivers. May be called for bridges * which are not hotplug-capable, in which case it has no effect because * no hotplug driver is bound to the bridge.
*/ void pci_hp_ignore_link_change(struct pci_dev *pdev)
{
set_bit(PCI_LINK_CHANGING, &pdev->priv_flags);
smp_mb__after_atomic(); /* pairs with implied barrier of wait_event() */
}
/** * pci_hp_unignore_link_change - end code section causing spurious link changes * @pdev: PCI hotplug bridge * * Mark the end of a code section causing spurious link changes on the * Secondary Bus of @pdev. Must be paired with pci_hp_ignore_link_change().
*/ void pci_hp_unignore_link_change(struct pci_dev *pdev)
{
set_bit(PCI_LINK_CHANGED, &pdev->priv_flags);
mb(); /* ensure pci_hp_spurious_link_change() sees either bit set */
clear_bit(PCI_LINK_CHANGING, &pdev->priv_flags);
wake_up_all(&pci_hp_link_change_wq);
}
/** * pci_hp_spurious_link_change - check for spurious link changes * @pdev: PCI hotplug bridge * * Check whether a code section is executing concurrently which is causing * spurious link changes on the Secondary Bus of @pdev. Await the end of the * code section if so. * * May be called by hotplug drivers to check whether a link change is spurious * and can be ignored. * * Because a genuine link change may have occurred in-between a spurious link * change and the invocation of this function, hotplug drivers should perform * sanity checks such as retrieving the current link state and bringing down * the slot if the link is down. * * Return: %true if such a code section has been executing concurrently, * otherwise %false. Also return %true if such a code section has not been * executing concurrently, but at least once since the last invocation of this * function.
*/ bool pci_hp_spurious_link_change(struct pci_dev *pdev)
{
wait_event(pci_hp_link_change_wq,
!test_bit(PCI_LINK_CHANGING, &pdev->priv_flags));
/* * not really modular, but the easiest way to keep compat with existing * bootargs behaviour is to continue using module_param here.
*/
module_param(debug, bool, 0644);
MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
Messung V0.5
¤ Dauer der Verarbeitung: 0.24 Sekunden
(vorverarbeitet)
¤
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.