public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] libata: disable runtime pm for hotpluggable port
@ 2012-03-13  1:57 Lin Ming
  2012-03-14 22:49 ` Matt
  2012-04-01 20:48 ` Jiri Slaby
  0 siblings, 2 replies; 6+ messages in thread
From: Lin Ming @ 2012-03-13  1:57 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-ide, lkml, jslaby, cwillu, jackdachef, Sergei Shtylyov

Currently, hotplug doesn't work if port is already runtime suspended.
For now, we simply disable runtime pm for hotpluggable port.
Later, we should add runtime pm support for hotpluggable port too.

Bug report:
https://lkml.org/lkml/2012/2/19/70

v2:
- Use bit 2 and 3 for flags ATA_FLAG_EXTERNAL and ATA_FLAG_PLUGGABLE.

TODO: add similar hotpluggable port check for controllers other than
AHCI.

Reported-and-tested-by: Jiri Slaby <jslaby@suse.cz>
Reported-and-tested-by: cwillu@cwillu.com
Reported-and-tested-by: jackdachef@gmail.com
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
---
 drivers/ata/ahci.c             |    3 +++
 drivers/ata/ahci.h             |    3 +++
 drivers/ata/libahci.c          |   20 ++++++++++++++++++++
 drivers/ata/libata-transport.c |    6 ++++--
 include/linux/libata.h         |    2 ++
 5 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index d07bf03..02e93ff 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1145,6 +1145,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (hpriv->cap & HOST_CAP_PMP)
 		pi.flags |= ATA_FLAG_PMP;
 
