Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[SCSI] isci: T10 DIF support

This allows the controller to do WRITE_INSERT and READ_STRIP for SAS
disks that support protection information. SAS disks must be formatted
with protection information to use this feature via sg_format.

sg3_utils-1.32 -- sg_format version 1.19 20110730
sg_format usage:
sg_format --format --verbose --pinfo /dev/sda

Acked-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>

authored by

Dave Jiang and committed by
James Bottomley
3d2d7525 a6fe35c0

+193 -16
+7
drivers/scsi/isci/init.c
··· 528 528 goto err_host_alloc; 529 529 } 530 530 pci_info->hosts[i] = h; 531 + 532 + /* turn on DIF support */ 533 + scsi_host_set_prot(h->shost, 534 + SHOST_DIF_TYPE1_PROTECTION | 535 + SHOST_DIF_TYPE2_PROTECTION | 536 + SHOST_DIF_TYPE3_PROTECTION); 537 + scsi_host_set_guard(h->shost, SHOST_DIX_GUARD_CRC); 531 538 } 532 539 533 540 err = isci_setup_interrupts(pdev);
+147
drivers/scsi/isci/request.c
··· 53 53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 54 54 */ 55 55 56 + #include <scsi/scsi_cmnd.h> 56 57 #include "isci.h" 57 58 #include "task.h" 58 59 #include "request.h" ··· 265 264 task_context->response_iu_lower = lower_32_bits(dma_addr); 266 265 } 267 266 267 + static u8 scu_bg_blk_size(struct scsi_device *sdp) 268 + { 269 + switch (sdp->sector_size) { 270 + case 512: 271 + return 0; 272 + case 1024: 273 + return 1; 274 + case 4096: 275 + return 3; 276 + default: 277 + return 0xff; 278 + } 279 + } 280 + 281 + static u32 scu_dif_bytes(u32 len, u32 sector_size) 282 + { 283 + return (len >> ilog2(sector_size)) * 8; 284 + } 285 + 286 + static void scu_ssp_ireq_dif_insert(struct isci_request *ireq, u8 type, u8 op) 287 + { 288 + struct scu_task_context *tc = ireq->tc; 289 + struct scsi_cmnd *scmd = ireq->ttype_ptr.io_task_ptr->uldd_task; 290 + u8 blk_sz = scu_bg_blk_size(scmd->device); 291 + 292 + tc->block_guard_enable = 1; 293 + tc->blk_prot_en = 1; 294 + tc->blk_sz = blk_sz; 295 + /* DIF write insert */ 296 + tc->blk_prot_func = 0x2; 297 + 298 + tc->transfer_length_bytes += scu_dif_bytes(tc->transfer_length_bytes, 299 + scmd->device->sector_size); 300 + 301 + /* always init to 0, used by hw */ 302 + tc->interm_crc_val = 0; 303 + 304 + tc->init_crc_seed = 0; 305 + tc->app_tag_verify = 0; 306 + tc->app_tag_gen = 0; 307 + tc->ref_tag_seed_verify = 0; 308 + 309 + /* always init to same as bg_blk_sz */ 310 + tc->UD_bytes_immed_val = scmd->device->sector_size; 311 + 312 + tc->reserved_DC_0 = 0; 313 + 314 + /* always init to 8 */ 315 + tc->DIF_bytes_immed_val = 8; 316 + 317 + tc->reserved_DC_1 = 0; 318 + tc->bgc_blk_sz = scmd->device->sector_size; 319 + tc->reserved_E0_0 = 0; 320 + tc->app_tag_gen_mask = 0; 321 + 322 + /** setup block guard control **/ 323 + tc->bgctl = 0; 324 + 325 + /* DIF write insert */ 326 + tc->bgctl_f.op = 0x2; 327 + 328 + tc->app_tag_verify_mask = 0; 329 + 330 + /* must init to 0 for hw */ 331 + tc->blk_guard_err = 0; 332 + 333 + tc->reserved_E8_0 = 0; 334 + 335 + if ((type & SCSI_PROT_DIF_TYPE1) || (type & SCSI_PROT_DIF_TYPE2)) 336 + tc->ref_tag_seed_gen = scsi_get_lba(scmd) & 0xffffffff; 337 + else if (type & SCSI_PROT_DIF_TYPE3) 338 + tc->ref_tag_seed_gen = 0; 339 + } 340 + 341 + static void scu_ssp_ireq_dif_strip(struct isci_request *ireq, u8 type, u8 op) 342 + { 343 + struct scu_task_context *tc = ireq->tc; 344 + struct scsi_cmnd *scmd = ireq->ttype_ptr.io_task_ptr->uldd_task; 345 + u8 blk_sz = scu_bg_blk_size(scmd->device); 346 + 347 + tc->block_guard_enable = 1; 348 + tc->blk_prot_en = 1; 349 + tc->blk_sz = blk_sz; 350 + /* DIF read strip */ 351 + tc->blk_prot_func = 0x1; 352 + 353 + tc->transfer_length_bytes += scu_dif_bytes(tc->transfer_length_bytes, 354 + scmd->device->sector_size); 355 + 356 + /* always init to 0, used by hw */ 357 + tc->interm_crc_val = 0; 358 + 359 + tc->init_crc_seed = 0; 360 + tc->app_tag_verify = 0; 361 + tc->app_tag_gen = 0; 362 + 363 + if ((type & SCSI_PROT_DIF_TYPE1) || (type & SCSI_PROT_DIF_TYPE2)) 364 + tc->ref_tag_seed_verify = scsi_get_lba(scmd) & 0xffffffff; 365 + else if (type & SCSI_PROT_DIF_TYPE3) 366 + tc->ref_tag_seed_verify = 0; 367 + 368 + /* always init to same as bg_blk_sz */ 369 + tc->UD_bytes_immed_val = scmd->device->sector_size; 370 + 371 + tc->reserved_DC_0 = 0; 372 + 373 + /* always init to 8 */ 374 + tc->DIF_bytes_immed_val = 8; 375 + 376 + tc->reserved_DC_1 = 0; 377 + tc->bgc_blk_sz = scmd->device->sector_size; 378 + tc->reserved_E0_0 = 0; 379 + tc->app_tag_gen_mask = 0; 380 + 381 + /** setup block guard control **/ 382 + tc->bgctl = 0; 383 + 384 + /* DIF read strip */ 385 + tc->bgctl_f.crc_verify = 1; 386 + tc->bgctl_f.op = 0x1; 387 + if ((type & SCSI_PROT_DIF_TYPE1) || (type & SCSI_PROT_DIF_TYPE2)) { 388 + tc->bgctl_f.ref_tag_chk = 1; 389 + tc->bgctl_f.app_f_detect = 1; 390 + } else if (type & SCSI_PROT_DIF_TYPE3) 391 + tc->bgctl_f.app_ref_f_detect = 1; 392 + 393 + tc->app_tag_verify_mask = 0; 394 + 395 + /* must init to 0 for hw */ 396 + tc->blk_guard_err = 0; 397 + 398 + tc->reserved_E8_0 = 0; 399 + tc->ref_tag_seed_gen = 0; 400 + } 401 + 268 402 /** 269 403 * This method is will fill in the SCU Task Context for a SSP IO request. 270 404 * @sci_req: ··· 410 274 u32 len) 411 275 { 412 276 struct scu_task_context *task_context = ireq->tc; 277 + struct sas_task *sas_task = ireq->ttype_ptr.io_task_ptr; 278 + struct scsi_cmnd *scmd = sas_task->uldd_task; 279 + u8 prot_type = scsi_get_prot_type(scmd); 280 + u8 prot_op = scsi_get_prot_op(scmd); 413 281 414 282 scu_ssp_reqeust_construct_task_context(ireq, task_context); 415 283 ··· 436 296 437 297 if (task_context->transfer_length_bytes > 0) 438 298 sci_request_build_sgl(ireq); 299 + 300 + if (prot_type != SCSI_PROT_DIF_TYPE0) { 301 + if (prot_op == SCSI_PROT_READ_STRIP) 302 + scu_ssp_ireq_dif_strip(ireq, prot_type, prot_op); 303 + else if (prot_op == SCSI_PROT_WRITE_INSERT) 304 + scu_ssp_ireq_dif_insert(ireq, prot_type, prot_op); 305 + } 439 306 } 440 307 441 308 /**
+39 -16
drivers/scsi/isci/scu_task_context.h
··· 866 866 struct transport_snapshot snapshot; /* read only set to 0 */ 867 867 868 868 /* OFFSET 0x5C */ 869 - u32 block_protection_enable:1; 870 - u32 block_size:2; 871 - u32 block_protection_function:2; 869 + u32 blk_prot_en:1; 870 + u32 blk_sz:2; 871 + u32 blk_prot_func:2; 872 872 u32 reserved_5C_0:9; 873 873 u32 active_sgl_element:2; /* read only set to 0 */ 874 874 u32 sgl_exhausted:1; /* read only set to 0 */ ··· 896 896 u32 reserved_C4_CC[3]; 897 897 898 898 /* OFFSET 0xD0 */ 899 - u32 intermediate_crc_value:16; 900 - u32 initial_crc_seed:16; 899 + u32 interm_crc_val:16; 900 + u32 init_crc_seed:16; 901 901 902 902 /* OFFSET 0xD4 */ 903 - u32 application_tag_for_verify:16; 904 - u32 application_tag_for_generate:16; 903 + u32 app_tag_verify:16; 904 + u32 app_tag_gen:16; 905 905 906 906 /* OFFSET 0xD8 */ 907 - u32 reference_tag_seed_for_verify_function; 907 + u32 ref_tag_seed_verify; 908 908 909 909 /* OFFSET 0xDC */ 910 - u32 reserved_DC; 910 + u32 UD_bytes_immed_val:13; 911 + u32 reserved_DC_0:3; 912 + u32 DIF_bytes_immed_val:4; 913 + u32 reserved_DC_1:12; 911 914 912 915 /* OFFSET 0xE0 */ 913 - u32 reserved_E0_0:16; 914 - u32 application_tag_mask_for_generate:16; 916 + u32 bgc_blk_sz:13; 917 + u32 reserved_E0_0:3; 918 + u32 app_tag_gen_mask:16; 915 919 916 920 /* OFFSET 0xE4 */ 917 - u32 block_protection_control:16; 918 - u32 application_tag_mask_for_verify:16; 921 + union { 922 + u16 bgctl; 923 + struct { 924 + u16 crc_verify:1; 925 + u16 app_tag_chk:1; 926 + u16 ref_tag_chk:1; 927 + u16 op:2; 928 + u16 legacy:1; 929 + u16 invert_crc_seed:1; 930 + u16 ref_tag_gen:1; 931 + u16 fixed_ref_tag:1; 932 + u16 invert_crc:1; 933 + u16 app_ref_f_detect:1; 934 + u16 uninit_dif_check_err:1; 935 + u16 uninit_dif_bypass:1; 936 + u16 app_f_detect:1; 937 + u16 reserved_0:2; 938 + } bgctl_f; 939 + }; 940 + 941 + u16 app_tag_verify_mask; 919 942 920 943 /* OFFSET 0xE8 */ 921 - u32 block_protection_error:8; 944 + u32 blk_guard_err:8; 922 945 u32 reserved_E8_0:24; 923 946 924 947 /* OFFSET 0xEC */ 925 - u32 reference_tag_seed_for_verify; 948 + u32 ref_tag_seed_gen; 926 949 927 950 /* OFFSET 0xF0 */ 928 951 u32 intermediate_crc_valid_snapshot:16; ··· 960 937 /* OFFSET 0xFC */ 961 938 u32 reference_tag_seed_for_generate_function_snapshot; 962 939 963 - }; 940 + } __packed; 964 941 965 942 #endif /* _SCU_TASK_CONTEXT_H_ */