Blame view

drivers/target/target_core_cdb.c 34.6 KB
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  /*
   * CDB emulation for non-READ/WRITE commands.
   *
   * Copyright (c) 2002, 2003, 2004, 2005 PyX Technologies, Inc.
   * Copyright (c) 2005, 2006, 2007 SBE, Inc.
   * Copyright (c) 2007-2010 Rising Tide Systems
   * Copyright (c) 2008-2010 Linux-iSCSI.org
   *
   * Nicholas A. Bellinger <nab@kernel.org>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   */
11650b859   Andy Shevchenko   target: remove cu...
25
  #include <linux/kernel.h>
c9abb9bb0   Nicholas Bellinger   target: Fix compi...
26
  #include <linux/module.h>
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
27
28
29
30
31
32
33
  #include <asm/unaligned.h>
  #include <scsi/scsi.h>
  
  #include <target/target_core_base.h>
  #include <target/target_core_transport.h>
  #include <target/target_core_fabric_ops.h>
  #include "target_core_ua.h"
5bda90c8f   Christoph Hellwig   target: use ->exe...
34
  #include "target_core_cdb.h"
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
  
  static void
  target_fill_alua_data(struct se_port *port, unsigned char *buf)
  {
  	struct t10_alua_tg_pt_gp *tg_pt_gp;
  	struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
  
  	/*
  	 * Set SCCS for MAINTENANCE_IN + REPORT_TARGET_PORT_GROUPS.
  	 */
  	buf[5]	= 0x80;
  
  	/*
  	 * Set TPGS field for explict and/or implict ALUA access type
  	 * and opteration.
  	 *
  	 * See spc4r17 section 6.4.2 Table 135
  	 */
  	if (!port)
  		return;
  	tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
  	if (!tg_pt_gp_mem)
  		return;
  
  	spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
  	tg_pt_gp = tg_pt_gp_mem->tg_pt_gp;
  	if (tg_pt_gp)
  		buf[5] |= tg_pt_gp->tg_pt_gp_alua_access_type;
  	spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
  }
  
  static int
  target_emulate_inquiry_std(struct se_cmd *cmd)
  {
e3d6f909e   Andy Grover   target: Core clea...
69
  	struct se_lun *lun = cmd->se_lun;
5951146de   Andy Grover   target: More core...
70
  	struct se_device *dev = cmd->se_dev;
052605c6c   Nicholas Bellinger   target: Make stan...
71
  	struct se_portal_group *tpg = lun->lun_sep->sep_tpg;
05d1c7c0d   Andy Grover   target: Make all ...
72
  	unsigned char *buf;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
73
74
75
76
77
78
  
  	/*
  	 * Make sure we at least have 6 bytes of INQUIRY response
  	 * payload going back for EVPD=0
  	 */
  	if (cmd->data_length < 6) {
6708bb27b   Andy Grover   target: Follow up...
79
  		pr_err("SCSI Inquiry payload length: %u"
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
80
81
  			" too small for EVPD=0
  ", cmd->data_length);
e3d6f909e   Andy Grover   target: Core clea...
82
  		return -EINVAL;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
83
  	}
05d1c7c0d   Andy Grover   target: Make all ...
84
  	buf = transport_kmap_first_data_page(cmd);
052605c6c   Nicholas Bellinger   target: Make stan...
85
86
87
88
89
90
91
  	if (dev == tpg->tpg_virt_lun0.lun_se_dev) {
  		buf[0] = 0x3f; /* Not connected */
  	} else {
  		buf[0] = dev->transport->get_device_type(dev);
  		if (buf[0] == TYPE_TAPE)
  			buf[1] = 0x80;
  	}
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
92
93
94
95
96
  	buf[2] = dev->transport->get_device_rev(dev);
  
  	/*
  	 * Enable SCCS and TPGS fields for Emulated ALUA
  	 */
e3d6f909e   Andy Grover   target: Core clea...
97
  	if (dev->se_sub_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
98
99
100
101
  		target_fill_alua_data(lun->lun_sep, buf);
  
  	if (cmd->data_length < 8) {
  		buf[4] = 1; /* Set additional length to 1 */
05d1c7c0d   Andy Grover   target: Make all ...
102
  		goto out;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
103
104
105
106
107
108
109
110
111
112
  	}
  
  	buf[7] = 0x32; /* Sync=1 and CmdQue=1 */
  
  	/*
  	 * Do not include vendor, product, reversion info in INQUIRY
  	 * response payload for cdbs with a small allocation length.
  	 */
  	if (cmd->data_length < 36) {
  		buf[4] = 3; /* Set additional length to 3 */
05d1c7c0d   Andy Grover   target: Make all ...
113
  		goto out;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
114
115
116
117
  	}
  
  	snprintf((unsigned char *)&buf[8], 8, "LIO-ORG");
  	snprintf((unsigned char *)&buf[16], 16, "%s",
e3d6f909e   Andy Grover   target: Core clea...
118
  		 &dev->se_sub_dev->t10_wwn.model[0]);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
119
  	snprintf((unsigned char *)&buf[32], 4, "%s",
e3d6f909e   Andy Grover   target: Core clea...
120
  		 &dev->se_sub_dev->t10_wwn.revision[0]);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
121
  	buf[4] = 31; /* Set additional length to 31 */
05d1c7c0d   Andy Grover   target: Make all ...
122
123
124
  
  out:
  	transport_kunmap_first_data_page(cmd);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
125
126
  	return 0;
  }
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
127
128
129
130
  /* unit serial number */
  static int
  target_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf)
  {
5951146de   Andy Grover   target: More core...
131
  	struct se_device *dev = cmd->se_dev;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
132
  	u16 len = 0;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
133
134
135
136
137
  	if (dev->se_sub_dev->su_dev_flags &
  			SDF_EMULATED_VPD_UNIT_SERIAL) {
  		u32 unit_serial_len;
  
  		unit_serial_len =
e3d6f909e   Andy Grover   target: Core clea...
138
  			strlen(&dev->se_sub_dev->t10_wwn.unit_serial[0]);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
139
140
141
142
143
144
145
146
147
  		unit_serial_len++; /* For NULL Terminator */
  
  		if (((len + 4) + unit_serial_len) > cmd->data_length) {
  			len += unit_serial_len;
  			buf[2] = ((len >> 8) & 0xff);
  			buf[3] = (len & 0xff);
  			return 0;
  		}
  		len += sprintf((unsigned char *)&buf[4], "%s",
e3d6f909e   Andy Grover   target: Core clea...
148
  			&dev->se_sub_dev->t10_wwn.unit_serial[0]);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
149
150
151
152
153
  		len++; /* Extra Byte for NULL Terminator */
  		buf[3] = len;
  	}
  	return 0;
  }
784eb99eb   Nicholas Bellinger   target: Skip non ...
154
  static void
b6b4e61ff   Andy Shevchenko   target: simplify ...
155
  target_parse_naa_6h_vendor_specific(struct se_device *dev, unsigned char *buf)
784eb99eb   Nicholas Bellinger   target: Skip non ...
156
157
  {
  	unsigned char *p = &dev->se_sub_dev->t10_wwn.unit_serial[0];
b6b4e61ff   Andy Shevchenko   target: simplify ...
158
159
  	int cnt;
  	bool next = true;
784eb99eb   Nicholas Bellinger   target: Skip non ...
160
161
162
163
164
165
166
167
  	/*
  	 * Generate up to 36 bits of VENDOR SPECIFIC IDENTIFIER starting on
  	 * byte 3 bit 3-0 for NAA IEEE Registered Extended DESIGNATOR field
  	 * format, followed by 64 bits of VENDOR SPECIFIC IDENTIFIER EXTENSION
  	 * to complete the payload.  These are based from VPD=0x80 PRODUCT SERIAL
  	 * NUMBER set via vpd_unit_serial in target_core_configfs.c to ensure
  	 * per device uniqeness.
  	 */
b6b4e61ff   Andy Shevchenko   target: simplify ...
168
169
170
171
  	for (cnt = 0; *p && cnt < 13; p++) {
  		int val = hex_to_bin(*p);
  
  		if (val < 0)
784eb99eb   Nicholas Bellinger   target: Skip non ...
172
  			continue;
b6b4e61ff   Andy Shevchenko   target: simplify ...
173
174
175
176
  
  		if (next) {
  			next = false;
  			buf[cnt++] |= val;
784eb99eb   Nicholas Bellinger   target: Skip non ...
177
  		} else {
b6b4e61ff   Andy Shevchenko   target: simplify ...
178
179
  			next = true;
  			buf[cnt] = val << 4;
784eb99eb   Nicholas Bellinger   target: Skip non ...
180
181
182
  		}
  	}
  }
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
183
184
185
186
187
188
189
  /*
   * Device identification VPD, for a complete list of
   * DESIGNATOR TYPEs see spc4r17 Table 459.
   */
  static int
  target_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf)
  {
5951146de   Andy Grover   target: More core...
190
  	struct se_device *dev = cmd->se_dev;
e3d6f909e   Andy Grover   target: Core clea...
191
  	struct se_lun *lun = cmd->se_lun;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
192
193
194
195
196
  	struct se_port *port = NULL;
  	struct se_portal_group *tpg = NULL;
  	struct t10_alua_lu_gp_member *lu_gp_mem;
  	struct t10_alua_tg_pt_gp *tg_pt_gp;
  	struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
e3d6f909e   Andy Grover   target: Core clea...
197
  	unsigned char *prod = &dev->se_sub_dev->t10_wwn.model[0];
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
198
199
  	u32 prod_len;
  	u32 unit_serial_len, off = 0;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
200
  	u16 len = 0, id_len;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
  	off = 4;
  
  	/*
  	 * NAA IEEE Registered Extended Assigned designator format, see
  	 * spc4r17 section 7.7.3.6.5
  	 *
  	 * We depend upon a target_core_mod/ConfigFS provided
  	 * /sys/kernel/config/target/core/$HBA/$DEV/wwn/vpd_unit_serial
  	 * value in order to return the NAA id.
  	 */
  	if (!(dev->se_sub_dev->su_dev_flags & SDF_EMULATED_VPD_UNIT_SERIAL))
  		goto check_t10_vend_desc;
  
  	if (off + 20 > cmd->data_length)
  		goto check_t10_vend_desc;
  
  	/* CODE SET == Binary */
  	buf[off++] = 0x1;
163cd5fa9   Andy Shevchenko   target: fix typo ...
219
  	/* Set ASSOCIATION == addressed logical unit: 0)b */
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
220
221
222
  	buf[off] = 0x00;
  
  	/* Identifier/Designator type == NAA identifier */
163cd5fa9   Andy Shevchenko   target: fix typo ...
223
  	buf[off++] |= 0x3;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
  	off++;
  
  	/* Identifier/Designator length */
  	buf[off++] = 0x10;
  
  	/*
  	 * Start NAA IEEE Registered Extended Identifier/Designator
  	 */
  	buf[off++] = (0x6 << 4);
  
  	/*
  	 * Use OpenFabrics IEEE Company ID: 00 14 05
  	 */
  	buf[off++] = 0x01;
  	buf[off++] = 0x40;
  	buf[off] = (0x5 << 4);
  
  	/*
  	 * Return ConfigFS Unit Serial Number information for
  	 * VENDOR_SPECIFIC_IDENTIFIER and
  	 * VENDOR_SPECIFIC_IDENTIFIER_EXTENTION
  	 */
784eb99eb   Nicholas Bellinger   target: Skip non ...
246
  	target_parse_naa_6h_vendor_specific(dev, &buf[off]);
11650b859   Andy Shevchenko   target: remove cu...
247

c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
  	len = 20;
  	off = (len + 4);
  
  check_t10_vend_desc:
  	/*
  	 * T10 Vendor Identifier Page, see spc4r17 section 7.7.3.4
  	 */
  	id_len = 8; /* For Vendor field */
  	prod_len = 4; /* For VPD Header */
  	prod_len += 8; /* For Vendor field */
  	prod_len += strlen(prod);
  	prod_len++; /* For : */
  
  	if (dev->se_sub_dev->su_dev_flags &
  			SDF_EMULATED_VPD_UNIT_SERIAL) {
  		unit_serial_len =
e3d6f909e   Andy Grover   target: Core clea...
264
  			strlen(&dev->se_sub_dev->t10_wwn.unit_serial[0]);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
265
266
267
268
269
270
271
272
273
274
  		unit_serial_len++; /* For NULL Terminator */
  
  		if ((len + (id_len + 4) +
  		    (prod_len + unit_serial_len)) >
  				cmd->data_length) {
  			len += (prod_len + unit_serial_len);
  			goto check_port;
  		}
  		id_len += sprintf((unsigned char *)&buf[off+12],
  				"%s:%s", prod,
e3d6f909e   Andy Grover   target: Core clea...
275
  				&dev->se_sub_dev->t10_wwn.unit_serial[0]);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
  	}
  	buf[off] = 0x2; /* ASCII */
  	buf[off+1] = 0x1; /* T10 Vendor ID */
  	buf[off+2] = 0x0;
  	memcpy((unsigned char *)&buf[off+4], "LIO-ORG", 8);
  	/* Extra Byte for NULL Terminator */
  	id_len++;
  	/* Identifier Length */
  	buf[off+3] = id_len;
  	/* Header size for Designation descriptor */
  	len += (id_len + 4);
  	off += (id_len + 4);
  	/*
  	 * struct se_port is only set for INQUIRY VPD=1 through $FABRIC_MOD
  	 */
  check_port:
  	port = lun->lun_sep;
  	if (port) {
  		struct t10_alua_lu_gp *lu_gp;
  		u32 padding, scsi_name_len;
  		u16 lu_gp_id = 0;
  		u16 tg_pt_gp_id = 0;
  		u16 tpgt;
  
  		tpg = port->sep_tpg;
  		/*
  		 * Relative target port identifer, see spc4r17
  		 * section 7.7.3.7
  		 *
  		 * Get the PROTOCOL IDENTIFIER as defined by spc4r17
  		 * section 7.5.1 Table 362
  		 */
  		if (((len + 4) + 8) > cmd->data_length) {
  			len += 8;
  			goto check_tpgi;
  		}
  		buf[off] =
e3d6f909e   Andy Grover   target: Core clea...
313
  			(tpg->se_tpg_tfo->get_fabric_proto_ident(tpg) << 4);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
314
315
  		buf[off++] |= 0x1; /* CODE SET == Binary */
  		buf[off] = 0x80; /* Set PIV=1 */
163cd5fa9   Andy Shevchenko   target: fix typo ...
316
  		/* Set ASSOCIATION == target port: 01b */
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
  		buf[off] |= 0x10;
  		/* DESIGNATOR TYPE == Relative target port identifer */
  		buf[off++] |= 0x4;
  		off++; /* Skip over Reserved */
  		buf[off++] = 4; /* DESIGNATOR LENGTH */
  		/* Skip over Obsolete field in RTPI payload
  		 * in Table 472 */
  		off += 2;
  		buf[off++] = ((port->sep_rtpi >> 8) & 0xff);
  		buf[off++] = (port->sep_rtpi & 0xff);
  		len += 8; /* Header size + Designation descriptor */
  		/*
  		 * Target port group identifier, see spc4r17
  		 * section 7.7.3.8
  		 *
  		 * Get the PROTOCOL IDENTIFIER as defined by spc4r17
  		 * section 7.5.1 Table 362
  		 */
  check_tpgi:
e3d6f909e   Andy Grover   target: Core clea...
336
  		if (dev->se_sub_dev->t10_alua.alua_type !=
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
337
338
339
340
341
342
343
344
345
346
347
348
349
  				SPC3_ALUA_EMULATED)
  			goto check_scsi_name;
  
  		if (((len + 4) + 8) > cmd->data_length) {
  			len += 8;
  			goto check_lu_gp;
  		}
  		tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
  		if (!tg_pt_gp_mem)
  			goto check_lu_gp;
  
  		spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
  		tg_pt_gp = tg_pt_gp_mem->tg_pt_gp;
6708bb27b   Andy Grover   target: Follow up...
350
  		if (!tg_pt_gp) {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
351
352
353
354
355
356
357
  			spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
  			goto check_lu_gp;
  		}
  		tg_pt_gp_id = tg_pt_gp->tg_pt_gp_id;
  		spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
  
  		buf[off] =
e3d6f909e   Andy Grover   target: Core clea...
358
  			(tpg->se_tpg_tfo->get_fabric_proto_ident(tpg) << 4);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
359
360
  		buf[off++] |= 0x1; /* CODE SET == Binary */
  		buf[off] = 0x80; /* Set PIV=1 */
163cd5fa9   Andy Shevchenko   target: fix typo ...
361
  		/* Set ASSOCIATION == target port: 01b */
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
  		buf[off] |= 0x10;
  		/* DESIGNATOR TYPE == Target port group identifier */
  		buf[off++] |= 0x5;
  		off++; /* Skip over Reserved */
  		buf[off++] = 4; /* DESIGNATOR LENGTH */
  		off += 2; /* Skip over Reserved Field */
  		buf[off++] = ((tg_pt_gp_id >> 8) & 0xff);
  		buf[off++] = (tg_pt_gp_id & 0xff);
  		len += 8; /* Header size + Designation descriptor */
  		/*
  		 * Logical Unit Group identifier, see spc4r17
  		 * section 7.7.3.8
  		 */
  check_lu_gp:
  		if (((len + 4) + 8) > cmd->data_length) {
  			len += 8;
  			goto check_scsi_name;
  		}
  		lu_gp_mem = dev->dev_alua_lu_gp_mem;
6708bb27b   Andy Grover   target: Follow up...
381
  		if (!lu_gp_mem)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
382
383
384
385
  			goto check_scsi_name;
  
  		spin_lock(&lu_gp_mem->lu_gp_mem_lock);
  		lu_gp = lu_gp_mem->lu_gp;
6708bb27b   Andy Grover   target: Follow up...
386
  		if (!lu_gp) {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
  			spin_unlock(&lu_gp_mem->lu_gp_mem_lock);
  			goto check_scsi_name;
  		}
  		lu_gp_id = lu_gp->lu_gp_id;
  		spin_unlock(&lu_gp_mem->lu_gp_mem_lock);
  
  		buf[off++] |= 0x1; /* CODE SET == Binary */
  		/* DESIGNATOR TYPE == Logical Unit Group identifier */
  		buf[off++] |= 0x6;
  		off++; /* Skip over Reserved */
  		buf[off++] = 4; /* DESIGNATOR LENGTH */
  		off += 2; /* Skip over Reserved Field */
  		buf[off++] = ((lu_gp_id >> 8) & 0xff);
  		buf[off++] = (lu_gp_id & 0xff);
  		len += 8; /* Header size + Designation descriptor */
  		/*
  		 * SCSI name string designator, see spc4r17
  		 * section 7.7.3.11
  		 *
  		 * Get the PROTOCOL IDENTIFIER as defined by spc4r17
  		 * section 7.5.1 Table 362
  		 */
  check_scsi_name:
e3d6f909e   Andy Grover   target: Core clea...
410
  		scsi_name_len = strlen(tpg->se_tpg_tfo->tpg_get_wwn(tpg));
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
411
412
413
414
415
416
417
418
419
420
421
422
423
424
  		/* UTF-8 ",t,0x<16-bit TPGT>" + NULL Terminator */
  		scsi_name_len += 10;
  		/* Check for 4-byte padding */
  		padding = ((-scsi_name_len) & 3);
  		if (padding != 0)
  			scsi_name_len += padding;
  		/* Header size + Designation descriptor */
  		scsi_name_len += 4;
  
  		if (((len + 4) + scsi_name_len) > cmd->data_length) {
  			len += scsi_name_len;
  			goto set_len;
  		}
  		buf[off] =
e3d6f909e   Andy Grover   target: Core clea...
425
  			(tpg->se_tpg_tfo->get_fabric_proto_ident(tpg) << 4);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
426
427
  		buf[off++] |= 0x3; /* CODE SET == UTF-8 */
  		buf[off] = 0x80; /* Set PIV=1 */
163cd5fa9   Andy Shevchenko   target: fix typo ...
428
  		/* Set ASSOCIATION == target port: 01b */
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
429
430
431
432
433
434
435
436
437
438
  		buf[off] |= 0x10;
  		/* DESIGNATOR TYPE == SCSI name string */
  		buf[off++] |= 0x8;
  		off += 2; /* Skip over Reserved and length */
  		/*
  		 * SCSI name string identifer containing, $FABRIC_MOD
  		 * dependent information.  For LIO-Target and iSCSI
  		 * Target Port, this means "<iSCSI name>,t,0x<TPGT> in
  		 * UTF-8 encoding.
  		 */
e3d6f909e   Andy Grover   target: Core clea...
439
  		tpgt = tpg->se_tpg_tfo->tpg_get_tag(tpg);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
440
  		scsi_name_len = sprintf(&buf[off], "%s,t,0x%04x",
e3d6f909e   Andy Grover   target: Core clea...
441
  					tpg->se_tpg_tfo->tpg_get_wwn(tpg), tpgt);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
  		scsi_name_len += 1 /* Include  NULL terminator */;
  		/*
  		 * The null-terminated, null-padded (see 4.4.2) SCSI
  		 * NAME STRING field contains a UTF-8 format string.
  		 * The number of bytes in the SCSI NAME STRING field
  		 * (i.e., the value in the DESIGNATOR LENGTH field)
  		 * shall be no larger than 256 and shall be a multiple
  		 * of four.
  		 */
  		if (padding)
  			scsi_name_len += padding;
  
  		buf[off-1] = scsi_name_len;
  		off += scsi_name_len;
  		/* Header size + Designation descriptor */
  		len += (scsi_name_len + 4);
  	}
  set_len:
  	buf[2] = ((len >> 8) & 0xff);
  	buf[3] = (len & 0xff); /* Page Length for VPD 0x83 */
  	return 0;
  }
  
  /* Extended INQUIRY Data VPD Page */
  static int
  target_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf)
  {
  	if (cmd->data_length < 60)
  		return 0;
1289a0571   Roland Dreier   target: Fix page ...
471
  	buf[3] = 0x3c;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
472
473
474
475
  	/* Set HEADSUP, ORDSUP, SIMPSUP */
  	buf[5] = 0x07;
  
  	/* If WriteCache emulation is enabled, set V_SUP */
5951146de   Andy Grover   target: More core...
476
  	if (cmd->se_dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
477
478
479
480
481
482
483
484
  		buf[6] = 0x01;
  	return 0;
  }
  
  /* Block Limits VPD page */
  static int
  target_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
  {
5951146de   Andy Grover   target: More core...
485
  	struct se_device *dev = cmd->se_dev;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
486
487
488
489
490
491
492
  	int have_tp = 0;
  
  	/*
  	 * Following sbc3r22 section 6.5.3 Block Limits VPD page, when
  	 * emulate_tpu=1 or emulate_tpws=1 we will be expect a
  	 * different page length for Thin Provisioning.
  	 */
e3d6f909e   Andy Grover   target: Core clea...
493
  	if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
494
495
496
  		have_tp = 1;
  
  	if (cmd->data_length < (0x10 + 4)) {
6708bb27b   Andy Grover   target: Follow up...
497
  		pr_debug("Received data_length: %u"
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
498
499
500
  			" too small for EVPD 0xb0
  ",
  			cmd->data_length);
e3d6f909e   Andy Grover   target: Core clea...
501
  		return -EINVAL;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
502
503
504
  	}
  
  	if (have_tp && cmd->data_length < (0x3c + 4)) {
6708bb27b   Andy Grover   target: Follow up...
505
  		pr_debug("Received data_length: %u"
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
506
507
508
509
510
511
512
  			" too small for TPE=1 EVPD 0xb0
  ",
  			cmd->data_length);
  		have_tp = 0;
  	}
  
  	buf[0] = dev->transport->get_device_type(dev);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
513
  	buf[3] = have_tp ? 0x3c : 0x10;
6708bb27b   Andy Grover   target: Follow up...
514
515
  	/* Set WSNZ to 1 */
  	buf[4] = 0x01;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
516
517
518
519
520
521
522
523
  	/*
  	 * Set OPTIMAL TRANSFER LENGTH GRANULARITY
  	 */
  	put_unaligned_be16(1, &buf[6]);
  
  	/*
  	 * Set MAXIMUM TRANSFER LENGTH
  	 */
e3d6f909e   Andy Grover   target: Core clea...
524
  	put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.max_sectors, &buf[8]);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
525
526
527
528
  
  	/*
  	 * Set OPTIMAL TRANSFER LENGTH
  	 */
e3d6f909e   Andy Grover   target: Core clea...
529
  	put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.optimal_sectors, &buf[12]);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
