• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
scsi_device_type(unsigned type)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 
scsi_pr_type_to_block(enum scsi_pr_type type)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 
block_pr_type_to_scsi(enum pr_type type)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  */
scsilun_to_int(struct scsi_lun * scsilun)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  */
int_to_scsilun(u64 lun,struct scsi_lun * scsilun)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  */
scsi_normalize_sense(const u8 * sense_buffer,int sb_len,struct scsi_sense_hdr * sshdr)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  */
scsi_sense_desc_find(const u8 * sense_buffer,int sb_len,int desc_type)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  **/
scsi_build_sense_buffer(int desc,u8 * buf,u8 key,u8 asc,u8 ascq)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  **/
scsi_set_sense_information(u8 * buf,int buf_len,u64 info)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  */
scsi_set_sense_field_pointer(u8 * buf,int buf_len,u16 fp,u8 bp,bool cd)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);
401