diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2013-02-13 09:49:08 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-02-14 14:24:07 -0500 |
commit | bdb084b22d8aee66c87af5e9c36bd6cf7f3bccfd (patch) | |
tree | 62cdfe1e5a6a6a71b43b7580338837661e579cf0 /drivers | |
parent | 4ea545d476d3182056aeb042c439237ed61d261e (diff) |
iwlegacy: more checks for dma mapping errors
This patch check output of pci_map_single() calls. I missed them on
my previous patch "iwlegacy: check for dma mapping errors", which
fixed only pci_map_page() calls.
To handle remaining possible dma mappings errors, we need to rearrange
ilXXXX_tx_skb() and il_enqueue_hcmd() functions.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlegacy/3945-mac.c | 51 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/4965-mac.c | 36 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/common.c | 16 |
3 files changed, 59 insertions, 44 deletions
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index 83856d1a6101..3630a41df50d 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c | |||
@@ -572,26 +572,11 @@ il3945_tx_skb(struct il_priv *il, | |||
572 | il3945_hw_build_tx_cmd_rate(il, out_cmd, info, hdr, sta_id); | 572 | il3945_hw_build_tx_cmd_rate(il, out_cmd, info, hdr, sta_id); |
573 | 573 | ||
574 | /* Total # bytes to be transmitted */ | 574 | /* Total # bytes to be transmitted */ |
575 | len = (u16) skb->len; | 575 | tx_cmd->len = cpu_to_le16((u16) skb->len); |
576 | tx_cmd->len = cpu_to_le16(len); | ||
577 | 576 | ||
578 | il_update_stats(il, true, fc, len); | ||
579 | tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; | 577 | tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; |
580 | tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; | 578 | tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; |
581 | 579 | ||
582 | if (!ieee80211_has_morefrags(hdr->frame_control)) { | ||
583 | txq->need_update = 1; | ||
584 | } else { | ||
585 | wait_write_ptr = 1; | ||
586 | txq->need_update = 0; | ||
587 | } | ||
588 | |||
589 | D_TX("sequence nr = 0X%x\n", le16_to_cpu(out_cmd->hdr.sequence)); | ||
590 | D_TX("tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); | ||
591 | il_print_hex_dump(il, IL_DL_TX, tx_cmd, sizeof(*tx_cmd)); | ||
592 | il_print_hex_dump(il, IL_DL_TX, (u8 *) tx_cmd->hdr, | ||
593 | ieee80211_hdrlen(fc)); | ||
594 | |||
595 | /* | 580 | /* |
596 | * Use the first empty entry in this queue's command buffer array | 581 | * Use the first empty entry in this queue's command buffer array |
597 | * to contain the Tx command and MAC header concatenated together | 582 | * to contain the Tx command and MAC header concatenated together |
@@ -610,14 +595,8 @@ il3945_tx_skb(struct il_priv *il, | |||
610 | * within command buffer array. */ | 595 | * within command buffer array. */ |
611 | txcmd_phys = | 596 | txcmd_phys = |
612 | pci_map_single(il->pci_dev, &out_cmd->hdr, len, PCI_DMA_TODEVICE); | 597 | pci_map_single(il->pci_dev, &out_cmd->hdr, len, PCI_DMA_TODEVICE); |
613 | /* we do not map meta data ... so we can safely access address to | 598 | if (unlikely(pci_dma_mapping_error(il->pci_dev, txcmd_phys))) |
614 | * provide to unmap command*/ | 599 | goto drop_unlock; |
615 | dma_unmap_addr_set(out_meta, mapping, txcmd_phys); | ||
616 | dma_unmap_len_set(out_meta, len, len); | ||
617 | |||
618 | /* Add buffer containing Tx command and MAC(!) header to TFD's | ||
619 | * first entry */ | ||
620 | il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1, 0); | ||
621 | 600 | ||
622 | /* Set up TFD's 2nd entry to point directly to remainder of skb, | 601 | /* Set up TFD's 2nd entry to point directly to remainder of skb, |
623 | * if any (802.11 null frames have no payload). */ | 602 | * if any (802.11 null frames have no payload). */ |
@@ -626,10 +605,34 @@ il3945_tx_skb(struct il_priv *il, | |||
626 | phys_addr = | 605 | phys_addr = |
627 | pci_map_single(il->pci_dev, skb->data + hdr_len, len, | 606 | pci_map_single(il->pci_dev, skb->data + hdr_len, len, |
628 | PCI_DMA_TODEVICE); | 607 | PCI_DMA_TODEVICE); |
608 | if (unlikely(pci_dma_mapping_error(il->pci_dev, phys_addr))) | ||
609 | goto drop_unlock; | ||
610 | } | ||
611 | |||
612 | /* Add buffer containing Tx command and MAC(!) header to TFD's | ||
613 | * first entry */ | ||
614 | il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1, 0); | ||
615 | dma_unmap_addr_set(out_meta, mapping, txcmd_phys); | ||
616 | dma_unmap_len_set(out_meta, len, len); | ||
617 | if (len) | ||
629 | il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, len, 0, | 618 | il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, len, 0, |
630 | U32_PAD(len)); | 619 | U32_PAD(len)); |
620 | |||
621 | if (!ieee80211_has_morefrags(hdr->frame_control)) { | ||
622 | txq->need_update = 1; | ||
623 | } else { | ||
624 | wait_write_ptr = 1; | ||
625 | txq->need_update = 0; | ||
631 | } | 626 | } |
632 | 627 | ||
628 | il_update_stats(il, true, fc, skb->len); | ||
629 | |||
630 | D_TX("sequence nr = 0X%x\n", le16_to_cpu(out_cmd->hdr.sequence)); | ||
631 | D_TX("tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); | ||
632 | il_print_hex_dump(il, IL_DL_TX, tx_cmd, sizeof(*tx_cmd)); | ||
633 | il_print_hex_dump(il, IL_DL_TX, (u8 *) tx_cmd->hdr, | ||
634 | ieee80211_hdrlen(fc)); | ||
635 | |||
633 | /* Tell device the write idx *just past* this latest filled TFD */ | 636 | /* Tell device the write idx *just past* this latest filled TFD */ |
634 | q->write_ptr = il_queue_inc_wrap(q->write_ptr, q->n_bd); | 637 | q->write_ptr = il_queue_inc_wrap(q->write_ptr, q->n_bd); |
635 | il_txq_update_write_ptr(il, txq); | 638 | il_txq_update_write_ptr(il, txq); |
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 835662a449da..7941eb3a0166 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c | |||
@@ -1793,8 +1793,7 @@ il4965_tx_skb(struct il_priv *il, | |||
1793 | memcpy(tx_cmd->hdr, hdr, hdr_len); | 1793 | memcpy(tx_cmd->hdr, hdr, hdr_len); |
1794 | 1794 | ||
1795 | /* Total # bytes to be transmitted */ | 1795 | /* Total # bytes to be transmitted */ |
1796 | len = (u16) skb->len; | 1796 | tx_cmd->len = cpu_to_le16((u16) skb->len); |
1797 | tx_cmd->len = cpu_to_le16(len); | ||
1798 | 1797 | ||
1799 | if (info->control.hw_key) | 1798 | if (info->control.hw_key) |
1800 | il4965_tx_cmd_build_hwcrypto(il, info, tx_cmd, skb, sta_id); | 1799 | il4965_tx_cmd_build_hwcrypto(il, info, tx_cmd, skb, sta_id); |
@@ -1804,7 +1803,6 @@ il4965_tx_skb(struct il_priv *il, | |||
1804 | 1803 | ||
1805 | il4965_tx_cmd_build_rate(il, tx_cmd, info, sta, fc); | 1804 | il4965_tx_cmd_build_rate(il, tx_cmd, info, sta, fc); |
1806 | 1805 | ||
1807 | il_update_stats(il, true, fc, len); | ||
1808 | /* | 1806 | /* |
1809 | * Use the first empty entry in this queue's command buffer array | 1807 | * Use the first empty entry in this queue's command buffer array |
1810 | * to contain the Tx command and MAC header concatenated together | 1808 | * to contain the Tx command and MAC header concatenated together |
@@ -1826,18 +1824,8 @@ il4965_tx_skb(struct il_priv *il, | |||
1826 | txcmd_phys = | 1824 | txcmd_phys = |
1827 | pci_map_single(il->pci_dev, &out_cmd->hdr, firstlen, | 1825 | pci_map_single(il->pci_dev, &out_cmd->hdr, firstlen, |
1828 | PCI_DMA_BIDIRECTIONAL); | 1826 | PCI_DMA_BIDIRECTIONAL); |
1829 | dma_unmap_addr_set(out_meta, mapping, txcmd_phys); | 1827 | if (unlikely(pci_dma_mapping_error(il->pci_dev, txcmd_phys))) |
1830 | dma_unmap_len_set(out_meta, len, firstlen); | 1828 | goto drop_unlock; |
1831 | /* Add buffer containing Tx command and MAC(!) header to TFD's | ||
1832 | * first entry */ | ||
1833 | il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen, 1, 0); | ||
1834 | |||
1835 | if (!ieee80211_has_morefrags(hdr->frame_control)) { | ||
1836 | txq->need_update = 1; | ||
1837 | } else { | ||
1838 | wait_write_ptr = 1; | ||
1839 | txq->need_update = 0; | ||
1840 | } | ||
1841 | 1829 | ||
1842 | /* Set up TFD's 2nd entry to point directly to remainder of skb, | 1830 | /* Set up TFD's 2nd entry to point directly to remainder of skb, |
1843 | * if any (802.11 null frames have no payload). */ | 1831 | * if any (802.11 null frames have no payload). */ |
@@ -1846,8 +1834,24 @@ il4965_tx_skb(struct il_priv *il, | |||
1846 | phys_addr = | 1834 | phys_addr = |
1847 | pci_map_single(il->pci_dev, skb->data + hdr_len, secondlen, | 1835 | pci_map_single(il->pci_dev, skb->data + hdr_len, secondlen, |
1848 | PCI_DMA_TODEVICE); | 1836 | PCI_DMA_TODEVICE); |
1837 | if (unlikely(pci_dma_mapping_error(il->pci_dev, phys_addr))) | ||
1838 | goto drop_unlock; | ||
1839 | } | ||
1840 | |||
1841 | /* Add buffer containing Tx command and MAC(!) header to TFD's | ||
1842 | * first entry */ | ||
1843 | il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen, 1, 0); | ||
1844 | dma_unmap_addr_set(out_meta, mapping, txcmd_phys); | ||
1845 | dma_unmap_len_set(out_meta, len, firstlen); | ||
1846 | if (secondlen) | ||
1849 | il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, secondlen, | 1847 | il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, secondlen, |
1850 | 0, 0); | 1848 | 0, 0); |
1849 | |||
1850 | if (!ieee80211_has_morefrags(hdr->frame_control)) { | ||
1851 | txq->need_update = 1; | ||
1852 | } else { | ||
1853 | wait_write_ptr = 1; | ||
1854 | txq->need_update = 0; | ||
1851 | } | 1855 | } |
1852 | 1856 | ||
1853 | scratch_phys = | 1857 | scratch_phys = |
@@ -1860,6 +1864,8 @@ il4965_tx_skb(struct il_priv *il, | |||
1860 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); | 1864 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); |
1861 | tx_cmd->dram_msb_ptr = il_get_dma_hi_addr(scratch_phys); | 1865 | tx_cmd->dram_msb_ptr = il_get_dma_hi_addr(scratch_phys); |
1862 | 1866 | ||
1867 | il_update_stats(il, true, fc, skb->len); | ||
1868 | |||
1863 | D_TX("sequence nr = 0X%x\n", le16_to_cpu(out_cmd->hdr.sequence)); | 1869 | D_TX("sequence nr = 0X%x\n", le16_to_cpu(out_cmd->hdr.sequence)); |
1864 | D_TX("tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); | 1870 | D_TX("tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); |
1865 | il_print_hex_dump(il, IL_DL_TX, (u8 *) tx_cmd, sizeof(*tx_cmd)); | 1871 | il_print_hex_dump(il, IL_DL_TX, (u8 *) tx_cmd, sizeof(*tx_cmd)); |
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 1f598604a79c..4ed2949f314d 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c | |||
@@ -3162,18 +3162,23 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd) | |||
3162 | idx, il->cmd_queue); | 3162 | idx, il->cmd_queue); |
3163 | } | 3163 | } |
3164 | #endif | 3164 | #endif |
3165 | txq->need_update = 1; | ||
3166 | |||
3167 | if (il->ops->txq_update_byte_cnt_tbl) | ||
3168 | /* Set up entry in queue's byte count circular buffer */ | ||
3169 | il->ops->txq_update_byte_cnt_tbl(il, txq, 0); | ||
3170 | 3165 | ||
3171 | phys_addr = | 3166 | phys_addr = |
3172 | pci_map_single(il->pci_dev, &out_cmd->hdr, fix_size, | 3167 | pci_map_single(il->pci_dev, &out_cmd->hdr, fix_size, |
3173 | PCI_DMA_BIDIRECTIONAL); | 3168 | PCI_DMA_BIDIRECTIONAL); |
3169 | if (unlikely(pci_dma_mapping_error(il->pci_dev, phys_addr))) { | ||
3170 | idx = -ENOMEM; | ||
3171 | goto out; | ||
3172 | } | ||
3174 | dma_unmap_addr_set(out_meta, mapping, phys_addr); | 3173 | dma_unmap_addr_set(out_meta, mapping, phys_addr); |
3175 | dma_unmap_len_set(out_meta, len, fix_size); | 3174 | dma_unmap_len_set(out_meta, len, fix_size); |
3176 | 3175 | ||
3176 | txq->need_update = 1; | ||
3177 | |||
3178 | if (il->ops->txq_update_byte_cnt_tbl) | ||
3179 | /* Set up entry in queue's byte count circular buffer */ | ||
3180 | il->ops->txq_update_byte_cnt_tbl(il, txq, 0); | ||
3181 | |||
3177 | il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, fix_size, 1, | 3182 | il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, fix_size, 1, |
3178 | U32_PAD(cmd->len)); | 3183 | U32_PAD(cmd->len)); |
3179 | 3184 | ||
@@ -3181,6 +3186,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd) | |||
3181 | q->write_ptr = il_queue_inc_wrap(q->write_ptr, q->n_bd); | 3186 | q->write_ptr = il_queue_inc_wrap(q->write_ptr, q->n_bd); |
3182 | il_txq_update_write_ptr(il, txq); | 3187 | il_txq_update_write_ptr(il, txq); |
3183 | 3188 | ||
3189 | out: | ||
3184 | spin_unlock_irqrestore(&il->hcmd_lock, flags); | 3190 | spin_unlock_irqrestore(&il->hcmd_lock, flags); |
3185 | return idx; | 3191 | return idx; |
3186 | } | 3192 | } |