cxgbe(4): Auto-dump the device log on a mailbox timeout or when the
firmware reports an error in pcie_fw. Sponsored by: Chelsio Communications
This commit is contained in:
parent
13607f6db5
commit
286fd42ba6
@ -1164,6 +1164,7 @@ void free_atid(struct adapter *, int);
|
||||
void release_tid(struct adapter *, int, struct sge_wrq *);
|
||||
int cxgbe_media_change(struct ifnet *);
|
||||
void cxgbe_media_status(struct ifnet *, struct ifmediareq *);
|
||||
void t4_os_dump_devlog(struct adapter *);
|
||||
|
||||
#ifdef DEV_NETMAP
|
||||
/* t4_netmap.c */
|
||||
|
@ -212,9 +212,11 @@ static void t4_report_fw_error(struct adapter *adap)
|
||||
|
||||
pcie_fw = t4_read_reg(adap, A_PCIE_FW);
|
||||
if (pcie_fw & F_PCIE_FW_ERR) {
|
||||
adap->flags &= ~FW_OK;
|
||||
CH_ERR(adap, "firmware reports adapter error: %s (0x%08x)\n",
|
||||
reason[G_PCIE_FW_EVAL(pcie_fw)], pcie_fw);
|
||||
adap->flags &= ~FW_OK;
|
||||
if (pcie_fw != 0xffffffff)
|
||||
t4_os_dump_devlog(adap);
|
||||
}
|
||||
}
|
||||
|
||||
@ -488,13 +490,19 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
|
||||
* the error and also check to see if the firmware reported any
|
||||
* errors ...
|
||||
*/
|
||||
ret = (pcie_fw & F_PCIE_FW_ERR) ? -ENXIO : -ETIMEDOUT;
|
||||
CH_ERR(adap, "command %#x in mbox %d timed out (0x%08x).\n",
|
||||
*(const u8 *)cmd, mbox, pcie_fw);
|
||||
CH_DUMP_MBOX(adap, mbox, 0, "cmdsent", cmd_rpl, true);
|
||||
CH_DUMP_MBOX(adap, mbox, data_reg, "current", NULL, true);
|
||||
|
||||
t4_report_fw_error(adap);
|
||||
if (pcie_fw & F_PCIE_FW_ERR) {
|
||||
ret = -ENXIO;
|
||||
t4_report_fw_error(adap);
|
||||
} else {
|
||||
ret = -ETIMEDOUT;
|
||||
t4_os_dump_devlog(adap);
|
||||
}
|
||||
|
||||
t4_fatal_err(adap, true);
|
||||
return ret;
|
||||
}
|
||||
|
@ -7625,19 +7625,18 @@ static const char * const devlog_facility_strings[] = {
|
||||
};
|
||||
|
||||
static int
|
||||
sysctl_devlog(SYSCTL_HANDLER_ARGS)
|
||||
sbuf_devlog(struct adapter *sc, struct sbuf *sb, int flags)
|
||||
{
|
||||
struct adapter *sc = arg1;
|
||||
int i, j, rc, nentries, first = 0;
|
||||
struct devlog_params *dparams = &sc->params.devlog;
|
||||
struct fw_devlog_e *buf, *e;
|
||||
int i, j, rc, nentries, first = 0;
|
||||
struct sbuf *sb;
|
||||
uint64_t ftstamp = UINT64_MAX;
|
||||
|
||||
if (dparams->addr == 0)
|
||||
return (ENXIO);
|
||||
|
||||
buf = malloc(dparams->size, M_CXGBE, M_NOWAIT);
|
||||
MPASS(flags == M_WAITOK || flags == M_NOWAIT);
|
||||
buf = malloc(dparams->size, M_CXGBE, M_ZERO | flags);
|
||||
if (buf == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
@ -7666,15 +7665,6 @@ sysctl_devlog(SYSCTL_HANDLER_ARGS)
|
||||
if (buf[first].timestamp == 0)
|
||||
goto done; /* nothing in the log */
|
||||
|
||||
rc = sysctl_wire_old_buffer(req, 0);
|
||||
if (rc != 0)
|
||||
goto done;
|
||||
|
||||
sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req);
|
||||
if (sb == NULL) {
|
||||
rc = ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
sbuf_printf(sb, "%10s %15s %8s %8s %s\n",
|
||||
"Seq#", "Tstamp", "Level", "Facility", "Message");
|
||||
|
||||
@ -7697,14 +7687,51 @@ sysctl_devlog(SYSCTL_HANDLER_ARGS)
|
||||
if (++i == nentries)
|
||||
i = 0;
|
||||
} while (i != first);
|
||||
|
||||
rc = sbuf_finish(sb);
|
||||
sbuf_delete(sb);
|
||||
done:
|
||||
free(buf, M_CXGBE);
|
||||
return (rc);
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_devlog(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct adapter *sc = arg1;
|
||||
int rc;
|
||||
struct sbuf *sb;
|
||||
|
||||
rc = sysctl_wire_old_buffer(req, 0);
|
||||
if (rc != 0)
|
||||
return (rc);
|
||||
sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req);
|
||||
if (sb == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
rc = sbuf_devlog(sc, sb, M_WAITOK);
|
||||
if (rc == 0)
|
||||
rc = sbuf_finish(sb);
|
||||
sbuf_delete(sb);
|
||||
return (rc);
|
||||
}
|
||||
|
||||
void
|
||||
t4_os_dump_devlog(struct adapter *sc)
|
||||
{
|
||||
int rc;
|
||||
struct sbuf sb;
|
||||
|
||||
if (sbuf_new(&sb, NULL, 4096, SBUF_AUTOEXTEND) != &sb)
|
||||
return;
|
||||
rc = sbuf_devlog(sc, &sb, M_NOWAIT);
|
||||
if (rc == 0) {
|
||||
rc = sbuf_finish(&sb);
|
||||
if (rc == 0) {
|
||||
log(LOG_DEBUG, "%s: device log follows.\n%s",
|
||||
device_get_nameunit(sc->dev), sbuf_data(&sb));
|
||||
}
|
||||
}
|
||||
sbuf_delete(&sb);
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_fcoe_stats(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user