Skip to content

Commit

Permalink
[SCSI] qla2xxx: Retrieve additional HBA port statistics from recent I…
Browse files Browse the repository at this point in the history
…SPs.

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>
  • Loading branch information
Andrew Vasquez authored and James Bottomley committed Jan 23, 2008
1 parent 4733fcb commit 43ef058
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 98 deletions.
44 changes: 30 additions & 14 deletions drivers/scsi/qla2xxx/qla_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -967,35 +967,51 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
{
scsi_qla_host_t *ha = shost_priv(shost);
int rval;
uint16_t mb_stat[1];
link_stat_t stat_buf;
struct link_statistics *stats;
dma_addr_t stats_dma;
struct fc_host_statistics *pfc_host_stat;

rval = QLA_FUNCTION_FAILED;
pfc_host_stat = &ha->fc_host_stat;
memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics));

stats = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &stats_dma);
if (stats == NULL) {
DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n",
__func__, ha->host_no));
goto done;
}
memset(stats, 0, DMA_POOL_SIZE);

rval = QLA_FUNCTION_FAILED;
if (IS_FWI2_CAPABLE(ha)) {
rval = qla24xx_get_isp_stats(ha, (uint32_t *)&stat_buf,
sizeof(stat_buf) / 4, mb_stat);
rval = qla24xx_get_isp_stats(ha, stats, stats_dma);
} else if (atomic_read(&ha->loop_state) == LOOP_READY &&
!test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) &&
!test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) &&
!ha->dpc_active) {
/* Must be in a 'READY' state for statistics retrieval. */
rval = qla2x00_get_link_status(ha, ha->loop_id, &stat_buf,
mb_stat);
rval = qla2x00_get_link_status(ha, ha->loop_id, stats,
stats_dma);
}

if (rval != QLA_SUCCESS)
goto done;
goto done_free;

pfc_host_stat->link_failure_count = stats->link_fail_cnt;
pfc_host_stat->loss_of_sync_count = stats->loss_sync_cnt;
pfc_host_stat->loss_of_signal_count = stats->loss_sig_cnt;
pfc_host_stat->prim_seq_protocol_err_count = stats->prim_seq_err_cnt;
pfc_host_stat->invalid_tx_word_count = stats->inval_xmit_word_cnt;
pfc_host_stat->invalid_crc_count = stats->inval_crc_cnt;
if (IS_FWI2_CAPABLE(ha)) {
pfc_host_stat->tx_frames = stats->tx_frames;
pfc_host_stat->rx_frames = stats->rx_frames;
pfc_host_stat->dumped_frames = stats->dumped_frames;
pfc_host_stat->nos_count = stats->nos_rcvd;
}

pfc_host_stat->link_failure_count = stat_buf.link_fail_cnt;
pfc_host_stat->loss_of_sync_count = stat_buf.loss_sync_cnt;
pfc_host_stat->loss_of_signal_count = stat_buf.loss_sig_cnt;
pfc_host_stat->prim_seq_protocol_err_count = stat_buf.prim_seq_err_cnt;
pfc_host_stat->invalid_tx_word_count = stat_buf.inval_xmit_word_cnt;
pfc_host_stat->invalid_crc_count = stat_buf.inval_crc_cnt;
done_free:
dma_pool_free(ha->s_dma_pool, stats, stats_dma);
done:
return pfc_host_stat;
}
Expand Down
22 changes: 14 additions & 8 deletions drivers/scsi/qla2xxx/qla_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -862,14 +862,20 @@ typedef struct {
#define GLSO_SEND_RPS BIT_0
#define GLSO_USE_DID BIT_3

typedef struct {
uint32_t link_fail_cnt;
uint32_t loss_sync_cnt;
uint32_t loss_sig_cnt;
uint32_t prim_seq_err_cnt;
uint32_t inval_xmit_word_cnt;
uint32_t inval_crc_cnt;
} link_stat_t;
struct link_statistics {
uint32_t link_fail_cnt;
uint32_t loss_sync_cnt;
uint32_t loss_sig_cnt;
uint32_t prim_seq_err_cnt;
uint32_t inval_xmit_word_cnt;
uint32_t inval_crc_cnt;
uint32_t unused1[0x1b];
uint32_t tx_frames;
uint32_t rx_frames;
uint32_t dumped_frames;
uint32_t unused2[2];
uint32_t nos_rcvd;
};

/*
* NVRAM Command values.
Expand Down
7 changes: 4 additions & 3 deletions drivers/scsi/qla2xxx/qla_gbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,12 @@ extern int
qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map);

extern int
qla2x00_get_link_status(scsi_qla_host_t *, uint16_t, link_stat_t *,
uint16_t *);
qla2x00_get_link_status(scsi_qla_host_t *, uint16_t, struct link_statistics *,
dma_addr_t);

extern int
qla24xx_get_isp_stats(scsi_qla_host_t *, uint32_t *, uint32_t, uint16_t *);
qla24xx_get_isp_stats(scsi_qla_host_t *, struct link_statistics *,
dma_addr_t);

extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *);
extern int qla24xx_abort_target(fc_port_t *);
Expand Down
99 changes: 26 additions & 73 deletions drivers/scsi/qla2xxx/qla_mbx.c
Original file line number Diff line number Diff line change
Expand Up @@ -2042,29 +2042,20 @@ qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map)
*/
int
qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id,
link_stat_t *ret_buf, uint16_t *status)
struct link_statistics *stats, dma_addr_t stats_dma)
{
int rval;
mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc;
link_stat_t *stat_buf;
dma_addr_t stat_buf_dma;
uint32_t *siter, *diter, dwords;

DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));

