New drives that default to reporting descriptor format sense data, do not have support for this in iprutils and it makes it impossible to use the drives. This patch adds code to convert the sense data to the format that user expects.
Signed-off-by: Brahadambal Srinivasan <la...@linux.vnet.ibm.com> Signed-off-by: Brian King <brk...@linux.vnet.ibm.com> Reviewed-by: Rick Lindsley <rickl...@linux.vnet.ibm.com> Reported-by: Timothy O'Callaghan <t...@us.ibm.com> --- iprlib.c | 31 +++++++++++++++++++++++++++++-- iprlib.h | 11 +++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/iprlib.c b/iprlib.c index 516f069..032fe1a 100644 --- a/iprlib.c +++ b/iprlib.c @@ -16,6 +16,8 @@ #ifndef iprlib_h #include "iprlib.h" #endif +#include <stdio.h> +#include <stdlib.h> static void default_exit_func() { @@ -5291,6 +5293,8 @@ static int _sg_ioctl(int fd, u8 cdb[IPR_CCB_CDB_LEN], int buff_len, segment_size; void *dxferp; u8 *buf; + struct sense_data_t sd; + struct df_sense_data_t *dfsdp = NULL; /* check if scatter gather should be used */ if (xfer_len > IPR_MAX_XFER) { @@ -5320,7 +5324,7 @@ static int _sg_ioctl(int fd, u8 cdb[IPR_CCB_CDB_LEN], for (i = 0; i < (retries + 1); i++) { memset(&io_hdr_t, 0, sizeof(io_hdr_t)); - memset(sense_data, 0, sizeof(struct sense_data_t)); + memset(&sd, 0, sizeof(struct sense_data_t)); io_hdr_t.interface_id = 'S'; io_hdr_t.cmd_len = cdb_size[(cdb[0] >> 5) & 0x7]; @@ -5328,7 +5332,7 @@ static int _sg_ioctl(int fd, u8 cdb[IPR_CCB_CDB_LEN], io_hdr_t.flags = 0; io_hdr_t.pack_id = 0; io_hdr_t.usr_ptr = 0; - io_hdr_t.sbp = (unsigned char *)sense_data; + io_hdr_t.sbp = (unsigned char *)&sd; io_hdr_t.mx_sb_len = sizeof(struct sense_data_t); io_hdr_t.timeout = timeout_in_sec * 1000; io_hdr_t.cmdp = cdb; @@ -5352,6 +5356,29 @@ static int _sg_ioctl(int fd, u8 cdb[IPR_CCB_CDB_LEN], break; } + memset(sense_data, 0, sizeof(struct sense_data_t)); + + if (((sd.error_code & 0x7F) == 0x72) || ((sd.error_code & 0x7F) == 0x73)) { + dfsdp = (struct df_sense_data_t *)&sd; + /* change error_codes 0x72 to 0x70 and 0x73 to 0x71 */ + sense_data->error_code = dfsdp->error_code & 0xFD; + + /* Do not change the order of the next two assignments + * In the same u8, bit 4 of the fixed format corresponds + * to SDAT_OVLF and the last 4 bits to sense_key. + */ + sense_data->sense_key = dfsdp->sense_key & 0x0F; + if (dfsdp->rfield & 0x80) + sense_data->sense_key |= 0x10; + + /* copy the other values */ + sense_data->add_sense_code = dfsdp->add_sense_code; + sense_data->add_sense_code_qual = dfsdp->add_sense_code_qual; + sense_data->add_sense_len = dfsdp->add_sense_len; + } else if (((sd.error_code & 0x7F) == 0x70) || ((sd.error_code & 0x7F) == 0x71)) { + memcpy((void *)sense_data, (void *)&sd, sizeof(struct sense_data_t)); + } + out: if (iovec_count) { for (i = 0, buf = (u8 *)data; i < iovec_count; i++) { diff --git a/iprlib.h b/iprlib.h index aa07989..ebd1c81 100644 --- a/iprlib.h +++ b/iprlib.h @@ -1727,6 +1727,17 @@ struct sense_data_t { u8 add_sense_bytes[0]; }; +/* Structure for Descriptive Format Sense Data */ +struct df_sense_data_t { + u8 error_code; + u8 sense_key; + u8 add_sense_code; + u8 add_sense_code_qual; + u8 rfield; + u8 rsrvd[2]; + u8 add_sense_len; +}; + struct ipr_ioa_mode_page { struct ipr_mode_page_hdr hdr; u8 reserved; -- 1.8.3.1 _______________________________________________ Iprdd-devel mailing list Iprdd-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/iprdd-devel