> while(dev->tbusy); /* Stop ring access */
> while(lp->tx_old != lp->tx_new); /* Wait for the ring to empty */
> One way of fixing this, I guess, would be to declare tbusy, tx_old and
> tx_new as "volatile". This would force a new memory access every time
> the variables were used. However, an alternative which affects only
> this file is to fill the loop with at least one instruction which the
> compiler thinks can affect the memory: this prevents the unwanted
> optimization. My choice was to use the macro mb() (defined in
> "asm/system.h"):
> #define mb() __asm__ __volatile__ ("" : : :"memory")
when gcc's optimizer decides to look at the contents of the "assembly"
and notices it's empty).
Anyway, it's not tbusy, etc., which you would declare volatile (fields
cannot be declared volatile). It's whatever dev and lp point to that
are volatile.
If what dev points to really can change behind the driver's back, it
*SHOULD* be declared volatile:
volatile something *dev;
You can also limit your change to just that loop, if you wish (limits
the change, though it's stylistically indefensible):
while (((volatile something *)dev)->tbusy)
;
while (((volatile somethingelse *)lp)->tx_old !=
((volatile somethingelse *)lp)->tx_new)
; /* Wait for the ring to empty */
Remember, volatile is your *friend*. Use it wisely, and you'll be
rewarded.
--
Shankar Unni Powertel Global, Inc.