Messages in this thread | | | Date | Fri, 6 Jul 2012 08:37:48 +0900 | From | Yasuaki Ishimatsu <> | Subject | Re: [PATCH v6 2/6] ACPI: Add _OST support for sysfs eject |
| |
Hi Toshi,
2012/07/05 23:43, Toshi Kani wrote: > On Thu, 2012-07-05 at 20:16 +0900, Yasuaki Ishimatsu wrote: >> Hi Toshi, >> >> 2012/06/27 5:42, Toshi Kani wrote: >>> Changed acpi_bus_hot_remove_device() to support _OST. This function is >>> also changed to global so that it can be called from hotplug notify >>> handlers to perform hot-remove operation. >>> >>> Changed acpi_eject_store(), which is the sysfs eject handler. It checks >>> eject_pending to see if the request was originated from ACPI eject >>> notification. If not, it calls _OST(0x103,84,) per Figure 6-37 in ACPI >>> 5.0 spec. >>> >>> Added eject_pending bit to acpi_device_flags. This bit is set when the >>> kernel has received an ACPI eject notification, but does not initiate >>> its hot-remove operation by itself. >>> >>> Added struct acpi_eject_event. This structure is used to pass extended >>> information to acpi_bus_hot_remove_device(), which has a single argument >>> to support asynchronous call >>> >>> Signed-off-by: Toshi Kani <toshi.kani@hp.com> >>> --- >>> drivers/acpi/scan.c | 57 +++++++++++++++++++++++++++++++++++++++------- >>> include/acpi/acpi_bus.h | 9 ++++++- >>> 2 files changed, 56 insertions(+), 10 deletions(-) >>> >>> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c >>> index c8a1f3b..dbdb9fc 100644 >>> --- a/drivers/acpi/scan.c >>> +++ b/drivers/acpi/scan.c >>> @@ -83,19 +83,29 @@ acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, cha >>> } >>> static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); >>> >>> -static void acpi_bus_hot_remove_device(void *context) >>> +/** >>> + * acpi_bus_hot_remove_device: hot-remove a device and its children >>> + * @context: struct acpi_eject_event pointer (freed in this func) >>> + * >>> + * Hot-remove a device and its children. This function frees up the >>> + * memory space passed by arg context, so that the caller may call >>> + * this function asynchronously through acpi_os_hotplug_execute(). >>> + */ >>> +void acpi_bus_hot_remove_device(void *context) >>> { >>> + struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context; >>> struct acpi_device *device; >>> - acpi_handle handle = context; >>> + acpi_handle handle = ej_event->handle; >>> struct acpi_object_list arg_list; >>> union acpi_object arg; >>> acpi_status status = AE_OK; >>> + u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ >>> >>> if (acpi_bus_get_device(handle, &device)) >>> - return; >>> + goto err_out; >>> >>> if (!device) >>> - return; >>> + goto err_out; >>> >>> ACPI_DEBUG_PRINT((ACPI_DB_INFO, >>> "Hot-removing device %s...\n", dev_name(&device->dev))); >>> @@ -103,7 +113,7 @@ static void acpi_bus_hot_remove_device(void *context) >>> if (acpi_bus_trim(device, 1)) { >>> printk(KERN_ERR PREFIX >>> "Removing device failed\n"); >>> - return; >>> + goto err_out; >>> } >>> >>> /* power off device */ >>> @@ -129,10 +139,20 @@ static void acpi_bus_hot_remove_device(void *context) >>> * TBD: _EJD support. >>> */ >>> status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); >>> - if (ACPI_FAILURE(status)) >>> - printk(KERN_WARNING PREFIX >>> - "Eject device failed\n"); >>> + if (ACPI_FAILURE(status)) { >>> + if (status != AE_NOT_FOUND) >>> + pr_warn(PREFIX "Eject device failed\n"); >>> + goto err_out; >>> + } >>> + >>> + kfree(context); >>> + return; >>> >>> +err_out: >>> + /* Inform firmware the hot-remove operation has completed w/ error */ >>> + (void) acpi_evaluate_hotplug_ost(handle, >>> + ej_event->event, ost_code, NULL); >>> + kfree(context); >>> return; >>> } >> >> When I read your patch named [PATCH] ACPI: Add ACPI CPU hot-remove support, >> a question about this patch appeared. >> >> The question is : >> Why does not acpi_bus_hot_remove_device() inform firmware of >> ACPI_OST_SC_SUCCESS, when it succeeded? Are thre any reasons? >> >> If you have already discussed my question, please let me know the log. > > Hi Yasuaki, > > Please refer Figure 2, page 14, of the following document. _EJ0 > substitutes _OST as it indicates to the firmware that the OS was > successful in offlining. > > DIG64 Hot-Plug & Partitioning Flow (HPPF) Specification R1.0 > http://www.dig64.org/home/DIG64_HPPF_R1_0.pdf > > Figure 6-37 of ACPI 5.0 spec also has a similar example flow.
My question was solved by the document.
Thanks, Yasuaki Ishimatsu
> > Thanks, > -Toshi > > >> Thanks, >> Yasuaki Ishimatsu >> >> >>> >>> @@ -144,6 +164,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, >>> acpi_status status; >>> acpi_object_type type = 0; >>> struct acpi_device *acpi_device = to_acpi_device(d); >>> + struct acpi_eject_event *ej_event; >>> >>> if ((!count) || (buf[0] != '1')) { >>> return -EINVAL; >>> @@ -160,7 +181,25 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, >>> goto err; >>> } >>> >>> - acpi_os_hotplug_execute(acpi_bus_hot_remove_device, acpi_device->handle); >>> + ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); >>> + if (!ej_event) { >>> + ret = -ENOMEM; >>> + goto err; >>> + } >>> + >>> + ej_event->handle = acpi_device->handle; >>> + if (acpi_device->flags.eject_pending) { >>> + /* event originated from ACPI eject notification */ >>> + ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; >>> + acpi_device->flags.eject_pending = 0; >>> + } else { >>> + /* event originated from user */ >>> + ej_event->event = ACPI_OST_EC_OSPM_EJECT; >>> + (void) acpi_evaluate_hotplug_ost(ej_event->handle, >>> + ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); >>> + } >>> + >>> + acpi_os_hotplug_execute(acpi_bus_hot_remove_device, (void *)ej_event); >>> err: >>> return ret; >>> } >>> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h >>> index 1d9e432..b22b774 100644 >>> --- a/include/acpi/acpi_bus.h >>> +++ b/include/acpi/acpi_bus.h >>> @@ -182,7 +182,8 @@ struct acpi_device_flags { >>> u32 suprise_removal_ok:1; >>> u32 power_manageable:1; >>> u32 performance_manageable:1; >>> - u32 reserved:24; >>> + u32 eject_pending:1; >>> + u32 reserved:23; >>> }; >>> >>> /* File System */ >>> @@ -334,6 +335,11 @@ struct acpi_bus_event { >>> u32 data; >>> }; >>> >>> +struct acpi_eject_event { >>> + acpi_handle handle; >>> + u32 event; >>> +}; >>> + >>> extern struct kobject *acpi_kobj; >>> extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int); >>> void acpi_bus_private_data_handler(acpi_handle, void *); >>> @@ -371,6 +377,7 @@ int acpi_bus_register_driver(struct acpi_driver *driver); >>> void acpi_bus_unregister_driver(struct acpi_driver *driver); >>> int acpi_bus_add(struct acpi_device **child, struct acpi_device *parent, >>> acpi_handle handle, int type); >>> +void acpi_bus_hot_remove_device(void *context); >>> int acpi_bus_trim(struct acpi_device *start, int rmdevice); >>> int acpi_bus_start(struct acpi_device *device); >>> acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd); >>> >> >> >> > >
| |