2002-06-24 19:34:05

by Jeff Garzik

[permalink] [raw]
Subject: Re: [PATCH] 2.5.24 : drivers/net/tlan.c; drivers/net/rrunner.c

Francois Romieu wrote:
> Greetings,
>
> [remaining DMA-mapping conversion in drivers/net]
>
> - tlan plays isa/pci and does as well some interesting things with copy
> buffers. The patch is attached but I'll feel safer if somebody with
> the adequate hardware at hand appears.

I've got some tlan cards

> - Imho rrunner wouldn't suffer from compat code removal + pci driver init
> style + DMA mapping conversion. I'd like to know what the maintainer
> thinks before resurrecting the patch. Jes ?

Just make sure you split it up... one of the reasons why I have stalled
applying davej's 2.4.x->2.5.x rrunner patch is that it's pretty darn
huge, even though the changes are fairly minor. (nothing against davej,
of course)

Jeff



2002-06-24 20:59:07

by Dave Jones

[permalink] [raw]
Subject: Re: [PATCH] 2.5.24 : drivers/net/tlan.c; drivers/net/rrunner.c

On Mon, Jun 24, 2002 at 03:34:22PM -0400, Jeff Garzik wrote:
> Just make sure you split it up... one of the reasons why I have stalled
> applying davej's 2.4.x->2.5.x rrunner patch is that it's pretty darn
> huge, even though the changes are fairly minor. (nothing against davej,
> of course)

There are a few net drivers just like that, which have seen quite a bit
of development in 2.4. Over time, it's possible the authors of the
drivers will submit stuff through you (or to Linus) bit by bit.
At which point, what's in my tree only serves as a "oh, you missed
this bit" service.

Dave

--
| Dave Jones. http://www.codemonkey.org.uk
| SuSE Labs

2002-06-30 15:16:33

by Francois Romieu

[permalink] [raw]
Subject: [PATCH] 2.5.24 - drivers/net/tlan.c dma mapping 1/10

- removal of code duplication.