530
531
532
533
534
535
536
537
538
539
540
  
  	/*
  	 * Exit now if we don't support TP or the initiator sent a too
  	 * short buffer.
  	 */
  	if (!have_tp || cmd->data_length < (0x3c + 4))
  		return 0;
  
  	/*
  	 * Set MAXIMUM UNMAP LBA COUNT
  	 */
e3d6f909e   Andy Grover   target: Core clea...
541
  	put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.max_unmap_lba_count, &buf[20]);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
542
543
544
545
  
  	/*
  	 * Set MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT
  	 */
e3d6f909e   Andy Grover   target: Core clea...
546
  	put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count,
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
547
548
549
550
551
  			   &buf[24]);
  
  	/*
  	 * Set OPTIMAL UNMAP GRANULARITY
  	 */
e3d6f909e   Andy Grover   target: Core clea...
552
  	put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.unmap_granularity, &buf[28]);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
553
554
555
556
  
  	/*
  	 * UNMAP GRANULARITY ALIGNMENT
  	 */
e3d6f909e   Andy Grover   target: Core clea...
557
  	put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.unmap_granularity_alignment,
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
558
  			   &buf[32]);
e3d6f909e   Andy Grover   target: Core clea...
559
  	if (dev->se_sub_dev->se_dev_attrib.unmap_granularity_alignment != 0)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
