2.6.27 kernel compat patch
[open-iscsi.git] / usr / scsi.c
blob14767e21e65064a6552a858af1e4aa685051dcee
1 /*
2 * The following is from the linux kernel scsi_error.c
4 * scsi_error.c Copyright (C) 1997 Eric Youngdale
6 * SCSI error/timeout handling
7 * Initial versions: Eric Youngdale. Based upon conversations with
8 * Leonard Zubkoff and David Miller at Linux Expo,
9 * ideas originating from all over the place.
11 * Restructured scsi_unjam_host and associated functions.
12 * September 04, 2002 Mike Anderson (andmike@us.ibm.com)
14 * Forward port of Russell King's (rmk@arm.linux.org.uk) changes and
15 * minor cleanups.
16 * September 30, 2002 Mike Anderson (andmike@us.ibm.com)
19 #include <string.h>
20 #include "scsi.h"
22 /**
23 * scsi_normalize_sense - normalize main elements from either fixed or
24 * descriptor sense data format into a common format.
26 * @sense_buffer: byte array containing sense data returned by device
27 * @sb_len: number of valid bytes in sense_buffer
28 * @sshdr: pointer to instance of structure that common
29 * elements are written to.
31 * Notes:
32 * The "main elements" from sense data are: response_code, sense_key,
33 * asc, ascq and additional_length (only for descriptor format).
35 * Typically this function can be called after a device has
36 * responded to a SCSI command with the CHECK_CONDITION status.
38 * Return value:
39 * 1 if valid sense data information found, else 0;
40 **/
41 int scsi_normalize_sense(const uint8_t *sense_buffer, int sb_len,
42 struct scsi_sense_hdr *sshdr)
44 if (!sense_buffer || !sb_len)
45 return 0;
47 memset(sshdr, 0, sizeof(struct scsi_sense_hdr));
49 sshdr->response_code = (sense_buffer[0] & 0x7f);
51 if (!scsi_sense_valid(sshdr))
52 return 0;
54 if (sshdr->response_code >= 0x72) {
56 * descriptor format
58 if (sb_len > 1)
59 sshdr->sense_key = (sense_buffer[1] & 0xf);
60 if (sb_len > 2)
61 sshdr->asc = sense_buffer[2];
62 if (sb_len > 3)
63 sshdr->ascq = sense_buffer[3];
64 if (sb_len > 7)
65 sshdr->additional_length = sense_buffer[7];
66 } else {
67 /*
68 * fixed format
70 if (sb_len > 2)
71 sshdr->sense_key = (sense_buffer[2] & 0xf);
72 if (sb_len > 7) {
73 sb_len = (sb_len < (sense_buffer[7] + 8)) ?
74 sb_len : (sense_buffer[7] + 8);
75 if (sb_len > 12)
76 sshdr->asc = sense_buffer[12];
77 if (sb_len > 13)
78 sshdr->ascq = sense_buffer[13];
82 return 1;