--- linux-2.5.24/drivers/net/tlan.c Sat Jun 29 21:59:16 2002
+++ linux-2.5.24/drivers/net/tlan.c Sat Jun 29 22:01:37 2002
@@ -295,6 +295,7 @@ static int TLan_ioctl( struct net_device
static int TLan_probe1( struct pci_dev *pdev, long ioaddr, int irq, int rev, const struct pci_device_id *ent);
static void TLan_tx_timeout( struct net_device *dev);
static int tlan_init_one( struct pci_dev *pdev, const struct pci_device_id *ent);
+static void TLan_Release_Dev(struct net_device *);

static u32 TLan_HandleInvalid( struct net_device *, u16 );
static u32 TLan_HandleTxEOF( struct net_device *, u16 );
@@ -415,18 +416,8 @@ TLan_SetTimer( struct net_device *dev, u
static void __devexit tlan_remove_one( struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata( pdev );
- TLanPrivateInfo *priv = dev->priv;
-
- unregister_netdev( dev );
-
- if ( priv->dmaStorage ) {
- kfree( priv->dmaStorage );
- }
-
- release_region( dev->base_addr, 0x10 );
-
- kfree( dev );

+ TLan_Release_Dev(dev);
pci_set_drvdata( pdev, NULL );
}

@@ -627,23 +618,25 @@ static int __devinit TLan_probe1(struct

}

+static void TLan_Release_Dev(struct net_device *dev)
+{
+ TLanPrivateInfo *priv = dev->priv;
+
+ if (priv->dmaStorage)
+ kfree(priv->dmaStorage);
+ release_region(dev->base_addr, 0x10);
+ unregister_netdev(dev);
+}

static void TLan_Eisa_Cleanup(void)
{
- struct net_device *dev;
- TLanPrivateInfo *priv;
+ for (; tlan_have_eisa; tlan_have_eisa--) {
+ struct net_device *dev = TLan_Eisa_Devices;
+ TLanPrivateInfo *priv = dev->priv;

- while( tlan_have_eisa ) {
- dev = TLan_Eisa_Devices;
- priv = dev->priv;
- if (priv->dmaStorage) {
- kfree(priv->dmaStorage);
- }
- release_region( dev->base_addr, 0x10);
- unregister_netdev( dev );
+ TLan_Release_Dev(dev);
TLan_Eisa_Devices = priv->nextDevice;
kfree( dev );
- tlan_have_eisa--;
}
}

2002-06-30 15:17:59

by Francois Romieu

[permalink] [raw]
Subject: [PATCH] 2.5.24 - drivers/net/tlan.c dma mapping 8/10

- descriptors converted to synchronous DMA mapping.

--- linux-2.5.24/drivers/net/tlan.h Sun Jun 30 00:00:39 2002
+++ linux-2.5.24/drivers/net/tlan.h Sun Jun 30 14:34:27 2002
@@ -173,8 +173,8 @@ typedef struct tlan_private_tag {
struct pci_dev *pci_dev;
dma_addr_t rxBuffer_dma;
dma_addr_t txBuffer_dma;
+ dma_addr_t lists_dma;
struct net_device *nextDevice;
- void *dmaStorage;
u8 *padBuffer;
TLanList *rxList;
u8 *rxBuffer;
--- linux-2.5.24/drivers/net/tlan.c Sun Jun 30 00:00:42 2002
+++ linux-2.5.24/drivers/net/tlan.c Sun Jun 30 14:53:29 2002
@@ -639,8 +639,7 @@ static void TLan_Release_Dev(struct net_
TLanPrivateInfo *priv = dev->priv;
struct pci_dev *pdev = priv->pci_dev;

- if (priv->dmaStorage)
- kfree(priv->dmaStorage);
+ pci_free_consistent(pdev, TLAN_TOTAL_SIZE, priv->rxList, priv->lists_dma);
if ( bbuf )
TLan_ReleaseBuffers(pdev, priv);
release_region(dev->base_addr, 0x10);
@@ -814,16 +813,19 @@ static int TLan_Init( struct net_device
}

dma_size = TLAN_TOTAL_SIZE;
- priv->dmaStorage = kmalloc(dma_size, GFP_KERNEL | GFP_DMA);
- if ( priv->dmaStorage == NULL ) {
+ addr = pci_alloc_consistent(pdev, TLAN_TOTAL_SIZE, &priv->lists_dma);
+ if (!addr) {
printk(KERN_ERR "TLAN: Could not allocate lists and buffers for %s.\n",
dev->name );
release_region( dev->base_addr, 0x10 );
return -ENOMEM;
}
- memset( priv->dmaStorage, 0, dma_size );
- priv->rxList = (TLanList *)
- ( ( ( (u32) priv->dmaStorage ) + 7 ) & 0xFFFFFFF8 );
+ /*
+ * pci_alloc_consistent and an adequate power of 2 for TLAN_NUM_RX_LISTS
+ * guarantees that &xList is aligned on a 8 bytes boundary (required
+ * for rx and tx).
+ */
+ priv->rxList = (TLanList *)addr;
priv->txList = priv->rxList + TLAN_NUM_RX_LISTS;
if ( bbuf ) {
dma_size = TLAN_NUM_ALL_LISTS * TLAN_MAX_FRAME_SIZE;
@@ -831,6 +833,8 @@ static int TLan_Init( struct net_device
if ( addr == NULL ) {
printk(KERN_ERR "%s: buffers allocation failed\n",
dev->name );
+ pci_free_consistent(pdev, TLAN_TOTAL_SIZE, priv->rxList,
+ priv->lists_dma);
release_region( dev->base_addr, 0x10 );
return -ENOMEM;
}
@@ -1074,15 +1078,15 @@ static int TLan_StartTx( struct sk_buff
if ( ! priv->txInProgress ) {
priv->txInProgress = 1;
TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Starting TX on buffer %d\n", priv->txTail );
- outl( virt_to_bus( tail_list ), dev->base_addr + TLAN_CH_PARM );
+ outl( priv->lists_dma +
+ (TLAN_NUM_RX_LISTS + priv->txTail)*sizeof(TLanList),
+ dev->base_addr + TLAN_CH_PARM );
outl( TLAN_HC_GO, dev->base_addr + TLAN_HOST_CMD );
} else {
TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Adding buffer %d to TX channel\n", priv->txTail );
- if ( priv->txTail == 0 ) {
- ( priv->txList + ( TLAN_NUM_TX_LISTS - 1 ) )->forward = virt_to_bus( tail_list );
- } else {
- ( priv->txList + ( priv->txTail - 1 ) )->forward = virt_to_bus( tail_list );
- }
+ priv->txList[(priv->txTail-1)%TLAN_NUM_TX_LISTS].forward =
+ priv->lists_dma +
+ (TLAN_NUM_RX_LISTS + priv->txTail)*sizeof(TLanList);
}
spin_unlock_irqrestore(&priv->lock, flags);

@@ -1397,7 +1401,9 @@ u32 TLan_HandleTxEOF( struct net_device
TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOC (Head=%d Tail=%d)\n", priv->txHead, priv->txTail );
head_list = priv->txList + priv->txHead;
if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
- outl( virt_to_bus( head_list ), dev->base_addr + TLAN_CH_PARM );
+ outl( priv->lists_dma +
+ (TLAN_NUM_RX_LISTS + priv->txHead)*sizeof(TLanList),
+ dev->base_addr + TLAN_CH_PARM );
ack |= TLAN_HC_GO;
} else {
priv->txInProgress = 0;
@@ -1560,7 +1566,8 @@ u32 TLan_HandleRxEOF( struct net_device
head_list->forward = 0;
head_list->cStat = 0;
tail_list = priv->rxList + priv->rxTail;
- tail_list->forward = virt_to_bus( head_list );
+ tail_list->forward = priv->lists_dma +
+ priv->rxHead*sizeof(TLanList);

CIRC_INC( priv->rxHead, TLAN_NUM_RX_LISTS );
CIRC_INC( priv->rxTail, TLAN_NUM_RX_LISTS );
@@ -1576,7 +1583,8 @@ u32 TLan_HandleRxEOF( struct net_device
if ( eoc ) {
TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOC (Head=%d Tail=%d)\n", priv->rxHead, priv->rxTail );
head_list = priv->rxList + priv->rxHead;
- outl( virt_to_bus( head_list ), dev->base_addr + TLAN_CH_PARM );
+ outl( priv->lists_dma + priv->rxHead*sizeof(TLanList),
+ dev->base_addr + TLAN_CH_PARM );
ack |= TLAN_HC_GO | TLAN_HC_RT;
priv->rxEocCount++;
}
@@ -1663,7 +1671,9 @@ u32 TLan_HandleTxEOC( struct net_device
head_list = priv->txList + priv->txHead;
if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
netif_stop_queue(dev);
- outl( virt_to_bus( head_list ), dev->base_addr + TLAN_CH_PARM );
+ outl( priv->lists_dma + (TLAN_NUM_RX_LISTS +
+ priv->txHead)*sizeof(TLanList),
+ dev->base_addr + TLAN_CH_PARM );
ack |= TLAN_HC_GO;
} else {
priv->txInProgress = 0;
@@ -1782,7 +1792,8 @@ u32 TLan_HandleRxEOC( struct net_device
if ( priv->tlanRev < 0x30 ) {
TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOC (Head=%d Tail=%d) -- IRQ\n", priv->rxHead, priv->rxTail );
head_list = priv->rxList + priv->rxHead;
- outl( virt_to_bus( head_list ), dev->base_addr + TLAN_CH_PARM );
+ outl( priv->lists_dma + priv->rxHead*sizeof(TLanList),
+ dev->base_addr + TLAN_CH_PARM );
ack |= TLAN_HC_GO | TLAN_HC_RT;
priv->rxEocCount++;
}
@@ -1964,12 +1975,9 @@ void TLan_ResetLists( struct net_device
}
list->buffer[1].count = 0;
list->buffer[1].address = 0;
- if ( i < TLAN_NUM_RX_LISTS - 1 )
- list->forward = virt_to_bus( list + 1 );
- else
- list->forward = 0;
+ list->forward = priv->lists_dma + (i+1)*sizeof(TLanList);
}
-
+ list->forward = 0;
} /* TLan_ResetLists */

static void TLan_ResetTxBuffer(struct pci_dev *pdev, TLanList *list)
@@ -2347,7 +2355,7 @@ TLan_FinishReset( struct net_device *dev
if ( debug >= 1 && debug != TLAN_DEBUG_PROBE ) {
outb( ( TLAN_HC_REQ_INT >> 8 ), dev->base_addr + TLAN_HOST_CMD + 1 );
}
- outl( virt_to_bus( priv->rxList ), dev->base_addr + TLAN_CH_PARM );
+ outl( priv->lists_dma, dev->base_addr + TLAN_CH_PARM );
outl( TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD );
} else {
printk( "TLAN: %s: Link inactive, will retry in 10 secs...\n", dev->name );

2002-06-30 15:20:32

by Francois Romieu

[permalink] [raw]
Subject: [PATCH] 2.5.24 - drivers/net/tlan.c dma mapping 10/10

- changelog update.

--- linux-2.5.24/drivers/net/tlan.c Sun Jun 30 15:13:20 2002
+++ linux-2.5.24/drivers/net/tlan.c Sun Jun 30 16:10:08 2002
@@ -164,6 +164,8 @@
* v1.15 Apr 4, 2002 - Correct operation when aui=1 to be
* 10T half duplex no loopback
* Thanks to Gunnar Eikman
+ *
+ * v1.16 Jun 30, 2002 - DMA mapping conversion <[email protected]>
*******************************************************************************/

#include <linux/module.h>
@@ -218,7 +220,7 @@ static int bbuf;
static dma_addr_t TLanPadBuffer_dma;
static u8 *TLanPadBuffer;
static char TLanSignature[] = "TLAN";
-static const char tlan_banner[] = "ThunderLAN driver v1.15\n";
+static const char tlan_banner[] = "ThunderLAN driver v1.16\n";
static int tlan_have_pci;
static int tlan_have_eisa;

2002-06-30 15:18:48

by Francois Romieu

[permalink] [raw]
Subject: [PATCH] 2.5.24 - drivers/net/tlan.c dma mapping 7/10

- private dma storage doesn't need room for Rx/Tx buffers anymore.

--- linux-2.5.24/drivers/net/tlan.h Sat Jun 29 23:51:42 2002
+++ linux-2.5.24/drivers/net/tlan.h Sat Jun 29 23:56:02 2002
@@ -42,6 +42,7 @@
#define TLAN_NUM_RX_LISTS 32
#define TLAN_NUM_TX_LISTS 64
#define TLAN_NUM_ALL_LISTS (TLAN_NUM_RX_LISTS+TLAN_NUM_TX_LISTS)
+#define TLAN_TOTAL_SIZE TLAN_NUM_ALL_LISTS*sizeof(TLanList)

#define TLAN_IGNORE 0
#define TLAN_RECORD 1
--- linux-2.5.24/drivers/net/tlan.c Sat Jun 29 23:51:38 2002
+++ linux-2.5.24/drivers/net/tlan.c Sun Jun 30 00:00:07 2002
@@ -813,13 +813,7 @@ static int TLan_Init( struct net_device
return -EIO;
}

- if ( bbuf ) {
- dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS )
- * ( sizeof(TLanList) + TLAN_MAX_FRAME_SIZE );
- } else {
- dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS )
- * ( sizeof(TLanList) );
- }
+ dma_size = TLAN_TOTAL_SIZE;
priv->dmaStorage = kmalloc(dma_size, GFP_KERNEL | GFP_DMA);
if ( priv->dmaStorage == NULL ) {
printk(KERN_ERR "TLAN: Could not allocate lists and buffers for %s.\n",

2002-06-30 15:16:22

by Francois Romieu

[permalink] [raw]
Subject: [PATCH] 2.5.24 - drivers/net/tlan.c dma mapping 0/10

- missing include and #error removal in order to compile.

--- linux-2.5.24/drivers/net/tlan.h Sun Jun 9 07:28:44 2002
+++ linux-2.5.24/drivers/net/tlan.h Sat Jun 29 21:59:54 2002
@@ -25,7 +25,7 @@
#include <asm/io.h>
#include <asm/types.h>
#include <linux/netdevice.h>
-
+#include <linux/tqueue.h>


/*****************************************************************
--- linux-2.5.24/drivers/net/tlan.c Sun Jun 9 07:27:29 2002
+++ linux-2.5.24/drivers/net/tlan.c Sat Jun 29 21:59:16 2002
@@ -166,8 +166,6 @@
* Thanks to Gunnar Eikman
*******************************************************************************/

-#error Please convert me to Documentation/DMA-mapping.txt
-
#include <linux/module.h>

#include "tlan.h"

2002-06-30 15:18:47

by Francois Romieu

[permalink] [raw]
Subject: [PATCH] 2.5.24 - drivers/net/tlan.c dma mapping 3/10

- (cosmetic) removal of unused variable (pad_allocated);
- (cosmetic) gotoize error paths in TLan_probe1. Extra benefit: code gets
correctly indented again.

--- linux-2.5.24/drivers/net/tlan.c Sat Jun 29 22:15:10 2002
+++ linux-2.5.24/drivers/net/tlan.c Sat Jun 29 22:25:22 2002
@@ -431,12 +431,9 @@ static struct pci_driver tlan_driver = {

static int __init tlan_probe(void)
{
- static int pad_allocated;
-
printk(KERN_INFO "%s", tlan_banner);

- TLanPadBuffer = (u8 *) kmalloc(TLAN_MIN_FRAME_SIZE,
- GFP_KERNEL);
+ TLanPadBuffer = (u8 *) kmalloc(TLAN_MIN_FRAME_SIZE, GFP_KERNEL);

if (TLanPadBuffer == NULL) {
printk(KERN_ERR "TLAN: Could not allocate memory for pad buffer.\n");
@@ -447,7 +444,6 @@ static int __init tlan_probe(void)


memset(TLanPadBuffer, 0, TLAN_MIN_FRAME_SIZE);
- pad_allocated = 1;

TLAN_DBG(TLAN_DEBUG_PROBE, "Starting PCI Probe....\n");

@@ -505,7 +501,7 @@ static int __devinit TLan_probe1(struct
TLanPrivateInfo *priv;
u8 pci_rev;
u16 device_id;
- int reg;
+ int reg, ret;

if (pdev && pci_enable_device(pdev))
return -EIO;
@@ -513,7 +509,8 @@ static int __devinit TLan_probe1(struct
dev = init_etherdev(NULL, sizeof(TLanPrivateInfo));
if (dev == NULL) {
printk(KERN_ERR "TLAN: Could not allocate memory for device.\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err_out;
}
SET_MODULE_OWNER(dev);

@@ -537,9 +534,8 @@ static int __devinit TLan_probe1(struct
}
if (!pci_io_base) {
printk(KERN_ERR "TLAN: No IO mappings available\n");
- unregister_netdev(dev);
- kfree(dev);
- return -ENODEV;
+ ret = -ENODEV;
+ goto err_unregister_dev;
}

dev->base_addr = pci_io_base;
@@ -594,10 +590,9 @@ static int __devinit TLan_probe1(struct

if (TLan_Init(dev)) {
printk(KERN_ERR "TLAN: Could not register device.\n");
- unregister_netdev(dev);
- kfree(dev);
- return -EAGAIN;
- } else {
+ ret = -EAGAIN;
+ goto err_unregister_dev;
+ }

TLanDevicesInstalled++;
boards_found++;
@@ -618,8 +613,12 @@ static int __devinit TLan_probe1(struct
priv->adapter->deviceLabel,
priv->adapterRev);
return 0;
- }

+err_unregister_dev:
+ unregister_netdev(dev);
+ kfree(dev);
+err_out:
+ return ret;
}

static void TLan_Release_Dev(struct net_device *dev)

2002-06-30 15:18:46

by Francois Romieu

[permalink] [raw]
Subject: [PATCH] 2.5.24 - drivers/net/tlan.c dma mapping 5/10

- more code duplication removal.

--- linux-2.5.24/drivers/net/tlan.c Sat Jun 29 23:09:16 2002
+++ linux-2.5.24/drivers/net/tlan.c Sat Jun 29 23:18:19 2002
@@ -296,6 +296,8 @@ static int TLan_ioctl( struct net_device
static int TLan_probe1( struct pci_dev *pdev, long ioaddr, int irq, int rev, const struct pci_device_id *ent);
static void TLan_tx_timeout( struct net_device *dev);
static int tlan_init_one( struct pci_dev *pdev, const struct pci_device_id *ent);
+static void TLan_ResetTxBuffer(struct pci_dev *, TLanList *);
+static void TLan_ResetRxBuffer(struct pci_dev *, TLanList *);
static void TLan_Release_Dev(struct net_device *);

static u32 TLan_HandleInvalid( struct net_device *, u16 );
@@ -1349,14 +1351,8 @@ u32 TLan_HandleTxEOF( struct net_device

while (((tmpCStat = head_list->cStat ) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) {
ack++;
- if ( ! bbuf ) {
- struct sk_buff *skb = (struct sk_buff *)head_list->buffer[9].address;
-
- pci_unmap_single(pdev, head_list->buffer[0].address,
- skb->len, PCI_DMA_TODEVICE);
- dev_kfree_skb_any(skb);
- head_list->buffer[9].address = 0;
- }
+ if ( ! bbuf )
+ TLan_ResetTxBuffer(pdev, head_list);

if ( tmpCStat & TLAN_CSTAT_EOC )
eoc = 1;
@@ -1948,37 +1944,42 @@ void TLan_ResetLists( struct net_device

} /* TLan_ResetLists */

-
-void TLan_FreeLists( struct net_device *dev )
+static void TLan_ResetTxBuffer(struct pci_dev *pdev, TLanList *list)
{
- TLanPrivateInfo *priv = dev->priv;
- struct pci_dev *pdev = priv->pci_dev;
- int i;
- TLanList *list;
- struct sk_buff *skb;
+ struct sk_buff *skb = (struct sk_buff *) list->buffer[9].address;

- if ( ! bbuf ) {
- for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ ) {
- list = priv->txList + i;
- skb = (struct sk_buff *) list->buffer[9].address;
- if ( skb ) {
- pci_unmap_single(pdev, list->buffer[0].address,
- skb->len, PCI_DMA_TODEVICE);
- dev_kfree_skb_any( skb );
+ if (skb) {
+ pci_unmap_single(pdev, list->buffer[0].address, skb->len,
+ PCI_DMA_TODEVICE);
+ dev_kfree_skb_any(skb);
list->buffer[9].address = 0;
}
- }
+}
+
+static void TLan_ResetRxBuffer(struct pci_dev *pdev, TLanList *list)
+{
+ struct sk_buff *skb = (struct sk_buff *) list->buffer[9].address;

- for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ ) {
- list = priv->rxList + i;
skb = (struct sk_buff *) list->buffer[9].address;
- if ( skb ) {
+ if (skb) {
pci_unmap_single(pdev, list->buffer[0].address,
TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
- dev_kfree_skb_any( skb );
+ dev_kfree_skb_any(skb);
list->buffer[9].address = 0;
}
- }
+}
+
+void TLan_FreeLists( struct net_device *dev )
+{
+ TLanPrivateInfo *priv = dev->priv;
+ struct pci_dev *pdev = priv->pci_dev;
+ int i;
+
+ if ( ! bbuf ) {
+ for (i = 0; i < TLAN_NUM_TX_LISTS; i++)
+ TLan_ResetTxBuffer(pdev, priv->txList + i);
+ for (i = 0; i < TLAN_NUM_RX_LISTS; i++)
+ TLan_ResetRxBuffer(pdev, priv->rxList + i);
}

} /* TLan_FreeLists */

2002-06-30 15:23:15

by Francois Romieu

[permalink] [raw]
Subject: [PATCH] 2.5.24 - drivers/net/tlan.c dma mapping 2/10

- TLAN pad buffer virt_to_bus -> pci_map_single conversion.

--- linux-2.5.24/drivers/net/tlan.c Sat Jun 29 22:06:32 2002
+++ linux-2.5.24/drivers/net/tlan.c Sat Jun 29 22:12:10 2002
@@ -215,6 +215,7 @@ MODULE_PARM_DESC(bbuf, "ThunderLAN use b
static int debug;

static int bbuf;
+static dma_addr_t TLanPadBuffer_dma;
static u8 *TLanPadBuffer;
static char TLanSignature[] = "TLAN";
static const char tlan_banner[] = "ThunderLAN driver v1.15\n";
@@ -441,6 +442,9 @@ static int __init tlan_probe(void)
printk(KERN_ERR "TLAN: Could not allocate memory for pad buffer.\n");
return -ENOMEM;
}
+ TLanPadBuffer_dma = pci_map_single(NULL, TLanPadBuffer,
+ TLAN_MIN_FRAME_SIZE, PCI_DMA_TODEVICE);
+

memset(TLanPadBuffer, 0, TLAN_MIN_FRAME_SIZE);
pad_allocated = 1;
@@ -647,6 +651,8 @@ static void __exit tlan_exit(void)

if (tlan_have_eisa)
TLan_Eisa_Cleanup();
+ pci_unmap_single(NULL, TLanPadBuffer_dma, TLAN_MIN_FRAME_SIZE,
+ PCI_DMA_TODEVICE);

kfree( TLanPadBuffer );

@@ -1026,7 +1032,7 @@ static int TLan_StartTx( struct sk_buff
tail_list->frameSize = (u16) skb->len + pad;
tail_list->buffer[0].count = (u32) skb->len;
tail_list->buffer[1].count = TLAN_LAST_BUFFER | (u32) pad;
- tail_list->buffer[1].address = virt_to_bus( TLanPadBuffer );
+ tail_list->buffer[1].address = TLanPadBuffer_dma;
} else {
tail_list->frameSize = (u16) skb->len;
tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) skb->len;

2002-06-30 15:18:44

by Francois Romieu

[permalink] [raw]
Subject: [PATCH] 2.5.24 - drivers/net/tlan.c dma mapping 6/10

- TLAN Rx/Tx buffers virt_to_bus -> pci_map_single conversion.

--- linux-2.5.24/drivers/net/tlan.h Sat Jun 29 23:09:21 2002
+++ linux-2.5.24/drivers/net/tlan.h Sat Jun 29 23:42:28 2002
@@ -41,6 +41,7 @@

#define TLAN_NUM_RX_LISTS 32
#define TLAN_NUM_TX_LISTS 64
+#define TLAN_NUM_ALL_LISTS (TLAN_NUM_RX_LISTS+TLAN_NUM_TX_LISTS)

#define TLAN_IGNORE 0
#define TLAN_RECORD 1
@@ -169,6 +170,8 @@ typedef u8 TLanBuffer[TLAN_MAX_FRAME_SIZ

typedef struct tlan_private_tag {
struct pci_dev *pci_dev;
+ dma_addr_t rxBuffer_dma;
+ dma_addr_t txBuffer_dma;
struct net_device *nextDevice;
void *dmaStorage;
u8 *padBuffer;
--- linux-2.5.24/drivers/net/tlan.c Sat Jun 29 23:19:12 2002
+++ linux-2.5.24/drivers/net/tlan.c Sat Jun 29 23:49:46 2002
@@ -298,6 +298,7 @@ static void TLan_tx_timeout( struct net_
static int tlan_init_one( struct pci_dev *pdev, const struct pci_device_id *ent);
static void TLan_ResetTxBuffer(struct pci_dev *, TLanList *);
static void TLan_ResetRxBuffer(struct pci_dev *, TLanList *);
+static void TLan_ReleaseBuffers(struct pci_dev *, TLanPrivateInfo *);
static void TLan_Release_Dev(struct net_device *);

static u32 TLan_HandleInvalid( struct net_device *, u16 );
@@ -624,12 +625,24 @@ err_out:
return ret;
}

+static void TLan_ReleaseBuffers(struct pci_dev *pdev, TLanPrivateInfo *priv)
+{
+ pci_unmap_single(pdev, priv->rxBuffer_dma,
+ TLAN_NUM_RX_LISTS*TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
+ pci_unmap_single(pdev, priv->txBuffer_dma,
+ TLAN_NUM_TX_LISTS*TLAN_MAX_FRAME_SIZE, PCI_DMA_TODEVICE);
+ kfree(priv->rxBuffer);
+}
+
static void TLan_Release_Dev(struct net_device *dev)
{
TLanPrivateInfo *priv = dev->priv;
+ struct pci_dev *pdev = priv->pci_dev;

if (priv->dmaStorage)
kfree(priv->dmaStorage);
+ if ( bbuf )
+ TLan_ReleaseBuffers(pdev, priv);
release_region(dev->base_addr, 0x10);
unregister_netdev(dev);
}
@@ -784,12 +797,12 @@ static void __init TLan_EisaProbe (void

static int TLan_Init( struct net_device *dev )
{
+ TLanPrivateInfo *priv = dev->priv;
+ struct pci_dev *pdev = priv->pci_dev;
+ void *addr;
int dma_size;
int err;
int i;
- TLanPrivateInfo *priv;
-
- priv = dev->priv;

if (!priv->is_eisa) /* EISA devices have already requested IO */
if (!request_region( dev->base_addr, 0x10, TLanSignature )) {
@@ -819,9 +832,24 @@ static int TLan_Init( struct net_device
( ( ( (u32) priv->dmaStorage ) + 7 ) & 0xFFFFFFF8 );
priv->txList = priv->rxList + TLAN_NUM_RX_LISTS;
if ( bbuf ) {
- priv->rxBuffer = (u8 *) ( priv->txList + TLAN_NUM_TX_LISTS );
- priv->txBuffer = priv->rxBuffer
- + ( TLAN_NUM_RX_LISTS * TLAN_MAX_FRAME_SIZE );
+ dma_size = TLAN_NUM_ALL_LISTS * TLAN_MAX_FRAME_SIZE;
+ addr = kmalloc(dma_size, GFP_KERNEL | GFP_DMA);
+ if ( addr == NULL ) {
+ printk(KERN_ERR "%s: buffers allocation failed\n",
+ dev->name );
+ release_region( dev->base_addr, 0x10 );
+ return -ENOMEM;
+ }
+ memset(addr, 0, dma_size );
+ priv->rxBuffer = (u8 *)addr;
+ priv->rxBuffer_dma = pci_map_single(pdev, addr,
+ TLAN_NUM_RX_LISTS*TLAN_MAX_FRAME_SIZE,
+ PCI_DMA_FROMDEVICE);
+ priv->txBuffer = priv->rxBuffer +
+ TLAN_NUM_RX_LISTS*TLAN_MAX_FRAME_SIZE;
+ priv->txBuffer_dma = pci_map_single(pdev, priv->txBuffer,
+ TLAN_NUM_TX_LISTS*TLAN_MAX_FRAME_SIZE,
+ PCI_DMA_TODEVICE);
}

err = 0;
@@ -1024,6 +1052,9 @@ static int TLan_StartTx( struct sk_buff
if ( bbuf ) {
tail_buffer = priv->txBuffer + ( priv->txTail * TLAN_MAX_FRAME_SIZE );
memcpy( tail_buffer, skb->data, skb->len );
+ pci_dma_sync_single(pdev, priv->txBuffer_dma +
+ priv->txTail*TLAN_MAX_FRAME_SIZE,
+ skb->len, PCI_DMA_TODEVICE);
} else {
tail_list->buffer[0].address = pci_map_single(pdev, skb->data,
skb->len, PCI_DMA_TODEVICE);
@@ -1488,6 +1519,9 @@ u32 TLan_HandleRxEOF( struct net_device

priv->stats.rx_bytes += head_list->frameSize;

+ pci_dma_sync_single(pdev, priv->rxBuffer_dma +
+ priv->rxHead*TLAN_MAX_FRAME_SIZE,
+ frameSize, PCI_DMA_FROMDEVICE);
memcpy( t, head_buffer, frameSize );
skb->protocol = eth_type_trans( skb, dev );
netif_rx( skb );
@@ -1901,7 +1935,7 @@ void TLan_ResetLists( struct net_device
list = priv->txList + i;
list->cStat = TLAN_CSTAT_UNUSED;
if ( bbuf ) {
- list->buffer[0].address = virt_to_bus( priv->txBuffer + ( i * TLAN_MAX_FRAME_SIZE ) );
+ list->buffer[0].address = priv->rxBuffer_dma + (i * TLAN_MAX_FRAME_SIZE);
} else {
list->buffer[0].address = 0;
}
@@ -1918,7 +1952,7 @@ void TLan_ResetLists( struct net_device
list->frameSize = TLAN_MAX_FRAME_SIZE;
list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER;
if ( bbuf ) {
- list->buffer[0].address = virt_to_bus( priv->rxBuffer + ( i * TLAN_MAX_FRAME_SIZE ) );
+ list->buffer[0].address = priv->rxBuffer_dma + (i * TLAN_MAX_FRAME_SIZE);
} else {
skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 );
if ( skb == NULL ) {

2002-06-30 15:18:45

by Francois Romieu

[permalink] [raw]
Subject: [PATCH] 2.5.24 - drivers/net/tlan.c dma mapping 4/10

- skbuff virt_to_bus -> pci_map_single conversion in Rx/Tx paths.

--- linux-2.5.24/drivers/net/tlan.h Sat Jun 29 22:01:16 2002
+++ linux-2.5.24/drivers/net/tlan.h Sat Jun 29 22:50:17 2002
@@ -168,6 +168,7 @@ typedef u8 TLanBuffer[TLAN_MAX_FRAME_SIZ
****************************************************************/

typedef struct tlan_private_tag {
+ struct pci_dev *pci_dev;
struct net_device *nextDevice;
void *dmaStorage;
u8 *padBuffer;
--- linux-2.5.24/drivers/net/tlan.c Sat Jun 29 22:28:42 2002
+++ linux-2.5.24/drivers/net/tlan.c Sat Jun 29 23:08:37 2002
@@ -515,6 +515,7 @@ static int __devinit TLan_probe1(struct
SET_MODULE_OWNER(dev);

priv = dev->priv;
+ priv->pci_dev = pdev;

/* Is this a PCI device? */
if (pdev) {
@@ -995,6 +996,7 @@ static void TLan_tx_timeout(struct net_d
static int TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
{
TLanPrivateInfo *priv = dev->priv;
+ struct pci_dev *pdev = priv->pci_dev;
TLanList *tail_list;
u8 *tail_buffer;
int pad;
@@ -1021,7 +1023,8 @@ static int TLan_StartTx( struct sk_buff
tail_buffer = priv->txBuffer + ( priv->txTail * TLAN_MAX_FRAME_SIZE );
memcpy( tail_buffer, skb->data, skb->len );
} else {
- tail_list->buffer[0].address = virt_to_bus( skb->data );
+ tail_list->buffer[0].address = pci_map_single(pdev, skb->data,
+ skb->len, PCI_DMA_TODEVICE);
tail_list->buffer[9].address = (u32) skb;
}

@@ -1335,6 +1338,7 @@ u32 TLan_HandleInvalid( struct net_devic
u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
{
TLanPrivateInfo *priv = dev->priv;
+ struct pci_dev *pdev = priv->pci_dev;
int eoc = 0;
TLanList *head_list;
u32 ack = 0;
@@ -1346,7 +1350,11 @@ u32 TLan_HandleTxEOF( struct net_device
while (((tmpCStat = head_list->cStat ) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) {
ack++;
if ( ! bbuf ) {
- dev_kfree_skb_any( (struct sk_buff *) head_list->buffer[9].address );
+ struct sk_buff *skb = (struct sk_buff *)head_list->buffer[9].address;
+
+ pci_unmap_single(pdev, head_list->buffer[0].address,
+ skb->len, PCI_DMA_TODEVICE);
+ dev_kfree_skb_any(skb);
head_list->buffer[9].address = 0;
}

@@ -1452,6 +1460,7 @@ u32 TLan_HandleStatOverflow( struct net_
u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
{
TLanPrivateInfo *priv = dev->priv;
+ struct pci_dev *pdev = priv->pci_dev;
u32 ack = 0;
int eoc = 0;
u8 *head_buffer;
@@ -1499,9 +1508,13 @@ u32 TLan_HandleRxEOF( struct net_device
new_skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 );

if ( new_skb != NULL ) {
+ TLanBufferRef *head_buf = head_list->buffer;
+
/* If this ever happened it would be a problem */
/* not any more - ac */
- skb = (struct sk_buff *) head_list->buffer[9].address;
+ pci_unmap_single(pdev, head_list->buffer[0].address,
+ TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
+ skb = (struct sk_buff *) head_buf[9].address;
skb_trim( skb, frameSize );

priv->stats.rx_bytes += frameSize;
@@ -1512,9 +1525,10 @@ u32 TLan_HandleRxEOF( struct net_device
new_skb->dev = dev;
skb_reserve( new_skb, 2 );
t = (void *) skb_put( new_skb, TLAN_MAX_FRAME_SIZE );
- head_list->buffer[0].address = virt_to_bus( t );
- head_list->buffer[8].address = (u32) t;
- head_list->buffer[9].address = (u32) new_skb;
+ head_buf[0].address = pci_map_single(pdev, t,
+ TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
+ head_buf[8].address = (u32) t;
+ head_buf[9].address = (u32) new_skb;
} else
printk(KERN_WARNING "TLAN: Couldn't allocate memory for received data.\n" );
}
@@ -1879,6 +1893,7 @@ void TLan_Timer( unsigned long data )
void TLan_ResetLists( struct net_device *dev )
{
TLanPrivateInfo *priv = dev->priv;
+ struct pci_dev *pdev = priv->pci_dev;
int i;
TLanList *list;
struct sk_buff *skb;
@@ -1918,7 +1933,8 @@ void TLan_ResetLists( struct net_device
skb_reserve( skb, 2 );
t = (void *) skb_put( skb, TLAN_MAX_FRAME_SIZE );
}
- list->buffer[0].address = virt_to_bus( t );
+ list->buffer[0].address = pci_map_single(pdev, t,
+ TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
list->buffer[8].address = (u32) t;
list->buffer[9].address = (u32) skb;
}
@@ -1936,6 +1952,7 @@ void TLan_ResetLists( struct net_device
void TLan_FreeLists( struct net_device *dev )
{
TLanPrivateInfo *priv = dev->priv;
+ struct pci_dev *pdev = priv->pci_dev;
int i;
TLanList *list;
struct sk_buff *skb;
@@ -1945,6 +1962,8 @@ void TLan_FreeLists( struct net_device *
list = priv->txList + i;
skb = (struct sk_buff *) list->buffer[9].address;
if ( skb ) {
+ pci_unmap_single(pdev, list->buffer[0].address,
+ skb->len, PCI_DMA_TODEVICE);
dev_kfree_skb_any( skb );
list->buffer[9].address = 0;
}
@@ -1954,6 +1973,8 @@ void TLan_FreeLists( struct net_device *
list = priv->rxList + i;
skb = (struct sk_buff *) list->buffer[9].address;
if ( skb ) {
+ pci_unmap_single(pdev, list->buffer[0].address,
+ TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
dev_kfree_skb_any( skb );
list->buffer[9].address = 0;
}

2002-06-30 15:29:17

by Francois Romieu

[permalink] [raw]
Subject: [PATCH] 2.5.24 - drivers/net/tlan.c dma mapping 9/10

- (cosmetic) gotoize error paths in TLan_Init.

--- linux-2.5.24/drivers/net/tlan.c Sun Jun 30 14:54:32 2002
+++ linux-2.5.24/drivers/net/tlan.c Sun Jun 30 15:10:34 2002
@@ -805,11 +805,10 @@ static int TLan_Init( struct net_device

if (!priv->is_eisa) /* EISA devices have already requested IO */
if (!request_region( dev->base_addr, 0x10, TLanSignature )) {
- printk(KERN_ERR "TLAN: %s: IO port region 0x%lx size 0x%x in use.\n",
- dev->name,
- dev->base_addr,
- 0x10 );
- return -EIO;
+ printk(KERN_ERR "%s: IO port region 0x%lx size 0x%x in use\n",
+ dev->name, dev->base_addr, 0x10);
+ err = -EIO;
+ goto err_out;
}

dma_size = TLAN_TOTAL_SIZE;
@@ -817,8 +816,8 @@ static int TLan_Init( struct net_device
if (!addr) {
printk(KERN_ERR "TLAN: Could not allocate lists and buffers for %s.\n",
dev->name );
- release_region( dev->base_addr, 0x10 );
- return -ENOMEM;
+ err = -ENOMEM;
+ goto err_out_release_region;
}
/*
* pci_alloc_consistent and an adequate power of 2 for TLAN_NUM_RX_LISTS
@@ -833,10 +832,8 @@ static int TLan_Init( struct net_device
if ( addr == NULL ) {
printk(KERN_ERR "%s: buffers allocation failed\n",
dev->name );
- pci_free_consistent(pdev, TLAN_TOTAL_SIZE, priv->rxList,
- priv->lists_dma);
- release_region( dev->base_addr, 0x10 );
- return -ENOMEM;
+ err = -ENOMEM;
+ goto err_out_free_consistent;
}
memset(addr, 0, dma_size );
priv->rxBuffer = (u8 *)addr;
@@ -874,6 +871,14 @@ static int TLan_Init( struct net_device

return 0;

+err_out_free_consistent:
+ pci_free_consistent(pdev, TLAN_TOTAL_SIZE, priv->rxList,
+ priv->lists_dma);
+err_out_release_region:
+ release_region( dev->base_addr, 0x10 );
+err_out:
+ return err;
+
} /* TLan_Init */