Skip to content

Commit

Permalink
mac8390: Fix mmio access size probe
Browse files Browse the repository at this point in the history
The bug that Stan reported is as follows. After a restart, a 16-bit NIC
may be incorrectly identified as a 32-bit NIC and stop working.

mac8390 slot.E: Memory length resource not found, probing
mac8390 slot.E: Farallon EtherMac II-C (type farallon)
mac8390 slot.E: MAC 00:00:c5:30:c2:99, IRQ 61, 32 KB shared memory at 0xfeed0000, 32-bit access.

The bug never arises after a cold start and only intermittently after a
warm start. (I didn't investigate why the bug is intermittent.)

It turns out that memcpy_toio() is deprecated and memcmp_withio() also
has issues. Replacing these calls with mmio accessors fixes the problem.

Reported-and-tested-by: Stan Johnson <userm57@yahoo.com>
Fixes: 2964db0 ("m68k: Mac DP8390 update")
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Finn Thain authored and David S. Miller committed Mar 18, 2019
1 parent c22da36 commit bb9e5c5
Showing 1 changed file with 12 additions and 7 deletions.
19 changes: 12 additions & 7 deletions drivers/net/ethernet/8390/mac8390.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,6 @@ static void dayna_block_input(struct net_device *dev, int count,
static void dayna_block_output(struct net_device *dev, int count,
const unsigned char *buf, int start_page);

#define memcmp_withio(a, b, c) memcmp((a), (void *)(b), (c))

/* Slow Sane (16-bit chunk memory read/write) Cabletron uses this */
static void slow_sane_get_8390_hdr(struct net_device *dev,
struct e8390_pkt_hdr *hdr, int ring_page);
Expand Down Expand Up @@ -233,19 +231,26 @@ static enum mac8390_type mac8390_ident(struct nubus_rsrc *fres)

static enum mac8390_access mac8390_testio(unsigned long membase)
{
unsigned long outdata = 0xA5A0B5B0;
unsigned long indata = 0x00000000;
u32 outdata = 0xA5A0B5B0;
u32 indata = 0;

/* Try writing 32 bits */
memcpy_toio((void __iomem *)membase, &outdata, 4);
/* Now compare them */
if (memcmp_withio(&outdata, membase, 4) == 0)
nubus_writel(outdata, membase);
/* Now read it back */
indata = nubus_readl(membase);
if (outdata == indata)
return ACCESS_32;

outdata = 0xC5C0D5D0;
indata = 0;

/* Write 16 bit output */
word_memcpy_tocard(membase, &outdata, 4);
/* Now read it back */
word_memcpy_fromcard(&indata, membase, 4);
if (outdata == indata)
return ACCESS_16;

return ACCESS_UNKNOWN;
}

Expand Down

0 comments on commit bb9e5c5

Please sign in to comment.