xref: /OK3568_Linux_fs/kernel/include/scsi/scsi_cmnd.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #ifndef _SCSI_SCSI_CMND_H
3*4882a593Smuzhiyun #define _SCSI_SCSI_CMND_H
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #include <linux/dma-mapping.h>
6*4882a593Smuzhiyun #include <linux/blkdev.h>
7*4882a593Smuzhiyun #include <linux/t10-pi.h>
8*4882a593Smuzhiyun #include <linux/list.h>
9*4882a593Smuzhiyun #include <linux/types.h>
10*4882a593Smuzhiyun #include <linux/timer.h>
11*4882a593Smuzhiyun #include <linux/scatterlist.h>
12*4882a593Smuzhiyun #include <scsi/scsi_device.h>
13*4882a593Smuzhiyun #include <scsi/scsi_request.h>
14*4882a593Smuzhiyun #include <linux/android_kabi.h>
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun struct Scsi_Host;
17*4882a593Smuzhiyun struct scsi_driver;
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun /*
20*4882a593Smuzhiyun  * MAX_COMMAND_SIZE is:
21*4882a593Smuzhiyun  * The longest fixed-length SCSI CDB as per the SCSI standard.
22*4882a593Smuzhiyun  * fixed-length means: commands that their size can be determined
23*4882a593Smuzhiyun  * by their opcode and the CDB does not carry a length specifier, (unlike
24*4882a593Smuzhiyun  * the VARIABLE_LENGTH_CMD(0x7f) command). This is actually not exactly
25*4882a593Smuzhiyun  * true and the SCSI standard also defines extended commands and
26*4882a593Smuzhiyun  * vendor specific commands that can be bigger than 16 bytes. The kernel
27*4882a593Smuzhiyun  * will support these using the same infrastructure used for VARLEN CDB's.
28*4882a593Smuzhiyun  * So in effect MAX_COMMAND_SIZE means the maximum size command scsi-ml
29*4882a593Smuzhiyun  * supports without specifying a cmd_len by ULD's
30*4882a593Smuzhiyun  */
31*4882a593Smuzhiyun #define MAX_COMMAND_SIZE 16
32*4882a593Smuzhiyun #if (MAX_COMMAND_SIZE > BLK_MAX_CDB)
33*4882a593Smuzhiyun # error MAX_COMMAND_SIZE can not be bigger than BLK_MAX_CDB
34*4882a593Smuzhiyun #endif
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun struct scsi_data_buffer {
37*4882a593Smuzhiyun 	struct sg_table table;
38*4882a593Smuzhiyun 	unsigned length;
39*4882a593Smuzhiyun };
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun /* embedded in scsi_cmnd */
42*4882a593Smuzhiyun struct scsi_pointer {
43*4882a593Smuzhiyun 	char *ptr;		/* data pointer */
44*4882a593Smuzhiyun 	int this_residual;	/* left in this buffer */
45*4882a593Smuzhiyun 	struct scatterlist *buffer;	/* which buffer */
46*4882a593Smuzhiyun 	int buffers_residual;	/* how many buffers left */
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun         dma_addr_t dma_handle;
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 	volatile int Status;
51*4882a593Smuzhiyun 	volatile int Message;
52*4882a593Smuzhiyun 	volatile int have_data_in;
53*4882a593Smuzhiyun 	volatile int sent_command;
54*4882a593Smuzhiyun 	volatile int phase;
55*4882a593Smuzhiyun };
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun /* for scmd->flags */
58*4882a593Smuzhiyun #define SCMD_TAGGED		(1 << 0)
59*4882a593Smuzhiyun #define SCMD_UNCHECKED_ISA_DMA	(1 << 1)
60*4882a593Smuzhiyun #define SCMD_INITIALIZED	(1 << 2)
61*4882a593Smuzhiyun #define SCMD_LAST		(1 << 3)
62*4882a593Smuzhiyun /* flags preserved across unprep / reprep */
63*4882a593Smuzhiyun #define SCMD_PRESERVED_FLAGS	(SCMD_UNCHECKED_ISA_DMA | SCMD_INITIALIZED)
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun /* for scmd->state */
66*4882a593Smuzhiyun #define SCMD_STATE_COMPLETE	0
67*4882a593Smuzhiyun #define SCMD_STATE_INFLIGHT	1
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun struct scsi_cmnd {
70*4882a593Smuzhiyun 	struct scsi_request req;
71*4882a593Smuzhiyun 	struct scsi_device *device;
72*4882a593Smuzhiyun 	struct list_head eh_entry; /* entry for the host eh_cmd_q */
73*4882a593Smuzhiyun 	struct delayed_work abort_work;
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 	struct rcu_head rcu;
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun 	int eh_eflags;		/* Used by error handlr */
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 	/*
80*4882a593Smuzhiyun 	 * This is set to jiffies as it was when the command was first
81*4882a593Smuzhiyun 	 * allocated.  It is used to time how long the command has
82*4882a593Smuzhiyun 	 * been outstanding
83*4882a593Smuzhiyun 	 */
84*4882a593Smuzhiyun 	unsigned long jiffies_at_alloc;
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	int retries;
87*4882a593Smuzhiyun 	int allowed;
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun 	unsigned char prot_op;
90*4882a593Smuzhiyun 	unsigned char prot_type;
91*4882a593Smuzhiyun 	unsigned char prot_flags;
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	unsigned short cmd_len;
94*4882a593Smuzhiyun 	enum dma_data_direction sc_data_direction;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 	/* These elements define the operation we are about to perform */
97*4882a593Smuzhiyun 	unsigned char *cmnd;
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	/* These elements define the operation we ultimately want to perform */
101*4882a593Smuzhiyun 	struct scsi_data_buffer sdb;
102*4882a593Smuzhiyun 	struct scsi_data_buffer *prot_sdb;
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	unsigned underflow;	/* Return error if less than
105*4882a593Smuzhiyun 				   this amount is transferred */
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	unsigned transfersize;	/* How much we are guaranteed to
108*4882a593Smuzhiyun 				   transfer with each SCSI transfer
109*4882a593Smuzhiyun 				   (ie, between disconnect /
110*4882a593Smuzhiyun 				   reconnects.   Probably == sector
111*4882a593Smuzhiyun 				   size */
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun 	struct request *request;	/* The command we are
114*4882a593Smuzhiyun 				   	   working on */
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	unsigned char *sense_buffer;
117*4882a593Smuzhiyun 				/* obtained by REQUEST SENSE when
118*4882a593Smuzhiyun 				 * CHECK CONDITION is received on original
119*4882a593Smuzhiyun 				 * command (auto-sense). Length must be
120*4882a593Smuzhiyun 				 * SCSI_SENSE_BUFFERSIZE bytes. */
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	/* Low-level done function - can be used by low-level driver to point
123*4882a593Smuzhiyun 	 *        to completion function.  Not used by mid/upper level code. */
124*4882a593Smuzhiyun 	void (*scsi_done) (struct scsi_cmnd *);
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 	/*
127*4882a593Smuzhiyun 	 * The following fields can be written to by the host specific code.
128*4882a593Smuzhiyun 	 * Everything else should be left alone.
129*4882a593Smuzhiyun 	 */
130*4882a593Smuzhiyun 	struct scsi_pointer SCp;	/* Scratchpad used by some host adapters */
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	unsigned char *host_scribble;	/* The host adapter is allowed to
133*4882a593Smuzhiyun 					 * call scsi_malloc and get some memory
134*4882a593Smuzhiyun 					 * and hang it here.  The host adapter
135*4882a593Smuzhiyun 					 * is also expected to call scsi_free
136*4882a593Smuzhiyun 					 * to release this memory.  (The memory
137*4882a593Smuzhiyun 					 * obtained by scsi_malloc is guaranteed
138*4882a593Smuzhiyun 					 * to be at an address < 16Mb). */
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	int result;		/* Status code from lower level driver */
141*4882a593Smuzhiyun 	int flags;		/* Command flags */
142*4882a593Smuzhiyun 	unsigned long state;	/* Command completion state */
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 	unsigned char tag;	/* SCSI-II queued command tag */
145*4882a593Smuzhiyun 	unsigned int extra_len;	/* length of alignment and padding */
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	ANDROID_KABI_RESERVE(1);
148*4882a593Smuzhiyun 	ANDROID_KABI_RESERVE(2);
149*4882a593Smuzhiyun 	ANDROID_KABI_RESERVE(3);
150*4882a593Smuzhiyun 	ANDROID_KABI_RESERVE(4);
151*4882a593Smuzhiyun };
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun /*
154*4882a593Smuzhiyun  * Return the driver private allocation behind the command.
155*4882a593Smuzhiyun  * Only works if cmd_size is set in the host template.
156*4882a593Smuzhiyun  */
scsi_cmd_priv(struct scsi_cmnd * cmd)157*4882a593Smuzhiyun static inline void *scsi_cmd_priv(struct scsi_cmnd *cmd)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun 	return cmd + 1;
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun /* make sure not to use it with passthrough commands */
scsi_cmd_to_driver(struct scsi_cmnd * cmd)163*4882a593Smuzhiyun static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun 	return *(struct scsi_driver **)cmd->request->rq_disk->private_data;
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun extern void scsi_finish_command(struct scsi_cmnd *cmd);
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count,
171*4882a593Smuzhiyun 				 size_t *offset, size_t *len);
172*4882a593Smuzhiyun extern void scsi_kunmap_atomic_sg(void *virt);
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun blk_status_t scsi_alloc_sgtables(struct scsi_cmnd *cmd);
175*4882a593Smuzhiyun void scsi_free_sgtables(struct scsi_cmnd *cmd);
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun #ifdef CONFIG_SCSI_DMA
178*4882a593Smuzhiyun extern int scsi_dma_map(struct scsi_cmnd *cmd);
179*4882a593Smuzhiyun extern void scsi_dma_unmap(struct scsi_cmnd *cmd);
180*4882a593Smuzhiyun #else /* !CONFIG_SCSI_DMA */
scsi_dma_map(struct scsi_cmnd * cmd)181*4882a593Smuzhiyun static inline int scsi_dma_map(struct scsi_cmnd *cmd) { return -ENOSYS; }
scsi_dma_unmap(struct scsi_cmnd * cmd)182*4882a593Smuzhiyun static inline void scsi_dma_unmap(struct scsi_cmnd *cmd) { }
183*4882a593Smuzhiyun #endif /* !CONFIG_SCSI_DMA */
184*4882a593Smuzhiyun 
scsi_sg_count(struct scsi_cmnd * cmd)185*4882a593Smuzhiyun static inline unsigned scsi_sg_count(struct scsi_cmnd *cmd)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun 	return cmd->sdb.table.nents;
188*4882a593Smuzhiyun }
189*4882a593Smuzhiyun 
scsi_sglist(struct scsi_cmnd * cmd)190*4882a593Smuzhiyun static inline struct scatterlist *scsi_sglist(struct scsi_cmnd *cmd)
191*4882a593Smuzhiyun {
192*4882a593Smuzhiyun 	return cmd->sdb.table.sgl;
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun 
scsi_bufflen(struct scsi_cmnd * cmd)195*4882a593Smuzhiyun static inline unsigned scsi_bufflen(struct scsi_cmnd *cmd)
196*4882a593Smuzhiyun {
197*4882a593Smuzhiyun 	return cmd->sdb.length;
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun 
scsi_set_resid(struct scsi_cmnd * cmd,unsigned int resid)200*4882a593Smuzhiyun static inline void scsi_set_resid(struct scsi_cmnd *cmd, unsigned int resid)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun 	cmd->req.resid_len = resid;
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun 
scsi_get_resid(struct scsi_cmnd * cmd)205*4882a593Smuzhiyun static inline unsigned int scsi_get_resid(struct scsi_cmnd *cmd)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun 	return cmd->req.resid_len;
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun #define scsi_for_each_sg(cmd, sg, nseg, __i)			\
211*4882a593Smuzhiyun 	for_each_sg(scsi_sglist(cmd), sg, nseg, __i)
212*4882a593Smuzhiyun 
scsi_sg_copy_from_buffer(struct scsi_cmnd * cmd,const void * buf,int buflen)213*4882a593Smuzhiyun static inline int scsi_sg_copy_from_buffer(struct scsi_cmnd *cmd,
214*4882a593Smuzhiyun 					   const void *buf, int buflen)
215*4882a593Smuzhiyun {
216*4882a593Smuzhiyun 	return sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd),
217*4882a593Smuzhiyun 				   buf, buflen);
218*4882a593Smuzhiyun }
219*4882a593Smuzhiyun 
scsi_sg_copy_to_buffer(struct scsi_cmnd * cmd,void * buf,int buflen)220*4882a593Smuzhiyun static inline int scsi_sg_copy_to_buffer(struct scsi_cmnd *cmd,
221*4882a593Smuzhiyun 					 void *buf, int buflen)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun 	return sg_copy_to_buffer(scsi_sglist(cmd), scsi_sg_count(cmd),
224*4882a593Smuzhiyun 				 buf, buflen);
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun /*
228*4882a593Smuzhiyun  * The operations below are hints that tell the controller driver how
229*4882a593Smuzhiyun  * to handle I/Os with DIF or similar types of protection information.
230*4882a593Smuzhiyun  */
231*4882a593Smuzhiyun enum scsi_prot_operations {
232*4882a593Smuzhiyun 	/* Normal I/O */
233*4882a593Smuzhiyun 	SCSI_PROT_NORMAL = 0,
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	/* OS-HBA: Protected, HBA-Target: Unprotected */
236*4882a593Smuzhiyun 	SCSI_PROT_READ_INSERT,
237*4882a593Smuzhiyun 	SCSI_PROT_WRITE_STRIP,
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 	/* OS-HBA: Unprotected, HBA-Target: Protected */
240*4882a593Smuzhiyun 	SCSI_PROT_READ_STRIP,
241*4882a593Smuzhiyun 	SCSI_PROT_WRITE_INSERT,
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 	/* OS-HBA: Protected, HBA-Target: Protected */
244*4882a593Smuzhiyun 	SCSI_PROT_READ_PASS,
245*4882a593Smuzhiyun 	SCSI_PROT_WRITE_PASS,
246*4882a593Smuzhiyun };
247*4882a593Smuzhiyun 
scsi_set_prot_op(struct scsi_cmnd * scmd,unsigned char op)248*4882a593Smuzhiyun static inline void scsi_set_prot_op(struct scsi_cmnd *scmd, unsigned char op)
249*4882a593Smuzhiyun {
250*4882a593Smuzhiyun 	scmd->prot_op = op;
251*4882a593Smuzhiyun }
252*4882a593Smuzhiyun 
scsi_get_prot_op(struct scsi_cmnd * scmd)253*4882a593Smuzhiyun static inline unsigned char scsi_get_prot_op(struct scsi_cmnd *scmd)
254*4882a593Smuzhiyun {
255*4882a593Smuzhiyun 	return scmd->prot_op;
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun enum scsi_prot_flags {
259*4882a593Smuzhiyun 	SCSI_PROT_TRANSFER_PI		= 1 << 0,
260*4882a593Smuzhiyun 	SCSI_PROT_GUARD_CHECK		= 1 << 1,
261*4882a593Smuzhiyun 	SCSI_PROT_REF_CHECK		= 1 << 2,
262*4882a593Smuzhiyun 	SCSI_PROT_REF_INCREMENT		= 1 << 3,
263*4882a593Smuzhiyun 	SCSI_PROT_IP_CHECKSUM		= 1 << 4,
264*4882a593Smuzhiyun };
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun /*
267*4882a593Smuzhiyun  * The controller usually does not know anything about the target it
268*4882a593Smuzhiyun  * is communicating with.  However, when DIX is enabled the controller
269*4882a593Smuzhiyun  * must be know target type so it can verify the protection
270*4882a593Smuzhiyun  * information passed along with the I/O.
271*4882a593Smuzhiyun  */
272*4882a593Smuzhiyun enum scsi_prot_target_type {
273*4882a593Smuzhiyun 	SCSI_PROT_DIF_TYPE0 = 0,
274*4882a593Smuzhiyun 	SCSI_PROT_DIF_TYPE1,
275*4882a593Smuzhiyun 	SCSI_PROT_DIF_TYPE2,
276*4882a593Smuzhiyun 	SCSI_PROT_DIF_TYPE3,
277*4882a593Smuzhiyun };
278*4882a593Smuzhiyun 
scsi_set_prot_type(struct scsi_cmnd * scmd,unsigned char type)279*4882a593Smuzhiyun static inline void scsi_set_prot_type(struct scsi_cmnd *scmd, unsigned char type)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun 	scmd->prot_type = type;
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun 
scsi_get_prot_type(struct scsi_cmnd * scmd)284*4882a593Smuzhiyun static inline unsigned char scsi_get_prot_type(struct scsi_cmnd *scmd)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun 	return scmd->prot_type;
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun 
scsi_get_lba(struct scsi_cmnd * scmd)289*4882a593Smuzhiyun static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd)
290*4882a593Smuzhiyun {
291*4882a593Smuzhiyun 	return blk_rq_pos(scmd->request);
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun 
scsi_prot_interval(struct scsi_cmnd * scmd)294*4882a593Smuzhiyun static inline unsigned int scsi_prot_interval(struct scsi_cmnd *scmd)
295*4882a593Smuzhiyun {
296*4882a593Smuzhiyun 	return scmd->device->sector_size;
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun 
scsi_prot_sg_count(struct scsi_cmnd * cmd)299*4882a593Smuzhiyun static inline unsigned scsi_prot_sg_count(struct scsi_cmnd *cmd)
300*4882a593Smuzhiyun {
301*4882a593Smuzhiyun 	return cmd->prot_sdb ? cmd->prot_sdb->table.nents : 0;
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun 
scsi_prot_sglist(struct scsi_cmnd * cmd)304*4882a593Smuzhiyun static inline struct scatterlist *scsi_prot_sglist(struct scsi_cmnd *cmd)
305*4882a593Smuzhiyun {
306*4882a593Smuzhiyun 	return cmd->prot_sdb ? cmd->prot_sdb->table.sgl : NULL;
307*4882a593Smuzhiyun }
308*4882a593Smuzhiyun 
scsi_prot(struct scsi_cmnd * cmd)309*4882a593Smuzhiyun static inline struct scsi_data_buffer *scsi_prot(struct scsi_cmnd *cmd)
310*4882a593Smuzhiyun {
311*4882a593Smuzhiyun 	return cmd->prot_sdb;
312*4882a593Smuzhiyun }
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun #define scsi_for_each_prot_sg(cmd, sg, nseg, __i)		\
315*4882a593Smuzhiyun 	for_each_sg(scsi_prot_sglist(cmd), sg, nseg, __i)
316*4882a593Smuzhiyun 
set_msg_byte(struct scsi_cmnd * cmd,char status)317*4882a593Smuzhiyun static inline void set_msg_byte(struct scsi_cmnd *cmd, char status)
318*4882a593Smuzhiyun {
319*4882a593Smuzhiyun 	cmd->result = (cmd->result & 0xffff00ff) | (status << 8);
320*4882a593Smuzhiyun }
321*4882a593Smuzhiyun 
set_host_byte(struct scsi_cmnd * cmd,char status)322*4882a593Smuzhiyun static inline void set_host_byte(struct scsi_cmnd *cmd, char status)
323*4882a593Smuzhiyun {
324*4882a593Smuzhiyun 	cmd->result = (cmd->result & 0xff00ffff) | (status << 16);
325*4882a593Smuzhiyun }
326*4882a593Smuzhiyun 
set_driver_byte(struct scsi_cmnd * cmd,char status)327*4882a593Smuzhiyun static inline void set_driver_byte(struct scsi_cmnd *cmd, char status)
328*4882a593Smuzhiyun {
329*4882a593Smuzhiyun 	cmd->result = (cmd->result & 0x00ffffff) | (status << 24);
330*4882a593Smuzhiyun }
331*4882a593Smuzhiyun 
scsi_transfer_length(struct scsi_cmnd * scmd)332*4882a593Smuzhiyun static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd)
333*4882a593Smuzhiyun {
334*4882a593Smuzhiyun 	unsigned int xfer_len = scmd->sdb.length;
335*4882a593Smuzhiyun 	unsigned int prot_interval = scsi_prot_interval(scmd);
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun 	if (scmd->prot_flags & SCSI_PROT_TRANSFER_PI)
338*4882a593Smuzhiyun 		xfer_len += (xfer_len >> ilog2(prot_interval)) * 8;
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	return xfer_len;
341*4882a593Smuzhiyun }
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun #endif /* _SCSI_SCSI_CMND_H */
344