diff options
Diffstat (limited to 'drivers/scsi/sd_dif.c')
-rw-r--r-- | drivers/scsi/sd_dif.c | 37 |
1 files changed, 20 insertions, 17 deletions
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 | */ |
363 | void sd_dif_op(struct scsi_cmnd *scmd, unsigned int dif, unsigned int dix) | 365 | void 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 | /* |