stat_buf = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &stat_buf_dma);
if (stat_buf == NULL) {
DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n",
__func__, ha->host_no));
return BIT_0;
}
memset(stat_buf, 0, sizeof(link_stat_t));

mcp->mb[0] = MBC_GET_LINK_STATUS;
mcp->mb[2] = MSW(stat_buf_dma);
mcp->mb[3] = LSW(stat_buf_dma);
mcp->mb[6] = MSW(MSD(stat_buf_dma));
mcp->mb[7] = LSW(MSD(stat_buf_dma));
mcp->mb[2] = MSW(stats_dma);
mcp->mb[3] = LSW(stats_dma);
mcp->mb[6] = MSW(MSD(stats_dma));
mcp->mb[7] = LSW(MSD(stats_dma));
mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
mcp->in_mb = MBX_0;
if (IS_FWI2_CAPABLE(ha)) {
Expand All @@ -2089,78 +2080,43 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id,
if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n",
__func__, ha->host_no, mcp->mb[0]));
status[0] = mcp->mb[0];
rval = BIT_1;
rval = QLA_FUNCTION_FAILED;
} else {
/* copy over data -- firmware data is LE. */
ret_buf->link_fail_cnt =
le32_to_cpu(stat_buf->link_fail_cnt);
ret_buf->loss_sync_cnt =
le32_to_cpu(stat_buf->loss_sync_cnt);
ret_buf->loss_sig_cnt =
le32_to_cpu(stat_buf->loss_sig_cnt);
ret_buf->prim_seq_err_cnt =
le32_to_cpu(stat_buf->prim_seq_err_cnt);
ret_buf->inval_xmit_word_cnt =
le32_to_cpu(stat_buf->inval_xmit_word_cnt);
ret_buf->inval_crc_cnt =
le32_to_cpu(stat_buf->inval_crc_cnt);

DEBUG11(printk("%s(%ld): stat dump: fail_cnt=%d "
"loss_sync=%d loss_sig=%d seq_err=%d "
"inval_xmt_word=%d inval_crc=%d.\n", __func__,
ha->host_no, stat_buf->link_fail_cnt,
stat_buf->loss_sync_cnt, stat_buf->loss_sig_cnt,
stat_buf->prim_seq_err_cnt,
stat_buf->inval_xmit_word_cnt,
stat_buf->inval_crc_cnt));
/* Copy over data -- firmware data is LE. */
dwords = offsetof(struct link_statistics, unused1) / 4;
siter = diter = &stats->link_fail_cnt;
while (dwords--)
*diter++ = le32_to_cpu(*siter++);
}
} else {
/* Failed. */
DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
ha->host_no, rval));
rval = BIT_1;
}

dma_pool_free(ha->s_dma_pool, stat_buf, stat_buf_dma);

return rval;
}

int
qla24xx_get_isp_stats(scsi_qla_host_t *ha, uint32_t *dwbuf, uint32_t dwords,
uint16_t *status)
qla24xx_get_isp_stats(scsi_qla_host_t *ha, struct link_statistics *stats,
dma_addr_t stats_dma)
{
int rval;
mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc;
uint32_t *sbuf, *siter;
dma_addr_t sbuf_dma;
uint32_t *siter, *diter, dwords;

DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));

if (dwords > (DMA_POOL_SIZE / 4)) {
DEBUG2_3_11(printk("%s(%ld): Unabled to retrieve %d DWORDs "
"(max %d).\n", __func__, ha->host_no, dwords,
DMA_POOL_SIZE / 4));
return BIT_0;
}
sbuf = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &sbuf_dma);
if (sbuf == NULL) {
DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n",
__func__, ha->host_no));
return BIT_0;
}
memset(sbuf, 0, DMA_POOL_SIZE);

mcp->mb[0] = MBC_GET_LINK_PRIV_STATS;
mcp->mb[2] = MSW(sbuf_dma);
mcp->mb[3] = LSW(sbuf_dma);
mcp->mb[6] = MSW(MSD(sbuf_dma));
mcp->mb[7] = LSW(MSD(sbuf_dma));
mcp->mb[8] = dwords;
mcp->mb[2] = MSW(stats_dma);
mcp->mb[3] = LSW(stats_dma);
mcp->mb[6] = MSW(MSD(stats_dma));
mcp->mb[7] = LSW(MSD(stats_dma));
mcp->mb[8] = sizeof(struct link_statistics) / 4;
mcp->mb[9] = ha->vp_idx;
mcp->mb[10] = 0;
mcp->out_mb = MBX_10|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
mcp->in_mb = MBX_2|MBX_1|MBX_0;
mcp->tov = 30;
mcp->flags = IOCTL_CMD;
Expand All @@ -2170,23 +2126,20 @@ qla24xx_get_isp_stats(scsi_qla_host_t *ha, uint32_t *dwbuf, uint32_t dwords,
if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n",
__func__, ha->host_no, mcp->mb[0]));
status[0] = mcp->mb[0];
rval = BIT_1;
rval = QLA_FUNCTION_FAILED;
} else {
/* Copy over data -- firmware data is LE. */
siter = sbuf;
dwords = sizeof(struct link_statistics) / 4;
siter = diter = &stats->link_fail_cnt;
while (dwords--)
*dwbuf++ = le32_to_cpu(*siter++);
*diter++ = le32_to_cpu(*siter++);
}
} else {
/* Failed. */
DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
ha->host_no, rval));
rval = BIT_1;
}

dma_pool_free(ha->s_dma_pool, sbuf, sbuf_dma);

return rval;
}

Expand Down

0 comments on commit 43ef058

Please sign in to comment.