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

Reply via email to