Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 534ff101 authored by Xiangliang Yu's avatar Xiangliang Yu Committed by James Bottomley
Browse files

[SCSI] mvsas: Add support for Non specific NCQ error interrupt

parent 45b583b1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -811,5 +811,6 @@ const struct mvs_dispatch mvs_64xx_dispatch = {
#ifndef DISABLE_HOTPLUG_DMA_FIX
	mvs_64xx_fix_dma,
#endif
	NULL,
};
+31 −1
Original line number Diff line number Diff line
@@ -249,7 +249,7 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi)

	/* enable completion queue interrupt */
	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;
	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);
}

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)
{
	void __iomem *regs = mvi->regs;
@@ -679,5 +708,6 @@ const struct mvs_dispatch mvs_94xx_dispatch = {
#ifndef DISABLE_HOTPLUG_DMA_FIX
	mvs_94xx_fix_dma,
#endif
	mvs_94xx_non_spec_ncq_error,
};
+3 −0
Original line number Diff line number Diff line
@@ -223,6 +223,9 @@ static inline void mvs_int_full(struct mvs_info *mvi)
			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)
		mvs_int_sata(mvi);

+1 −0
Original line number Diff line number Diff line
@@ -144,6 +144,7 @@ enum hw_register_bits {
	CINT_DMA_PCIE		= (1U << 27),	/* DMA to PCIE timeout */
	CINT_MEM		= (1U << 26),	/* int mem parity err */
	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_CI_STOP		= (1U << 1),	/* cmd issue stopped */
	CINT_DONE		= (1U << 0),	/* cmd completion */
+14 −0
Original line number Diff line number Diff line
@@ -253,6 +253,20 @@ int mvs_find_dev_phyno(struct domain_device *dev, int *phyno)
	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,
				struct mvs_device *dev)
{
Loading