Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8316df1 authored by Luis R. Rodriguez's avatar Luis R. Rodriguez Committed by John W. Linville
Browse files

ath9k: Check for pci_map_single() errors



pci_map_single() can fail so detect those errors with
pci_dma_mapping_error() and deal with them accordingly.

Signed-off-by: default avatarLuis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 73a52670
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -190,6 +190,13 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
		pci_map_single(sc->pdev, skb->data,
			       skb->len,
			       PCI_DMA_TODEVICE);
	if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_buf_addr))) {
		dev_kfree_skb_any(skb);
		bf->bf_mpdu = NULL;
		DPRINTF(sc, ATH_DBG_CONFIG,
			"pci_dma_mapping_error() on beaconing\n");
		return NULL;
	}

	skb = ieee80211_get_buffered_bc(sc->hw, vif);

@@ -392,11 +399,18 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
		memcpy(&hdr[1], &val, sizeof(val));
	}

	bf->bf_mpdu = skb;
	bf->bf_buf_addr = bf->bf_dmacontext =
		pci_map_single(sc->pdev, skb->data,
			       skb->len,
			       PCI_DMA_TODEVICE);
	bf->bf_mpdu = skb;
	if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_buf_addr))) {
		dev_kfree_skb_any(skb);
		bf->bf_mpdu = NULL;
		DPRINTF(sc, ATH_DBG_CONFIG,
			"pci_dma_mapping_error() on beacon alloc\n");
		return -ENOMEM;
	}

	return 0;
}
+17 −0
Original line number Diff line number Diff line
@@ -304,6 +304,15 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
			bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data,
					 sc->sc_rxbufsize,
					 PCI_DMA_FROMDEVICE);
			if (unlikely(pci_dma_mapping_error(sc->pdev,
				  bf->bf_buf_addr))) {
				dev_kfree_skb_any(skb);
				bf->bf_mpdu = NULL;
				DPRINTF(sc, ATH_DBG_CONFIG,
					"pci_dma_mapping_error() on RX init\n");
				error = -ENOMEM;
				break;
			}
			bf->bf_dmacontext = bf->bf_buf_addr;
		}
		sc->sc_rxlink = NULL;
@@ -589,6 +598,14 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
		bf->bf_buf_addr = pci_map_single(sc->pdev, requeue_skb->data,
					 sc->sc_rxbufsize,
					 PCI_DMA_FROMDEVICE);
		if (unlikely(pci_dma_mapping_error(sc->pdev,
			  bf->bf_buf_addr))) {
			dev_kfree_skb_any(requeue_skb);
			bf->bf_mpdu = NULL;
			DPRINTF(sc, ATH_DBG_CONFIG,
				"pci_dma_mapping_error() on RX\n");
			break;
		}
		bf->bf_dmacontext = bf->bf_buf_addr;

		/*
+21 −2
Original line number Diff line number Diff line
@@ -1642,7 +1642,7 @@ static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
	}
}

static void ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf,
static int ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf,
				struct sk_buff *skb,
				struct ath_tx_control *txctl)
{
@@ -1701,9 +1701,18 @@ static void ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf,
	/* DMA setup */

	bf->bf_mpdu = skb;

	bf->bf_dmacontext = pci_map_single(sc->pdev, skb->data,
					   skb->len, PCI_DMA_TODEVICE);
	if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_dmacontext))) {
		bf->bf_mpdu = NULL;
		DPRINTF(sc, ATH_DBG_CONFIG,
			"pci_dma_mapping_error() on TX\n");
		return -ENOMEM;
	}

	bf->bf_buf_addr = bf->bf_dmacontext;
	return 0;
}

/* FIXME: tx power */
@@ -1775,10 +1784,12 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
	spin_unlock_bh(&txctl->txq->axq_lock);
}

/* Upon failure caller should free skb */
int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb,
		 struct ath_tx_control *txctl)
{
	struct ath_buf *bf;
	int r;

	/* Check if a tx buffer is available */

@@ -1788,7 +1799,15 @@ int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb,
		return -1;
	}

	ath_tx_setup_buffer(sc, bf, skb, txctl);
	r = ath_tx_setup_buffer(sc, bf, skb, txctl);
	if (unlikely(r)) {
		spin_lock_bh(&sc->sc_txbuflock);
		DPRINTF(sc, ATH_DBG_FATAL, "TX mem alloc failure\n");
		list_add_tail(&bf->list, &sc->sc_txbuf);
		spin_unlock_bh(&sc->sc_txbuflock);
		return r;
	}

	ath_tx_start_dma(sc, bf, txctl);

	return 0;