Commit 09779c6df2dbe95483269d194b327d41fe2cc57e

Authored by Nicolas Pitre
Committed by Jeff Garzik
1 parent ac62ef0435

[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>

Showing 2 changed files with 307 additions and 220 deletions Side-by-side Diff

drivers/net/smc91x.c
... ... @@ -215,15 +215,12 @@
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
... ... @@ -2104,9 +2101,8 @@
2104 2101 * Set the appropriate byte/word mode.
2105 2102 */
2106 2103 ecsr = readb(addr + (ECSR << SMC_IO_SHIFT)) & ~ECSR_IOIS8;
2107   -#ifndef SMC_CAN_USE_16BIT
2108   - ecsr |= ECSR_IOIS8;
2109   -#endif
  2104 + if (!SMC_CAN_USE_16BIT)
  2105 + ecsr |= ECSR_IOIS8;
2110 2106 writeb(ecsr, addr + (ECSR << SMC_IO_SHIFT));
2111 2107 local_irq_restore(flags);
2112 2108  
2113 2109  
2114 2110  
2115 2111  
2116 2112  
2117 2113  
2118 2114  
2119 2115  
2120 2116  
2121 2117  
... ... @@ -2143,40 +2139,39 @@
2143 2139 release_mem_region(res->start, ATTRIB_SIZE);
2144 2140 }
2145 2141  
2146   -#ifdef SMC_CAN_USE_DATACS
2147   -static void smc_request_datacs(struct platform_device *pdev, struct net_device *ndev)
  2142 +static inline void smc_request_datacs(struct platform_device *pdev, struct net_device *ndev)
2148 2143 {
2149   - struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32");
2150   - struct smc_local *lp = netdev_priv(ndev);
  2144 + if (SMC_CAN_USE_DATACS) {
  2145 + struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32");
  2146 + struct smc_local *lp = netdev_priv(ndev);
2151 2147  
2152   - if (!res)
2153   - return;
  2148 + if (!res)
  2149 + return;
2154 2150  
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   - }
  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;
  2154 + }
2159 2155  
2160   - lp->datacs = ioremap(res->start, SMC_DATA_EXTENT);
  2156 + lp->datacs = ioremap(res->start, SMC_DATA_EXTENT);
  2157 + }
