- 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).
#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
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,
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));
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);
}
//----------------------------------------------------------------------------------------
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);
}
//----------------------------------------------------------------------------------------
/* 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 "
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 */
if (!e100_wait_exec_cmplx(bdp, command->dma_addr, SCB_CUC_START)) {
spin_unlock_irqrestore(&(bdp->bd_lock), lock_flag);
+ rc = false;
goto exit;
}
/* 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);
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;
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));
}
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;
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:
#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 */
/***************************************************************************/
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);