aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-scsi.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-04-20 11:32:26 +1000
committerDave Airlie <airlied@redhat.com>2015-04-20 13:05:20 +1000
commit2c33ce009ca2389dbf0535d0672214d09738e35e (patch)
tree6186a6458c3c160385d794a23eaf07c786a9e61b /drivers/ata/libata-scsi.c
parentmedia-bus: Fixup RGB444_1X12, RGB565_1X16, and YUV8_1X24 media bus format (diff)
parentMerge branch 'turbostat' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux (diff)
downloadlinux-dev-2c33ce009ca2389dbf0535d0672214d09738e35e.tar.xz
linux-dev-2c33ce009ca2389dbf0535d0672214d09738e35e.zip
Merge Linus master into drm-next
The merge is clean, but the arm build fails afterwards, due to API changes in the regulator tree. I've included the patch into the merge to fix the build. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r--drivers/ata/libata-scsi.c116
1 files changed, 75 insertions, 41 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index b061ba2c31d8..3131adcc1f87 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -270,13 +270,28 @@ DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR,
ata_scsi_park_show, ata_scsi_park_store);
EXPORT_SYMBOL_GPL(dev_attr_unload_heads);
-static void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
+void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
{
+ if (!cmd)
+ return;
+
cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
scsi_build_sense_buffer(0, cmd->sense_buffer, sk, asc, ascq);
}
+void ata_scsi_set_sense_information(struct scsi_cmnd *cmd,
+ const struct ata_taskfile *tf)
+{
+ u64 information;
+
+ if (!cmd)
+ return;
+
+ information = ata_tf_read_block(tf, NULL);
+ scsi_set_sense_information(cmd->sense_buffer, information);
+}
+
static ssize_t
ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
@@ -799,26 +814,27 @@ static void ata_dump_status(unsigned id, struct ata_taskfile *tf)
if (stat & ATA_BUSY) {
printk("Busy }\n"); /* Data is not valid in this case */
} else {
- if (stat & 0x40) printk("DriveReady ");
- if (stat & 0x20) printk("DeviceFault ");
- if (stat & 0x10) printk("SeekComplete ");
- if (stat & 0x08) printk("DataRequest ");
- if (stat & 0x04) printk("CorrectedError ");
- if (stat & 0x02) printk("Index ");
- if (stat & 0x01) printk("Error ");
+ if (stat & ATA_DRDY) printk("DriveReady ");
+ if (stat & ATA_DF) printk("DeviceFault ");
+ if (stat & ATA_DSC) printk("SeekComplete ");
+ if (stat & ATA_DRQ) printk("DataRequest ");
+ if (stat & ATA_CORR) printk("CorrectedError ");
+ if (stat & ATA_SENSE) printk("Sense ");
+ if (stat & ATA_ERR) printk("Error ");
printk("}\n");
if (err) {
printk(KERN_WARNING "ata%u: error=0x%02x { ", id, err);
- if (err & 0x04) printk("DriveStatusError ");
- if (err & 0x80) {
- if (err & 0x04) printk("BadCRC ");
+ if (err & ATA_ABORTED) printk("DriveStatusError ");
+ if (err & ATA_ICRC) {
+ if (err & ATA_ABORTED)
+ printk("BadCRC ");
else printk("Sector ");
}
- if (err & 0x40) printk("UncorrectableError ");
- if (err & 0x10) printk("SectorIdNotFound ");
- if (err & 0x02) printk("TrackZeroNotFound ");
- if (err & 0x01) printk("AddrMarkNotFound ");
+ if (err & ATA_UNC) printk("UncorrectableError ");
+ if (err & ATA_IDNF) printk("SectorIdNotFound ");
+ if (err & ATA_TRK0NF) printk("TrackZeroNotFound ");
+ if (err & ATA_AMNF) printk("AddrMarkNotFound ");
printk("}\n");
}
}
@@ -849,40 +865,59 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk,
/* Based on the 3ware driver translation table */
static const unsigned char sense_table[][4] = {
/* BBD|ECC|ID|MAR */
- {0xd1, ABORTED_COMMAND, 0x00, 0x00}, // Device busy Aborted command
+ {0xd1, ABORTED_COMMAND, 0x00, 0x00},
+ // Device busy Aborted command
/* BBD|ECC|ID */
- {0xd0, ABORTED_COMMAND, 0x00, 0x00}, // Device busy Aborted command
+ {0xd0, ABORTED_COMMAND, 0x00, 0x00},
+ // Device busy Aborted command
/* ECC|MC|MARK */
- {0x61, HARDWARE_ERROR, 0x00, 0x00}, // Device fault Hardware error
+ {0x61, HARDWARE_ERROR, 0x00, 0x00},
+ // Device fault Hardware error
/* ICRC|ABRT */ /* NB: ICRC & !ABRT is BBD */
- {0x84, ABORTED_COMMAND, 0x47, 0x00}, // Data CRC error SCSI parity error
+ {0x84, ABORTED_COMMAND, 0x47, 0x00},
+ // Data CRC error SCSI parity error
/* MC|ID|ABRT|TRK0|MARK */
- {0x37, NOT_READY, 0x04, 0x00}, // Unit offline Not ready
+ {0x37, NOT_READY, 0x04, 0x00},
+ // Unit offline Not ready
/* MCR|MARK */
- {0x09, NOT_READY, 0x04, 0x00}, // Unrecovered disk error Not ready
+ {0x09, NOT_READY, 0x04, 0x00},
+ // Unrecovered disk error Not ready
/* Bad address mark */
- {0x01, MEDIUM_ERROR, 0x13, 0x00}, // Address mark not found Address mark not found for data field
- /* TRK0 */
- {0x02, HARDWARE_ERROR, 0x00, 0x00}, // Track 0 not found Hardware error
+ {0x01, MEDIUM_ERROR, 0x13, 0x00},
+ // Address mark not found for data field
+ /* TRK0 - Track 0 not found */
+ {0x02, HARDWARE_ERROR, 0x00, 0x00},
+ // Hardware error
/* Abort: 0x04 is not translated here, see below */
/* Media change request */
- {0x08, NOT_READY, 0x04, 0x00}, // Media change request FIXME: faking offline
- /* SRV/IDNF */
- {0x10, ILLEGAL_REQUEST, 0x21, 0x00}, // ID not found Logical address out of range
- /* MC */
- {0x20, UNIT_ATTENTION, 0x28, 0x00}, // Media Changed Not ready to ready change, medium may have changed
- /* ECC */
- {0x40, MEDIUM_ERROR, 0x11, 0x04}, // Uncorrectable ECC error Unrecovered read error
+ {0x08, NOT_READY, 0x04, 0x00},
+ // FIXME: faking offline
+ /* SRV/IDNF - ID not found */
+ {0x10, ILLEGAL_REQUEST, 0x21, 0x00},
+ // Logical address out of range
+ /* MC - Media Changed */
+ {0x20, UNIT_ATTENTION, 0x28, 0x00},
+ // Not ready to ready change, medium may have changed
+ /* ECC - Uncorrectable ECC error */
+ {0x40, MEDIUM_ERROR, 0x11, 0x04},
+ // Unrecovered read error
/* BBD - block marked bad */
- {0x80, MEDIUM_ERROR, 0x11, 0x04}, // Block marked bad Medium error, unrecovered read error
+ {0x80, MEDIUM_ERROR, 0x11, 0x04},
+ // Block marked bad Medium error, unrecovered read error
{0xFF, 0xFF, 0xFF, 0xFF}, // END mark
};
static const unsigned char stat_table[][4] = {
/* Must be first because BUSY means no other bits valid */
- {0x80, ABORTED_COMMAND, 0x47, 0x00}, // Busy, fake parity for now
- {0x20, HARDWARE_ERROR, 0x44, 0x00}, // Device fault, internal target failure
- {0x08, ABORTED_COMMAND, 0x47, 0x00}, // Timed out in xfer, fake parity for now
- {0x04, RECOVERED_ERROR, 0x11, 0x00}, // Recovered ECC error Medium error, recovered
+ {0x80, ABORTED_COMMAND, 0x47, 0x00},
+ // Busy, fake parity for now
+ {0x40, ILLEGAL_REQUEST, 0x21, 0x04},
+ // Device ready, unaligned write command
+ {0x20, HARDWARE_ERROR, 0x44, 0x00},
+ // Device fault, internal target failure
+ {0x08, ABORTED_COMMAND, 0x47, 0x00},
+ // Timed out in xfer, fake parity for now
+ {0x04, RECOVERED_ERROR, 0x11, 0x00},
+ // Recovered ECC error Medium error, recovered
{0xFF, 0xFF, 0xFF, 0xFF}, // END mark
};
@@ -1757,7 +1792,9 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
((cdb[2] & 0x20) || need_sense)) {
ata_gen_passthru_sense(qc);
} else {
- if (!need_sense) {
+ if (qc->flags & ATA_QCFLAG_SENSE_VALID) {
+ cmd->result = SAM_STAT_CHECK_CONDITION;
+ } else if (!need_sense) {
cmd->result = SAM_STAT_GOOD;
} else {
/* TODO: decide which descriptor format to use
@@ -4240,10 +4277,7 @@ int ata_sas_allocate_tag(struct ata_port *ap)
unsigned int i, tag;
for (i = 0, tag = ap->sas_last_tag + 1; i < max_queue; i++, tag++) {
- if (ap->flags & ATA_FLAG_LOWTAG)
- tag = 1;
- else
- tag = tag < max_queue ? tag : 0;
+ tag = tag < max_queue ? tag : 0;
/* the last tag is reserved for internal command. */
if (tag == ATA_TAG_INTERNAL)