]> git.neil.brown.name Git - history.git/commitdiff
e100 net driver update 4/4:
authorEli Kupermann <eli.kupermann@intel.com>
Thu, 14 Mar 2002 21:39:16 +0000 (16:39 -0500)
committerJeff Garzik <jgarzik@mandrakesoft.com>
Thu, 14 Mar 2002 21:39:16 +0000 (16:39 -0500)
- switch to yield function as suggested by you, Arjan and Andrew.
- fixed broken logic in the use of time_before/time_after - possible
bug cause in previous design - in most of the places we were going to sleep
and than check if time expires before checking if condition is satisfied.
If, for example, we needed to wait up to 3 jiffies we could do
schedule_timeout(1) and get up after 4 ticks check that time expired and go
away crying about failure without checking that condition is OK.(in fact I
saw it happen on one SMP platform here).

drivers/net/e100/e100.h
drivers/net/e100/e100_eeprom.c
drivers/net/e100/e100_main.c
drivers/net/e100/e100_phy.c
drivers/net/e100/e100_proc.c

index e0b147cbf2c04ebe08c8b0e5beda9eab9ddf548b..4295e9c85712fde681c9080bd4b55474a9cb4223 100644 (file)
@@ -138,10 +138,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #define TX_THRSHLD     8
 
-/* sleep time is at least 50 ms, in jiffies */
-#define SLEEP_TIME ((HZ / 20) + 1)
-#define CUS_TIMEOUT 1000
-
 /* IFS parameters */
 #define MIN_NUMBER_OF_TRANSMITS_100 1000
 #define MIN_NUMBER_OF_TRANSMITS_10  100
@@ -1019,6 +1015,14 @@ extern unsigned char e100_selftest(struct e100_private *bdp, u32 *st_timeout,
 extern unsigned char e100_get_link_state(struct e100_private *bdp);
 extern unsigned char e100_wait_scb(struct e100_private *bdp);
 
+#ifndef yield
+#define yield()                                        \
+        do {                                   \
+                current->policy |= SCHED_YIELD;        \
+                schedule();                    \
+        } while (0)                                     
+#endif
+
 extern void e100_deisolate_driver(struct e100_private *bdp,
                                  u8 recover, u8 full_reset);
 extern unsigned char e100_hw_reset_recover(struct e100_private *bdp,
index 434ba03e32f5a9ff120757299b999cc70fbe4669..5062699b9d24ab05643ba4a134557b4315f1a91f 100644 (file)
@@ -137,7 +137,7 @@ eeprom_set_semaphore(struct e100_private *adapter)
        u16 data = 0;
        unsigned long expiration_time = jiffies + HZ / 100 + 1;
 
-       while (time_before(jiffies, expiration_time)) {
+       do {
                // Get current value of General Control 2
                data = readb(&CSR_GENERAL_CONTROL2_FIELD(adapter));
 
@@ -154,10 +154,12 @@ eeprom_set_semaphore(struct e100_private *adapter)
                        return true;
                }
 
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1+(HZ-1)/100);
-       }
-       return false;
+               if (time_before(jiffies, expiration_time))
+                       yield();
+               else
+                       return false;
+
+       } while (true);
 }
 
 //----------------------------------------------------------------------------------------
@@ -579,17 +581,16 @@ eeprom_wait_cmd_done(struct e100_private *adapter)
 
        eeprom_stand_by(adapter);
 
-       while (time_before(jiffies, expiration_time)) {
+       do {
                rmb();
                x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
                if (x & EEDO)
                        return true;
-
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1+(HZ-1)/100);
-       }
-
-       return false;
+               if (time_before(jiffies, expiration_time))
+                       yield();
+               else
+                       return false;
+       } while (true);
 }
 
 //----------------------------------------------------------------------------------------
index f1ddd5a8c2da549f061585d0577c2a89cb2c1f0c..3dcc137c218f1de7e028ac4a5e502d9edb2d138d 100644 (file)
@@ -165,7 +165,7 @@ static void e100_non_tx_background(unsigned long);
 /* Global Data structures and variables */
 char e100_copyright[] __devinitdata = "Copyright (c) 2002 Intel Corporation";
 
-#define E100_VERSION  "2.0.23-pre2"
+#define E100_VERSION  "2.0.24-pre1"
 
 #define E100_FULL_DRIVER_NAME  "Intel(R) PRO/100 Fast Ethernet Adapter - Loadable driver, ver "
 
@@ -2705,7 +2705,7 @@ e100_exec_non_cu_cmd(struct e100_private *bdp, nxmit_cb_entry_t *command)
        cb_header_t *ntcb_hdr;
        unsigned long lock_flag;
        unsigned long expiration_time;
-       unsigned char rc = false;
+       unsigned char rc = true;
 
        ntcb_hdr = (cb_header_t *) command->non_tx_cmd; /* get hdr of non tcb cmd */
 
@@ -2740,6 +2740,7 @@ e100_exec_non_cu_cmd(struct e100_private *bdp, nxmit_cb_entry_t *command)
 
        if (!e100_wait_exec_cmplx(bdp, command->dma_addr, SCB_CUC_START)) {
                spin_unlock_irqrestore(&(bdp->bd_lock), lock_flag);
+               rc = false;
                goto exit;
        }
 
