Re: [PATCH v2] libata: disable runtime pm for hotpluggable port
From: Lin Ming
Date: Wed Apr 04 2012 - 21:12:42 EST
On Mon, Apr 2, 2012 at 4:48 AM, Jiri Slaby <jslaby@xxxxxxx> 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@xxxxxxx>
>> Reported-and-tested-by: cwillu@xxxxxxxxxx
>> Reported-and-tested-by: jackdachef@xxxxxxxxx
>> Signed-off-by: Lin Ming <ming.m.lin@xxxxxxxxx>
>> ---
>> 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
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/