+	if (hpriv->cap & HOST_CAP_SXS)
+		pi.flags |= ATA_FLAG_EXTERNAL;
+
 	ahci_set_em_messages(hpriv, &pi);
 
 	if (ahci_broken_system_poweroff(pdev)) {
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index b175000..92f7172 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -172,6 +172,9 @@ enum {
 	PORT_CMD_ALPE		= (1 << 26), /* Aggressive Link PM enable */
 	PORT_CMD_ATAPI		= (1 << 24), /* Device is ATAPI */
 	PORT_CMD_FBSCP		= (1 << 22), /* FBS Capable Port */
+	PORT_CMD_ESP		= (1 << 21), /* External SATA Port */
+	PORT_CMD_MPSP		= (1 << 19), /* Mechanical Presence Switch Attached to Port */
+	PORT_CMD_HPCP		= (1 << 18), /* Hot Plug Capable Port */
 	PORT_CMD_PMP		= (1 << 17), /* PMP attached */
 	PORT_CMD_LIST_ON	= (1 << 15), /* cmd list DMA engine running */
 	PORT_CMD_FIS_ON		= (1 << 14), /* FIS DMA engine running */
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index a72bfd0..7d72d3c 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -1097,6 +1097,23 @@ static void ahci_port_init(struct device *dev, struct ata_port *ap,
 	writel(1 << port_no, mmio + HOST_IRQ_STAT);
 }
 
+static bool ahci_port_pluggable(struct ata_port *ap)
+{
+	void __iomem *port_mmio = ahci_port_base(ap);
+	u32 cmd;
+
+	cmd = readl(port_mmio + PORT_CMD);
+
+	if ((ap->flags & ATA_FLAG_EXTERNAL) &&
+	    (cmd & PORT_CMD_ESP))
+		return true;
+
+	if (cmd & (PORT_CMD_MPSP | PORT_CMD_HPCP))
+		return true;
+
+	return false;
+}
+
 void ahci_init_controller(struct ata_host *host)
 {
 	struct ahci_host_priv *hpriv = host->private_data;
@@ -1112,6 +1129,9 @@ void ahci_init_controller(struct ata_host *host)
 		if (ata_port_is_dummy(ap))
 			continue;
 
+		if (ahci_port_pluggable(ap))
+			ap->flags |= ATA_FLAG_PLUGGABLE;
+
 		ahci_port_init(host->dev, ap, i, mmio, port_mmio);
 	}
 
diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
index 74aaee3..a7166b9 100644
--- a/drivers/ata/libata-transport.c
+++ b/drivers/ata/libata-transport.c
@@ -292,8 +292,10 @@ int ata_tport_add(struct device *parent,
 	}
 
 	device_enable_async_suspend(dev);
-	pm_runtime_set_active(dev);
-	pm_runtime_enable(dev);
+	if (!(ap->flags & ATA_FLAG_PLUGGABLE)) {
+		pm_runtime_set_active(dev);
+		pm_runtime_enable(dev);
+	}
 
 	transport_add_device(dev);
 	transport_configure_device(dev);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index cafc09a..f46961d 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -187,6 +187,8 @@ enum {
 	ATA_FLAG_SLAVE_POSS	= (1 << 0), /* host supports slave dev */
 					    /* (doesn't imply presence) */
 	ATA_FLAG_SATA		= (1 << 1),
+	ATA_FLAG_EXTERNAL	= (1 << 2), /* Controller supports external SATA */
+	ATA_FLAG_PLUGGABLE	= (1 << 3), /* Port is hotpluggable */
 	ATA_FLAG_NO_ATAPI	= (1 << 6), /* No ATAPI support */
 	ATA_FLAG_PIO_DMA	= (1 << 7), /* PIO cmds via DMA */
 	ATA_FLAG_PIO_LBA48	= (1 << 8), /* Host DMA engine is LBA28 only */
-- 
1.7.2.5




^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] libata: disable runtime pm for hotpluggable port
  2012-03-13  1:57 [PATCH v2] libata: disable runtime pm for hotpluggable port Lin Ming
@ 2012-03-14 22:49 ` Matt
  2012-03-15  1:27   ` Lin Ming
  2012-03-21  4:20   ` Lin Ming
  2012-04-01 20:48 ` Jiri Slaby
  1 sibling, 2 replies; 6+ messages in thread
From: Matt @ 2012-03-14 22:49 UTC (permalink / raw)
  To: Lin Ming; +Cc: Jeff Garzik, linux-ide, lkml, jslaby, cwillu, Sergei Shtylyov

On Tue, Mar 13, 2012 at 2:57 AM, Lin Ming <ming.m.lin@intel.com> wrote:
> Currently, hotplug doesn't work if port is already runtime suspended.
> For now, we simply disable runtime pm for hotpluggable port.
> Later, we should add runtime pm support for hotpluggable port too.
>
> Bug report:
> https://lkml.org/lkml/2012/2/19/70
>
> v2:
> - Use bit 2 and 3 for flags ATA_FLAG_EXTERNAL and ATA_FLAG_PLUGGABLE.
>
> TODO: add similar hotpluggable port check for controllers other than
> AHCI.
>
> Reported-and-tested-by: Jiri Slaby <jslaby@suse.cz>
> Reported-and-tested-by: cwillu@cwillu.com
> Reported-and-tested-by: jackdachef@gmail.com
> Signed-off-by: Lin Ming <ming.m.lin@intel.com>
> ---
>  drivers/ata/ahci.c             |    3 +++
>  drivers/ata/ahci.h             |    3 +++
>  drivers/ata/libahci.c          |   20 ++++++++++++++++++++
>  drivers/ata/libata-transport.c |    6 ++++--
>  include/linux/libata.h         |    2 ++
>  5 files changed, 32 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
> index d07bf03..02e93ff 100644
> --- a/drivers/ata/ahci.c
> +++ b/drivers/ata/ahci.c
> @@ -1145,6 +1145,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
>        if (hpriv->cap & HOST_CAP_PMP)
>                pi.flags |= ATA_FLAG_PMP;
>
> +       if (hpriv->cap & HOST_CAP_SXS)
> +               pi.flags |= ATA_FLAG_EXTERNAL;
> +
>        ahci_set_em_messages(hpriv, &pi);
>
>        if (ahci_broken_system_poweroff(pdev)) {
> diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
> index b175000..92f7172 100644
> --- a/drivers/ata/ahci.h
> +++ b/drivers/ata/ahci.h
> @@ -172,6 +172,9 @@ enum {
>        PORT_CMD_ALPE           = (1 << 26), /* Aggressive Link PM enable */
>        PORT_CMD_ATAPI          = (1 << 24), /* Device is ATAPI */
>        PORT_CMD_FBSCP          = (1 << 22), /* FBS Capable Port */
> +       PORT_CMD_ESP            = (1 << 21), /* External SATA Port */
> +       PORT_CMD_MPSP           = (1 << 19), /* Mechanical Presence Switch Attached to Port */
> +       PORT_CMD_HPCP           = (1 << 18), /* Hot Plug Capable Port */
>        PORT_CMD_PMP            = (1 << 17), /* PMP attached */
>        PORT_CMD_LIST_ON        = (1 << 15), /* cmd list DMA engine running */
>        PORT_CMD_FIS_ON         = (1 << 14), /* FIS DMA engine running */
> diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
> index a72bfd0..7d72d3c 100644
> --- a/drivers/ata/libahci.c
> +++ b/drivers/ata/libahci.c
> @@ -1097,6 +1097,23 @@ static void ahci_port_init(struct device *dev, struct ata_port *ap,
>        writel(1 << port_no, mmio + HOST_IRQ_STAT);
>  }
>
> +static bool ahci_port_pluggable(struct ata_port *ap)
> +{
> +       void __iomem *port_mmio = ahci_port_base(ap);
> +       u32 cmd;
> +
> +       cmd = readl(port_mmio + PORT_CMD);
> +
> +       if ((ap->flags & ATA_FLAG_EXTERNAL) &&
> +           (cmd & PORT_CMD_ESP))
> +               return true;
> +
> +       if (cmd & (PORT_CMD_MPSP | PORT_CMD_HPCP))
> +               return true;
> +
> +       return false;
> +}
> +
>  void ahci_init_controller(struct ata_host *host)
>  {
>        struct ahci_host_priv *hpriv = host->private_data;
> @@ -1112,6 +1129,9 @@ void ahci_init_controller(struct ata_host *host)
>                if (ata_port_is_dummy(ap))
>                        continue;
>
> +               if (ahci_port_pluggable(ap))
> +                       ap->flags |= ATA_FLAG_PLUGGABLE;
> +
>                ahci_port_init(host->dev, ap, i, mmio, port_mmio);
>        }
>
> diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
> index 74aaee3..a7166b9 100644
> --- a/drivers/ata/libata-transport.c
> +++ b/drivers/ata/libata-transport.c
> @@ -292,8 +292,10 @@ int ata_tport_add(struct device *parent,
>        }
>
>        device_enable_async_suspend(dev);
> -       pm_runtime_set_active(dev);
> -       pm_runtime_enable(dev);
> +       if (!(ap->flags & ATA_FLAG_PLUGGABLE)) {
> +               pm_runtime_set_active(dev);
> +               pm_runtime_enable(dev);
> +       }
>
>        transport_add_device(dev);
>        transport_configure_device(dev);
> diff --git a/include/linux/libata.h b/include/linux/libata.h
> index cafc09a..f46961d 100644
> --- a/include/linux/libata.h
> +++ b/include/linux/libata.h
> @@ -187,6 +187,8 @@ enum {
>        ATA_FLAG_SLAVE_POSS     = (1 << 0), /* host supports slave dev */
>                                            /* (doesn't imply presence) */
>        ATA_FLAG_SATA           = (1 << 1),
> +       ATA_FLAG_EXTERNAL       = (1 << 2), /* Controller supports external SATA */
> +       ATA_FLAG_PLUGGABLE      = (1 << 3), /* Port is hotpluggable */
>        ATA_FLAG_NO_ATAPI       = (1 << 6), /* No ATAPI support */
>        ATA_FLAG_PIO_DMA        = (1 << 7), /* PIO cmds via DMA */
>        ATA_FLAG_PIO_LBA48      = (1 << 8), /* Host DMA engine is LBA28 only */
> --
> 1.7.2.5
>
>
>

Hi Lin Ming,

thanks for CCing on the updated patch

I just finished testing it with 3.3-rc7 and it works as advertised


Kind Regards

Matt

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] libata: disable runtime pm for hotpluggable port
  2012-03-14 22:49 ` Matt
@ 2012-03-15  1:27   ` Lin Ming
  2012-03-21  4:20   ` Lin Ming
  1 sibling, 0 replies; 6+ messages in thread
From: Lin Ming @ 2012-03-15  1:27 UTC (permalink / raw)
  To: Matt; +Cc: Jeff Garzik, linux-ide, lkml, jslaby, cwillu, Sergei Shtylyov

On Wed, 2012-03-14 at 23:49 +0100, Matt wrote:
[...]
> 
> Hi Lin Ming,
> 
> thanks for CCing on the updated patch
> 
> I just finished testing it with 3.3-rc7 and it works as advertised

Thanks a lot for the test :)

> 
> 
> Kind Regards
> 
> Matt



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] libata: disable runtime pm for hotpluggable port
  2012-03-14 22:49 ` Matt
  2012-03-15  1:27   ` Lin Ming
@ 2012-03-21  4:20   ` Lin Ming
  1 sibling, 0 replies; 6+ messages in thread
From: Lin Ming @ 2012-03-21  4:20 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Matt, linux-ide, lkml, jslaby, cwillu, Sergei Shtylyov

On Thu, Mar 15, 2012 at 6:49 AM, Matt <jackdachef@gmail.com> wrote:
[......]
>
> Hi Lin Ming,
>
> thanks for CCing on the updated patch
>
> I just finished testing it with 3.3-rc7 and it works as advertised

Hi Jeff,

Any comment?
Could you apply this patch for 3.4-rc?

Thanks,
Lin Ming

>
>
> Kind Regards
>
> Matt

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] libata: disable runtime pm for hotpluggable port
  2012-03-13  1:57 [PATCH v2] libata: disable runtime pm for hotpluggable port Lin Ming
  2012-03-14 22:49 ` Matt
@ 2012-04-01 20:48 ` Jiri Slaby
  2012-04-05  1:12   ` Lin Ming
  1 sibling, 1 reply; 6+ messages in thread
From: Jiri Slaby @ 2012-04-01 20:48 UTC (permalink / raw)
  To: Lin Ming
  Cc: Jeff Garzik, linux-ide, lkml, Jiri Slaby, cwillu, jackdachef,
	Sergei Shtylyov, Linus Torvalds

On 03/13/2012 02:57 AM, Lin Ming wrote:
> Currently, hotplug doesn't work if port is already runtime suspended.
> For now, we simply disable runtime pm for hotpluggable port.
> Later, we should add runtime pm support for hotpluggable port too.
> 
> Bug report:
> https://lkml.org/lkml/2012/2/19/70
> 
> v2:
> - Use bit 2 and 3 for flags ATA_FLAG_EXTERNAL and ATA_FLAG_PLUGGABLE.
> 
> TODO: add similar hotpluggable port check for controllers other than
> AHCI.

Any updates on this? The patches which introduced the bug are in -rc1
now. Unlike this patch.

> Reported-and-tested-by: Jiri Slaby <jslaby@suse.cz>
> Reported-and-tested-by: cwillu@cwillu.com
> Reported-and-tested-by: jackdachef@gmail.com
> Signed-off-by: Lin Ming <ming.m.lin@intel.com>
> ---
>  drivers/ata/ahci.c             |    3 +++
>  drivers/ata/ahci.h             |    3 +++
>  drivers/ata/libahci.c          |   20 ++++++++++++++++++++
>  drivers/ata/libata-transport.c |    6 ++++--
>  include/linux/libata.h         |    2 ++
>  5 files changed, 32 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
> index d07bf03..02e93ff 100644
> --- a/drivers/ata/ahci.c
> +++ b/drivers/ata/ahci.c
> @@ -1145,6 +1145,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
>  	if (hpriv->cap & HOST_CAP_PMP)
>  		pi.flags |= ATA_FLAG_PMP;
>  
> +	if (hpriv->cap & HOST_CAP_SXS)
> +		pi.flags |= ATA_FLAG_EXTERNAL;
> +
>  	ahci_set_em_messages(hpriv, &pi);
>  
>  	if (ahci_broken_system_poweroff(pdev)) {
> diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
> index b175000..92f7172 100644
> --- a/drivers/ata/ahci.h
> +++ b/drivers/ata/ahci.h
> @@ -172,6 +172,9 @@ enum {
>  	PORT_CMD_ALPE		= (1 << 26), /* Aggressive Link PM enable */
>  	PORT_CMD_ATAPI		= (1 << 24), /* Device is ATAPI */
>  	PORT_CMD_FBSCP		= (1 << 22), /* FBS Capable Port */
> +	PORT_CMD_ESP		= (1 << 21), /* External SATA Port */
> +	PORT_CMD_MPSP		= (1 << 19), /* Mechanical Presence Switch Attached to Port */
> +	PORT_CMD_HPCP		= (1 << 18), /* Hot Plug Capable Port */
>  	PORT_CMD_PMP		= (1 << 17), /* PMP attached */
>  	PORT_CMD_LIST_ON	= (1 << 15), /* cmd list DMA engine running */
>  	PORT_CMD_FIS_ON		= (1 << 14), /* FIS DMA engine running */
> diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
> index a72bfd0..7d72d3c 100644
> --- a/drivers/ata/libahci.c
> +++ b/drivers/ata/libahci.c
> @@ -1097,6 +1097,23 @@ static void ahci_port_init(struct device *dev, struct ata_port *ap,
>  	writel(1 << port_no, mmio + HOST_IRQ_STAT);
>  }
>  
> +static bool ahci_port_pluggable(struct ata_port *ap)
> +{
> +	void __iomem *port_mmio = ahci_port_base(ap);
> +	u32 cmd;
> +
> +	cmd = readl(port_mmio + PORT_CMD);
> +
> +	if ((ap->flags & ATA_FLAG_EXTERNAL) &&
> +	    (cmd & PORT_CMD_ESP))
> +		return true;
> +
> +	if (cmd & (PORT_CMD_MPSP | PORT_CMD_HPCP))
> +		return true;
> +
> +	return false;
> +}
> +
>  void ahci_init_controller(struct ata_host *host)
>  {
>  	struct ahci_host_priv *hpriv = host->private_data;
> @@ -1112,6 +1129,9 @@ void ahci_init_controller(struct ata_host *host)
>  		if (ata_port_is_dummy(ap))
>  			continue;
>  
> +		if (ahci_port_pluggable(ap))
> +			ap->flags |= ATA_FLAG_PLUGGABLE;
> +
>  		ahci_port_init(host->dev, ap, i, mmio, port_mmio);
>  	}
>  
> diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
> index 74aaee3..a7166b9 100644
> --- a/drivers/ata/libata-transport.c
> +++ b/drivers/ata/libata-transport.c
> @@ -292,8 +292,10 @@ int ata_tport_add(struct device *parent,
>  	}
>  
>  	device_enable_async_suspend(dev);
> -	pm_runtime_set_active(dev);
> -	pm_runtime_enable(dev);
> +	if (!(ap->flags & ATA_FLAG_PLUGGABLE)) {
> +		pm_runtime_set_active(dev);
> +		pm_runtime_enable(dev);
> +	}
>  
>  	transport_add_device(dev);
>  	transport_configure_device(dev);
> diff --git a/include/linux/libata.h b/include/linux/libata.h
> index cafc09a..f46961d 100644
> --- a/include/linux/libata.h
> +++ b/include/linux/libata.h
> @@ -187,6 +187,8 @@ enum {
>  	ATA_FLAG_SLAVE_POSS	= (1 << 0), /* host supports slave dev */
>  					    /* (doesn't imply presence) */
>  	ATA_FLAG_SATA		= (1 << 1),
> +	ATA_FLAG_EXTERNAL	= (1 << 2), /* Controller supports external SATA */
> +	ATA_FLAG_PLUGGABLE	= (1 << 3), /* Port is hotpluggable */
>  	ATA_FLAG_NO_ATAPI	= (1 << 6), /* No ATAPI support */
>  	ATA_FLAG_PIO_DMA	= (1 << 7), /* PIO cmds via DMA */
>  	ATA_FLAG_PIO_LBA48	= (1 << 8), /* Host DMA engine is LBA28 only */
> 
-- 
js
suse labs


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] libata: disable runtime pm for hotpluggable port
  2012-04-01 20:48 ` Jiri Slaby
@ 2012-04-05  1:12   ` Lin Ming
  0 siblings, 0 replies; 6+ messages in thread
From: Lin Ming @ 2012-04-05  1:12 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: Jeff Garzik, linux-ide, lkml, Jiri Slaby, cwillu, jackdachef,
	Sergei Shtylyov, Linus Torvalds

On Mon, Apr 2, 2012 at 4:48 AM, Jiri Slaby <jslaby@suse.cz> wrote:
> On 03/13/2012 02:57 AM, Lin Ming wrote:
>> Currently, hotplug doesn't work if port is already runtime suspended.
>> For now, we simply disable runtime pm for hotpluggable port.
>> Later, we should add runtime pm support for hotpluggable port too.
>>
>> Bug report:
>> https://lkml.org/lkml/2012/2/19/70
>>
>> v2:
>> - Use bit 2 and 3 for flags ATA_FLAG_EXTERNAL and ATA_FLAG_PLUGGABLE.
>>
>> TODO: add similar hotpluggable port check for controllers other than
>> AHCI.
>
> Any updates on this? The patches which introduced the bug are in -rc1
> now. Unlike this patch.

Jeff,

Any concern to apply this patch?

Regards,
Lin Ming

>
>> Reported-and-tested-by: Jiri Slaby <jslaby@suse.cz>
>> Reported-and-tested-by: cwillu@cwillu.com
>> Reported-and-tested-by: jackdachef@gmail.com
>> Signed-off-by: Lin Ming <ming.m.lin@intel.com>
>> ---
>>  drivers/ata/ahci.c             |    3 +++
>>  drivers/ata/ahci.h             |    3 +++
>>  drivers/ata/libahci.c          |   20 ++++++++++++++++++++
>>  drivers/ata/libata-transport.c |    6 ++++--
>>  include/linux/libata.h         |    2 ++
>>  5 files changed, 32 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
>> index d07bf03..02e93ff 100644
>> --- a/drivers/ata/ahci.c
>> +++ b/drivers/ata/ahci.c
>> @@ -1145,6 +1145,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
>>       if (hpriv->cap & HOST_CAP_PMP)
>>               pi.flags |= ATA_FLAG_PMP;
>>
>> +     if (hpriv->cap & HOST_CAP_SXS)
>> +             pi.flags |= ATA_FLAG_EXTERNAL;
>> +
>>       ahci_set_em_messages(hpriv, &pi);
>>
>>       if (ahci_broken_system_poweroff(pdev)) {
>> diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
>> index b175000..92f7172 100644
>> --- a/drivers/ata/ahci.h
>> +++ b/drivers/ata/ahci.h
>> @@ -172,6 +172,9 @@ enum {
>>       PORT_CMD_ALPE           = (1 << 26), /* Aggressive Link PM enable */
>>       PORT_CMD_ATAPI          = (1 << 24), /* Device is ATAPI */
>>       PORT_CMD_FBSCP          = (1 << 22), /* FBS Capable Port */
>> +     PORT_CMD_ESP            = (1 << 21), /* External SATA Port */
>> +     PORT_CMD_MPSP           = (1 << 19), /* Mechanical Presence Switch Attached to Port */
>> +     PORT_CMD_HPCP           = (1 << 18), /* Hot Plug Capable Port */
>>       PORT_CMD_PMP            = (1 << 17), /* PMP attached */
>>       PORT_CMD_LIST_ON        = (1 << 15), /* cmd list DMA engine running */
>>       PORT_CMD_FIS_ON         = (1 << 14), /* FIS DMA engine running */
>> diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
>> index a72bfd0..7d72d3c 100644
>> --- a/drivers/ata/libahci.c
>> +++ b/drivers/ata/libahci.c
>> @@ -1097,6 +1097,23 @@ static void ahci_port_init(struct device *dev, struct ata_port *ap,
>>       writel(1 << port_no, mmio + HOST_IRQ_STAT);
>>  }
>>
>> +static bool ahci_port_pluggable(struct ata_port *ap)
>> +{
>> +     void __iomem *port_mmio = ahci_port_base(ap);
>> +     u32 cmd;
>> +
>> +     cmd = readl(port_mmio + PORT_CMD);
>> +
>> +     if ((ap->flags & ATA_FLAG_EXTERNAL) &&
>> +         (cmd & PORT_CMD_ESP))
>> +             return true;
>> +
>> +     if (cmd & (PORT_CMD_MPSP | PORT_CMD_HPCP))
>> +             return true;
>> +
>> +     return false;
>> +}
>> +
>>  void ahci_init_controller(struct ata_host *host)
>>  {
>>       struct ahci_host_priv *hpriv = host->private_data;
>> @@ -1112,6 +1129,9 @@ void ahci_init_controller(struct ata_host *host)
>>               if (ata_port_is_dummy(ap))
>>                       continue;
>>
>> +             if (ahci_port_pluggable(ap))
>> +                     ap->flags |= ATA_FLAG_PLUGGABLE;
>> +
>>               ahci_port_init(host->dev, ap, i, mmio, port_mmio);
>>       }
>>
>> diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
>> index 74aaee3..a7166b9 100644
>> --- a/drivers/ata/libata-transport.c
>> +++ b/drivers/ata/libata-transport.c
>> @@ -292,8 +292,10 @@ int ata_tport_add(struct device *parent,
>>       }
>>
>>       device_enable_async_suspend(dev);
>> -     pm_runtime_set_active(dev);
>> -     pm_runtime_enable(dev);
>> +     if (!(ap->flags & ATA_FLAG_PLUGGABLE)) {
>> +             pm_runtime_set_active(dev);
>> +             pm_runtime_enable(dev);
>> +     }
>>
>>       transport_add_device(dev);
>>       transport_configure_device(dev);
>> diff --git a/include/linux/libata.h b/include/linux/libata.h
>> index cafc09a..f46961d 100644
>> --- a/include/linux/libata.h
>> +++ b/include/linux/libata.h
>> @@ -187,6 +187,8 @@ enum {
>>       ATA_FLAG_SLAVE_POSS     = (1 << 0), /* host supports slave dev */
>>                                           /* (doesn't imply presence) */
>>       ATA_FLAG_SATA           = (1 << 1),
>> +     ATA_FLAG_EXTERNAL       = (1 << 2), /* Controller supports external SATA */
>> +     ATA_FLAG_PLUGGABLE      = (1 << 3), /* Port is hotpluggable */
>>       ATA_FLAG_NO_ATAPI       = (1 << 6), /* No ATAPI support */
>>       ATA_FLAG_PIO_DMA        = (1 << 7), /* PIO cmds via DMA */
>>       ATA_FLAG_PIO_LBA48      = (1 << 8), /* Host DMA engine is LBA28 only */
>>
> --
> js
> suse labs

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2012-04-05  1:12 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-13  1:57 [PATCH v2] libata: disable runtime pm for hotpluggable port Lin Ming
2012-03-14 22:49 ` Matt
2012-03-15  1:27   ` Lin Ming
2012-03-21  4:20   ` Lin Ming
2012-04-01 20:48 ` Jiri Slaby
2012-04-05  1:12   ` Lin Ming

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox