Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=8e9859184031ac1b0a0234b8671a90cfcd333666
Commit:     8e9859184031ac1b0a0234b8671a90cfcd333666
Parent:     8543da6672b0994921f014f2250e27ae81645580
Author:     Al Viro <[EMAIL PROTECTED]>
AuthorDate: Mon Dec 10 18:39:29 2007 +0000
Committer:  Jeff Garzik <[EMAIL PROTECTED]>
CommitDate: Fri Dec 14 15:26:15 2007 -0500

    hamachi endianness fixes
    
    badly broken on big-endian
    
    * passing little-endian to pci_unmap_single() et.al.
    * cpu_to_le32() before passing value to writel()
    * worse, cpu_to_le64() and shifting/masking result before the same
    *                   hmp->tx_ring[i].status_n_length = cpu_to_le32(
                                DescEndRing |
                                (hmp->tx_ring[i].status_n_length & 0x0000FFFF));
      is obviously bogus on big-endian.  Not hard to untangle, fortunately...
    * poisoning addresses in rx_ring is better done after we'd done
    pci_unmap_single() on them, not before that.  [this one affects 
little-endian
    as well, obviously, provided that pci_unmap_single() is not a no-op on 
target
    in question]
    
    Signed-off-by: Al Viro <[EMAIL PROTECTED]>
    Signed-off-by: Jeff Garzik <[EMAIL PROTECTED]>
---
 drivers/net/hamachi.c |   70 ++++++++++++++++++++++++++-----------------------
 1 files changed, 37 insertions(+), 33 deletions(-)

diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index ed407c8..b53f6b6 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -204,8 +204,10 @@ KERN_INFO "   Further modifications by Keith Underwood 
<[EMAIL PROTECTED]>
 /* Condensed bus+endian portability operations. */
 #if ADDRLEN == 64
 #define cpu_to_leXX(addr)      cpu_to_le64(addr)
+#define leXX_to_cpu(addr)      le64_to_cpu(addr)
 #else
 #define cpu_to_leXX(addr)      cpu_to_le32(addr)
+#define leXX_to_cpu(addr)      le32_to_cpu(addr)
 #endif
 
 
