[eepro100] Re: Integrated Pro/100 on Intel D815EEA - serious problem
Andrey Savochkin
saw@saw.sw.com.sg
Tue, 20 Feb 2001 18:36:18 -0800
--dDRMvlgZJXvWKvBx
Content-Type: text/plain; charset=us-ascii
Hi,
On Tue, Feb 20, 2001 at 11:29:03PM +0100, Noll Janos wrote:
> I've tried to get informed about this problem. Using Deja.com-s search, I've
> found that many people are having problems with the Intel D815EEA motherboard
> (which has an integrated ethernet card).
>
> The system seems to run "fine" until it gets some (not even too large) net
> load...
[snip]
> [...]
> eepro100: wait_for_cmd_done timeout!
It's interesting to know which command caused this timeout.
I debugged some similar problems with the attached patch.
Best regards
Andrey
--dDRMvlgZJXvWKvBx
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff
--- versions/eepro100.c.R1.33 Fri May 26 19:33:47 2000
+++ patches/eepro100.c-testwait Tue Jun 20 03:07:45 2000
@@ -363,19 +363,6 @@
#define outl writel
#endif
-/* How to wait for the command unit to accept a command.
- Typically this takes 0 ticks. */
-static inline void wait_for_cmd_done(long cmd_ioaddr)
-{
- int wait = 1000;
- do ;
- while(inb(cmd_ioaddr) && --wait >= 0);
-#ifndef final_version
- if (wait < 0)
- printk(KERN_ALERT "eepro100: wait_for_cmd_done timeout!\n");
-#endif
-}
-
/* Offsets to the various registers.
All accesses need not be longword aligned. */
enum speedo_offsets {
@@ -532,6 +519,7 @@
unsigned int full_duplex:1; /* Full-duplex operation requested. */
unsigned int flow_ctrl:1; /* Use 802.3x flow control. */
unsigned int rx_bug:1; /* Work around receiver hang errata. */
+ unsigned int dumpstat; /* Last command was CUDumpStat. */
unsigned char default_port:8; /* Last dev->if_port value. */
unsigned char rx_ring_state; /* RX ring status flags. */
unsigned short phy[2]; /* PHY media interfaces available. */
@@ -1036,6 +1039,77 @@
return 0;
}
+/* How to wait for the command unit to accept a command.
+ Typically this takes 0 ticks. */
+
+static int show_trace(int dummy)
+{
+ int i;
+ unsigned long *stack, addr, module_start, module_end;
+#define MODULE_RANGE (8*1024*1024)
+ printk("CPU: %d\nEIP: [<%08lx>]\n",
+ smp_processor_id(), (unsigned long)__builtin_return_address(0));
+ printk("Stack: ");
+ stack = (unsigned long *) &dummy;
+ for(i = 0; i < 24; i++) {
+ if (((long) stack & (THREAD_SIZE-1)) == 0)
+ break;
+ if (i && ((i % 8) == 0))
+ printk("\n ");
+ printk("%08lx ", *stack++);
+ }
+ printk("\nCall Trace: ");
+ stack = (unsigned long *) &dummy;
+ i = 1;
+ module_start = PAGE_OFFSET + (max_mapnr << PAGE_SHIFT);
+ module_start = ((module_start + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1));
+ module_end = module_start + MODULE_RANGE;
+ while (((long) stack & (THREAD_SIZE-1)) != 0) {
+ extern char _stext, _etext;
+ addr = *stack++;
+ /*
+ * If the address is either in the text segment of the
+ * kernel, or in the region which contains vmalloc'ed
+ * memory, it *may* be the address of a calling
+ * routine; if so, print it so that someone tracing
+ * down the cause of the crash will be able to figure
+ * out the call path that was taken.
+ */
+ if (((addr >= (unsigned long) &_stext) &&
+ (addr <= (unsigned long) &_etext)) ||
+ ((addr >= module_start) && (addr <= module_end))) {
+ if (i && ((i % 8) == 0))
+ printk("\n ");
+ printk("[<%08lx>] ", addr);
+ i++;
+ }
+ }
+ return 0;
+}
+
+#if 0
+static void wait_for_cmd_done(long cmd_ioaddr)
+#endif
+#define wait_for_cmd_done(cmd_ioaddr) \
+do \
+{ \
+ int wait = 1000; \
+ do ; \
+ while(inb(cmd_ioaddr) && --wait >= 0); \
+ if (wait < 0) { \
+ printk(KERN_ALERT "eepro100: wait_for_cmd_done timeout!\n"); \
+ /* DEBUG */ \
+ show_trace(0); \
+ printk(KERN_INFO \
+ "eepro100: w-f-c-d-t, cmd=%04x, stat=%04x, %d.\n", \
+ inw(cmd_ioaddr), inw(cmd_ioaddr + SCBStatus - SCBCmd), \
+ sp->dumpstat); \
+ } else { \
+ sp->dumpstat = 0; \
+ } \
+} \
+while (0)
+
/* Start the chip hardware after a full reset. */
static void speedo_resume(struct net_device *dev)
{
@@ -1934,6 +1999,7 @@
spin_lock_irqsave(&sp->lock, flags);
wait_for_cmd_done(ioaddr + SCBCmd);
outb(CUDumpStats, ioaddr + SCBCmd);
+ sp->dumpstat = 2;
spin_unlock_irqrestore(&sp->lock, flags);
}
}
--dDRMvlgZJXvWKvBx--