ioat: clear the internal channel error register on reset

I/OAT device will refuse to resume from the Halted
state until we clear both CHANERR and CHANERR_INT
registers.

We only cleared CHANERR so far. So after the I/OAT
device encountered an error, SPDK would not be able
to initialize it ever again unless it's rebound to
the ioatdma driver.

Unlike CHANERR, CHANERR_INT is only accessible through
PCI config space.

CHANERR_INT is only available on I/OAT devices with
version < 3.3.

Change-Id: Ib369ca76f58c4868fe61ff9532b2e7947e5091d3
Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/422026
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Dariusz Stojaczyk 2018-08-13 03:30:05 +02:00 committed by Jim Harris
parent db5d6f4f4f
commit 9b172afdb6
2 changed files with 15 additions and 0 deletions

View File

@ -47,6 +47,8 @@ extern "C" {
#include "spdk/assert.h"
#define SPDK_IOAT_PCI_CHANERR_INT_OFFSET 0x180
#define SPDK_IOAT_INTRCTRL_MASTER_INT_EN 0x01
#define SPDK_IOAT_VER_3_0 0x30

View File

@ -259,6 +259,7 @@ static int ioat_reset_hw(struct spdk_ioat_chan *ioat)
int timeout;
uint64_t status;
uint32_t chanerr;
int rc;
status = ioat_get_chansts(ioat);
if (is_ioat_active(status) || is_ioat_idle(status)) {
@ -283,6 +284,18 @@ static int ioat_reset_hw(struct spdk_ioat_chan *ioat)
chanerr = ioat->regs->chanerr;
ioat->regs->chanerr = chanerr;
if (ioat->regs->cbver < SPDK_IOAT_VER_3_3) {
rc = spdk_pci_device_cfg_read32(ioat->device, &chanerr,
SPDK_IOAT_PCI_CHANERR_INT_OFFSET);
if (rc) {
SPDK_ERRLOG("failed to read the internal channel error register\n");
return -1;
}
spdk_pci_device_cfg_write32(ioat->device, chanerr,
SPDK_IOAT_PCI_CHANERR_INT_OFFSET);
}
ioat_reset(ioat);
timeout = 20;