@@ -2748,20 +2749,21 @@ e100_exec_non_cu_cmd(struct e100_private *bdp, nxmit_cb_entry_t *command)
 
        /* now wait for completion of non-cu CB up to 20 msec */
        expiration_time = jiffies + HZ / 50 + 1;
-       while (time_before(jiffies, expiration_time)) {
-               rmb();
-               if ((ntcb_hdr->cb_status &
+       rmb();
+       while (!(ntcb_hdr->cb_status &
                     __constant_cpu_to_le16(CB_STATUS_COMPLETE))) {
-                       rc = true;
+
+               if (time_before(jiffies, expiration_time)) {
+                       spin_unlock_bh(&(bdp->bd_non_tx_lock));
+                       yield();
+                       spin_lock_bh(&(bdp->bd_non_tx_lock));
+               } else {
+                       rc = false;
                        goto exit;
                }
-               spin_unlock_bh(&(bdp->bd_non_tx_lock));
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
-               spin_lock_bh(&(bdp->bd_non_tx_lock));
+               rmb();
        }
 
-       /* didn't get a C bit assume command failed */
 exit:
        e100_free_non_tx_cmd(bdp, command);
 
index 9f25ef1a6e59a40afd5235b64bba3bb2d1e76c0f..80029f9839668478adf0c847e83b7d2dce519602 100644 (file)
@@ -653,7 +653,7 @@ static void
 e100_force_speed_duplex(struct e100_private *bdp)
 {
        u16 control;
-       int neg_timeout = 2 * HZ;       //2 sec in jiffies
+       unsigned long expires;
 
        bdp->flags |= DF_SPEED_FORCED;
 
@@ -696,20 +696,18 @@ e100_force_speed_duplex(struct e100_private *bdp)
        e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr, control);
 
        /* loop must run at least once */
+       expires = jiffies + 2 * HZ;
        do {
-               spin_unlock_bh(&(bdp->mdi_access_lock));
-
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(SLEEP_TIME);
-
-               spin_lock_bh(&(bdp->mdi_access_lock));
-
-               if (e100_update_link_state(bdp)) {
+               if (e100_update_link_state(bdp) || 
+                   time_after(jiffies, expires)) {
                        break;
+               } else {
+                       spin_unlock_bh(&(bdp->mdi_access_lock));
+                       yield();
+                       spin_lock_bh(&(bdp->mdi_access_lock));
                }
-               neg_timeout -= SLEEP_TIME;
 
-       } while (neg_timeout > 0);
+       } while (true);
 
        spin_unlock_bh(&(bdp->mdi_access_lock));
 }
@@ -819,7 +817,7 @@ static void
 e100_auto_neg(struct e100_private *bdp, unsigned char force_restart)
 {
        u16 stat_reg;
-       unsigned int i;
+       unsigned long expires;
 
        bdp->flags &= ~DF_SPEED_FORCED;
 
@@ -840,22 +838,21 @@ e100_auto_neg(struct e100_private *bdp, unsigned char force_restart)
                               BMCR_ANENABLE | BMCR_ANRESTART);
 
                /* wait for autoneg to complete (up to 3 seconds) */
-               for (i = 0; i < 60; i++) {
+               expires = jiffies + HZ * 3;
+               do {
                        /* now re-read the value. Sticky so read twice */
                        e100_mdi_read(bdp, MII_BMSR, bdp->phy_addr, &stat_reg);
                        e100_mdi_read(bdp, MII_BMSR, bdp->phy_addr, &stat_reg);
 
-                       if (stat_reg & BMSR_ANEGCOMPLETE)
+                       if ((stat_reg & BMSR_ANEGCOMPLETE) ||
+                           time_after(jiffies, expires) ) {
                                goto exit;
-
-                       spin_unlock_bh(&(bdp->mdi_access_lock));
-
-                       set_current_state(TASK_UNINTERRUPTIBLE);
-                       schedule_timeout(SLEEP_TIME);
-
-                       spin_lock_bh(&(bdp->mdi_access_lock));
-
-               }
+                       } else {
+                               spin_unlock_bh(&(bdp->mdi_access_lock));
+                               yield();
+                               spin_lock_bh(&(bdp->mdi_access_lock));
+                       }
+               } while (true);
        }
 
 exit:
index 982b2f54d1ef7bbf860473c2a6ac39cec4f90e63..a17c24ff6a812fcc3e6fec85ff0d7c402cd6423a 100644 (file)
@@ -97,7 +97,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #ifdef E100_CONFIG_PROC_FS
 #include "e100.h"
-
+/* MDI sleep time is at least 50 ms, in jiffies */
+#define MDI_SLEEP_TIME ((HZ / 20) + 1)
 /***************************************************************************/
 /*       /proc File System Interaface Support Functions                    */
 /***************************************************************************/
@@ -230,7 +231,7 @@ set_led(struct e100_private *bdp, u16 led_mdi_op)
        spin_unlock_bh(&bdp->mdi_access_lock);
 
        set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout(SLEEP_TIME);
+       schedule_timeout(MDI_SLEEP_TIME);
 
        spin_lock_bh(&bdp->mdi_access_lock);