aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_init.c
diff options
context:
space:
mode:
authorSarang Radke <sarang.radke@qlogic.com>2010-03-19 20:03:59 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-04-11 10:45:50 -0400
commit09ff701a177b116c6c15b6e501e58fbfb306b424 (patch)
treefd99933ea29dbc36fc6636f5278d237dbee89b96 /drivers/scsi/qla2xxx/qla_init.c
parent6e98016ca077c5c751167bfdb1a3a2a3bee581cf (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.c168
1 files changed, 168 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 4229bb483c5..e7fe11486bb 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 */
4933uint8_t
4934qla24xx_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 */
5026int
5027qla24xx_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 */
5063int
5064qla24xx_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}