560
561
562
563
  		buf[32] |= 0x80; /* Set the UGAVALID bit */
  
  	return 0;
  }
e22a7f075   Roland Dreier   target: Implement...
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
  /* Block Device Characteristics VPD page */
  static int
  target_emulate_evpd_b1(struct se_cmd *cmd, unsigned char *buf)
  {
  	struct se_device *dev = cmd->se_dev;
  
  	buf[0] = dev->transport->get_device_type(dev);
  	buf[3] = 0x3c;
  
  	if (cmd->data_length >= 5 &&
  	    dev->se_sub_dev->se_dev_attrib.is_nonrot)
  		buf[5] = 1;
  
  	return 0;
  }
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
579
580
581
582
  /* Thin Provisioning VPD */
  static int
  target_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf)
  {
5951146de   Andy Grover   target: More core...
583
  	struct se_device *dev = cmd->se_dev;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
584
585
586
587
588
589
590
591
592
593
  
  	/*
  	 * From sbc3r22 section 6.5.4 Thin Provisioning VPD page:
  	 *
  	 * The PAGE LENGTH field is defined in SPC-4. If the DP bit is set to
  	 * zero, then the page length shall be set to 0004h.  If the DP bit
  	 * is set to one, then the page length shall be set to the value
  	 * defined in table 162.
  	 */
  	buf[0] = dev->transport->get_device_type(dev);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
  
  	/*
  	 * Set Hardcoded length mentioned above for DP=0
  	 */
  	put_unaligned_be16(0x0004, &buf[2]);
  
  	/*
  	 * The THRESHOLD EXPONENT field indicates the threshold set size in
  	 * LBAs as a power of 2 (i.e., the threshold set size is equal to
  	 * 2(threshold exponent)).
  	 *
  	 * Note that this is currently set to 0x00 as mkp says it will be
  	 * changing again.  We can enable this once it has settled in T10
  	 * and is actually used by Linux/SCSI ML code.
  	 */
  	buf[4] = 0x00;
  
  	/*
  	 * A TPU bit set to one indicates that the device server supports
  	 * the UNMAP command (see 5.25). A TPU bit set to zero indicates
  	 * that the device server does not support the UNMAP command.
  	 */
e3d6f909e   Andy Grover   target: Core clea...
616
  	if (dev->se_sub_dev->se_dev_attrib.emulate_tpu != 0)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
617
618
619
620
621
622
623
624
  		buf[5] = 0x80;
  
  	/*
  	 * A TPWS bit set to one indicates that the device server supports
  	 * the use of the WRITE SAME (16) command (see 5.42) to unmap LBAs.
  	 * A TPWS bit set to zero indicates that the device server does not
  	 * support the use of the WRITE SAME (16) command to unmap LBAs.
  	 */
e3d6f909e   Andy Grover   target: Core clea...
625
  	if (dev->se_sub_dev->se_dev_attrib.emulate_tpws != 0)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
626
627
628
629
630
631
  		buf[5] |= 0x40;
  
  	return 0;
  }
  
  static int
