aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_os.c
diff options
context:
space:
mode:
authorArun Easi <arun.easi@qlogic.com>2010-05-04 18:01:30 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-05-16 18:21:59 -0400
commitbad750028917a7b804623701d0674e46c6012c18 (patch)
treef8c4032b480e3c93b906e313eb6d371565b4b66d /drivers/scsi/qla2xxx/qla_os.c
parent3822263eb1e74821ad1ae886ddd2184ae9395ff7 (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.c75
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);
92MODULE_PARM_DESC(ql2xmaxqdepth, 92MODULE_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 */
96int ql2xenabledif = 1;
97module_param(ql2xenabledif, int, S_IRUGO|S_IWUSR);
98MODULE_PARM_DESC(ql2xenabledif,
99 " Enable T10-CRC-DIF "
100 " Default is 0 - No DIF Support. 1 - Enable it");
101
102int ql2xenablehba_err_chk;
103module_param(ql2xenablehba_err_chk, int, S_IRUGO|S_IWUSR);
104MODULE_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
95int ql2xiidmaenable=1; 108int ql2xiidmaenable=1;
96module_param(ql2xiidmaenable, int, S_IRUGO|S_IRUSR); 109module_param(ql2xiidmaenable, int, S_IRUGO|S_IRUSR);
97MODULE_PARM_DESC(ql2xiidmaenable, 110MODULE_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;
2680fail_dma_pool: 2719fail_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 }
2685fail_dl_dma_pool: 2724fail_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
3346qla2x00_sp_free_dma(srb_t *sp) 3385qla2x00_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))