aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-scsi.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-11-14 08:37:35 -0500
committerJeff Garzik <jeff@garzik.org>2006-12-01 22:46:00 -0500
commitd25614bad6eec8fb80f3ef5bffbf720ebb7d2412 (patch)
tree955408142e756dbb9dd0b9538525959d526bd8fc /drivers/ata/libata-scsi.c
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/ata/libata-scsi.c')
-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 6626ee1d57dc..56d7e1ea9d72 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)
746 * ata_gen_ata_sense - generate a SCSI fixed sense block 746 * ata_gen_ata_sense - generate a SCSI fixed sense block
747 * @qc: Command that we are erroring out 747 * @qc: Command that we are erroring out
748 * 748 *
749 * Leverage ata_to_sense_error() to give us the codes. Fit our 749 * Generate sense block for a failed ATA command @qc. Descriptor
750 * LBA in here if there's room. 750 * format is used to accomodate LBA48 block address.
751 * 751 *
752 * LOCKING: 752 * LOCKING:
753 * None. 753 * None.
754 */ 754 */
755static void ata_gen_ata_sense(struct ata_queued_cmd *qc) 755static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
756{ 756{
757 struct ata_device *dev = qc->dev;
757 struct scsi_cmnd *cmd = qc->scsicmd; 758 struct scsi_cmnd *cmd = qc->scsicmd;
758 struct ata_taskfile *tf = &qc->result_tf; 759 struct ata_taskfile *tf = &qc->result_tf;
759 unsigned char *sb = cmd->sense_buffer; 760 unsigned char *sb = cmd->sense_buffer;
761 unsigned char *desc = sb + 8;
760 int verbose = qc->ap->ops->error_handler == NULL; 762 int verbose = qc->ap->ops->error_handler == NULL;
763 u64 block;
761 764
762 memset(sb, 0, SCSI_SENSE_BUFFERSIZE); 765 memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
763 766
764 cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; 767 cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
765 768
766 /* 769 /* sense data is current and format is descriptor */
767 * Use ata_to_sense_error() to map status register bits 770 sb[0] = 0x72;
771
772 /* Use ata_to_sense_error() to map status register bits
768 * onto sense key, asc & ascq. 773 * onto sense key, asc & ascq.
769 */ 774 */
770 if (qc->err_mask || 775 if (qc->err_mask ||
771 tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { 776 tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
772 ata_to_sense_error(qc->ap->id, tf->command, tf->feature, 777 ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
773 &sb[2], &sb[12], &sb[13], verbose); 778 &sb[1], &sb[2], &sb[3], verbose);
774 sb[2] &= 0x0f; 779 sb[1] &= 0x0f;
775 } 780 }
776 781
777 sb[0] = 0x70; 782 block = ata_tf_read_block(&qc->result_tf, dev);
778 sb[7] = 0x0a;
779 783
780 if (tf->flags & ATA_TFLAG_LBA48) { 784 /* information sense data descriptor */
781 /* TODO: find solution for LBA48 descriptors */ 785 sb[7] = 12;
782 } 786 desc[0] = 0x00;
787 desc[1] = 10;
783 788
784 else if (tf->flags & ATA_TFLAG_LBA) { 789 desc[2] |= 0x80; /* valid */
785 /* A small (28b) LBA will fit in the 32b info field */ 790 desc[6] = block >> 40;
786 sb[0] |= 0x80; /* set valid bit */ 791 desc[7] = block >> 32;
787 sb[3] = tf->device & 0x0f; 792 desc[8] = block >> 24;
788 sb[4] = tf->lbah; 793 desc[9] = block >> 16;
789 sb[5] = tf->lbam; 794 desc[10] = block >> 8;
790 sb[6] = tf->lbal; 795 desc[11] = block;
791 }
792
793 else {
794 /* TODO: C/H/S */
795 }
796} 796}
797 797
798static void ata_scsi_sdev_config(struct scsi_device *sdev) 798static void ata_scsi_sdev_config(struct scsi_device *sdev)