b2eb705e0   Roland Dreier   target: Fix repor...
632
633
634
635
636
637
638
639
640
641
642
  target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf);
  
  static struct {
  	uint8_t		page;
  	int		(*emulate)(struct se_cmd *, unsigned char *);
  } evpd_handlers[] = {
  	{ .page = 0x00, .emulate = target_emulate_evpd_00 },
  	{ .page = 0x80, .emulate = target_emulate_evpd_80 },
  	{ .page = 0x83, .emulate = target_emulate_evpd_83 },
  	{ .page = 0x86, .emulate = target_emulate_evpd_86 },
  	{ .page = 0xb0, .emulate = target_emulate_evpd_b0 },
e22a7f075   Roland Dreier   target: Implement...
643
  	{ .page = 0xb1, .emulate = target_emulate_evpd_b1 },
b2eb705e0   Roland Dreier   target: Fix repor...
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
  	{ .page = 0xb2, .emulate = target_emulate_evpd_b2 },
  };
  
  /* supported vital product data pages */
  static int
  target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf)
  {
  	int p;
  
  	if (cmd->data_length < 8)
  		return 0;
  	/*
  	 * Only report the INQUIRY EVPD=1 pages after a valid NAA
  	 * Registered Extended LUN WWN has been set via ConfigFS
  	 * during device creation/restart.
  	 */
  	if (cmd->se_dev->se_sub_dev->su_dev_flags &
  			SDF_EMULATED_VPD_UNIT_SERIAL) {
  		buf[3] = ARRAY_SIZE(evpd_handlers);
  		for (p = 0; p < min_t(int, ARRAY_SIZE(evpd_handlers),
  				      cmd->data_length - 4); ++p)
  			buf[p + 4] = evpd_handlers[p].page;
  	}
  
  	return 0;
  }
