From: Al Viro Date: Sun, 16 Dec 2007 23:30:08 +0000 (+0000) Subject: sunhme endianness annotations X-Git-Tag: v2.6.25-rc1~1162^2~349 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f3ec33e587df02e25963755989cc473e3f07bf0d;p=linux-2.6 sunhme endianness annotations This one is interesting - SBUS and PCI variants have opposite endianness in descriptors (SBUS is sparc-only, so there host-endian == big-endian). Solution: declare a bitwise type (hme32) and in accessor helpers do typechecking and force-casts (once we know that the type is right). Signed-off-by: Al Viro Signed-off-by: Jeff Garzik --- diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index 9cc13dd8a8..25ce26a882 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -194,21 +194,21 @@ static u32 sbus_hme_read32(void __iomem *reg) static void sbus_hme_write_rxd(struct happy_meal_rxd *rxd, u32 flags, u32 addr) { - rxd->rx_addr = addr; + rxd->rx_addr = (__force hme32)addr; wmb(); - rxd->rx_flags = flags; + rxd->rx_flags = (__force hme32)flags; } static void sbus_hme_write_txd(struct happy_meal_txd *txd, u32 flags, u32 addr) { - txd->tx_addr = addr; + txd->tx_addr = (__force hme32)addr; wmb(); - txd->tx_flags = flags; + txd->tx_flags = (__force hme32)flags; } -static u32 sbus_hme_read_desc32(u32 *p) +static u32 sbus_hme_read_desc32(hme32 *p) { - return *p; + return (__force u32)*p; } static void pci_hme_write32(void __iomem *reg, u32 val) @@ -223,21 +223,21 @@ static u32 pci_hme_read32(void __iomem *reg) static void pci_hme_write_rxd(struct happy_meal_rxd *rxd, u32 flags, u32 addr) { - rxd->rx_addr = cpu_to_le32(addr); + rxd->rx_addr = (__force hme32)cpu_to_le32(addr); wmb(); - rxd->rx_flags = cpu_to_le32(flags); + rxd->rx_flags = (__force hme32)cpu_to_le32(flags); } static void pci_hme_write_txd(struct happy_meal_txd *txd, u32 flags, u32 addr) { - txd->tx_addr = cpu_to_le32(addr); + txd->tx_addr = (__force hme32)cpu_to_le32(addr); wmb(); - txd->tx_flags = cpu_to_le32(flags); + txd->tx_flags = (__force hme32)cpu_to_le32(flags); } -static u32 pci_hme_read_desc32(u32 *p) +static u32 pci_hme_read_desc32(hme32 *p) { - return cpu_to_le32p(p); + return le32_to_cpup((__le32 *)p); } #define hme_write32(__hp, __reg, __val) \ @@ -266,16 +266,16 @@ static u32 pci_hme_read_desc32(u32 *p) #define hme_read32(__hp, __reg) \ sbus_readl(__reg) #define hme_write_rxd(__hp, __rxd, __flags, __addr) \ -do { (__rxd)->rx_addr = (__addr); \ +do { (__rxd)->rx_addr = (__force hme32)(u32)(__addr); \ wmb(); \ - (__rxd)->rx_flags = (__flags); \ + (__rxd)->rx_flags = (__force hme32)(u32)(__flags); \ } while(0) #define hme_write_txd(__hp, __txd, __flags, __addr) \ -do { (__txd)->tx_addr = (__addr); \ +do { (__txd)->tx_addr = (__force hme32)(u32)(__addr); \ wmb(); \ - (__txd)->tx_flags = (__flags); \ + (__txd)->tx_flags = (__force hme32)(u32)(__flags); \ } while(0) -#define hme_read_desc32(__hp, __p) (*(__p)) +#define hme_read_desc32(__hp, __p) ((__force u32)(hme32)*(__p)) #define hme_dma_map(__hp, __ptr, __size, __dir) \ sbus_map_single((__hp)->happy_dev, (__ptr), (__size), (__dir)) #define hme_dma_unmap(__hp, __addr, __size, __dir) \ @@ -291,16 +291,19 @@ do { (__txd)->tx_addr = (__addr); \ #define hme_read32(__hp, __reg) \ readl(__reg) #define hme_write_rxd(__hp, __rxd, __flags, __addr) \ -do { (__rxd)->rx_addr = cpu_to_le32(__addr); \ +do { (__rxd)->rx_addr = (__force hme32)cpu_to_le32(__addr); \ wmb(); \ - (__rxd)->rx_flags = cpu_to_le32(__flags); \ + (__rxd)->rx_flags = (__force hme32)cpu_to_le32(__flags); \ } while(0) #define hme_write_txd(__hp, __txd, __flags, __addr) \ -do { (__txd)->tx_addr = cpu_to_le32(__addr); \ +do { (__txd)->tx_addr = (__force hme32)cpu_to_le32(__addr); \ wmb(); \ - (__txd)->tx_flags = cpu_to_le32(__flags); \ + (__txd)->tx_flags = (__force hme32)cpu_to_le32(__flags); \ } while(0) -#define hme_read_desc32(__hp, __p) cpu_to_le32p(__p) +static inline u32 hme_read_desc32(struct happy_meal *hp, hme32 *p) +{ + return le32_to_cpup((__le32 *)p); +} #define hme_dma_map(__hp, __ptr, __size, __dir) \ pci_map_single((__hp)->happy_dev, (__ptr), (__size), (__dir)) #define hme_dma_unmap(__hp, __addr, __size, __dir) \ @@ -2075,7 +2078,7 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev) } /* This card is _fucking_ hot... */ - skb->csum = ntohs(csum ^ 0xffff); + skb->csum = csum_unfold(~(__force __sum16)htons(csum)); skb->ip_summed = CHECKSUM_COMPLETE; RXD(("len=%d csum=%4x]", len, csum)); diff --git a/drivers/net/sunhme.h b/drivers/net/sunhme.h index 90f446db9b..4da5539fac 100644 --- a/drivers/net/sunhme.h +++ b/drivers/net/sunhme.h @@ -302,9 +302,11 @@ * Always write the address first before setting the ownership * bits to avoid races with the hardware scanning the ring. */ +typedef u32 __bitwise__ hme32; + struct happy_meal_rxd { - u32 rx_flags; - u32 rx_addr; + hme32 rx_flags; + hme32 rx_addr; }; #define RXFLAG_OWN 0x80000000 /* 1 = hardware, 0 = software */ @@ -313,8 +315,8 @@ struct happy_meal_rxd { #define RXFLAG_CSUM 0x0000ffff /* HW computed checksum */ struct happy_meal_txd { - u32 tx_flags; - u32 tx_addr; + hme32 tx_flags; + hme32 tx_addr; }; #define TXFLAG_OWN 0x80000000 /* 1 = hardware, 0 = software */ @@ -400,7 +402,7 @@ struct happy_meal { struct hmeal_init_block *happy_block; /* RX and TX descriptors (CPU addr) */ #if defined(CONFIG_SBUS) && defined(CONFIG_PCI) - u32 (*read_desc32)(u32 *); + u32 (*read_desc32)(hme32 *); void (*write_txd)(struct happy_meal_txd *, u32, u32); void (*write_rxd)(struct happy_meal_rxd *, u32, u32); u32 (*dma_map)(void *, void *, long, int);