Re: [PATCH v2 24/37] PCI, ACPI: Add pci_root_hp hot removalnotification support.
From: Bjorn Helgaas
Date: Mon Mar 12 2012 - 23:26:10 EST
On Sat, Mar 10, 2012 at 12:00 AM, Yinghai Lu <yinghai@xxxxxxxxxx> wrote:
> Add missing hot_remove support for root device.
>
> How to use it?
> Find out root bus number to acpi root name mapping from dmesg or /sys
>
> echo "\_SB.PCIB 3" > /proc/acpi/sci/notify
> to remove root bus
Same comments as before: this is definitely NOT the way users should
use this. If you want to do that for debugging the ACPI notification
path, fine, but the normal way is for the platform to generate this
notification. I think the normal way for users to manually remove an
ACPI device should be something like:
echo 1 > /sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/remove
just like we do for PCI devices.
> Signed-off-by: Yinghai Lu <yinghai@xxxxxxxxxx>
> Cc: Len Brown <lenb@xxxxxxxxxx>
> Cc: linux-acpi@xxxxxxxxxxxxxxx
> ---
> drivers/acpi/pci_root_hp.c | 61 ++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 61 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/acpi/pci_root_hp.c b/drivers/acpi/pci_root_hp.c
> index dc11e81..f5585f5 100644
> --- a/drivers/acpi/pci_root_hp.c
> +++ b/drivers/acpi/pci_root_hp.c
> @@ -73,6 +73,12 @@ static void add_acpi_root_bridge(acpi_handle handle)
> list_add(&bridge->list, &acpi_root_bridge_list);
> }
>
> +static void remove_acpi_root_bridge(struct acpi_root_bridge *bridge)
> +{
> + list_del(&bridge->list);
> + kfree(bridge);
> +}
> +
> struct acpi_root_hp_work {
> struct work_struct work;
> acpi_handle handle;
> @@ -142,6 +148,55 @@ static void handle_root_bridge_insertion(acpi_handle handle)
> printk(KERN_ERR "cannot start bridge\n");
> }
>
> +static int acpi_root_evaluate_object(acpi_handle handle, char *cmd, int val)
> +{
> + acpi_status status;
> + struct acpi_object_list arg_list;
> + union acpi_object arg;
> +
> + arg_list.count = 1;
> + arg_list.pointer = &arg;
> + arg.type = ACPI_TYPE_INTEGER;
> + arg.integer.value = val;
> +
> + status = acpi_evaluate_object(handle, cmd, &arg_list, NULL);
> + if (ACPI_FAILURE(status)) {
> + printk(KERN_WARNING "%s: %s to %d failed\n",
> + __func__, cmd, val);
> + return -1;
> + }
> +
> + return 0;
This function really has nothing to do with host bridges. Are you
sure there's no generic function you can use instead?
> +}
> +
> +static void handle_root_bridge_removal(acpi_handle handle,
> + struct acpi_root_bridge *bridge)
> +{
> + u32 flags = 0;
> + struct acpi_device *device;
> +
> + if (bridge) {
> + flags = bridge->flags;
> + remove_acpi_root_bridge(bridge);
> + }
> +
> + if (!acpi_bus_get_device(handle, &device)) {
> + int ret_val = acpi_bus_trim(device, 1);
> +
> + printk(KERN_DEBUG "acpi_bus_trim return %x\n", ret_val);
> + }
> +
> + if (flags & ROOT_BRIDGE_HAS_PS3) {
> + acpi_status status;
> +
> + status = acpi_evaluate_object(handle, "_PS3", NULL, NULL);
> + if (ACPI_FAILURE(status))
> + printk(KERN_WARNING "%s: _PS3 failed\n", __func__);
> + }
> + if (flags & ROOT_BRIDGE_HAS_EJ0)
> + acpi_root_evaluate_object(handle, "_EJ0", 1);
> +}
> +
> static void _handle_hotplug_event_root(struct work_struct *work)
> {
> struct acpi_root_bridge *bridge;
> @@ -182,6 +237,12 @@ static void _handle_hotplug_event_root(struct work_struct *work)
> }
> break;
>
> + case ACPI_NOTIFY_EJECT_REQUEST:
> + /* request device eject */
> + printk(KERN_DEBUG "%s: Device eject notify on %s\n", __func__,
> + objname);
> + handle_root_bridge_removal(handle, bridge);
> + break;
> default:
> printk(KERN_WARNING "notify_handler: unknown event type 0x%x for %s\n",
> type, objname);
> --
> 1.7.7
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/