aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_scsi.c
diff options
context:
space:
mode:
authorFelix Beck <felix.beck@de.ibm.com>2010-07-16 09:37:42 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-28 10:48:56 -0400
commitef3eb71d8ba4fd9d48c5f9310bc9d90ca00323b4 (patch)
tree9903cbae6c03184687c51b4be926572913cda93f /drivers/s390/scsi/zfcp_scsi.c
parentdcc18f48a2f1a44c5e8848f30d0cf53a8066c62a (diff)
[SCSI] zfcp: Introduce experimental support for DIF/DIX
Introduce support for DIF/DIX in zfcp: Report the capabilities for the Scsi_host, map the protection data when issuing I/O requests and handle the new error codes. Also add the fsf data_direction field to the hba trace, it is useful information for debugging in that area. This is an EXPERIMENTAL feature for now. Signed-off-by: Felix Beck <felix.beck@de.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/s390/scsi/zfcp_scsi.c')
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index eb471a1723cd..cb000c9833bb 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -12,6 +12,7 @@
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <scsi/fc/fc_fcp.h> 14#include <scsi/fc/fc_fcp.h>
15#include <scsi/scsi_eh.h>
15#include <asm/atomic.h> 16#include <asm/atomic.h>
16#include "zfcp_ext.h" 17#include "zfcp_ext.h"
17#include "zfcp_dbf.h" 18#include "zfcp_dbf.h"
@@ -22,6 +23,13 @@ static unsigned int default_depth = 32;
22module_param_named(queue_depth, default_depth, uint, 0600); 23module_param_named(queue_depth, default_depth, uint, 0600);
23MODULE_PARM_DESC(queue_depth, "Default queue depth for new SCSI devices"); 24MODULE_PARM_DESC(queue_depth, "Default queue depth for new SCSI devices");
24 25
26static bool enable_dif;
27
28#ifdef CONFIG_ZFCP_DIF
29module_param_named(dif, enable_dif, bool, 0600);
30MODULE_PARM_DESC(dif, "Enable DIF/DIX data integrity support");
31#endif
32
25static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth, 33static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth,
26 int reason) 34 int reason)
27{ 35{
@@ -652,6 +660,51 @@ void zfcp_scsi_scan_work(struct work_struct *work)
652 put_device(&unit->dev); 660 put_device(&unit->dev);
653} 661}
654 662
663/**
664 * zfcp_scsi_set_prot - Configure DIF/DIX support in scsi_host
665 * @adapter: The adapter where to configure DIF/DIX for the SCSI host
666 */
667void zfcp_scsi_set_prot(struct zfcp_adapter *adapter)
668{
669 unsigned int mask = 0;
670 unsigned int data_div;
671 struct Scsi_Host *shost = adapter->scsi_host;
672
673 data_div = atomic_read(&adapter->status) &
674 ZFCP_STATUS_ADAPTER_DATA_DIV_ENABLED;
675
676 if (enable_dif &&
677 adapter->adapter_features & FSF_FEATURE_DIF_PROT_TYPE1)
678 mask |= SHOST_DIF_TYPE1_PROTECTION;
679
680 if (enable_dif && data_div &&
681 adapter->adapter_features & FSF_FEATURE_DIX_PROT_TCPIP) {
682 mask |= SHOST_DIX_TYPE1_PROTECTION;
683 scsi_host_set_guard(shost, SHOST_DIX_GUARD_IP);
684 shost->sg_tablesize = ZFCP_QDIO_MAX_SBALES_PER_REQ / 2;
685 shost->max_sectors = ZFCP_QDIO_MAX_SBALES_PER_REQ * 8 / 2;
686 }
687
688 scsi_host_set_prot(shost, mask);
689}
690
691/**
692 * zfcp_scsi_dif_sense_error - Report DIF/DIX error as driver sense error
693 * @scmd: The SCSI command to report the error for
694 * @ascq: The ASCQ to put in the sense buffer
695 *
696 * See the error handling in sd_done for the sense codes used here.
697 * Set DID_SOFT_ERROR to retry the request, if possible.
698 */
699void zfcp_scsi_dif_sense_error(struct scsi_cmnd *scmd, int ascq)
700{
701 scsi_build_sense_buffer(1, scmd->sense_buffer,
702 ILLEGAL_REQUEST, 0x10, ascq);
703 set_driver_byte(scmd, DRIVER_SENSE);
704 scmd->result |= SAM_STAT_CHECK_CONDITION;
705 set_host_byte(scmd, DID_SOFT_ERROR);
706}
707
655struct fc_function_template zfcp_transport_functions = { 708struct fc_function_template zfcp_transport_functions = {
656 .show_starget_port_id = 1, 709 .show_starget_port_id = 1,
657 .show_starget_port_name = 1, 710 .show_starget_port_name = 1,