diff options
author | James Smart <james.smart@emulex.com> | 2012-01-18 16:25:09 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-19 09:08:52 -0500 |
commit | acd6859b084d1e1b3ec8bc9befe6532223260d33 (patch) | |
tree | e06983f9b080226622fa06c071f3223caac4c7fd /drivers/scsi/lpfc | |
parent | 6b5151fd7baec6812fece993ddd7a2cf9fd0125f (diff) |
[SCSI] lpfc 8.3.29: T10 Diff fixes and enhancements
T10 Diff fixes and enhancements:
- Add SLI4 Lancer support for T10 DIF / BlockGuard (121980)
- Fix SLI4 BlockGuard behavior when protection data is generated by HBA (121980)
- Enhance debugfs for injecting T10 DIF errors (123966, 132966)
- Fix Incorrect usage of bghm for BlockGuard errors (127022)
Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 13 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_debugfs.c | 19 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw4.h | 23 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 10 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 1054 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 54 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.h | 1 |
7 files changed, 1049 insertions, 125 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 825f9307417a..5fc044ff656e 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -534,6 +534,7 @@ struct lpfc_hba { | |||
534 | void (*lpfc_scsi_prep_cmnd) | 534 | void (*lpfc_scsi_prep_cmnd) |
535 | (struct lpfc_vport *, struct lpfc_scsi_buf *, | 535 | (struct lpfc_vport *, struct lpfc_scsi_buf *, |
536 | struct lpfc_nodelist *); | 536 | struct lpfc_nodelist *); |
537 | |||
537 | /* IOCB interface function jump table entries */ | 538 | /* IOCB interface function jump table entries */ |
538 | int (*__lpfc_sli_issue_iocb) | 539 | int (*__lpfc_sli_issue_iocb) |
539 | (struct lpfc_hba *, uint32_t, | 540 | (struct lpfc_hba *, uint32_t, |
@@ -541,8 +542,6 @@ struct lpfc_hba { | |||
541 | void (*__lpfc_sli_release_iocbq)(struct lpfc_hba *, | 542 | void (*__lpfc_sli_release_iocbq)(struct lpfc_hba *, |
542 | struct lpfc_iocbq *); | 543 | struct lpfc_iocbq *); |
543 | int (*lpfc_hba_down_post)(struct lpfc_hba *phba); | 544 | int (*lpfc_hba_down_post)(struct lpfc_hba *phba); |
544 | |||
545 | |||
546 | IOCB_t * (*lpfc_get_iocb_from_iocbq) | 545 | IOCB_t * (*lpfc_get_iocb_from_iocbq) |
547 | (struct lpfc_iocbq *); | 546 | (struct lpfc_iocbq *); |
548 | void (*lpfc_scsi_cmd_iocb_cmpl) | 547 | void (*lpfc_scsi_cmd_iocb_cmpl) |
@@ -551,10 +550,12 @@ struct lpfc_hba { | |||
551 | /* MBOX interface function jump table entries */ | 550 | /* MBOX interface function jump table entries */ |
552 | int (*lpfc_sli_issue_mbox) | 551 | int (*lpfc_sli_issue_mbox) |
553 | (struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); | 552 | (struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); |
553 | |||
554 | /* Slow-path IOCB process function jump table entries */ | 554 | /* Slow-path IOCB process function jump table entries */ |
555 | void (*lpfc_sli_handle_slow_ring_event) | 555 | void (*lpfc_sli_handle_slow_ring_event) |
556 | (struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 556 | (struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
557 | uint32_t mask); | 557 | uint32_t mask); |
558 | |||
558 | /* INIT device interface function jump table entries */ | 559 | /* INIT device interface function jump table entries */ |
559 | int (*lpfc_sli_hbq_to_firmware) | 560 | int (*lpfc_sli_hbq_to_firmware) |
560 | (struct lpfc_hba *, uint32_t, struct hbq_dmabuf *); | 561 | (struct lpfc_hba *, uint32_t, struct hbq_dmabuf *); |
@@ -573,6 +574,10 @@ struct lpfc_hba { | |||
573 | int (*lpfc_selective_reset) | 574 | int (*lpfc_selective_reset) |
574 | (struct lpfc_hba *); | 575 | (struct lpfc_hba *); |
575 | 576 | ||
577 | int (*lpfc_bg_scsi_prep_dma_buf) | ||
578 | (struct lpfc_hba *, struct lpfc_scsi_buf *); | ||
579 | /* Add new entries here */ | ||
580 | |||
576 | /* SLI4 specific HBA data structure */ | 581 | /* SLI4 specific HBA data structure */ |
577 | struct lpfc_sli4_hba sli4_hba; | 582 | struct lpfc_sli4_hba sli4_hba; |
578 | 583 | ||
@@ -838,6 +843,7 @@ struct lpfc_hba { | |||
838 | struct dentry *debug_writeGuard; /* inject write guard_tag errors */ | 843 | struct dentry *debug_writeGuard; /* inject write guard_tag errors */ |
839 | struct dentry *debug_writeApp; /* inject write app_tag errors */ | 844 | struct dentry *debug_writeApp; /* inject write app_tag errors */ |
840 | struct dentry *debug_writeRef; /* inject write ref_tag errors */ | 845 | struct dentry *debug_writeRef; /* inject write ref_tag errors */ |
846 | struct dentry *debug_readGuard; /* inject read guard_tag errors */ | ||
841 | struct dentry *debug_readApp; /* inject read app_tag errors */ | 847 | struct dentry *debug_readApp; /* inject read app_tag errors */ |
842 | struct dentry *debug_readRef; /* inject read ref_tag errors */ | 848 | struct dentry *debug_readRef; /* inject read ref_tag errors */ |
843 | 849 | ||
@@ -845,10 +851,11 @@ struct lpfc_hba { | |||
845 | uint32_t lpfc_injerr_wgrd_cnt; | 851 | uint32_t lpfc_injerr_wgrd_cnt; |
846 | uint32_t lpfc_injerr_wapp_cnt; | 852 | uint32_t lpfc_injerr_wapp_cnt; |
847 | uint32_t lpfc_injerr_wref_cnt; | 853 | uint32_t lpfc_injerr_wref_cnt; |
854 | uint32_t lpfc_injerr_rgrd_cnt; | ||
848 | uint32_t lpfc_injerr_rapp_cnt; | 855 | uint32_t lpfc_injerr_rapp_cnt; |
849 | uint32_t lpfc_injerr_rref_cnt; | 856 | uint32_t lpfc_injerr_rref_cnt; |
850 | sector_t lpfc_injerr_lba; | 857 | sector_t lpfc_injerr_lba; |
851 | #define LPFC_INJERR_LBA_OFF (sector_t)0xffffffffffffffff | 858 | #define LPFC_INJERR_LBA_OFF (sector_t)(-1) |
852 | 859 | ||
853 | struct dentry *debug_slow_ring_trc; | 860 | struct dentry *debug_slow_ring_trc; |
854 | struct lpfc_debugfs_trc *slow_ring_trc; | 861 | struct lpfc_debugfs_trc *slow_ring_trc; |
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 3587a3fe8fcb..22e17be04d8a 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c | |||
@@ -1019,6 +1019,8 @@ lpfc_debugfs_dif_err_read(struct file *file, char __user *buf, | |||
1019 | cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wapp_cnt); | 1019 | cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wapp_cnt); |
1020 | else if (dent == phba->debug_writeRef) | 1020 | else if (dent == phba->debug_writeRef) |
1021 | cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wref_cnt); | 1021 | cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wref_cnt); |
1022 | else if (dent == phba->debug_readGuard) | ||
1023 | cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_rgrd_cnt); | ||
1022 | else if (dent == phba->debug_readApp) | 1024 | else if (dent == phba->debug_readApp) |
1023 | cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_rapp_cnt); | 1025 | cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_rapp_cnt); |
1024 | else if (dent == phba->debug_readRef) | 1026 | else if (dent == phba->debug_readRef) |
@@ -1057,6 +1059,8 @@ lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf, | |||
1057 | phba->lpfc_injerr_wapp_cnt = (uint32_t)tmp; | 1059 | phba->lpfc_injerr_wapp_cnt = (uint32_t)tmp; |
1058 | else if (dent == phba->debug_writeRef) | 1060 | else if (dent == phba->debug_writeRef) |
1059 | phba->lpfc_injerr_wref_cnt = (uint32_t)tmp; | 1061 | phba->lpfc_injerr_wref_cnt = (uint32_t)tmp; |
1062 | else if (dent == phba->debug_readGuard) | ||
1063 | phba->lpfc_injerr_rgrd_cnt = (uint32_t)tmp; | ||
1060 | else if (dent == phba->debug_readApp) | 1064 | else if (dent == phba->debug_readApp) |
1061 | phba->lpfc_injerr_rapp_cnt = (uint32_t)tmp; | 1065 | phba->lpfc_injerr_rapp_cnt = (uint32_t)tmp; |
1062 | else if (dent == phba->debug_readRef) | 1066 | else if (dent == phba->debug_readRef) |
@@ -3978,6 +3982,17 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) | |||
3978 | goto debug_failed; | 3982 | goto debug_failed; |
3979 | } | 3983 | } |
3980 | 3984 | ||
3985 | snprintf(name, sizeof(name), "readGuardInjErr"); | ||
3986 | phba->debug_readGuard = | ||
3987 | debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, | ||
3988 | phba->hba_debugfs_root, | ||
3989 | phba, &lpfc_debugfs_op_dif_err); | ||
3990 | if (!phba->debug_readGuard) { | ||
3991 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, | ||
3992 | "0808 Cannot create debugfs readGuard\n"); | ||
3993 | goto debug_failed; | ||
3994 | } | ||
3995 | |||
3981 | snprintf(name, sizeof(name), "readAppInjErr"); | 3996 | snprintf(name, sizeof(name), "readAppInjErr"); |
3982 | phba->debug_readApp = | 3997 | phba->debug_readApp = |
3983 | debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, | 3998 | debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, |
@@ -4318,6 +4333,10 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport) | |||
4318 | debugfs_remove(phba->debug_writeRef); /* writeRef */ | 4333 | debugfs_remove(phba->debug_writeRef); /* writeRef */ |
4319 | phba->debug_writeRef = NULL; | 4334 | phba->debug_writeRef = NULL; |
4320 | } | 4335 | } |
4336 | if (phba->debug_readGuard) { | ||
4337 | debugfs_remove(phba->debug_readGuard); /* readGuard */ | ||
4338 | phba->debug_readGuard = NULL; | ||
4339 | } | ||
4321 | if (phba->debug_readApp) { | 4340 | if (phba->debug_readApp) { |
4322 | debugfs_remove(phba->debug_readApp); /* readApp */ | 4341 | debugfs_remove(phba->debug_readApp); /* readApp */ |
4323 | phba->debug_readApp = NULL; | 4342 | phba->debug_readApp = NULL; |
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index cc19bc1b5ace..9e2b9b227e1a 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
@@ -321,6 +321,10 @@ struct lpfc_cqe { | |||
321 | #define CQE_STATUS_CMD_REJECT 0xb | 321 | #define CQE_STATUS_CMD_REJECT 0xb |
322 | #define CQE_STATUS_FCP_TGT_LENCHECK 0xc | 322 | #define CQE_STATUS_FCP_TGT_LENCHECK 0xc |
323 | #define CQE_STATUS_NEED_BUFF_ENTRY 0xf | 323 | #define CQE_STATUS_NEED_BUFF_ENTRY 0xf |
324 | #define CQE_STATUS_DI_ERROR 0x16 | ||
325 | |||
326 | /* Used when mapping CQE status to IOCB */ | ||
327 | #define LPFC_IOCB_STATUS_MASK 0xf | ||
324 | 328 | ||
325 | /* Status returned by hardware (valid only if status = CQE_STATUS_SUCCESS). */ | 329 | /* Status returned by hardware (valid only if status = CQE_STATUS_SUCCESS). */ |
326 | #define CQE_HW_STATUS_NO_ERR 0x0 | 330 | #define CQE_HW_STATUS_NO_ERR 0x0 |
@@ -348,6 +352,21 @@ struct lpfc_wcqe_complete { | |||
348 | #define lpfc_wcqe_c_hw_status_WORD word0 | 352 | #define lpfc_wcqe_c_hw_status_WORD word0 |
349 | uint32_t total_data_placed; | 353 | uint32_t total_data_placed; |
350 | uint32_t parameter; | 354 | uint32_t parameter; |
355 | #define lpfc_wcqe_c_bg_edir_SHIFT 5 | ||
356 | #define lpfc_wcqe_c_bg_edir_MASK 0x00000001 | ||
357 | #define lpfc_wcqe_c_bg_edir_WORD parameter | ||
358 | #define lpfc_wcqe_c_bg_tdpv_SHIFT 3 | ||
359 | #define lpfc_wcqe_c_bg_tdpv_MASK 0x00000001 | ||
360 | #define lpfc_wcqe_c_bg_tdpv_WORD parameter | ||
361 | #define lpfc_wcqe_c_bg_re_SHIFT 2 | ||
362 | #define lpfc_wcqe_c_bg_re_MASK 0x00000001 | ||
363 | #define lpfc_wcqe_c_bg_re_WORD parameter | ||
364 | #define lpfc_wcqe_c_bg_ae_SHIFT 1 | ||
365 | #define lpfc_wcqe_c_bg_ae_MASK 0x00000001 | ||
366 | #define lpfc_wcqe_c_bg_ae_WORD parameter | ||
367 | #define lpfc_wcqe_c_bg_ge_SHIFT 0 | ||
368 | #define lpfc_wcqe_c_bg_ge_MASK 0x00000001 | ||
369 | #define lpfc_wcqe_c_bg_ge_WORD parameter | ||
351 | uint32_t word3; | 370 | uint32_t word3; |
352 | #define lpfc_wcqe_c_valid_SHIFT lpfc_cqe_valid_SHIFT | 371 | #define lpfc_wcqe_c_valid_SHIFT lpfc_cqe_valid_SHIFT |
353 | #define lpfc_wcqe_c_valid_MASK lpfc_cqe_valid_MASK | 372 | #define lpfc_wcqe_c_valid_MASK lpfc_cqe_valid_MASK |
@@ -359,8 +378,8 @@ struct lpfc_wcqe_complete { | |||
359 | #define lpfc_wcqe_c_pv_MASK 0x00000001 | 378 | #define lpfc_wcqe_c_pv_MASK 0x00000001 |
360 | #define lpfc_wcqe_c_pv_WORD word3 | 379 | #define lpfc_wcqe_c_pv_WORD word3 |
361 | #define lpfc_wcqe_c_priority_SHIFT 24 | 380 | #define lpfc_wcqe_c_priority_SHIFT 24 |
362 | #define lpfc_wcqe_c_priority_MASK 0x00000007 | 381 | #define lpfc_wcqe_c_priority_MASK 0x00000007 |
363 | #define lpfc_wcqe_c_priority_WORD word3 | 382 | #define lpfc_wcqe_c_priority_WORD word3 |
364 | #define lpfc_wcqe_c_code_SHIFT lpfc_cqe_code_SHIFT | 383 | #define lpfc_wcqe_c_code_SHIFT lpfc_cqe_code_SHIFT |
365 | #define lpfc_wcqe_c_code_MASK lpfc_cqe_code_MASK | 384 | #define lpfc_wcqe_c_code_MASK lpfc_cqe_code_MASK |
366 | #define lpfc_wcqe_c_code_WORD lpfc_cqe_code_WORD | 385 | #define lpfc_wcqe_c_code_WORD lpfc_cqe_code_WORD |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index f3ad7349f5d1..d9628770f11e 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -4380,6 +4380,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
4380 | uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0}; | 4380 | uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0}; |
4381 | struct lpfc_mqe *mqe; | 4381 | struct lpfc_mqe *mqe; |
4382 | int longs, sli_family; | 4382 | int longs, sli_family; |
4383 | int sges_per_segment; | ||
4383 | 4384 | ||
4384 | /* Before proceed, wait for POST done and device ready */ | 4385 | /* Before proceed, wait for POST done and device ready */ |
4385 | rc = lpfc_sli4_post_status_check(phba); | 4386 | rc = lpfc_sli4_post_status_check(phba); |
@@ -4443,6 +4444,11 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
4443 | phba->fc_map[1] = LPFC_FCOE_FCF_MAP1; | 4444 | phba->fc_map[1] = LPFC_FCOE_FCF_MAP1; |
4444 | phba->fc_map[2] = LPFC_FCOE_FCF_MAP2; | 4445 | phba->fc_map[2] = LPFC_FCOE_FCF_MAP2; |
4445 | 4446 | ||
4447 | /* With BlockGuard we can have multiple SGEs per Data Segemnt */ | ||
4448 | sges_per_segment = 1; | ||
4449 | if (phba->cfg_enable_bg) | ||
4450 | sges_per_segment = 2; | ||
4451 | |||
4446 | /* | 4452 | /* |
4447 | * Since the sg_tablesize is module parameter, the sg_dma_buf_size | 4453 | * Since the sg_tablesize is module parameter, the sg_dma_buf_size |
4448 | * used to create the sg_dma_buf_pool must be dynamically calculated. | 4454 | * used to create the sg_dma_buf_pool must be dynamically calculated. |
@@ -4451,7 +4457,8 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
4451 | * sgl sizes of must be a power of 2. | 4457 | * sgl sizes of must be a power of 2. |
4452 | */ | 4458 | */ |
4453 | buf_size = (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp) + | 4459 | buf_size = (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp) + |
4454 | ((phba->cfg_sg_seg_cnt + 2) * sizeof(struct sli4_sge))); | 4460 | (((phba->cfg_sg_seg_cnt * sges_per_segment) + 2) * |
4461 | sizeof(struct sli4_sge))); | ||
4455 | 4462 | ||
4456 | sli_family = bf_get(lpfc_sli_intf_sli_family, &phba->sli4_hba.sli_intf); | 4463 | sli_family = bf_get(lpfc_sli_intf_sli_family, &phba->sli4_hba.sli_intf); |
4457 | max_buf_size = LPFC_SLI4_MAX_BUF_SIZE; | 4464 | max_buf_size = LPFC_SLI4_MAX_BUF_SIZE; |
@@ -4468,6 +4475,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
4468 | default: | 4475 | default: |
4469 | break; | 4476 | break; |
4470 | } | 4477 | } |
4478 | |||
4471 | for (dma_buf_size = LPFC_SLI4_MIN_BUF_SIZE; | 4479 | for (dma_buf_size = LPFC_SLI4_MIN_BUF_SIZE; |
4472 | dma_buf_size < max_buf_size && buf_size > dma_buf_size; | 4480 | dma_buf_size < max_buf_size && buf_size > dma_buf_size; |
4473 | dma_buf_size = dma_buf_size << 1) | 4481 | dma_buf_size = dma_buf_size << 1) |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index c60f5d0b3869..efc055b6bac4 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2011 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2012 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -1280,31 +1280,45 @@ lpfc_cmd_blksize(struct scsi_cmnd *sc) | |||
1280 | } | 1280 | } |
1281 | 1281 | ||
1282 | #ifdef CONFIG_SCSI_LPFC_DEBUG_FS | 1282 | #ifdef CONFIG_SCSI_LPFC_DEBUG_FS |
1283 | /* | 1283 | |
1284 | * Given a scsi cmnd, determine the BlockGuard tags to be used with it | 1284 | #define BG_ERR_INIT 1 |
1285 | #define BG_ERR_TGT 2 | ||
1286 | #define BG_ERR_SWAP 3 | ||
1287 | #define BG_ERR_CHECK 4 | ||
1288 | |||
1289 | /** | ||
1290 | * lpfc_bg_err_inject - Determine if we should inject an error | ||
1291 | * @phba: The Hba for which this call is being executed. | ||
1285 | * @sc: The SCSI command to examine | 1292 | * @sc: The SCSI command to examine |
1286 | * @reftag: (out) BlockGuard reference tag for transmitted data | 1293 | * @reftag: (out) BlockGuard reference tag for transmitted data |
1287 | * @apptag: (out) BlockGuard application tag for transmitted data | 1294 | * @apptag: (out) BlockGuard application tag for transmitted data |
1288 | * @new_guard (in) Value to replace CRC with if needed | 1295 | * @new_guard (in) Value to replace CRC with if needed |
1289 | * | 1296 | * |
1290 | * Returns (1) if error injection was performed, (0) otherwise | 1297 | * Returns (1) if error injection is detected by Initiator |
1291 | */ | 1298 | * Returns (2) if error injection is detected by Target |
1299 | * Returns (3) if swapping CSUM->CRC is required for error injection | ||
1300 | * Returns (4) disabling Guard/Ref/App checking is required for error injection | ||
1301 | **/ | ||
1292 | static int | 1302 | static int |
1293 | lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, | 1303 | lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, |
1294 | uint32_t *reftag, uint16_t *apptag, uint32_t new_guard) | 1304 | uint32_t *reftag, uint16_t *apptag, uint32_t new_guard) |
1295 | { | 1305 | { |
1296 | struct scatterlist *sgpe; /* s/g prot entry */ | 1306 | struct scatterlist *sgpe; /* s/g prot entry */ |
1297 | struct scatterlist *sgde; /* s/g data entry */ | 1307 | struct scatterlist *sgde; /* s/g data entry */ |
1298 | struct scsi_dif_tuple *src; | 1308 | struct scsi_dif_tuple *src = NULL; |
1299 | uint32_t op = scsi_get_prot_op(sc); | 1309 | uint32_t op = scsi_get_prot_op(sc); |
1300 | uint32_t blksize; | 1310 | uint32_t blksize; |
1301 | uint32_t numblks; | 1311 | uint32_t numblks; |
1302 | sector_t lba; | 1312 | sector_t lba; |
1303 | int rc = 0; | 1313 | int rc = 0; |
1314 | int blockoff = 0; | ||
1304 | 1315 | ||
1305 | if (op == SCSI_PROT_NORMAL) | 1316 | if (op == SCSI_PROT_NORMAL) |
1306 | return 0; | 1317 | return 0; |
1307 | 1318 | ||
1319 | sgpe = scsi_prot_sglist(sc); | ||
1320 | sgde = scsi_sglist(sc); | ||
1321 | |||
1308 | lba = scsi_get_lba(sc); | 1322 | lba = scsi_get_lba(sc); |
1309 | if (phba->lpfc_injerr_lba != LPFC_INJERR_LBA_OFF) { | 1323 | if (phba->lpfc_injerr_lba != LPFC_INJERR_LBA_OFF) { |
1310 | blksize = lpfc_cmd_blksize(sc); | 1324 | blksize = lpfc_cmd_blksize(sc); |
@@ -1314,142 +1328,296 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, | |||
1314 | if ((phba->lpfc_injerr_lba < lba) || | 1328 | if ((phba->lpfc_injerr_lba < lba) || |
1315 | (phba->lpfc_injerr_lba >= (lba + numblks))) | 1329 | (phba->lpfc_injerr_lba >= (lba + numblks))) |
1316 | return 0; | 1330 | return 0; |
1331 | if (sgpe) { | ||
1332 | blockoff = phba->lpfc_injerr_lba - lba; | ||
1333 | numblks = sg_dma_len(sgpe) / | ||
1334 | sizeof(struct scsi_dif_tuple); | ||
1335 | if (numblks < blockoff) | ||
1336 | blockoff = numblks; | ||
1337 | src = (struct scsi_dif_tuple *)sg_virt(sgpe); | ||
1338 | src += blockoff; | ||
1339 | } | ||
1317 | } | 1340 | } |
1318 | 1341 | ||
1319 | sgpe = scsi_prot_sglist(sc); | ||
1320 | sgde = scsi_sglist(sc); | ||
1321 | |||
1322 | /* Should we change the Reference Tag */ | 1342 | /* Should we change the Reference Tag */ |
1323 | if (reftag) { | 1343 | if (reftag) { |
1324 | /* | 1344 | if (phba->lpfc_injerr_wref_cnt) { |
1325 | * If we are SCSI_PROT_WRITE_STRIP, the protection data is | 1345 | switch (op) { |
1326 | * being stripped from the wire, thus it doesn't matter. | 1346 | case SCSI_PROT_WRITE_PASS: |
1327 | */ | 1347 | if (blockoff && src) { |
1328 | if ((op == SCSI_PROT_WRITE_PASS) || | 1348 | /* Insert error in middle of the IO */ |
1329 | (op == SCSI_PROT_WRITE_INSERT)) { | 1349 | |
1330 | if (phba->lpfc_injerr_wref_cnt) { | 1350 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, |
1351 | "9076 BLKGRD: Injecting reftag error: " | ||
1352 | "write lba x%lx + x%x oldrefTag x%x\n", | ||
1353 | (unsigned long)lba, blockoff, | ||
1354 | src->ref_tag); | ||
1355 | |||
1356 | /* | ||
1357 | * NOTE, this will change ref tag in | ||
1358 | * the memory location forever! | ||
1359 | */ | ||
1360 | src->ref_tag = 0xDEADBEEF; | ||
1361 | phba->lpfc_injerr_wref_cnt--; | ||
1362 | phba->lpfc_injerr_lba = | ||
1363 | LPFC_INJERR_LBA_OFF; | ||
1364 | rc = BG_ERR_CHECK; | ||
1365 | break; | ||
1366 | } | ||
1367 | /* Drop thru */ | ||
1368 | case SCSI_PROT_WRITE_STRIP: | ||
1369 | /* | ||
1370 | * For WRITE_STRIP and WRITE_PASS, | ||
1371 | * force the error on data | ||
1372 | * being copied from SLI-Host to SLI-Port. | ||
1373 | */ | ||
1374 | *reftag = 0xDEADBEEF; | ||
1375 | phba->lpfc_injerr_wref_cnt--; | ||
1376 | phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; | ||
1377 | rc = BG_ERR_INIT; | ||
1331 | 1378 | ||
1379 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | ||
1380 | "9077 BLKGRD: Injecting reftag error: " | ||
1381 | "write lba x%lx\n", (unsigned long)lba); | ||
1382 | break; | ||
1383 | case SCSI_PROT_WRITE_INSERT: | ||
1384 | /* | ||
1385 | * For WRITE_INSERT, force the | ||
1386 | * error to be sent on the wire. It should be | ||
1387 | * detected by the Target. | ||
1388 | */ | ||
1332 | /* DEADBEEF will be the reftag on the wire */ | 1389 | /* DEADBEEF will be the reftag on the wire */ |
1333 | *reftag = 0xDEADBEEF; | 1390 | *reftag = 0xDEADBEEF; |
1334 | phba->lpfc_injerr_wref_cnt--; | 1391 | phba->lpfc_injerr_wref_cnt--; |
1335 | phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; | 1392 | phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; |
1336 | rc = 1; | 1393 | rc = BG_ERR_TGT; |
1337 | 1394 | ||
1338 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | 1395 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, |
1339 | "9081 BLKGRD: Injecting reftag error: " | 1396 | "9078 BLKGRD: Injecting reftag error: " |
1340 | "write lba x%lx\n", (unsigned long)lba); | 1397 | "write lba x%lx\n", (unsigned long)lba); |
1398 | break; | ||
1341 | } | 1399 | } |
1342 | } else { | 1400 | } |
1343 | if (phba->lpfc_injerr_rref_cnt) { | 1401 | if (phba->lpfc_injerr_rref_cnt) { |
1402 | switch (op) { | ||
1403 | case SCSI_PROT_READ_INSERT: | ||
1404 | /* | ||
1405 | * For READ_INSERT, it doesn't make sense | ||
1406 | * to change the reftag. | ||
1407 | */ | ||
1408 | break; | ||
1409 | case SCSI_PROT_READ_STRIP: | ||
1410 | case SCSI_PROT_READ_PASS: | ||
1411 | /* | ||
1412 | * For READ_STRIP and READ_PASS, force the | ||
1413 | * error on data being read off the wire. It | ||
1414 | * should force an IO error to the driver. | ||
1415 | */ | ||
1344 | *reftag = 0xDEADBEEF; | 1416 | *reftag = 0xDEADBEEF; |
1345 | phba->lpfc_injerr_rref_cnt--; | 1417 | phba->lpfc_injerr_rref_cnt--; |
1346 | phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; | 1418 | phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; |
1347 | rc = 1; | 1419 | rc = BG_ERR_INIT; |
1348 | 1420 | ||
1349 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | 1421 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, |
1350 | "9076 BLKGRD: Injecting reftag error: " | 1422 | "9079 BLKGRD: Injecting reftag error: " |
1351 | "read lba x%lx\n", (unsigned long)lba); | 1423 | "read lba x%lx\n", (unsigned long)lba); |
1424 | break; | ||
1352 | } | 1425 | } |
1353 | } | 1426 | } |
1354 | } | 1427 | } |
1355 | 1428 | ||
1356 | /* Should we change the Application Tag */ | 1429 | /* Should we change the Application Tag */ |
1357 | if (apptag) { | 1430 | if (apptag) { |
1358 | /* | 1431 | if (phba->lpfc_injerr_wapp_cnt) { |
1359 | * If we are SCSI_PROT_WRITE_STRIP, the protection data is | 1432 | switch (op) { |
1360 | * being stripped from the wire, thus it doesn't matter. | 1433 | case SCSI_PROT_WRITE_PASS: |
1361 | */ | 1434 | if (blockoff && src) { |
1362 | if ((op == SCSI_PROT_WRITE_PASS) || | 1435 | /* Insert error in middle of the IO */ |
1363 | (op == SCSI_PROT_WRITE_INSERT)) { | 1436 | |
1364 | if (phba->lpfc_injerr_wapp_cnt) { | 1437 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, |
1438 | "9080 BLKGRD: Injecting apptag error: " | ||
1439 | "write lba x%lx + x%x oldappTag x%x\n", | ||
1440 | (unsigned long)lba, blockoff, | ||
1441 | src->app_tag); | ||
1365 | 1442 | ||
1443 | /* | ||
1444 | * NOTE, this will change app tag in | ||
1445 | * the memory location forever! | ||
1446 | */ | ||
1447 | src->app_tag = 0xDEAD; | ||
1448 | phba->lpfc_injerr_wapp_cnt--; | ||
1449 | phba->lpfc_injerr_lba = | ||
1450 | LPFC_INJERR_LBA_OFF; | ||
1451 | rc = BG_ERR_CHECK; | ||
1452 | break; | ||
1453 | } | ||
1454 | /* Drop thru */ | ||
1455 | case SCSI_PROT_WRITE_STRIP: | ||
1456 | /* | ||
1457 | * For WRITE_STRIP and WRITE_PASS, | ||
1458 | * force the error on data | ||
1459 | * being copied from SLI-Host to SLI-Port. | ||
1460 | */ | ||
1461 | *apptag = 0xDEAD; | ||
1462 | phba->lpfc_injerr_wapp_cnt--; | ||
1463 | phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; | ||
1464 | rc = BG_ERR_INIT; | ||
1465 | |||
1466 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | ||
1467 | "0812 BLKGRD: Injecting apptag error: " | ||
1468 | "write lba x%lx\n", (unsigned long)lba); | ||
1469 | break; | ||
1470 | case SCSI_PROT_WRITE_INSERT: | ||
1471 | /* | ||
1472 | * For WRITE_INSERT, force the | ||
1473 | * error to be sent on the wire. It should be | ||
1474 | * detected by the Target. | ||
1475 | */ | ||
1366 | /* DEAD will be the apptag on the wire */ | 1476 | /* DEAD will be the apptag on the wire */ |
1367 | *apptag = 0xDEAD; | 1477 | *apptag = 0xDEAD; |
1368 | phba->lpfc_injerr_wapp_cnt--; | 1478 | phba->lpfc_injerr_wapp_cnt--; |
1369 | phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; | 1479 | phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; |
1370 | rc = 1; | 1480 | rc = BG_ERR_TGT; |
1371 | 1481 | ||
1372 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | 1482 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, |
1373 | "9077 BLKGRD: Injecting apptag error: " | 1483 | "0813 BLKGRD: Injecting apptag error: " |
1374 | "write lba x%lx\n", (unsigned long)lba); | 1484 | "write lba x%lx\n", (unsigned long)lba); |
1485 | break; | ||
1375 | } | 1486 | } |
1376 | } else { | 1487 | } |
1377 | if (phba->lpfc_injerr_rapp_cnt) { | 1488 | if (phba->lpfc_injerr_rapp_cnt) { |
1489 | switch (op) { | ||
1490 | case SCSI_PROT_READ_INSERT: | ||
1491 | /* | ||
1492 | * For READ_INSERT, it doesn't make sense | ||
1493 | * to change the apptag. | ||
1494 | */ | ||
1495 | break; | ||
1496 | case SCSI_PROT_READ_STRIP: | ||
1497 | case SCSI_PROT_READ_PASS: | ||
1498 | /* | ||
1499 | * For READ_STRIP and READ_PASS, force the | ||
1500 | * error on data being read off the wire. It | ||
1501 | * should force an IO error to the driver. | ||
1502 | */ | ||
1378 | *apptag = 0xDEAD; | 1503 | *apptag = 0xDEAD; |
1379 | phba->lpfc_injerr_rapp_cnt--; | 1504 | phba->lpfc_injerr_rapp_cnt--; |
1380 | phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; | 1505 | phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; |
1381 | rc = 1; | 1506 | rc = BG_ERR_INIT; |
1382 | 1507 | ||
1383 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | 1508 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, |
1384 | "9078 BLKGRD: Injecting apptag error: " | 1509 | "0814 BLKGRD: Injecting apptag error: " |
1385 | "read lba x%lx\n", (unsigned long)lba); | 1510 | "read lba x%lx\n", (unsigned long)lba); |
1511 | break; | ||
1386 | } | 1512 | } |
1387 | } | 1513 | } |
1388 | } | 1514 | } |
1389 | 1515 | ||
1516 | |||
1390 | /* Should we change the Guard Tag */ | 1517 | /* Should we change the Guard Tag */ |
1518 | if (new_guard) { | ||
1519 | if (phba->lpfc_injerr_wgrd_cnt) { | ||
1520 | switch (op) { | ||
1521 | case SCSI_PROT_WRITE_PASS: | ||
1522 | if (blockoff && src) { | ||
1523 | /* Insert error in middle of the IO */ | ||
1524 | |||
1525 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | ||
1526 | "0815 BLKGRD: Injecting guard error: " | ||
1527 | "write lba x%lx + x%x oldgrdTag x%x\n", | ||
1528 | (unsigned long)lba, blockoff, | ||
1529 | src->guard_tag); | ||
1391 | 1530 | ||
1392 | /* | 1531 | /* |
1393 | * If we are SCSI_PROT_WRITE_INSERT, the protection data is | 1532 | * NOTE, this will change guard tag in |
1394 | * being on the wire is being fully generated on the HBA. | 1533 | * the memory location forever! |
1395 | * The host cannot change it or force an error. | 1534 | */ |
1396 | */ | 1535 | src->guard_tag = 0xDEAD; |
1397 | if (((op == SCSI_PROT_WRITE_STRIP) || | 1536 | phba->lpfc_injerr_wgrd_cnt--; |
1398 | (op == SCSI_PROT_WRITE_PASS)) && | 1537 | phba->lpfc_injerr_lba = |
1399 | phba->lpfc_injerr_wgrd_cnt) { | 1538 | LPFC_INJERR_LBA_OFF; |
1400 | if (sgpe) { | 1539 | rc = BG_ERR_CHECK; |
1401 | src = (struct scsi_dif_tuple *)sg_virt(sgpe); | 1540 | break; |
1402 | /* | 1541 | } |
1403 | * Just inject an error in the first | 1542 | /* Drop thru */ |
1404 | * prot block. | 1543 | case SCSI_PROT_WRITE_STRIP: |
1405 | */ | 1544 | /* |
1406 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | 1545 | * For WRITE_STRIP and WRITE_PASS, |
1407 | "9079 BLKGRD: Injecting guard error: " | 1546 | * force the error on data |
1408 | "write lba x%lx oldGuard x%x refTag x%x\n", | 1547 | * being copied from SLI-Host to SLI-Port. |
1409 | (unsigned long)lba, src->guard_tag, | 1548 | */ |
1410 | src->ref_tag); | 1549 | phba->lpfc_injerr_wgrd_cnt--; |
1550 | phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; | ||
1411 | 1551 | ||
1412 | src->guard_tag = (uint16_t)new_guard; | 1552 | rc = BG_ERR_SWAP; |
1413 | phba->lpfc_injerr_wgrd_cnt--; | 1553 | /* Signals the caller to swap CRC->CSUM */ |
1414 | phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; | ||
1415 | rc = 1; | ||
1416 | 1554 | ||
1417 | } else { | 1555 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, |
1418 | blksize = lpfc_cmd_blksize(sc); | 1556 | "0816 BLKGRD: Injecting guard error: " |
1419 | /* | 1557 | "write lba x%lx\n", (unsigned long)lba); |
1420 | * Jump past the first data block | 1558 | break; |
1421 | * and inject an error in the | 1559 | case SCSI_PROT_WRITE_INSERT: |
1422 | * prot data. The prot data is already | 1560 | /* |
1423 | * embedded after the regular data. | 1561 | * For WRITE_INSERT, force the |
1424 | */ | 1562 | * error to be sent on the wire. It should be |
1425 | src = (struct scsi_dif_tuple *) | 1563 | * detected by the Target. |
1426 | (sg_virt(sgde) + blksize); | 1564 | */ |
1565 | phba->lpfc_injerr_wgrd_cnt--; | ||
1566 | phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; | ||
1427 | 1567 | ||
1428 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | 1568 | rc = BG_ERR_SWAP; |
1429 | "9080 BLKGRD: Injecting guard error: " | 1569 | /* Signals the caller to swap CRC->CSUM */ |
1430 | "write lba x%lx oldGuard x%x refTag x%x\n", | 1570 | |
1431 | (unsigned long)lba, src->guard_tag, | 1571 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, |
1432 | src->ref_tag); | 1572 | "0817 BLKGRD: Injecting guard error: " |
1433 | 1573 | "write lba x%lx\n", (unsigned long)lba); | |
1434 | src->guard_tag = (uint16_t)new_guard; | 1574 | break; |
1435 | phba->lpfc_injerr_wgrd_cnt--; | 1575 | } |
1436 | phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; | 1576 | } |
1437 | rc = 1; | 1577 | if (phba->lpfc_injerr_rgrd_cnt) { |
1578 | switch (op) { | ||
1579 | case SCSI_PROT_READ_INSERT: | ||
1580 | /* | ||
1581 | * For READ_INSERT, it doesn't make sense | ||
1582 | * to change the guard tag. | ||
1583 | */ | ||
1584 | break; | ||
1585 | case SCSI_PROT_READ_STRIP: | ||
1586 | case SCSI_PROT_READ_PASS: | ||
1587 | /* | ||
1588 | * For READ_STRIP and READ_PASS, force the | ||
1589 | * error on data being read off the wire. It | ||
1590 | * should force an IO error to the driver. | ||
1591 | */ | ||
1592 | *apptag = 0xDEAD; | ||
1593 | phba->lpfc_injerr_rgrd_cnt--; | ||
1594 | phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; | ||
1595 | |||
1596 | rc = BG_ERR_SWAP; | ||
1597 | /* Signals the caller to swap CRC->CSUM */ | ||
1598 | |||
1599 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | ||
1600 | "0818 BLKGRD: Injecting guard error: " | ||
1601 | "read lba x%lx\n", (unsigned long)lba); | ||
1602 | } | ||
1438 | } | 1603 | } |
1439 | } | 1604 | } |
1605 | |||
1440 | return rc; | 1606 | return rc; |
1441 | } | 1607 | } |
1442 | #endif | 1608 | #endif |
1443 | 1609 | ||
1444 | /* | 1610 | /** |
1445 | * Given a scsi cmnd, determine the BlockGuard opcodes to be used with it | 1611 | * lpfc_sc_to_bg_opcodes - Determine the BlockGuard opcodes to be used with |
1612 | * the specified SCSI command. | ||
1613 | * @phba: The Hba for which this call is being executed. | ||
1446 | * @sc: The SCSI command to examine | 1614 | * @sc: The SCSI command to examine |
1447 | * @txopt: (out) BlockGuard operation for transmitted data | 1615 | * @txopt: (out) BlockGuard operation for transmitted data |
1448 | * @rxopt: (out) BlockGuard operation for received data | 1616 | * @rxopt: (out) BlockGuard operation for received data |
1449 | * | 1617 | * |
1450 | * Returns: zero on success; non-zero if tx and/or rx op cannot be determined | 1618 | * Returns: zero on success; non-zero if tx and/or rx op cannot be determined |
1451 | * | 1619 | * |
1452 | */ | 1620 | **/ |
1453 | static int | 1621 | static int |
1454 | lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc, | 1622 | lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc, |
1455 | uint8_t *txop, uint8_t *rxop) | 1623 | uint8_t *txop, uint8_t *rxop) |
@@ -1519,8 +1687,88 @@ lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc, | |||
1519 | return ret; | 1687 | return ret; |
1520 | } | 1688 | } |
1521 | 1689 | ||
1522 | /* | 1690 | #ifdef CONFIG_SCSI_LPFC_DEBUG_FS |
1523 | * This function sets up buffer list for protection groups of | 1691 | /** |
1692 | * lpfc_bg_err_opcodes - reDetermine the BlockGuard opcodes to be used with | ||
1693 | * the specified SCSI command in order to force a guard tag error. | ||
1694 | * @phba: The Hba for which this call is being executed. | ||
1695 | * @sc: The SCSI command to examine | ||
1696 | * @txopt: (out) BlockGuard operation for transmitted data | ||
1697 | * @rxopt: (out) BlockGuard operation for received data | ||
1698 | * | ||
1699 | * Returns: zero on success; non-zero if tx and/or rx op cannot be determined | ||
1700 | * | ||
1701 | **/ | ||
1702 | static int | ||
1703 | lpfc_bg_err_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc, | ||
1704 | uint8_t *txop, uint8_t *rxop) | ||
1705 | { | ||
1706 | uint8_t guard_type = scsi_host_get_guard(sc->device->host); | ||
1707 | uint8_t ret = 0; | ||
1708 | |||
1709 | if (guard_type == SHOST_DIX_GUARD_IP) { | ||
1710 | switch (scsi_get_prot_op(sc)) { | ||
1711 | case SCSI_PROT_READ_INSERT: | ||
1712 | case SCSI_PROT_WRITE_STRIP: | ||
1713 | *txop = BG_OP_IN_CRC_OUT_NODIF; | ||
1714 | *rxop = BG_OP_IN_NODIF_OUT_CRC; | ||
1715 | break; | ||
1716 | |||
1717 | case SCSI_PROT_READ_STRIP: | ||
1718 | case SCSI_PROT_WRITE_INSERT: | ||
1719 | *txop = BG_OP_IN_NODIF_OUT_CSUM; | ||
1720 | *rxop = BG_OP_IN_CSUM_OUT_NODIF; | ||
1721 | break; | ||
1722 | |||
1723 | case SCSI_PROT_READ_PASS: | ||
1724 | case SCSI_PROT_WRITE_PASS: | ||
1725 | *txop = BG_OP_IN_CRC_OUT_CRC; | ||
1726 | *rxop = BG_OP_IN_CRC_OUT_CRC; | ||
1727 | break; | ||
1728 | |||
1729 | case SCSI_PROT_NORMAL: | ||
1730 | default: | ||
1731 | break; | ||
1732 | |||
1733 | } | ||
1734 | } else { | ||
1735 | switch (scsi_get_prot_op(sc)) { | ||
1736 | case SCSI_PROT_READ_STRIP: | ||
1737 | case SCSI_PROT_WRITE_INSERT: | ||
1738 | *txop = BG_OP_IN_NODIF_OUT_CSUM; | ||
1739 | *rxop = BG_OP_IN_CSUM_OUT_NODIF; | ||
1740 | break; | ||
1741 | |||
1742 | case SCSI_PROT_READ_PASS: | ||
1743 | case SCSI_PROT_WRITE_PASS: | ||
1744 | *txop = BG_OP_IN_CSUM_OUT_CRC; | ||
1745 | *rxop = BG_OP_IN_CRC_OUT_CSUM; | ||
1746 | break; | ||
1747 | |||
1748 | case SCSI_PROT_READ_INSERT: | ||
1749 | case SCSI_PROT_WRITE_STRIP: | ||
1750 | *txop = BG_OP_IN_CSUM_OUT_NODIF; | ||
1751 | *rxop = BG_OP_IN_NODIF_OUT_CSUM; | ||
1752 | break; | ||
1753 | |||
1754 | case SCSI_PROT_NORMAL: | ||
1755 | default: | ||
1756 | break; | ||
1757 | } | ||
1758 | } | ||
1759 | |||
1760 | return ret; | ||
1761 | } | ||
1762 | #endif | ||
1763 | |||
1764 | /** | ||
1765 | * lpfc_bg_setup_bpl - Setup BlockGuard BPL with no protection data | ||
1766 | * @phba: The Hba for which this call is being executed. | ||
1767 | * @sc: pointer to scsi command we're working on | ||
1768 | * @bpl: pointer to buffer list for protection groups | ||
1769 | * @datacnt: number of segments of data that have been dma mapped | ||
1770 | * | ||
1771 | * This function sets up BPL buffer list for protection groups of | ||
1524 | * type LPFC_PG_TYPE_NO_DIF | 1772 | * type LPFC_PG_TYPE_NO_DIF |
1525 | * | 1773 | * |
1526 | * This is usually used when the HBA is instructed to generate | 1774 | * This is usually used when the HBA is instructed to generate |
@@ -1539,12 +1787,11 @@ lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc, | |||
1539 | * |more Data BDE's ... (opt)| | 1787 | * |more Data BDE's ... (opt)| |
1540 | * +-------------------------+ | 1788 | * +-------------------------+ |
1541 | * | 1789 | * |
1542 | * @sc: pointer to scsi command we're working on | ||
1543 | * @bpl: pointer to buffer list for protection groups | ||
1544 | * @datacnt: number of segments of data that have been dma mapped | ||
1545 | * | 1790 | * |
1546 | * Note: Data s/g buffers have been dma mapped | 1791 | * Note: Data s/g buffers have been dma mapped |
1547 | */ | 1792 | * |
1793 | * Returns the number of BDEs added to the BPL. | ||
1794 | **/ | ||
1548 | static int | 1795 | static int |
1549 | lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc, | 1796 | lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc, |
1550 | struct ulp_bde64 *bpl, int datasegcnt) | 1797 | struct ulp_bde64 *bpl, int datasegcnt) |
@@ -1555,6 +1802,8 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc, | |||
1555 | dma_addr_t physaddr; | 1802 | dma_addr_t physaddr; |
1556 | int i = 0, num_bde = 0, status; | 1803 | int i = 0, num_bde = 0, status; |
1557 | int datadir = sc->sc_data_direction; | 1804 | int datadir = sc->sc_data_direction; |
1805 | uint32_t rc; | ||
1806 | uint32_t checking = 1; | ||
1558 | uint32_t reftag; | 1807 | uint32_t reftag; |
1559 | unsigned blksize; | 1808 | unsigned blksize; |
1560 | uint8_t txop, rxop; | 1809 | uint8_t txop, rxop; |
@@ -1565,11 +1814,16 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc, | |||
1565 | 1814 | ||
1566 | /* extract some info from the scsi command for pde*/ | 1815 | /* extract some info from the scsi command for pde*/ |
1567 | blksize = lpfc_cmd_blksize(sc); | 1816 | blksize = lpfc_cmd_blksize(sc); |
1568 | reftag = scsi_get_lba(sc) & 0xffffffff; | 1817 | reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */ |
1569 | 1818 | ||
1570 | #ifdef CONFIG_SCSI_LPFC_DEBUG_FS | 1819 | #ifdef CONFIG_SCSI_LPFC_DEBUG_FS |
1571 | /* reftag is the only error we can inject here */ | 1820 | rc = lpfc_bg_err_inject(phba, sc, &reftag, 0, 1); |
1572 | lpfc_bg_err_inject(phba, sc, &reftag, 0, 0); | 1821 | if (rc) { |
1822 | if (rc == BG_ERR_SWAP) | ||
1823 | lpfc_bg_err_opcodes(phba, sc, &txop, &rxop); | ||
1824 | if (rc == BG_ERR_CHECK) | ||
1825 | checking = 0; | ||
1826 | } | ||
1573 | #endif | 1827 | #endif |
1574 | 1828 | ||
1575 | /* setup PDE5 with what we have */ | 1829 | /* setup PDE5 with what we have */ |
@@ -1592,8 +1846,8 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc, | |||
1592 | bf_set(pde6_optx, pde6, txop); | 1846 | bf_set(pde6_optx, pde6, txop); |
1593 | bf_set(pde6_oprx, pde6, rxop); | 1847 | bf_set(pde6_oprx, pde6, rxop); |
1594 | if (datadir == DMA_FROM_DEVICE) { | 1848 | if (datadir == DMA_FROM_DEVICE) { |
1595 | bf_set(pde6_ce, pde6, 1); | 1849 | bf_set(pde6_ce, pde6, checking); |
1596 | bf_set(pde6_re, pde6, 1); | 1850 | bf_set(pde6_re, pde6, checking); |
1597 | } | 1851 | } |
1598 | bf_set(pde6_ai, pde6, 1); | 1852 | bf_set(pde6_ai, pde6, 1); |
1599 | bf_set(pde6_ae, pde6, 0); | 1853 | bf_set(pde6_ae, pde6, 0); |
@@ -1627,9 +1881,16 @@ out: | |||
1627 | return num_bde; | 1881 | return num_bde; |
1628 | } | 1882 | } |
1629 | 1883 | ||
1630 | /* | 1884 | /** |
1631 | * This function sets up buffer list for protection groups of | 1885 | * lpfc_bg_setup_bpl_prot - Setup BlockGuard BPL with protection data |
1632 | * type LPFC_PG_TYPE_DIF_BUF | 1886 | * @phba: The Hba for which this call is being executed. |
1887 | * @sc: pointer to scsi command we're working on | ||
1888 | * @bpl: pointer to buffer list for protection groups | ||
1889 | * @datacnt: number of segments of data that have been dma mapped | ||
1890 | * @protcnt: number of segment of protection data that have been dma mapped | ||
1891 | * | ||
1892 | * This function sets up BPL buffer list for protection groups of | ||
1893 | * type LPFC_PG_TYPE_DIF | ||
1633 | * | 1894 | * |
1634 | * This is usually used when DIFs are in their own buffers, | 1895 | * This is usually used when DIFs are in their own buffers, |
1635 | * separate from the data. The HBA can then by instructed | 1896 | * separate from the data. The HBA can then by instructed |
@@ -1654,14 +1915,11 @@ out: | |||
1654 | * | ... | | 1915 | * | ... | |
1655 | * +-------------------------+ | 1916 | * +-------------------------+ |
1656 | * | 1917 | * |
1657 | * @sc: pointer to scsi command we're working on | ||
1658 | * @bpl: pointer to buffer list for protection groups | ||
1659 | * @datacnt: number of segments of data that have been dma mapped | ||
1660 | * @protcnt: number of segment of protection data that have been dma mapped | ||
1661 | * | ||
1662 | * Note: It is assumed that both data and protection s/g buffers have been | 1918 | * Note: It is assumed that both data and protection s/g buffers have been |
1663 | * mapped for DMA | 1919 | * mapped for DMA |
1664 | */ | 1920 | * |
1921 | * Returns the number of BDEs added to the BPL. | ||
1922 | **/ | ||
1665 | static int | 1923 | static int |
1666 | lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, | 1924 | lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, |
1667 | struct ulp_bde64 *bpl, int datacnt, int protcnt) | 1925 | struct ulp_bde64 *bpl, int datacnt, int protcnt) |
@@ -1681,6 +1939,8 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, | |||
1681 | int datadir = sc->sc_data_direction; | 1939 | int datadir = sc->sc_data_direction; |
1682 | unsigned char pgdone = 0, alldone = 0; | 1940 | unsigned char pgdone = 0, alldone = 0; |
1683 | unsigned blksize; | 1941 | unsigned blksize; |
1942 | uint32_t rc; | ||
1943 | uint32_t checking = 1; | ||
1684 | uint32_t reftag; | 1944 | uint32_t reftag; |
1685 | uint8_t txop, rxop; | 1945 | uint8_t txop, rxop; |
1686 | int num_bde = 0; | 1946 | int num_bde = 0; |
@@ -1701,11 +1961,16 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, | |||
1701 | 1961 | ||
1702 | /* extract some info from the scsi command */ | 1962 | /* extract some info from the scsi command */ |
1703 | blksize = lpfc_cmd_blksize(sc); | 1963 | blksize = lpfc_cmd_blksize(sc); |
1704 | reftag = scsi_get_lba(sc) & 0xffffffff; | 1964 | reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */ |
1705 | 1965 | ||
1706 | #ifdef CONFIG_SCSI_LPFC_DEBUG_FS | 1966 | #ifdef CONFIG_SCSI_LPFC_DEBUG_FS |
1707 | /* reftag / guard tag are the only errors we can inject here */ | 1967 | rc = lpfc_bg_err_inject(phba, sc, &reftag, 0, 1); |
1708 | lpfc_bg_err_inject(phba, sc, &reftag, 0, 0xDEAD); | 1968 | if (rc) { |
1969 | if (rc == BG_ERR_SWAP) | ||
1970 | lpfc_bg_err_opcodes(phba, sc, &txop, &rxop); | ||
1971 | if (rc == BG_ERR_CHECK) | ||
1972 | checking = 0; | ||
1973 | } | ||
1709 | #endif | 1974 | #endif |
1710 | 1975 | ||
1711 | split_offset = 0; | 1976 | split_offset = 0; |
@@ -1729,8 +1994,8 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, | |||
1729 | bf_set(pde6_type, pde6, LPFC_PDE6_DESCRIPTOR); | 1994 | bf_set(pde6_type, pde6, LPFC_PDE6_DESCRIPTOR); |
1730 | bf_set(pde6_optx, pde6, txop); | 1995 | bf_set(pde6_optx, pde6, txop); |
1731 | bf_set(pde6_oprx, pde6, rxop); | 1996 | bf_set(pde6_oprx, pde6, rxop); |
1732 | bf_set(pde6_ce, pde6, 1); | 1997 | bf_set(pde6_ce, pde6, checking); |
1733 | bf_set(pde6_re, pde6, 1); | 1998 | bf_set(pde6_re, pde6, checking); |
1734 | bf_set(pde6_ai, pde6, 1); | 1999 | bf_set(pde6_ai, pde6, 1); |
1735 | bf_set(pde6_ae, pde6, 0); | 2000 | bf_set(pde6_ae, pde6, 0); |
1736 | bf_set(pde6_apptagval, pde6, 0); | 2001 | bf_set(pde6_apptagval, pde6, 0); |
@@ -1852,13 +2117,358 @@ out: | |||
1852 | return num_bde; | 2117 | return num_bde; |
1853 | } | 2118 | } |
1854 | 2119 | ||
1855 | /* | 2120 | /** |
2121 | * lpfc_bg_setup_sgl - Setup BlockGuard SGL with no protection data | ||
2122 | * @phba: The Hba for which this call is being executed. | ||
2123 | * @sc: pointer to scsi command we're working on | ||
2124 | * @sgl: pointer to buffer list for protection groups | ||
2125 | * @datacnt: number of segments of data that have been dma mapped | ||
2126 | * | ||
2127 | * This function sets up SGL buffer list for protection groups of | ||
2128 | * type LPFC_PG_TYPE_NO_DIF | ||
2129 | * | ||
2130 | * This is usually used when the HBA is instructed to generate | ||
2131 | * DIFs and insert them into data stream (or strip DIF from | ||
2132 | * incoming data stream) | ||
2133 | * | ||
2134 | * The buffer list consists of just one protection group described | ||
2135 | * below: | ||
2136 | * +-------------------------+ | ||
2137 | * start of prot group --> | DI_SEED | | ||
2138 | * +-------------------------+ | ||
2139 | * | Data SGE | | ||
2140 | * +-------------------------+ | ||
2141 | * |more Data SGE's ... (opt)| | ||
2142 | * +-------------------------+ | ||
2143 | * | ||
2144 | * | ||
2145 | * Note: Data s/g buffers have been dma mapped | ||
2146 | * | ||
2147 | * Returns the number of SGEs added to the SGL. | ||
2148 | **/ | ||
2149 | static int | ||
2150 | lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, | ||
2151 | struct sli4_sge *sgl, int datasegcnt) | ||
2152 | { | ||
2153 | struct scatterlist *sgde = NULL; /* s/g data entry */ | ||
2154 | struct sli4_sge_diseed *diseed = NULL; | ||
2155 | dma_addr_t physaddr; | ||
2156 | int i = 0, num_sge = 0, status; | ||
2157 | int datadir = sc->sc_data_direction; | ||
2158 | uint32_t reftag; | ||
2159 | unsigned blksize; | ||
2160 | uint8_t txop, rxop; | ||
2161 | uint32_t rc; | ||
2162 | uint32_t checking = 1; | ||
2163 | uint32_t dma_len; | ||
2164 | uint32_t dma_offset = 0; | ||
2165 | |||
2166 | status = lpfc_sc_to_bg_opcodes(phba, sc, &txop, &rxop); | ||
2167 | if (status) | ||
2168 | goto out; | ||
2169 | |||
2170 | /* extract some info from the scsi command for pde*/ | ||
2171 | blksize = lpfc_cmd_blksize(sc); | ||
2172 | reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */ | ||
2173 | |||
2174 | #ifdef CONFIG_SCSI_LPFC_DEBUG_FS | ||
2175 | rc = lpfc_bg_err_inject(phba, sc, &reftag, 0, 1); | ||
2176 | if (rc) { | ||
2177 | if (rc == BG_ERR_SWAP) | ||
2178 | lpfc_bg_err_opcodes(phba, sc, &txop, &rxop); | ||
2179 | if (rc == BG_ERR_CHECK) | ||
2180 | checking = 0; | ||
2181 | } | ||
2182 | #endif | ||
2183 | |||
2184 | /* setup DISEED with what we have */ | ||
2185 | diseed = (struct sli4_sge_diseed *) sgl; | ||
2186 | memset(diseed, 0, sizeof(struct sli4_sge_diseed)); | ||
2187 | bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DISEED); | ||
2188 | |||
2189 | /* Endianness conversion if necessary */ | ||
2190 | diseed->ref_tag = cpu_to_le32(reftag); | ||
2191 | diseed->ref_tag_tran = diseed->ref_tag; | ||
2192 | |||
2193 | /* setup DISEED with the rest of the info */ | ||
2194 | bf_set(lpfc_sli4_sge_dif_optx, diseed, txop); | ||
2195 | bf_set(lpfc_sli4_sge_dif_oprx, diseed, rxop); | ||
2196 | if (datadir == DMA_FROM_DEVICE) { | ||
2197 | bf_set(lpfc_sli4_sge_dif_ce, diseed, checking); | ||
2198 | bf_set(lpfc_sli4_sge_dif_re, diseed, checking); | ||
2199 | } | ||
2200 | bf_set(lpfc_sli4_sge_dif_ai, diseed, 1); | ||
2201 | bf_set(lpfc_sli4_sge_dif_me, diseed, 0); | ||
2202 | |||
2203 | /* Endianness conversion if necessary for DISEED */ | ||
2204 | diseed->word2 = cpu_to_le32(diseed->word2); | ||
2205 | diseed->word3 = cpu_to_le32(diseed->word3); | ||
2206 | |||
2207 | /* advance bpl and increment sge count */ | ||
2208 | num_sge++; | ||
2209 | sgl++; | ||
2210 | |||
2211 | /* assumption: caller has already run dma_map_sg on command data */ | ||
2212 | scsi_for_each_sg(sc, sgde, datasegcnt, i) { | ||
2213 | physaddr = sg_dma_address(sgde); | ||
2214 | dma_len = sg_dma_len(sgde); | ||
2215 | sgl->addr_lo = cpu_to_le32(putPaddrLow(physaddr)); | ||
2216 | sgl->addr_hi = cpu_to_le32(putPaddrHigh(physaddr)); | ||
2217 | if ((i + 1) == datasegcnt) | ||
2218 | bf_set(lpfc_sli4_sge_last, sgl, 1); | ||
2219 | else | ||
2220 | bf_set(lpfc_sli4_sge_last, sgl, 0); | ||
2221 | bf_set(lpfc_sli4_sge_offset, sgl, dma_offset); | ||
2222 | bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DATA); | ||
2223 | |||
2224 | sgl->sge_len = cpu_to_le32(dma_len); | ||
2225 | dma_offset += dma_len; | ||
2226 | |||
2227 | sgl++; | ||
2228 | num_sge++; | ||
2229 | } | ||
2230 | |||
2231 | out: | ||
2232 | return num_sge; | ||
2233 | } | ||
2234 | |||
2235 | /** | ||
2236 | * lpfc_bg_setup_sgl_prot - Setup BlockGuard SGL with protection data | ||
2237 | * @phba: The Hba for which this call is being executed. | ||
2238 | * @sc: pointer to scsi command we're working on | ||
2239 | * @sgl: pointer to buffer list for protection groups | ||
2240 | * @datacnt: number of segments of data that have been dma mapped | ||
2241 | * @protcnt: number of segment of protection data that have been dma mapped | ||
2242 | * | ||
2243 | * This function sets up SGL buffer list for protection groups of | ||
2244 | * type LPFC_PG_TYPE_DIF | ||
2245 | * | ||
2246 | * This is usually used when DIFs are in their own buffers, | ||
2247 | * separate from the data. The HBA can then by instructed | ||
2248 | * to place the DIFs in the outgoing stream. For read operations, | ||
2249 | * The HBA could extract the DIFs and place it in DIF buffers. | ||
2250 | * | ||
2251 | * The buffer list for this type consists of one or more of the | ||
2252 | * protection groups described below: | ||
2253 | * +-------------------------+ | ||
2254 | * start of first prot group --> | DISEED | | ||
2255 | * +-------------------------+ | ||
2256 | * | DIF (Prot SGE) | | ||
2257 | * +-------------------------+ | ||
2258 | * | Data SGE | | ||
2259 | * +-------------------------+ | ||
2260 | * |more Data SGE's ... (opt)| | ||
2261 | * +-------------------------+ | ||
2262 | * start of new prot group --> | DISEED | | ||
2263 | * +-------------------------+ | ||
2264 | * | ... | | ||
2265 | * +-------------------------+ | ||
2266 | * | ||
2267 | * Note: It is assumed that both data and protection s/g buffers have been | ||
2268 | * mapped for DMA | ||
2269 | * | ||
2270 | * Returns the number of SGEs added to the SGL. | ||
2271 | **/ | ||
2272 | static int | ||
2273 | lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, | ||
2274 | struct sli4_sge *sgl, int datacnt, int protcnt) | ||
2275 | { | ||
2276 | struct scatterlist *sgde = NULL; /* s/g data entry */ | ||
2277 | struct scatterlist *sgpe = NULL; /* s/g prot entry */ | ||
2278 | struct sli4_sge_diseed *diseed = NULL; | ||
2279 | dma_addr_t dataphysaddr, protphysaddr; | ||
2280 | unsigned short curr_data = 0, curr_prot = 0; | ||
2281 | unsigned int split_offset; | ||
2282 | unsigned int protgroup_len, protgroup_offset = 0, protgroup_remainder; | ||
2283 | unsigned int protgrp_blks, protgrp_bytes; | ||
2284 | unsigned int remainder, subtotal; | ||
2285 | int status; | ||
2286 | unsigned char pgdone = 0, alldone = 0; | ||
2287 | unsigned blksize; | ||
2288 | uint32_t reftag; | ||
2289 | uint8_t txop, rxop; | ||
2290 | uint32_t dma_len; | ||
2291 | uint32_t rc; | ||
2292 | uint32_t checking = 1; | ||
2293 | uint32_t dma_offset = 0; | ||
2294 | int num_sge = 0; | ||
2295 | |||
2296 | sgpe = scsi_prot_sglist(sc); | ||
2297 | sgde = scsi_sglist(sc); | ||
2298 | |||
2299 | if (!sgpe || !sgde) { | ||
2300 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | ||
2301 | "9082 Invalid s/g entry: data=0x%p prot=0x%p\n", | ||
2302 | sgpe, sgde); | ||
2303 | return 0; | ||
2304 | } | ||
2305 | |||
2306 | status = lpfc_sc_to_bg_opcodes(phba, sc, &txop, &rxop); | ||
2307 | if (status) | ||
2308 | goto out; | ||
2309 | |||
2310 | /* extract some info from the scsi command */ | ||
2311 | blksize = lpfc_cmd_blksize(sc); | ||
2312 | reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */ | ||
2313 | |||
2314 | #ifdef CONFIG_SCSI_LPFC_DEBUG_FS | ||
2315 | rc = lpfc_bg_err_inject(phba, sc, &reftag, 0, 1); | ||
2316 | if (rc) { | ||
2317 | if (rc == BG_ERR_SWAP) | ||
2318 | lpfc_bg_err_opcodes(phba, sc, &txop, &rxop); | ||
2319 | if (rc == BG_ERR_CHECK) | ||
2320 | checking = 0; | ||
2321 | } | ||
2322 | #endif | ||
2323 | |||
2324 | split_offset = 0; | ||
2325 | do { | ||
2326 | /* setup DISEED with what we have */ | ||
2327 | diseed = (struct sli4_sge_diseed *) sgl; | ||
2328 | memset(diseed, 0, sizeof(struct sli4_sge_diseed)); | ||
2329 | bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DISEED); | ||
2330 | |||
2331 | /* Endianness conversion if necessary */ | ||
2332 | diseed->ref_tag = cpu_to_le32(reftag); | ||
2333 | diseed->ref_tag_tran = diseed->ref_tag; | ||
2334 | |||
2335 | /* setup DISEED with the rest of the info */ | ||
2336 | bf_set(lpfc_sli4_sge_dif_optx, diseed, txop); | ||
2337 | bf_set(lpfc_sli4_sge_dif_oprx, diseed, rxop); | ||
2338 | bf_set(lpfc_sli4_sge_dif_ce, diseed, checking); | ||
2339 | bf_set(lpfc_sli4_sge_dif_re, diseed, checking); | ||
2340 | bf_set(lpfc_sli4_sge_dif_ai, diseed, 1); | ||
2341 | bf_set(lpfc_sli4_sge_dif_me, diseed, 0); | ||
2342 | |||
2343 | /* Endianness conversion if necessary for DISEED */ | ||
2344 | diseed->word2 = cpu_to_le32(diseed->word2); | ||
2345 | diseed->word3 = cpu_to_le32(diseed->word3); | ||
2346 | |||
2347 | /* advance sgl and increment bde count */ | ||
2348 | num_sge++; | ||
2349 | sgl++; | ||
2350 | |||
2351 | /* setup the first BDE that points to protection buffer */ | ||
2352 | protphysaddr = sg_dma_address(sgpe) + protgroup_offset; | ||
2353 | protgroup_len = sg_dma_len(sgpe) - protgroup_offset; | ||
2354 | |||
2355 | /* must be integer multiple of the DIF block length */ | ||
2356 | BUG_ON(protgroup_len % 8); | ||
2357 | |||
2358 | /* Now setup DIF SGE */ | ||
2359 | sgl->word2 = 0; | ||
2360 | bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DIF); | ||
2361 | sgl->addr_hi = le32_to_cpu(putPaddrHigh(protphysaddr)); | ||
2362 | sgl->addr_lo = le32_to_cpu(putPaddrLow(protphysaddr)); | ||
2363 | sgl->word2 = cpu_to_le32(sgl->word2); | ||
2364 | |||
2365 | protgrp_blks = protgroup_len / 8; | ||
2366 | protgrp_bytes = protgrp_blks * blksize; | ||
2367 | |||
2368 | /* check if DIF SGE is crossing the 4K boundary; if so split */ | ||
2369 | if ((sgl->addr_lo & 0xfff) + protgroup_len > 0x1000) { | ||
2370 | protgroup_remainder = 0x1000 - (sgl->addr_lo & 0xfff); | ||
2371 | protgroup_offset += protgroup_remainder; | ||
2372 | protgrp_blks = protgroup_remainder / 8; | ||
2373 | protgrp_bytes = protgrp_blks * blksize; | ||
2374 | } else { | ||
2375 | protgroup_offset = 0; | ||
2376 | curr_prot++; | ||
2377 | } | ||
2378 | |||
2379 | num_sge++; | ||
2380 | |||
2381 | /* setup SGE's for data blocks associated with DIF data */ | ||
2382 | pgdone = 0; | ||
2383 | subtotal = 0; /* total bytes processed for current prot grp */ | ||
2384 | while (!pgdone) { | ||
2385 | if (!sgde) { | ||
2386 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | ||
2387 | "9086 BLKGRD:%s Invalid data segment\n", | ||
2388 | __func__); | ||
2389 | return 0; | ||
2390 | } | ||
2391 | sgl++; | ||
2392 | dataphysaddr = sg_dma_address(sgde) + split_offset; | ||
2393 | |||
2394 | remainder = sg_dma_len(sgde) - split_offset; | ||
2395 | |||
2396 | if ((subtotal + remainder) <= protgrp_bytes) { | ||
2397 | /* we can use this whole buffer */ | ||
2398 | dma_len = remainder; | ||
2399 | split_offset = 0; | ||
2400 | |||
2401 | if ((subtotal + remainder) == protgrp_bytes) | ||
2402 | pgdone = 1; | ||
2403 | } else { | ||
2404 | /* must split this buffer with next prot grp */ | ||
2405 | dma_len = protgrp_bytes - subtotal; | ||
2406 | split_offset += dma_len; | ||
2407 | } | ||
2408 | |||
2409 | subtotal += dma_len; | ||
2410 | |||
2411 | sgl->addr_lo = cpu_to_le32(putPaddrLow(dataphysaddr)); | ||
2412 | sgl->addr_hi = cpu_to_le32(putPaddrHigh(dataphysaddr)); | ||
2413 | bf_set(lpfc_sli4_sge_last, sgl, 0); | ||
2414 | bf_set(lpfc_sli4_sge_offset, sgl, dma_offset); | ||
2415 | bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DATA); | ||
2416 | |||
2417 | sgl->sge_len = cpu_to_le32(dma_len); | ||
2418 | dma_offset += dma_len; | ||
2419 | |||
2420 | num_sge++; | ||
2421 | curr_data++; | ||
2422 | |||
2423 | if (split_offset) | ||
2424 | break; | ||
2425 | |||
2426 | /* Move to the next s/g segment if possible */ | ||
2427 | sgde = sg_next(sgde); | ||
2428 | } | ||
2429 | |||
2430 | if (protgroup_offset) { | ||
2431 | /* update the reference tag */ | ||
2432 | reftag += protgrp_blks; | ||
2433 | sgl++; | ||
2434 | continue; | ||
2435 | } | ||
2436 | |||
2437 | /* are we done ? */ | ||
2438 | if (curr_prot == protcnt) { | ||
2439 | bf_set(lpfc_sli4_sge_last, sgl, 1); | ||
2440 | alldone = 1; | ||
2441 | } else if (curr_prot < protcnt) { | ||
2442 | /* advance to next prot buffer */ | ||
2443 | sgpe = sg_next(sgpe); | ||
2444 | sgl++; | ||
2445 | |||
2446 | /* update the reference tag */ | ||
2447 | reftag += protgrp_blks; | ||
2448 | } else { | ||
2449 | /* if we're here, we have a bug */ | ||
2450 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | ||
2451 | "9085 BLKGRD: bug in %s\n", __func__); | ||
2452 | } | ||
2453 | |||
2454 | } while (!alldone); | ||
2455 | |||
2456 | out: | ||
2457 | |||
2458 | return num_sge; | ||
2459 | } | ||
2460 | |||
2461 | /** | ||
2462 | * lpfc_prot_group_type - Get prtotection group type of SCSI command | ||
2463 | * @phba: The Hba for which this call is being executed. | ||
2464 | * @sc: pointer to scsi command we're working on | ||
2465 | * | ||
1856 | * Given a SCSI command that supports DIF, determine composition of protection | 2466 | * Given a SCSI command that supports DIF, determine composition of protection |
1857 | * groups involved in setting up buffer lists | 2467 | * groups involved in setting up buffer lists |
1858 | * | 2468 | * |
1859 | * Returns: | 2469 | * Returns: Protection group type (with or without DIF) |
1860 | * for DIF (for both read and write) | 2470 | * |
1861 | * */ | 2471 | **/ |
1862 | static int | 2472 | static int |
1863 | lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc) | 2473 | lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc) |
1864 | { | 2474 | { |
@@ -1885,13 +2495,17 @@ lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc) | |||
1885 | return ret; | 2495 | return ret; |
1886 | } | 2496 | } |
1887 | 2497 | ||
1888 | /* | 2498 | /** |
2499 | * lpfc_bg_scsi_prep_dma_buf_s3 - DMA mapping for scsi buffer to SLI3 IF spec | ||
2500 | * @phba: The Hba for which this call is being executed. | ||
2501 | * @lpfc_cmd: The scsi buffer which is going to be prep'ed. | ||
2502 | * | ||
1889 | * This is the protection/DIF aware version of | 2503 | * This is the protection/DIF aware version of |
1890 | * lpfc_scsi_prep_dma_buf(). It may be a good idea to combine the | 2504 | * lpfc_scsi_prep_dma_buf(). It may be a good idea to combine the |
1891 | * two functions eventually, but for now, it's here | 2505 | * two functions eventually, but for now, it's here |
1892 | */ | 2506 | **/ |
1893 | static int | 2507 | static int |
1894 | lpfc_bg_scsi_prep_dma_buf(struct lpfc_hba *phba, | 2508 | lpfc_bg_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, |
1895 | struct lpfc_scsi_buf *lpfc_cmd) | 2509 | struct lpfc_scsi_buf *lpfc_cmd) |
1896 | { | 2510 | { |
1897 | struct scsi_cmnd *scsi_cmnd = lpfc_cmd->pCmd; | 2511 | struct scsi_cmnd *scsi_cmnd = lpfc_cmd->pCmd; |
@@ -2147,7 +2761,21 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd, | |||
2147 | cmd->sense_buffer[8] = 0; /* Information descriptor type */ | 2761 | cmd->sense_buffer[8] = 0; /* Information descriptor type */ |
2148 | cmd->sense_buffer[9] = 0xa; /* Additional descriptor length */ | 2762 | cmd->sense_buffer[9] = 0xa; /* Additional descriptor length */ |
2149 | cmd->sense_buffer[10] = 0x80; /* Validity bit */ | 2763 | cmd->sense_buffer[10] = 0x80; /* Validity bit */ |
2150 | bghm /= cmd->device->sector_size; | 2764 | |
2765 | /* bghm is a "on the wire" FC frame based count */ | ||
2766 | switch (scsi_get_prot_op(cmd)) { | ||
2767 | case SCSI_PROT_READ_INSERT: | ||
2768 | case SCSI_PROT_WRITE_STRIP: | ||
2769 | bghm /= cmd->device->sector_size; | ||
2770 | break; | ||
2771 | case SCSI_PROT_READ_STRIP: | ||
2772 | case SCSI_PROT_WRITE_INSERT: | ||
2773 | case SCSI_PROT_READ_PASS: | ||
2774 | case SCSI_PROT_WRITE_PASS: | ||
2775 | bghm /= (cmd->device->sector_size + | ||
2776 | sizeof(struct scsi_dif_tuple)); | ||
2777 | break; | ||
2778 | } | ||
2151 | 2779 | ||
2152 | failing_sector = scsi_get_lba(cmd); | 2780 | failing_sector = scsi_get_lba(cmd); |
2153 | failing_sector += bghm; | 2781 | failing_sector += bghm; |
@@ -2292,6 +2920,180 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
2292 | } | 2920 | } |
2293 | 2921 | ||
2294 | /** | 2922 | /** |
2923 | * lpfc_bg_scsi_adjust_dl - Adjust SCSI data length for BlockGuard | ||
2924 | * @phba: The Hba for which this call is being executed. | ||
2925 | * @lpfc_cmd: The scsi buffer which is going to be adjusted. | ||
2926 | * | ||
2927 | * Adjust the data length to account for how much data | ||
2928 | * is actually on the wire. | ||
2929 | * | ||
2930 | * returns the adjusted data length | ||
2931 | **/ | ||
2932 | static int | ||
2933 | lpfc_bg_scsi_adjust_dl(struct lpfc_hba *phba, | ||
2934 | struct lpfc_scsi_buf *lpfc_cmd) | ||
2935 | { | ||
2936 | struct scsi_cmnd *sc = lpfc_cmd->pCmd; | ||
2937 | int diflen, fcpdl; | ||
2938 | unsigned blksize; | ||
2939 | |||
2940 | fcpdl = scsi_bufflen(sc); | ||
2941 | |||
2942 | /* Check if there is protection data on the wire */ | ||
2943 | if (sc->sc_data_direction == DMA_FROM_DEVICE) { | ||
2944 | /* Read */ | ||
2945 | if (scsi_get_prot_op(sc) == SCSI_PROT_READ_INSERT) | ||
2946 | return fcpdl; | ||
2947 | |||
2948 | } else { | ||
2949 | /* Write */ | ||
2950 | if (scsi_get_prot_op(sc) == SCSI_PROT_WRITE_STRIP) | ||
2951 | return fcpdl; | ||
2952 | } | ||
2953 | |||
2954 | /* If protection data on the wire, adjust the count accordingly */ | ||
2955 | blksize = lpfc_cmd_blksize(sc); | ||
2956 | diflen = (fcpdl / blksize) * 8; | ||
2957 | fcpdl += diflen; | ||
2958 | return fcpdl; | ||
2959 | } | ||
2960 | |||
2961 | /** | ||
2962 | * lpfc_bg_scsi_prep_dma_buf_s4 - DMA mapping for scsi buffer to SLI4 IF spec | ||
2963 | * @phba: The Hba for which this call is being executed. | ||
2964 | * @lpfc_cmd: The scsi buffer which is going to be mapped. | ||
2965 | * | ||
2966 | * This is the protection/DIF aware version of | ||
2967 | * lpfc_scsi_prep_dma_buf(). It may be a good idea to combine the | ||
2968 | * two functions eventually, but for now, it's here | ||
2969 | **/ | ||
2970 | static int | ||
2971 | lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, | ||
2972 | struct lpfc_scsi_buf *lpfc_cmd) | ||
2973 | { | ||
2974 | struct scsi_cmnd *scsi_cmnd = lpfc_cmd->pCmd; | ||
2975 | struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd; | ||
2976 | struct sli4_sge *sgl = (struct sli4_sge *)(lpfc_cmd->fcp_bpl); | ||
2977 | IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb; | ||
2978 | uint32_t num_bde = 0; | ||
2979 | int datasegcnt, protsegcnt, datadir = scsi_cmnd->sc_data_direction; | ||
2980 | int prot_group_type = 0; | ||
2981 | int fcpdl; | ||
2982 | |||
2983 | /* | ||
2984 | * Start the lpfc command prep by bumping the sgl beyond fcp_cmnd | ||
2985 | * fcp_rsp regions to the first data bde entry | ||
2986 | */ | ||
2987 | if (scsi_sg_count(scsi_cmnd)) { | ||
2988 | /* | ||
2989 | * The driver stores the segment count returned from pci_map_sg | ||
2990 | * because this a count of dma-mappings used to map the use_sg | ||
2991 | * pages. They are not guaranteed to be the same for those | ||
2992 | * architectures that implement an IOMMU. | ||
2993 | */ | ||
2994 | datasegcnt = dma_map_sg(&phba->pcidev->dev, | ||
2995 | scsi_sglist(scsi_cmnd), | ||
2996 | scsi_sg_count(scsi_cmnd), datadir); | ||
2997 | if (unlikely(!datasegcnt)) | ||
2998 | return 1; | ||
2999 | |||
3000 | sgl += 1; | ||
3001 | /* clear the last flag in the fcp_rsp map entry */ | ||
3002 | sgl->word2 = le32_to_cpu(sgl->word2); | ||
3003 | bf_set(lpfc_sli4_sge_last, sgl, 0); | ||
3004 | sgl->word2 = cpu_to_le32(sgl->word2); | ||
3005 | |||
3006 | sgl += 1; | ||
3007 | lpfc_cmd->seg_cnt = datasegcnt; | ||
3008 | if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) { | ||
3009 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | ||
3010 | "9087 BLKGRD: %s: Too many sg segments" | ||
3011 | " from dma_map_sg. Config %d, seg_cnt" | ||
3012 | " %d\n", | ||
3013 | __func__, phba->cfg_sg_seg_cnt, | ||
3014 | lpfc_cmd->seg_cnt); | ||
3015 | scsi_dma_unmap(scsi_cmnd); | ||
3016 | return 1; | ||
3017 | } | ||
3018 | |||
3019 | prot_group_type = lpfc_prot_group_type(phba, scsi_cmnd); | ||
3020 | |||
3021 | switch (prot_group_type) { | ||
3022 | case LPFC_PG_TYPE_NO_DIF: | ||
3023 | num_bde = lpfc_bg_setup_sgl(phba, scsi_cmnd, sgl, | ||
3024 | datasegcnt); | ||
3025 | /* we should have 2 or more entries in buffer list */ | ||
3026 | if (num_bde < 2) | ||
3027 | goto err; | ||
3028 | break; | ||
3029 | case LPFC_PG_TYPE_DIF_BUF:{ | ||
3030 | /* | ||
3031 | * This type indicates that protection buffers are | ||
3032 | * passed to the driver, so that needs to be prepared | ||
3033 | * for DMA | ||
3034 | */ | ||
3035 | protsegcnt = dma_map_sg(&phba->pcidev->dev, | ||
3036 | scsi_prot_sglist(scsi_cmnd), | ||
3037 | scsi_prot_sg_count(scsi_cmnd), datadir); | ||
3038 | if (unlikely(!protsegcnt)) { | ||
3039 | scsi_dma_unmap(scsi_cmnd); | ||
3040 | return 1; | ||
3041 | } | ||
3042 | |||
3043 | lpfc_cmd->prot_seg_cnt = protsegcnt; | ||
3044 | if (lpfc_cmd->prot_seg_cnt | ||
3045 | > phba->cfg_prot_sg_seg_cnt) { | ||
3046 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | ||
3047 | "9088 BLKGRD: %s: Too many prot sg " | ||
3048 | "segments from dma_map_sg. Config %d," | ||
3049 | "prot_seg_cnt %d\n", __func__, | ||
3050 | phba->cfg_prot_sg_seg_cnt, | ||
3051 | lpfc_cmd->prot_seg_cnt); | ||
3052 | dma_unmap_sg(&phba->pcidev->dev, | ||
3053 | scsi_prot_sglist(scsi_cmnd), | ||
3054 | scsi_prot_sg_count(scsi_cmnd), | ||
3055 | datadir); | ||
3056 | scsi_dma_unmap(scsi_cmnd); | ||
3057 | return 1; | ||
3058 | } | ||
3059 | |||
3060 | num_bde = lpfc_bg_setup_sgl_prot(phba, scsi_cmnd, sgl, | ||
3061 | datasegcnt, protsegcnt); | ||
3062 | /* we should have 3 or more entries in buffer list */ | ||
3063 | if (num_bde < 3) | ||
3064 | goto err; | ||
3065 | break; | ||
3066 | } | ||
3067 | case LPFC_PG_TYPE_INVALID: | ||
3068 | default: | ||
3069 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | ||
3070 | "9083 Unexpected protection group %i\n", | ||
3071 | prot_group_type); | ||
3072 | return 1; | ||
3073 | } | ||
3074 | } | ||
3075 | |||
3076 | fcpdl = lpfc_bg_scsi_adjust_dl(phba, lpfc_cmd); | ||
3077 | |||
3078 | fcp_cmnd->fcpDl = be32_to_cpu(fcpdl); | ||
3079 | |||
3080 | /* | ||
3081 | * Due to difference in data length between DIF/non-DIF paths, | ||
3082 | * we need to set word 4 of IOCB here | ||
3083 | */ | ||
3084 | iocb_cmd->un.fcpi.fcpi_parm = fcpdl; | ||
3085 | lpfc_cmd->cur_iocbq.iocb_flag |= LPFC_IO_DIF; | ||
3086 | |||
3087 | return 0; | ||
3088 | err: | ||
3089 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | ||
3090 | "9084 Could not setup all needed BDE's" | ||
3091 | "prot_group_type=%d, num_bde=%d\n", | ||
3092 | prot_group_type, num_bde); | ||
3093 | return 1; | ||
3094 | } | ||
3095 | |||
3096 | /** | ||
2295 | * lpfc_scsi_prep_dma_buf - Wrapper function for DMA mapping of scsi buffer | 3097 | * lpfc_scsi_prep_dma_buf - Wrapper function for DMA mapping of scsi buffer |
2296 | * @phba: The Hba for which this call is being executed. | 3098 | * @phba: The Hba for which this call is being executed. |
2297 | * @lpfc_cmd: The scsi buffer which is going to be mapped. | 3099 | * @lpfc_cmd: The scsi buffer which is going to be mapped. |
@@ -2310,6 +3112,25 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
2310 | } | 3112 | } |
2311 | 3113 | ||
2312 | /** | 3114 | /** |
3115 | * lpfc_bg_scsi_prep_dma_buf - Wrapper function for DMA mapping of scsi buffer | ||
3116 | * using BlockGuard. | ||
3117 | * @phba: The Hba for which this call is being executed. | ||
3118 | * @lpfc_cmd: The scsi buffer which is going to be mapped. | ||
3119 | * | ||
3120 | * This routine wraps the actual DMA mapping function pointer from the | ||
3121 | * lpfc_hba struct. | ||
3122 | * | ||
3123 | * Return codes: | ||
3124 | * 1 - Error | ||
3125 | * 0 - Success | ||
3126 | **/ | ||
3127 | static inline int | ||
3128 | lpfc_bg_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | ||
3129 | { | ||
3130 | return phba->lpfc_bg_scsi_prep_dma_buf(phba, lpfc_cmd); | ||
3131 | } | ||
3132 | |||
3133 | /** | ||
2313 | * lpfc_send_scsi_error_event - Posts an event when there is SCSI error | 3134 | * lpfc_send_scsi_error_event - Posts an event when there is SCSI error |
2314 | * @phba: Pointer to hba context object. | 3135 | * @phba: Pointer to hba context object. |
2315 | * @vport: Pointer to vport object. | 3136 | * @vport: Pointer to vport object. |
@@ -3072,12 +3893,14 @@ lpfc_scsi_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp) | |||
3072 | case LPFC_PCI_DEV_LP: | 3893 | case LPFC_PCI_DEV_LP: |
3073 | phba->lpfc_new_scsi_buf = lpfc_new_scsi_buf_s3; | 3894 | phba->lpfc_new_scsi_buf = lpfc_new_scsi_buf_s3; |
3074 | phba->lpfc_scsi_prep_dma_buf = lpfc_scsi_prep_dma_buf_s3; | 3895 | phba->lpfc_scsi_prep_dma_buf = lpfc_scsi_prep_dma_buf_s3; |
3896 | phba->lpfc_bg_scsi_prep_dma_buf = lpfc_bg_scsi_prep_dma_buf_s3; | ||
3075 | phba->lpfc_release_scsi_buf = lpfc_release_scsi_buf_s3; | 3897 | phba->lpfc_release_scsi_buf = lpfc_release_scsi_buf_s3; |
3076 | phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf_s3; | 3898 | phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf_s3; |
3077 | break; | 3899 | break; |
3078 | case LPFC_PCI_DEV_OC: | 3900 | case LPFC_PCI_DEV_OC: |
3079 | phba->lpfc_new_scsi_buf = lpfc_new_scsi_buf_s4; | 3901 | phba->lpfc_new_scsi_buf = lpfc_new_scsi_buf_s4; |
3080 | phba->lpfc_scsi_prep_dma_buf = lpfc_scsi_prep_dma_buf_s4; | 3902 | phba->lpfc_scsi_prep_dma_buf = lpfc_scsi_prep_dma_buf_s4; |
3903 | phba->lpfc_bg_scsi_prep_dma_buf = lpfc_bg_scsi_prep_dma_buf_s4; | ||
3081 | phba->lpfc_release_scsi_buf = lpfc_release_scsi_buf_s4; | 3904 | phba->lpfc_release_scsi_buf = lpfc_release_scsi_buf_s4; |
3082 | phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf_s4; | 3905 | phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf_s4; |
3083 | break; | 3906 | break; |
@@ -3250,8 +4073,7 @@ lpfc_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) | |||
3250 | ndlp = rdata->pnode; | 4073 | ndlp = rdata->pnode; |
3251 | 4074 | ||
3252 | if ((scsi_get_prot_op(cmnd) != SCSI_PROT_NORMAL) && | 4075 | if ((scsi_get_prot_op(cmnd) != SCSI_PROT_NORMAL) && |
3253 | (!(phba->sli3_options & LPFC_SLI3_BG_ENABLED) || | 4076 | (!(phba->sli3_options & LPFC_SLI3_BG_ENABLED))) { |
3254 | (phba->sli_rev == LPFC_SLI_REV4))) { | ||
3255 | 4077 | ||
3256 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, | 4078 | lpfc_printf_log(phba, KERN_ERR, LOG_BG, |
3257 | "9058 BLKGRD: ERROR: rcvd protected cmd:%02x" | 4079 | "9058 BLKGRD: ERROR: rcvd protected cmd:%02x" |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 1a391e2df3b3..73da1c039b9d 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -7839,12 +7839,16 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
7839 | bf_set(wqe_lnk, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpXS); | 7839 | bf_set(wqe_lnk, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpXS); |
7840 | /* Always open the exchange */ | 7840 | /* Always open the exchange */ |
7841 | bf_set(wqe_xc, &wqe->fcp_iwrite.wqe_com, 0); | 7841 | bf_set(wqe_xc, &wqe->fcp_iwrite.wqe_com, 0); |
7842 | bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 1); | ||
7843 | bf_set(wqe_iod, &wqe->fcp_iwrite.wqe_com, LPFC_WQE_IOD_WRITE); | 7842 | bf_set(wqe_iod, &wqe->fcp_iwrite.wqe_com, LPFC_WQE_IOD_WRITE); |
7844 | bf_set(wqe_lenloc, &wqe->fcp_iwrite.wqe_com, | 7843 | bf_set(wqe_lenloc, &wqe->fcp_iwrite.wqe_com, |
7845 | LPFC_WQE_LENLOC_WORD4); | 7844 | LPFC_WQE_LENLOC_WORD4); |
7846 | bf_set(wqe_ebde_cnt, &wqe->fcp_iwrite.wqe_com, 0); | 7845 | bf_set(wqe_ebde_cnt, &wqe->fcp_iwrite.wqe_com, 0); |
7847 | bf_set(wqe_pu, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpPU); | 7846 | bf_set(wqe_pu, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpPU); |
7847 | if (iocbq->iocb_flag & LPFC_IO_DIF) { | ||
7848 | iocbq->iocb_flag &= ~LPFC_IO_DIF; | ||
7849 | bf_set(wqe_dif, &wqe->generic.wqe_com, 1); | ||
7850 | } | ||
7851 | bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 1); | ||
7848 | break; | 7852 | break; |
7849 | case CMD_FCP_IREAD64_CR: | 7853 | case CMD_FCP_IREAD64_CR: |
7850 | /* word3 iocb=iotag wqe=payload_offset_len */ | 7854 | /* word3 iocb=iotag wqe=payload_offset_len */ |
@@ -7858,12 +7862,16 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
7858 | bf_set(wqe_lnk, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpXS); | 7862 | bf_set(wqe_lnk, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpXS); |
7859 | /* Always open the exchange */ | 7863 | /* Always open the exchange */ |
7860 | bf_set(wqe_xc, &wqe->fcp_iread.wqe_com, 0); | 7864 | bf_set(wqe_xc, &wqe->fcp_iread.wqe_com, 0); |
7861 | bf_set(wqe_dbde, &wqe->fcp_iread.wqe_com, 1); | ||
7862 | bf_set(wqe_iod, &wqe->fcp_iread.wqe_com, LPFC_WQE_IOD_READ); | 7865 | bf_set(wqe_iod, &wqe->fcp_iread.wqe_com, LPFC_WQE_IOD_READ); |
7863 | bf_set(wqe_lenloc, &wqe->fcp_iread.wqe_com, | 7866 | bf_set(wqe_lenloc, &wqe->fcp_iread.wqe_com, |
7864 | LPFC_WQE_LENLOC_WORD4); | 7867 | LPFC_WQE_LENLOC_WORD4); |
7865 | bf_set(wqe_ebde_cnt, &wqe->fcp_iread.wqe_com, 0); | 7868 | bf_set(wqe_ebde_cnt, &wqe->fcp_iread.wqe_com, 0); |
7866 | bf_set(wqe_pu, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpPU); | 7869 | bf_set(wqe_pu, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpPU); |
7870 | if (iocbq->iocb_flag & LPFC_IO_DIF) { | ||
7871 | iocbq->iocb_flag &= ~LPFC_IO_DIF; | ||
7872 | bf_set(wqe_dif, &wqe->generic.wqe_com, 1); | ||
7873 | } | ||
7874 | bf_set(wqe_dbde, &wqe->fcp_iread.wqe_com, 1); | ||
7867 | break; | 7875 | break; |
7868 | case CMD_FCP_ICMND64_CR: | 7876 | case CMD_FCP_ICMND64_CR: |
7869 | /* word3 iocb=IO_TAG wqe=reserved */ | 7877 | /* word3 iocb=IO_TAG wqe=reserved */ |
@@ -10672,12 +10680,14 @@ lpfc_sli4_iocb_param_transfer(struct lpfc_hba *phba, | |||
10672 | struct lpfc_wcqe_complete *wcqe) | 10680 | struct lpfc_wcqe_complete *wcqe) |
10673 | { | 10681 | { |
10674 | unsigned long iflags; | 10682 | unsigned long iflags; |
10683 | uint32_t status; | ||
10675 | size_t offset = offsetof(struct lpfc_iocbq, iocb); | 10684 | size_t offset = offsetof(struct lpfc_iocbq, iocb); |
10676 | 10685 | ||
10677 | memcpy((char *)pIocbIn + offset, (char *)pIocbOut + offset, | 10686 | memcpy((char *)pIocbIn + offset, (char *)pIocbOut + offset, |
10678 | sizeof(struct lpfc_iocbq) - offset); | 10687 | sizeof(struct lpfc_iocbq) - offset); |
10679 | /* Map WCQE parameters into irspiocb parameters */ | 10688 | /* Map WCQE parameters into irspiocb parameters */ |
10680 | pIocbIn->iocb.ulpStatus = bf_get(lpfc_wcqe_c_status, wcqe); | 10689 | status = bf_get(lpfc_wcqe_c_status, wcqe); |
10690 | pIocbIn->iocb.ulpStatus = (status & LPFC_IOCB_STATUS_MASK); | ||
10681 | if (pIocbOut->iocb_flag & LPFC_IO_FCP) | 10691 | if (pIocbOut->iocb_flag & LPFC_IO_FCP) |
10682 | if (pIocbIn->iocb.ulpStatus == IOSTAT_FCP_RSP_ERROR) | 10692 | if (pIocbIn->iocb.ulpStatus == IOSTAT_FCP_RSP_ERROR) |
10683 | pIocbIn->iocb.un.fcpi.fcpi_parm = | 10693 | pIocbIn->iocb.un.fcpi.fcpi_parm = |
@@ -10690,6 +10700,44 @@ lpfc_sli4_iocb_param_transfer(struct lpfc_hba *phba, | |||
10690 | pIocbIn->iocb.un.genreq64.bdl.bdeSize = wcqe->total_data_placed; | 10700 | pIocbIn->iocb.un.genreq64.bdl.bdeSize = wcqe->total_data_placed; |
10691 | } | 10701 | } |
10692 | 10702 | ||
10703 | /* Convert BG errors for completion status */ | ||
10704 | if (status == CQE_STATUS_DI_ERROR) { | ||
10705 | pIocbIn->iocb.ulpStatus = IOSTAT_LOCAL_REJECT; | ||
10706 | |||
10707 | if (bf_get(lpfc_wcqe_c_bg_edir, wcqe)) | ||
10708 | pIocbIn->iocb.un.ulpWord[4] = IOERR_RX_DMA_FAILED; | ||
10709 | else | ||
10710 | pIocbIn->iocb.un.ulpWord[4] = IOERR_TX_DMA_FAILED; | ||
10711 | |||
10712 | pIocbIn->iocb.unsli3.sli3_bg.bgstat = 0; | ||
10713 | if (bf_get(lpfc_wcqe_c_bg_ge, wcqe)) /* Guard Check failed */ | ||
10714 | pIocbIn->iocb.unsli3.sli3_bg.bgstat |= | ||
10715 | BGS_GUARD_ERR_MASK; | ||
10716 | if (bf_get(lpfc_wcqe_c_bg_ae, wcqe)) /* App Tag Check failed */ | ||
10717 | pIocbIn->iocb.unsli3.sli3_bg.bgstat |= | ||
10718 | BGS_APPTAG_ERR_MASK; | ||
10719 | if (bf_get(lpfc_wcqe_c_bg_re, wcqe)) /* Ref Tag Check failed */ | ||
10720 | pIocbIn->iocb.unsli3.sli3_bg.bgstat |= | ||
10721 | BGS_REFTAG_ERR_MASK; | ||
10722 | |||
10723 | /* Check to see if there was any good data before the error */ | ||
10724 | if (bf_get(lpfc_wcqe_c_bg_tdpv, wcqe)) { | ||
10725 | pIocbIn->iocb.unsli3.sli3_bg.bgstat |= | ||
10726 | BGS_HI_WATER_MARK_PRESENT_MASK; | ||
10727 | pIocbIn->iocb.unsli3.sli3_bg.bghm = | ||
10728 | wcqe->total_data_placed; | ||
10729 | } | ||
10730 | |||
10731 | /* | ||
10732 | * Set ALL the error bits to indicate we don't know what | ||
10733 | * type of error it is. | ||
10734 | */ | ||
10735 | if (!pIocbIn->iocb.unsli3.sli3_bg.bgstat) | ||
10736 | pIocbIn->iocb.unsli3.sli3_bg.bgstat |= | ||
10737 | (BGS_REFTAG_ERR_MASK | BGS_APPTAG_ERR_MASK | | ||
10738 | BGS_GUARD_ERR_MASK); | ||
10739 | } | ||
10740 | |||
10693 | /* Pick up HBA exchange busy condition */ | 10741 | /* Pick up HBA exchange busy condition */ |
10694 | if (bf_get(lpfc_wcqe_c_xb, wcqe)) { | 10742 | if (bf_get(lpfc_wcqe_c_xb, wcqe)) { |
10695 | spin_lock_irqsave(&phba->hbalock, iflags); | 10743 | spin_lock_irqsave(&phba->hbalock, iflags); |
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index 29c13b63e323..3290b8e7ab65 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h | |||
@@ -69,6 +69,7 @@ struct lpfc_iocbq { | |||
69 | #define LPFC_USE_FCPWQIDX 0x80 /* Submit to specified FCPWQ index */ | 69 | #define LPFC_USE_FCPWQIDX 0x80 /* Submit to specified FCPWQ index */ |
70 | #define DSS_SECURITY_OP 0x100 /* security IO */ | 70 | #define DSS_SECURITY_OP 0x100 /* security IO */ |
71 | #define LPFC_IO_ON_Q 0x200 /* The IO is still on the TXCMPLQ */ | 71 | #define LPFC_IO_ON_Q 0x200 /* The IO is still on the TXCMPLQ */ |
72 | #define LPFC_IO_DIF 0x400 /* T10 DIF IO */ | ||
72 | 73 | ||
73 | #define LPFC_FIP_ELS_ID_MASK 0xc000 /* ELS_ID range 0-3, non-shifted mask */ | 74 | #define LPFC_FIP_ELS_ID_MASK 0xc000 /* ELS_ID range 0-3, non-shifted mask */ |
74 | #define LPFC_FIP_ELS_ID_SHIFT 14 | 75 | #define LPFC_FIP_ELS_ID_SHIFT 14 |