summaryrefslogtreecommitdiff
path: root/drivers/ata/libata-scsi.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-03 18:19:53 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-03 18:19:53 -0700
commit357397a14117f0c2eeafcac06a1f8412a02aa6af (patch)
tree8420d5aab6b80fc211979d894174462c9806b26e /drivers/ata/libata-scsi.c
parent9ee52a1633a77961cb7b7fb5bd40be682f8412c7 (diff)
parent86a565e61bcb9574bae3b622799682fef2d855bb (diff)
Merge branch 'for-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata
Pull libata changes from Tejun Heo: "Two interesting changes. - libata acpi handling has been restructured so that the association between ata devices and ACPI handles are less convoluted. This change shouldn't change visible behavior. - Queued TRIM support, which enables sending TRIM to the device without draining in-flight RW commands, is added. Currently only enabled for ahci (and likely to stay that way for the foreseeable future). Other changes are driver-specific updates / fixes" * 'for-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata: libata: bugfix: Remove __le32 in ata_tf_to_fis() libata: acpi: Remove ata_dev_acpi_handle stub in libata.h libata: Add support for queued DSM TRIM libata: Add support for SEND/RECEIVE FPDMA QUEUED libata: Add H2D FIS "auxiliary" port flag libata: Populate host-to-device FIS "auxiliary" field ata: acpi: rework the ata acpi bind support sata, highbank: send extra clock cycles in SGPIO patterns sata, highbank: set tx_atten override bits devicetree: create a separate binding description for sata_highbank drivers/ata/sata_rcar.c: simplify use of devm_ioremap_resource sata highbank: enable 64-bit DMA mask when using LPAE ata: pata_samsung_cf: add missing __iomem annotation ata: pata_arasan: Staticize local symbols sata_mv: Remove unneeded CONFIG_HAVE_CLK ifdefs ata: use dev_get_platdata() sata_mv: Remove unneeded forward declaration libata: acpi: remove dead code for ata_acpi_(un)bind libata: move 'struct ata_taskfile' and friends from ata.h to libata.h
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r--drivers/ata/libata-scsi.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index b1e880a3c3da..97a0cef12959 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -49,7 +49,6 @@
#include <linux/hdreg.h>
#include <linux/uaccess.h>
#include <linux/suspend.h>
-#include <linux/pm_qos.h>
#include <asm/unaligned.h>
#include "libata.h"
@@ -3100,12 +3099,25 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
buf = page_address(sg_page(scsi_sglist(scmd)));
size = ata_set_lba_range_entries(buf, 512, block, n_block);
- tf->protocol = ATA_PROT_DMA;
- tf->hob_feature = 0;
- tf->feature = ATA_DSM_TRIM;
- tf->hob_nsect = (size / 512) >> 8;
- tf->nsect = size / 512;
- tf->command = ATA_CMD_DSM;
+ if (ata_ncq_enabled(dev) && ata_fpdma_dsm_supported(dev)) {
+ /* Newer devices support queued TRIM commands */
+ tf->protocol = ATA_PROT_NCQ;
+ tf->command = ATA_CMD_FPDMA_SEND;
+ tf->hob_nsect = ATA_SUBCMD_FPDMA_SEND_DSM & 0x1f;
+ tf->nsect = qc->tag << 3;
+ tf->hob_feature = (size / 512) >> 8;
+ tf->feature = size / 512;
+
+ tf->auxiliary = 1;
+ } else {
+ tf->protocol = ATA_PROT_DMA;
+ tf->hob_feature = 0;
+ tf->feature = ATA_DSM_TRIM;
+ tf->hob_nsect = (size / 512) >> 8;
+ tf->nsect = size / 512;
+ tf->command = ATA_CMD_DSM;
+ }
+
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 |
ATA_TFLAG_WRITE;
@@ -3667,9 +3679,7 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)
if (!IS_ERR(sdev)) {
dev->sdev = sdev;
scsi_device_put(sdev);
- if (zpodd_dev_enabled(dev))
- dev_pm_qos_expose_flags(
- &sdev->sdev_gendev, 0);
+ ata_scsi_acpi_bind(dev);
} else {
dev->sdev = NULL;
}
@@ -3757,6 +3767,8 @@ static void ata_scsi_remove_dev(struct ata_device *dev)
struct scsi_device *sdev;
unsigned long flags;
+ ata_scsi_acpi_unbind(dev);
+
/* Alas, we need to grab scan_mutex to ensure SCSI device
* state doesn't change underneath us and thus
* scsi_device_get() always succeeds. The mutex locking can
@@ -3766,9 +3778,6 @@ static void ata_scsi_remove_dev(struct ata_device *dev)
mutex_lock(&ap->scsi_host->scan_mutex);
spin_lock_irqsave(ap->lock, flags);
- if (zpodd_dev_enabled(dev))
- zpodd_exit(dev);
-
/* clearing dev->sdev is protected by host lock */
sdev = dev->sdev;
dev->sdev = NULL;
@@ -3818,6 +3827,9 @@ static void ata_scsi_handle_link_detach(struct ata_link *link)
dev->flags &= ~ATA_DFLAG_DETACHED;
spin_unlock_irqrestore(ap->lock, flags);
+ if (zpodd_dev_enabled(dev))
+ zpodd_exit(dev);
+
ata_scsi_remove_dev(dev);
}
}