aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/talitos.c
diff options
context:
space:
mode:
authorKim Phillips <kim.phillips@freescale.com>2011-10-21 09:20:28 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2011-10-21 09:20:28 -0400
commit3e721aeb3df3816e283ab18e327cd4652972e213 (patch)
treeea6fbc0353eea5b5daf5850f60ab49e394ac5670 /drivers/crypto/talitos.c
parente6ea64ece7f4c14294b2fce5403b1e71eab87f1e (diff)
crypto: talitos - handle descriptor not found in error path
The CDPR (Current Descriptor Pointer Register) can be unreliable when trying to locate an offending descriptor. Handle that case by (a) not OOPSing, and (b) reverting to the machine internal copy of the descriptor header in order to report the correct execution unit error. Note: printing all execution units' ISRs is not effective because it results in an internal time out (ITO) error and the EU resetting its ISR value (at least when specifying an invalid key length on an SEC 2.2/MPC8313E). Reported-by: Sven Schnelle <svens@stackframe.org> Signed-off-by: Kim Phillips <kim.phillips@freescale.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/talitos.c')
-rw-r--r--drivers/crypto/talitos.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 8a0bb417aa11..dbe76b5df9cf 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -416,7 +416,7 @@ static void talitos_done(unsigned long data)
416/* 416/*
417 * locate current (offending) descriptor 417 * locate current (offending) descriptor
418 */ 418 */
419static struct talitos_desc *current_desc(struct device *dev, int ch) 419static u32 current_desc_hdr(struct device *dev, int ch)
420{ 420{
421 struct talitos_private *priv = dev_get_drvdata(dev); 421 struct talitos_private *priv = dev_get_drvdata(dev);
422 int tail = priv->chan[ch].tail; 422 int tail = priv->chan[ch].tail;
@@ -428,23 +428,25 @@ static struct talitos_desc *current_desc(struct device *dev, int ch)
428 tail = (tail + 1) & (priv->fifo_len - 1); 428 tail = (tail + 1) & (priv->fifo_len - 1);
429 if (tail == priv->chan[ch].tail) { 429 if (tail == priv->chan[ch].tail) {
430 dev_err(dev, "couldn't locate current descriptor\n"); 430 dev_err(dev, "couldn't locate current descriptor\n");
431 return NULL; 431 return 0;
432 } 432 }
433 } 433 }
434 434
435 return priv->chan[ch].fifo[tail].desc; 435 return priv->chan[ch].fifo[tail].desc->hdr;
436} 436}
437 437
438/* 438/*
439 * user diagnostics; report root cause of error based on execution unit status 439 * user diagnostics; report root cause of error based on execution unit status
440 */ 440 */
441static void report_eu_error(struct device *dev, int ch, 441static void report_eu_error(struct device *dev, int ch, u32 desc_hdr)
442 struct talitos_desc *desc)
443{ 442{
444 struct talitos_private *priv = dev_get_drvdata(dev); 443 struct talitos_private *priv = dev_get_drvdata(dev);
445 int i; 444 int i;
446 445
447 switch (desc->hdr & DESC_HDR_SEL0_MASK) { 446 if (!desc_hdr)
447 desc_hdr = in_be32(priv->reg + TALITOS_DESCBUF(ch));
448
449 switch (desc_hdr & DESC_HDR_SEL0_MASK) {
448 case DESC_HDR_SEL0_AFEU: 450 case DESC_HDR_SEL0_AFEU:
449 dev_err(dev, "AFEUISR 0x%08x_%08x\n", 451 dev_err(dev, "AFEUISR 0x%08x_%08x\n",
450 in_be32(priv->reg + TALITOS_AFEUISR), 452 in_be32(priv->reg + TALITOS_AFEUISR),
@@ -488,7 +490,7 @@ static void report_eu_error(struct device *dev, int ch,
488 break; 490 break;
489 } 491 }
490 492
491 switch (desc->hdr & DESC_HDR_SEL1_MASK) { 493 switch (desc_hdr & DESC_HDR_SEL1_MASK) {
492 case DESC_HDR_SEL1_MDEUA: 494 case DESC_HDR_SEL1_MDEUA:
493 case DESC_HDR_SEL1_MDEUB: 495 case DESC_HDR_SEL1_MDEUB:
494 dev_err(dev, "MDEUISR 0x%08x_%08x\n", 496 dev_err(dev, "MDEUISR 0x%08x_%08x\n",
@@ -550,7 +552,7 @@ static void talitos_error(unsigned long data, u32 isr, u32 isr_lo)
550 if (v_lo & TALITOS_CCPSR_LO_IEU) 552 if (v_lo & TALITOS_CCPSR_LO_IEU)
551 dev_err(dev, "invalid execution unit error\n"); 553 dev_err(dev, "invalid execution unit error\n");
552 if (v_lo & TALITOS_CCPSR_LO_EU) 554 if (v_lo & TALITOS_CCPSR_LO_EU)
553 report_eu_error(dev, ch, current_desc(dev, ch)); 555 report_eu_error(dev, ch, current_desc_hdr(dev, ch));
554 if (v_lo & TALITOS_CCPSR_LO_GB) 556 if (v_lo & TALITOS_CCPSR_LO_GB)
555 dev_err(dev, "gather boundary error\n"); 557 dev_err(dev, "gather boundary error\n");
556 if (v_lo & TALITOS_CCPSR_LO_GRL) 558 if (v_lo & TALITOS_CCPSR_LO_GRL)