2161 2158 }
2162 2159  
2163 2160 static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev)
2164 2161 {
2165   - struct smc_local *lp = netdev_priv(ndev);
2166   - struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32");
  2162 + if (SMC_CAN_USE_DATACS) {
  2163 + struct smc_local *lp = netdev_priv(ndev);
  2164 + struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32");
2167 2165  
2168   - if (lp->datacs)
2169   - iounmap(lp->datacs);
  2166 + if (lp->datacs)
  2167 + iounmap(lp->datacs);
2170 2168  
2171   - lp->datacs = NULL;
  2169 + lp->datacs = NULL;
2172 2170  
2173   - if (res)
2174   - release_mem_region(res->start, SMC_DATA_EXTENT);
  2171 + if (res)
  2172 + release_mem_region(res->start, SMC_DATA_EXTENT);
  2173 + }
2175 2174 }
2176   -#else
2177   -static void smc_request_datacs(struct platform_device *pdev, struct net_device *ndev) {}
2178   -static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev) {}
2179   -#endif
2180 2175  
2181 2176 /*
2182 2177 * smc_init(void)
drivers/net/smc91x.h
... ... @@ -275,7 +275,10 @@
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) {
... ... @@ -342,10 +345,6 @@
342 345  
343 346 #endif
344 347  
345   -#ifndef SMC_IRQ_FLAGS
346   -#define SMC_IRQ_FLAGS SA_TRIGGER_RISING
347   -#endif
348   -
349 348 #ifdef SMC_USE_PXA_DMA
350 349 /*
351 350 * Let's use the DMA engine on the XScale PXA2xx for RX packets. This is
352 351  
... ... @@ -441,10 +440,85 @@
441 440 #endif /* SMC_USE_PXA_DMA */
442 441  
443 442  
444   -/* Because of bank switching, the LAN91x uses only 16 I/O ports */
  443 +/*
  444 + * Everything a particular hardware setup needs should have been defined
  445 + * at this point. Add stubs for the undefined cases, mainly to avoid
  446 + * compilation warnings since they'll be optimized away, or to prevent buggy
  447 + * use of them.
  448 + */
  449 +
  450 +#if ! SMC_CAN_USE_32BIT
  451 +#define SMC_inl(ioaddr, reg) ({ BUG(); 0; })
  452 +#define SMC_outl(x, ioaddr, reg) BUG()
  453 +#define SMC_insl(a, r, p, l) BUG()
  454 +#define SMC_outsl(a, r, p, l) BUG()
  455 +#endif
  456 +
  457 +#if !defined(SMC_insl) || !defined(SMC_outsl)
  458 +#define SMC_insl(a, r, p, l) BUG()
  459 +#define SMC_outsl(a, r, p, l) BUG()
  460 +#endif
  461 +
  462 +#if ! SMC_CAN_USE_16BIT
  463 +
  464 +/*
  465 + * Any 16-bit access is performed with two 8-bit accesses if the hardware
  466 + * can't do it directly. Most registers are 16-bit so those are mandatory.
  467 + */
  468 +#define SMC_outw(x, ioaddr, reg) \
  469 + do { \
  470 + unsigned int __val16 = (x); \
  471 + SMC_outb( __val16, ioaddr, reg ); \
  472 + SMC_outb( __val16 >> 8, ioaddr, reg + (1 << SMC_IO_SHIFT));\
  473 + } while (0)
  474 +#define SMC_inw(ioaddr, reg) \
  475 + ({ \
  476 + unsigned int __val16; \
  477 + __val16 = SMC_inb( ioaddr, reg ); \
  478 + __val16 |= SMC_inb( ioaddr, reg + (1 << SMC_IO_SHIFT)) << 8; \
  479 + __val16; \
  480 + })
  481 +
  482 +#define SMC_insw(a, r, p, l) BUG()
  483 +#define SMC_outsw(a, r, p, l) BUG()
  484 +
  485 +#endif
  486 +
  487 +#if !defined(SMC_insw) || !defined(SMC_outsw)
  488 +#define SMC_insw(a, r, p, l) BUG()
  489 +#define SMC_outsw(a, r, p, l) BUG()
  490 +#endif
  491 +
  492 +#if ! SMC_CAN_USE_8BIT
  493 +#define SMC_inb(ioaddr, reg) ({ BUG(); 0; })
  494 +#define SMC_outb(x, ioaddr, reg) BUG()
  495 +#define SMC_insb(a, r, p, l) BUG()
  496 +#define SMC_outsb(a, r, p, l) BUG()
  497 +#endif
  498 +
  499 +#if !defined(SMC_insb) || !defined(SMC_outsb)
  500 +#define SMC_insb(a, r, p, l) BUG()
  501 +#define SMC_outsb(a, r, p, l) BUG()
  502 +#endif
  503 +
  504 +#ifndef SMC_CAN_USE_DATACS
  505 +#define SMC_CAN_USE_DATACS 0
  506 +#endif
  507 +
445 508 #ifndef SMC_IO_SHIFT
446 509 #define SMC_IO_SHIFT 0
447 510 #endif
  511 +
  512 +#ifndef SMC_IRQ_FLAGS
  513 +#define SMC_IRQ_FLAGS SA_TRIGGER_RISING
  514 +#endif
  515 +
  516 +#ifndef SMC_INTERRUPT_PREAMBLE
  517 +#define SMC_INTERRUPT_PREAMBLE
  518 +#endif
  519 +
  520 +
  521 +/* Because of bank switching, the LAN91x uses only 16 I/O ports */
