diff options
-rw-r--r-- | drivers/scsi/scsi_error.c | 3 | ||||
-rw-r--r-- | include/scsi/scsi_cmnd.h | 66 | ||||
-rw-r--r-- | include/scsi/scsi_eh.h | 1 |
3 files changed, 70 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 006a95916f72..a69397fd314a 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -664,7 +664,9 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, | |||
664 | ses->sdb = scmd->sdb; | 664 | ses->sdb = scmd->sdb; |
665 | ses->next_rq = scmd->request->next_rq; | 665 | ses->next_rq = scmd->request->next_rq; |
666 | ses->result = scmd->result; | 666 | ses->result = scmd->result; |
667 | ses->prot_op = scmd->prot_op; | ||
667 | 668 | ||
669 | scmd->prot_op = SCSI_PROT_NORMAL; | ||
668 | scmd->cmnd = ses->eh_cmnd; | 670 | scmd->cmnd = ses->eh_cmnd; |
669 | memset(scmd->cmnd, 0, BLK_MAX_CDB); | 671 | memset(scmd->cmnd, 0, BLK_MAX_CDB); |
670 | memset(&scmd->sdb, 0, sizeof(scmd->sdb)); | 672 | memset(&scmd->sdb, 0, sizeof(scmd->sdb)); |
@@ -722,6 +724,7 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses) | |||
722 | scmd->sdb = ses->sdb; | 724 | scmd->sdb = ses->sdb; |
723 | scmd->request->next_rq = ses->next_rq; | 725 | scmd->request->next_rq = ses->next_rq; |
724 | scmd->result = ses->result; | 726 | scmd->result = ses->result; |
727 | scmd->prot_op = ses->prot_op; | ||
725 | } | 728 | } |
726 | EXPORT_SYMBOL(scsi_eh_restore_cmnd); | 729 | EXPORT_SYMBOL(scsi_eh_restore_cmnd); |
727 | 730 | ||
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 66c944849d6b..402c1078d01c 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h | |||
@@ -77,6 +77,9 @@ struct scsi_cmnd { | |||
77 | int allowed; | 77 | int allowed; |
78 | int timeout_per_command; | 78 | int timeout_per_command; |
79 | 79 | ||
80 | unsigned char prot_op; | ||
81 | unsigned char prot_type; | ||
82 | |||
80 | unsigned short cmd_len; | 83 | unsigned short cmd_len; |
81 | enum dma_data_direction sc_data_direction; | 84 | enum dma_data_direction sc_data_direction; |
82 | 85 | ||
@@ -208,4 +211,67 @@ static inline int scsi_sg_copy_to_buffer(struct scsi_cmnd *cmd, | |||
208 | buf, buflen); | 211 | buf, buflen); |
209 | } | 212 | } |
210 | 213 | ||
214 | /* | ||
215 | * The operations below are hints that tell the controller driver how | ||
216 | * to handle I/Os with DIF or similar types of protection information. | ||
217 | */ | ||
218 | enum scsi_prot_operations { | ||
219 | /* Normal I/O */ | ||
220 | SCSI_PROT_NORMAL = 0, | ||
221 | |||
222 | /* OS-HBA: Protected, HBA-Target: Unprotected */ | ||
223 | SCSI_PROT_READ_INSERT, | ||
224 | SCSI_PROT_WRITE_STRIP, | ||
225 | |||
226 | /* OS-HBA: Unprotected, HBA-Target: Protected */ | ||
227 | SCSI_PROT_READ_STRIP, | ||
228 | SCSI_PROT_WRITE_INSERT, | ||
229 | |||
230 | /* OS-HBA: Protected, HBA-Target: Protected */ | ||
231 | SCSI_PROT_READ_PASS, | ||
232 | SCSI_PROT_WRITE_PASS, | ||
233 | |||
234 | /* OS-HBA: Protected, HBA-Target: Protected, checksum conversion */ | ||
235 | SCSI_PROT_READ_CONVERT, | ||
236 | SCSI_PROT_WRITE_CONVERT, | ||
237 | }; | ||
238 | |||
239 | static inline void scsi_set_prot_op(struct scsi_cmnd *scmd, unsigned char op) | ||
240 | { | ||
241 | scmd->prot_op = op; | ||
242 | } | ||
243 | |||
244 | static inline unsigned char scsi_get_prot_op(struct scsi_cmnd *scmd) | ||
245 | { | ||
246 | return scmd->prot_op; | ||
247 | } | ||
248 | |||
249 | /* | ||
250 | * The controller usually does not know anything about the target it | ||
251 | * is communicating with. However, when DIX is enabled the controller | ||
252 | * must be know target type so it can verify the protection | ||
253 | * information passed along with the I/O. | ||
254 | */ | ||
255 | enum scsi_prot_target_type { | ||
256 | SCSI_PROT_DIF_TYPE0 = 0, | ||
257 | SCSI_PROT_DIF_TYPE1, | ||
258 | SCSI_PROT_DIF_TYPE2, | ||
259 | SCSI_PROT_DIF_TYPE3, | ||
260 | }; | ||
261 | |||
262 | static inline void scsi_set_prot_type(struct scsi_cmnd *scmd, unsigned char type) | ||
263 | { | ||
264 | scmd->prot_type = type; | ||
265 | } | ||
266 | |||
267 | static inline unsigned char scsi_get_prot_type(struct scsi_cmnd *scmd) | ||
268 | { | ||
269 | return scmd->prot_type; | ||
270 | } | ||
271 | |||
272 | static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd) | ||
273 | { | ||
274 | return scmd->request->sector; | ||
275 | } | ||
276 | |||
211 | #endif /* _SCSI_SCSI_CMND_H */ | 277 | #endif /* _SCSI_SCSI_CMND_H */ |
diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h index 2a9add21267d..e5499ed0e376 100644 --- a/include/scsi/scsi_eh.h +++ b/include/scsi/scsi_eh.h | |||
@@ -75,6 +75,7 @@ struct scsi_eh_save { | |||
75 | int result; | 75 | int result; |
76 | enum dma_data_direction data_direction; | 76 | enum dma_data_direction data_direction; |
77 | unsigned char cmd_len; | 77 | unsigned char cmd_len; |
78 | unsigned char prot_op; | ||
78 | unsigned char *cmnd; | 79 | unsigned char *cmnd; |
79 | struct scsi_data_buffer sdb; | 80 | struct scsi_data_buffer sdb; |
80 | struct request *next_rq; | 81 | struct request *next_rq; |