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

[PATCH] smc91x: allow for dynamic bus access configs

All accessor's different methods are now selected with C code and unused
ones statically optimized away at compile time instead of being selected
with #if's and #ifdef's. This has many advantages such as allowing the
compiler to validate the syntax of the whole code, making it cleaner and
easier to understand, and ultimately allowing people to define
configuration symbols in terms of variables if they really want to
dynamically support multiple bus configurations at the same time (with
the unavoidable performance cost).

Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

authored by

Nicolas Pitre and committed by
Jeff Garzik
09779c6d ac62ef04

+308 -221
+24 -29
drivers/net/smc91x.c
··· 215 215 216 216 spinlock_t lock; 217 217 218 - #ifdef SMC_CAN_USE_DATACS 219 - u32 __iomem *datacs; 220 - #endif 221 - 222 218 #ifdef SMC_USE_PXA_DMA 223 219 /* DMA needs the physical address of the chip */ 224 220 u_long physaddr; 225 221 #endif 226 222 void __iomem *base; 223 + void __iomem *datacs; 227 224 }; 228 225 229 226 #if SMC_DEBUG > 0 ··· 2101 2104 * Set the appropriate byte/word mode. 2102 2105 */ 2103 2106 ecsr = readb(addr + (ECSR << SMC_IO_SHIFT)) & ~ECSR_IOIS8; 2104 - #ifndef SMC_CAN_USE_16BIT 2105 - ecsr |= ECSR_IOIS8; 2106 - #endif 2107 + if (!SMC_CAN_USE_16BIT) 2108 + ecsr |= ECSR_IOIS8; 2107 2109 writeb(ecsr, addr + (ECSR << SMC_IO_SHIFT)); 2108 2110 local_irq_restore(flags); 2109 2111 ··· 2139 2143 release_mem_region(res->start, ATTRIB_SIZE); 2140 2144 } 2141 2145 2142 - #ifdef SMC_CAN_USE_DATACS 2143 - static void smc_request_datacs(struct platform_device *pdev, struct net_device *ndev) 2146 + static inline void smc_request_datacs(struct platform_device *pdev, struct net_device *ndev) 2144 2147 { 2145 - struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32"); 2146 - struct smc_local *lp = netdev_priv(ndev); 2148 + if (SMC_CAN_USE_DATACS) { 2149 + struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32"); 2150 + struct smc_local *lp = netdev_priv(ndev); 2147 2151 2148 - if (!res) 2149 - return; 2152 + if (!res) 2153 + return; 2150 2154 2151 - if(!request_mem_region(res->start, SMC_DATA_EXTENT, CARDNAME)) { 2152 - printk(KERN_INFO "%s: failed to request datacs memory region.\n", CARDNAME); 2153 - return; 2155 + if(!request_mem_region(res->start, SMC_DATA_EXTENT, CARDNAME)) { 2156 + printk(KERN_INFO "%s: failed to request datacs memory region.\n", CARDNAME); 2157 + return; 2158 + } 2159 + 2160 + lp->datacs = ioremap(res->start, SMC_DATA_EXTENT); 2154 2161 } 2155 - 2156 - lp->datacs = ioremap(res->start, SMC_DATA_EXTENT); 2157 2162 } 2158 2163 2159 2164 static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev) 2160 2165 { 2161 - struct smc_local *lp = netdev_priv(ndev); 2162 - struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32"); 2166 + if (SMC_CAN_USE_DATACS) { 2167 + struct smc_local *lp = netdev_priv(ndev); 2168 + struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32"); 2163 2169 2164 - if (lp->datacs) 2165 - iounmap(lp->datacs); 2170 + if (lp->datacs) 2171 + iounmap(lp->datacs); 2166 2172 2167 - lp->datacs = NULL; 2173 + lp->datacs = NULL; 2168 2174 2169 - if (res) 2170 - release_mem_region(res->start, SMC_DATA_EXTENT); 2175 + if (res) 2176 + release_mem_region(res->start, SMC_DATA_EXTENT); 2177 + } 2171 2178 } 2172 - #else 2173 - static void smc_request_datacs(struct platform_device *pdev, struct net_device *ndev) {} 2174 - static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev) {} 2175 - #endif 2176 2179 2177 2180 /* 2178 2181 * smc_init(void)
+284 -192
drivers/net/smc91x.h
··· 275 275 #define SMC_insw(a,r,p,l) readsw ((void*) ((a) + (r)), p, l) 276 276 #define SMC_outw(v,a,r) ({ writew ((v), (a) + (r)); LPD7A40X_IOBARRIER; }) 277 277 278 - static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l) 278 + #define SMC_outsw LPD7A40X_SMC_outsw 279 + 280 + static inline void LPD7A40X_SMC_outsw(unsigned long a, int r, 281 + unsigned char* p, int l) 279 282 { 280 283 unsigned short* ps = (unsigned short*) p; 281 284 while (l-- > 0) { ··· 343 340 #define RPC_LSA_DEFAULT RPC_LED_100_10 344 341 #define RPC_LSB_DEFAULT RPC_LED_TX_RX 345 342 346 - #endif 347 - 348 - #ifndef SMC_IRQ_FLAGS 349 - #define SMC_IRQ_FLAGS SA_TRIGGER_RISING 350 343 #endif 351 344 352 345 #ifdef SMC_USE_PXA_DMA ··· 440 441 #endif /* SMC_USE_PXA_DMA */ 441 442 442 443 443 - /* Because of bank switching, the LAN91x uses only 16 I/O ports */ 444 + /* 445 + * Everything a particular hardware setup needs should have been defined 446 + * at this point. Add stubs for the undefined cases, mainly to avoid 447 + * compilation warnings since they'll be optimized away, or to prevent buggy 448 + * use of them. 449 + */ 450 + 451 + #if ! SMC_CAN_USE_32BIT 452 + #define SMC_inl(ioaddr, reg) ({ BUG(); 0; }) 453 + #define SMC_outl(x, ioaddr, reg) BUG() 454 + #define SMC_insl(a, r, p, l) BUG() 455 + #define SMC_outsl(a, r, p, l) BUG() 456 + #endif 457 + 458 + #if !defined(SMC_insl) || !defined(SMC_outsl) 459 + #define SMC_insl(a, r, p, l) BUG() 460 + #define SMC_outsl(a, r, p, l) BUG() 461 + #endif 462 + 463 + #if ! SMC_CAN_USE_16BIT 464 + 465 + /* 466 + * Any 16-bit access is performed with two 8-bit accesses if the hardware 467 + * can't do it directly. Most registers are 16-bit so those are mandatory. 468 + */ 469 + #define SMC_outw(x, ioaddr, reg) \ 470 + do { \ 471 + unsigned int __val16 = (x); \ 472 + SMC_outb( __val16, ioaddr, reg ); \ 473 + SMC_outb( __val16 >> 8, ioaddr, reg + (1 << SMC_IO_SHIFT));\ 474 + } while (0) 475 + #define SMC_inw(ioaddr, reg) \ 476 + ({ \ 477 + unsigned int __val16; \ 478 + __val16 = SMC_inb( ioaddr, reg ); \ 479 + __val16 |= SMC_inb( ioaddr, reg + (1 << SMC_IO_SHIFT)) << 8; \ 480 + __val16; \ 481 + }) 482 + 483 + #define SMC_insw(a, r, p, l) BUG() 484 + #define SMC_outsw(a, r, p, l) BUG() 485 + 486 + #endif 487 + 488 + #if !defined(SMC_insw) || !defined(SMC_outsw) 489 + #define SMC_insw(a, r, p, l) BUG() 490 + #define SMC_outsw(a, r, p, l) BUG() 491 + #endif 492 + 493 + #if ! SMC_CAN_USE_8BIT 494 + #define SMC_inb(ioaddr, reg) ({ BUG(); 0; }) 495 + #define SMC_outb(x, ioaddr, reg) BUG() 496 + #define SMC_insb(a, r, p, l) BUG() 497 + #define SMC_outsb(a, r, p, l) BUG() 498 + #endif 499 + 500 + #if !defined(SMC_insb) || !defined(SMC_outsb) 501 + #define SMC_insb(a, r, p, l) BUG() 502 + #define SMC_outsb(a, r, p, l) BUG() 503 + #endif 504 + 505 + #ifndef SMC_CAN_USE_DATACS 506 + #define SMC_CAN_USE_DATACS 0 507 + #endif 508 + 444 509 #ifndef SMC_IO_SHIFT 445 510 #define SMC_IO_SHIFT 0 446 511 #endif 512 + 513 + #ifndef SMC_IRQ_FLAGS 514 + #define SMC_IRQ_FLAGS SA_TRIGGER_RISING 515 + #endif 516 + 517 + #ifndef SMC_INTERRUPT_PREAMBLE 518 + #define SMC_INTERRUPT_PREAMBLE 519 + #endif 520 + 521 + 522 + /* Because of bank switching, the LAN91x uses only 16 I/O ports */ 447 523 #define SMC_IO_EXTENT (16 << SMC_IO_SHIFT) 448 524 #define SMC_DATA_EXTENT (4) 449 525 ··· 891 817 * Note: the following macros do *not* select the bank -- this must 892 818 * be done separately as needed in the main code. The SMC_REG() macro 893 819 * only uses the bank argument for debugging purposes (when enabled). 820 + * 821 + * Note: despite inline functions being safer, everything leading to this 822 + * should preferably be macros to let BUG() display the line number in 823 + * the core source code since we're interested in the top call site 824 + * not in any inline function location. 894 825 */ 895 826 896 827 #if SMC_DEBUG > 0 ··· 913 834 #define SMC_REG(reg, bank) (reg<<SMC_IO_SHIFT) 914 835 #endif 915 836 916 - #if SMC_CAN_USE_8BIT 917 - #define SMC_GET_PN() SMC_inb( ioaddr, PN_REG ) 918 - #define SMC_SET_PN(x) SMC_outb( x, ioaddr, PN_REG ) 919 - #define SMC_GET_AR() SMC_inb( ioaddr, AR_REG ) 920 - #define SMC_GET_TXFIFO() SMC_inb( ioaddr, TXFIFO_REG ) 921 - #define SMC_GET_RXFIFO() SMC_inb( ioaddr, RXFIFO_REG ) 922 - #define SMC_GET_INT() SMC_inb( ioaddr, INT_REG ) 923 - #define SMC_ACK_INT(x) SMC_outb( x, ioaddr, INT_REG ) 924 - #define SMC_GET_INT_MASK() SMC_inb( ioaddr, IM_REG ) 925 - #define SMC_SET_INT_MASK(x) SMC_outb( x, ioaddr, IM_REG ) 926 - #else 927 - #define SMC_GET_PN() (SMC_inw( ioaddr, PN_REG ) & 0xFF) 928 - #define SMC_SET_PN(x) SMC_outw( x, ioaddr, PN_REG ) 929 - #define SMC_GET_AR() (SMC_inw( ioaddr, PN_REG ) >> 8) 930 - #define SMC_GET_TXFIFO() (SMC_inw( ioaddr, TXFIFO_REG ) & 0xFF) 931 - #define SMC_GET_RXFIFO() (SMC_inw( ioaddr, TXFIFO_REG ) >> 8) 932 - #define SMC_GET_INT() (SMC_inw( ioaddr, INT_REG ) & 0xFF) 837 + /* 838 + * Hack Alert: Some setups just can't write 8 or 16 bits reliably when not 839 + * aligned to a 32 bit boundary. I tell you that does exist! 840 + * Fortunately the affected register accesses can be easily worked around 841 + * since we can write zeroes to the preceeding 16 bits without adverse 842 + * effects and use a 32-bit access. 843 + * 844 + * Enforce it on any 32-bit capable setup for now. 845 + */ 846 + #define SMC_MUST_ALIGN_WRITE SMC_CAN_USE_32BIT 847 + 848 + #define SMC_GET_PN() \ 849 + ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, PN_REG)) \ 850 + : (SMC_inw(ioaddr, PN_REG) & 0xFF) ) 851 + 852 + #define SMC_SET_PN(x) \ 853 + do { \ 854 + if (SMC_MUST_ALIGN_WRITE) \ 855 + SMC_outl((x)<<16, ioaddr, SMC_REG(0, 2)); \ 856 + else if (SMC_CAN_USE_8BIT) \ 857 + SMC_outb(x, ioaddr, PN_REG); \ 858 + else \ 859 + SMC_outw(x, ioaddr, PN_REG); \ 860 + } while (0) 861 + 862 + #define SMC_GET_AR() \ 863 + ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, AR_REG)) \ 864 + : (SMC_inw(ioaddr, PN_REG) >> 8) ) 865 + 866 + #define SMC_GET_TXFIFO() \ 867 + ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, TXFIFO_REG)) \ 868 + : (SMC_inw(ioaddr, TXFIFO_REG) & 0xFF) ) 869 + 870 + #define SMC_GET_RXFIFO() \ 871 + ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, RXFIFO_REG)) \ 872 + : (SMC_inw(ioaddr, TXFIFO_REG) >> 8) ) 873 + 874 + #define SMC_GET_INT() \ 875 + ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, INT_REG)) \ 876 + : (SMC_inw(ioaddr, INT_REG) & 0xFF) ) 877 + 933 878 #define SMC_ACK_INT(x) \ 934 879 do { \ 935 - unsigned long __flags; \ 936 - int __mask; \ 937 - local_irq_save(__flags); \ 938 - __mask = SMC_inw( ioaddr, INT_REG ) & ~0xff; \ 939 - SMC_outw( __mask | (x), ioaddr, INT_REG ); \ 940 - local_irq_restore(__flags); \ 880 + if (SMC_CAN_USE_8BIT) \ 881 + SMC_outb(x, ioaddr, INT_REG); \ 882 + else { \ 883 + unsigned long __flags; \ 884 + int __mask; \ 885 + local_irq_save(__flags); \ 886 + __mask = SMC_inw( ioaddr, INT_REG ) & ~0xff; \ 887 + SMC_outw( __mask | (x), ioaddr, INT_REG ); \ 888 + local_irq_restore(__flags); \ 889 + } \ 941 890 } while (0) 942 - #define SMC_GET_INT_MASK() (SMC_inw( ioaddr, INT_REG ) >> 8) 943 - #define SMC_SET_INT_MASK(x) SMC_outw( (x) << 8, ioaddr, INT_REG ) 944 - #endif 945 891 946 - #define SMC_CURRENT_BANK() SMC_inw( ioaddr, BANK_SELECT ) 947 - #define SMC_SELECT_BANK(x) SMC_outw( x, ioaddr, BANK_SELECT ) 948 - #define SMC_GET_BASE() SMC_inw( ioaddr, BASE_REG ) 949 - #define SMC_SET_BASE(x) SMC_outw( x, ioaddr, BASE_REG ) 950 - #define SMC_GET_CONFIG() SMC_inw( ioaddr, CONFIG_REG ) 951 - #define SMC_SET_CONFIG(x) SMC_outw( x, ioaddr, CONFIG_REG ) 952 - #define SMC_GET_COUNTER() SMC_inw( ioaddr, COUNTER_REG ) 953 - #define SMC_GET_CTL() SMC_inw( ioaddr, CTL_REG ) 954 - #define SMC_SET_CTL(x) SMC_outw( x, ioaddr, CTL_REG ) 955 - #define SMC_GET_MII() SMC_inw( ioaddr, MII_REG ) 956 - #define SMC_SET_MII(x) SMC_outw( x, ioaddr, MII_REG ) 957 - #define SMC_GET_MIR() SMC_inw( ioaddr, MIR_REG ) 958 - #define SMC_SET_MIR(x) SMC_outw( x, ioaddr, MIR_REG ) 959 - #define SMC_GET_MMU_CMD() SMC_inw( ioaddr, MMU_CMD_REG ) 960 - #define SMC_SET_MMU_CMD(x) SMC_outw( x, ioaddr, MMU_CMD_REG ) 961 - #define SMC_GET_FIFO() SMC_inw( ioaddr, FIFO_REG ) 962 - #define SMC_GET_PTR() SMC_inw( ioaddr, PTR_REG ) 963 - #define SMC_SET_PTR(x) SMC_outw( x, ioaddr, PTR_REG ) 964 - #define SMC_GET_EPH_STATUS() SMC_inw( ioaddr, EPH_STATUS_REG ) 965 - #define SMC_GET_RCR() SMC_inw( ioaddr, RCR_REG ) 966 - #define SMC_SET_RCR(x) SMC_outw( x, ioaddr, RCR_REG ) 967 - #define SMC_GET_REV() SMC_inw( ioaddr, REV_REG ) 968 - #define SMC_GET_RPC() SMC_inw( ioaddr, RPC_REG ) 969 - #define SMC_SET_RPC(x) SMC_outw( x, ioaddr, RPC_REG ) 970 - #define SMC_GET_TCR() SMC_inw( ioaddr, TCR_REG ) 971 - #define SMC_SET_TCR(x) SMC_outw( x, ioaddr, TCR_REG ) 892 + #define SMC_GET_INT_MASK() \ 893 + ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, IM_REG)) \ 894 + : (SMC_inw( ioaddr, INT_REG ) >> 8) ) 895 + 896 + #define SMC_SET_INT_MASK(x) \ 897 + do { \ 898 + if (SMC_CAN_USE_8BIT) \ 899 + SMC_outb(x, ioaddr, IM_REG); \ 900 + else \ 901 + SMC_outw((x) << 8, ioaddr, INT_REG); \ 902 + } while (0) 903 + 904 + #define SMC_CURRENT_BANK() SMC_inw(ioaddr, BANK_SELECT) 905 + 906 + #define SMC_SELECT_BANK(x) \ 907 + do { \ 908 + if (SMC_MUST_ALIGN_WRITE) \ 909 + SMC_outl((x)<<16, ioaddr, 12<<SMC_IO_SHIFT); \ 910 + else \ 911 + SMC_outw(x, ioaddr, BANK_SELECT); \ 912 + } while (0) 913 + 914 + #define SMC_GET_BASE() SMC_inw(ioaddr, BASE_REG) 915 + 916 + #define SMC_SET_BASE(x) SMC_outw(x, ioaddr, BASE_REG) 917 + 918 + #define SMC_GET_CONFIG() SMC_inw(ioaddr, CONFIG_REG) 919 + 920 + #define SMC_SET_CONFIG(x) SMC_outw(x, ioaddr, CONFIG_REG) 921 + 922 + #define SMC_GET_COUNTER() SMC_inw(ioaddr, COUNTER_REG) 923 + 924 + #define SMC_GET_CTL() SMC_inw(ioaddr, CTL_REG) 925 + 926 + #define SMC_SET_CTL(x) SMC_outw(x, ioaddr, CTL_REG) 927 + 928 + #define SMC_GET_MII() SMC_inw(ioaddr, MII_REG) 929 + 930 + #define SMC_SET_MII(x) SMC_outw(x, ioaddr, MII_REG) 931 + 932 + #define SMC_GET_MIR() SMC_inw(ioaddr, MIR_REG) 933 + 934 + #define SMC_SET_MIR(x) SMC_outw(x, ioaddr, MIR_REG) 935 + 936 + #define SMC_GET_MMU_CMD() SMC_inw(ioaddr, MMU_CMD_REG) 937 + 938 + #define SMC_SET_MMU_CMD(x) SMC_outw(x, ioaddr, MMU_CMD_REG) 939 + 940 + #define SMC_GET_FIFO() SMC_inw(ioaddr, FIFO_REG) 941 + 942 + #define SMC_GET_PTR() SMC_inw(ioaddr, PTR_REG) 943 + 944 + #define SMC_SET_PTR(x) \ 945 + do { \ 946 + if (SMC_MUST_ALIGN_WRITE) \ 947 + SMC_outl((x)<<16, ioaddr, SMC_REG(4, 2)); \ 948 + else \ 949 + SMC_outw(x, ioaddr, PTR_REG); \ 950 + } while (0) 951 + 952 + #define SMC_GET_EPH_STATUS() SMC_inw(ioaddr, EPH_STATUS_REG) 953 + 954 + #define SMC_GET_RCR() SMC_inw(ioaddr, RCR_REG) 955 + 956 + #define SMC_SET_RCR(x) SMC_outw(x, ioaddr, RCR_REG) 957 + 958 + #define SMC_GET_REV() SMC_inw(ioaddr, REV_REG) 959 + 960 + #define SMC_GET_RPC() SMC_inw(ioaddr, RPC_REG) 961 + 962 + #define SMC_SET_RPC(x) \ 963 + do { \ 964 + if (SMC_MUST_ALIGN_WRITE) \ 965 + SMC_outl((x)<<16, ioaddr, SMC_REG(8, 0)); \ 966 + else \ 967 + SMC_outw(x, ioaddr, RPC_REG); \ 968 + } while (0) 969 + 970 + #define SMC_GET_TCR() SMC_inw(ioaddr, TCR_REG) 971 + 972 + #define SMC_SET_TCR(x) SMC_outw(x, ioaddr, TCR_REG) 972 973 973 974 #ifndef SMC_GET_MAC_ADDR 974 975 #define SMC_GET_MAC_ADDR(addr) \ ··· 1079 920 SMC_outw( mt[6] | (mt[7] << 8), ioaddr, MCAST_REG4 ); \ 1080 921 } while (0) 1081 922 1082 - #if SMC_CAN_USE_32BIT 1083 - /* 1084 - * Some setups just can't write 8 or 16 bits reliably when not aligned 1085 - * to a 32 bit boundary. I tell you that exists! 1086 - * We re-do the ones here that can be easily worked around if they can have 1087 - * their low parts written to 0 without adverse effects. 1088 - */ 1089 - #undef SMC_SELECT_BANK 1090 - #define SMC_SELECT_BANK(x) SMC_outl( (x)<<16, ioaddr, 12<<SMC_IO_SHIFT ) 1091 - #undef SMC_SET_RPC 1092 - #define SMC_SET_RPC(x) SMC_outl( (x)<<16, ioaddr, SMC_REG(8, 0) ) 1093 - #undef SMC_SET_PN 1094 - #define SMC_SET_PN(x) SMC_outl( (x)<<16, ioaddr, SMC_REG(0, 2) ) 1095 - #undef SMC_SET_PTR 1096 - #define SMC_SET_PTR(x) SMC_outl( (x)<<16, ioaddr, SMC_REG(4, 2) ) 1097 - #endif 1098 - 1099 - #if SMC_CAN_USE_32BIT 1100 - #define SMC_PUT_PKT_HDR(status, length) \ 1101 - SMC_outl( (status) | (length) << 16, ioaddr, DATA_REG ) 1102 - #define SMC_GET_PKT_HDR(status, length) \ 1103 - do { \ 1104 - unsigned int __val = SMC_inl( ioaddr, DATA_REG ); \ 1105 - (status) = __val & 0xffff; \ 1106 - (length) = __val >> 16; \ 1107 - } while (0) 1108 - #else 1109 923 #define SMC_PUT_PKT_HDR(status, length) \ 1110 924 do { \ 1111 - SMC_outw( status, ioaddr, DATA_REG ); \ 1112 - SMC_outw( length, ioaddr, DATA_REG ); \ 925 + if (SMC_CAN_USE_32BIT) \ 926 + SMC_outl((status) | (length)<<16, ioaddr, DATA_REG); \ 927 + else { \ 928 + SMC_outw(status, ioaddr, DATA_REG); \ 929 + SMC_outw(length, ioaddr, DATA_REG); \ 930 + } \ 1113 931 } while (0) 932 + 1114 933 #define SMC_GET_PKT_HDR(status, length) \ 1115 934 do { \ 1116 - (status) = SMC_inw( ioaddr, DATA_REG ); \ 1117 - (length) = SMC_inw( ioaddr, DATA_REG ); \ 1118 - } while (0) 1119 - #endif 1120 - 1121 - #if SMC_CAN_USE_32BIT 1122 - #define _SMC_PUSH_DATA(p, l) \ 1123 - do { \ 1124 - char *__ptr = (p); \ 1125 - int __len = (l); \ 1126 - if (__len >= 2 && (unsigned long)__ptr & 2) { \ 1127 - __len -= 2; \ 1128 - SMC_outw( *(u16 *)__ptr, ioaddr, DATA_REG ); \ 1129 - __ptr += 2; \ 1130 - } \ 1131 - SMC_outsl( ioaddr, DATA_REG, __ptr, __len >> 2); \ 1132 - if (__len & 2) { \ 1133 - __ptr += (__len & ~3); \ 1134 - SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \ 935 + if (SMC_CAN_USE_32BIT) { \ 936 + unsigned int __val = SMC_inl(ioaddr, DATA_REG); \ 937 + (status) = __val & 0xffff; \ 938 + (length) = __val >> 16; \ 939 + } else { \ 940 + (status) = SMC_inw(ioaddr, DATA_REG); \ 941 + (length) = SMC_inw(ioaddr, DATA_REG); \ 1135 942 } \ 1136 943 } while (0) 1137 - #define _SMC_PULL_DATA(p, l) \ 1138 - do { \ 1139 - char *__ptr = (p); \ 1140 - int __len = (l); \ 1141 - if ((unsigned long)__ptr & 2) { \ 1142 - /* \ 1143 - * We want 32bit alignment here. \ 1144 - * Since some buses perform a full 32bit \ 1145 - * fetch even for 16bit data we can't use \ 1146 - * SMC_inw() here. Back both source (on chip \ 1147 - * and destination) pointers of 2 bytes. \ 1148 - */ \ 1149 - __ptr -= 2; \ 1150 - __len += 2; \ 1151 - SMC_SET_PTR( 2|PTR_READ|PTR_RCV|PTR_AUTOINC ); \ 1152 - } \ 1153 - __len += 2; \ 1154 - SMC_insl( ioaddr, DATA_REG, __ptr, __len >> 2); \ 1155 - } while (0) 1156 - #elif SMC_CAN_USE_16BIT 1157 - #define _SMC_PUSH_DATA(p, l) SMC_outsw( ioaddr, DATA_REG, p, (l) >> 1 ) 1158 - #define _SMC_PULL_DATA(p, l) SMC_insw ( ioaddr, DATA_REG, p, (l) >> 1 ) 1159 - #elif SMC_CAN_USE_8BIT 1160 - #define _SMC_PUSH_DATA(p, l) SMC_outsb( ioaddr, DATA_REG, p, l ) 1161 - #define _SMC_PULL_DATA(p, l) SMC_insb ( ioaddr, DATA_REG, p, l ) 1162 - #endif 1163 944 1164 - #if ! SMC_CAN_USE_16BIT 1165 - #define SMC_outw(x, ioaddr, reg) \ 1166 - do { \ 1167 - unsigned int __val16 = (x); \ 1168 - SMC_outb( __val16, ioaddr, reg ); \ 1169 - SMC_outb( __val16 >> 8, ioaddr, reg + (1 << SMC_IO_SHIFT));\ 1170 - } while (0) 1171 - #define SMC_inw(ioaddr, reg) \ 1172 - ({ \ 1173 - unsigned int __val16; \ 1174 - __val16 = SMC_inb( ioaddr, reg ); \ 1175 - __val16 |= SMC_inb( ioaddr, reg + (1 << SMC_IO_SHIFT)) << 8; \ 1176 - __val16; \ 1177 - }) 1178 - #endif 1179 - 1180 - #ifdef SMC_CAN_USE_DATACS 1181 945 #define SMC_PUSH_DATA(p, l) \ 1182 - if ( lp->datacs ) { \ 1183 - unsigned char *__ptr = (p); \ 1184 - int __len = (l); \ 1185 - if (__len >= 2 && (unsigned long)__ptr & 2) { \ 1186 - __len -= 2; \ 1187 - SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \ 1188 - __ptr += 2; \ 1189 - } \ 1190 - outsl(lp->datacs, __ptr, __len >> 2); \ 1191 - if (__len & 2) { \ 1192 - __ptr += (__len & ~3); \ 1193 - SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \ 1194 - } \ 1195 - } else { \ 1196 - _SMC_PUSH_DATA(p, l); \ 1197 - } 946 + do { \ 947 + if (SMC_CAN_USE_32BIT) { \ 948 + void *__ptr = (p); \ 949 + int __len = (l); \ 950 + void *__ioaddr = ioaddr; \ 951 + if (__len >= 2 && (unsigned long)__ptr & 2) { \ 952 + __len -= 2; \ 953 + SMC_outw(*(u16 *)__ptr, ioaddr, DATA_REG); \ 954 + __ptr += 2; \ 955 + } \ 956 + if (SMC_CAN_USE_DATACS && lp->datacs) \ 957 + __ioaddr = lp->datacs; \ 958 + SMC_outsl(__ioaddr, DATA_REG, __ptr, __len>>2); \ 959 + if (__len & 2) { \ 960 + __ptr += (__len & ~3); \ 961 + SMC_outw(*((u16 *)__ptr), ioaddr, DATA_REG); \ 962 + } \ 963 + } else if (SMC_CAN_USE_16BIT) \ 964 + SMC_outsw(ioaddr, DATA_REG, p, (l) >> 1); \ 965 + else if (SMC_CAN_USE_8BIT) \ 966 + SMC_outsb(ioaddr, DATA_REG, p, l); \ 967 + } while (0) 1198 968 1199 969 #define SMC_PULL_DATA(p, l) \ 1200 - if ( lp->datacs ) { \ 1201 - unsigned char *__ptr = (p); \ 1202 - int __len = (l); \ 1203 - if ((unsigned long)__ptr & 2) { \ 1204 - /* \ 1205 - * We want 32bit alignment here. \ 1206 - * Since some buses perform a full 32bit \ 1207 - * fetch even for 16bit data we can't use \ 1208 - * SMC_inw() here. Back both source (on chip \ 1209 - * and destination) pointers of 2 bytes. \ 1210 - */ \ 1211 - __ptr -= 2; \ 970 + do { \ 971 + if (SMC_CAN_USE_32BIT) { \ 972 + void *__ptr = (p); \ 973 + int __len = (l); \ 974 + void *__ioaddr = ioaddr; \ 975 + if ((unsigned long)__ptr & 2) { \ 976 + /* \ 977 + * We want 32bit alignment here. \ 978 + * Since some buses perform a full \ 979 + * 32bit fetch even for 16bit data \ 980 + * we can't use SMC_inw() here. \ 981 + * Back both source (on-chip) and \ 982 + * destination pointers of 2 bytes. \ 983 + * This is possible since the call to \ 984 + * SMC_GET_PKT_HDR() already advanced \ 985 + * the source pointer of 4 bytes, and \ 986 + * the skb_reserve(skb, 2) advanced \ 987 + * the destination pointer of 2 bytes. \ 988 + */ \ 989 + __ptr -= 2; \ 990 + __len += 2; \ 991 + SMC_SET_PTR(2|PTR_READ|PTR_RCV|PTR_AUTOINC); \ 992 + } \ 993 + if (SMC_CAN_USE_DATACS && lp->datacs) \ 994 + __ioaddr = lp->datacs; \ 1212 995 __len += 2; \ 1213 - SMC_SET_PTR( 2|PTR_READ|PTR_RCV|PTR_AUTOINC ); \ 1214 - } \ 1215 - __len += 2; \ 1216 - insl( lp->datacs, __ptr, __len >> 2); \ 1217 - } else { \ 1218 - _SMC_PULL_DATA(p, l); \ 1219 - } 1220 - #else 1221 - #define SMC_PUSH_DATA(p, l) _SMC_PUSH_DATA(p, l) 1222 - #define SMC_PULL_DATA(p, l) _SMC_PULL_DATA(p, l) 1223 - #endif 1224 - 1225 - #if !defined (SMC_INTERRUPT_PREAMBLE) 1226 - # define SMC_INTERRUPT_PREAMBLE 1227 - #endif 996 + SMC_insl(__ioaddr, DATA_REG, __ptr, __len>>2); \ 997 + } else if (SMC_CAN_USE_16BIT) \ 998 + SMC_insw(ioaddr, DATA_REG, p, (l) >> 1); \ 999 + else if (SMC_CAN_USE_8BIT) \ 1000 + SMC_insb(ioaddr, DATA_REG, p, l); \ 1001 + } while (0) 1228 1002 1229 1003 #endif /* _SMC91X_H_ */