1
2#ifndef _SCSI_SCSI_CMND_H
3#define _SCSI_SCSI_CMND_H
4
5#include <linux/dma-mapping.h>
6#include <linux/blkdev.h>
7#include <linux/t10-pi.h>
8#include <linux/list.h>
9#include <linux/types.h>
10#include <linux/timer.h>
11#include <linux/scatterlist.h>
12#include <scsi/scsi_device.h>
13#include <scsi/scsi_request.h>
14
15struct Scsi_Host;
16struct scsi_driver;
17
18
19
20
21
22
23
24
25
26
27
28
29
30#define MAX_COMMAND_SIZE 16
31#if (MAX_COMMAND_SIZE > BLK_MAX_CDB)
32# error MAX_COMMAND_SIZE can not be bigger than BLK_MAX_CDB
33#endif
34
35struct scsi_data_buffer {
36 struct sg_table table;
37 unsigned length;
38};
39
40
41struct scsi_pointer {
42 char *ptr;
43 int this_residual;
44 struct scatterlist *buffer;
45 int buffers_residual;
46
47 dma_addr_t dma_handle;
48
49 volatile int Status;
50 volatile int Message;
51 volatile int have_data_in;
52 volatile int sent_command;
53 volatile int phase;
54};
55
56
57#define SCMD_TAGGED (1 << 0)
58#define SCMD_UNCHECKED_ISA_DMA (1 << 1)
59#define SCMD_INITIALIZED (1 << 2)
60#define SCMD_LAST (1 << 3)
61
62#define SCMD_PRESERVED_FLAGS (SCMD_UNCHECKED_ISA_DMA | SCMD_INITIALIZED)
63
64
65#define SCMD_STATE_COMPLETE 0
66#define SCMD_STATE_INFLIGHT 1
67
68struct scsi_cmnd {
69 struct scsi_request req;
70 struct scsi_device *device;
71 struct list_head eh_entry;
72 struct delayed_work abort_work;
73
74 struct rcu_head rcu;
75
76 int eh_eflags;
77
78
79
80
81
82
83 unsigned long jiffies_at_alloc;
84
85 int retries;
86 int allowed;
87
88 unsigned char prot_op;
89 unsigned char prot_type;
90 unsigned char prot_flags;
91
92 unsigned short cmd_len;
93 enum dma_data_direction sc_data_direction;
94
95
96 unsigned char *cmnd;
97
98
99
100 struct scsi_data_buffer sdb;
101 struct scsi_data_buffer *prot_sdb;
102
103 unsigned underflow;
104
105
106 unsigned transfersize;
107
108
109
110
111
112 struct request *request;
113
114
115 unsigned char *sense_buffer;
116
117
118
119
120
121
122
123 void (*scsi_done) (struct scsi_cmnd *);
124
125
126
127
128
129 struct scsi_pointer SCp;
130
131 unsigned char *host_scribble;
132
133
134
135
136
137
138
139 int result;
140 int flags;
141 unsigned long state;
142
143 unsigned char tag;
144 unsigned int extra_len;
145};
146
147
148
149
150
151static inline void *scsi_cmd_priv(struct scsi_cmnd *cmd)
152{
153 return cmd + 1;
154}
155
156
157static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd)
158{
159 return *(struct scsi_driver **)cmd->request->rq_disk->private_data;
160}
161
162extern void scsi_finish_command(struct scsi_cmnd *cmd);
163
164extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count,
165 size_t *offset, size_t *len);
166extern void scsi_kunmap_atomic_sg(void *virt);
167
168blk_status_t scsi_alloc_sgtables(struct scsi_cmnd *cmd);
169void scsi_free_sgtables(struct scsi_cmnd *cmd);
170
171#ifdef CONFIG_SCSI_DMA
172extern int scsi_dma_map(struct scsi_cmnd *cmd);
173extern void scsi_dma_unmap(struct scsi_cmnd *cmd);
174#else
175static inline int scsi_dma_map(struct scsi_cmnd *cmd) { return -ENOSYS; }
176static inline void scsi_dma_unmap(struct scsi_cmnd *cmd) { }
177#endif
178
179static inline unsigned scsi_sg_count(struct scsi_cmnd *cmd)
180{
181 return cmd->sdb.table.nents;
182}
183
184static inline struct scatterlist *scsi_sglist(struct scsi_cmnd *cmd)
185{
186 return cmd->sdb.table.sgl;
187}
188
189static inline unsigned scsi_bufflen(struct scsi_cmnd *cmd)
190{
191 return cmd->sdb.length;
192}
193
194static inline void scsi_set_resid(struct scsi_cmnd *cmd, unsigned int resid)
195{
196 cmd->req.resid_len = resid;
197}
198
199static inline unsigned int scsi_get_resid(struct scsi_cmnd *cmd)
200{
201 return cmd->req.resid_len;
202}
203
204#define scsi_for_each_sg(cmd, sg, nseg, __i) \
205 for_each_sg(scsi_sglist(cmd), sg, nseg, __i)
206
207static inline int scsi_sg_copy_from_buffer(struct scsi_cmnd *cmd,
208 void *buf, int buflen)
209{
210 return sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd),
211 buf, buflen);
212}
213
214static inline int scsi_sg_copy_to_buffer(struct scsi_cmnd *cmd,
215 void *buf, int buflen)
216{
217 return sg_copy_to_buffer(scsi_sglist(cmd), scsi_sg_count(cmd),
218 buf, buflen);
219}
220
221
222
223
224
225enum scsi_prot_operations {
226
227 SCSI_PROT_NORMAL = 0,
228
229
230 SCSI_PROT_READ_INSERT,
231 SCSI_PROT_WRITE_STRIP,
232
233
234 SCSI_PROT_READ_STRIP,
235 SCSI_PROT_WRITE_INSERT,
236
237
238 SCSI_PROT_READ_PASS,
239 SCSI_PROT_WRITE_PASS,
240};
241
242static inline void scsi_set_prot_op(struct scsi_cmnd *scmd, unsigned char op)
243{
244 scmd->prot_op = op;
245}
246
247static inline unsigned char scsi_get_prot_op(struct scsi_cmnd *scmd)
248{
249 return scmd->prot_op;
250}
251
252enum scsi_prot_flags {
253 SCSI_PROT_TRANSFER_PI = 1 << 0,
254 SCSI_PROT_GUARD_CHECK = 1 << 1,
255 SCSI_PROT_REF_CHECK = 1 << 2,
256 SCSI_PROT_REF_INCREMENT = 1 << 3,
257 SCSI_PROT_IP_CHECKSUM = 1 << 4,
258};
259
260
261
262
263
264
265
266enum scsi_prot_target_type {
267 SCSI_PROT_DIF_TYPE0 = 0,
268 SCSI_PROT_DIF_TYPE1,
269 SCSI_PROT_DIF_TYPE2,
270 SCSI_PROT_DIF_TYPE3,
271};
272
273static inline void scsi_set_prot_type(struct scsi_cmnd *scmd, unsigned char type)
274{
275 scmd->prot_type = type;
276}
277
278static inline unsigned char scsi_get_prot_type(struct scsi_cmnd *scmd)
279{
280 return scmd->prot_type;
281}
282
283static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd)
284{
285 return blk_rq_pos(scmd->request);
286}
287
288static inline unsigned int scsi_prot_interval(struct scsi_cmnd *scmd)
289{
290 return scmd->device->sector_size;
291}
292
293static inline unsigned scsi_prot_sg_count(struct scsi_cmnd *cmd)
294{
295 return cmd->prot_sdb ? cmd->prot_sdb->table.nents : 0;
296}
297
298static inline struct scatterlist *scsi_prot_sglist(struct scsi_cmnd *cmd)
299{
300 return cmd->prot_sdb ? cmd->prot_sdb->table.sgl : NULL;
301}
302
303static inline struct scsi_data_buffer *scsi_prot(struct scsi_cmnd *cmd)
304{
305 return cmd->prot_sdb;
306}
307
308#define scsi_for_each_prot_sg(cmd, sg, nseg, __i) \
309 for_each_sg(scsi_prot_sglist(cmd), sg, nseg, __i)
310
311static inline void set_msg_byte(struct scsi_cmnd *cmd, char status)
312{
313 cmd->result = (cmd->result & 0xffff00ff) | (status << 8);
314}
315
316static inline void set_host_byte(struct scsi_cmnd *cmd, char status)
317{
318 cmd->result = (cmd->result & 0xff00ffff) | (status << 16);
319}
320
321static inline void set_driver_byte(struct scsi_cmnd *cmd, char status)
322{
323 cmd->result = (cmd->result & 0x00ffffff) | (status << 24);
324}
325
326static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd)
327{
328 unsigned int xfer_len = scmd->sdb.length;
329 unsigned int prot_interval = scsi_prot_interval(scmd);
330
331 if (scmd->prot_flags & SCSI_PROT_TRANSFER_PI)
332 xfer_len += (xfer_len >> ilog2(prot_interval)) * 8;
333
334 return xfer_len;
335}
336
337#endif
338