diff options
author | Andi Kleen <andi@firstfloor.org> | 2008-06-18 07:58:36 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-06-27 01:31:22 -0400 |
commit | 64c42f697661e27c9688a32c1ba61d0228e81d84 (patch) | |
tree | 57d86c9f63a2afba3bc6b5d9b9db11763740282b /drivers/net | |
parent | 581abbc26a7adb693fb8b913f1be18d1c349c1ab (diff) |
[netdrvr] Fix IOMMU overflow checking in s2io.c
s2io has IOMMU overflow checking, but unfortunately it is wrong.
It didn't use the standard macros, which meant that it only worked
on POWER and SPARC because only those define DMA_ERROR_CODE. Convert it to
use the standard macros instead.
I also commented two more bugs in the IOMMU handling. It assumes
that 0 DMA addresses cannot happen, but that's not true in all IOMMU setups.
The information if a buffer has been already mapped needs to be stored
elsewhere.
Didn't fix those because it needs careful checking of the buffer handling
by the maintainers.
Cc: ram.vepa@neterion.com
Cc: santosh.rastapur@neterion.com
Cc: sivakumar.subramani@neterion.com
Cc: sreenivasa.honnur@neterion.com
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/s2io.c | 35 | ||||
-rw-r--r-- | drivers/net/s2io.h | 4 |
2 files changed, 12 insertions, 27 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index b5c1e663417d..ae7b697456b4 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -2625,9 +2625,7 @@ static int fill_rx_buffers(struct ring_info *ring) | |||
2625 | rxdp1->Buffer0_ptr = pci_map_single | 2625 | rxdp1->Buffer0_ptr = pci_map_single |
2626 | (ring->pdev, skb->data, size - NET_IP_ALIGN, | 2626 | (ring->pdev, skb->data, size - NET_IP_ALIGN, |
2627 | PCI_DMA_FROMDEVICE); | 2627 | PCI_DMA_FROMDEVICE); |
2628 | if( (rxdp1->Buffer0_ptr == 0) || | 2628 | if(pci_dma_mapping_error(rxdp1->Buffer0_ptr)) |
2629 | (rxdp1->Buffer0_ptr == | ||
2630 | DMA_ERROR_CODE)) | ||
2631 | goto pci_map_failed; | 2629 | goto pci_map_failed; |
2632 | 2630 | ||
2633 | rxdp->Control_2 = | 2631 | rxdp->Control_2 = |
@@ -2657,6 +2655,7 @@ static int fill_rx_buffers(struct ring_info *ring) | |||
2657 | skb->data = (void *) (unsigned long)tmp; | 2655 | skb->data = (void *) (unsigned long)tmp; |
2658 | skb_reset_tail_pointer(skb); | 2656 | skb_reset_tail_pointer(skb); |
2659 | 2657 | ||
2658 | /* AK: check is wrong. 0 can be valid dma address */ | ||
2660 | if (!(rxdp3->Buffer0_ptr)) | 2659 | if (!(rxdp3->Buffer0_ptr)) |
2661 | rxdp3->Buffer0_ptr = | 2660 | rxdp3->Buffer0_ptr = |
2662 | pci_map_single(ring->pdev, ba->ba_0, | 2661 | pci_map_single(ring->pdev, ba->ba_0, |
@@ -2665,8 +2664,7 @@ static int fill_rx_buffers(struct ring_info *ring) | |||
2665 | pci_dma_sync_single_for_device(ring->pdev, | 2664 | pci_dma_sync_single_for_device(ring->pdev, |
2666 | (dma_addr_t) rxdp3->Buffer0_ptr, | 2665 | (dma_addr_t) rxdp3->Buffer0_ptr, |
2667 | BUF0_LEN, PCI_DMA_FROMDEVICE); | 2666 | BUF0_LEN, PCI_DMA_FROMDEVICE); |
2668 | if( (rxdp3->Buffer0_ptr == 0) || | 2667 | if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) |
2669 | (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) | ||
2670 | goto pci_map_failed; | 2668 | goto pci_map_failed; |
2671 | 2669 | ||
2672 | rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); | 2670 | rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); |
@@ -2681,18 +2679,17 @@ static int fill_rx_buffers(struct ring_info *ring) | |||
2681 | (ring->pdev, skb->data, ring->mtu + 4, | 2679 | (ring->pdev, skb->data, ring->mtu + 4, |
2682 | PCI_DMA_FROMDEVICE); | 2680 | PCI_DMA_FROMDEVICE); |
2683 | 2681 | ||
2684 | if( (rxdp3->Buffer2_ptr == 0) || | 2682 | if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) |
2685 | (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) | ||
2686 | goto pci_map_failed; | 2683 | goto pci_map_failed; |
2687 | 2684 | ||
2685 | /* AK: check is wrong */ | ||
2688 | if (!rxdp3->Buffer1_ptr) | 2686 | if (!rxdp3->Buffer1_ptr) |
2689 | rxdp3->Buffer1_ptr = | 2687 | rxdp3->Buffer1_ptr = |
2690 | pci_map_single(ring->pdev, | 2688 | pci_map_single(ring->pdev, |
2691 | ba->ba_1, BUF1_LEN, | 2689 | ba->ba_1, BUF1_LEN, |
2692 | PCI_DMA_FROMDEVICE); | 2690 | PCI_DMA_FROMDEVICE); |
2693 | 2691 | ||
2694 | if( (rxdp3->Buffer1_ptr == 0) || | 2692 | if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) { |
2695 | (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { | ||
2696 | pci_unmap_single | 2693 | pci_unmap_single |
2697 | (ring->pdev, | 2694 | (ring->pdev, |
2698 | (dma_addr_t)(unsigned long) | 2695 | (dma_addr_t)(unsigned long) |
@@ -4264,16 +4261,14 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4264 | txdp->Buffer_Pointer = pci_map_single(sp->pdev, | 4261 | txdp->Buffer_Pointer = pci_map_single(sp->pdev, |
4265 | fifo->ufo_in_band_v, | 4262 | fifo->ufo_in_band_v, |
4266 | sizeof(u64), PCI_DMA_TODEVICE); | 4263 | sizeof(u64), PCI_DMA_TODEVICE); |
4267 | if((txdp->Buffer_Pointer == 0) || | 4264 | if (pci_dma_mapping_error(txdp->Buffer_Pointer)) |
4268 | (txdp->Buffer_Pointer == DMA_ERROR_CODE)) | ||
4269 | goto pci_map_failed; | 4265 | goto pci_map_failed; |
4270 | txdp++; | 4266 | txdp++; |
4271 | } | 4267 | } |
4272 | 4268 | ||
4273 | txdp->Buffer_Pointer = pci_map_single | 4269 | txdp->Buffer_Pointer = pci_map_single |
4274 | (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); | 4270 | (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); |
4275 | if((txdp->Buffer_Pointer == 0) || | 4271 | if (pci_dma_mapping_error(txdp->Buffer_Pointer)) |
4276 | (txdp->Buffer_Pointer == DMA_ERROR_CODE)) | ||
4277 | goto pci_map_failed; | 4272 | goto pci_map_failed; |
4278 | 4273 | ||
4279 | txdp->Host_Control = (unsigned long) skb; | 4274 | txdp->Host_Control = (unsigned long) skb; |
@@ -6884,10 +6879,8 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, | |||
6884 | pci_map_single( sp->pdev, (*skb)->data, | 6879 | pci_map_single( sp->pdev, (*skb)->data, |
6885 | size - NET_IP_ALIGN, | 6880 | size - NET_IP_ALIGN, |
6886 | PCI_DMA_FROMDEVICE); | 6881 | PCI_DMA_FROMDEVICE); |
6887 | if( (rxdp1->Buffer0_ptr == 0) || | 6882 | if (pci_dma_mapping_error(rxdp1->Buffer0_ptr)) |
6888 | (rxdp1->Buffer0_ptr == DMA_ERROR_CODE)) { | ||
6889 | goto memalloc_failed; | 6883 | goto memalloc_failed; |
6890 | } | ||
6891 | rxdp->Host_Control = (unsigned long) (*skb); | 6884 | rxdp->Host_Control = (unsigned long) (*skb); |
6892 | } | 6885 | } |
6893 | } else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) { | 6886 | } else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) { |
@@ -6913,15 +6906,12 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, | |||
6913 | pci_map_single(sp->pdev, (*skb)->data, | 6906 | pci_map_single(sp->pdev, (*skb)->data, |
6914 | dev->mtu + 4, | 6907 | dev->mtu + 4, |
6915 | PCI_DMA_FROMDEVICE); | 6908 | PCI_DMA_FROMDEVICE); |
6916 | if( (rxdp3->Buffer2_ptr == 0) || | 6909 | if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) |
6917 | (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) { | ||
6918 | goto memalloc_failed; | 6910 | goto memalloc_failed; |
6919 | } | ||
6920 | rxdp3->Buffer0_ptr = *temp0 = | 6911 | rxdp3->Buffer0_ptr = *temp0 = |
6921 | pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, | 6912 | pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, |
6922 | PCI_DMA_FROMDEVICE); | 6913 | PCI_DMA_FROMDEVICE); |
6923 | if( (rxdp3->Buffer0_ptr == 0) || | 6914 | if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) { |
6924 | (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) { | ||
6925 | pci_unmap_single (sp->pdev, | 6915 | pci_unmap_single (sp->pdev, |
6926 | (dma_addr_t)rxdp3->Buffer2_ptr, | 6916 | (dma_addr_t)rxdp3->Buffer2_ptr, |
6927 | dev->mtu + 4, PCI_DMA_FROMDEVICE); | 6917 | dev->mtu + 4, PCI_DMA_FROMDEVICE); |
@@ -6933,8 +6923,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, | |||
6933 | rxdp3->Buffer1_ptr = *temp1 = | 6923 | rxdp3->Buffer1_ptr = *temp1 = |
6934 | pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, | 6924 | pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, |
6935 | PCI_DMA_FROMDEVICE); | 6925 | PCI_DMA_FROMDEVICE); |
6936 | if( (rxdp3->Buffer1_ptr == 0) || | 6926 | if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) { |
6937 | (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { | ||
6938 | pci_unmap_single (sp->pdev, | 6927 | pci_unmap_single (sp->pdev, |
6939 | (dma_addr_t)rxdp3->Buffer0_ptr, | 6928 | (dma_addr_t)rxdp3->Buffer0_ptr, |
6940 | BUF0_LEN, PCI_DMA_FROMDEVICE); | 6929 | BUF0_LEN, PCI_DMA_FROMDEVICE); |
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 4706f7f9acb6..1827b6686c98 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h | |||
@@ -75,10 +75,6 @@ static int debug_level = ERR_DBG; | |||
75 | /* DEBUG message print. */ | 75 | /* DEBUG message print. */ |
76 | #define DBG_PRINT(dbg_level, args...) if(!(debug_level<dbg_level)) printk(args) | 76 | #define DBG_PRINT(dbg_level, args...) if(!(debug_level<dbg_level)) printk(args) |
77 | 77 | ||
78 | #ifndef DMA_ERROR_CODE | ||
79 | #define DMA_ERROR_CODE (~(dma_addr_t)0x0) | ||
80 | #endif | ||
81 | |||
82 | /* Protocol assist features of the NIC */ | 78 | /* Protocol assist features of the NIC */ |
83 | #define L3_CKSUM_OK 0xFFFF | 79 | #define L3_CKSUM_OK 0xFFFF |
84 | #define L4_CKSUM_OK 0xFFFF | 80 | #define L4_CKSUM_OK 0xFFFF |