diff options
author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2008-01-17 12:02:08 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-23 12:29:29 -0500 |
commit | 43ef058010c79a967195539bbcdeee8c5b24219d (patch) | |
tree | b0d13f3b2a79777a306d9c84adbfec3499c97af0 | |
parent | 4733fcb1fe4d64402a8bd18cec766e8b8ad25eee (diff) |
[SCSI] qla2xxx: Retrieve additional HBA port statistics from recent ISPs.
HBAs supporting these additional counters include ISP24xx and
ISP25xx type boards.
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 44 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 22 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 7 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 99 |
4 files changed, 74 insertions, 98 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 745283fcbf2c..e3bda8f7668c 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -967,35 +967,51 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) | |||
967 | { | 967 | { |
968 | scsi_qla_host_t *ha = shost_priv(shost); | 968 | scsi_qla_host_t *ha = shost_priv(shost); |
969 | int rval; | 969 | int rval; |
970 | uint16_t mb_stat[1]; | 970 | struct link_statistics *stats; |
971 | link_stat_t stat_buf; | 971 | dma_addr_t stats_dma; |
972 | struct fc_host_statistics *pfc_host_stat; | 972 | struct fc_host_statistics *pfc_host_stat; |
973 | 973 | ||
974 | rval = QLA_FUNCTION_FAILED; | ||
975 | pfc_host_stat = &ha->fc_host_stat; | 974 | pfc_host_stat = &ha->fc_host_stat; |
976 | memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); | 975 | memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); |
977 | 976 | ||
977 | stats = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &stats_dma); | ||
978 | if (stats == NULL) { | ||
979 | DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n", | ||
980 | __func__, ha->host_no)); | ||
981 | goto done; | ||
982 | } | ||
983 | memset(stats, 0, DMA_POOL_SIZE); | ||
984 | |||
985 | rval = QLA_FUNCTION_FAILED; | ||
978 | if (IS_FWI2_CAPABLE(ha)) { | 986 | if (IS_FWI2_CAPABLE(ha)) { |
979 | rval = qla24xx_get_isp_stats(ha, (uint32_t *)&stat_buf, | 987 | rval = qla24xx_get_isp_stats(ha, stats, stats_dma); |
980 | sizeof(stat_buf) / 4, mb_stat); | ||
981 | } else if (atomic_read(&ha->loop_state) == LOOP_READY && | 988 | } else if (atomic_read(&ha->loop_state) == LOOP_READY && |
982 | !test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) && | 989 | !test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) && |
983 | !test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) && | 990 | !test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) && |
984 | !ha->dpc_active) { | 991 | !ha->dpc_active) { |
985 | /* Must be in a 'READY' state for statistics retrieval. */ | 992 | /* Must be in a 'READY' state for statistics retrieval. */ |
986 | rval = qla2x00_get_link_status(ha, ha->loop_id, &stat_buf, | 993 | rval = qla2x00_get_link_status(ha, ha->loop_id, stats, |
987 | mb_stat); | 994 | stats_dma); |
988 | } | 995 | } |
989 | 996 | ||
990 | if (rval != QLA_SUCCESS) | 997 | if (rval != QLA_SUCCESS) |
991 | goto done; | 998 | goto done_free; |
999 | |||
1000 | pfc_host_stat->link_failure_count = stats->link_fail_cnt; | ||
1001 | pfc_host_stat->loss_of_sync_count = stats->loss_sync_cnt; | ||
1002 | pfc_host_stat->loss_of_signal_count = stats->loss_sig_cnt; | ||
1003 | pfc_host_stat->prim_seq_protocol_err_count = stats->prim_seq_err_cnt; | ||
1004 | pfc_host_stat->invalid_tx_word_count = stats->inval_xmit_word_cnt; | ||
1005 | pfc_host_stat->invalid_crc_count = stats->inval_crc_cnt; | ||
1006 | if (IS_FWI2_CAPABLE(ha)) { | ||
1007 | pfc_host_stat->tx_frames = stats->tx_frames; | ||
1008 | pfc_host_stat->rx_frames = stats->rx_frames; | ||
1009 | pfc_host_stat->dumped_frames = stats->dumped_frames; | ||
1010 | pfc_host_stat->nos_count = stats->nos_rcvd; | ||
1011 | } | ||
992 | 1012 | ||
993 | pfc_host_stat->link_failure_count = stat_buf.link_fail_cnt; | 1013 | done_free: |
994 | pfc_host_stat->loss_of_sync_count = stat_buf.loss_sync_cnt; | 1014 | dma_pool_free(ha->s_dma_pool, stats, stats_dma); |
995 | pfc_host_stat->loss_of_signal_count = stat_buf.loss_sig_cnt; | ||
996 | pfc_host_stat->prim_seq_protocol_err_count = stat_buf.prim_seq_err_cnt; | ||
997 | pfc_host_stat->invalid_tx_word_count = stat_buf.inval_xmit_word_cnt; | ||
998 | pfc_host_stat->invalid_crc_count = stat_buf.inval_crc_cnt; | ||
999 | done: | 1015 | done: |
1000 | return pfc_host_stat; | 1016 | return pfc_host_stat; |
1001 | } | 1017 | } |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index fe8f7828f592..a33d3d57a17e 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -862,14 +862,20 @@ typedef struct { | |||
862 | #define GLSO_SEND_RPS BIT_0 | 862 | #define GLSO_SEND_RPS BIT_0 |
863 | #define GLSO_USE_DID BIT_3 | 863 | #define GLSO_USE_DID BIT_3 |
864 | 864 | ||
865 | typedef struct { | 865 | struct link_statistics { |
866 | uint32_t link_fail_cnt; | 866 | uint32_t link_fail_cnt; |
867 | uint32_t loss_sync_cnt; | 867 | uint32_t loss_sync_cnt; |
868 | uint32_t loss_sig_cnt; | 868 | uint32_t loss_sig_cnt; |
869 | uint32_t prim_seq_err_cnt; | 869 | uint32_t prim_seq_err_cnt; |
870 | uint32_t inval_xmit_word_cnt; | 870 | uint32_t inval_xmit_word_cnt; |
871 | uint32_t inval_crc_cnt; | 871 | uint32_t inval_crc_cnt; |
872 | } link_stat_t; | 872 | uint32_t unused1[0x1b]; |
873 | uint32_t tx_frames; | ||
874 | uint32_t rx_frames; | ||
875 | uint32_t dumped_frames; | ||
876 | uint32_t unused2[2]; | ||
877 | uint32_t nos_rcvd; | ||
878 | }; | ||
873 | 879 | ||
874 | /* | 880 | /* |
875 | * NVRAM Command values. | 881 | * NVRAM Command values. |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 09cb2a908059..5b381dc8d749 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -222,11 +222,12 @@ extern int | |||
222 | qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map); | 222 | qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map); |
223 | 223 | ||
224 | extern int | 224 | extern int |
225 | qla2x00_get_link_status(scsi_qla_host_t *, uint16_t, link_stat_t *, | 225 | qla2x00_get_link_status(scsi_qla_host_t *, uint16_t, struct link_statistics *, |
226 | uint16_t *); | 226 | dma_addr_t); |
227 | 227 | ||
228 | extern int | 228 | extern int |
229 | qla24xx_get_isp_stats(scsi_qla_host_t *, uint32_t *, uint32_t, uint16_t *); | 229 | qla24xx_get_isp_stats(scsi_qla_host_t *, struct link_statistics *, |
230 | dma_addr_t); | ||
230 | 231 | ||
231 | extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *); | 232 | extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *); |
232 | extern int qla24xx_abort_target(fc_port_t *); | 233 | extern int qla24xx_abort_target(fc_port_t *); |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 031f269149b1..0fc165288f88 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -2042,29 +2042,20 @@ qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map) | |||
2042 | */ | 2042 | */ |
2043 | int | 2043 | int |
2044 | qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, | 2044 | qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, |
2045 | link_stat_t *ret_buf, uint16_t *status) | 2045 | struct link_statistics *stats, dma_addr_t stats_dma) |
2046 | { | 2046 | { |
2047 | int rval; | 2047 | int rval; |
2048 | mbx_cmd_t mc; | 2048 | mbx_cmd_t mc; |
2049 | mbx_cmd_t *mcp = &mc; | 2049 | mbx_cmd_t *mcp = &mc; |
2050 | link_stat_t *stat_buf; | 2050 | uint32_t *siter, *diter, dwords; |
2051 | dma_addr_t stat_buf_dma; | ||
2052 | 2051 | ||
2053 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | 2052 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
2054 | 2053 | ||
2055 | stat_buf = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &stat_buf_dma); | ||
2056 | if (stat_buf == NULL) { | ||
2057 | DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n", | ||
2058 | __func__, ha->host_no)); | ||
2059 | return BIT_0; | ||
2060 | } | ||
2061 | memset(stat_buf, 0, sizeof(link_stat_t)); | ||
2062 | |||
2063 | mcp->mb[0] = MBC_GET_LINK_STATUS; | 2054 | mcp->mb[0] = MBC_GET_LINK_STATUS; |
2064 | mcp->mb[2] = MSW(stat_buf_dma); | 2055 | mcp->mb[2] = MSW(stats_dma); |
2065 | mcp->mb[3] = LSW(stat_buf_dma); | 2056 | mcp->mb[3] = LSW(stats_dma); |
2066 | mcp->mb[6] = MSW(MSD(stat_buf_dma)); | 2057 | mcp->mb[6] = MSW(MSD(stats_dma)); |
2067 | mcp->mb[7] = LSW(MSD(stat_buf_dma)); | 2058 | mcp->mb[7] = LSW(MSD(stats_dma)); |
2068 | mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; | 2059 | mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; |
2069 | mcp->in_mb = MBX_0; | 2060 | mcp->in_mb = MBX_0; |
2070 | if (IS_FWI2_CAPABLE(ha)) { | 2061 | if (IS_FWI2_CAPABLE(ha)) { |
@@ -2089,78 +2080,43 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, | |||
2089 | if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { | 2080 | if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { |
2090 | DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n", | 2081 | DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n", |
2091 | __func__, ha->host_no, mcp->mb[0])); | 2082 | __func__, ha->host_no, mcp->mb[0])); |
2092 | status[0] = mcp->mb[0]; | 2083 | rval = QLA_FUNCTION_FAILED; |
2093 | rval = BIT_1; | ||
2094 | } else { | 2084 | } else { |
2095 | /* copy over data -- firmware data is LE. */ | 2085 | /* Copy over data -- firmware data is LE. */ |
2096 | ret_buf->link_fail_cnt = | 2086 | dwords = offsetof(struct link_statistics, unused1) / 4; |
2097 | le32_to_cpu(stat_buf->link_fail_cnt); | 2087 | siter = diter = &stats->link_fail_cnt; |
2098 | ret_buf->loss_sync_cnt = | 2088 | while (dwords--) |
2099 | le32_to_cpu(stat_buf->loss_sync_cnt); | 2089 | *diter++ = le32_to_cpu(*siter++); |
2100 | ret_buf->loss_sig_cnt = | ||
2101 | le32_to_cpu(stat_buf->loss_sig_cnt); | ||
2102 | ret_buf->prim_seq_err_cnt = | ||
2103 | le32_to_cpu(stat_buf->prim_seq_err_cnt); | ||
2104 | ret_buf->inval_xmit_word_cnt = | ||
2105 | le32_to_cpu(stat_buf->inval_xmit_word_cnt); | ||
2106 | ret_buf->inval_crc_cnt = | ||
2107 | le32_to_cpu(stat_buf->inval_crc_cnt); | ||
2108 | |||
2109 | DEBUG11(printk("%s(%ld): stat dump: fail_cnt=%d " | ||
2110 | "loss_sync=%d loss_sig=%d seq_err=%d " | ||
2111 | "inval_xmt_word=%d inval_crc=%d.\n", __func__, | ||
2112 | ha->host_no, stat_buf->link_fail_cnt, | ||
2113 | stat_buf->loss_sync_cnt, stat_buf->loss_sig_cnt, | ||
2114 | stat_buf->prim_seq_err_cnt, | ||
2115 | stat_buf->inval_xmit_word_cnt, | ||
2116 | stat_buf->inval_crc_cnt)); | ||
2117 | } | 2090 | } |
2118 | } else { | 2091 | } else { |
2119 | /* Failed. */ | 2092 | /* Failed. */ |
2120 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, | 2093 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, |
2121 | ha->host_no, rval)); | 2094 | ha->host_no, rval)); |
2122 | rval = BIT_1; | ||
2123 | } | 2095 | } |
2124 | 2096 | ||
2125 | dma_pool_free(ha->s_dma_pool, stat_buf, stat_buf_dma); | ||
2126 | |||
2127 | return rval; | 2097 | return rval; |
2128 | } | 2098 | } |
2129 | 2099 | ||
2130 | int | 2100 | int |
2131 | qla24xx_get_isp_stats(scsi_qla_host_t *ha, uint32_t *dwbuf, uint32_t dwords, | 2101 | qla24xx_get_isp_stats(scsi_qla_host_t *ha, struct link_statistics *stats, |
2132 | uint16_t *status) | 2102 | dma_addr_t stats_dma) |
2133 | { | 2103 | { |
2134 | int rval; | 2104 | int rval; |
2135 | mbx_cmd_t mc; | 2105 | mbx_cmd_t mc; |
2136 | mbx_cmd_t *mcp = &mc; | 2106 | mbx_cmd_t *mcp = &mc; |
2137 | uint32_t *sbuf, *siter; | 2107 | uint32_t *siter, *diter, dwords; |
2138 | dma_addr_t sbuf_dma; | ||
2139 | 2108 | ||
2140 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | 2109 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
2141 | 2110 | ||
2142 | if (dwords > (DMA_POOL_SIZE / 4)) { | ||
2143 | DEBUG2_3_11(printk("%s(%ld): Unabled to retrieve %d DWORDs " | ||
2144 | "(max %d).\n", __func__, ha->host_no, dwords, | ||
2145 | DMA_POOL_SIZE / 4)); | ||
2146 | return BIT_0; | ||
2147 | } | ||
2148 | sbuf = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &sbuf_dma); | ||
2149 | if (sbuf == NULL) { | ||
2150 | DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n", | ||
2151 | __func__, ha->host_no)); | ||
2152 | return BIT_0; | ||
2153 | } | ||
2154 | memset(sbuf, 0, DMA_POOL_SIZE); | ||
2155 | |||
2156 | mcp->mb[0] = MBC_GET_LINK_PRIV_STATS; | 2111 | mcp->mb[0] = MBC_GET_LINK_PRIV_STATS; |
2157 | mcp->mb[2] = MSW(sbuf_dma); | 2112 | mcp->mb[2] = MSW(stats_dma); |
2158 | mcp->mb[3] = LSW(sbuf_dma); | 2113 | mcp->mb[3] = LSW(stats_dma); |
2159 | mcp->mb[6] = MSW(MSD(sbuf_dma)); | 2114 | mcp->mb[6] = MSW(MSD(stats_dma)); |
2160 | mcp->mb[7] = LSW(MSD(sbuf_dma)); | 2115 | mcp->mb[7] = LSW(MSD(stats_dma)); |
2161 | mcp->mb[8] = dwords; | 2116 | mcp->mb[8] = sizeof(struct link_statistics) / 4; |
2117 | mcp->mb[9] = ha->vp_idx; | ||
2162 | mcp->mb[10] = 0; | 2118 | mcp->mb[10] = 0; |
2163 | mcp->out_mb = MBX_10|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; | 2119 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; |
2164 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | 2120 | mcp->in_mb = MBX_2|MBX_1|MBX_0; |
2165 | mcp->tov = 30; | 2121 | mcp->tov = 30; |
2166 | mcp->flags = IOCTL_CMD; | 2122 | mcp->flags = IOCTL_CMD; |
@@ -2170,23 +2126,20 @@ qla24xx_get_isp_stats(scsi_qla_host_t *ha, uint32_t *dwbuf, uint32_t dwords, | |||
2170 | if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { | 2126 | if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { |
2171 | DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n", | 2127 | DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n", |
2172 | __func__, ha->host_no, mcp->mb[0])); | 2128 | __func__, ha->host_no, mcp->mb[0])); |
2173 | status[0] = mcp->mb[0]; | 2129 | rval = QLA_FUNCTION_FAILED; |
2174 | rval = BIT_1; | ||
2175 | } else { | 2130 | } else { |
2176 | /* Copy over data -- firmware data is LE. */ | 2131 | /* Copy over data -- firmware data is LE. */ |
2177 | siter = sbuf; | 2132 | dwords = sizeof(struct link_statistics) / 4; |
2133 | siter = diter = &stats->link_fail_cnt; | ||
2178 | while (dwords--) | 2134 | while (dwords--) |
2179 | *dwbuf++ = le32_to_cpu(*siter++); | 2135 | *diter++ = le32_to_cpu(*siter++); |
2180 | } | 2136 | } |
2181 | } else { | 2137 | } else { |
2182 | /* Failed. */ | 2138 | /* Failed. */ |
2183 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, | 2139 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, |
2184 | ha->host_no, rval)); | 2140 | ha->host_no, rval)); |
2185 | rval = BIT_1; | ||
2186 | } | 2141 | } |
2187 | 2142 | ||
2188 | dma_pool_free(ha->s_dma_pool, sbuf, sbuf_dma); | ||
2189 | |||
2190 | return rval; | 2143 | return rval; |
2191 | } | 2144 | } |
2192 | 2145 | ||