mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-19 23:06:11 +07:00
[SCSI] mvsas: Add support for Non specific NCQ error interrupt
Signed-off-by: Xiangliang Yu <yuxiangl@marvell.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
45b583b10a
commit
534ff10104
@ -811,5 +811,6 @@ const struct mvs_dispatch mvs_64xx_dispatch = {
|
|||||||
#ifndef DISABLE_HOTPLUG_DMA_FIX
|
#ifndef DISABLE_HOTPLUG_DMA_FIX
|
||||||
mvs_64xx_fix_dma,
|
mvs_64xx_fix_dma,
|
||||||
#endif
|
#endif
|
||||||
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -249,7 +249,7 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi)
|
|||||||
|
|
||||||
/* enable completion queue interrupt */
|
/* enable completion queue interrupt */
|
||||||
tmp = (CINT_PORT_MASK | CINT_DONE | CINT_MEM | CINT_SRS | CINT_CI_STOP |
|
tmp = (CINT_PORT_MASK | CINT_DONE | CINT_MEM | CINT_SRS | CINT_CI_STOP |
|
||||||
CINT_DMA_PCIE);
|
CINT_DMA_PCIE | CINT_NON_SPEC_NCQ_ERROR);
|
||||||
tmp |= CINT_PHY_MASK;
|
tmp |= CINT_PHY_MASK;
|
||||||
mw32(MVS_INT_MASK, tmp);
|
mw32(MVS_INT_MASK, tmp);
|
||||||
|
|
||||||
@ -367,6 +367,35 @@ static void mvs_94xx_issue_stop(struct mvs_info *mvi, enum mvs_port_type type,
|
|||||||
mw32(MVS_PCS, tmp);
|
mw32(MVS_PCS, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mvs_94xx_non_spec_ncq_error(struct mvs_info *mvi)
|
||||||
|
{
|
||||||
|
void __iomem *regs = mvi->regs;
|
||||||
|
u32 err_0, err_1;
|
||||||
|
u8 i;
|
||||||
|
struct mvs_device *device;
|
||||||
|
|
||||||
|
err_0 = mr32(MVS_NON_NCQ_ERR_0);
|
||||||
|
err_1 = mr32(MVS_NON_NCQ_ERR_1);
|
||||||
|
|
||||||
|
mv_dprintk("non specific ncq error err_0:%x,err_1:%x.\n",
|
||||||
|
err_0, err_1);
|
||||||
|
for (i = 0; i < 32; i++) {
|
||||||
|
if (err_0 & bit(i)) {
|
||||||
|
device = mvs_find_dev_by_reg_set(mvi, i);
|
||||||
|
if (device)
|
||||||
|
mvs_release_task(mvi, device->sas_device);
|
||||||
|
}
|
||||||
|
if (err_1 & bit(i)) {
|
||||||
|
device = mvs_find_dev_by_reg_set(mvi, i+32);
|
||||||
|
if (device)
|
||||||
|
mvs_release_task(mvi, device->sas_device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mw32(MVS_NON_NCQ_ERR_0, err_0);
|
||||||
|
mw32(MVS_NON_NCQ_ERR_1, err_1);
|
||||||
|
}
|
||||||
|
|
||||||
static void mvs_94xx_free_reg_set(struct mvs_info *mvi, u8 *tfs)
|
static void mvs_94xx_free_reg_set(struct mvs_info *mvi, u8 *tfs)
|
||||||
{
|
{
|
||||||
void __iomem *regs = mvi->regs;
|
void __iomem *regs = mvi->regs;
|
||||||
@ -679,5 +708,6 @@ const struct mvs_dispatch mvs_94xx_dispatch = {
|
|||||||
#ifndef DISABLE_HOTPLUG_DMA_FIX
|
#ifndef DISABLE_HOTPLUG_DMA_FIX
|
||||||
mvs_94xx_fix_dma,
|
mvs_94xx_fix_dma,
|
||||||
#endif
|
#endif
|
||||||
|
mvs_94xx_non_spec_ncq_error,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -223,6 +223,9 @@ static inline void mvs_int_full(struct mvs_info *mvi)
|
|||||||
mvs_int_port(mvi, i, tmp);
|
mvs_int_port(mvi, i, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stat & CINT_NON_SPEC_NCQ_ERROR)
|
||||||
|
MVS_CHIP_DISP->non_spec_ncq_error(mvi);
|
||||||
|
|
||||||
if (stat & CINT_SRS)
|
if (stat & CINT_SRS)
|
||||||
mvs_int_sata(mvi);
|
mvs_int_sata(mvi);
|
||||||
|
|
||||||
|
@ -144,6 +144,7 @@ enum hw_register_bits {
|
|||||||
CINT_DMA_PCIE = (1U << 27), /* DMA to PCIE timeout */
|
CINT_DMA_PCIE = (1U << 27), /* DMA to PCIE timeout */
|
||||||
CINT_MEM = (1U << 26), /* int mem parity err */
|
CINT_MEM = (1U << 26), /* int mem parity err */
|
||||||
CINT_I2C_SLAVE = (1U << 25), /* slave I2C event */
|
CINT_I2C_SLAVE = (1U << 25), /* slave I2C event */
|
||||||
|
CINT_NON_SPEC_NCQ_ERROR = (1U << 25), /* Non specific NCQ error */
|
||||||
CINT_SRS = (1U << 3), /* SRS event */
|
CINT_SRS = (1U << 3), /* SRS event */
|
||||||
CINT_CI_STOP = (1U << 1), /* cmd issue stopped */
|
CINT_CI_STOP = (1U << 1), /* cmd issue stopped */
|
||||||
CINT_DONE = (1U << 0), /* cmd completion */
|
CINT_DONE = (1U << 0), /* cmd completion */
|
||||||
|
@ -253,6 +253,20 @@ int mvs_find_dev_phyno(struct domain_device *dev, int *phyno)
|
|||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mvs_device *mvs_find_dev_by_reg_set(struct mvs_info *mvi,
|
||||||
|
u8 reg_set)
|
||||||
|
{
|
||||||
|
u32 dev_no;
|
||||||
|
for (dev_no = 0; dev_no < MVS_MAX_DEVICES; dev_no++) {
|
||||||
|
if (mvi->devices[dev_no].taskfileset == MVS_ID_NOT_MAPPED)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (mvi->devices[dev_no].taskfileset == reg_set)
|
||||||
|
return &mvi->devices[dev_no];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void mvs_free_reg_set(struct mvs_info *mvi,
|
static inline void mvs_free_reg_set(struct mvs_info *mvi,
|
||||||
struct mvs_device *dev)
|
struct mvs_device *dev)
|
||||||
{
|
{
|
||||||
|
@ -170,6 +170,7 @@ struct mvs_dispatch {
|
|||||||
#ifndef DISABLE_HOTPLUG_DMA_FIX
|
#ifndef DISABLE_HOTPLUG_DMA_FIX
|
||||||
void (*dma_fix)(dma_addr_t buf_dma, int buf_len, int from, void *prd);
|
void (*dma_fix)(dma_addr_t buf_dma, int buf_len, int from, void *prd);
|
||||||
#endif
|
#endif
|
||||||
|
void (*non_spec_ncq_error)(struct mvs_info *mvi);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -416,5 +417,6 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events);
|
|||||||
void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st);
|
void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st);
|
||||||
int mvs_int_rx(struct mvs_info *mvi, bool self_clear);
|
int mvs_int_rx(struct mvs_info *mvi, bool self_clear);
|
||||||
void mvs_hexdump(u32 size, u8 *data, u32 baseaddr);
|
void mvs_hexdump(u32 size, u8 *data, u32 baseaddr);
|
||||||
|
struct mvs_device *mvs_find_dev_by_reg_set(struct mvs_info *mvi, u8 reg_set);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user