Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d25614ba authored by Tejun Heo's avatar Tejun Heo Committed by Jeff Garzik
Browse files

[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: default avatarTejun Heo <htejun@gmail.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 35b649fe
Loading
Loading
Loading
Loading
+23 −23
Original line number Original line Diff line number Diff line
@@ -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
 *	ata_gen_ata_sense - generate a SCSI fixed sense block
 *	@qc: Command that we are erroring out
 *	@qc: Command that we are erroring out
 *
 *
 *	Leverage ata_to_sense_error() to give us the codes.  Fit our
 *	Generate sense block for a failed ATA command @qc.  Descriptor
 *	LBA in here if there's room.
 *	format is used to accomodate LBA48 block address.
 *
 *
 *	LOCKING:
 *	LOCKING:
 *	None.
 *	None.
 */
 */
static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
{
{
	struct ata_device *dev = qc->dev;
	struct scsi_cmnd *cmd = qc->scsicmd;
	struct scsi_cmnd *cmd = qc->scsicmd;
	struct ata_taskfile *tf = &qc->result_tf;
	struct ata_taskfile *tf = &qc->result_tf;
	unsigned char *sb = cmd->sense_buffer;
	unsigned char *sb = cmd->sense_buffer;
	unsigned char *desc = sb + 8;
	int verbose = qc->ap->ops->error_handler == NULL;
	int verbose = qc->ap->ops->error_handler == NULL;
	u64 block;


	memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
	memset(sb, 0, SCSI_SENSE_BUFFERSIZE);


	cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
	cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;


	/*
	/* sense data is current and format is descriptor */
	 * Use ata_to_sense_error() to map status register bits
	sb[0] = 0x72;

	/* Use ata_to_sense_error() to map status register bits
	 * onto sense key, asc & ascq.
	 * onto sense key, asc & ascq.
	 */
	 */
	if (qc->err_mask ||
	if (qc->err_mask ||
	    tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
	    tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
		ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
		ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
				   &sb[2], &sb[12], &sb[13], verbose);
				   &sb[1], &sb[2], &sb[3], verbose);
		sb[2] &= 0x0f;
		sb[1] &= 0x0f;
	}
	}


	sb[0] = 0x70;
	block = ata_tf_read_block(&qc->result_tf, dev);
	sb[7] = 0x0a;


	if (tf->flags & ATA_TFLAG_LBA48) {
	/* information sense data descriptor */
		/* TODO: find solution for LBA48 descriptors */
	sb[7] = 12;
	}
	desc[0] = 0x00;
	desc[1] = 10;


	else if (tf->flags & ATA_TFLAG_LBA) {
	desc[2] |= 0x80;	/* valid */
		/* A small (28b) LBA will fit in the 32b info field */
	desc[6] = block >> 40;
		sb[0] |= 0x80;		/* set valid bit */
	desc[7] = block >> 32;
		sb[3] = tf->device & 0x0f;
	desc[8] = block >> 24;
		sb[4] = tf->lbah;
	desc[9] = block >> 16;
		sb[5] = tf->lbam;
	desc[10] = block >> 8;
		sb[6] = tf->lbal;
	desc[11] = block;
	}

	else {
		/* TODO: C/H/S */
	}
}
}


static void ata_scsi_sdev_config(struct scsi_device *sdev)
static void ata_scsi_sdev_config(struct scsi_device *sdev)