From: "Michael Chan" <[EMAIL PROTECTED]> Date: Tue, 13 Dec 2005 13:37:25 -0800
> Fix nvram arbitration bugs. The nvram arbitration rules were not > strictly followed in a few places and this could lead to reading > corrupted values from the nvram. > > Signed-off-by: Michael Chan <[EMAIL PROTECTED]> Why not solve that last case by making tg3_nvram_{lock,unlock}() nest properly? Like this: diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 47bd4a3..41e7602 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -4140,16 +4140,19 @@ static int tg3_abort_hw(struct tg3 *tp, static int tg3_nvram_lock(struct tg3 *tp) { if (tp->tg3_flags & TG3_FLAG_NVRAM) { - int i; + int i, was_zero = (tp->nvram_lock_cnt == 0); - tw32(NVRAM_SWARB, SWARB_REQ_SET1); - for (i = 0; i < 8000; i++) { - if (tr32(NVRAM_SWARB) & SWARB_GNT1) - break; - udelay(20); + tp->nvram_lock_cnt++; + if (was_zero) { + tw32(NVRAM_SWARB, SWARB_REQ_SET1); + for (i = 0; i < 8000; i++) { + if (tr32(NVRAM_SWARB) & SWARB_GNT1) + break; + udelay(20); + } + if (i == 8000) + return -ENODEV; } - if (i == 8000) - return -ENODEV; } return 0; } @@ -4157,8 +4160,12 @@ static int tg3_nvram_lock(struct tg3 *tp /* tp->lock is held. */ static void tg3_nvram_unlock(struct tg3 *tp) { - if (tp->tg3_flags & TG3_FLAG_NVRAM) - tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1); + if (tp->tg3_flags & TG3_FLAG_NVRAM) { + tp->nvram_lock_cnt--; + + if (tp->nvram_lock_cnt == 0) + tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1); + } } /* tp->lock is held. */ @@ -8533,6 +8540,7 @@ static void __devinit tg3_nvram_init(str GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) { tp->tg3_flags |= TG3_FLAG_NVRAM; + tg3_nvram_lock(tp); tg3_enable_nvram_access(tp); if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752) @@ -8543,6 +8551,7 @@ static void __devinit tg3_nvram_init(str tg3_get_nvram_size(tp); tg3_disable_nvram_access(tp); + tg3_nvram_unlock(tp); } else { tp->tg3_flags &= ~(TG3_FLAG_NVRAM | TG3_FLAG_NVRAM_BUFFERED); @@ -8640,10 +8649,10 @@ static int tg3_nvram_read(struct tg3 *tp if (ret == 0) *val = swab32(tr32(NVRAM_RDDATA)); - tg3_nvram_unlock(tp); - tg3_disable_nvram_access(tp); + tg3_nvram_unlock(tp); + return ret; } diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index fb7e2a5..92a8130 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2261,6 +2261,7 @@ struct tg3 { dma_addr_t stats_mapping; struct work_struct reset_task; + int nvram_lock_cnt; u32 nvram_size; u32 nvram_pagesize; u32 nvram_jedecnum; - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html