From: Jeff Garzik <jeff@garzik.org>
To: Matthew Garrett <mjg59@srcf.ucam.org>
Cc: Tejun Heo <htejun@gmail.com>,
linux-ide@vger.kernel.org, linux-acpi@vger.kernel.org,
Andrew Morton <akpm@linux-foundation.org>,
kristen.c.accardi@intel.com
Subject: Re: [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 3
Date: Tue, 02 Oct 2007 11:04:41 -0400 [thread overview]
Message-ID: <47025E09.1030803@garzik.org> (raw)
In-Reply-To: <20070924231436.GA32119@srcf.ucam.org>
Matthew Garrett wrote:
> Modern laptops with hotswap bays still tend to utilise a PATA interface
> on a SATA bridge, generally with the host controller in some legacy
> emulation mode rather than AHCI. This means that the existing hotplug
> code in libata is unable to work. The ACPI specification states that
> these devices can send notifications when hotswapped, which avoids the
> need to obtain notification from the controller. This patch uses the
> existing libata-acpi code and simply registers a notification in order
> to trigger a rescan whenever the firmware signals an event.
>
> Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org>
>
> ---
>
> This makes two changes to the previous patch:
>
> 1) It implements the locking suggested by Tejun
> 2) It sends a uevent on the device kobject. I've implemented this
> because grabbing the notification handler means that the bay driver can
> no longer do it, so it's necessary to generate compatible events. If the
> event type is 3, it indicates that the user has merely requested an
> eject - the drive hasn't gone at this point. Sending the notification
> allows userspace to attempt to unmount the filesystems before sending a
> command to initiate the eject.
>
> I'm not especially happy about the chain used to get the scsi device
> kobject. Is there a cleaner way to do that? Other than that, I've now
> tested this on multiple systems (a 965-based Thinkpad, a 915-era Dell
> and even an HP with no SATA whatsoever) without any obvious breakage.
>
> diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
> index c059f78..68bb7fa 100644
> --- a/drivers/ata/libata-acpi.c
> +++ b/drivers/ata/libata-acpi.c
> @@ -14,6 +14,7 @@
> #include <linux/acpi.h>
> #include <linux/libata.h>
> #include <linux/pci.h>
> +#include <scsi/scsi_device.h>
> #include "libata.h"
>
> #include <acpi/acpi_bus.h>
> @@ -66,6 +67,41 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap)
> }
> }
>
> +static void ata_acpi_notify(acpi_handle handle, u32 event, void *data)
> +{
> + struct ata_port *ap = data;
> + struct ata_eh_info *ehi = &ap->eh_info;
> + char event_string[12];
> + char *envp[] = { event_string, NULL };
> + struct kobject *kobj = NULL;
> + int i;
> +
> + if (ap->acpi_handle && handle == ap->acpi_handle)
> + kobj = &ap->dev->kobj;
> + else {
> + for (i = 0; i < ata_port_max_devices(ap); i++) {
> + struct ata_device *dev = &ap->device[i];
> + if (dev->acpi_handle && handle == dev->acpi_handle)
> + kobj = &dev->sdev->sdev_gendev.kobj;
> + }
> + }
> +
> + if (event == 0 || event == 1) {
> + unsigned long flags;
> + spin_lock_irqsave(ap->lock, flags);
> + ata_ehi_clear_desc(ehi);
> + ata_ehi_push_desc(ehi, "ACPI event");
> + ata_ehi_hotplugged(ehi);
> + ata_port_freeze(ap);
> + spin_unlock_irqrestore(ap->lock, flags);
> + }
> +
> + if (kobj) {
> + sprintf(event_string, "BAY_EVENT=%d\n", event);
> + kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
> + }
> +}
> +
> /**
> * ata_acpi_associate - associate ATA host with ACPI objects
> * @host: target ATA host
> @@ -81,7 +117,7 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap)
> */
> void ata_acpi_associate(struct ata_host *host)
> {
> - int i;
> + int i, j;
>
> if (!is_pci_dev(host->dev) || libata_noacpi)
> return;
> @@ -97,6 +133,22 @@ void ata_acpi_associate(struct ata_host *host)
> ata_acpi_associate_sata_port(ap);
> else
> ata_acpi_associate_ide_port(ap);
> +
> + if (ap->acpi_handle)
> + acpi_install_notify_handler (ap->acpi_handle,
> + ACPI_SYSTEM_NOTIFY,
> + ata_acpi_notify,
> + ap);
> +
> + for (j = 0; j < ata_port_max_devices(ap); j++) {
> + struct ata_device *dev = &ap->device[j];
> +
> + if (dev->acpi_handle)
> + acpi_install_notify_handler (dev->acpi_handle,
> + ACPI_SYSTEM_NOTIFY,
> + ata_acpi_notify,
> + ap);
Mostly OK. Notes:
1) Check dev->sdev for NULL
2) remove the unnecessary ata_device loop. If you know the ata_device
pointer, you should not throw it away and then do a search to find it again.
You need two functions, ata_acpi_ap_notify() and ata_acpi_dev_notify().
Pass 'ap' to the former, and 'dev' to the latter.
Both functions should marshal their arguments, then call a common
function (presumably what 95% of current ata_acpi_notify does).
3) Won't this result in a single hotplug event calling
ata_ehi_hotplugged() multiple times -- once for the port, and once for
each device attached to the port?
next prev parent reply other threads:[~2007-10-02 15:04 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-15 3:01 [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug Matthew Garrett
2007-09-15 17:06 ` [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 2 Matthew Garrett
2007-09-16 12:22 ` Tejun Heo
2007-09-20 22:04 ` Jeff Garzik
2007-09-20 22:21 ` Matthew Garrett
2007-09-21 2:35 ` Tejun Heo
2007-09-21 2:42 ` Matthew Garrett
2007-09-21 2:53 ` Tejun Heo
2007-09-21 2:57 ` Matthew Garrett
2007-09-21 3:08 ` Tejun Heo
2007-09-21 3:12 ` Matthew Garrett
2007-09-21 3:19 ` Tejun Heo
2007-09-24 23:14 ` [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 3 Matthew Garrett
2007-09-27 17:26 ` Kristen Carlson Accardi
2007-09-27 17:55 ` Matthew Garrett
2007-09-27 20:39 ` Henrique de Moraes Holschuh
2007-10-02 15:04 ` Jeff Garzik [this message]
2007-10-02 18:46 ` Matthew Garrett
2007-10-02 18:49 ` [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 4 Matthew Garrett
2007-10-02 18:55 ` Jeff Garzik
2007-10-02 20:38 ` Jeff Garzik
2007-10-02 20:42 ` Matthew Garrett
2007-10-02 21:20 ` Matthew Garrett
2007-10-02 21:23 ` Jeff Garzik
2007-10-03 0:24 ` [PATCH] libata: Integrate ACPI-based PATA/SATA hotplug - version 5 Matthew Garrett
2007-10-03 20:27 ` Jeff Garzik
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=47025E09.1030803@garzik.org \
--to=jeff@garzik.org \
--cc=akpm@linux-foundation.org \
--cc=htejun@gmail.com \
--cc=kristen.c.accardi@intel.com \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-ide@vger.kernel.org \
--cc=mjg59@srcf.ucam.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).