All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.