448 522 #define SMC_IO_EXTENT (16 << SMC_IO_SHIFT)
449 523 #define SMC_DATA_EXTENT (4)
450 524  
... ... @@ -817,6 +891,11 @@
817 891 * Note: the following macros do *not* select the bank -- this must
818 892 * be done separately as needed in the main code. The SMC_REG() macro
819 893 * only uses the bank argument for debugging purposes (when enabled).
  894 + *
  895 + * Note: despite inline functions being safer, everything leading to this
  896 + * should preferably be macros to let BUG() display the line number in
  897 + * the core source code since we're interested in the top call site
  898 + * not in any inline function location.
820 899 */
821 900  
822 901 #if SMC_DEBUG > 0
823 902  
824 903  
825 904  
826 905  
... ... @@ -834,63 +913,143 @@
834 913 #define SMC_REG(reg, bank) (reg<<SMC_IO_SHIFT)
835 914 #endif
836 915  
837   -#if SMC_CAN_USE_8BIT
838   -#define SMC_GET_PN() SMC_inb( ioaddr, PN_REG )
839   -#define SMC_SET_PN(x) SMC_outb( x, ioaddr, PN_REG )
840   -#define SMC_GET_AR() SMC_inb( ioaddr, AR_REG )
841   -#define SMC_GET_TXFIFO() SMC_inb( ioaddr, TXFIFO_REG )
842   -#define SMC_GET_RXFIFO() SMC_inb( ioaddr, RXFIFO_REG )
843   -#define SMC_GET_INT() SMC_inb( ioaddr, INT_REG )
844   -#define SMC_ACK_INT(x) SMC_outb( x, ioaddr, INT_REG )
845   -#define SMC_GET_INT_MASK() SMC_inb( ioaddr, IM_REG )
846   -#define SMC_SET_INT_MASK(x) SMC_outb( x, ioaddr, IM_REG )
847   -#else
848   -#define SMC_GET_PN() (SMC_inw( ioaddr, PN_REG ) & 0xFF)
849   -#define SMC_SET_PN(x) SMC_outw( x, ioaddr, PN_REG )
850   -#define SMC_GET_AR() (SMC_inw( ioaddr, PN_REG ) >> 8)
851   -#define SMC_GET_TXFIFO() (SMC_inw( ioaddr, TXFIFO_REG ) & 0xFF)
852   -#define SMC_GET_RXFIFO() (SMC_inw( ioaddr, TXFIFO_REG ) >> 8)
853   -#define SMC_GET_INT() (SMC_inw( ioaddr, INT_REG ) & 0xFF)
  916 +/*
  917 + * Hack Alert: Some setups just can't write 8 or 16 bits reliably when not
  918 + * aligned to a 32 bit boundary. I tell you that does exist!
  919 + * Fortunately the affected register accesses can be easily worked around
  920 + * since we can write zeroes to the preceeding 16 bits without adverse
  921 + * effects and use a 32-bit access.
  922 + *
  923 + * Enforce it on any 32-bit capable setup for now.
  924 + */
  925 +#define SMC_MUST_ALIGN_WRITE SMC_CAN_USE_32BIT
  926 +
  927 +#define SMC_GET_PN() \
  928 + ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, PN_REG)) \
  929 + : (SMC_inw(ioaddr, PN_REG) & 0xFF) )
  930 +
  931 +#define SMC_SET_PN(x) \
  932 + do { \
  933 + if (SMC_MUST_ALIGN_WRITE) \
  934 + SMC_outl((x)<<16, ioaddr, SMC_REG(0, 2)); \
  935 + else if (SMC_CAN_USE_8BIT) \
  936 + SMC_outb(x, ioaddr, PN_REG); \
  937 + else \
  938 + SMC_outw(x, ioaddr, PN_REG); \
  939 + } while (0)
  940 +
  941 +#define SMC_GET_AR() \
  942 + ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, AR_REG)) \
  943 + : (SMC_inw(ioaddr, PN_REG) >> 8) )
  944 +
  945 +#define SMC_GET_TXFIFO() \
  946 + ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, TXFIFO_REG)) \
  947 + : (SMC_inw(ioaddr, TXFIFO_REG) & 0xFF) )
  948 +
  949 +#define SMC_GET_RXFIFO() \
  950 + ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, RXFIFO_REG)) \
  951 + : (SMC_inw(ioaddr, TXFIFO_REG) >> 8) )
  952 +
  953 +#define SMC_GET_INT() \
  954 + ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, INT_REG)) \
  955 + : (SMC_inw(ioaddr, INT_REG) & 0xFF) )
  956 +