5bda90c8f   Christoph Hellwig   target: use ->exe...
670
  int target_emulate_inquiry(struct se_task *task)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
671
  {
6ed5a5579   Christoph Hellwig   target: refactor ...
672
  	struct se_cmd *cmd = task->task_se_cmd;
5951146de   Andy Grover   target: More core...
673
  	struct se_device *dev = cmd->se_dev;
05d1c7c0d   Andy Grover   target: Make all ...
674
  	unsigned char *buf;
a1d8b49ab   Andy Grover   target: Updates f...
675
  	unsigned char *cdb = cmd->t_task_cdb;
05d1c7c0d   Andy Grover   target: Make all ...
676
  	int p, ret;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
677

d29a5b6ac   Christoph Hellwig   target: remove SC...
678
679
680
681
  	if (!(cdb[1] & 0x1)) {
  		ret = target_emulate_inquiry_std(cmd);
  		goto out;
  	}
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
682
683
684
685
686
687
688
689
690
  
  	/*
  	 * Make sure we at least have 4 bytes of INQUIRY response
  	 * payload for 0x00 going back for EVPD=1.  Note that 0x80
  	 * and 0x83 will check for enough payload data length and
  	 * jump to set_len: label when there is not enough inquiry EVPD
  	 * payload length left for the next outgoing EVPD metadata
  	 */
  	if (cmd->data_length < 4) {
6708bb27b   Andy Grover   target: Follow up...
691
  		pr_err("SCSI Inquiry payload length: %u"
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
692
693
  			" too small for EVPD=1
  ", cmd->data_length);
03e98c9eb   Nicholas Bellinger   target: Address l...
694
  		cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
e3d6f909e   Andy Grover   target: Core clea...
695
  		return -EINVAL;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
696
  	}
05d1c7c0d   Andy Grover   target: Make all ...
697
698
  
  	buf = transport_kmap_first_data_page(cmd);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
699
  	buf[0] = dev->transport->get_device_type(dev);
d29a5b6ac   Christoph Hellwig   target: remove SC...
700
  	for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p) {
b2eb705e0   Roland Dreier   target: Fix repor...
701
702
  		if (cdb[2] == evpd_handlers[p].page) {
  			buf[1] = cdb[2];
05d1c7c0d   Andy Grover   target: Make all ...
703
  			ret = evpd_handlers[p].emulate(cmd, buf);
d29a5b6ac   Christoph Hellwig   target: remove SC...
704
  			goto out_unmap;
b2eb705e0   Roland Dreier   target: Fix repor...
705
  		}
d29a5b6ac   Christoph Hellwig   target: remove SC...
706
  	}
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
707

6708bb27b   Andy Grover   target: Follow up...
708
709
  	pr_err("Unknown VPD Code: 0x%02x
  ", cdb[2]);
03e98c9eb   Nicholas Bellinger   target: Address l...
710
  	cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
d29a5b6ac   Christoph Hellwig   target: remove SC...
711
712
713
714
715
716
717
718
719
720
  	ret = -EINVAL;
  
  out_unmap:
  	transport_kunmap_first_data_page(cmd);
  out:
  	if (!ret) {
  		task->task_scsi_status = GOOD;
  		transport_complete_task(task, 1);
  	}
  	return ret;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
721
  }
5bda90c8f   Christoph Hellwig   target: use ->exe...
722
  int target_emulate_readcapacity(struct se_task *task)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
723
  {
6ed5a5579   Christoph Hellwig   target: refactor ...
724
  	struct se_cmd *cmd = task->task_se_cmd;
5951146de   Andy Grover   target: More core...
725
  	struct se_device *dev = cmd->se_dev;
05d1c7c0d   Andy Grover   target: Make all ...
726
  	unsigned char *buf;
904f0bc48   Nicholas Bellinger   [SCSI] target: Fi...
727
728
729
730
731
732
733
  	unsigned long long blocks_long = dev->transport->get_blocks(dev);
  	u32 blocks;
  
  	if (blocks_long >= 0x00000000ffffffff)
  		blocks = 0xffffffff;
  	else
  		blocks = (u32)blocks_long;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
734

05d1c7c0d   Andy Grover   target: Make all ...
735
  	buf = transport_kmap_first_data_page(cmd);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
736
737
738
739
  	buf[0] = (blocks >> 24) & 0xff;
  	buf[1] = (blocks >> 16) & 0xff;
  	buf[2] = (blocks >> 8) & 0xff;
  	buf[3] = blocks & 0xff;
e3d6f909e   Andy Grover   target: Core clea...
740
741
742
743
  	buf[4] = (dev->se_sub_dev->se_dev_attrib.block_size >> 24) & 0xff;
  	buf[5] = (dev->se_sub_dev->se_dev_attrib.block_size >> 16) & 0xff;
  	buf[6] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff;
  	buf[7] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
744
745
746
  	/*
  	 * Set max 32-bit blocks to signal SERVICE ACTION READ_CAPACITY_16
  	*/
e3d6f909e   Andy Grover   target: Core clea...
747
  	if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
748
  		put_unaligned_be32(0xFFFFFFFF, &buf[0]);
05d1c7c0d   Andy Grover   target: Make all ...
749
  	transport_kunmap_first_data_page(cmd);
d29a5b6ac   Christoph Hellwig   target: remove SC...
750
751
  	task->task_scsi_status = GOOD;
  	transport_complete_task(task, 1);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
752
753
  	return 0;
  }
5bda90c8f   Christoph Hellwig   target: use ->exe...
754
  int target_emulate_readcapacity_16(struct se_task *task)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
755
  {
6ed5a5579   Christoph Hellwig   target: refactor ...
756
  	struct se_cmd *cmd = task->task_se_cmd;
5951146de   Andy Grover   target: More core...
757
  	struct se_device *dev = cmd->se_dev;
05d1c7c0d   Andy Grover   target: Make all ...
758
  	unsigned char *buf;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
759
  	unsigned long long blocks = dev->transport->get_blocks(dev);
05d1c7c0d   Andy Grover   target: Make all ...
760
  	buf = transport_kmap_first_data_page(cmd);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
761
762
763
764
765
766
767
768
  	buf[0] = (blocks >> 56) & 0xff;
  	buf[1] = (blocks >> 48) & 0xff;
  	buf[2] = (blocks >> 40) & 0xff;
  	buf[3] = (blocks >> 32) & 0xff;
  	buf[4] = (blocks >> 24) & 0xff;
  	buf[5] = (blocks >> 16) & 0xff;
  	buf[6] = (blocks >> 8) & 0xff;
  	buf[7] = blocks & 0xff;
e3d6f909e   Andy Grover   target: Core clea...
769
770
771
772
  	buf[8] = (dev->se_sub_dev->se_dev_attrib.block_size >> 24) & 0xff;
  	buf[9] = (dev->se_sub_dev->se_dev_attrib.block_size >> 16) & 0xff;
  	buf[10] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff;
  	buf[11] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
773
774
775
776
  	/*
  	 * Set Thin Provisioning Enable bit following sbc3r22 in section
  	 * READ CAPACITY (16) byte 14 if emulate_tpu or emulate_tpws is enabled.
  	 */
e3d6f909e   Andy Grover   target: Core clea...
777
  	if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
778
  		buf[14] = 0x80;
05d1c7c0d   Andy Grover   target: Make all ...
779
  	transport_kunmap_first_data_page(cmd);
d29a5b6ac   Christoph Hellwig   target: remove SC...
780
781
  	task->task_scsi_status = GOOD;
  	transport_complete_task(task, 1);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
  	return 0;
  }
  
  static int
  target_modesense_rwrecovery(unsigned char *p)
  {
  	p[0] = 0x01;
  	p[1] = 0x0a;
  
  	return 12;
  }
  
  static int
  target_modesense_control(struct se_device *dev, unsigned char *p)
  {
  	p[0] = 0x0a;
  	p[1] = 0x0a;
  	p[2] = 2;
  	/*
5de619a31   Nicholas Bellinger   target: Update QU...
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
  	 * From spc4r23, 7.4.7 Control mode page
  	 *
  	 * The QUEUE ALGORITHM MODIFIER field (see table 368) specifies
  	 * restrictions on the algorithm used for reordering commands
  	 * having the SIMPLE task attribute (see SAM-4).
  	 *
  	 *                    Table 368 -- QUEUE ALGORITHM MODIFIER field
  	 *                         Code      Description
  	 *                          0h       Restricted reordering
  	 *                          1h       Unrestricted reordering allowed
  	 *                          2h to 7h    Reserved
  	 *                          8h to Fh    Vendor specific
  	 *
  	 * A value of zero in the QUEUE ALGORITHM MODIFIER field specifies that
  	 * the device server shall order the processing sequence of commands
  	 * having the SIMPLE task attribute such that data integrity is maintained
  	 * for that I_T nexus (i.e., if the transmission of new SCSI transport protocol
  	 * requests is halted at any time, the final value of all data observable
  	 * on the medium shall be the same as if all the commands had been processed
  	 * with the ORDERED task attribute).
  	 *
  	 * A value of one in the QUEUE ALGORITHM MODIFIER field specifies that the
  	 * device server may reorder the processing sequence of commands having the
  	 * SIMPLE task attribute in any manner. Any data integrity exposures related to
  	 * command sequence order shall be explicitly handled by the application client
  	 * through the selection of appropriate ommands and task attributes.
  	 */
  	p[3] = (dev->se_sub_dev->se_dev_attrib.emulate_rest_reord == 1) ? 0x00 : 0x10;
  	/*
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
  	 * From spc4r17, section 7.4.6 Control mode Page
  	 *
  	 * Unit Attention interlocks control (UN_INTLCK_CTRL) to code 00b
  	 *
  	 * 00b: The logical unit shall clear any unit attention condition
  	 * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION
  	 * status and shall not establish a unit attention condition when a com-
  	 * mand is completed with BUSY, TASK SET FULL, or RESERVATION CONFLICT
  	 * status.
  	 *
  	 * 10b: The logical unit shall not clear any unit attention condition
  	 * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION
  	 * status and shall not establish a unit attention condition when
  	 * a command is completed with BUSY, TASK SET FULL, or RESERVATION
  	 * CONFLICT status.
  	 *
  	 * 11b a The logical unit shall not clear any unit attention condition
  	 * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION
  	 * status and shall establish a unit attention condition for the
  	 * initiator port associated with the I_T nexus on which the BUSY,
  	 * TASK SET FULL, or RESERVATION CONFLICT status is being returned.
  	 * Depending on the status, the additional sense code shall be set to
  	 * PREVIOUS BUSY STATUS, PREVIOUS TASK SET FULL STATUS, or PREVIOUS
  	 * RESERVATION CONFLICT STATUS. Until it is cleared by a REQUEST SENSE
  	 * command, a unit attention condition shall be established only once
  	 * for a BUSY, TASK SET FULL, or RESERVATION CONFLICT status regardless
  	 * to the number of commands completed with one of those status codes.
  	 */
e3d6f909e   Andy Grover   target: Core clea...
858
859
  	p[4] = (dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl == 2) ? 0x30 :
  	       (dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl == 1) ? 0x20 : 0x00;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
860
861
862
863
864
865
866
867
868
869
870
871
  	/*
  	 * From spc4r17, section 7.4.6 Control mode Page
  	 *
  	 * Task Aborted Status (TAS) bit set to zero.
  	 *
  	 * A task aborted status (TAS) bit set to zero specifies that aborted
  	 * tasks shall be terminated by the device server without any response
  	 * to the application client. A TAS bit set to one specifies that tasks
  	 * aborted by the actions of an I_T nexus other than the I_T nexus on
  	 * which the command was received shall be completed with TASK ABORTED
  	 * status (see SAM-4).
  	 */
e3d6f909e   Andy Grover   target: Core clea...
872
  	p[5] = (dev->se_sub_dev->se_dev_attrib.emulate_tas) ? 0x40 : 0x00;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
873
874
875
876
877
878
879
880
881
882
883
884
  	p[8] = 0xff;
  	p[9] = 0xff;
  	p[11] = 30;
  
  	return 12;
  }
  
  static int
  target_modesense_caching(struct se_device *dev, unsigned char *p)
  {
  	p[0] = 0x08;
  	p[1] = 0x12;
e3d6f909e   Andy Grover   target: Core clea...
885
  	if (dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
  		p[2] = 0x04; /* Write Cache Enable */
  	p[12] = 0x20; /* Disabled Read Ahead */
  
  	return 20;
  }
  
  static void
  target_modesense_write_protect(unsigned char *buf, int type)
  {
  	/*
  	 * I believe that the WP bit (bit 7) in the mode header is the same for
  	 * all device types..
  	 */
  	switch (type) {
  	case TYPE_DISK:
  	case TYPE_TAPE:
  	default:
  		buf[0] |= 0x80; /* WP bit */
  		break;
  	}
  }
  
  static void
  target_modesense_dpofua(unsigned char *buf, int type)
  {
  	switch (type) {
  	case TYPE_DISK:
  		buf[0] |= 0x10; /* DPOFUA bit */
  		break;
  	default:
  		break;
  	}
  }
5bda90c8f   Christoph Hellwig   target: use ->exe...
919
  int target_emulate_modesense(struct se_task *task)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
920
  {
6ed5a5579   Christoph Hellwig   target: refactor ...
921
  	struct se_cmd *cmd = task->task_se_cmd;
5951146de   Andy Grover   target: More core...
922
  	struct se_device *dev = cmd->se_dev;
a1d8b49ab   Andy Grover   target: Updates f...
923
  	char *cdb = cmd->t_task_cdb;
05d1c7c0d   Andy Grover   target: Make all ...
924
  	unsigned char *rbuf;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
925
  	int type = dev->transport->get_device_type(dev);
6ed5a5579   Christoph Hellwig   target: refactor ...
926
927
  	int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10);
  	int offset = ten ? 8 : 4;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
  	int length = 0;
  	unsigned char buf[SE_MODE_PAGE_BUF];
  
  	memset(buf, 0, SE_MODE_PAGE_BUF);
  
  	switch (cdb[2] & 0x3f) {
  	case 0x01:
  		length = target_modesense_rwrecovery(&buf[offset]);
  		break;
  	case 0x08:
  		length = target_modesense_caching(dev, &buf[offset]);
  		break;
  	case 0x0a:
  		length = target_modesense_control(dev, &buf[offset]);
  		break;
  	case 0x3f:
  		length = target_modesense_rwrecovery(&buf[offset]);
  		length += target_modesense_caching(dev, &buf[offset+length]);
  		length += target_modesense_control(dev, &buf[offset+length]);
  		break;
  	default:
f15ea5780   Roland Dreier   target: Print sub...
949
950
951
  		pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x
  ",
  		       cdb[2] & 0x3f, cdb[3]);
03e98c9eb   Nicholas Bellinger   target: Address l...
952
953
  		cmd->scsi_sense_reason = TCM_UNKNOWN_MODE_PAGE;
  		return -EINVAL;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
954
955
956
957
958
959
960
  	}
  	offset += length;
  
  	if (ten) {
  		offset -= 2;
  		buf[0] = (offset >> 8) & 0xff;
  		buf[1] = offset & 0xff;
e3d6f909e   Andy Grover   target: Core clea...
961
  		if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) ||
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
962
963
964
  		    (cmd->se_deve &&
  		    (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)))
  			target_modesense_write_protect(&buf[3], type);
