diff options
author | Arun Easi <arun.easi@qlogic.com> | 2010-05-04 18:01:30 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-05-16 18:21:59 -0400 |
commit | bad750028917a7b804623701d0674e46c6012c18 (patch) | |
tree | f8c4032b480e3c93b906e313eb6d371565b4b66d /drivers/scsi/qla2xxx/qla_os.c | |
parent | 3822263eb1e74821ad1ae886ddd2184ae9395ff7 (diff) |
[SCSI] qla2xxx: T10 DIF support added.
Signed-off-by: Duane Grigsby <duane.grigsby@qlogic.com>
Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 75 |
1 files changed, 67 insertions, 8 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 523d414b59af..5104aefdc7e6 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -92,6 +92,19 @@ module_param(ql2xmaxqdepth, int, S_IRUGO|S_IWUSR); | |||
92 | MODULE_PARM_DESC(ql2xmaxqdepth, | 92 | MODULE_PARM_DESC(ql2xmaxqdepth, |
93 | "Maximum queue depth to report for target devices."); | 93 | "Maximum queue depth to report for target devices."); |
94 | 94 | ||
95 | /* Do not change the value of this after module load */ | ||
96 | int ql2xenabledif = 1; | ||
97 | module_param(ql2xenabledif, int, S_IRUGO|S_IWUSR); | ||
98 | MODULE_PARM_DESC(ql2xenabledif, | ||
99 | " Enable T10-CRC-DIF " | ||
100 | " Default is 0 - No DIF Support. 1 - Enable it"); | ||
101 | |||
102 | int ql2xenablehba_err_chk; | ||
103 | module_param(ql2xenablehba_err_chk, int, S_IRUGO|S_IWUSR); | ||
104 | MODULE_PARM_DESC(ql2xenablehba_err_chk, | ||
105 | " Enable T10-CRC-DIF Error isolation by HBA" | ||
106 | " Default is 0 - Error isolation disabled, 1 - Enable it"); | ||
107 | |||
95 | int ql2xiidmaenable=1; | 108 | int ql2xiidmaenable=1; |
96 | module_param(ql2xiidmaenable, int, S_IRUGO|S_IRUSR); | 109 | module_param(ql2xiidmaenable, int, S_IRUGO|S_IRUSR); |
97 | MODULE_PARM_DESC(ql2xiidmaenable, | 110 | MODULE_PARM_DESC(ql2xiidmaenable, |
@@ -537,6 +550,14 @@ qla2xxx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | |||
537 | if (fcport->drport) | 550 | if (fcport->drport) |
538 | goto qc24_target_busy; | 551 | goto qc24_target_busy; |
539 | 552 | ||
553 | if (!vha->flags.difdix_supported && | ||
554 | scsi_get_prot_op(cmd) != SCSI_PROT_NORMAL) { | ||
555 | DEBUG2(qla_printk(KERN_ERR, ha, | ||
556 | "DIF Cap Not Reg, fail DIF capable cmd's:%x\n", | ||
557 | cmd->cmnd[0])); | ||
558 | cmd->result = DID_NO_CONNECT << 16; | ||
559 | goto qc24_fail_command; | ||
560 | } | ||
540 | if (atomic_read(&fcport->state) != FCS_ONLINE) { | 561 | if (atomic_read(&fcport->state) != FCS_ONLINE) { |
541 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || | 562 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || |
542 | atomic_read(&base_vha->loop_state) == LOOP_DEAD) { | 563 | atomic_read(&base_vha->loop_state) == LOOP_DEAD) { |
@@ -776,7 +797,8 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
776 | 797 | ||
777 | if (sp == NULL) | 798 | if (sp == NULL) |
778 | continue; | 799 | continue; |
779 | if ((sp->ctx) && !(sp->flags & SRB_FCP_CMND_DMA_VALID)) | 800 | if ((sp->ctx) && !(sp->flags & SRB_FCP_CMND_DMA_VALID) && |
801 | !IS_PROT_IO(sp)) | ||
780 | continue; | 802 | continue; |
781 | if (sp->cmd != cmd) | 803 | if (sp->cmd != cmd) |
782 | continue; | 804 | continue; |
@@ -842,7 +864,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t, | |||
842 | sp = req->outstanding_cmds[cnt]; | 864 | sp = req->outstanding_cmds[cnt]; |
843 | if (!sp) | 865 | if (!sp) |
844 | continue; | 866 | continue; |
845 | if (sp->ctx) | 867 | if ((sp->ctx) && !IS_PROT_IO(sp)) |
846 | continue; | 868 | continue; |
847 | if (vha->vp_idx != sp->fcport->vha->vp_idx) | 869 | if (vha->vp_idx != sp->fcport->vha->vp_idx) |
848 | continue; | 870 | continue; |
@@ -1189,7 +1211,8 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) | |||
1189 | if (sp) { | 1211 | if (sp) { |
1190 | req->outstanding_cmds[cnt] = NULL; | 1212 | req->outstanding_cmds[cnt] = NULL; |
1191 | if (!sp->ctx || | 1213 | if (!sp->ctx || |
1192 | (sp->flags & SRB_FCP_CMND_DMA_VALID)) { | 1214 | (sp->flags & SRB_FCP_CMND_DMA_VALID) || |
1215 | IS_PROT_IO(sp)) { | ||
1193 | sp->cmd->result = res; | 1216 | sp->cmd->result = res; |
1194 | qla2x00_sp_compl(ha, sp); | 1217 | qla2x00_sp_compl(ha, sp); |
1195 | } else { | 1218 | } else { |
@@ -1553,7 +1576,7 @@ static struct isp_operations qla25xx_isp_ops = { | |||
1553 | .read_optrom = qla25xx_read_optrom_data, | 1576 | .read_optrom = qla25xx_read_optrom_data, |
1554 | .write_optrom = qla24xx_write_optrom_data, | 1577 | .write_optrom = qla24xx_write_optrom_data, |
1555 | .get_flash_version = qla24xx_get_flash_version, | 1578 | .get_flash_version = qla24xx_get_flash_version, |
1556 | .start_scsi = qla24xx_start_scsi, | 1579 | .start_scsi = qla24xx_dif_start_scsi, |
1557 | .abort_isp = qla2x00_abort_isp, | 1580 | .abort_isp = qla2x00_abort_isp, |
1558 | }; | 1581 | }; |
1559 | 1582 | ||
@@ -2185,6 +2208,22 @@ skip_dpc: | |||
2185 | DEBUG2(printk("DEBUG: detect hba %ld at address = %p\n", | 2208 | DEBUG2(printk("DEBUG: detect hba %ld at address = %p\n", |
2186 | base_vha->host_no, ha)); | 2209 | base_vha->host_no, ha)); |
2187 | 2210 | ||
2211 | if (IS_QLA25XX(ha) && ql2xenabledif) { | ||
2212 | if (ha->fw_attributes & BIT_4) { | ||
2213 | base_vha->flags.difdix_supported = 1; | ||
2214 | DEBUG18(qla_printk(KERN_INFO, ha, | ||
2215 | "Registering for DIF/DIX type 1 and 3" | ||
2216 | " protection.\n")); | ||
2217 | scsi_host_set_prot(host, | ||
2218 | SHOST_DIF_TYPE1_PROTECTION | ||
2219 | | SHOST_DIF_TYPE3_PROTECTION | ||
2220 | | SHOST_DIX_TYPE1_PROTECTION | ||
2221 | | SHOST_DIX_TYPE3_PROTECTION); | ||
2222 | scsi_host_set_guard(host, SHOST_DIX_GUARD_CRC); | ||
2223 | } else | ||
2224 | base_vha->flags.difdix_supported = 0; | ||
2225 | } | ||
2226 | |||
2188 | ha->isp_ops->enable_intrs(ha); | 2227 | ha->isp_ops->enable_intrs(ha); |
2189 | 2228 | ||
2190 | ret = scsi_add_host(host, &pdev->dev); | 2229 | ret = scsi_add_host(host, &pdev->dev); |
@@ -2546,7 +2585,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, | |||
2546 | if (!ha->s_dma_pool) | 2585 | if (!ha->s_dma_pool) |
2547 | goto fail_free_nvram; | 2586 | goto fail_free_nvram; |
2548 | 2587 | ||
2549 | if (IS_QLA82XX(ha)) { | 2588 | if (IS_QLA82XX(ha) || ql2xenabledif) { |
2550 | ha->dl_dma_pool = dma_pool_create(name, &ha->pdev->dev, | 2589 | ha->dl_dma_pool = dma_pool_create(name, &ha->pdev->dev, |
2551 | DSD_LIST_DMA_POOL_SIZE, 8, 0); | 2590 | DSD_LIST_DMA_POOL_SIZE, 8, 0); |
2552 | if (!ha->dl_dma_pool) { | 2591 | if (!ha->dl_dma_pool) { |
@@ -2678,12 +2717,12 @@ fail_free_ms_iocb: | |||
2678 | ha->ms_iocb = NULL; | 2717 | ha->ms_iocb = NULL; |
2679 | ha->ms_iocb_dma = 0; | 2718 | ha->ms_iocb_dma = 0; |
2680 | fail_dma_pool: | 2719 | fail_dma_pool: |
2681 | if (IS_QLA82XX(ha)) { | 2720 | if (IS_QLA82XX(ha) || ql2xenabledif) { |
2682 | dma_pool_destroy(ha->fcp_cmnd_dma_pool); | 2721 | dma_pool_destroy(ha->fcp_cmnd_dma_pool); |
2683 | ha->fcp_cmnd_dma_pool = NULL; | 2722 | ha->fcp_cmnd_dma_pool = NULL; |
2684 | } | 2723 | } |
2685 | fail_dl_dma_pool: | 2724 | fail_dl_dma_pool: |
2686 | if (IS_QLA82XX(ha)) { | 2725 | if (IS_QLA82XX(ha) || ql2xenabledif) { |
2687 | dma_pool_destroy(ha->dl_dma_pool); | 2726 | dma_pool_destroy(ha->dl_dma_pool); |
2688 | ha->dl_dma_pool = NULL; | 2727 | ha->dl_dma_pool = NULL; |
2689 | } | 2728 | } |
@@ -3346,11 +3385,31 @@ static void | |||
3346 | qla2x00_sp_free_dma(srb_t *sp) | 3385 | qla2x00_sp_free_dma(srb_t *sp) |
3347 | { | 3386 | { |
3348 | struct scsi_cmnd *cmd = sp->cmd; | 3387 | struct scsi_cmnd *cmd = sp->cmd; |
3388 | struct qla_hw_data *ha = sp->fcport->vha->hw; | ||
3349 | 3389 | ||
3350 | if (sp->flags & SRB_DMA_VALID) { | 3390 | if (sp->flags & SRB_DMA_VALID) { |
3351 | scsi_dma_unmap(cmd); | 3391 | scsi_dma_unmap(cmd); |
3352 | sp->flags &= ~SRB_DMA_VALID; | 3392 | sp->flags &= ~SRB_DMA_VALID; |
3353 | } | 3393 | } |
3394 | |||
3395 | if (sp->flags & SRB_CRC_PROT_DMA_VALID) { | ||
3396 | dma_unmap_sg(&ha->pdev->dev, scsi_prot_sglist(cmd), | ||
3397 | scsi_prot_sg_count(cmd), cmd->sc_data_direction); | ||
3398 | sp->flags &= ~SRB_CRC_PROT_DMA_VALID; | ||
3399 | } | ||
3400 | |||
3401 | if (sp->flags & SRB_CRC_CTX_DSD_VALID) { | ||
3402 | /* List assured to be having elements */ | ||
3403 | qla2x00_clean_dsd_pool(ha, sp); | ||
3404 | sp->flags &= ~SRB_CRC_CTX_DSD_VALID; | ||
3405 | } | ||
3406 | |||
3407 | if (sp->flags & SRB_CRC_CTX_DMA_VALID) { | ||
3408 | dma_pool_free(ha->dl_dma_pool, sp->ctx, | ||
3409 | ((struct crc_context *)sp->ctx)->crc_ctx_dma); | ||
3410 | sp->flags &= ~SRB_CRC_CTX_DMA_VALID; | ||
3411 | } | ||
3412 | |||
3354 | CMD_SP(cmd) = NULL; | 3413 | CMD_SP(cmd) = NULL; |
3355 | } | 3414 | } |
3356 | 3415 | ||
@@ -3464,7 +3523,7 @@ qla2x00_timer(scsi_qla_host_t *vha) | |||
3464 | sp = req->outstanding_cmds[index]; | 3523 | sp = req->outstanding_cmds[index]; |
3465 | if (!sp) | 3524 | if (!sp) |
3466 | continue; | 3525 | continue; |
3467 | if (sp->ctx) | 3526 | if (sp->ctx && !IS_PROT_IO(sp)) |
3468 | continue; | 3527 | continue; |
3469 | sfcp = sp->fcport; | 3528 | sfcp = sp->fcport; |
3470 | if (!(sfcp->flags & FCF_FCP2_DEVICE)) | 3529 | if (!(sfcp->flags & FCF_FCP2_DEVICE)) |