All of lore.kernel.org
 help / color / mirror / Atom feed
* [parisc-linux] memcpy_fromio() seems partially broken [with patch]
@ 2001-06-08 21:37 Helge Deller
  2001-06-09  1:39 ` Matthew Wilcox
  0 siblings, 1 reply; 3+ messages in thread
From: Helge Deller @ 2001-06-08 21:37 UTC (permalink / raw)
  To: parisc-linux

Hi,

while I was playing with a few network-cards in the c3k I found a strange 
behaviour when copying unaligned data with memcpy_fromio() off the PCI bus.

Background: 
I wanted to copy data off the network-card (HP J2585A) from an 4-byte aligned 
PCI address to an 2-byte aligned (b/c of skb_reserve(skb, 2)) memory-address 
with memcpy_fromio().
The current code in CVS for memcpy_fromio() copied byteswapped and/or 
completely wrong data for all copied values, while the following 
memcpy_fromio() worked without problems:

/* Copies a block of memory from a device in an efficient manner.
 * Assumes the device can cope with 32-bit transfers.  If it can't,
 * don't use this function.
 */
void memcpy_fromio(const void *dest, unsigned long src, int count)
{
        u32 value;
        if (((unsigned long)dest & 3) != (src & 3))
                goto wordcopy;
        while (src & 3) {
                *(char *)dest = readb(src++);
                ((char *)dest)++;
                count--;
        }
        while (count > 3) {
                *(u32 *)dest = readl(src);
                dest += 4;
                src += 4;
                count -= 4;
        }
        if (!count)
                return;
 wordcopy:
        if (src & 3)
                goto bytecopy;
 wordcopy_loop:
        value = readl(src);
        *((char*)dest) = (char) (value >> 24);  dest++;
        if (--count == 0) return;
        *((char*)dest) = (char) (value >> 16);  dest++;
        if (--count == 0) return;
        *((char*)dest) = (char) (value >> 8);   dest++;
        if (--count == 0) return;
        *((char*)dest) = (char) (value);  dest++;
        if (count) goto wordcopy_loop;
        return;
 
 bytecopy:
        while (count--) {
                *(char *)dest = readb(src++);
                ((char *)dest)++;
        }
}

The previous version copied all data with readb() while this implementation 
tries to access the (pci-)bus most of the time with readl()s. 
I know, this is not the best or cleanest implementation, but I think we need 
to change memcpy_fromio() in such a manner.

What is your thought about it, or any ideas why the previous version sucked ?

Greetings,
Helge

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2001-06-11  0:11 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-06-08 21:37 [parisc-linux] memcpy_fromio() seems partially broken [with patch] Helge Deller
2001-06-09  1:39 ` Matthew Wilcox
2001-06-11  0:03   ` Grant Grundler

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.