854 957 #define SMC_ACK_INT(x) \
855 958 do { \
856   - unsigned long __flags; \
857   - int __mask; \
858   - local_irq_save(__flags); \
859   - __mask = SMC_inw( ioaddr, INT_REG ) & ~0xff; \
860   - SMC_outw( __mask | (x), ioaddr, INT_REG ); \
861   - local_irq_restore(__flags); \
  959 + if (SMC_CAN_USE_8BIT) \
  960 + SMC_outb(x, ioaddr, INT_REG); \
  961 + else { \
  962 + unsigned long __flags; \
  963 + int __mask; \
  964 + local_irq_save(__flags); \
  965 + __mask = SMC_inw( ioaddr, INT_REG ) & ~0xff; \
  966 + SMC_outw( __mask | (x), ioaddr, INT_REG ); \
  967 + local_irq_restore(__flags); \
  968 + } \
862 969 } while (0)
863   -#define SMC_GET_INT_MASK() (SMC_inw( ioaddr, INT_REG ) >> 8)
864   -#define SMC_SET_INT_MASK(x) SMC_outw( (x) << 8, ioaddr, INT_REG )
865   -#endif
866 970  
867   -#define SMC_CURRENT_BANK() SMC_inw( ioaddr, BANK_SELECT )
868   -#define SMC_SELECT_BANK(x) SMC_outw( x, ioaddr, BANK_SELECT )
869   -#define SMC_GET_BASE() SMC_inw( ioaddr, BASE_REG )
870   -#define SMC_SET_BASE(x) SMC_outw( x, ioaddr, BASE_REG )
871   -#define SMC_GET_CONFIG() SMC_inw( ioaddr, CONFIG_REG )
872   -#define SMC_SET_CONFIG(x) SMC_outw( x, ioaddr, CONFIG_REG )
873   -#define SMC_GET_COUNTER() SMC_inw( ioaddr, COUNTER_REG )
874   -#define SMC_GET_CTL() SMC_inw( ioaddr, CTL_REG )
875   -#define SMC_SET_CTL(x) SMC_outw( x, ioaddr, CTL_REG )
876   -#define SMC_GET_MII() SMC_inw( ioaddr, MII_REG )
877   -#define SMC_SET_MII(x) SMC_outw( x, ioaddr, MII_REG )
878   -#define SMC_GET_MIR() SMC_inw( ioaddr, MIR_REG )
879   -#define SMC_SET_MIR(x) SMC_outw( x, ioaddr, MIR_REG )
880   -#define SMC_GET_MMU_CMD() SMC_inw( ioaddr, MMU_CMD_REG )
881   -#define SMC_SET_MMU_CMD(x) SMC_outw( x, ioaddr, MMU_CMD_REG )
882   -#define SMC_GET_FIFO() SMC_inw( ioaddr, FIFO_REG )
883   -#define SMC_GET_PTR() SMC_inw( ioaddr, PTR_REG )
884   -#define SMC_SET_PTR(x) SMC_outw( x, ioaddr, PTR_REG )
885   -#define SMC_GET_EPH_STATUS() SMC_inw( ioaddr, EPH_STATUS_REG )
886   -#define SMC_GET_RCR() SMC_inw( ioaddr, RCR_REG )
887   -#define SMC_SET_RCR(x) SMC_outw( x, ioaddr, RCR_REG )
888   -#define SMC_GET_REV() SMC_inw( ioaddr, REV_REG )
889   -#define SMC_GET_RPC() SMC_inw( ioaddr, RPC_REG )
890   -#define SMC_SET_RPC(x) SMC_outw( x, ioaddr, RPC_REG )
891   -#define SMC_GET_TCR() SMC_inw( ioaddr, TCR_REG )
892   -#define SMC_SET_TCR(x) SMC_outw( x, ioaddr, TCR_REG )
  971 +#define SMC_GET_INT_MASK() \
  972 + ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, IM_REG)) \
  973 + : (SMC_inw( ioaddr, INT_REG ) >> 8) )
