aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-11-14 22:37:35 +0900
committerJeff Garzik <jeff@garzik.org>2006-12-01 22:46:00 -0500
commitd25614bad6eec8fb80f3ef5bffbf720ebb7d2412 (patch)
tree955408142e756dbb9dd0b9538525959d526bd8fc /drivers
parent35b649fe2587b2e569c17c022ba3506ba441b6a2 (diff)
[PATCH] libata: improve SCSI sense data generation
Update ata_gen_ata_sense() to use desc format sense data to report the first failed block. The first failed block is read from result_tf using ata_tf_read_block() which can handle all three address formats. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/libata-scsi.c46
1 files changed, 23 insertions, 23 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 6626ee1d57d..56d7e1ea9d7 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -746,53 +746,53 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
* ata_gen_ata_sense - generate a SCSI fixed sense block
* @qc: Command that we are erroring out
*
- * Leverage ata_to_sense_error() to give us the codes. Fit our
- * LBA in here if there's room.
+ * Generate sense block for a failed ATA command @qc. Descriptor
+ * format is used to accomodate LBA48 block address.
*
* LOCKING:
* None.
*/
static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
{
+ struct ata_device *dev = qc->dev;
struct scsi_cmnd *cmd = qc->scsicmd;
struct ata_taskfile *tf = &qc->result_tf;
unsigned char *sb = cmd->sense_buffer;
+ unsigned char *desc = sb + 8;
int verbose = qc->ap->ops->error_handler == NULL;
+ u64 block;
memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
- /*
- * Use ata_to_sense_error() to map status register bits
+ /* sense data is current and format is descriptor */
+ sb[0] = 0x72;
+
+ /* Use ata_to_sense_error() to map status register bits
* onto sense key, asc & ascq.
*/
if (qc->err_mask ||
tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
- &sb[2], &sb[12], &sb[13], verbose);
- sb[2] &= 0x0f;
+ &sb[1], &sb[2], &sb[3], verbose);
+ sb[1] &= 0x0f;
}
- sb[0] = 0x70;
- sb[7] = 0x0a;
+ block = ata_tf_read_block(&qc->result_tf, dev);
- if (tf->flags & ATA_TFLAG_LBA48) {
- /* TODO: find solution for LBA48 descriptors */
- }
+ /* information sense data descriptor */
+ sb[7] = 12;
+ desc[0] = 0x00;
+ desc[1] = 10;
- else if (tf->flags & ATA_TFLAG_LBA) {
- /* A small (28b) LBA will fit in the 32b info field */
- sb[0] |= 0x80; /* set valid bit */
- sb[3] = tf->device & 0x0f;
- sb[4] = tf->lbah;
- sb[5] = tf->lbam;
- sb[6] = tf->lbal;
- }
-
- else {
- /* TODO: C/H/S */
- }
+ desc[2] |= 0x80; /* valid */
+ desc[6] = block >> 40;
+ desc[7] = block >> 32;
+ desc[8] = block >> 24;
+ desc[9] = block >> 16;
+ desc[10] = block >> 8;
+ desc[11] = block;
}
static void ata_scsi_sdev_config(struct scsi_device *sdev)