aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2006-03-20 11:54:27 -0500
committerJeff Garzik <jeff@garzik.org>2006-03-21 16:00:53 -0500
commit09779c6df2dbe95483269d194b327d41fe2cc57e (patch)
tree9ee7873eb248481bd06f73fdda79c019292c0e26 /drivers/net
parentac62ef043504d5c754357325cd514553ddabb046 (diff)
[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>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/smc91x.c53
-rw-r--r--drivers/net/smc91x.h474
2 files changed, 307 insertions, 220 deletions
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 75e9b3b910c..0e9833adf9f 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -215,15 +215,12 @@ struct smc_local {
215 215
216 spinlock_t lock; 216 spinlock_t lock;
217 217
218#ifdef SMC_CAN_USE_DATACS
219 u32 __iomem *datacs;
220#endif
221
222#ifdef SMC_USE_PXA_DMA 218#ifdef SMC_USE_PXA_DMA
223 /* DMA needs the physical address of the chip */ 219 /* DMA needs the physical address of the chip */
224 u_long physaddr; 220 u_long physaddr;
225#endif 221#endif
226 void __iomem *base; 222 void __iomem *base;
223 void __iomem *datacs;
227}; 224};
228 225
229#if SMC_DEBUG > 0 226#if SMC_DEBUG > 0
@@ -2104,9 +2101,8 @@ static int smc_enable_device(struct platform_device *pdev)
2104 * Set the appropriate byte/word mode. 2101 * Set the appropriate byte/word mode.
2105 */ 2102 */
2106 ecsr = readb(addr + (ECSR << SMC_IO_SHIFT)) & ~ECSR_IOIS8; 2103 ecsr = readb(addr + (ECSR << SMC_IO_SHIFT)) & ~ECSR_IOIS8;
2107#ifndef SMC_CAN_USE_16BIT 2104 if (!SMC_CAN_USE_16BIT)
2108 ecsr |= ECSR_IOIS8; 2105 ecsr |= ECSR_IOIS8;
2109#endif
2110 writeb(ecsr, addr + (ECSR << SMC_IO_SHIFT)); 2106 writeb(ecsr, addr + (ECSR << SMC_IO_SHIFT));
2111 local_irq_restore(flags); 2107 local_irq_restore(flags);
2112 2108
@@ -2143,40 +2139,39 @@ static void smc_release_attrib(struct platform_device *pdev)
2143 release_mem_region(res->start, ATTRIB_SIZE); 2139 release_mem_region(res->start, ATTRIB_SIZE);
2144} 2140}
2145 2141
2146#ifdef SMC_CAN_USE_DATACS 2142static inline void smc_request_datacs(struct platform_device *pdev, struct net_device *ndev)
2147static 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"); 2144 if (SMC_CAN_USE_DATACS) {
2150 struct smc_local *lp = netdev_priv(ndev); 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) 2148 if (!res)
2153 return; 2149 return;
2154 2150
2155 if(!request_mem_region(res->start, SMC_DATA_EXTENT, CARDNAME)) { 2151 if(!request_mem_region(res->start, SMC_DATA_EXTENT, CARDNAME)) {
2156 printk(KERN_INFO "%s: failed to request datacs memory region.\n", CARDNAME); 2152 printk(KERN_INFO "%s: failed to request datacs memory region.\n", CARDNAME);
2157 return; 2153 return;
2158 } 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
2163static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev) 2160static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev)
2164{ 2161{
2165 struct smc_local *lp = netdev_priv(ndev); 2162 if (SMC_CAN_USE_DATACS) {
2166 struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32"); 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) 2166 if (lp->datacs)
2169 iounmap(lp->datacs); 2167 iounmap(lp->datacs);
2170 2168
2171 lp->datacs = NULL; 2169 lp->datacs = NULL;
2172 2170
2173 if (res) 2171 if (res)
2174 release_mem_region(res->start, SMC_DATA_EXTENT); 2172 release_mem_region(res->start, SMC_DATA_EXTENT);
2173 }
2175} 2174}
2176#else
2177static void smc_request_datacs(struct platform_device *pdev, struct net_device *ndev) {}
2178static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev) {}
2179#endif
2180 2175
2181/* 2176/*
2182 * smc_init(void) 2177 * smc_init(void)
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index e0efd1964e7..e1be1af5120 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -275,7 +275,10 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
275#define SMC_insw(a,r,p,l) readsw ((void*) ((a) + (r)), p, l) 275#define SMC_insw(a,r,p,l) readsw ((void*) ((a) + (r)), p, l)
276#define SMC_outw(v,a,r) ({ writew ((v), (a) + (r)); LPD7A40X_IOBARRIER; }) 276#define SMC_outw(v,a,r) ({ writew ((v), (a) + (r)); LPD7A40X_IOBARRIER; })
277 277
278static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l) 278#define SMC_outsw LPD7A40X_SMC_outsw
279
280static inline void LPD7A40X_SMC_outsw(unsigned long a, int r,
281 unsigned char* p, int l)
279{ 282{
280 unsigned short* ps = (unsigned short*) p; 283 unsigned short* ps = (unsigned short*) p;
281 while (l-- > 0) { 284 while (l-- > 0) {
@@ -342,10 +345,6 @@ static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l)
342 345
343#endif 346#endif
344 347
345#ifndef SMC_IRQ_FLAGS
346#define SMC_IRQ_FLAGS SA_TRIGGER_RISING
347#endif
348
349#ifdef SMC_USE_PXA_DMA 348#ifdef SMC_USE_PXA_DMA
350/* 349/*
351 * Let's use the DMA engine on the XScale PXA2xx for RX packets. This is 350 * Let's use the DMA engine on the XScale PXA2xx for RX packets. This is
@@ -441,10 +440,85 @@ smc_pxa_dma_irq(int dma, void *dummy, struct pt_regs *regs)
441#endif /* SMC_USE_PXA_DMA */ 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#ifndef SMC_IO_SHIFT 508#ifndef SMC_IO_SHIFT
446#define SMC_IO_SHIFT 0 509#define SMC_IO_SHIFT 0
447#endif 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#define SMC_IO_EXTENT (16 << SMC_IO_SHIFT) 522#define SMC_IO_EXTENT (16 << SMC_IO_SHIFT)
449#define SMC_DATA_EXTENT (4) 523#define SMC_DATA_EXTENT (4)
450 524
@@ -817,6 +891,11 @@ static const char * chip_ids[ 16 ] = {
817 * Note: the following macros do *not* select the bank -- this must 891 * Note: the following macros do *not* select the bank -- this must
818 * be done separately as needed in the main code. The SMC_REG() macro 892 * be done separately as needed in the main code. The SMC_REG() macro
819 * only uses the bank argument for debugging purposes (when enabled). 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#if SMC_DEBUG > 0 901#if SMC_DEBUG > 0
@@ -834,62 +913,142 @@ static const char * chip_ids[ 16 ] = {
834#define SMC_REG(reg, bank) (reg<<SMC_IO_SHIFT) 913#define SMC_REG(reg, bank) (reg<<SMC_IO_SHIFT)
835#endif 914#endif
836 915
837#if SMC_CAN_USE_8BIT 916/*
838#define SMC_GET_PN() SMC_inb( ioaddr, PN_REG ) 917 * Hack Alert: Some setups just can't write 8 or 16 bits reliably when not
839#define SMC_SET_PN(x) SMC_outb( x, ioaddr, PN_REG ) 918 * aligned to a 32 bit boundary. I tell you that does exist!
840#define SMC_GET_AR() SMC_inb( ioaddr, AR_REG ) 919 * Fortunately the affected register accesses can be easily worked around
841#define SMC_GET_TXFIFO() SMC_inb( ioaddr, TXFIFO_REG ) 920 * since we can write zeroes to the preceeding 16 bits without adverse
842#define SMC_GET_RXFIFO() SMC_inb( ioaddr, RXFIFO_REG ) 921 * effects and use a 32-bit access.
843#define SMC_GET_INT() SMC_inb( ioaddr, INT_REG ) 922 *
844#define SMC_ACK_INT(x) SMC_outb( x, ioaddr, INT_REG ) 923 * Enforce it on any 32-bit capable setup for now.
845#define SMC_GET_INT_MASK() SMC_inb( ioaddr, IM_REG ) 924 */
846#define SMC_SET_INT_MASK(x) SMC_outb( x, ioaddr, IM_REG ) 925#define SMC_MUST_ALIGN_WRITE SMC_CAN_USE_32BIT
847#else 926
848#define SMC_GET_PN() (SMC_inw( ioaddr, PN_REG ) & 0xFF) 927#define SMC_GET_PN() \
849#define SMC_SET_PN(x) SMC_outw( x, ioaddr, PN_REG ) 928 ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, PN_REG)) \
850#define SMC_GET_AR() (SMC_inw( ioaddr, PN_REG ) >> 8) 929 : (SMC_inw(ioaddr, PN_REG) & 0xFF) )
851#define SMC_GET_TXFIFO() (SMC_inw( ioaddr, TXFIFO_REG ) & 0xFF) 930
852#define SMC_GET_RXFIFO() (SMC_inw( ioaddr, TXFIFO_REG ) >> 8) 931#define SMC_SET_PN(x) \
853#define SMC_GET_INT() (SMC_inw( ioaddr, INT_REG ) & 0xFF) 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#define SMC_ACK_INT(x) \ 957#define SMC_ACK_INT(x) \
855 do { \ 958 do { \
856 unsigned long __flags; \ 959 if (SMC_CAN_USE_8BIT) \
857 int __mask; \ 960 SMC_outb(x, ioaddr, INT_REG); \
858 local_irq_save(__flags); \ 961 else { \
859 __mask = SMC_inw( ioaddr, INT_REG ) & ~0xff; \ 962 unsigned long __flags; \
860 SMC_outw( __mask | (x), ioaddr, INT_REG ); \ 963 int __mask; \
861 local_irq_restore(__flags); \ 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 } \
969 } while (0)
970
971#define SMC_GET_INT_MASK() \
972 ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, IM_REG)) \
973 : (SMC_inw( ioaddr, INT_REG ) >> 8) )
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); \
862 } while (0) 1029 } 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 1030
867#define SMC_CURRENT_BANK() SMC_inw( ioaddr, BANK_SELECT ) 1031#define SMC_GET_EPH_STATUS() SMC_inw(ioaddr, EPH_STATUS_REG)
868#define SMC_SELECT_BANK(x) SMC_outw( x, ioaddr, BANK_SELECT ) 1032
869#define SMC_GET_BASE() SMC_inw( ioaddr, BASE_REG ) 1033#define SMC_GET_RCR() SMC_inw(ioaddr, RCR_REG)
870#define SMC_SET_BASE(x) SMC_outw( x, ioaddr, BASE_REG ) 1034
871#define SMC_GET_CONFIG() SMC_inw( ioaddr, CONFIG_REG ) 1035#define SMC_SET_RCR(x) SMC_outw(x, ioaddr, RCR_REG)
872#define SMC_SET_CONFIG(x) SMC_outw( x, ioaddr, CONFIG_REG ) 1036
873#define SMC_GET_COUNTER() SMC_inw( ioaddr, COUNTER_REG ) 1037#define SMC_GET_REV() SMC_inw(ioaddr, REV_REG)
874#define SMC_GET_CTL() SMC_inw( ioaddr, CTL_REG ) 1038
875#define SMC_SET_CTL(x) SMC_outw( x, ioaddr, CTL_REG ) 1039#define SMC_GET_RPC() SMC_inw(ioaddr, RPC_REG)
876#define SMC_GET_MII() SMC_inw( ioaddr, MII_REG ) 1040
877#define SMC_SET_MII(x) SMC_outw( x, ioaddr, MII_REG ) 1041#define SMC_SET_RPC(x) \
878#define SMC_GET_MIR() SMC_inw( ioaddr, MIR_REG ) 1042 do { \
879#define SMC_SET_MIR(x) SMC_outw( x, ioaddr, MIR_REG ) 1043 if (SMC_MUST_ALIGN_WRITE) \
880#define SMC_GET_MMU_CMD() SMC_inw( ioaddr, MMU_CMD_REG ) 1044 SMC_outl((x)<<16, ioaddr, SMC_REG(8, 0)); \
881#define SMC_SET_MMU_CMD(x) SMC_outw( x, ioaddr, MMU_CMD_REG ) 1045 else \
882#define SMC_GET_FIFO() SMC_inw( ioaddr, FIFO_REG ) 1046 SMC_outw(x, ioaddr, RPC_REG); \
883#define SMC_GET_PTR() SMC_inw( ioaddr, PTR_REG ) 1047 } while (0)
884#define SMC_SET_PTR(x) SMC_outw( x, ioaddr, PTR_REG ) 1048
885#define SMC_GET_EPH_STATUS() SMC_inw( ioaddr, EPH_STATUS_REG ) 1049#define SMC_GET_TCR() SMC_inw(ioaddr, TCR_REG)
886#define SMC_GET_RCR() SMC_inw( ioaddr, RCR_REG ) 1050
887#define SMC_SET_RCR(x) SMC_outw( x, ioaddr, RCR_REG ) 1051#define SMC_SET_TCR(x) SMC_outw(x, ioaddr, TCR_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 )
893 1052
894#ifndef SMC_GET_MAC_ADDR 1053#ifndef SMC_GET_MAC_ADDR
895#define SMC_GET_MAC_ADDR(addr) \ 1054#define SMC_GET_MAC_ADDR(addr) \
@@ -920,151 +1079,84 @@ static const char * chip_ids[ 16 ] = {
920 SMC_outw( mt[6] | (mt[7] << 8), ioaddr, MCAST_REG4 ); \ 1079 SMC_outw( mt[6] | (mt[7] << 8), ioaddr, MCAST_REG4 ); \
921 } while (0) 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#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 do { \
945 unsigned int __val = SMC_inl( ioaddr, DATA_REG ); \
946 (status) = __val & 0xffff; \
947 (length) = __val >> 16; \
948 } while (0)
949#else
950#define SMC_PUT_PKT_HDR(status, length) \ 1082#define SMC_PUT_PKT_HDR(status, length) \
951 do { \ 1083 do { \
952 SMC_outw( status, ioaddr, DATA_REG ); \ 1084 if (SMC_CAN_USE_32BIT) \
953 SMC_outw( length, ioaddr, DATA_REG ); \ 1085 SMC_outl((status) | (length)<<16, ioaddr, DATA_REG); \
954 } while (0) 1086 else { \
955#define SMC_GET_PKT_HDR(status, length) \ 1087 SMC_outw(status, ioaddr, DATA_REG); \
956 do { \ 1088 SMC_outw(length, ioaddr, DATA_REG); \
957 (status) = SMC_inw( ioaddr, DATA_REG ); \ 1089 } \
958 (length) = SMC_inw( ioaddr, DATA_REG ); \
959 } while (0) 1090 } while (0)
960#endif
961 1091
962#if SMC_CAN_USE_32BIT 1092#define SMC_GET_PKT_HDR(status, length) \
963#define _SMC_PUSH_DATA(p, l) \
964 do { \ 1093 do { \
965 char *__ptr = (p); \ 1094 if (SMC_CAN_USE_32BIT) { \
966 int __len = (l); \ 1095 unsigned int __val = SMC_inl(ioaddr, DATA_REG); \
967 if (__len >= 2 && (unsigned long)__ptr & 2) { \ 1096 (status) = __val & 0xffff; \
968 __len -= 2; \ 1097 (length) = __val >> 16; \
969 SMC_outw( *(u16 *)__ptr, ioaddr, DATA_REG ); \ 1098 } else { \
970 __ptr += 2; \ 1099 (status) = SMC_inw(ioaddr, DATA_REG); \
971 } \ 1100 (length) = SMC_inw(ioaddr, DATA_REG); \
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 } \ 1101 } \
977 } while (0) 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 1104#define SMC_PUSH_DATA(p, l) \
1006#define SMC_outw(x, ioaddr, reg) \
1007 do { \ 1105 do { \
1008 unsigned int __val16 = (x); \ 1106 if (SMC_CAN_USE_32BIT) { \
1009 SMC_outb( __val16, ioaddr, reg ); \ 1107 void *__ptr = (p); \
1010 SMC_outb( __val16 >> 8, ioaddr, reg + (1 << SMC_IO_SHIFT));\ 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 } while (0) 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
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 1127
1040#define SMC_PULL_DATA(p, l) \ 1128#define SMC_PULL_DATA(p, l) \
1041 if ( lp->datacs ) { \ 1129 do { \
1042 unsigned char *__ptr = (p); \ 1130 if (SMC_CAN_USE_32BIT) { \
1043 int __len = (l); \ 1131 void *__ptr = (p); \
1044 if ((unsigned long)__ptr & 2) { \ 1132 int __len = (l); \
1045 /* \ 1133 void *__ioaddr = ioaddr; \
1046 * We want 32bit alignment here. \ 1134 if ((unsigned long)__ptr & 2) { \
1047 * Since some buses perform a full 32bit \ 1135 /* \
1048 * fetch even for 16bit data we can't use \ 1136 * We want 32bit alignment here. \
1049 * SMC_inw() here. Back both source (on chip \ 1137 * Since some buses perform a full \
1050 * and destination) pointers of 2 bytes. \ 1138 * 32bit fetch even for 16bit data \
1051 */ \ 1139 * we can't use SMC_inw() here. \
1052 __ptr -= 2; \ 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 __len += 2; \ 1154 __len += 2; \
1054 SMC_SET_PTR( 2|PTR_READ|PTR_RCV|PTR_AUTOINC ); \ 1155 SMC_insl(__ioaddr, DATA_REG, __ptr, __len>>2); \
1055 } \ 1156 } else if (SMC_CAN_USE_16BIT) \
1056 __len += 2; \ 1157 SMC_insw(ioaddr, DATA_REG, p, (l) >> 1); \
1057 insl( lp->datacs, __ptr, __len >> 2); \ 1158 else if (SMC_CAN_USE_8BIT) \
1058 } else { \ 1159 SMC_insb(ioaddr, DATA_REG, p, l); \
1059 _SMC_PULL_DATA(p, l); \ 1160 } while (0)
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
1069 1161
1070#endif /* _SMC91X_H_ */ 1162#endif /* _SMC91X_H_ */