aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXiangliang Yu <yuxiangl@marvell.com>2011-05-24 10:26:50 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-07-26 02:25:02 -0400
commit534ff10104427ccad071ef87ae7017d47d08e50b (patch)
tree3e0e7a74ef1c109a7a343817295ed6e925fd22c7
parent45b583b10a8b438b970e95a7d1d4db22c9e35004 (diff)
[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>
-rw-r--r--drivers/scsi/mvsas/mv_64xx.c1
-rw-r--r--drivers/scsi/mvsas/mv_94xx.c32
-rw-r--r--drivers/scsi/mvsas/mv_chips.h3
-rw-r--r--drivers/scsi/mvsas/mv_defs.h1
-rw-r--r--drivers/scsi/mvsas/mv_sas.c14
-rw-r--r--drivers/scsi/mvsas/mv_sas.h2
6 files changed, 52 insertions, 1 deletions
diff --git a/drivers/scsi/mvsas/mv_64xx.c b/drivers/scsi/mvsas/mv_64xx.c
index 13c960481391..0e13e6441da7 100644
--- a/drivers/scsi/mvsas/mv_64xx.c
+++ b/drivers/scsi/mvsas/mv_64xx.c
@@ -811,5 +811,6 @@ const struct mvs_dispatch mvs_64xx_dispatch = {
811#ifndef DISABLE_HOTPLUG_DMA_FIX 811#ifndef DISABLE_HOTPLUG_DMA_FIX
812 mvs_64xx_fix_dma, 812 mvs_64xx_fix_dma,
813#endif 813#endif
814 NULL,
814}; 815};
815 816
diff --git a/drivers/scsi/mvsas/mv_94xx.c b/drivers/scsi/mvsas/mv_94xx.c
index 78162c3c36e6..9d60c7c19b32 100644
--- a/drivers/scsi/mvsas/mv_94xx.c
+++ b/drivers/scsi/mvsas/mv_94xx.c
@@ -249,7 +249,7 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi)
249 249
250 /* enable completion queue interrupt */ 250 /* enable completion queue interrupt */
251 tmp = (CINT_PORT_MASK | CINT_DONE | CINT_MEM | CINT_SRS | CINT_CI_STOP | 251 tmp = (CINT_PORT_MASK | CINT_DONE | CINT_MEM | CINT_SRS | CINT_CI_STOP |
252 CINT_DMA_PCIE); 252 CINT_DMA_PCIE | CINT_NON_SPEC_NCQ_ERROR);
253 tmp |= CINT_PHY_MASK; 253 tmp |= CINT_PHY_MASK;
254 mw32(MVS_INT_MASK, tmp); 254 mw32(MVS_INT_MASK, tmp);
255 255
@@ -367,6 +367,35 @@ static void mvs_94xx_issue_stop(struct mvs_info *mvi, enum mvs_port_type type,
367 mw32(MVS_PCS, tmp); 367 mw32(MVS_PCS, tmp);
368} 368}
369 369
370static void mvs_94xx_non_spec_ncq_error(struct mvs_info *mvi)
371{
372 void __iomem *regs = mvi->regs;
373 u32 err_0, err_1;
374 u8 i;
375 struct mvs_device *device;
376
377 err_0 = mr32(MVS_NON_NCQ_ERR_0);
378 err_1 = mr32(MVS_NON_NCQ_ERR_1);
379
380 mv_dprintk("non specific ncq error err_0:%x,err_1:%x.\n",
381 err_0, err_1);
382 for (i = 0; i < 32; i++) {
383 if (err_0 & bit(i)) {
384 device = mvs_find_dev_by_reg_set(mvi, i);
385 if (device)
386 mvs_release_task(mvi, device->sas_device);
387 }
388 if (err_1 & bit(i)) {
389 device = mvs_find_dev_by_reg_set(mvi, i+32);
390 if (device)
391 mvs_release_task(mvi, device->sas_device);
392 }
393 }
394
395 mw32(MVS_NON_NCQ_ERR_0, err_0);
396 mw32(MVS_NON_NCQ_ERR_1, err_1);
397}
398
370static void mvs_94xx_free_reg_set(struct mvs_info *mvi, u8 *tfs) 399static void mvs_94xx_free_reg_set(struct mvs_info *mvi, u8 *tfs)
371{ 400{
372 void __iomem *regs = mvi->regs; 401 void __iomem *regs = mvi->regs;
@@ -679,5 +708,6 @@ const struct mvs_dispatch mvs_94xx_dispatch = {
679#ifndef DISABLE_HOTPLUG_DMA_FIX 708#ifndef DISABLE_HOTPLUG_DMA_FIX
680 mvs_94xx_fix_dma, 709 mvs_94xx_fix_dma,
681#endif 710#endif
711 mvs_94xx_non_spec_ncq_error,
682}; 712};
683 713
diff --git a/drivers/scsi/mvsas/mv_chips.h b/drivers/scsi/mvsas/mv_chips.h
index 1753a6fc42d0..4519f809a8df 100644
--- a/drivers/scsi/mvsas/mv_chips.h
+++ b/drivers/scsi/mvsas/mv_chips.h
@@ -223,6 +223,9 @@ static inline void mvs_int_full(struct mvs_info *mvi)
223 mvs_int_port(mvi, i, tmp); 223 mvs_int_port(mvi, i, tmp);
224 } 224 }
225 225
226 if (stat & CINT_NON_SPEC_NCQ_ERROR)
227 MVS_CHIP_DISP->non_spec_ncq_error(mvi);
228
226 if (stat & CINT_SRS) 229 if (stat & CINT_SRS)
227 mvs_int_sata(mvi); 230 mvs_int_sata(mvi);
228 231
diff --git a/drivers/scsi/mvsas/mv_defs.h b/drivers/scsi/mvsas/mv_defs.h
index bc00c940743c..9202bc68801d 100644
--- a/drivers/scsi/mvsas/mv_defs.h
+++ b/drivers/scsi/mvsas/mv_defs.h
@@ -144,6 +144,7 @@ enum hw_register_bits {
144 CINT_DMA_PCIE = (1U << 27), /* DMA to PCIE timeout */ 144 CINT_DMA_PCIE = (1U << 27), /* DMA to PCIE timeout */
145 CINT_MEM = (1U << 26), /* int mem parity err */ 145 CINT_MEM = (1U << 26), /* int mem parity err */
146 CINT_I2C_SLAVE = (1U << 25), /* slave I2C event */ 146 CINT_I2C_SLAVE = (1U << 25), /* slave I2C event */
147 CINT_NON_SPEC_NCQ_ERROR = (1U << 25), /* Non specific NCQ error */
147 CINT_SRS = (1U << 3), /* SRS event */ 148 CINT_SRS = (1U << 3), /* SRS event */
148 CINT_CI_STOP = (1U << 1), /* cmd issue stopped */ 149 CINT_CI_STOP = (1U << 1), /* cmd issue stopped */
149 CINT_DONE = (1U << 0), /* cmd completion */ 150 CINT_DONE = (1U << 0), /* cmd completion */
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c
index 0ef27425c447..aaa475a3eda6 100644
--- a/drivers/scsi/mvsas/mv_sas.c
+++ b/drivers/scsi/mvsas/mv_sas.c
@@ -253,6 +253,20 @@ int mvs_find_dev_phyno(struct domain_device *dev, int *phyno)
253 return num; 253 return num;
254} 254}
255 255
256struct mvs_device *mvs_find_dev_by_reg_set(struct mvs_info *mvi,
257 u8 reg_set)
258{
259 u32 dev_no;
260 for (dev_no = 0; dev_no < MVS_MAX_DEVICES; dev_no++) {
261 if (mvi->devices[dev_no].taskfileset == MVS_ID_NOT_MAPPED)
262 continue;
263
264 if (mvi->devices[dev_no].taskfileset == reg_set)
265 return &mvi->devices[dev_no];
266 }
267 return NULL;
268}
269
256static inline void mvs_free_reg_set(struct mvs_info *mvi, 270static inline void mvs_free_reg_set(struct mvs_info *mvi,
257 struct mvs_device *dev) 271 struct mvs_device *dev)
258{ 272{
diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h
index 1367d8b9350d..f96100d7aee1 100644
--- a/drivers/scsi/mvsas/mv_sas.h
+++ b/drivers/scsi/mvsas/mv_sas.h
@@ -170,6 +170,7 @@ struct mvs_dispatch {
170#ifndef DISABLE_HOTPLUG_DMA_FIX 170#ifndef DISABLE_HOTPLUG_DMA_FIX
171 void (*dma_fix)(dma_addr_t buf_dma, int buf_len, int from, void *prd); 171 void (*dma_fix)(dma_addr_t buf_dma, int buf_len, int from, void *prd);
172#endif 172#endif
173 void (*non_spec_ncq_error)(struct mvs_info *mvi);
173 174
174}; 175};
175 176
@@ -416,5 +417,6 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events);
416void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st); 417void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st);
417int mvs_int_rx(struct mvs_info *mvi, bool self_clear); 418int mvs_int_rx(struct mvs_info *mvi, bool self_clear);
418void mvs_hexdump(u32 size, u8 *data, u32 baseaddr); 419void mvs_hexdump(u32 size, u8 *data, u32 baseaddr);
420struct mvs_device *mvs_find_dev_by_reg_set(struct mvs_info *mvi, u8 reg_set);
419#endif 421#endif
420 422