e3d6f909e   Andy Grover   target: Core clea...
965
966
  		if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) &&
  		    (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0))
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
967
968
969
970
971
972
973
974
  			target_modesense_dpofua(&buf[3], type);
  
  		if ((offset + 2) > cmd->data_length)
  			offset = cmd->data_length;
  
  	} else {
  		offset -= 1;
  		buf[0] = offset & 0xff;
e3d6f909e   Andy Grover   target: Core clea...
975
  		if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) ||
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
976
977
978
  		    (cmd->se_deve &&
  		    (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)))
  			target_modesense_write_protect(&buf[2], type);
e3d6f909e   Andy Grover   target: Core clea...
979
980
  		if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) &&
  		    (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0))
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
981
982
983
984
985
  			target_modesense_dpofua(&buf[2], type);
  
  		if ((offset + 1) > cmd->data_length)
  			offset = cmd->data_length;
  	}
05d1c7c0d   Andy Grover   target: Make all ...
986
987
  
  	rbuf = transport_kmap_first_data_page(cmd);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
988
  	memcpy(rbuf, buf, offset);
05d1c7c0d   Andy Grover   target: Make all ...
989
  	transport_kunmap_first_data_page(cmd);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
990

d29a5b6ac   Christoph Hellwig   target: remove SC...
991
992
  	task->task_scsi_status = GOOD;
  	transport_complete_task(task, 1);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
