* [PATCH] gianfar: pass the proper dev to DMA ops
@ 2009-03-17 16:16 Kumar Gala
2009-03-17 22:24 ` Becky Bruce
2009-03-19 6:28 ` David Miller
0 siblings, 2 replies; 3+ messages in thread
From: Kumar Gala @ 2009-03-17 16:16 UTC (permalink / raw)
To: davem; +Cc: Becky Bruce, netdev, Andy Fleming, linuxppc-dev
We need to be passing the of_platform device struct into the DMA ops as
its the one that has the archdata setup to know which low-level DMA ops we
should be using (not the net_device one). This isn't an issue until we
expect the archdata to be setup correctly.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
Dave,
This is for net-next. We are working on having per device dma ops for .30 and
expect the struct device archdata to be setup properly but in .29 we still
default to a direct DMA ops on ppc32 so this "bug" will never show up.
- k
drivers/net/gianfar.c | 34 ++++++++++++++++++----------------
drivers/net/gianfar.h | 3 ++-
2 files changed, 20 insertions(+), 17 deletions(-)
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index bed30ef..8659833 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -365,8 +365,10 @@ static int gfar_probe(struct of_device *ofdev,
return -ENOMEM;
priv = netdev_priv(dev);
- priv->dev = dev;
+ priv->ndev = dev;
+ priv->ofdev = ofdev;
priv->node = ofdev->node;
+ SET_NETDEV_DEV(dev, &ofdev->dev);
err = gfar_of_init(dev);
@@ -538,7 +540,7 @@ static int gfar_remove(struct of_device *ofdev)
dev_set_drvdata(&ofdev->dev, NULL);
iounmap(priv->regs);
- free_netdev(priv->dev);
+ free_netdev(priv->ndev);
return 0;
}
@@ -870,7 +872,7 @@ void stop_gfar(struct net_device *dev)
free_skb_resources(priv);
- dma_free_coherent(&dev->dev,
+ dma_free_coherent(&priv->ofdev->dev,
sizeof(struct txbd8)*priv->tx_ring_size
+ sizeof(struct rxbd8)*priv->rx_ring_size,
priv->tx_bd_base,
@@ -892,12 +894,12 @@ static void free_skb_resources(struct gfar_private *priv)
if (!priv->tx_skbuff[i])
continue;
- dma_unmap_single(&priv->dev->dev, txbdp->bufPtr,
+ dma_unmap_single(&priv->ofdev->dev, txbdp->bufPtr,
txbdp->length, DMA_TO_DEVICE);
txbdp->lstatus = 0;
for (j = 0; j < skb_shinfo(priv->tx_skbuff[i])->nr_frags; j++) {
txbdp++;
- dma_unmap_page(&priv->dev->dev, txbdp->bufPtr,
+ dma_unmap_page(&priv->ofdev->dev, txbdp->bufPtr,
txbdp->length, DMA_TO_DEVICE);
}
txbdp++;
@@ -914,7 +916,7 @@ static void free_skb_resources(struct gfar_private *priv)
if(priv->rx_skbuff != NULL) {
for (i = 0; i < priv->rx_ring_size; i++) {
if (priv->rx_skbuff[i]) {
- dma_unmap_single(&priv->dev->dev, rxbdp->bufPtr,
+ dma_unmap_single(&priv->ofdev->dev, rxbdp->bufPtr,
priv->rx_buffer_size,
DMA_FROM_DEVICE);
@@ -980,7 +982,7 @@ int startup_gfar(struct net_device *dev)
gfar_write(®s->imask, IMASK_INIT_CLEAR);
/* Allocate memory for the buffer descriptors */
- vaddr = (unsigned long) dma_alloc_coherent(&dev->dev,
+ vaddr = (unsigned long) dma_alloc_coherent(&priv->ofdev->dev,
sizeof (struct txbd8) * priv->tx_ring_size +
sizeof (struct rxbd8) * priv->rx_ring_size,
&addr, GFP_KERNEL);
@@ -1192,7 +1194,7 @@ err_rxalloc_fail:
rx_skb_fail:
free_skb_resources(priv);
tx_skb_fail:
- dma_free_coherent(&dev->dev,
+ dma_free_coherent(&priv->ofdev->dev,
sizeof(struct txbd8)*priv->tx_ring_size
+ sizeof(struct rxbd8)*priv->rx_ring_size,
priv->tx_bd_base,
@@ -1345,7 +1347,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (i == nr_frags - 1)
lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
- bufaddr = dma_map_page(&dev->dev,
+ bufaddr = dma_map_page(&priv->ofdev->dev,
skb_shinfo(skb)->frags[i].page,
skb_shinfo(skb)->frags[i].page_offset,
length,
@@ -1377,7 +1379,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* setup the TxBD length and buffer pointer for the first BD */
priv->tx_skbuff[priv->skb_curtx] = skb;
- txbdp_start->bufPtr = dma_map_single(&dev->dev, skb->data,
+ txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
skb_headlen(skb), DMA_TO_DEVICE);
lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb);
@@ -1563,7 +1565,7 @@ static void gfar_reset_task(struct work_struct *work)
{
struct gfar_private *priv = container_of(work, struct gfar_private,
reset_task);
- struct net_device *dev = priv->dev;
+ struct net_device *dev = priv->ndev;
if (dev->flags & IFF_UP) {
stop_gfar(dev);
@@ -1610,7 +1612,7 @@ static int gfar_clean_tx_ring(struct net_device *dev)
(lstatus & BD_LENGTH_MASK))
break;
- dma_unmap_single(&dev->dev,
+ dma_unmap_single(&priv->ofdev->dev,
bdp->bufPtr,
bdp->length,
DMA_TO_DEVICE);
@@ -1619,7 +1621,7 @@ static int gfar_clean_tx_ring(struct net_device *dev)
bdp = next_txbd(bdp, base, tx_ring_size);
for (i = 0; i < frags; i++) {
- dma_unmap_page(&dev->dev,
+ dma_unmap_page(&priv->ofdev->dev,
bdp->bufPtr,
bdp->length,
DMA_TO_DEVICE);
@@ -1696,7 +1698,7 @@ static void gfar_new_rxbdp(struct net_device *dev, struct rxbd8 *bdp,
struct gfar_private *priv = netdev_priv(dev);
u32 lstatus;
- bdp->bufPtr = dma_map_single(&dev->dev, skb->data,
+ bdp->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
priv->rx_buffer_size, DMA_FROM_DEVICE);
lstatus = BD_LFLAG(RXBD_EMPTY | RXBD_INTERRUPT);
@@ -1856,7 +1858,7 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
skb = priv->rx_skbuff[priv->skb_currx];
- dma_unmap_single(&priv->dev->dev, bdp->bufPtr,
+ dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr,
priv->rx_buffer_size, DMA_FROM_DEVICE);
/* We drop the frame if we failed to allocate a new buffer */
@@ -1916,7 +1918,7 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
static int gfar_poll(struct napi_struct *napi, int budget)
{
struct gfar_private *priv = container_of(napi, struct gfar_private, napi);
- struct net_device *dev = priv->dev;
+ struct net_device *dev = priv->ndev;
int tx_cleaned = 0;
int rx_cleaned = 0;
unsigned long flags;
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 54332b0..dd499d7 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -738,7 +738,8 @@ struct gfar_private {
spinlock_t rxlock;
struct device_node *node;
- struct net_device *dev;
+ struct net_device *ndev;
+ struct of_device *ofdev;
struct napi_struct napi;
/* skb array and index */
--
1.5.6.6
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] gianfar: pass the proper dev to DMA ops
2009-03-17 16:16 [PATCH] gianfar: pass the proper dev to DMA ops Kumar Gala
@ 2009-03-17 22:24 ` Becky Bruce
2009-03-19 6:28 ` David Miller
1 sibling, 0 replies; 3+ messages in thread
From: Becky Bruce @ 2009-03-17 22:24 UTC (permalink / raw)
To: Kumar Gala; +Cc: netdev, Andy Fleming, davem, linuxppc-dev
On Mar 17, 2009, at 11:16 AM, Kumar Gala wrote:
> We need to be passing the of_platform device struct into the DMA ops
> as
> its the one that has the archdata setup to know which low-level DMA
> ops we
> should be using (not the net_device one). This isn't an issue until
> we
> expect the archdata to be setup correctly.
>
> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Boots on 8641D stock config and gets rid of the panic I was seeing.
Acked-by: Becky Bruce <beckyb@kernel.crashing.org>
Cheers,
Becky
>
> ---
>
> Dave,
>
> This is for net-next. We are working on having per device dma ops
> for .30 and
> expect the struct device archdata to be setup properly but in .29 we
> still
> default to a direct DMA ops on ppc32 so this "bug" will never show up.
>
> - k
>
> drivers/net/gianfar.c | 34 ++++++++++++++++++----------------
> drivers/net/gianfar.h | 3 ++-
> 2 files changed, 20 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
> index bed30ef..8659833 100644
> --- a/drivers/net/gianfar.c
> +++ b/drivers/net/gianfar.c
> @@ -365,8 +365,10 @@ static int gfar_probe(struct of_device *ofdev,
> return -ENOMEM;
>
> priv = netdev_priv(dev);
> - priv->dev = dev;
> + priv->ndev = dev;
> + priv->ofdev = ofdev;
> priv->node = ofdev->node;
> + SET_NETDEV_DEV(dev, &ofdev->dev);
>
> err = gfar_of_init(dev);
>
> @@ -538,7 +540,7 @@ static int gfar_remove(struct of_device *ofdev)
> dev_set_drvdata(&ofdev->dev, NULL);
>
> iounmap(priv->regs);
> - free_netdev(priv->dev);
> + free_netdev(priv->ndev);
>
> return 0;
> }
> @@ -870,7 +872,7 @@ void stop_gfar(struct net_device *dev)
>
> free_skb_resources(priv);
>
> - dma_free_coherent(&dev->dev,
> + dma_free_coherent(&priv->ofdev->dev,
> sizeof(struct txbd8)*priv->tx_ring_size
> + sizeof(struct rxbd8)*priv->rx_ring_size,
> priv->tx_bd_base,
> @@ -892,12 +894,12 @@ static void free_skb_resources(struct
> gfar_private *priv)
> if (!priv->tx_skbuff[i])
> continue;
>
> - dma_unmap_single(&priv->dev->dev, txbdp->bufPtr,
> + dma_unmap_single(&priv->ofdev->dev, txbdp->bufPtr,
> txbdp->length, DMA_TO_DEVICE);
> txbdp->lstatus = 0;
> for (j = 0; j < skb_shinfo(priv->tx_skbuff[i])->nr_frags; j++) {
> txbdp++;
> - dma_unmap_page(&priv->dev->dev, txbdp->bufPtr,
> + dma_unmap_page(&priv->ofdev->dev, txbdp->bufPtr,
> txbdp->length, DMA_TO_DEVICE);
> }
> txbdp++;
> @@ -914,7 +916,7 @@ static void free_skb_resources(struct
> gfar_private *priv)
> if(priv->rx_skbuff != NULL) {
> for (i = 0; i < priv->rx_ring_size; i++) {
> if (priv->rx_skbuff[i]) {
> - dma_unmap_single(&priv->dev->dev, rxbdp->bufPtr,
> + dma_unmap_single(&priv->ofdev->dev, rxbdp->bufPtr,
> priv->rx_buffer_size,
> DMA_FROM_DEVICE);
>
> @@ -980,7 +982,7 @@ int startup_gfar(struct net_device *dev)
> gfar_write(®s->imask, IMASK_INIT_CLEAR);
>
> /* Allocate memory for the buffer descriptors */
> - vaddr = (unsigned long) dma_alloc_coherent(&dev->dev,
> + vaddr = (unsigned long) dma_alloc_coherent(&priv->ofdev->dev,
> sizeof (struct txbd8) * priv->tx_ring_size +
> sizeof (struct rxbd8) * priv->rx_ring_size,
> &addr, GFP_KERNEL);
> @@ -1192,7 +1194,7 @@ err_rxalloc_fail:
> rx_skb_fail:
> free_skb_resources(priv);
> tx_skb_fail:
> - dma_free_coherent(&dev->dev,
> + dma_free_coherent(&priv->ofdev->dev,
> sizeof(struct txbd8)*priv->tx_ring_size
> + sizeof(struct rxbd8)*priv->rx_ring_size,
> priv->tx_bd_base,
> @@ -1345,7 +1347,7 @@ static int gfar_start_xmit(struct sk_buff
> *skb, struct net_device *dev)
> if (i == nr_frags - 1)
> lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
>
> - bufaddr = dma_map_page(&dev->dev,
> + bufaddr = dma_map_page(&priv->ofdev->dev,
> skb_shinfo(skb)->frags[i].page,
> skb_shinfo(skb)->frags[i].page_offset,
> length,
> @@ -1377,7 +1379,7 @@ static int gfar_start_xmit(struct sk_buff
> *skb, struct net_device *dev)
>
> /* setup the TxBD length and buffer pointer for the first BD */
> priv->tx_skbuff[priv->skb_curtx] = skb;
> - txbdp_start->bufPtr = dma_map_single(&dev->dev, skb->data,
> + txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
> skb_headlen(skb), DMA_TO_DEVICE);
>
> lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb);
> @@ -1563,7 +1565,7 @@ static void gfar_reset_task(struct work_struct
> *work)
> {
> struct gfar_private *priv = container_of(work, struct gfar_private,
> reset_task);
> - struct net_device *dev = priv->dev;
> + struct net_device *dev = priv->ndev;
>
> if (dev->flags & IFF_UP) {
> stop_gfar(dev);
> @@ -1610,7 +1612,7 @@ static int gfar_clean_tx_ring(struct
> net_device *dev)
> (lstatus & BD_LENGTH_MASK))
> break;
>
> - dma_unmap_single(&dev->dev,
> + dma_unmap_single(&priv->ofdev->dev,
> bdp->bufPtr,
> bdp->length,
> DMA_TO_DEVICE);
> @@ -1619,7 +1621,7 @@ static int gfar_clean_tx_ring(struct
> net_device *dev)
> bdp = next_txbd(bdp, base, tx_ring_size);
>
> for (i = 0; i < frags; i++) {
> - dma_unmap_page(&dev->dev,
> + dma_unmap_page(&priv->ofdev->dev,
> bdp->bufPtr,
> bdp->length,
> DMA_TO_DEVICE);
> @@ -1696,7 +1698,7 @@ static void gfar_new_rxbdp(struct net_device
> *dev, struct rxbd8 *bdp,
> struct gfar_private *priv = netdev_priv(dev);
> u32 lstatus;
>
> - bdp->bufPtr = dma_map_single(&dev->dev, skb->data,
> + bdp->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
> priv->rx_buffer_size, DMA_FROM_DEVICE);
>
> lstatus = BD_LFLAG(RXBD_EMPTY | RXBD_INTERRUPT);
> @@ -1856,7 +1858,7 @@ int gfar_clean_rx_ring(struct net_device *dev,
> int rx_work_limit)
>
> skb = priv->rx_skbuff[priv->skb_currx];
>
> - dma_unmap_single(&priv->dev->dev, bdp->bufPtr,
> + dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr,
> priv->rx_buffer_size, DMA_FROM_DEVICE);
>
> /* We drop the frame if we failed to allocate a new buffer */
> @@ -1916,7 +1918,7 @@ int gfar_clean_rx_ring(struct net_device *dev,
> int rx_work_limit)
> static int gfar_poll(struct napi_struct *napi, int budget)
> {
> struct gfar_private *priv = container_of(napi, struct gfar_private,
> napi);
> - struct net_device *dev = priv->dev;
> + struct net_device *dev = priv->ndev;
> int tx_cleaned = 0;
> int rx_cleaned = 0;
> unsigned long flags;
> diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
> index 54332b0..dd499d7 100644
> --- a/drivers/net/gianfar.h
> +++ b/drivers/net/gianfar.h
> @@ -738,7 +738,8 @@ struct gfar_private {
> spinlock_t rxlock;
>
> struct device_node *node;
> - struct net_device *dev;
> + struct net_device *ndev;
> + struct of_device *ofdev;
> struct napi_struct napi;
>
> /* skb array and index */
> --
> 1.5.6.6
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] gianfar: pass the proper dev to DMA ops
2009-03-17 16:16 [PATCH] gianfar: pass the proper dev to DMA ops Kumar Gala
2009-03-17 22:24 ` Becky Bruce
@ 2009-03-19 6:28 ` David Miller
1 sibling, 0 replies; 3+ messages in thread
From: David Miller @ 2009-03-19 6:28 UTC (permalink / raw)
To: galak; +Cc: becky.bruce, netdev, afleming, linuxppc-dev
From: Kumar Gala <galak@kernel.crashing.org>
Date: Tue, 17 Mar 2009 11:16:07 -0500
> We need to be passing the of_platform device struct into the DMA ops as
> its the one that has the archdata setup to know which low-level DMA ops we
> should be using (not the net_device one). This isn't an issue until we
> expect the archdata to be setup correctly.
>
> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
> ---
>
> Dave,
>
> This is for net-next. We are working on having per device dma ops for .30 and
> expect the struct device archdata to be setup properly but in .29 we still
> default to a direct DMA ops on ppc32 so this "bug" will never show up.
Applied to net-next-2.6, thanks.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2009-03-19 6:28 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-17 16:16 [PATCH] gianfar: pass the proper dev to DMA ops Kumar Gala
2009-03-17 22:24 ` Becky Bruce
2009-03-19 6:28 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).