summaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorManuel Lauss <manuel.lauss@gmail.com>2015-09-30 21:10:25 +0200
committerTejun Heo <tj@kernel.org>2015-09-30 17:37:55 -0400
commit8a3e33cf92c7b7ae25c589eccd1a69ab11cc4353 (patch)
tree5dd0856ad1213f3100101f7be901f682ca3ebf98 /drivers/ata
parenta73f22f9811da0f69d5f04eadcfc87b4d6280814 (diff)
downloadlinux-8a3e33cf92c7b7ae25c589eccd1a69ab11cc4353.tar.gz
linux-8a3e33cf92c7b7ae25c589eccd1a69ab11cc4353.tar.bz2
linux-8a3e33cf92c7b7ae25c589eccd1a69ab11cc4353.zip
ata: ahci: find eSATA ports and flag them as removable
If the AHCI ports' HPCP or ESP bits are set, the port should be considered external (e.g. eSATA) and is marked as removable. Userspace tools like udisks then treat it like an usb drive. With this patch applied, when I plug a drive into the esata port, KDE pops up a window asking what to do with the drives(s), just like it does for any random USB stick. Removability is indicated to the upper layers by way of the SCSI RMB bit, as I haven't found another way to signal userspace to treat a sata disk like any usb stick. Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/ahci.h2
-rw-r--r--drivers/ata/libahci.c7
-rw-r--r--drivers/ata/libata-scsi.c7
3 files changed, 14 insertions, 2 deletions
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 5b8e8a0fab48..45586c1dbbdc 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -181,6 +181,8 @@ 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_HPCP = (1 << 18), /* HotPlug 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 d256a66158be..2fa551a5146e 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -1117,6 +1117,7 @@ static void ahci_port_init(struct device *dev, struct ata_port *ap,
int port_no, void __iomem *mmio,
void __iomem *port_mmio)
{
+ struct ahci_host_priv *hpriv = ap->host->private_data;
const char *emsg = NULL;
int rc;
u32 tmp;
@@ -1138,6 +1139,12 @@ static void ahci_port_init(struct device *dev, struct ata_port *ap,
writel(tmp, port_mmio + PORT_IRQ_STAT);
writel(1 << port_no, mmio + HOST_IRQ_STAT);
+
+ /* mark esata ports */
+ tmp = readl(port_mmio + PORT_CMD);
+ if ((tmp & PORT_CMD_HPCP) ||
+ ((tmp & PORT_CMD_ESP) && (hpriv->cap & HOST_CAP_SXS)))
+ ap->pflags |= ATA_PFLAG_EXTERNAL;
}
void ahci_init_controller(struct ata_host *host)
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 0d7f0da3a269..183a57bff935 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2015,8 +2015,11 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
VPRINTK("ENTER\n");
- /* set scsi removable (RMB) bit per ata bit */
- if (ata_id_removable(args->id))
+ /* set scsi removable (RMB) bit per ata bit, or if the
+ * AHCI port says it's external (Hotplug-capable, eSATA).
+ */
+ if (ata_id_removable(args->id) ||
+ (args->dev->link->ap->pflags & ATA_PFLAG_EXTERNAL))
hdr[1] |= (1 << 7);
if (args->dev->class == ATA_DEV_ZAC) {