993
994
  	return 0;
  }
5bda90c8f   Christoph Hellwig   target: use ->exe...
995
  int target_emulate_request_sense(struct se_task *task)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
996
  {
6ed5a5579   Christoph Hellwig   target: refactor ...
997
  	struct se_cmd *cmd = task->task_se_cmd;
a1d8b49ab   Andy Grover   target: Updates f...
998
  	unsigned char *cdb = cmd->t_task_cdb;
05d1c7c0d   Andy Grover   target: Make all ...
999
  	unsigned char *buf;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1000
  	u8 ua_asc = 0, ua_ascq = 0;
05d1c7c0d   Andy Grover   target: Make all ...
1001
  	int err = 0;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1002
1003
  
  	if (cdb[1] & 0x01) {
6708bb27b   Andy Grover   target: Follow up...
1004
  		pr_err("REQUEST_SENSE description emulation not"
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1005
1006
  			" supported
  ");
03e98c9eb   Nicholas Bellinger   target: Address l...
1007
1008
  		cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
  		return -ENOSYS;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1009
  	}
05d1c7c0d   Andy Grover   target: Make all ...
1010
1011
  
  	buf = transport_kmap_first_data_page(cmd);
6708bb27b   Andy Grover   target: Follow up...
1012
  	if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) {
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
  		/*
  		 * CURRENT ERROR, UNIT ATTENTION
  		 */
  		buf[0] = 0x70;
  		buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION;
  		/*
  		 * Make sure request data length is enough for additional
  		 * sense data.
  		 */
  		if (cmd->data_length <= 18) {
  			buf[7] = 0x00;
05d1c7c0d   Andy Grover   target: Make all ...
1024
1025
  			err = -EINVAL;
  			goto end;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
  		}
  		/*
  		 * The Additional Sense Code (ASC) from the UNIT ATTENTION
  		 */
  		buf[SPC_ASC_KEY_OFFSET] = ua_asc;
  		buf[SPC_ASCQ_KEY_OFFSET] = ua_ascq;
  		buf[7] = 0x0A;
  	} else {
  		/*
  		 * CURRENT ERROR, NO SENSE
  		 */
  		buf[0] = 0x70;
  		buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE;
  		/*
  		 * Make sure request data length is enough for additional
  		 * sense data.
  		 */
  		if (cmd->data_length <= 18) {
  			buf[7] = 0x00;
05d1c7c0d   Andy Grover   target: Make all ...
1045
1046
  			err = -EINVAL;
  			goto end;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1047
1048
1049
1050
1051
1052
1053
  		}
  		/*
  		 * NO ADDITIONAL SENSE INFORMATION
  		 */
  		buf[SPC_ASC_KEY_OFFSET] = 0x00;
  		buf[7] = 0x0A;
  	}
05d1c7c0d   Andy Grover   target: Make all ...
1054
1055
  end:
  	transport_kunmap_first_data_page(cmd);
d29a5b6ac   Christoph Hellwig   target: remove SC...
1056
1057
  	task->task_scsi_status = GOOD;
  	transport_complete_task(task, 1);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1058
1059
1060
1061
1062
1063
1064
  	return 0;
  }
  
  /*
   * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support.
   * Note this is not used for TCM/pSCSI passthrough
   */
