linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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?




  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).