aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorChad Dupuis <chad.dupuis@qlogic.com>2010-07-23 06:28:25 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-28 10:06:09 -0400
commite8c72ba51a159f5d1cb195d3fb47262c782939d9 (patch)
tree7ea9c96011386e4c36b9bb2c35da55ae7160fcb9 /drivers/scsi
parent2f0f3f4f06f7cfadebf58b70bd9e7f71d8fd96e4 (diff)
[SCSI] qla2xxx: Use GFF_ID to check FCP-SCSI FC4 type before logging into Nx_Ports
The default method that qla2xxx uses is the GID_PT nameserver command to get a list of Nx_Ports. This patch adds a GFF_ID call for each port returned by GID_PT to get the FC4 type. If the FC4 type is not FCP SCSI then the qla2xxx driver will not record that port in it's port database. For switches that do not support the GFF_ID command, the behavior will be for qla2xxx to store that port anyways. Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h20
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h1
-rw-r--r--drivers/scsi/qla2xxx/qla_gs.c72
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c11
4 files changed, 103 insertions, 1 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 7f9f86b8140b..02c7480c99c3 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -1652,8 +1652,14 @@ typedef struct {
1652 uint8_t port_name[WWN_SIZE]; 1652 uint8_t port_name[WWN_SIZE];
1653 uint8_t fabric_port_name[WWN_SIZE]; 1653 uint8_t fabric_port_name[WWN_SIZE];
1654 uint16_t fp_speed; 1654 uint16_t fp_speed;
1655 uint8_t fc4_type;
1655} sw_info_t; 1656} sw_info_t;
1656 1657
1658/* FCP-4 types */
1659#define FC4_TYPE_FCP_SCSI 0x08
1660#define FC4_TYPE_OTHER 0x0
1661#define FC4_TYPE_UNKNOWN 0xff
1662
1657/* 1663/*
1658 * Fibre channel port type. 1664 * Fibre channel port type.
1659 */ 1665 */
@@ -1697,6 +1703,7 @@ typedef struct fc_port {
1697 u32 supported_classes; 1703 u32 supported_classes;
1698 1704
1699 uint16_t vp_idx; 1705 uint16_t vp_idx;
1706 uint8_t fc4_type;
1700} fc_port_t; 1707} fc_port_t;
1701 1708
1702/* 1709/*
@@ -1779,6 +1786,9 @@ typedef struct fc_port {
1779#define GPSC_REQ_SIZE (16 + 8) 1786#define GPSC_REQ_SIZE (16 + 8)
1780#define GPSC_RSP_SIZE (16 + 2 + 2) 1787#define GPSC_RSP_SIZE (16 + 2 + 2)
1781 1788
1789#define GFF_ID_CMD 0x011F
1790#define GFF_ID_REQ_SIZE (16 + 4)
1791#define GFF_ID_RSP_SIZE (16 + 128)
1782 1792
1783/* 1793/*
1784 * HBA attribute types. 1794 * HBA attribute types.
@@ -1980,6 +1990,11 @@ struct ct_sns_req {
1980 struct { 1990 struct {
1981 uint8_t port_name[8]; 1991 uint8_t port_name[8];
1982 } gpsc; 1992 } gpsc;
1993
1994 struct {
1995 uint8_t reserved;
1996 uint8_t port_name[3];
1997 } gff_id;
1983 } req; 1998 } req;
1984}; 1999};
1985 2000
@@ -2052,6 +2067,11 @@ struct ct_sns_rsp {
2052 uint16_t speeds; 2067 uint16_t speeds;
2053 uint16_t speed; 2068 uint16_t speed;
2054 } gpsc; 2069 } gpsc;
2070
2071#define GFF_FCP_SCSI_OFFSET 7
2072 struct {
2073 uint8_t fc4_features[128];
2074 } gff_id;
2055 } rsp; 2075 } rsp;
2056}; 2076};
2057 2077
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index fd299911d7d6..55f4599ade63 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -441,6 +441,7 @@ extern int qla2x00_ga_nxt(scsi_qla_host_t *, fc_port_t *);
441extern int qla2x00_gid_pt(scsi_qla_host_t *, sw_info_t *); 441extern int qla2x00_gid_pt(scsi_qla_host_t *, sw_info_t *);
442extern int qla2x00_gpn_id(scsi_qla_host_t *, sw_info_t *); 442extern int qla2x00_gpn_id(scsi_qla_host_t *, sw_info_t *);
443extern int qla2x00_gnn_id(scsi_qla_host_t *, sw_info_t *); 443extern int qla2x00_gnn_id(scsi_qla_host_t *, sw_info_t *);
444extern void qla2x00_gff_id(scsi_qla_host_t *, sw_info_t *);
444extern int qla2x00_rft_id(scsi_qla_host_t *); 445extern int qla2x00_rft_id(scsi_qla_host_t *);
445extern int qla2x00_rff_id(scsi_qla_host_t *); 446extern int qla2x00_rff_id(scsi_qla_host_t *);
446extern int qla2x00_rnn_id(scsi_qla_host_t *); 447extern int qla2x00_rnn_id(scsi_qla_host_t *);
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 872c55f049a5..2fabae8daec4 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -1913,3 +1913,75 @@ qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list)
1913 1913
1914 return (rval); 1914 return (rval);
1915} 1915}
1916
1917/**
1918 * qla2x00_gff_id() - SNS Get FC-4 Features (GFF_ID) query.
1919 *
1920 * @ha: HA context
1921 * @list: switch info entries to populate
1922 *
1923 */
1924void
1925qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
1926{
1927 int rval;
1928 uint16_t i;
1929
1930 ms_iocb_entry_t *ms_pkt;
1931 struct ct_sns_req *ct_req;
1932 struct ct_sns_rsp *ct_rsp;
1933 struct qla_hw_data *ha = vha->hw;
1934 uint8_t fcp_scsi_features = 0;
1935
1936 for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
1937 /* Set default FC4 Type as UNKNOWN so the default is to
1938 * Process this port */
1939 list[i].fc4_type = FC4_TYPE_UNKNOWN;
1940
1941 /* Do not attempt GFF_ID if we are not FWI_2 capable */
1942 if (!IS_FWI2_CAPABLE(ha))
1943 continue;
1944
1945 /* Prepare common MS IOCB */
1946 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GFF_ID_REQ_SIZE,
1947 GFF_ID_RSP_SIZE);
1948
1949 /* Prepare CT request */
1950 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFF_ID_CMD,
1951 GFF_ID_RSP_SIZE);
1952 ct_rsp = &ha->ct_sns->p.rsp;
1953
1954 /* Prepare CT arguments -- port_id */
1955 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
1956 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
1957 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
1958
1959 /* Execute MS IOCB */
1960 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
1961 sizeof(ms_iocb_entry_t));
1962
1963 if (rval != QLA_SUCCESS) {
1964 DEBUG2_3(printk(KERN_INFO
1965 "scsi(%ld): GFF_ID issue IOCB failed "
1966 "(%d).\n", vha->host_no, rval));
1967 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
1968 "GPN_ID") != QLA_SUCCESS) {
1969 DEBUG2_3(printk(KERN_INFO
1970 "scsi(%ld): GFF_ID IOCB status had a "
1971 "failure status code\n", vha->host_no));
1972 } else {
1973 fcp_scsi_features =
1974 ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
1975 fcp_scsi_features &= 0x0f;
1976
1977 if (fcp_scsi_features)
1978 list[i].fc4_type = FC4_TYPE_FCP_SCSI;
1979 else
1980 list[i].fc4_type = FC4_TYPE_OTHER;
1981 }
1982
1983 /* Last device exit. */
1984 if (list[i].d_id.b.rsvd_1 != 0)
1985 break;
1986 }
1987}
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index cea491bf0fc0..685c350007b0 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -3078,7 +3078,6 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
3078 return (rval); 3078 return (rval);
3079} 3079}
3080 3080
3081
3082/* 3081/*
3083 * qla2x00_find_all_fabric_devs 3082 * qla2x00_find_all_fabric_devs
3084 * 3083 *
@@ -3131,6 +3130,10 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
3131 qla2x00_gfpn_id(vha, swl) == QLA_SUCCESS) { 3130 qla2x00_gfpn_id(vha, swl) == QLA_SUCCESS) {
3132 qla2x00_gpsc(vha, swl); 3131 qla2x00_gpsc(vha, swl);
3133 } 3132 }
3133
3134 /* If other queries succeeded probe for FC-4 type */
3135 if (swl)
3136 qla2x00_gff_id(vha, swl);
3134 } 3137 }
3135 swl_idx = 0; 3138 swl_idx = 0;
3136 3139
@@ -3172,6 +3175,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
3172 memcpy(new_fcport->fabric_port_name, 3175 memcpy(new_fcport->fabric_port_name,
3173 swl[swl_idx].fabric_port_name, WWN_SIZE); 3176 swl[swl_idx].fabric_port_name, WWN_SIZE);
3174 new_fcport->fp_speed = swl[swl_idx].fp_speed; 3177 new_fcport->fp_speed = swl[swl_idx].fp_speed;
3178 new_fcport->fc4_type = swl[swl_idx].fc4_type;
3175 3179
3176 if (swl[swl_idx].d_id.b.rsvd_1 != 0) { 3180 if (swl[swl_idx].d_id.b.rsvd_1 != 0) {
3177 last_dev = 1; 3181 last_dev = 1;
@@ -3233,6 +3237,11 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
3233 if ((new_fcport->d_id.b.domain & 0xf0) == 0xf0) 3237 if ((new_fcport->d_id.b.domain & 0xf0) == 0xf0)
3234 continue; 3238 continue;
3235 3239
3240 /* Bypass ports whose FCP-4 type is not FCP_SCSI */
3241 if (new_fcport->fc4_type != FC4_TYPE_FCP_SCSI &&
3242 new_fcport->fc4_type != FC4_TYPE_UNKNOWN)
3243 continue;
3244
3236 /* Locate matching device in database. */ 3245 /* Locate matching device in database. */
3237 found = 0; 3246 found = 0;
3238 list_for_each_entry(fcport, &vha->vp_fcports, list) { 3247 list_for_each_entry(fcport, &vha->vp_fcports, list) {