893 974  
  975 +#define SMC_SET_INT_MASK(x) \
  976 + do { \
  977 + if (SMC_CAN_USE_8BIT) \
  978 + SMC_outb(x, ioaddr, IM_REG); \
  979 + else \
  980 + SMC_outw((x) << 8, ioaddr, INT_REG); \
  981 + } while (0)
  982 +
  983 +#define SMC_CURRENT_BANK() SMC_inw(ioaddr, BANK_SELECT)
  984 +
  985 +#define SMC_SELECT_BANK(x) \
  986 + do { \
  987 + if (SMC_MUST_ALIGN_WRITE) \
  988 + SMC_outl((x)<<16, ioaddr, 12<<SMC_IO_SHIFT); \
  989 + else \
  990 + SMC_outw(x, ioaddr, BANK_SELECT); \
  991 + } while (0)
  992 +
  993 +#define SMC_GET_BASE() SMC_inw(ioaddr, BASE_REG)
  994 +
  995 +#define SMC_SET_BASE(x) SMC_outw(x, ioaddr, BASE_REG)
  996 +
  997 +#define SMC_GET_CONFIG() SMC_inw(ioaddr, CONFIG_REG)
  998 +
  999 +#define SMC_SET_CONFIG(x) SMC_outw(x, ioaddr, CONFIG_REG)
  1000 +
  1001 +#define SMC_GET_COUNTER() SMC_inw(ioaddr, COUNTER_REG)
  1002 +
  1003 +#define SMC_GET_CTL() SMC_inw(ioaddr, CTL_REG)
  1004 +
  1005 +#define SMC_SET_CTL(x) SMC_outw(x, ioaddr, CTL_REG)
  1006 +
  1007 +#define SMC_GET_MII() SMC_inw(ioaddr, MII_REG)
  1008 +
  1009 +#define SMC_SET_MII(x) SMC_outw(x, ioaddr, MII_REG)
  1010 +
  1011 +#define SMC_GET_MIR() SMC_inw(ioaddr, MIR_REG)
  1012 +
  1013 +#define SMC_SET_MIR(x) SMC_outw(x, ioaddr, MIR_REG)
  1014 +
  1015 +#define SMC_GET_MMU_CMD() SMC_inw(ioaddr, MMU_CMD_REG)
  1016 +
  1017 +#define SMC_SET_MMU_CMD(x) SMC_outw(x, ioaddr, MMU_CMD_REG)
  1018 +
  1019 +#define SMC_GET_FIFO() SMC_inw(ioaddr, FIFO_REG)
  1020 +
  1021 +#define SMC_GET_PTR() SMC_inw(ioaddr, PTR_REG)
  1022 +
  1023 +#define SMC_SET_PTR(x) \
  1024 + do { \
  1025 + if (SMC_MUST_ALIGN_WRITE) \
  1026 + SMC_outl((x)<<16, ioaddr, SMC_REG(4, 2)); \
  1027 + else \
  1028 + SMC_outw(x, ioaddr, PTR_REG); \
  1029 + } while (0)
  1030 +
  1031 +#define SMC_GET_EPH_STATUS() SMC_inw(ioaddr, EPH_STATUS_REG)
  1032 +
  1033 +#define SMC_GET_RCR() SMC_inw(ioaddr, RCR_REG)
  1034 +
  1035 +#define SMC_SET_RCR(x) SMC_outw(x, ioaddr, RCR_REG)
  1036 +
  1037 +#define SMC_GET_REV() SMC_inw(ioaddr, REV_REG)
  1038 +
  1039 +#define SMC_GET_RPC() SMC_inw(ioaddr, RPC_REG)
  1040 +
  1041 +#define SMC_SET_RPC(x) \
  1042 + do { \
  1043 + if (SMC_MUST_ALIGN_WRITE) \
  1044 + SMC_outl((x)<<16, ioaddr, SMC_REG(8, 0)); \
  1045 + else \
  1046 + SMC_outw(x, ioaddr, RPC_REG); \
  1047 + } while (0)
  1048 +
  1049 +#define SMC_GET_TCR() SMC_inw(ioaddr, TCR_REG)
  1050 +
  1051 +#define SMC_SET_TCR(x) SMC_outw(x, ioaddr, TCR_REG)
  1052 +
