Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <viro@zeniv.linux.org.uk>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

authored by

Al Viro and committed by
David S. Miller
f3ec33e5 b710b43c

+33 -28
+26 -23
drivers/net/sunhme.c
··· 194 194 195 195 static void sbus_hme_write_rxd(struct happy_meal_rxd *rxd, u32 flags, u32 addr) 196 196 { 197 - rxd->rx_addr = addr; 197 + rxd->rx_addr = (__force hme32)addr; 198 198 wmb(); 199 - rxd->rx_flags = flags; 199 + rxd->rx_flags = (__force hme32)flags; 200 200 } 201 201 202 202 static void sbus_hme_write_txd(struct happy_meal_txd *txd, u32 flags, u32 addr) 203 203 { 204 - txd->tx_addr = addr; 204 + txd->tx_addr = (__force hme32)addr; 205 205 wmb(); 206 - txd->tx_flags = flags; 206 + txd->tx_flags = (__force hme32)flags; 207 207 } 208 208 209 - static u32 sbus_hme_read_desc32(u32 *p) 209 + static u32 sbus_hme_read_desc32(hme32 *p) 210 210 { 211 - return *p; 211 + return (__force u32)*p; 212 212 } 213 213 214 214 static void pci_hme_write32(void __iomem *reg, u32 val) ··· 223 223 224 224 static void pci_hme_write_rxd(struct happy_meal_rxd *rxd, u32 flags, u32 addr) 225 225 { 226 - rxd->rx_addr = cpu_to_le32(addr); 226 + rxd->rx_addr = (__force hme32)cpu_to_le32(addr); 227 227 wmb(); 228 - rxd->rx_flags = cpu_to_le32(flags); 228 + rxd->rx_flags = (__force hme32)cpu_to_le32(flags); 229 229 } 230 230 231 231 static void pci_hme_write_txd(struct happy_meal_txd *txd, u32 flags, u32 addr) 232 232 { 233 - txd->tx_addr = cpu_to_le32(addr); 233 + txd->tx_addr = (__force hme32)cpu_to_le32(addr); 234 234 wmb(); 235 - txd->tx_flags = cpu_to_le32(flags); 235 + txd->tx_flags = (__force hme32)cpu_to_le32(flags); 236 236 } 237 237 238 - static u32 pci_hme_read_desc32(u32 *p) 238 + static u32 pci_hme_read_desc32(hme32 *p) 239 239 { 240 - return cpu_to_le32p(p); 240 + return le32_to_cpup((__le32 *)p); 241 241 } 242 242 243 243 #define hme_write32(__hp, __reg, __val) \ ··· 266 266 #define hme_read32(__hp, __reg) \ 267 267 sbus_readl(__reg) 268 268 #define hme_write_rxd(__hp, __rxd, __flags, __addr) \ 269 - do { (__rxd)->rx_addr = (__addr); \ 269 + do { (__rxd)->rx_addr = (__force hme32)(u32)(__addr); \ 270 270 wmb(); \ 271 - (__rxd)->rx_flags = (__flags); \ 271 + (__rxd)->rx_flags = (__force hme32)(u32)(__flags); \ 272 272 } while(0) 273 273 #define hme_write_txd(__hp, __txd, __flags, __addr) \ 274 - do { (__txd)->tx_addr = (__addr); \ 274 + do { (__txd)->tx_addr = (__force hme32)(u32)(__addr); \ 275 275 wmb(); \ 276 - (__txd)->tx_flags = (__flags); \ 276 + (__txd)->tx_flags = (__force hme32)(u32)(__flags); \ 277 277 } while(0) 278 - #define hme_read_desc32(__hp, __p) (*(__p)) 278 + #define hme_read_desc32(__hp, __p) ((__force u32)(hme32)*(__p)) 279 279 #define hme_dma_map(__hp, __ptr, __size, __dir) \ 280 280 sbus_map_single((__hp)->happy_dev, (__ptr), (__size), (__dir)) 281 281 #define hme_dma_unmap(__hp, __addr, __size, __dir) \ ··· 291 291 #define hme_read32(__hp, __reg) \ 292 292 readl(__reg) 293 293 #define hme_write_rxd(__hp, __rxd, __flags, __addr) \ 294 - do { (__rxd)->rx_addr = cpu_to_le32(__addr); \ 294 + do { (__rxd)->rx_addr = (__force hme32)cpu_to_le32(__addr); \ 295 295 wmb(); \ 296 - (__rxd)->rx_flags = cpu_to_le32(__flags); \ 296 + (__rxd)->rx_flags = (__force hme32)cpu_to_le32(__flags); \ 297 297 } while(0) 298 298 #define hme_write_txd(__hp, __txd, __flags, __addr) \ 299 - do { (__txd)->tx_addr = cpu_to_le32(__addr); \ 299 + do { (__txd)->tx_addr = (__force hme32)cpu_to_le32(__addr); \ 300 300 wmb(); \ 301 - (__txd)->tx_flags = cpu_to_le32(__flags); \ 301 + (__txd)->tx_flags = (__force hme32)cpu_to_le32(__flags); \ 302 302 } while(0) 303 - #define hme_read_desc32(__hp, __p) cpu_to_le32p(__p) 303 + static inline u32 hme_read_desc32(struct happy_meal *hp, hme32 *p) 304 + { 305 + return le32_to_cpup((__le32 *)p); 306 + } 304 307 #define hme_dma_map(__hp, __ptr, __size, __dir) \ 305 308 pci_map_single((__hp)->happy_dev, (__ptr), (__size), (__dir)) 306 309 #define hme_dma_unmap(__hp, __addr, __size, __dir) \ ··· 2078 2075 } 2079 2076 2080 2077 /* This card is _fucking_ hot... */ 2081 - skb->csum = ntohs(csum ^ 0xffff); 2078 + skb->csum = csum_unfold(~(__force __sum16)htons(csum)); 2082 2079 skb->ip_summed = CHECKSUM_COMPLETE; 2083 2080 2084 2081 RXD(("len=%d csum=%4x]", len, csum));
+7 -5
drivers/net/sunhme.h
··· 302 302 * Always write the address first before setting the ownership 303 303 * bits to avoid races with the hardware scanning the ring. 304 304 */ 305 + typedef u32 __bitwise__ hme32; 306 + 305 307 struct happy_meal_rxd { 306 - u32 rx_flags; 307 - u32 rx_addr; 308 + hme32 rx_flags; 309 + hme32 rx_addr; 308 310 }; 309 311 310 312 #define RXFLAG_OWN 0x80000000 /* 1 = hardware, 0 = software */ ··· 315 313 #define RXFLAG_CSUM 0x0000ffff /* HW computed checksum */ 316 314 317 315 struct happy_meal_txd { 318 - u32 tx_flags; 319 - u32 tx_addr; 316 + hme32 tx_flags; 317 + hme32 tx_addr; 320 318 }; 321 319 322 320 #define TXFLAG_OWN 0x80000000 /* 1 = hardware, 0 = software */ ··· 402 400 struct hmeal_init_block *happy_block; /* RX and TX descriptors (CPU addr) */ 403 401 404 402 #if defined(CONFIG_SBUS) && defined(CONFIG_PCI) 405 - u32 (*read_desc32)(u32 *); 403 + u32 (*read_desc32)(hme32 *); 406 404 void (*write_txd)(struct happy_meal_txd *, u32, u32); 407 405 void (*write_rxd)(struct happy_meal_rxd *, u32, u32); 408 406 u32 (*dma_map)(void *, void *, long, int);