Commit 2f4734ea authored by Jeff Garzik's avatar Jeff Garzik

Merge redhat.com:/garz/repo/linus-2.5

into redhat.com:/garz/repo/net-drivers-2.5
parents 6f06499b 90447fbb
...@@ -301,13 +301,13 @@ RCInitI2OMsgLayer (struct net_device *dev, ...@@ -301,13 +301,13 @@ RCInitI2OMsgLayer (struct net_device *dev,
PPAB pPab; PPAB pPab;
U32 pciBaseAddr = dev->base_addr; U32 pciBaseAddr = dev->base_addr;
PDPA pDpa = dev->priv; PDPA pDpa = dev->priv;
PU8 p_msgbuf = pDpa->PLanApiPA; PU8 p_msgbuf = pDpa->msgbuf;
PU8 p_phymsgbuf = (PU8) virt_to_bus ((void *) p_msgbuf); PU8 p_phymsgbuf = (PU8) pDpa->msgbuf_dma;
dprintk dprintk
("InitI2O: Adapter:0x%04ux ATU:0x%08ulx msgbuf:0x%08ulx phymsgbuf:0x%08ulx\n" ("InitI2O: Adapter:0x%04ux ATU:0x%08ulx msgbuf:%p phymsgbuf:0x%08ulx\n"
"TransmitCallbackFunction:0x%08ulx ReceiveCallbackFunction:0x%08ulx\n", "TransmitCallbackFunction:0x%08ulx ReceiveCallbackFunction:0x%08ulx\n",
pDpa->id, pciBaseAddr, (u32) p_msgbuf, (u32) p_phymsgbuf, pDpa->id, pciBaseAddr, p_msgbuf, (u32) p_phymsgbuf,
(u32) TransmitCallbackFunction, (u32) ReceiveCallbackFunction); (u32) TransmitCallbackFunction, (u32) ReceiveCallbackFunction);
/* Check if this interface already initialized - if so, shut it down */ /* Check if this interface already initialized - if so, shut it down */
...@@ -445,7 +445,7 @@ RCI2OSendPacket (struct net_device * dev, U32 InitiatorContext, ...@@ -445,7 +445,7 @@ RCI2OSendPacket (struct net_device * dev, U32 InitiatorContext,
return RC_RTN_FREE_Q_EMPTY; return RC_RTN_FREE_Q_EMPTY;
} }
/* calc virual address of msg - virual already mapped to physical */ /* calc virtual address of msg - virtual already mapped to physical */
pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset); pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
size = FillI2OMsgSGLFromTCB (pMsg + 4, pTransCtrlBlock); size = FillI2OMsgSGLFromTCB (pMsg + 4, pTransCtrlBlock);
...@@ -502,7 +502,7 @@ RCPostRecvBuffers (struct net_device * dev, PRCTCB pTransCtrlBlock) ...@@ -502,7 +502,7 @@ RCPostRecvBuffers (struct net_device * dev, PRCTCB pTransCtrlBlock)
dprintk ("RCPostRecvBuffers(): Inbound Free Q empty!\n"); dprintk ("RCPostRecvBuffers(): Inbound Free Q empty!\n");
return RC_RTN_FREE_Q_EMPTY; return RC_RTN_FREE_Q_EMPTY;
} }
/* calc virual address of msg - virual already mapped to physical */ /* calc virtual address of msg - virtual already mapped to physical */
pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset); pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
size = FillI2OMsgSGLFromTCB (pMsg + 4, pTransCtrlBlock); size = FillI2OMsgSGLFromTCB (pMsg + 4, pTransCtrlBlock);
...@@ -677,7 +677,7 @@ RCGetLinkStatistics (struct net_device *dev, ...@@ -677,7 +677,7 @@ RCGetLinkStatistics (struct net_device *dev,
return RC_RTN_FREE_Q_EMPTY; return RC_RTN_FREE_Q_EMPTY;
} }
/* calc virual address of msg - virual already mapped to physical */ /* calc virtual address of msg - virtual already mapped to physical */
pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset); pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
/*dprintk("Get82558Stats - pMsg = 0x%08ulx, InQ msgOffset = 0x%08ulx\n", pMsg, msgOffset);*/ /*dprintk("Get82558Stats - pMsg = 0x%08ulx, InQ msgOffset = 0x%08ulx\n", pMsg, msgOffset);*/
...@@ -751,7 +751,7 @@ RCGetLinkStatus (struct net_device * dev, PU32 ReturnAddr, ...@@ -751,7 +751,7 @@ RCGetLinkStatus (struct net_device * dev, PU32 ReturnAddr,
return RC_RTN_FREE_Q_EMPTY; return RC_RTN_FREE_Q_EMPTY;
} }
/* calc virual address of msg - virual already mapped to physical */ /* calc virtual address of msg - virtual already mapped to physical */
pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset); pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
/*dprintk("Get82558LinkStatus - pMsg = 0x%08ulx, InQ msgOffset = 0x%08ulx\n", pMsg, msgOffset);*/ /*dprintk("Get82558LinkStatus - pMsg = 0x%08ulx, InQ msgOffset = 0x%08ulx\n", pMsg, msgOffset);*/
/*dprintk("Get82558LinkStatus - pMsg = 0x%08X, InQ msgOffset = 0x%08X\n", pMsg, msgOffset);*/ /*dprintk("Get82558LinkStatus - pMsg = 0x%08X, InQ msgOffset = 0x%08X\n", pMsg, msgOffset);*/
...@@ -1452,7 +1452,7 @@ RCResetIOP (struct net_device * dev) ...@@ -1452,7 +1452,7 @@ RCResetIOP (struct net_device * dev)
pMsg[7] = 0; pMsg[7] = 0;
pMsg[8] = 1; /* return 1 byte */ pMsg[8] = 1; /* return 1 byte */
/* virual pointer to return buffer - clear first two dwords */ /* virtual pointer to return buffer - clear first two dwords */
p32 = (volatile PU32) pPab->pLinOutMsgBlock; p32 = (volatile PU32) pPab->pLinOutMsgBlock;
p32[0] = 0; p32[0] = 0;
p32[1] = 0; p32[1] = 0;
...@@ -1693,7 +1693,7 @@ SendI2OOutboundQInitMsg (PPAB pPab) ...@@ -1693,7 +1693,7 @@ SendI2OOutboundQInitMsg (PPAB pPab)
return RC_RTN_FREE_Q_EMPTY; return RC_RTN_FREE_Q_EMPTY;
} }
/* calc virual address of msg - virual already mapped to physical */ /* calc virtual address of msg - virtual already mapped to physical */
pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset); pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
dprintk dprintk
...@@ -1711,7 +1711,7 @@ SendI2OOutboundQInitMsg (PPAB pPab) ...@@ -1711,7 +1711,7 @@ SendI2OOutboundQInitMsg (PPAB pPab)
/* phys address to return status - area right after PAB */ /* phys address to return status - area right after PAB */
pMsg[7] = pPab->outMsgBlockPhyAddr; pMsg[7] = pPab->outMsgBlockPhyAddr;
/* virual pointer to return buffer - clear first two dwords */ /* virtual pointer to return buffer - clear first two dwords */
p32 = (PU32) pPab->pLinOutMsgBlock; p32 = (PU32) pPab->pLinOutMsgBlock;
p32[0] = 0; p32[0] = 0;
...@@ -1779,7 +1779,7 @@ GetI2OStatus (PPAB pPab) ...@@ -1779,7 +1779,7 @@ GetI2OStatus (PPAB pPab)
return RC_RTN_FREE_Q_EMPTY; return RC_RTN_FREE_Q_EMPTY;
} }
/* calc virual address of msg - virual already mapped to physical */ /* calc virtual address of msg - virtual already mapped to physical */
pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset); pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
pMsg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_0; pMsg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_0;
...@@ -1793,7 +1793,7 @@ GetI2OStatus (PPAB pPab) ...@@ -1793,7 +1793,7 @@ GetI2OStatus (PPAB pPab)
pMsg[7] = 0; pMsg[7] = 0;
pMsg[8] = 88; /* return 88 bytes */ pMsg[8] = 88; /* return 88 bytes */
/* virual pointer to return buffer - clear first two dwords */ /* virtual pointer to return buffer - clear first two dwords */
p32 = (volatile PU32) pPab->pLinOutMsgBlock; p32 = (volatile PU32) pPab->pLinOutMsgBlock;
p32[0] = 0; p32[0] = 0;
p32[1] = 0; p32[1] = 0;
...@@ -1862,7 +1862,7 @@ SendEnableSysMsg (PPAB pPab) ...@@ -1862,7 +1862,7 @@ SendEnableSysMsg (PPAB pPab)
return RC_RTN_FREE_Q_EMPTY; return RC_RTN_FREE_Q_EMPTY;
} }
/* calc virual address of msg - virual already mapped to physical */ /* calc virtual address of msg - virtual already mapped to physical */
pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset); pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
dprintk dprintk
...@@ -1885,7 +1885,7 @@ SendEnableSysMsg (PPAB pPab) ...@@ -1885,7 +1885,7 @@ SendEnableSysMsg (PPAB pPab)
** ========================================================================= ** =========================================================================
** FillI2OMsgFromTCB() ** FillI2OMsgFromTCB()
** **
** inputs pMsgU32 - virual pointer (mapped to physical) of message frame ** inputs pMsgU32 - virtual pointer (mapped to physical) of message frame
** pXmitCntrlBlock - pointer to caller buffer control block. ** pXmitCntrlBlock - pointer to caller buffer control block.
** **
** fills in LAN SGL after Transaction Control Word or Bucket Count. ** fills in LAN SGL after Transaction Control Word or Bucket Count.
......
...@@ -182,6 +182,7 @@ typedef struct { ...@@ -182,6 +182,7 @@ typedef struct {
U32 pci_addr; /* the pci address of the adapter */ U32 pci_addr; /* the pci address of the adapter */
U32 pci_addr_len; U32 pci_addr_len;
struct pci_dev *pci_dev;
struct timer_list timer; /* timer */ struct timer_list timer; /* timer */
struct net_device_stats stats; /* the statistics structure */ struct net_device_stats stats; /* the statistics structure */
unsigned long numOutRcvBuffers; /* number of outstanding receive buffers */ unsigned long numOutRcvBuffers; /* number of outstanding receive buffers */
...@@ -189,7 +190,7 @@ typedef struct { ...@@ -189,7 +190,7 @@ typedef struct {
unsigned char reboot; unsigned char reboot;
unsigned char nexus; unsigned char nexus;
PU8 msgbuf; /* Pointer to Lan Api Private Area */ PU8 msgbuf; /* Pointer to Lan Api Private Area */
PU8 PLanApiPA; /* Pointer to Lan Api Private Area (aligned) */ dma_addr_t msgbuf_dma;
PPAB pPab; /* Pointer to the PCI Adapter Block */ PPAB pPab; /* Pointer to the PCI Adapter Block */
} *PDPA; } *PDPA;
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
** along with this program; if not, write to the Free Software ** along with this program; if not, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
** **
** Francois Romieu, Apr 2003: Converted to pci DMA mapping API.
**
** Pete Popov, Oct 2001: Fixed a few bugs to make the driver functional ** Pete Popov, Oct 2001: Fixed a few bugs to make the driver functional
** again. Note that this card is not supported or manufactured by ** again. Note that this card is not supported or manufactured by
** RedCreek anymore. ** RedCreek anymore.
...@@ -47,8 +49,6 @@ ...@@ -47,8 +49,6 @@
** **
***************************************************************************/ ***************************************************************************/
#error Please convert me to Documentation/DMA-mapping.txt
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/string.h> #include <linux/string.h>
...@@ -66,7 +66,7 @@ ...@@ -66,7 +66,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
static char version[] __initdata = static char version[] __initdata =
"RedCreek Communications PCI linux driver version 2.20\n"; "RedCreek Communications PCI linux driver version 2.21\n";
#define RC_LINUX_MODULE #define RC_LINUX_MODULE
#include "rclanmtl.h" #include "rclanmtl.h"
...@@ -95,6 +95,12 @@ static char version[] __initdata = ...@@ -95,6 +95,12 @@ static char version[] __initdata =
*/ */
#define MSG_BUF_SIZE 16384 #define MSG_BUF_SIZE 16384
/* 2003/04/20: I don't know about the hardware ability but the driver won't
* play safe with 64 bit addressing and DAC without NETIF_F_HIGHDMA doesn't
* really make sense anyway. Let's play safe - romieu.
*/
#define RCPCI45_DMA_MASK ((u64) 0xffffffff)
static U32 DriverControlWord; static U32 DriverControlWord;
static void rc_timer (unsigned long); static void rc_timer (unsigned long);
...@@ -136,8 +142,8 @@ rcpci45_remove_one (struct pci_dev *pdev) ...@@ -136,8 +142,8 @@ rcpci45_remove_one (struct pci_dev *pdev)
free_irq (dev->irq, dev); free_irq (dev->irq, dev);
iounmap ((void *) dev->base_addr); iounmap ((void *) dev->base_addr);
pci_release_regions (pdev); pci_release_regions (pdev);
if (pDpa->msgbuf) pci_free_consistent (pdev, MSG_BUF_SIZE, pDpa->msgbuf,
kfree (pDpa->msgbuf); pDpa->msgbuf_dma);
if (pDpa->pPab) if (pDpa->pPab)
kfree (pDpa->pPab); kfree (pDpa->pPab);
kfree (dev); kfree (dev);
...@@ -172,6 +178,7 @@ rcpci45_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -172,6 +178,7 @@ rcpci45_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
error = -ENOMEM; error = -ENOMEM;
goto err_out; goto err_out;
} }
SET_MODULE_OWNER(dev);
error = pci_enable_device (pdev); error = pci_enable_device (pdev);
if (error) { if (error) {
...@@ -180,7 +187,6 @@ rcpci45_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -180,7 +187,6 @@ rcpci45_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
card_idx); card_idx);
goto err_out; goto err_out;
} }
error = -ENOMEM;
pci_start = pci_resource_start (pdev, 0); pci_start = pci_resource_start (pdev, 0);
pci_len = pci_resource_len (pdev, 0); pci_len = pci_resource_len (pdev, 0);
printk("pci_start %lx pci_len %lx\n", pci_start, pci_len); printk("pci_start %lx pci_len %lx\n", pci_start, pci_len);
...@@ -189,6 +195,7 @@ rcpci45_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -189,6 +195,7 @@ rcpci45_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
pDpa = dev->priv; pDpa = dev->priv;
pDpa->id = card_idx; pDpa->id = card_idx;
pDpa->pci_dev = pdev;
pDpa->pci_addr = pci_start; pDpa->pci_addr = pci_start;
if (!pci_start || !(pci_resource_flags (pdev, 0) & IORESOURCE_MEM)) { if (!pci_start || !(pci_resource_flags (pdev, 0) & IORESOURCE_MEM)) {
...@@ -200,24 +207,21 @@ rcpci45_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -200,24 +207,21 @@ rcpci45_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
/* /*
* pDpa->msgbuf is where the card will dma the I2O * pDpa->msgbuf is where the card will dma the I2O
* messages. Thus, we need contiguous physical pages of * messages. Thus, we need contiguous physical pages of memory.
* memory. * 2003/04/20: pci_alloc_consistent() provides well over the needed
*/ * alignment on a 256 bytes boundary for the LAN API private area.
pDpa->msgbuf = kmalloc (MSG_BUF_SIZE, GFP_DMA | GFP_KERNEL); * Thus it isn't needed anymore to align it by hand.
*/
pDpa->msgbuf = pci_alloc_consistent (pdev, MSG_BUF_SIZE,
&pDpa->msgbuf_dma);
if (!pDpa->msgbuf) { if (!pDpa->msgbuf) {
printk (KERN_ERR "(rcpci45 driver:) \ printk (KERN_ERR "(rcpci45 driver:) \
Could not allocate %d byte memory for the \ Could not allocate %d byte memory for the \
private msgbuf!\n", MSG_BUF_SIZE); private msgbuf!\n", MSG_BUF_SIZE);
error = -ENOMEM;
goto err_out_free_dev; goto err_out_free_dev;
} }
/*
* Save the starting address of the LAN API private area. We'll
* pass that to RCInitI2OMsgLayer().
*
*/
pDpa->PLanApiPA = (void *) (((long) pDpa->msgbuf + 0xff) & ~0xff);
/* The adapter is accessible through memory-access read/write, not /* The adapter is accessible through memory-access read/write, not
* I/O read/write. Thus, we need to map it to some virtual address * I/O read/write. Thus, we need to map it to some virtual address
* area in order to access the registers as normal memory. * area in order to access the registers as normal memory.
...@@ -226,12 +230,20 @@ rcpci45_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -226,12 +230,20 @@ rcpci45_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (error) if (error)
goto err_out_free_msgbuf; goto err_out_free_msgbuf;
error = pci_set_dma_mask (pdev, RCPCI45_DMA_MASK);
if (error) {
printk (KERN_ERR
"(rcpci45 driver:) pci_set_dma_mask failed!\n");
goto err_out_free_region;
}
vaddr = (ulong *) ioremap (pci_start, pci_len); vaddr = (ulong *) ioremap (pci_start, pci_len);
if (!vaddr) { if (!vaddr) {
printk (KERN_ERR printk (KERN_ERR
"(rcpci45 driver:) \ "(rcpci45 driver:) \
Unable to remap address range from %lu to %lu\n", Unable to remap address range from %lu to %lu\n",
pci_start, pci_start + pci_len); pci_start, pci_start + pci_len);
error = -EIO;
goto err_out_free_region; goto err_out_free_region;
} }
...@@ -249,13 +261,14 @@ rcpci45_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -249,13 +261,14 @@ rcpci45_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
err_out_free_region: err_out_free_region:
pci_release_regions (pdev); pci_release_regions (pdev);
err_out_free_msgbuf: err_out_free_msgbuf:
kfree (pDpa->msgbuf); pci_free_consistent (pdev, MSG_BUF_SIZE, pDpa->msgbuf,
pDpa->msgbuf_dma);
err_out_free_dev: err_out_free_dev:
unregister_netdev (dev); unregister_netdev (dev);
kfree (dev); kfree (dev);
err_out: err_out:
card_idx--; card_idx--;
return -ENODEV; return error;
} }
static struct pci_driver rcpci45_driver = { static struct pci_driver rcpci45_driver = {
...@@ -283,7 +296,6 @@ RCopen (struct net_device *dev) ...@@ -283,7 +296,6 @@ RCopen (struct net_device *dev)
int requested = 0; int requested = 0;
int error; int error;
MOD_INC_USE_COUNT;
if (pDpa->nexus) { if (pDpa->nexus) {
/* This is not the first time RCopen is called. Thus, /* This is not the first time RCopen is called. Thus,
* the interface was previously opened and later closed * the interface was previously opened and later closed
...@@ -365,7 +377,6 @@ RCopen (struct net_device *dev) ...@@ -365,7 +377,6 @@ RCopen (struct net_device *dev)
err_out_free_irq: err_out_free_irq:
free_irq (dev->irq, dev); free_irq (dev->irq, dev);
err_out: err_out:
MOD_DEC_USE_COUNT;
return error; return error;
} }
...@@ -402,7 +413,8 @@ RC_xmit_packet (struct sk_buff *skb, struct net_device *dev) ...@@ -402,7 +413,8 @@ RC_xmit_packet (struct sk_buff *skb, struct net_device *dev)
ptcb->b.context = (U32) skb; ptcb->b.context = (U32) skb;
ptcb->b.scount = 1; ptcb->b.scount = 1;
ptcb->b.size = skb->len; ptcb->b.size = skb->len;
ptcb->b.addr = virt_to_bus ((void *) skb->data); ptcb->b.addr = pci_map_single(pDpa->pci_dev, skb->data, skb->len,
PCI_DMA_TODEVICE);
if ((status = RCI2OSendPacket (dev, (U32) NULL, (PRCTCB) ptcb)) if ((status = RCI2OSendPacket (dev, (U32) NULL, (PRCTCB) ptcb))
!= RC_RTN_NO_ERROR) { != RC_RTN_NO_ERROR) {
...@@ -451,6 +463,8 @@ RCxmit_callback (U32 Status, ...@@ -451,6 +463,8 @@ RCxmit_callback (U32 Status,
while (PcktCount--) { while (PcktCount--) {
skb = (struct sk_buff *) (BufferContext[0]); skb = (struct sk_buff *) (BufferContext[0]);
BufferContext++; BufferContext++;
pci_unmap_single(pDpa->pci_dev, BufferContext[1], skb->len,
PCI_DMA_TODEVICE);
dev_kfree_skb_irq (skb); dev_kfree_skb_irq (skb);
} }
netif_wake_queue (dev); netif_wake_queue (dev);
...@@ -706,6 +720,7 @@ rc_timer (unsigned long data) ...@@ -706,6 +720,7 @@ rc_timer (unsigned long data)
RCDisableI2OInterrupts (dev); RCDisableI2OInterrupts (dev);
dev->flags &= ~IFF_UP; dev->flags &= ~IFF_UP;
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
/* FIXME: kill MOD_DEC_USE_COUNT, use dev_put */
} else { } else {
printk (KERN_INFO "%s: rescheduling timer...\n", printk (KERN_INFO "%s: rescheduling timer...\n",
dev->name); dev->name);
...@@ -731,7 +746,6 @@ RCclose (struct net_device *dev) ...@@ -731,7 +746,6 @@ RCclose (struct net_device *dev)
printk (KERN_INFO "%s skipping reset -- adapter already in reboot mode\n", dev->name); printk (KERN_INFO "%s skipping reset -- adapter already in reboot mode\n", dev->name);
dev->flags &= ~IFF_UP; dev->flags &= ~IFF_UP;
pDpa->shutdown = 1; pDpa->shutdown = 1;
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
...@@ -749,7 +763,6 @@ RCclose (struct net_device *dev) ...@@ -749,7 +763,6 @@ RCclose (struct net_device *dev)
(PFNCALLBACK) RCreset_callback); (PFNCALLBACK) RCreset_callback);
dev->flags &= ~IFF_UP; dev->flags &= ~IFF_UP;
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
...@@ -984,8 +997,9 @@ RC_allocate_and_post_buffers (struct net_device *dev, int numBuffers) ...@@ -984,8 +997,9 @@ RC_allocate_and_post_buffers (struct net_device *dev, int numBuffers)
PU32 p; PU32 p;
psingleB pB; psingleB pB;
struct sk_buff *skb; struct sk_buff *skb;
PDPA pDpa = dev->priv;
RC_RETURN status; RC_RETURN status;
U32 res; U32 res = 0;
if (!numBuffers) if (!numBuffers)
return 0; return 0;
...@@ -1001,7 +1015,7 @@ RC_allocate_and_post_buffers (struct net_device *dev, int numBuffers) ...@@ -1001,7 +1015,7 @@ RC_allocate_and_post_buffers (struct net_device *dev, int numBuffers)
if (!p) { if (!p) {
printk (KERN_WARNING "%s unable to allocate TCB\n", printk (KERN_WARNING "%s unable to allocate TCB\n",
dev->name); dev->name);
return 0; goto out;
} }
p[0] = 0; /* Buffer Count */ p[0] = 0; /* Buffer Count */
...@@ -1013,18 +1027,14 @@ RC_allocate_and_post_buffers (struct net_device *dev, int numBuffers) ...@@ -1013,18 +1027,14 @@ RC_allocate_and_post_buffers (struct net_device *dev, int numBuffers)
printk (KERN_WARNING printk (KERN_WARNING
"%s: unable to allocate enough skbs!\n", "%s: unable to allocate enough skbs!\n",
dev->name); dev->name);
if (*p != 0) { /* did we allocate any buffers */ goto err_out_unmap;
break;
} else {
kfree (p); /* Free the TCB */
return 0;
}
} }
skb_reserve (skb, 2); /* Align IP on 16 byte boundaries */ skb_reserve (skb, 2); /* Align IP on 16 byte boundaries */
pB->context = (U32) skb; pB->context = (U32) skb;
pB->scount = 1; /* segment count */ pB->scount = 1; /* segment count */
pB->size = MAX_ETHER_SIZE; pB->size = MAX_ETHER_SIZE;
pB->addr = virt_to_bus ((void *) skb->data); pB->addr = pci_map_single(pDpa->pci_dev, skb->data,
MAX_ETHER_SIZE, PCI_DMA_FROMDEVICE);
p[0]++; p[0]++;
pB++; pB++;
} }
...@@ -1032,16 +1042,21 @@ RC_allocate_and_post_buffers (struct net_device *dev, int numBuffers) ...@@ -1032,16 +1042,21 @@ RC_allocate_and_post_buffers (struct net_device *dev, int numBuffers)
if ((status = RCPostRecvBuffers (dev, (PRCTCB) p)) != RC_RTN_NO_ERROR) { if ((status = RCPostRecvBuffers (dev, (PRCTCB) p)) != RC_RTN_NO_ERROR) {
printk (KERN_WARNING "%s: Post buffer failed, error 0x%x\n", printk (KERN_WARNING "%s: Post buffer failed, error 0x%x\n",
dev->name, status); dev->name, status);
/* point to the first buffer */ goto err_out_unmap;
pB = (psingleB) ((U32) p + sizeof (U32));
while (p[0]) {
skb = (struct sk_buff *) pB->context;
dev_kfree_skb (skb);
p[0]--;
pB++;
}
} }
out_free:
res = p[0]; res = p[0];
kfree (p); kfree (p);
out:
return (res); /* return the number of posted buffers */ return (res); /* return the number of posted buffers */
err_out_unmap:
for (; p[0] > 0; p[0]--) {
--pB;
skb = (struct sk_buff *) pB->context;
pci_unmap_single(pDpa->pci_dev, pB->addr, MAX_ETHER_SIZE,
PCI_DMA_FROMDEVICE);
dev_kfree_skb (skb);
}
goto out_free;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment