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