@@ -465,12 +467,12 @@ enum intr_status_bits {
 
 /* The Hamachi Rx and Tx buffer descriptors. */
 struct hamachi_desc {
-       u32 status_n_length;
+       __le32 status_n_length;
 #if ADDRLEN == 64
        u32 pad;
-       u64 addr;
+       __le64 addr;
 #else
-       u32 addr;
+       __le32 addr;
 #endif
 };
 
@@ -874,13 +876,13 @@ static int hamachi_open(struct net_device *dev)
 
 #if ADDRLEN == 64
        /* writellll anyone ? */
-       writel(cpu_to_le64(hmp->rx_ring_dma), ioaddr + RxPtr);
-       writel(cpu_to_le64(hmp->rx_ring_dma) >> 32, ioaddr + RxPtr + 4);
-       writel(cpu_to_le64(hmp->tx_ring_dma), ioaddr + TxPtr);
-       writel(cpu_to_le64(hmp->tx_ring_dma) >> 32, ioaddr + TxPtr + 4);
+       writel(hmp->rx_ring_dma, ioaddr + RxPtr);
+       writel(hmp->rx_ring_dma >> 32, ioaddr + RxPtr + 4);
+       writel(hmp->tx_ring_dma, ioaddr + TxPtr);
+       writel(hmp->tx_ring_dma >> 32, ioaddr + TxPtr + 4);
 #else
-       writel(cpu_to_le32(hmp->rx_ring_dma), ioaddr + RxPtr);
-       writel(cpu_to_le32(hmp->tx_ring_dma), ioaddr + TxPtr);
+       writel(hmp->rx_ring_dma, ioaddr + RxPtr);
+       writel(hmp->tx_ring_dma, ioaddr + TxPtr);
 #endif
 
        /* TODO:  It would make sense to organize this as words since the card
@@ -1019,8 +1021,8 @@ static inline int hamachi_tx(struct net_device *dev)
                skb = hmp->tx_skbuff[entry];
                if (skb) {
                        pci_unmap_single(hmp->pci_dev,
-                               hmp->tx_ring[entry].addr, skb->len,
-                               PCI_DMA_TODEVICE);
+                               leXX_to_cpu(hmp->tx_ring[entry].addr),
+                               skb->len, PCI_DMA_TODEVICE);
                        dev_kfree_skb(skb);
                        hmp->tx_skbuff[entry] = NULL;
                }
@@ -1071,10 +1073,10 @@ static void hamachi_tx_timeout(struct net_device *dev)
        {
                printk(KERN_DEBUG "  Rx ring %p: ", hmp->rx_ring);
                for (i = 0; i < RX_RING_SIZE; i++)
-                       printk(" %8.8x", (unsigned 
int)hmp->rx_ring[i].status_n_length);
+                       printk(" %8.8x", 
le32_to_cpu(hmp->rx_ring[i].status_n_length));
                printk("\n"KERN_DEBUG"  Tx ring %p: ", hmp->tx_ring);
                for (i = 0; i < TX_RING_SIZE; i++)
-                       printk(" %4.4x", hmp->tx_ring[i].status_n_length);
+                       printk(" %4.4x", 
le32_to_cpu(hmp->tx_ring[i].status_n_length));
                printk("\n");
        }
 
@@ -1099,14 +1101,15 @@ static void hamachi_tx_timeout(struct net_device *dev)
                struct sk_buff *skb;
 
                if (i >= TX_RING_SIZE - 1)
-                       hmp->tx_ring[i].status_n_length = cpu_to_le32(
-                               DescEndRing |
-                               (hmp->tx_ring[i].status_n_length & 0x0000FFFF));
+                       hmp->tx_ring[i].status_n_length =
+                               cpu_to_le32(DescEndRing) |
+                               (hmp->tx_ring[i].status_n_length &
+                                cpu_to_le32(0x0000ffff));
                else
-                       hmp->tx_ring[i].status_n_length &= 0x0000ffff;
+                       hmp->tx_ring[i].status_n_length &= 
cpu_to_le32(0x0000ffff);
                skb = hmp->tx_skbuff[i];
                if (skb){
-                       pci_unmap_single(hmp->pci_dev, hmp->tx_ring[i].addr,
+                       pci_unmap_single(hmp->pci_dev, 
leXX_to_cpu(hmp->tx_ring[i].addr),
                                skb->len, PCI_DMA_TODEVICE);
                        dev_kfree_skb(skb);
                        hmp->tx_skbuff[i] = NULL;
@@ -1128,7 +1131,8 @@ static void hamachi_tx_timeout(struct net_device *dev)
                struct sk_buff *skb = hmp->rx_skbuff[i];
 
                if (skb){
-                       pci_unmap_single(hmp->pci_dev, hmp->rx_ring[i].addr,
+                       pci_unmap_single(hmp->pci_dev,
+                               leXX_to_cpu(hmp->rx_ring[i].addr),
                                hmp->rx_buf_sz, PCI_DMA_FROMDEVICE);
                        dev_kfree_skb(skb);
                        hmp->rx_skbuff[i] = NULL;
@@ -1420,7 +1424,7 @@ static irqreturn_t hamachi_interrupt(int irq, void 
*dev_instance)
                                        /* Free the original skb. */
                                        if (skb){
                                                pci_unmap_single(hmp->pci_dev,
-                                                       
hmp->tx_ring[entry].addr,
+                                                       
leXX_to_cpu(hmp->tx_ring[entry].addr),
                                                        skb->len,
                                                        PCI_DMA_TODEVICE);
                                                dev_kfree_skb_irq(skb);
@@ -1500,11 +1504,11 @@ static int hamachi_rx(struct net_device *dev)
                if (desc_status & DescOwn)
                        break;
                pci_dma_sync_single_for_cpu(hmp->pci_dev,
-                                           desc->addr,
+                                           leXX_to_cpu(desc->addr),
                                            hmp->rx_buf_sz,
                                            PCI_DMA_FROMDEVICE);
                buf_addr = (u8 *) hmp->rx_skbuff[entry]->data;
-               frame_status = 
le32_to_cpu(get_unaligned((s32*)&(buf_addr[data_size - 12])));
+               frame_status = 
le32_to_cpu(get_unaligned((__le32*)&(buf_addr[data_size - 12])));
                if (hamachi_debug > 4)
                        printk(KERN_DEBUG "  hamachi_rx() status was %8.8x.\n",
                                frame_status);
@@ -1518,9 +1522,9 @@ static int hamachi_rx(struct net_device *dev)
                                   dev->name, desc, &hmp->rx_ring[hmp->cur_rx % 
RX_RING_SIZE]);
                        printk(KERN_WARNING "%s: Oversized Ethernet frame -- 
next status %x/%x last status %x.\n",
                                   dev->name,
-                                  hmp->rx_ring[(hmp->cur_rx+1) % 
RX_RING_SIZE].status_n_length & 0xffff0000,
-                                  hmp->rx_ring[(hmp->cur_rx+1) % 
RX_RING_SIZE].status_n_length & 0x0000ffff,
-                                  hmp->rx_ring[(hmp->cur_rx-1) % 
RX_RING_SIZE].status_n_length);
+                                  le32_to_cpu(hmp->rx_ring[(hmp->cur_rx+1) % 
RX_RING_SIZE].status_n_length) & 0xffff0000,
+                                  le32_to_cpu(hmp->rx_ring[(hmp->cur_rx+1) % 
RX_RING_SIZE].status_n_length) & 0x0000ffff,
+                                  le32_to_cpu(hmp->rx_ring[(hmp->cur_rx-1) % 
RX_RING_SIZE].status_n_length));
                        hmp->stats.rx_length_errors++;
                } /* else  Omit for prototype errata??? */
                if (frame_status & 0x00380000) {
@@ -1566,7 +1570,7 @@ static int hamachi_rx(struct net_device *dev)
 #endif
                                skb_reserve(skb, 2);    /* 16 byte align the IP 
header */
                                pci_dma_sync_single_for_cpu(hmp->pci_dev,
-                                                           
hmp->rx_ring[entry].addr,
+                                                           
leXX_to_cpu(hmp->rx_ring[entry].addr),
                                                            hmp->rx_buf_sz,
                                                            PCI_DMA_FROMDEVICE);
                                /* Call copy + cksum if available. */
@@ -1579,12 +1583,12 @@ static int hamachi_rx(struct net_device *dev)
                                        + entry*sizeof(*desc), pkt_len);
 #endif
                                pci_dma_sync_single_for_device(hmp->pci_dev,
-                                                              
hmp->rx_ring[entry].addr,
+                                                              
leXX_to_cpu(hmp->rx_ring[entry].addr),
                                                               hmp->rx_buf_sz,
                                                               
PCI_DMA_FROMDEVICE);
                        } else {
                                pci_unmap_single(hmp->pci_dev,
-                                                hmp->rx_ring[entry].addr,
+                                                
leXX_to_cpu(hmp->rx_ring[entry].addr),
                                                 hmp->rx_buf_sz, 
PCI_DMA_FROMDEVICE);
                                skb_put(skb = hmp->rx_skbuff[entry], pkt_len);
                                hmp->rx_skbuff[entry] = NULL;
@@ -1787,21 +1791,21 @@ static int hamachi_close(struct net_device *dev)
        for (i = 0; i < RX_RING_SIZE; i++) {
                skb = hmp->rx_skbuff[i];
                hmp->rx_ring[i].status_n_length = 0;
-               hmp->rx_ring[i].addr = 0xBADF00D0; /* An invalid address. */
                if (skb) {
                        pci_unmap_single(hmp->pci_dev,
-                               hmp->rx_ring[i].addr, hmp->rx_buf_sz,
-                               PCI_DMA_FROMDEVICE);
+                               leXX_to_cpu(hmp->rx_ring[i].addr),
+                               hmp->rx_buf_sz, PCI_DMA_FROMDEVICE);
                        dev_kfree_skb(skb);
                        hmp->rx_skbuff[i] = NULL;
                }
+               hmp->rx_ring[i].addr = cpu_to_leXX(0xBADF00D0); /* An invalid 
address. */
        }
        for (i = 0; i < TX_RING_SIZE; i++) {
                skb = hmp->tx_skbuff[i];
                if (skb) {
                        pci_unmap_single(hmp->pci_dev,
-                               hmp->tx_ring[i].addr, skb->len,
-                               PCI_DMA_TODEVICE);
+                               leXX_to_cpu(hmp->tx_ring[i].addr),
+                               skb->len, PCI_DMA_TODEVICE);
                        dev_kfree_skb(skb);
                        hmp->tx_skbuff[i] = NULL;
                }
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to