From 073ac8fd4a3e9a9265e8a59e0a79bc4b0b3822c3 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 1 Sep 2007 21:27:18 +0100 Subject: [NET] smc91x: fix PXA DMA support code The PXA DMA support code for smc91x doesn't pass a struct device to the dma_*map_single() functions, which leads to an oops in the dma bounce code. We have a struct device which was used to probe the SMC chip. Use it. (This patch is slightly larger because it requires struct smc_local to move into the header file.) Signed-off-by: Russell King --- drivers/net/smc91x.h | 64 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 8 deletions(-) (limited to 'drivers/net/smc91x.h') diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index af9e6bf59552..729fd28c08b5 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -462,6 +462,52 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r, #endif + +/* store this information for the driver.. */ +struct smc_local { + /* + * If I have to wait until memory is available to send a + * packet, I will store the skbuff here, until I get the + * desired memory. Then, I'll send it out and free it. + */ + struct sk_buff *pending_tx_skb; + struct tasklet_struct tx_task; + + /* version/revision of the SMC91x chip */ + int version; + + /* Contains the current active transmission mode */ + int tcr_cur_mode; + + /* Contains the current active receive mode */ + int rcr_cur_mode; + + /* Contains the current active receive/phy mode */ + int rpc_cur_mode; + int ctl_rfduplx; + int ctl_rspeed; + + u32 msg_enable; + u32 phy_type; + struct mii_if_info mii; + + /* work queue */ + struct work_struct phy_configure; + struct net_device *dev; + int work_pending; + + spinlock_t lock; + +#ifdef SMC_USE_PXA_DMA + /* DMA needs the physical address of the chip */ + u_long physaddr; + struct device *device; +#endif + void __iomem *base; + void __iomem *datacs; +}; + + #ifdef SMC_USE_PXA_DMA /* * Let's use the DMA engine on the XScale PXA2xx for RX packets. This is @@ -476,11 +522,12 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r, #ifdef SMC_insl #undef SMC_insl #define SMC_insl(a, r, p, l) \ - smc_pxa_dma_insl(a, lp->physaddr, r, dev->dma, p, l) + smc_pxa_dma_insl(a, lp, r, dev->dma, p, l) static inline void -smc_pxa_dma_insl(void __iomem *ioaddr, u_long physaddr, int reg, int dma, +smc_pxa_dma_insl(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma, u_char *buf, int len) { + u_long physaddr = lp->physaddr; dma_addr_t dmabuf; /* fallback if no DMA available */ @@ -497,7 +544,7 @@ smc_pxa_dma_insl(void __iomem *ioaddr, u_long physaddr, int reg, int dma, } len *= 4; - dmabuf = dma_map_single(NULL, buf, len, DMA_FROM_DEVICE); + dmabuf = dma_map_single(lp->device, buf, len, DMA_FROM_DEVICE); DCSR(dma) = DCSR_NODESC; DTADR(dma) = dmabuf; DSADR(dma) = physaddr + reg; @@ -507,18 +554,19 @@ smc_pxa_dma_insl(void __iomem *ioaddr, u_long physaddr, int reg, int dma, while (!(DCSR(dma) & DCSR_STOPSTATE)) cpu_relax(); DCSR(dma) = 0; - dma_unmap_single(NULL, dmabuf, len, DMA_FROM_DEVICE); + dma_unmap_single(lp->device, dmabuf, len, DMA_FROM_DEVICE); } #endif #ifdef SMC_insw #undef SMC_insw #define SMC_insw(a, r, p, l) \ - smc_pxa_dma_insw(a, lp->physaddr, r, dev->dma, p, l) + smc_pxa_dma_insw(a, lp, r, dev->dma, p, l) static inline void -smc_pxa_dma_insw(void __iomem *ioaddr, u_long physaddr, int reg, int dma, +smc_pxa_dma_insw(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma, u_char *buf, int len) { + u_long physaddr = lp->physaddr; dma_addr_t dmabuf; /* fallback if no DMA available */ @@ -535,7 +583,7 @@ smc_pxa_dma_insw(void __iomem *ioaddr, u_long physaddr, int reg, int dma, } len *= 2; - dmabuf = dma_map_single(NULL, buf, len, DMA_FROM_DEVICE); + dmabuf = dma_map_single(lp->device, buf, len, DMA_FROM_DEVICE); DCSR(dma) = DCSR_NODESC; DTADR(dma) = dmabuf; DSADR(dma) = physaddr + reg; @@ -545,7 +593,7 @@ smc_pxa_dma_insw(void __iomem *ioaddr, u_long physaddr, int reg, int dma, while (!(DCSR(dma) & DCSR_STOPSTATE)) cpu_relax(); DCSR(dma) = 0; - dma_unmap_single(NULL, dmabuf, len, DMA_FROM_DEVICE); + dma_unmap_single(lp->device, dmabuf, len, DMA_FROM_DEVICE); } #endif -- cgit v1.2.3