5bda90c8f   Christoph Hellwig   target: use ->exe...
1065
  int target_emulate_unmap(struct se_task *task)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1066
  {
e3d6f909e   Andy Grover   target: Core clea...
1067
  	struct se_cmd *cmd = task->task_se_cmd;
5951146de   Andy Grover   target: More core...
1068
  	struct se_device *dev = cmd->se_dev;
05d1c7c0d   Andy Grover   target: Make all ...
1069
  	unsigned char *buf, *ptr = NULL;
a1d8b49ab   Andy Grover   target: Updates f...
1070
  	unsigned char *cdb = &cmd->t_task_cdb[0];
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1071
1072
  	sector_t lba;
  	unsigned int size = cmd->data_length, range;
05d1c7c0d   Andy Grover   target: Make all ...
1073
  	int ret = 0, offset;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1074
  	unsigned short dl, bd_dl;
6ed5a5579   Christoph Hellwig   target: refactor ...
1075
1076
1077
1078
  	if (!dev->transport->do_discard) {
  		pr_err("UNMAP emulation not supported for: %s
  ",
  				dev->transport->name);
03e98c9eb   Nicholas Bellinger   target: Address l...
1079
1080
  		cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
  		return -ENOSYS;
6ed5a5579   Christoph Hellwig   target: refactor ...
1081
  	}
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1082
1083
1084
1085
1086
  	/* First UNMAP block descriptor starts at 8 byte offset */
  	offset = 8;
  	size -= 8;
  	dl = get_unaligned_be16(&cdb[0]);
  	bd_dl = get_unaligned_be16(&cdb[2]);
05d1c7c0d   Andy Grover   target: Make all ...
1087
1088
  
  	buf = transport_kmap_first_data_page(cmd);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1089
  	ptr = &buf[offset];
6708bb27b   Andy Grover   target: Follow up...
1090
  	pr_debug("UNMAP: Sub: %s Using dl: %hu bd_dl: %hu size: %hu"
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1091
1092
1093
1094
1095
1096
  		" ptr: %p
  ", dev->transport->name, dl, bd_dl, size, ptr);
  
  	while (size) {
  		lba = get_unaligned_be64(&ptr[0]);
  		range = get_unaligned_be32(&ptr[8]);
6708bb27b   Andy Grover   target: Follow up...
1097
1098
  		pr_debug("UNMAP: Using lba: %llu and range: %u
  ",
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1099
1100
1101
1102
  				 (unsigned long long)lba, range);
  
  		ret = dev->transport->do_discard(dev, lba, range);
  		if (ret < 0) {
6708bb27b   Andy Grover   target: Follow up...
1103
1104
  			pr_err("blkdev_issue_discard() failed: %d
  ",
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1105
  					ret);
05d1c7c0d   Andy Grover   target: Make all ...
1106
  			goto err;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1107
1108
1109
1110
1111
  		}
  
  		ptr += 16;
  		size -= 16;
  	}
05d1c7c0d   Andy Grover   target: Make all ...
1112
1113
  err:
  	transport_kunmap_first_data_page(cmd);
d29a5b6ac   Christoph Hellwig   target: remove SC...
1114
1115
1116
1117
  	if (!ret) {
  		task->task_scsi_status = GOOD;
  		transport_complete_task(task, 1);
  	}
05d1c7c0d   Andy Grover   target: Make all ...
1118
  	return ret;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1119
1120
1121
1122
1123
1124
  }
  
  /*
   * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support.
   * Note this is not used for TCM/pSCSI passthrough
   */
5bda90c8f   Christoph Hellwig   target: use ->exe...
1125
  int target_emulate_write_same(struct se_task *task)
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1126
  {
e3d6f909e   Andy Grover   target: Core clea...
1127
  	struct se_cmd *cmd = task->task_se_cmd;
5951146de   Andy Grover   target: More core...
1128
  	struct se_device *dev = cmd->se_dev;
a1d8b49ab   Andy Grover   target: Updates f...
1129
1130
  	sector_t range;
  	sector_t lba = cmd->t_task_lba;
6ed5a5579   Christoph Hellwig   target: refactor ...
1131
  	u32 num_blocks;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1132
  	int ret;
6ed5a5579   Christoph Hellwig   target: refactor ...
1133
1134
1135
1136
1137
  
  	if (!dev->transport->do_discard) {
  		pr_err("WRITE_SAME emulation not supported"
  				" for: %s
  ", dev->transport->name);
03e98c9eb   Nicholas Bellinger   target: Address l...
1138
1139
  		cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
  		return -ENOSYS;
6ed5a5579   Christoph Hellwig   target: refactor ...
1140
1141
1142
1143
1144
1145
1146
1147
  	}
  
  	if (cmd->t_task_cdb[0] == WRITE_SAME)
  		num_blocks = get_unaligned_be16(&cmd->t_task_cdb[7]);
  	else if (cmd->t_task_cdb[0] == WRITE_SAME_16)
  		num_blocks = get_unaligned_be32(&cmd->t_task_cdb[10]);
  	else /* WRITE_SAME_32 via VARIABLE_LENGTH_CMD */
  		num_blocks = get_unaligned_be32(&cmd->t_task_cdb[28]);
dd3a5ad8e   Nicholas Bellinger   target: Fix WRITE...
1148
  	/*
706d58609   Nicholas Bellinger   target: Add WRITE...
1149
1150
  	 * Use the explicit range when non zero is supplied, otherwise calculate
  	 * the remaining range based on ->get_blocks() - starting LBA.
dd3a5ad8e   Nicholas Bellinger   target: Fix WRITE...
1151
  	 */
dd3a5ad8e   Nicholas Bellinger   target: Fix WRITE...
1152
1153
1154
1155
  	if (num_blocks != 0)
  		range = num_blocks;
  	else
  		range = (dev->transport->get_blocks(dev) - lba);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1156

6708bb27b   Andy Grover   target: Follow up...
1157
1158
  	pr_debug("WRITE_SAME UNMAP: LBA: %llu Range: %llu
  ",
dd3a5ad8e   Nicholas Bellinger   target: Fix WRITE...
1159
  		 (unsigned long long)lba, (unsigned long long)range);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1160
1161
1162
  
  	ret = dev->transport->do_discard(dev, lba, range);
  	if (ret < 0) {
6708bb27b   Andy Grover   target: Follow up...
1163
1164
  		pr_debug("blkdev_issue_discard() failed for WRITE_SAME
  ");
e3d6f909e   Andy Grover   target: Core clea...
1165
  		return ret;
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1166
  	}
d29a5b6ac   Christoph Hellwig   target: remove SC...
1167
1168
  	task->task_scsi_status = GOOD;
  	transport_complete_task(task, 1);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
1169
1170
  	return 0;
  }
5bda90c8f   Christoph Hellwig   target: use ->exe...
1171
  int target_emulate_synchronize_cache(struct se_task *task)
6ed5a5579   Christoph Hellwig   target: refactor ...
1172
1173
  {
  	struct se_device *dev = task->task_se_cmd->se_dev;
03e98c9eb   Nicholas Bellinger   target: Address l...
1174
  	struct se_cmd *cmd = task->task_se_cmd;
6ed5a5579   Christoph Hellwig   target: refactor ...
1175
1176
1177
1178
1179
  
  	if (!dev->transport->do_sync_cache) {
  		pr_err("SYNCHRONIZE_CACHE emulation not supported"
  			" for: %s
  ", dev->transport->name);
03e98c9eb   Nicholas Bellinger   target: Address l...
1180
1181
  		cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
  		return -ENOSYS;
6ed5a5579   Christoph Hellwig   target: refactor ...
1182
1183
1184
1185
1186
  	}
  
  	dev->transport->do_sync_cache(task);
  	return 0;
  }
5bda90c8f   Christoph Hellwig   target: use ->exe...
1187
  int target_emulate_noop(struct se_task *task)
d29a5b6ac   Christoph Hellwig   target: remove SC...
1188
1189
1190
1191
1192
  {
  	task->task_scsi_status = GOOD;
  	transport_complete_task(task, 1);
  	return 0;
  }
485fd0d1e   Christoph Hellwig   target: replace -...
1193
1194
1195
1196
1197
1198
1199
  /*
   * Write a CDB into @cdb that is based on the one the intiator sent us,
   * but updated to only cover the sectors that the current task handles.
   */
  void target_get_task_cdb(struct se_task *task, unsigned char *cdb)
  {
  	struct se_cmd *cmd = task->task_se_cmd;
b937d2705   Christoph Hellwig   target: remove th...
1200
  	unsigned int cdb_len = scsi_command_size(cmd->t_task_cdb);
485fd0d1e   Christoph Hellwig   target: replace -...
1201

b937d2705   Christoph Hellwig   target: remove th...
1202
  	memcpy(cdb, cmd->t_task_cdb, cdb_len);
485fd0d1e   Christoph Hellwig   target: replace -...
1203
  	if (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) {
b937d2705   Christoph Hellwig   target: remove th...
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
  		unsigned long long lba = task->task_lba;
  		u32 sectors = task->task_sectors;
  
  		switch (cdb_len) {
  		case 6:
  			/* 21-bit LBA and 8-bit sectors */
  			cdb[1] = (lba >> 16) & 0x1f;
  			cdb[2] = (lba >> 8) & 0xff;
  			cdb[3] = lba & 0xff;
  			cdb[4] = sectors & 0xff;
  			break;
  		case 10:
  			/* 32-bit LBA and 16-bit sectors */
  			put_unaligned_be32(lba, &cdb[2]);
  			put_unaligned_be16(sectors, &cdb[7]);
  			break;
  		case 12:
  			/* 32-bit LBA and 32-bit sectors */
  			put_unaligned_be32(lba, &cdb[2]);
  			put_unaligned_be32(sectors, &cdb[6]);
  			break;
  		case 16:
  			/* 64-bit LBA and 32-bit sectors */
  			put_unaligned_be64(lba, &cdb[2]);
  			put_unaligned_be32(sectors, &cdb[10]);
  			break;
  		case 32:
  			/* 64-bit LBA and 32-bit sectors, extended CDB */
  			put_unaligned_be64(lba, &cdb[12]);
  			put_unaligned_be32(sectors, &cdb[28]);
  			break;
  		default:
  			BUG();
  		}
485fd0d1e   Christoph Hellwig   target: replace -...
1238
1239
1240
  	}
  }
  EXPORT_SYMBOL(target_get_task_cdb);