GNU Linux-libre 6.8.9-gnu
[releases.git] / drivers / scsi / scsi_common.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * SCSI functions used by both the initiator and the target code.
4  */
5
6 #include <linux/bug.h>
7 #include <linux/kernel.h>
8 #include <linux/string.h>
9 #include <linux/errno.h>
10 #include <linux/module.h>
11 #include <uapi/linux/pr.h>
12 #include <asm/unaligned.h>
13 #include <scsi/scsi_common.h>
14
15 MODULE_LICENSE("GPL v2");
16
17 /* Command group 3 is reserved and should never be used.  */
18 const unsigned char scsi_command_size_tbl[8] = {
19         6, 10, 10, 12, 16, 12, 10, 10
20 };
21 EXPORT_SYMBOL(scsi_command_size_tbl);
22
23 /* NB: These are exposed through /proc/scsi/scsi and form part of the ABI.
24  * You may not alter any existing entry (although adding new ones is
25  * encouraged once assigned by ANSI/INCITS T10).
26  */
27 static const char *const scsi_device_types[] = {
28         "Direct-Access    ",
29         "Sequential-Access",
30         "Printer          ",
31         "Processor        ",
32         "WORM             ",
33         "CD-ROM           ",
34         "Scanner          ",
35         "Optical Device   ",
36         "Medium Changer   ",
37         "Communications   ",
38         "ASC IT8          ",
39         "ASC IT8          ",
40         "RAID             ",
41         "Enclosure        ",
42         "Direct-Access-RBC",
43         "Optical card     ",
44         "Bridge controller",
45         "Object storage   ",
46         "Automation/Drive ",
47         "Security Manager ",
48         "Direct-Access-ZBC",
49 };
50
51 /**
52  * scsi_device_type - Return 17-char string indicating device type.
53  * @type: type number to look up
54  */
55 const char *scsi_device_type(unsigned type)
56 {
57         if (type == 0x1e)
58                 return "Well-known LUN   ";
59         if (type == 0x1f)
60                 return "No Device        ";
61         if (type >= ARRAY_SIZE(scsi_device_types))
62                 return "Unknown          ";
63         return scsi_device_types[type];
64 }
65 EXPORT_SYMBOL(scsi_device_type);
66
67 enum pr_type scsi_pr_type_to_block(enum scsi_pr_type type)
68 {
69         switch (type) {
70         case SCSI_PR_WRITE_EXCLUSIVE:
71                 return PR_WRITE_EXCLUSIVE;
72         case SCSI_PR_EXCLUSIVE_ACCESS:
73                 return PR_EXCLUSIVE_ACCESS;
74         case SCSI_PR_WRITE_EXCLUSIVE_REG_ONLY:
75                 return PR_WRITE_EXCLUSIVE_REG_ONLY;
76         case SCSI_PR_EXCLUSIVE_ACCESS_REG_ONLY:
77                 return PR_EXCLUSIVE_ACCESS_REG_ONLY;
78         case SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS:
79                 return PR_WRITE_EXCLUSIVE_ALL_REGS;
80         case SCSI_PR_EXCLUSIVE_ACCESS_ALL_REGS:
81                 return PR_EXCLUSIVE_ACCESS_ALL_REGS;
82         }
83
84         return 0;
85 }
86 EXPORT_SYMBOL_GPL(scsi_pr_type_to_block);
87
88 enum scsi_pr_type block_pr_type_to_scsi(enum pr_type type)
89 {
90         switch (type) {
91         case PR_WRITE_EXCLUSIVE:
92                 return SCSI_PR_WRITE_EXCLUSIVE;
93         case PR_EXCLUSIVE_ACCESS:
94                 return SCSI_PR_EXCLUSIVE_ACCESS;
95         case PR_WRITE_EXCLUSIVE_REG_ONLY:
96                 return SCSI_PR_WRITE_EXCLUSIVE_REG_ONLY;
97         case PR_EXCLUSIVE_ACCESS_REG_ONLY:
98                 return SCSI_PR_EXCLUSIVE_ACCESS_REG_ONLY;
99         case PR_WRITE_EXCLUSIVE_ALL_REGS:
100                 return SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS;
101         case PR_EXCLUSIVE_ACCESS_ALL_REGS:
102                 return SCSI_PR_EXCLUSIVE_ACCESS_ALL_REGS;
103         }
104
105         return 0;
106 }
107 EXPORT_SYMBOL_GPL(block_pr_type_to_scsi);
108
109 /**
110  * scsilun_to_int - convert a scsi_lun to an int
111  * @scsilun:    struct scsi_lun to be converted.
112  *
113  * Description:
114  *     Convert @scsilun from a struct scsi_lun to a four-byte host byte-ordered
115  *     integer, and return the result. The caller must check for
116  *     truncation before using this function.
117  *
118  * Notes:
119  *     For a description of the LUN format, post SCSI-3 see the SCSI
120  *     Architecture Model, for SCSI-3 see the SCSI Controller Commands.
121  *
122  *     Given a struct scsi_lun of: d2 04 0b 03 00 00 00 00, this function
123  *     returns the integer: 0x0b03d204
124  *
125  *     This encoding will return a standard integer LUN for LUNs smaller
126  *     than 256, which typically use a single level LUN structure with
127  *     addressing method 0.
128  */
129 u64 scsilun_to_int(struct scsi_lun *scsilun)
130 {
131         int i;
132         u64 lun;
133
134         lun = 0;
135         for (i = 0; i < sizeof(lun); i += 2)
136                 lun = lun | (((u64)scsilun->scsi_lun[i] << ((i + 1) * 8)) |
137                              ((u64)scsilun->scsi_lun[i + 1] << (i * 8)));
138         return lun;
139 }
140 EXPORT_SYMBOL(scsilun_to_int);
141
142 /**
143  * int_to_scsilun - reverts an int into a scsi_lun
144  * @lun:        integer to be reverted
145  * @scsilun:    struct scsi_lun to be set.
146  *
147  * Description:
148  *     Reverts the functionality of the scsilun_to_int, which packed
149  *     an 8-byte lun value into an int. This routine unpacks the int
150  *     back into the lun value.
151  *
152  * Notes:
153  *     Given an integer : 0x0b03d204, this function returns a
154  *     struct scsi_lun of: d2 04 0b 03 00 00 00 00
155  *
156  */
157 void int_to_scsilun(u64 lun, struct scsi_lun *scsilun)
158 {
159         int i;
160
161         memset(scsilun->scsi_lun, 0, sizeof(scsilun->scsi_lun));
162
163         for (i = 0; i < sizeof(lun); i += 2) {
164                 scsilun->scsi_lun[i] = (lun >> 8) & 0xFF;
165                 scsilun->scsi_lun[i+1] = lun & 0xFF;
166                 lun = lun >> 16;
167         }
168 }
169 EXPORT_SYMBOL(int_to_scsilun);
170
171 /**
172  * scsi_normalize_sense - normalize main elements from either fixed or
173  *                      descriptor sense data format into a common format.
174  *
175  * @sense_buffer:       byte array containing sense data returned by device
176  * @sb_len:             number of valid bytes in sense_buffer
177  * @sshdr:              pointer to instance of structure that common
178  *                      elements are written to.
179  *
180  * Notes:
181  *      The "main elements" from sense data are: response_code, sense_key,
182  *      asc, ascq and additional_length (only for descriptor format).
183  *
184  *      Typically this function can be called after a device has
185  *      responded to a SCSI command with the CHECK_CONDITION status.
186  *
187  * Return value:
188  *      true if valid sense data information found, else false;
189  */
190 bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len,
191                           struct scsi_sense_hdr *sshdr)
192 {
193         memset(sshdr, 0, sizeof(struct scsi_sense_hdr));
194
195         if (!sense_buffer || !sb_len)
196                 return false;
197
198         sshdr->response_code = (sense_buffer[0] & 0x7f);
199
200         if (!scsi_sense_valid(sshdr))
201                 return false;
202
203         if (sshdr->response_code >= 0x72) {
204                 /*
205                  * descriptor format
206                  */
207                 if (sb_len > 1)
208                         sshdr->sense_key = (sense_buffer[1] & 0xf);
209                 if (sb_len > 2)
210                         sshdr->asc = sense_buffer[2];
211                 if (sb_len > 3)
212                         sshdr->ascq = sense_buffer[3];
213                 if (sb_len > 7)
214                         sshdr->additional_length = sense_buffer[7];
215         } else {
216                 /*
217                  * fixed format
218                  */
219                 if (sb_len > 2)
220                         sshdr->sense_key = (sense_buffer[2] & 0xf);
221                 if (sb_len > 7) {
222                         sb_len = min(sb_len, sense_buffer[7] + 8);
223                         if (sb_len > 12)
224                                 sshdr->asc = sense_buffer[12];
225                         if (sb_len > 13)
226                                 sshdr->ascq = sense_buffer[13];
227                 }
228         }
229
230         return true;
231 }
232 EXPORT_SYMBOL(scsi_normalize_sense);
233
234 /**
235  * scsi_sense_desc_find - search for a given descriptor type in descriptor sense data format.
236  * @sense_buffer:       byte array of descriptor format sense data
237  * @sb_len:             number of valid bytes in sense_buffer
238  * @desc_type:          value of descriptor type to find
239  *                      (e.g. 0 -> information)
240  *
241  * Notes:
242  *      only valid when sense data is in descriptor format
243  *
244  * Return value:
245  *      pointer to start of (first) descriptor if found else NULL
246  */
247 const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len,
248                                 int desc_type)
249 {
250         int add_sen_len, add_len, desc_len, k;
251         const u8 * descp;
252
253         if ((sb_len < 8) || (0 == (add_sen_len = sense_buffer[7])))
254                 return NULL;
255         if ((sense_buffer[0] < 0x72) || (sense_buffer[0] > 0x73))
256                 return NULL;
257         add_sen_len = (add_sen_len < (sb_len - 8)) ?
258                         add_sen_len : (sb_len - 8);
259         descp = &sense_buffer[8];
260         for (desc_len = 0, k = 0; k < add_sen_len; k += desc_len) {
261                 descp += desc_len;
262                 add_len = (k < (add_sen_len - 1)) ? descp[1]: -1;
263                 desc_len = add_len + 2;
264                 if (descp[0] == desc_type)
265                         return descp;
266                 if (add_len < 0) // short descriptor ??
267                         break;
268         }
269         return NULL;
270 }
271 EXPORT_SYMBOL(scsi_sense_desc_find);
272
273 /**
274  * scsi_build_sense_buffer - build sense data in a buffer
275  * @desc:       Sense format (non-zero == descriptor format,
276  *              0 == fixed format)
277  * @buf:        Where to build sense data
278  * @key:        Sense key
279  * @asc:        Additional sense code
280  * @ascq:       Additional sense code qualifier
281  *
282  **/
283 void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq)
284 {
285         if (desc) {
286                 buf[0] = 0x72;  /* descriptor, current */
287                 buf[1] = key;
288                 buf[2] = asc;
289                 buf[3] = ascq;
290                 buf[7] = 0;
291         } else {
292                 buf[0] = 0x70;  /* fixed, current */
293                 buf[2] = key;
294                 buf[7] = 0xa;
295                 buf[12] = asc;
296                 buf[13] = ascq;
297         }
298 }
299 EXPORT_SYMBOL(scsi_build_sense_buffer);
300
301 /**
302  * scsi_set_sense_information - set the information field in a
303  *              formatted sense data buffer
304  * @buf:        Where to build sense data
305  * @buf_len:    buffer length
306  * @info:       64-bit information value to be set
307  *
308  * Return value:
309  *      0 on success or -EINVAL for invalid sense buffer length
310  **/
311 int scsi_set_sense_information(u8 *buf, int buf_len, u64 info)
312 {
313         if ((buf[0] & 0x7f) == 0x72) {
314                 u8 *ucp, len;
315
316                 len = buf[7];
317                 ucp = (char *)scsi_sense_desc_find(buf, len + 8, 0);
318                 if (!ucp) {
319                         buf[7] = len + 0xc;
320                         ucp = buf + 8 + len;
321                 }
322
323                 if (buf_len < len + 0xc)
324                         /* Not enough room for info */
325                         return -EINVAL;
326
327                 ucp[0] = 0;
328                 ucp[1] = 0xa;
329                 ucp[2] = 0x80; /* Valid bit */
330                 ucp[3] = 0;
331                 put_unaligned_be64(info, &ucp[4]);
332         } else if ((buf[0] & 0x7f) == 0x70) {
333                 /*
334                  * Only set the 'VALID' bit if we can represent the value
335                  * correctly; otherwise just fill out the lower bytes and
336                  * clear the 'VALID' flag.
337                  */
338                 if (info <= 0xffffffffUL)
339                         buf[0] |= 0x80;
340                 else
341                         buf[0] &= 0x7f;
342                 put_unaligned_be32((u32)info, &buf[3]);
343         }
344
345         return 0;
346 }
347 EXPORT_SYMBOL(scsi_set_sense_information);
348
349 /**
350  * scsi_set_sense_field_pointer - set the field pointer sense key
351  *              specific information in a formatted sense data buffer
352  * @buf:        Where to build sense data
353  * @buf_len:    buffer length
354  * @fp:         field pointer to be set
355  * @bp:         bit pointer to be set
356  * @cd:         command/data bit
357  *
358  * Return value:
359  *      0 on success or -EINVAL for invalid sense buffer length
360  */
361 int scsi_set_sense_field_pointer(u8 *buf, int buf_len, u16 fp, u8 bp, bool cd)
362 {
363         u8 *ucp, len;
364
365         if ((buf[0] & 0x7f) == 0x72) {
366                 len = buf[7];
367                 ucp = (char *)scsi_sense_desc_find(buf, len + 8, 2);
368                 if (!ucp) {
369                         buf[7] = len + 8;
370                         ucp = buf + 8 + len;
371                 }
372
373                 if (buf_len < len + 8)
374                         /* Not enough room for info */
375                         return -EINVAL;
376
377                 ucp[0] = 2;
378                 ucp[1] = 6;
379                 ucp[4] = 0x80; /* Valid bit */
380                 if (cd)
381                         ucp[4] |= 0x40;
382                 if (bp < 0x8)
383                         ucp[4] |= 0x8 | bp;
384                 put_unaligned_be16(fp, &ucp[5]);
385         } else if ((buf[0] & 0x7f) == 0x70) {
386                 len = buf[7];
387                 if (len < 18)
388                         buf[7] = 18;
389
390                 buf[15] = 0x80;
391                 if (cd)
392                         buf[15] |= 0x40;
393                 if (bp < 0x8)
394                         buf[15] |= 0x8 | bp;
395                 put_unaligned_be16(fp, &buf[16]);
396         }
397
398         return 0;
399 }
400 EXPORT_SYMBOL(scsi_set_sense_field_pointer);