Auke Kok wrote:
index d14cc4b..0e80406 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -1042,6 +1044,10 @@ static int e1000_setup_desc_rings(struct e1000_adapter 
*adapter)
                tx_ring->buffer_info[i].dma =
                        pci_map_single(pdev, skb->data, skb->len,
                                       PCI_DMA_TODEVICE);
+               if (pci_dma_mapping_error(tx_ring->buffer_info[i].dma)) {
+                       ret_val = 4;
+                       goto err_nomem;
+               }
                tx_desc->buffer_addr = cpu_to_le64(
                                         tx_ring->buffer_info[i].dma);
                tx_desc->lower.data = cpu_to_le32(skb->len);
@@ -1059,7 +1065,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter 
*adapter)
        size = rx_ring->count * sizeof(struct e1000_buffer);
        rx_ring->buffer_info = kmalloc(size, GFP_KERNEL);
        if (!rx_ring->buffer_info) {
-               ret_val = 4;
+               ret_val = 5;
                goto err_nomem;
        }
        memset(rx_ring->buffer_info, 0, size);
@@ -1068,7 +1074,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter 
*adapter)
        rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size,
                                           &rx_ring->dma, GFP_KERNEL);
        if (!rx_ring->desc) {
-               ret_val = 5;
+               ret_val = 6;
                goto err_nomem;
        }
        memset(rx_ring->desc, 0, rx_ring->size);
@@ -1093,7 +1099,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter 
*adapter)
skb = alloc_skb(2048 + NET_IP_ALIGN, GFP_KERNEL);
                if (!skb) {
-                       ret_val = 6;
+                       ret_val = 7;
                        goto err_nomem;
                }
                skb_reserve(skb, NET_IP_ALIGN);
@@ -1101,6 +1107,10 @@ static int e1000_setup_desc_rings(struct e1000_adapter 
*adapter)
                rx_ring->buffer_info[i].dma =
                        pci_map_single(pdev, skb->data, 2048,
                                       PCI_DMA_FROMDEVICE);
+               if (pci_dma_mapping_error(rx_ring->buffer_info[i].dma)) {
+                       ret_val = 8;
+                       goto err_nomem;
+               }
                rx_desc->buffer_addr =
                        cpu_to_le64(rx_ring->buffer_info[i].dma);
                memset(skb->data, 0x00, skb->len);


this function is a bit fragile if two additional error checks cause a 'ret_val' ripple effect throughout the function.


diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 51c9024..8ebe238 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -195,6 +195,11 @@ map_skb:
                buffer_info->dma = pci_map_single(pdev, skb->data,
                                                  adapter->rx_buffer_len,
                                                  PCI_DMA_FROMDEVICE);
+               if (pci_dma_mapping_error(buffer_info->dma)) {
+                       dev_err(&pdev->dev, "RX DMA map failed\n");
+                       adapter->rx_dma_failed++;
+                       break;
+               }
rx_desc = E1000_RX_DESC(*rx_ring, i);
                rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
@@ -255,6 +260,13 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter 
*adapter,
                                                           ps_page->page,
                                                           0, PAGE_SIZE,
                                                           PCI_DMA_FROMDEVICE);
+                                       if (pci_dma_mapping_error(
+                                                       ps_page->dma)) {
+                                               dev_err(&adapter->pdev->dev,
+                                                 "RX DMA page map failed\n");
+                                               adapter->rx_dma_failed++;
+                                               goto no_buffers;
+                                       }
                                }
                                /*
                                 * Refresh the desc even if buffer_addrs
@@ -286,6 +298,14 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter 
*adapter,
                buffer_info->dma = pci_map_single(pdev, skb->data,
                                                  adapter->rx_ps_bsize0,
                                                  PCI_DMA_FROMDEVICE);
+               if (pci_dma_mapping_error(buffer_info->dma)) {
+                       dev_err(&pdev->dev, "RX DMA map failed\n");
+                       adapter->rx_dma_failed++;
+                       /* cleanup skb */
+                       dev_kfree_skb_any(skb);
+                       buffer_info->skb = NULL;
+                       break;
+               }
rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma); @@ -374,6 +394,11 @@ check_page:
                                                        buffer_info->page, 0,
                                                        PAGE_SIZE,
                                                        PCI_DMA_FROMDEVICE);
+               if (pci_dma_mapping_error(buffer_info->dma)) {
+                       dev_err(&adapter->pdev->dev, "RX DMA page map 
failed\n");
+                       adapter->rx_dma_failed++;
+                       break;
+               }
rx_desc = E1000_RX_DESC(*rx_ring, i);
                rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
@@ -3214,6 +3239,11 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
                                skb->data + offset,
                                size,
                                PCI_DMA_TODEVICE);
+               if (pci_dma_mapping_error(buffer_info->dma)) {
+                       dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
+                       adapter->tx_dma_failed++;
+                       return -1;
+               }
                buffer_info->next_to_watch = i;
len -= size;
@@ -3247,6 +3277,13 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
                                        offset,
                                        size,
                                        PCI_DMA_TODEVICE);
+                       if (pci_dma_mapping_error(buffer_info->dma)) {
+                               dev_err(&adapter->pdev->dev,
+                                       "TX DMA page map failed\n");
+                               adapter->tx_dma_failed++;
+                               return -1;
+                       }
+
                        buffer_info->next_to_watch = i;
len -= size;
@@ -3512,9 +3549,15 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct 
net_device *netdev)
        if (skb->protocol == htons(ETH_P_IP))
                tx_flags |= E1000_TX_FLAGS_IPV4;
- e1000_tx_queue(adapter, tx_flags,
-                      e1000_tx_map(adapter, skb, first,
-                                   max_per_txd, nr_frags, mss));
+       count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss);
+       if (count < 0) {
+               /* handle pci_map_single() error in e1000_tx_map */
+               dev_kfree_skb_any(skb);
+               spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
+               return NETDEV_TX_BUSY;
+       }
+
+       e1000_tx_queue(adapter, tx_flags, count);

are you really supposed to free the skb, if you are returning NETDEV_TX_BUSY? My memory is rusty but that seems strange

-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to