aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/sd.c3
-rw-r--r--drivers/scsi/sd.h2
-rw-r--r--drivers/scsi/sd_dif.c37
3 files changed, 23 insertions, 19 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index a494a2ec67d7..7c4d2e68df1c 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -575,7 +575,8 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
575 575
576 /* If DIF or DIX is enabled, tell HBA how to handle request */ 576 /* If DIF or DIX is enabled, tell HBA how to handle request */
577 if (host_dif || scsi_prot_sg_count(SCpnt)) 577 if (host_dif || scsi_prot_sg_count(SCpnt))
578 sd_dif_op(SCpnt, sdkp->protection_type, scsi_prot_sg_count(SCpnt)); 578 sd_dif_op(SCpnt, host_dif, scsi_prot_sg_count(SCpnt),
579 sdkp->protection_type);
579 580
580 /* 581 /*
581 * We shouldn't disconnect in the middle of a sector, so with a dumb 582 * We shouldn't disconnect in the middle of a sector, so with a dumb
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index 95b9f06534d5..a92b991d98ab 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -99,7 +99,7 @@ struct sd_dif_tuple {
99 99
100#if defined(CONFIG_BLK_DEV_INTEGRITY) 100#if defined(CONFIG_BLK_DEV_INTEGRITY)
101 101
102extern void sd_dif_op(struct scsi_cmnd *, unsigned int, unsigned int); 102extern void sd_dif_op(struct scsi_cmnd *, unsigned int, unsigned int, unsigned int);
103extern void sd_dif_config_host(struct scsi_disk *); 103extern void sd_dif_config_host(struct scsi_disk *);
104extern int sd_dif_prepare(struct request *rq, sector_t, unsigned int); 104extern int sd_dif_prepare(struct request *rq, sector_t, unsigned int);
105extern void sd_dif_complete(struct scsi_cmnd *, unsigned int); 105extern void sd_dif_complete(struct scsi_cmnd *, unsigned int);
diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c
index 943fde7e7ffb..194c7706083b 100644
--- a/drivers/scsi/sd_dif.c
+++ b/drivers/scsi/sd_dif.c
@@ -311,24 +311,26 @@ void sd_dif_config_host(struct scsi_disk *sdkp)
311 struct scsi_device *sdp = sdkp->device; 311 struct scsi_device *sdp = sdkp->device;
312 struct gendisk *disk = sdkp->disk; 312 struct gendisk *disk = sdkp->disk;
313 u8 type = sdkp->protection_type; 313 u8 type = sdkp->protection_type;
314 int dif, dix;
314 315
315 /* If this HBA doesn't support DIX, resort to normal I/O or DIF */ 316 dif = scsi_host_dif_capable(sdp->host, type);
316 if (scsi_host_dix_capable(sdp->host, type) == 0) { 317 dix = scsi_host_dix_capable(sdp->host, type);
317 318
318 if (type == SD_DIF_TYPE0_PROTECTION) 319 if (!dix && scsi_host_dix_capable(sdp->host, 0)) {
319 return; 320 dif = 0; dix = 1;
320 321 }
321 if (scsi_host_dif_capable(sdp->host, type) == 0) {
322 sd_printk(KERN_INFO, sdkp, "Type %d protection " \
323 "unsupported by HBA. Disabling DIF.\n", type);
324 return;
325 }
326 322
327 sd_printk(KERN_INFO, sdkp, "Enabling DIF Type %d protection\n", 323 if (type) {
328 type); 324 if (dif)
325 sd_printk(KERN_INFO, sdkp,
326 "Enabling DIF Type %d protection\n", type);
327 else
328 sd_printk(KERN_INFO, sdkp,
329 "Disabling DIF Type %d protection\n", type);
330 }
329 331
332 if (!dix)
330 return; 333 return;
331 }
332 334
333 /* Enable DMA of protection information */ 335 /* Enable DMA of protection information */
334 if (scsi_host_get_guard(sdkp->device->host) & SHOST_DIX_GUARD_IP) 336 if (scsi_host_get_guard(sdkp->device->host) & SHOST_DIX_GUARD_IP)
@@ -343,10 +345,10 @@ void sd_dif_config_host(struct scsi_disk *sdkp)
343 blk_integrity_register(disk, &dif_type1_integrity_crc); 345 blk_integrity_register(disk, &dif_type1_integrity_crc);
344 346
345 sd_printk(KERN_INFO, sdkp, 347 sd_printk(KERN_INFO, sdkp,
346 "Enabling %s integrity protection\n", disk->integrity->name); 348 "Enabling DIX %s protection\n", disk->integrity->name);
347 349
348 /* Signal to block layer that we support sector tagging */ 350 /* Signal to block layer that we support sector tagging */
349 if (type && sdkp->ATO) { 351 if (dif && type && sdkp->ATO) {
350 if (type == SD_DIF_TYPE3_PROTECTION) 352 if (type == SD_DIF_TYPE3_PROTECTION)
351 disk->integrity->tag_size = sizeof(u16) + sizeof(u32); 353 disk->integrity->tag_size = sizeof(u16) + sizeof(u32);
352 else 354 else
@@ -360,7 +362,7 @@ void sd_dif_config_host(struct scsi_disk *sdkp)
360/* 362/*
361 * DIF DMA operation magic decoder ring. 363 * DIF DMA operation magic decoder ring.
362 */ 364 */
363void sd_dif_op(struct scsi_cmnd *scmd, unsigned int dif, unsigned int dix) 365void sd_dif_op(struct scsi_cmnd *scmd, unsigned int dif, unsigned int dix, unsigned int type)
364{ 366{
365 int csum_convert, prot_op; 367 int csum_convert, prot_op;
366 368
@@ -405,7 +407,8 @@ void sd_dif_op(struct scsi_cmnd *scmd, unsigned int dif, unsigned int dix)
405 } 407 }
406 408
407 scsi_set_prot_op(scmd, prot_op); 409 scsi_set_prot_op(scmd, prot_op);
408 scsi_set_prot_type(scmd, dif); 410 if (dif)
411 scsi_set_prot_type(scmd, type);
409} 412}
410 413
411/* 414/*