aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r--drivers/ata/libata-core.c68
1 files changed, 35 insertions, 33 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 826d41f341e4..d3ce5c383f3a 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -665,33 +665,33 @@ u64 ata_tf_read_block(const struct ata_taskfile *tf, struct ata_device *dev)
/**
* ata_build_rw_tf - Build ATA taskfile for given read/write request
- * @tf: Target ATA taskfile
- * @dev: ATA device @tf belongs to
+ * @qc: Metadata associated with the taskfile to build
* @block: Block address
* @n_block: Number of blocks
* @tf_flags: RW/FUA etc...
- * @tag: tag
* @class: IO priority class
*
* LOCKING:
* None.
*
- * Build ATA taskfile @tf for read/write request described by
- * @block, @n_block, @tf_flags and @tag on @dev.
+ * Build ATA taskfile for the command @qc for read/write request described
+ * by @block, @n_block, @tf_flags and @class.
*
* RETURNS:
*
* 0 on success, -ERANGE if the request is too large for @dev,
* -EINVAL if the request is invalid.
*/
-int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
- u64 block, u32 n_block, unsigned int tf_flags,
- unsigned int tag, int class)
+int ata_build_rw_tf(struct ata_queued_cmd *qc, u64 block, u32 n_block,
+ unsigned int tf_flags, int class)
{
+ struct ata_taskfile *tf = &qc->tf;
+ struct ata_device *dev = qc->dev;
+
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf->flags |= tf_flags;
- if (ata_ncq_enabled(dev) && !ata_tag_internal(tag)) {
+ if (ata_ncq_enabled(dev)) {
/* yay, NCQ */
if (!lba_48_ok(block, n_block))
return -ERANGE;
@@ -704,7 +704,7 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
else
tf->command = ATA_CMD_FPDMA_READ;
- tf->nsect = tag << 3;
+ tf->nsect = qc->hw_tag << 3;
tf->hob_feature = (n_block >> 8) & 0xff;
tf->feature = n_block & 0xff;
@@ -719,7 +719,7 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
if (tf->flags & ATA_TFLAG_FUA)
tf->device |= 1 << 7;
- if (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE &&
+ if (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLED &&
class == IOPRIO_CLASS_RT)
tf->hob_nsect |= ATA_PRIO_HIGH << ATA_SHIFT_PRIO;
} else if (dev->flags & ATA_DFLAG_LBA) {
@@ -1578,8 +1578,8 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev,
else
ata_qc_complete(qc);
- ata_dev_warn(dev, "qc timeout (cmd 0x%x)\n",
- command);
+ ata_dev_warn(dev, "qc timeout after %u msecs (cmd 0x%x)\n",
+ timeout, command);
}
spin_unlock_irqrestore(ap->lock, flags);
@@ -2171,7 +2171,7 @@ static void ata_dev_config_ncq_prio(struct ata_device *dev)
return;
not_supported:
- dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE;
+ dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLED;
dev->flags &= ~ATA_DFLAG_NCQ_PRIO;
}
@@ -3021,7 +3021,8 @@ static void sata_print_link_status(struct ata_link *link)
if (sata_scr_read(link, SCR_STATUS, &sstatus))
return;
- sata_scr_read(link, SCR_CONTROL, &scontrol);
+ if (sata_scr_read(link, SCR_CONTROL, &scontrol))
+ return;
if (ata_phys_link_online(link)) {
tmp = (sstatus >> 4) & 0xf;
@@ -3988,6 +3989,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "PIONEER DVD-RW DVR-212D", NULL, ATA_HORKAGE_NOSETXFER },
{ "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER },
+ /* These specific Pioneer models have LPM issues */
+ { "PIONEER BD-RW BDR-207M", NULL, ATA_HORKAGE_NOLPM },
+ { "PIONEER BD-RW BDR-205", NULL, ATA_HORKAGE_NOLPM },
+
/* Crucial BX100 SSD 500GB has broken LPM support */
{ "CT500BX100SSD1", NULL, ATA_HORKAGE_NOLPM },
@@ -4295,7 +4300,6 @@ static void ata_dev_xfermask(struct ata_device *dev)
static unsigned int ata_dev_set_xfermode(struct ata_device *dev)
{
struct ata_taskfile tf;
- unsigned int err_mask;
/* set up set-features taskfile */
ata_dev_dbg(dev, "set features - xfer mode\n");
@@ -4317,20 +4321,20 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev)
else /* In the ancient relic department - skip all of this */
return 0;
- /* On some disks, this command causes spin-up, so we need longer timeout */
- err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 15000);
-
- return err_mask;
+ /*
+ * On some disks, this command causes spin-up, so we need longer
+ * timeout.
+ */
+ return ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 15000);
}
/**
- * ata_dev_set_feature - Issue SET FEATURES - SATA FEATURES
+ * ata_dev_set_feature - Issue SET FEATURES
* @dev: Device to which command will be sent
- * @enable: Whether to enable or disable the feature
- * @feature: The sector count represents the feature to set
+ * @subcmd: The SET FEATURES subcommand to be sent
+ * @action: The sector count represents a subcommand specific action
*
- * Issue SET FEATURES - SATA FEATURES command to device @dev
- * on port @ap with sector count
+ * Issue SET FEATURES command to device @dev on port @ap with sector count
*
* LOCKING:
* PCI/etc. bus probe sem.
@@ -4338,28 +4342,26 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev)
* RETURNS:
* 0 on success, AC_ERR_* mask otherwise.
*/
-unsigned int ata_dev_set_feature(struct ata_device *dev, u8 enable, u8 feature)
+unsigned int ata_dev_set_feature(struct ata_device *dev, u8 subcmd, u8 action)
{
struct ata_taskfile tf;
- unsigned int err_mask;
unsigned int timeout = 0;
/* set up set-features taskfile */
- ata_dev_dbg(dev, "set features - SATA features\n");
+ ata_dev_dbg(dev, "set features\n");
ata_tf_init(dev, &tf);
tf.command = ATA_CMD_SET_FEATURES;
- tf.feature = enable;
+ tf.feature = subcmd;
tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf.protocol = ATA_PROT_NODATA;
- tf.nsect = feature;
+ tf.nsect = action;
- if (enable == SETFEATURES_SPINUP)
+ if (subcmd == SETFEATURES_SPINUP)
timeout = ata_probe_timeout ?
ata_probe_timeout * 1000 : SETFEATURES_SPINUP_TIMEOUT;
- err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, timeout);
- return err_mask;
+ return ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, timeout);
}
EXPORT_SYMBOL_GPL(ata_dev_set_feature);