Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

libata-scsi: generate correct ATA pass-through sense

Generate ATA pass-through sense for both fixed and descriptor
format sense.

Signed-off-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Tejun Heo <tj@kernel.org>

authored by

Hannes Reinecke and committed by
Tejun Heo
11093cb1 3852e373

+58 -33
+58 -33
drivers/ata/libata-scsi.c
··· 1016 1016 &sense_key, &asc, &ascq, verbose); 1017 1017 ata_scsi_set_sense(cmd, sense_key, asc, ascq); 1018 1018 } else { 1019 - /* ATA PASS-THROUGH INFORMATION AVAILABLE */ 1020 - ata_scsi_set_sense(cmd, RECOVERED_ERROR, 0, 0x1D); 1019 + /* 1020 + * ATA PASS-THROUGH INFORMATION AVAILABLE 1021 + * Always in descriptor format sense. 1022 + */ 1023 + scsi_build_sense_buffer(1, cmd->sense_buffer, 1024 + RECOVERED_ERROR, 0, 0x1D); 1021 1025 } 1022 1026 1023 - /* 1024 - * Sense data is current and format is descriptor. 1025 - */ 1026 - sb[0] = 0x72; 1027 + if ((cmd->sense_buffer[0] & 0x7f) >= 0x72) { 1028 + u8 len; 1027 1029 1028 - desc[0] = 0x09; 1030 + /* descriptor format */ 1031 + len = sb[7]; 1032 + desc = (char *)scsi_sense_desc_find(sb, len + 8, 9); 1033 + if (!desc) { 1034 + if (SCSI_SENSE_BUFFERSIZE < len + 14) 1035 + return; 1036 + sb[7] = len + 14; 1037 + desc = sb + 8 + len; 1038 + } 1039 + desc[0] = 9; 1040 + desc[1] = 12; 1041 + /* 1042 + * Copy registers into sense buffer. 1043 + */ 1044 + desc[2] = 0x00; 1045 + desc[3] = tf->feature; /* == error reg */ 1046 + desc[5] = tf->nsect; 1047 + desc[7] = tf->lbal; 1048 + desc[9] = tf->lbam; 1049 + desc[11] = tf->lbah; 1050 + desc[12] = tf->device; 1051 + desc[13] = tf->command; /* == status reg */ 1029 1052 1030 - /* set length of additional sense data */ 1031 - sb[7] = 14; 1032 - desc[1] = 12; 1033 - 1034 - /* 1035 - * Copy registers into sense buffer. 1036 - */ 1037 - desc[2] = 0x00; 1038 - desc[3] = tf->feature; /* == error reg */ 1039 - desc[5] = tf->nsect; 1040 - desc[7] = tf->lbal; 1041 - desc[9] = tf->lbam; 1042 - desc[11] = tf->lbah; 1043 - desc[12] = tf->device; 1044 - desc[13] = tf->command; /* == status reg */ 1045 - 1046 - /* 1047 - * Fill in Extend bit, and the high order bytes 1048 - * if applicable. 1049 - */ 1050 - if (tf->flags & ATA_TFLAG_LBA48) { 1051 - desc[2] |= 0x01; 1052 - desc[4] = tf->hob_nsect; 1053 - desc[6] = tf->hob_lbal; 1054 - desc[8] = tf->hob_lbam; 1055 - desc[10] = tf->hob_lbah; 1053 + /* 1054 + * Fill in Extend bit, and the high order bytes 1055 + * if applicable. 1056 + */ 1057 + if (tf->flags & ATA_TFLAG_LBA48) { 1058 + desc[2] |= 0x01; 1059 + desc[4] = tf->hob_nsect; 1060 + desc[6] = tf->hob_lbal; 1061 + desc[8] = tf->hob_lbam; 1062 + desc[10] = tf->hob_lbah; 1063 + } 1064 + } else { 1065 + /* Fixed sense format */ 1066 + desc[0] = tf->feature; 1067 + desc[1] = tf->command; /* status */ 1068 + desc[2] = tf->device; 1069 + desc[3] = tf->nsect; 1070 + desc[0] = 0; 1071 + if (tf->flags & ATA_TFLAG_LBA48) { 1072 + desc[8] |= 0x80; 1073 + if (tf->hob_nsect) 1074 + desc[8] |= 0x40; 1075 + if (tf->hob_lbal || tf->hob_lbam || tf->hob_lbah) 1076 + desc[8] |= 0x20; 1077 + } 1078 + desc[9] = tf->lbal; 1079 + desc[10] = tf->lbam; 1080 + desc[11] = tf->lbah; 1056 1081 } 1057 1082 } 1058 1083