diff options
| author | Anton Blanchard <anton@samba.org> | 2010-02-19 12:54:53 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2010-02-23 04:24:59 -0500 |
| commit | b5abb028e214cca68f4231d4f3bc0847ddbc986e (patch) | |
| tree | 1ff65ef5395914b6b5e9f77b7cd550cebc7dc20f | |
| parent | 242cc0547f3bcecc0b02ca6f3e9512760185727e (diff) | |
e1000: Fix DMA mapping error handling on RX
Check for error return from pci_map_single/pci_map_page and clean up.
With this and the previous patch the driver was able to handle a significant
percentage of errors (I set the fault injection rate to 10% and could still
download large files at a reasonable speed).
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/net/e1000/e1000_main.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index d29bb532eccf..765543663a4f 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
| @@ -4006,11 +4006,21 @@ check_page: | |||
| 4006 | } | 4006 | } |
| 4007 | } | 4007 | } |
| 4008 | 4008 | ||
| 4009 | if (!buffer_info->dma) | 4009 | if (!buffer_info->dma) { |
| 4010 | buffer_info->dma = pci_map_page(pdev, | 4010 | buffer_info->dma = pci_map_page(pdev, |
| 4011 | buffer_info->page, 0, | 4011 | buffer_info->page, 0, |
| 4012 | buffer_info->length, | 4012 | buffer_info->length, |
| 4013 | PCI_DMA_FROMDEVICE); | 4013 | PCI_DMA_FROMDEVICE); |
| 4014 | if (pci_dma_mapping_error(pdev, buffer_info->dma)) { | ||
| 4015 | put_page(buffer_info->page); | ||
| 4016 | dev_kfree_skb(skb); | ||
| 4017 | buffer_info->page = NULL; | ||
| 4018 | buffer_info->skb = NULL; | ||
| 4019 | buffer_info->dma = 0; | ||
| 4020 | adapter->alloc_rx_buff_failed++; | ||
| 4021 | break; /* while !buffer_info->skb */ | ||
| 4022 | } | ||
| 4023 | } | ||
| 4014 | 4024 | ||
| 4015 | rx_desc = E1000_RX_DESC(*rx_ring, i); | 4025 | rx_desc = E1000_RX_DESC(*rx_ring, i); |
| 4016 | rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); | 4026 | rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); |
| @@ -4101,6 +4111,13 @@ map_skb: | |||
| 4101 | skb->data, | 4111 | skb->data, |
| 4102 | buffer_info->length, | 4112 | buffer_info->length, |
| 4103 | PCI_DMA_FROMDEVICE); | 4113 | PCI_DMA_FROMDEVICE); |
| 4114 | if (pci_dma_mapping_error(pdev, buffer_info->dma)) { | ||
| 4115 | dev_kfree_skb(skb); | ||
| 4116 | buffer_info->skb = NULL; | ||
| 4117 | buffer_info->dma = 0; | ||
| 4118 | adapter->alloc_rx_buff_failed++; | ||
| 4119 | break; /* while !buffer_info->skb */ | ||
| 4120 | } | ||
| 4104 | 4121 | ||
| 4105 | /* | 4122 | /* |
| 4106 | * XXX if it was allocated cleanly it will never map to a | 4123 | * XXX if it was allocated cleanly it will never map to a |