894 1053 #ifndef SMC_GET_MAC_ADDR
895 1054 #define SMC_GET_MAC_ADDR(addr) \
896 1055 do { \
897 1056  
898 1057  
899 1058  
900 1059  
901 1060  
902 1061  
903 1062  
904 1063  
905 1064  
906 1065  
907 1066  
908 1067  
... ... @@ -920,152 +1079,85 @@
920 1079 SMC_outw( mt[6] | (mt[7] << 8), ioaddr, MCAST_REG4 ); \
921 1080 } while (0)
922 1081  
923   -#if SMC_CAN_USE_32BIT
924   -/*
925   - * Some setups just can't write 8 or 16 bits reliably when not aligned
926   - * to a 32 bit boundary. I tell you that exists!
927   - * We re-do the ones here that can be easily worked around if they can have
928   - * their low parts written to 0 without adverse effects.
929   - */
930   -#undef SMC_SELECT_BANK
931   -#define SMC_SELECT_BANK(x) SMC_outl( (x)<<16, ioaddr, 12<<SMC_IO_SHIFT )
932   -#undef SMC_SET_RPC
933   -#define SMC_SET_RPC(x) SMC_outl( (x)<<16, ioaddr, SMC_REG(8, 0) )
934   -#undef SMC_SET_PN
935   -#define SMC_SET_PN(x) SMC_outl( (x)<<16, ioaddr, SMC_REG(0, 2) )
936   -#undef SMC_SET_PTR
937   -#define SMC_SET_PTR(x) SMC_outl( (x)<<16, ioaddr, SMC_REG(4, 2) )
938   -#endif
939   -
940   -#if SMC_CAN_USE_32BIT
941 1082 #define SMC_PUT_PKT_HDR(status, length) \
942   - SMC_outl( (status) | (length) << 16, ioaddr, DATA_REG )
943   -#define SMC_GET_PKT_HDR(status, length) \
944 1083 do { \
945   - unsigned int __val = SMC_inl( ioaddr, DATA_REG ); \
946   - (status) = __val & 0xffff; \
947   - (length) = __val >> 16; \
  1084 + if (SMC_CAN_USE_32BIT) \
  1085 + SMC_outl((status) | (length)<<16, ioaddr, DATA_REG); \
  1086 + else { \
  1087 + SMC_outw(status, ioaddr, DATA_REG); \
  1088 + SMC_outw(length, ioaddr, DATA_REG); \
  1089 + } \
948 1090 } while (0)
949   -#else
950   -#define SMC_PUT_PKT_HDR(status, length) \
951   - do { \
952   - SMC_outw( status, ioaddr, DATA_REG ); \
953   - SMC_outw( length, ioaddr, DATA_REG ); \
954   - } while (0)
  1091 +
