From 8a3e33cf92c7b7ae25c589eccd1a69ab11cc4353 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Wed, 30 Sep 2015 21:10:25 +0200 Subject: 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 Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/ata/libata-scsi.c') 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) { -- cgit v1.2.3 From 25c7ce7f7b511fc02b6eef95595af2cea80e2612 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 3 Oct 2015 19:21:11 +0200 Subject: libata: cleanup ata_scsi_qc_complete Remove an incorrect comment and untangle an if statement in ata_scsi_qc_complete. Signed-off-by: Christoph Hellwig Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'drivers/ata/libata-scsi.c') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 183a57bff935..ebcba8504ac0 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1774,21 +1774,12 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) * asc,ascq = ATA PASS-THROUGH INFORMATION AVAILABLE */ if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) && - ((cdb[2] & 0x20) || need_sense)) { + ((cdb[2] & 0x20) || need_sense)) ata_gen_passthru_sense(qc); - } else { - if (!need_sense) { - cmd->result = SAM_STAT_GOOD; - } else { - /* TODO: decide which descriptor format to use - * for 48b LBA devices and call that here - * instead of the fixed desc, which is only - * good for smaller LBA (and maybe CHS?) - * devices. - */ - ata_gen_ata_sense(qc); - } - } + else if (need_sense) + ata_gen_ata_sense(qc); + else + cmd->result = SAM_STAT_GOOD; if (need_sense && !ap->ops->error_handler) ata_dump_status(ap->print_id, &qc->result_tf); -- cgit v1.2.3 From 2aa8f5d63d9183ab185364d4ce849566ede0f301 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 8 Oct 2015 10:25:41 +0200 Subject: libata: only call ->done once all per-tag ressources are released When calling ->done before releasing resources we could run into a race where the SCSI midlayer sends another command and races with the resources beeing manipulated. For libata this can't currently happen as synchronization happens at a higher level, but I'd still like to fix it to future proof libata and to avoid copy & paste into SCSI drivers where this pattern has led to reproducible crashes. Signed-off-by: Christoph Hellwig Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers/ata/libata-scsi.c') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index ebcba8504ac0..560cedea2b40 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1757,6 +1757,15 @@ nothing_to_do: return 1; } +static void ata_qc_done(struct ata_queued_cmd *qc) +{ + struct scsi_cmnd *cmd = qc->scsicmd; + void (*done)(struct scsi_cmnd *) = qc->scsidone; + + ata_qc_free(qc); + done(cmd); +} + static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; @@ -1784,9 +1793,7 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) if (need_sense && !ap->ops->error_handler) ata_dump_status(ap->print_id, &qc->result_tf); - qc->scsidone(cmd); - - ata_qc_free(qc); + ata_qc_done(qc); } /** @@ -2588,8 +2595,7 @@ static void atapi_sense_complete(struct ata_queued_cmd *qc) ata_gen_passthru_sense(qc); } - qc->scsidone(qc->scsicmd); - ata_qc_free(qc); + ata_qc_done(qc); } /* is it pointless to prefer PIO for "safety reasons"? */ @@ -2684,8 +2690,7 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) qc->dev->sdev->locked = 0; qc->scsicmd->result = SAM_STAT_CHECK_CONDITION; - qc->scsidone(cmd); - ata_qc_free(qc); + ata_qc_done(qc); return; } @@ -2729,8 +2734,7 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) cmd->result = SAM_STAT_GOOD; } - qc->scsidone(cmd); - ata_qc_free(qc); + ata_qc_done(qc); } /** * atapi_xlat - Initialize PACKET taskfile -- cgit v1.2.3 From ee7fb331c3ac642b6bf8b9dc6f23a6a2e389d717 Mon Sep 17 00:00:00 2001 From: Vinayak Kale Date: Tue, 27 Oct 2015 11:19:15 +0530 Subject: libata: add support for NCQ commands for SG interface This patch is needed to make NCQ commands with FPDMA protocol value (eg READ/WRITE FPDMA) work over SCSI Generic (SG) interface. Signed-off-by: Vinayak Kale Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/ata/libata-scsi.c') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 560cedea2b40..8dffa9990985 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2912,12 +2912,14 @@ ata_scsi_map_proto(u8 byte1) case 5: /* PIO Data-out */ return ATA_PROT_PIO; + case 12: /* FPDMA */ + return ATA_PROT_NCQ; + case 0: /* Hard Reset */ case 1: /* SRST */ case 8: /* Device Diagnostic */ case 9: /* Device Reset */ case 7: /* DMA Queued */ - case 12: /* FPDMA */ case 15: /* Return Response Info */ default: /* Reserved */ break; @@ -2990,6 +2992,10 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) tf->command = cdb[9]; } + /* For NCQ commands with FPDMA protocol, copy the tag value */ + if (tf->protocol == ATA_PROT_NCQ) + tf->nsect = qc->tag << 3; + /* enforce correct master/slave bit */ tf->device = dev->devno ? tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1; -- cgit v1.2.3 From 5f8e7f17f6f5472d8029c22b1b8d3f9a4b1c8dff Mon Sep 17 00:00:00 2001 From: Vinayak Kale Date: Tue, 27 Oct 2015 13:11:46 +0530 Subject: libata: enable LBA flag in taskfile for ata_scsi_pass_thru() Enable LBA in taskfile flags for ata_scsi_pass_thru() Signed-off-by: Vinayak Kale Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/ata/libata-scsi.c') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 8dffa9990985..8b3a7861fa44 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2947,6 +2947,9 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) if ((tf->protocol = ata_scsi_map_proto(cdb[1])) == ATA_PROT_UNKNOWN) goto invalid_fld; + /* enable LBA */ + tf->flags |= ATA_TFLAG_LBA; + /* * 12 and 16 byte CDBs use different offsets to * provide the various register values. -- cgit v1.2.3