diff options
author | Ingo Molnar <[email protected]> | 2016-06-08 09:26:46 +0200 |
---|---|---|
committer | Ingo Molnar <[email protected]> | 2016-06-08 09:26:46 +0200 |
commit | 616d1c1b98ac79f30216a57a170dd7cea19b3df3 (patch) | |
tree | 6f244c2e5a7160190e73bc82b4cd7fa7bb22ee31 /drivers/scsi/scsi_common.c | |
parent | a4f144ebbdf6f7807c477bce8e136047ed27321f (diff) | |
parent | c8ae067f2635be0f8c7e5db1bb74b757d623e05b (diff) |
Merge branch 'linus' into perf/core, to refresh the branch
Signed-off-by: Ingo Molnar <[email protected]>
Diffstat (limited to 'drivers/scsi/scsi_common.c')
-rw-r--r-- | drivers/scsi/scsi_common.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_common.c b/drivers/scsi/scsi_common.c index ce79de822e46..b1383a71400e 100644 --- a/drivers/scsi/scsi_common.c +++ b/drivers/scsi/scsi_common.c @@ -293,3 +293,56 @@ int scsi_set_sense_information(u8 *buf, int buf_len, u64 info) return 0; } EXPORT_SYMBOL(scsi_set_sense_information); + +/** + * scsi_set_sense_field_pointer - set the field pointer sense key + * specific information in a formatted sense data buffer + * @buf: Where to build sense data + * @buf_len: buffer length + * @fp: field pointer to be set + * @bp: bit pointer to be set + * @cd: command/data bit + * + * Return value: + * 0 on success or EINVAL for invalid sense buffer length + */ +int scsi_set_sense_field_pointer(u8 *buf, int buf_len, u16 fp, u8 bp, bool cd) +{ + u8 *ucp, len; + + if ((buf[0] & 0x7f) == 0x72) { + len = buf[7]; + ucp = (char *)scsi_sense_desc_find(buf, len + 8, 2); + if (!ucp) { + buf[7] = len + 8; + ucp = buf + 8 + len; + } + + if (buf_len < len + 8) + /* Not enough room for info */ + return -EINVAL; + + ucp[0] = 2; + ucp[1] = 6; + ucp[4] = 0x80; /* Valid bit */ + if (cd) + ucp[4] |= 0x40; + if (bp < 0x8) + ucp[4] |= 0x8 | bp; + put_unaligned_be16(fp, &ucp[5]); + } else if ((buf[0] & 0x7f) == 0x70) { + len = buf[7]; + if (len < 18) + buf[7] = 18; + + buf[15] = 0x80; + if (cd) + buf[15] |= 0x40; + if (bp < 0x8) + buf[15] |= 0x8 | bp; + put_unaligned_be16(fp, &buf[16]); + } + + return 0; +} +EXPORT_SYMBOL(scsi_set_sense_field_pointer); |