diff options
Diffstat (limited to 'drivers/net/yellowfin.c')
-rw-r--r-- | drivers/net/yellowfin.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index 9509477f61f4..4987040c414b 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c | |||
@@ -346,7 +346,7 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | |||
346 | static int yellowfin_open(struct net_device *dev); | 346 | static int yellowfin_open(struct net_device *dev); |
347 | static void yellowfin_timer(unsigned long data); | 347 | static void yellowfin_timer(unsigned long data); |
348 | static void yellowfin_tx_timeout(struct net_device *dev); | 348 | static void yellowfin_tx_timeout(struct net_device *dev); |
349 | static void yellowfin_init_ring(struct net_device *dev); | 349 | static int yellowfin_init_ring(struct net_device *dev); |
350 | static netdev_tx_t yellowfin_start_xmit(struct sk_buff *skb, | 350 | static netdev_tx_t yellowfin_start_xmit(struct sk_buff *skb, |
351 | struct net_device *dev); | 351 | struct net_device *dev); |
352 | static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance); | 352 | static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance); |
@@ -574,19 +574,24 @@ static int yellowfin_open(struct net_device *dev) | |||
574 | { | 574 | { |
575 | struct yellowfin_private *yp = netdev_priv(dev); | 575 | struct yellowfin_private *yp = netdev_priv(dev); |
576 | void __iomem *ioaddr = yp->base; | 576 | void __iomem *ioaddr = yp->base; |
577 | int i; | 577 | int i, ret; |
578 | 578 | ||
579 | /* Reset the chip. */ | 579 | /* Reset the chip. */ |
580 | iowrite32(0x80000000, ioaddr + DMACtrl); | 580 | iowrite32(0x80000000, ioaddr + DMACtrl); |
581 | 581 | ||
582 | i = request_irq(dev->irq, &yellowfin_interrupt, IRQF_SHARED, dev->name, dev); | 582 | ret = request_irq(dev->irq, &yellowfin_interrupt, IRQF_SHARED, dev->name, dev); |
583 | if (i) return i; | 583 | if (ret) |
584 | return ret; | ||
584 | 585 | ||
585 | if (yellowfin_debug > 1) | 586 | if (yellowfin_debug > 1) |
586 | printk(KERN_DEBUG "%s: yellowfin_open() irq %d.\n", | 587 | printk(KERN_DEBUG "%s: yellowfin_open() irq %d.\n", |
587 | dev->name, dev->irq); | 588 | dev->name, dev->irq); |
588 | 589 | ||
589 | yellowfin_init_ring(dev); | 590 | ret = yellowfin_init_ring(dev); |
591 | if (ret) { | ||
592 | free_irq(dev->irq, dev); | ||
593 | return ret; | ||
594 | } | ||
590 | 595 | ||
591 | iowrite32(yp->rx_ring_dma, ioaddr + RxPtr); | 596 | iowrite32(yp->rx_ring_dma, ioaddr + RxPtr); |
592 | iowrite32(yp->tx_ring_dma, ioaddr + TxPtr); | 597 | iowrite32(yp->tx_ring_dma, ioaddr + TxPtr); |
@@ -726,10 +731,10 @@ static void yellowfin_tx_timeout(struct net_device *dev) | |||
726 | } | 731 | } |
727 | 732 | ||
728 | /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ | 733 | /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ |
729 | static void yellowfin_init_ring(struct net_device *dev) | 734 | static int yellowfin_init_ring(struct net_device *dev) |
730 | { | 735 | { |
731 | struct yellowfin_private *yp = netdev_priv(dev); | 736 | struct yellowfin_private *yp = netdev_priv(dev); |
732 | int i; | 737 | int i, j; |
733 | 738 | ||
734 | yp->tx_full = 0; | 739 | yp->tx_full = 0; |
735 | yp->cur_rx = yp->cur_tx = 0; | 740 | yp->cur_rx = yp->cur_tx = 0; |
@@ -754,6 +759,11 @@ static void yellowfin_init_ring(struct net_device *dev) | |||
754 | yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev, | 759 | yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev, |
755 | skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); | 760 | skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); |
756 | } | 761 | } |
762 | if (i != RX_RING_SIZE) { | ||
763 | for (j = 0; j < i; j++) | ||
764 | dev_kfree_skb(yp->rx_skbuff[j]); | ||
765 | return -ENOMEM; | ||
766 | } | ||
757 | yp->rx_ring[i-1].dbdma_cmd = cpu_to_le32(CMD_STOP); | 767 | yp->rx_ring[i-1].dbdma_cmd = cpu_to_le32(CMD_STOP); |
758 | yp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); | 768 | yp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); |
759 | 769 | ||
@@ -770,8 +780,6 @@ static void yellowfin_init_ring(struct net_device *dev) | |||
770 | yp->tx_ring[--i].dbdma_cmd = cpu_to_le32(CMD_STOP | BRANCH_ALWAYS); | 780 | yp->tx_ring[--i].dbdma_cmd = cpu_to_le32(CMD_STOP | BRANCH_ALWAYS); |
771 | #else | 781 | #else |
772 | { | 782 | { |
773 | int j; | ||
774 | |||
775 | /* Tx ring needs a pair of descriptors, the second for the status. */ | 783 | /* Tx ring needs a pair of descriptors, the second for the status. */ |
776 | for (i = 0; i < TX_RING_SIZE; i++) { | 784 | for (i = 0; i < TX_RING_SIZE; i++) { |
777 | j = 2*i; | 785 | j = 2*i; |
@@ -806,7 +814,7 @@ static void yellowfin_init_ring(struct net_device *dev) | |||
806 | } | 814 | } |
807 | #endif | 815 | #endif |
808 | yp->tx_tail_desc = &yp->tx_status[0]; | 816 | yp->tx_tail_desc = &yp->tx_status[0]; |
809 | return; | 817 | return 0; |
810 | } | 818 | } |
811 | 819 | ||
812 | static netdev_tx_t yellowfin_start_xmit(struct sk_buff *skb, | 820 | static netdev_tx_t yellowfin_start_xmit(struct sk_buff *skb, |