955 1092 #define SMC_GET_PKT_HDR(status, length) \
956 1093 do { \
957   - (status) = SMC_inw( ioaddr, DATA_REG ); \
958   - (length) = SMC_inw( ioaddr, DATA_REG ); \
959   - } while (0)
960   -#endif
961   -
962   -#if SMC_CAN_USE_32BIT
963   -#define _SMC_PUSH_DATA(p, l) \
964   - do { \
965   - char *__ptr = (p); \
966   - int __len = (l); \
967   - if (__len >= 2 && (unsigned long)__ptr & 2) { \
968   - __len -= 2; \
969   - SMC_outw( *(u16 *)__ptr, ioaddr, DATA_REG ); \
970   - __ptr += 2; \
  1094 + if (SMC_CAN_USE_32BIT) { \
  1095 + unsigned int __val = SMC_inl(ioaddr, DATA_REG); \
  1096 + (status) = __val & 0xffff; \
  1097 + (length) = __val >> 16; \
  1098 + } else { \
  1099 + (status) = SMC_inw(ioaddr, DATA_REG); \
  1100 + (length) = SMC_inw(ioaddr, DATA_REG); \
971 1101 } \
972   - SMC_outsl( ioaddr, DATA_REG, __ptr, __len >> 2); \
973   - if (__len & 2) { \
974   - __ptr += (__len & ~3); \
975   - SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \
976   - } \
977 1102 } while (0)
978   -#define _SMC_PULL_DATA(p, l) \
979   - do { \
980   - char *__ptr = (p); \
981   - int __len = (l); \
982   - if ((unsigned long)__ptr & 2) { \
983   - /* \
984   - * We want 32bit alignment here. \
985   - * Since some buses perform a full 32bit \
986   - * fetch even for 16bit data we can't use \
987   - * SMC_inw() here. Back both source (on chip \
988   - * and destination) pointers of 2 bytes. \
989   - */ \
990   - __ptr -= 2; \
991   - __len += 2; \
992   - SMC_SET_PTR( 2|PTR_READ|PTR_RCV|PTR_AUTOINC ); \
993   - } \
994   - __len += 2; \
995   - SMC_insl( ioaddr, DATA_REG, __ptr, __len >> 2); \
996   - } while (0)
997   -#elif SMC_CAN_USE_16BIT
998   -#define _SMC_PUSH_DATA(p, l) SMC_outsw( ioaddr, DATA_REG, p, (l) >> 1 )
999   -#define _SMC_PULL_DATA(p, l) SMC_insw ( ioaddr, DATA_REG, p, (l) >> 1 )
1000   -#elif SMC_CAN_USE_8BIT
1001   -#define _SMC_PUSH_DATA(p, l) SMC_outsb( ioaddr, DATA_REG, p, l )
1002   -#define _SMC_PULL_DATA(p, l) SMC_insb ( ioaddr, DATA_REG, p, l )
1003   -#endif
1004 1103  
1005   -#if ! SMC_CAN_USE_16BIT
1006   -#define SMC_outw(x, ioaddr, reg) \
  1104 +#define SMC_PUSH_DATA(p, l) \
1007 1105 do { \
1008   - unsigned int __val16 = (x); \
1009   - SMC_outb( __val16, ioaddr, reg ); \
1010   - SMC_outb( __val16 >> 8, ioaddr, reg + (1 << SMC_IO_SHIFT));\
  1106 + if (SMC_CAN_USE_32BIT) { \
  1107 + void *__ptr = (p); \
  1108 + int __len = (l); \
  1109 + void *__ioaddr = ioaddr; \
  1110 + if (__len >= 2 && (unsigned long)__ptr & 2) { \
  1111 + __len -= 2; \
  1112 + SMC_outw(*(u16 *)__ptr, ioaddr, DATA_REG); \
  1113 + __ptr += 2; \
  1114 + } \
  1115 + if (SMC_CAN_USE_DATACS && lp->datacs) \
  1116 + __ioaddr = lp->datacs; \
  1117 + SMC_outsl(__ioaddr, DATA_REG, __ptr, __len>>2); \
  1118 + if (__len & 2) { \
  1119 + __ptr += (__len & ~3); \
  1120 + SMC_outw(*((u16 *)__ptr), ioaddr, DATA_REG); \
  1121 + } \
  1122 + } else if (SMC_CAN_USE_16BIT) \
  1123 + SMC_outsw(ioaddr, DATA_REG, p, (l) >> 1); \
  1124 + else if (SMC_CAN_USE_8BIT) \
  1125 + SMC_outsb(ioaddr, DATA_REG, p, l); \
1011 1126 } while (0)
1012   -#define SMC_inw(ioaddr, reg) \
1013   - ({ \
1014   - unsigned int __val16; \
1015   - __val16 = SMC_inb( ioaddr, reg ); \
1016   - __val16 |= SMC_inb( ioaddr, reg + (1 << SMC_IO_SHIFT)) << 8; \
1017   - __val16; \
1018   - })
1019   -#endif
1020 1127  
1021   -#ifdef SMC_CAN_USE_DATACS
1022   -#define SMC_PUSH_DATA(p, l) \
1023   - if ( lp->datacs ) { \
1024   - unsigned char *__ptr = (p); \
1025   - int __len = (l); \
1026   - if (__len >= 2 && (unsigned long)__ptr & 2) { \
1027   - __len -= 2; \
1028   - SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \
1029   - __ptr += 2; \
1030   - } \
1031   - outsl(lp->datacs, __ptr, __len >> 2); \
1032   - if (__len & 2) { \
1033   - __ptr += (__len & ~3); \
1034   - SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \
1035   - } \
1036   - } else { \
1037   - _SMC_PUSH_DATA(p, l); \
1038   - }
1039   -
1040 1128 #define SMC_PULL_DATA(p, l) \
1041   - if ( lp->datacs ) { \
1042   - unsigned char *__ptr = (p); \
1043   - int __len = (l); \
1044   - if ((unsigned long)__ptr & 2) { \
1045   - /* \
1046   - * We want 32bit alignment here. \
1047   - * Since some buses perform a full 32bit \
1048   - * fetch even for 16bit data we can't use \
1049   - * SMC_inw() here. Back both source (on chip \
1050   - * and destination) pointers of 2 bytes. \
1051   - */ \
1052   - __ptr -= 2; \
  1129 + do { \
  1130 + if (SMC_CAN_USE_32BIT) { \
  1131 + void *__ptr = (p); \
  1132 + int __len = (l); \
  1133 + void *__ioaddr = ioaddr; \
  1134 + if ((unsigned long)__ptr & 2) { \
  1135 + /* \
  1136 + * We want 32bit alignment here. \
  1137 + * Since some buses perform a full \
  1138 + * 32bit fetch even for 16bit data \
  1139 + * we can't use SMC_inw() here. \
  1140 + * Back both source (on-chip) and \
  1141 + * destination pointers of 2 bytes. \
  1142 + * This is possible since the call to \
  1143 + * SMC_GET_PKT_HDR() already advanced \
  1144 + * the source pointer of 4 bytes, and \
  1145 + * the skb_reserve(skb, 2) advanced \
  1146 + * the destination pointer of 2 bytes. \
  1147 + */ \
  1148 + __ptr -= 2; \
  1149 + __len += 2; \
  1150 + SMC_SET_PTR(2|PTR_READ|PTR_RCV|PTR_AUTOINC); \
  1151 + } \
  1152 + if (SMC_CAN_USE_DATACS && lp->datacs) \
  1153 + __ioaddr = lp->datacs; \
1053 1154 __len += 2; \
1054   - SMC_SET_PTR( 2|PTR_READ|PTR_RCV|PTR_AUTOINC ); \
1055   - } \
1056   - __len += 2; \
1057   - insl( lp->datacs, __ptr, __len >> 2); \
1058   - } else { \
1059   - _SMC_PULL_DATA(p, l); \
1060   - }
1061   -#else
1062   -#define SMC_PUSH_DATA(p, l) _SMC_PUSH_DATA(p, l)
1063   -#define SMC_PULL_DATA(p, l) _SMC_PULL_DATA(p, l)
1064   -#endif
1065   -
1066   -#if !defined (SMC_INTERRUPT_PREAMBLE)
1067   -# define SMC_INTERRUPT_PREAMBLE
1068   -#endif
  1155 + SMC_insl(__ioaddr, DATA_REG, __ptr, __len>>2); \
  1156 + } else if (SMC_CAN_USE_16BIT) \
  1157 + SMC_insw(ioaddr, DATA_REG, p, (l) >> 1); \
  1158 + else if (SMC_CAN_USE_8BIT) \
  1159 + SMC_insb(ioaddr, DATA_REG, p, l); \
  1160 + } while (0)
1069 1161  
1070 1162 #endif /* _SMC91X_H_ */