diff options
author | Sarang Radke <sarang.radke@qlogic.com> | 2010-03-19 20:03:59 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-04-11 10:45:50 -0400 |
commit | 09ff701a177b116c6c15b6e501e58fbfb306b424 (patch) | |
tree | fd99933ea29dbc36fc6636f5278d237dbee89b96 /drivers/scsi/qla2xxx/qla_init.c | |
parent | 6e98016ca077c5c751167bfdb1a3a2a3bee581cf (diff) |
[SCSI] qla2xxx: Add APEX support.
Allows priority setting for FCP_CMNDs.
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_init.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 4229bb483c5e..e7fe11486bb8 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -349,6 +349,12 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) | |||
349 | } | 349 | } |
350 | } | 350 | } |
351 | 351 | ||
352 | if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)) { | ||
353 | if (qla24xx_read_fcp_prio_cfg(vha)) | ||
354 | qla_printk(KERN_ERR, ha, | ||
355 | "Unable to read FCP priority data.\n"); | ||
356 | } | ||
357 | |||
352 | return (rval); | 358 | return (rval); |
353 | } | 359 | } |
354 | 360 | ||
@@ -4905,3 +4911,165 @@ qla81xx_update_fw_options(scsi_qla_host_t *vha) | |||
4905 | ha->fw_options[2] |= BIT_9; | 4911 | ha->fw_options[2] |= BIT_9; |
4906 | qla2x00_set_fw_options(vha, ha->fw_options); | 4912 | qla2x00_set_fw_options(vha, ha->fw_options); |
4907 | } | 4913 | } |
4914 | |||
4915 | /* | ||
4916 | * qla24xx_get_fcp_prio | ||
4917 | * Gets the fcp cmd priority value for the logged in port. | ||
4918 | * Looks for a match of the port descriptors within | ||
4919 | * each of the fcp prio config entries. If a match is found, | ||
4920 | * the tag (priority) value is returned. | ||
4921 | * | ||
4922 | * Input: | ||
4923 | * ha = adapter block po | ||
4924 | * fcport = port structure pointer. | ||
4925 | * | ||
4926 | * Return: | ||
4927 | * non-zero (if found) | ||
4928 | * 0 (if not found) | ||
4929 | * | ||
4930 | * Context: | ||
4931 | * Kernel context | ||
4932 | */ | ||
4933 | uint8_t | ||
4934 | qla24xx_get_fcp_prio(scsi_qla_host_t *vha, fc_port_t *fcport) | ||
4935 | { | ||
4936 | int i, entries; | ||
4937 | uint8_t pid_match, wwn_match; | ||
4938 | uint8_t priority; | ||
4939 | uint32_t pid1, pid2; | ||
4940 | uint64_t wwn1, wwn2; | ||
4941 | struct qla_fcp_prio_entry *pri_entry; | ||
4942 | struct qla_hw_data *ha = vha->hw; | ||
4943 | |||
4944 | if (!ha->fcp_prio_cfg || !ha->flags.fcp_prio_enabled) | ||
4945 | return 0; | ||
4946 | |||
4947 | priority = 0; | ||
4948 | entries = ha->fcp_prio_cfg->num_entries; | ||
4949 | pri_entry = &ha->fcp_prio_cfg->entry[0]; | ||
4950 | |||
4951 | for (i = 0; i < entries; i++) { | ||
4952 | pid_match = wwn_match = 0; | ||
4953 | |||
4954 | if (!(pri_entry->flags & FCP_PRIO_ENTRY_VALID)) { | ||
4955 | pri_entry++; | ||
4956 | continue; | ||
4957 | } | ||
4958 | |||
4959 | /* check source pid for a match */ | ||
4960 | if (pri_entry->flags & FCP_PRIO_ENTRY_SPID_VALID) { | ||
4961 | pid1 = pri_entry->src_pid & INVALID_PORT_ID; | ||
4962 | pid2 = vha->d_id.b24 & INVALID_PORT_ID; | ||
4963 | if (pid1 == INVALID_PORT_ID) | ||
4964 | pid_match++; | ||
4965 | else if (pid1 == pid2) | ||
4966 | pid_match++; | ||
4967 | } | ||
4968 | |||
4969 | /* check destination pid for a match */ | ||
4970 | if (pri_entry->flags & FCP_PRIO_ENTRY_DPID_VALID) { | ||
4971 | pid1 = pri_entry->dst_pid & INVALID_PORT_ID; | ||
4972 | pid2 = fcport->d_id.b24 & INVALID_PORT_ID; | ||
4973 | if (pid1 == INVALID_PORT_ID) | ||
4974 | pid_match++; | ||
4975 | else if (pid1 == pid2) | ||
4976 | pid_match++; | ||
4977 | } | ||
4978 | |||
4979 | /* check source WWN for a match */ | ||
4980 | if (pri_entry->flags & FCP_PRIO_ENTRY_SWWN_VALID) { | ||
4981 | wwn1 = wwn_to_u64(vha->port_name); | ||
4982 | wwn2 = wwn_to_u64(pri_entry->src_wwpn); | ||
4983 | if (wwn2 == (uint64_t)-1) | ||
4984 | wwn_match++; | ||
4985 | else if (wwn1 == wwn2) | ||
4986 | wwn_match++; | ||
4987 | } | ||
4988 | |||
4989 | /* check destination WWN for a match */ | ||
4990 | if (pri_entry->flags & FCP_PRIO_ENTRY_DWWN_VALID) { | ||
4991 | wwn1 = wwn_to_u64(fcport->port_name); | ||
4992 | wwn2 = wwn_to_u64(pri_entry->dst_wwpn); | ||
4993 | if (wwn2 == (uint64_t)-1) | ||
4994 | wwn_match++; | ||
4995 | else if (wwn1 == wwn2) | ||
4996 | wwn_match++; | ||
4997 | } | ||
4998 | |||
4999 | if (pid_match == 2 || wwn_match == 2) { | ||
5000 | /* Found a matching entry */ | ||
5001 | if (pri_entry->flags & FCP_PRIO_ENTRY_TAG_VALID) | ||
5002 | priority = pri_entry->tag; | ||
5003 | break; | ||
5004 | } | ||
5005 | |||
5006 | pri_entry++; | ||
5007 | } | ||
5008 | |||
5009 | return priority; | ||
5010 | } | ||
5011 | |||
5012 | /* | ||
5013 | * qla24xx_update_fcport_fcp_prio | ||
5014 | * Activates fcp priority for the logged in fc port | ||
5015 | * | ||
5016 | * Input: | ||
5017 | * ha = adapter block pointer. | ||
5018 | * fcp = port structure pointer. | ||
5019 | * | ||
5020 | * Return: | ||
5021 | * QLA_SUCCESS or QLA_FUNCTION_FAILED | ||
5022 | * | ||
5023 | * Context: | ||
5024 | * Kernel context. | ||
5025 | */ | ||
5026 | int | ||
5027 | qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *ha, fc_port_t *fcport) | ||
5028 | { | ||
5029 | int ret; | ||
5030 | uint8_t priority; | ||
5031 | uint16_t mb[5]; | ||
5032 | |||
5033 | if (atomic_read(&fcport->state) == FCS_UNCONFIGURED || | ||
5034 | fcport->port_type != FCT_TARGET || | ||
5035 | fcport->loop_id == FC_NO_LOOP_ID) | ||
5036 | return QLA_FUNCTION_FAILED; | ||
5037 | |||
5038 | priority = qla24xx_get_fcp_prio(ha, fcport); | ||
5039 | ret = qla24xx_set_fcp_prio(ha, fcport->loop_id, priority, mb); | ||
5040 | if (ret == QLA_SUCCESS) | ||
5041 | fcport->fcp_prio = priority; | ||
5042 | else | ||
5043 | DEBUG2(printk(KERN_WARNING | ||
5044 | "scsi(%ld): Unable to activate fcp priority, " | ||
5045 | " ret=0x%x\n", ha->host_no, ret)); | ||
5046 | |||
5047 | return ret; | ||
5048 | } | ||
5049 | |||
5050 | /* | ||
5051 | * qla24xx_update_all_fcp_prio | ||
5052 | * Activates fcp priority for all the logged in ports | ||
5053 | * | ||
5054 | * Input: | ||
5055 | * ha = adapter block pointer. | ||
5056 | * | ||
5057 | * Return: | ||
5058 | * QLA_SUCCESS or QLA_FUNCTION_FAILED | ||
5059 | * | ||
5060 | * Context: | ||
5061 | * Kernel context. | ||
5062 | */ | ||
5063 | int | ||
5064 | qla24xx_update_all_fcp_prio(scsi_qla_host_t *vha) | ||
5065 | { | ||
5066 | int ret; | ||
5067 | fc_port_t *fcport; | ||
5068 | |||
5069 | ret = QLA_FUNCTION_FAILED; | ||
5070 | /* We need to set priority for all logged in ports */ | ||
5071 | list_for_each_entry(fcport, &vha->vp_fcports, list) | ||
5072 | ret = qla24xx_update_fcport_fcp_prio(vha, fcport); | ||
5073 | |||
5074 | return ret; | ||
5075 | } | ||