Skip to contentSkip to conversation

remove pci_dma_* abuses and workarounds V2

PATCH In review Christoph Hellwig 5 participants 10 messages Jan 10, 2018 – Jan 18, 2018

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

Back before the dawn of time pci_dma_* with a NULL pci_dev argument was used for all kinds of things, e.g. dma mapping for non-PCI devices. All this has been long removed, but it turns out we still care for a NULL pci_dev in the wrappers, and we still have two odd USB drivers that use pci_dma_alloc_consistent for allocating memory while ignoring the dma_addr_t entirely, and a network driver mixing the already wrong usage of dma_* with a NULL device with a single call to pci_free_consistent.

This series switches the two usb drivers to use plain kzalloc, the net driver to properly use the dma API and then removes the handling of the NULL pci_dev in the pci_dma_* wrappers.

Changes since V1:
- remove allocation failure printks
- use kcalloc
- fix tsi108_eth
- improve changelogs

#1 lore raw

PATCH 1/4 media/ttusb-budget: remove pci_zalloc_coherent abuse

Switch to a plain kzalloc instead of pci_zalloc_coherent to allocate memory for the USB DMA.

---
 drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)
drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c +4 -14
index a142b9dc0feb..ea40a24947ba 100644
@@ -102,7 +102,6 @@ struct ttusb {
 	unsigned int isoc_in_pipe;
 
 	void *iso_buffer;
-	dma_addr_t iso_dma_handle;
 
 	struct urb *iso_urb[ISO_BUF_COUNT];
 
@@ -792,26 +791,17 @@ static void ttusb_free_iso_urbs(struct ttusb *ttusb)
 
 	for (i = 0; i < ISO_BUF_COUNT; i++)
 		usb_free_urb(ttusb->iso_urb[i]);
-
-	pci_free_consistent(NULL,
-			    ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF *
-			    ISO_BUF_COUNT, ttusb->iso_buffer,
-			    ttusb->iso_dma_handle);
+	kfree(ttusb->iso_buffer);
 }
 
 static int ttusb_alloc_iso_urbs(struct ttusb *ttusb)
 {
 	int i;
 
-	ttusb->iso_buffer = pci_zalloc_consistent(NULL,
-						  ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT,
-						  &ttusb->iso_dma_handle);
-
-	if (!ttusb->iso_buffer) {
-		dprintk("%s: pci_alloc_consistent - not enough memory\n",
-			__func__);
+	ttusb->iso_buffer = kcalloc(FRAMES_PER_ISO_BUF * ISO_BUF_COUNT,
+			ISO_FRAME_SIZE, GFP_KERNEL);
+	if (!ttusb->iso_buffer)
 		return -ENOMEM;
-	}
 
 	for (i = 0; i < ISO_BUF_COUNT; i++) {
 		struct urb *urb;
Signature · 1 line
2.14.2
#2 lore raw

PATCH 2/4 media/ttusb-dev: remove pci_zalloc_coherent abuse

In reply to Christoph Hellwig

Switch to a plain kzalloc instead of pci_zalloc_coherent to allocate memory for the USB DMA.

---
 drivers/media/usb/ttusb-dec/ttusb_dec.c | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)
drivers/media/usb/ttusb-dec/ttusb_dec.c +4 -14
index cdefb5dfbbdc..4d5acdf578a6 100644
@@ -127,7 +127,6 @@ struct ttusb_dec {
 	struct urb		*irq_urb;
 	dma_addr_t		irq_dma_handle;
 	void			*iso_buffer;
-	dma_addr_t		iso_dma_handle;
 	struct urb		*iso_urb[ISO_BUF_COUNT];
 	int			iso_stream_count;
 	struct mutex		iso_mutex;
@@ -1185,11 +1184,7 @@ static void ttusb_dec_free_iso_urbs(struct ttusb_dec *dec)
 
 	for (i = 0; i < ISO_BUF_COUNT; i++)
 		usb_free_urb(dec->iso_urb[i]);
-
-	pci_free_consistent(NULL,
-			    ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF *
-					      ISO_BUF_COUNT),
-			    dec->iso_buffer, dec->iso_dma_handle);
+	kfree(dec->iso_buffer);
 }
 
 static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)
@@ -1198,15 +1193,10 @@ static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)
 
 	dprintk("%s\n", __func__);
 
-	dec->iso_buffer = pci_zalloc_consistent(NULL,
-						ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT),
-						&dec->iso_dma_handle);
-
-	if (!dec->iso_buffer) {
-		dprintk("%s: pci_alloc_consistent - not enough memory\n",
-			__func__);
+	dec->iso_buffer = kcalloc(FRAMES_PER_ISO_BUF * ISO_BUF_COUNT,
+			ISO_FRAME_SIZE, GFP_KERNEL);
+	if (!dec->iso_buffer)
 		return -ENOMEM;
-	}
 
 	for (i = 0; i < ISO_BUF_COUNT; i++) {
 		struct urb *urb;
Signature · 1 line
2.14.2
#3 lore raw

PATCH 3/4 tsi108_eth: use dma API properly

In reply to Christoph Hellwig

We need to pass a struct device to the dma API, even if some architectures still support that for legacy reasons, and should not mix it with the old PCI dma API.

Note that the driver also seems to never actually unmap its dma mappings, but to fix that we'll need someone more familar with the driver.

---
 drivers/net/ethernet/tundra/tsi108_eth.c | 36 ++++++++++++++++++--------------
 1 file changed, 20 insertions(+), 16 deletions(-)
drivers/net/ethernet/tundra/tsi108_eth.c +20 -16
index 0624b71ab5d4..edcd1e60b30d 100644
@@ -152,6 +152,8 @@ struct tsi108_prv_data {
 	u32 msg_enable;			/* debug message level */
 	struct mii_if_info mii_if;
 	unsigned int init_media;
+
+	struct platform_device *pdev;
 };
 
 /* Structure for a device driver */
@@ -703,17 +705,18 @@ static int tsi108_send_packet(struct sk_buff * skb, struct net_device *dev)
 		data->txskbs[tx] = skb;
 
 		if (i == 0) {
-			data->txring[tx].buf0 = dma_map_single(NULL, skb->data,
-					skb_headlen(skb), DMA_TO_DEVICE);
+			data->txring[tx].buf0 = dma_map_single(&data->pdev->dev,
+					skb->data, skb_headlen(skb),
+					DMA_TO_DEVICE);
 			data->txring[tx].len = skb_headlen(skb);
 			misc |= TSI108_TX_SOF;
 		} else {
 			const skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1];
 
-			data->txring[tx].buf0 = skb_frag_dma_map(NULL, frag,
-								 0,
-								 skb_frag_size(frag),
-								 DMA_TO_DEVICE);
+			data->txring[tx].buf0 =
+				skb_frag_dma_map(&data->pdev->dev, frag,
+						0, skb_frag_size(frag),
+						DMA_TO_DEVICE);
 			data->txring[tx].len = skb_frag_size(frag);
 		}
 
@@ -808,9 +811,9 @@ static int tsi108_refill_rx(struct net_device *dev, int budget)
 		if (!skb)
 			break;
 
-		data->rxring[rx].buf0 = dma_map_single(NULL, skb->data,
-							TSI108_RX_SKB_SIZE,
-							DMA_FROM_DEVICE);
+		data->rxring[rx].buf0 = dma_map_single(&data->pdev->dev,
+				skb->data, TSI108_RX_SKB_SIZE,
+				DMA_FROM_DEVICE);
 
 		/* Sometimes the hardware sets blen to zero after packet
 		 * reception, even though the manual says that it's only ever
@@ -1308,15 +1311,15 @@ static int tsi108_open(struct net_device *dev)
 		       data->id, dev->irq, dev->name);
 	}
 
-	data->rxring = dma_zalloc_coherent(NULL, rxring_size, &data->rxdma,
-					   GFP_KERNEL);
+	data->rxring = dma_zalloc_coherent(&data->pdev->dev, rxring_size,
+			&data->rxdma, GFP_KERNEL);
 	if (!data->rxring)
 		return -ENOMEM;
 
-	data->txring = dma_zalloc_coherent(NULL, txring_size, &data->txdma,
-					   GFP_KERNEL);
+	data->txring = dma_zalloc_coherent(&data->pdev->dev, txring_size,
+			&data->txdma, GFP_KERNEL);
 	if (!data->txring) {
-		pci_free_consistent(NULL, rxring_size, data->rxring,
+		dma_free_coherent(&data->pdev->dev, rxring_size, data->rxring,
 				    data->rxdma);
 		return -ENOMEM;
 	}
@@ -1428,10 +1431,10 @@ static int tsi108_close(struct net_device *dev)
 		dev_kfree_skb(skb);
 	}
 
-	dma_free_coherent(0,
+	dma_free_coherent(&data->pdev->dev,
 			    TSI108_RXRING_LEN * sizeof(rx_desc),
 			    data->rxring, data->rxdma);
-	dma_free_coherent(0,
+	dma_free_coherent(&data->pdev->dev,
 			    TSI108_TXRING_LEN * sizeof(tx_desc),
 			    data->txring, data->txdma);
 
@@ -1576,6 +1579,7 @@ tsi108_init_one(struct platform_device *pdev)
 	printk("tsi108_eth%d: probe...\n", pdev->id);
 	data = netdev_priv(dev);
 	data->dev = dev;
+	data->pdev = pdev;
 
 	pr_debug("tsi108_eth%d:regs:phyresgs:phy:irq_num=0x%x:0x%x:0x%x:0x%x\n",
 			pdev->id, einfo->regs, einfo->phyregs,
Signature · 1 line
2.14.2
#4 lore raw

Re: [PATCH 3/4] tsi108_eth: use dma API properly

Quoted 8 lines · Christoph Hellwig

We need to pass a struct device to the dma API, even if some architectures still support that for legacy reasons, and should not mix it with the old PCI dma API.

Note that the driver also seems to never actually unmap its dma mappings, but to fix that we'll need someone more familar with the driver.

+ struct platform_device *pdev;

Do you really need platform_defice reference?

Perhaps

struct device *hdev; // hardware device

data->hdev = &pdev->dev;

Another idea

dev->dev.parent = &pdev->dev;

No new member needed.

Quoted 86 lines

};

/* Structure for a device driver */

drivers/net/ethernet/tundra/tsi108_eth.c +18 -17
@@ -703,17 +705,18 @@ static int tsi108_send_packet(struct sk_buff * skb, struct net_device *dev)
                data->txskbs[tx] = skb;
 
                if (i == 0) {
-                       data->txring[tx].buf0 = dma_map_single(NULL, skb->data,
-                                       skb_headlen(skb), DMA_TO_DEVICE);
+                       data->txring[tx].buf0 = dma_map_single(&data->pdev->dev,
+                                       skb->data, skb_headlen(skb),
+                                       DMA_TO_DEVICE);
                        data->txring[tx].len = skb_headlen(skb);
                        misc |= TSI108_TX_SOF;
                } else {
                        const skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1];
 
-                       data->txring[tx].buf0 = skb_frag_dma_map(NULL, frag,
-                                                                0,
-                                                                skb_frag_size(frag),
-                                                                DMA_TO_DEVICE);
+                       data->txring[tx].buf0 =
+                               skb_frag_dma_map(&data->pdev->dev, frag,
+                                               0, skb_frag_size(frag),
+                                               DMA_TO_DEVICE);
                        data->txring[tx].len = skb_frag_size(frag);
                }
 
@@ -808,9 +811,9 @@ static int tsi108_refill_rx(struct net_device *dev, int budget)
                if (!skb)
                        break;
 
-               data->rxring[rx].buf0 = dma_map_single(NULL, skb->data,
-                                                       TSI108_RX_SKB_SIZE,
-                                                       DMA_FROM_DEVICE);
+               data->rxring[rx].buf0 = dma_map_single(&data->pdev->dev,
+                               skb->data, TSI108_RX_SKB_SIZE,
+                               DMA_FROM_DEVICE);
 
                /* Sometimes the hardware sets blen to zero after packet
                 * reception, even though the manual says that it's only ever
@@ -1308,15 +1311,15 @@ static int tsi108_open(struct net_device *dev)
                       data->id, dev->irq, dev->name);
        }
 
-       data->rxring = dma_zalloc_coherent(NULL, rxring_size, &data->rxdma,
-                                          GFP_KERNEL);
+       data->rxring = dma_zalloc_coherent(&data->pdev->dev, rxring_size,
+                       &data->rxdma, GFP_KERNEL);
        if (!data->rxring)
                return -ENOMEM;
 
-       data->txring = dma_zalloc_coherent(NULL, txring_size, &data->txdma,
-                                          GFP_KERNEL);
+       data->txring = dma_zalloc_coherent(&data->pdev->dev, txring_size,
+                       &data->txdma, GFP_KERNEL);
        if (!data->txring) {
-               pci_free_consistent(NULL, rxring_size, data->rxring,
+               dma_free_coherent(&data->pdev->dev, rxring_size, data->rxring,
                                    data->rxdma);
                return -ENOMEM;
        }
@@ -1428,10 +1431,10 @@ static int tsi108_close(struct net_device *dev)
                dev_kfree_skb(skb);
        }
 
-       dma_free_coherent(0,
+       dma_free_coherent(&data->pdev->dev,
                            TSI108_RXRING_LEN * sizeof(rx_desc),
                            data->rxring, data->rxdma);
-       dma_free_coherent(0,
+       dma_free_coherent(&data->pdev->dev,
                            TSI108_TXRING_LEN * sizeof(tx_desc),
                            data->txring, data->txdma);
 
@@ -1576,6 +1579,7 @@ tsi108_init_one(struct platform_device *pdev)
        printk("tsi108_eth%d: probe...\n", pdev->id);
        data = netdev_priv(dev);
        data->dev = dev;
+       data->pdev = pdev;
 
        pr_debug("tsi108_eth%d:regs:phyresgs:phy:irq_num=0x%x:0x%x:0x%x:0x%x\n",
                        pdev->id, einfo->regs, einfo->phyregs,
--

2.14.2

Signature · 2 lines
With Best Regards,
Andy Shevchenko
#5 lore raw

Re: [PATCH 3/4] tsi108_eth: use dma API properly

Quoted 9 lines · Andy Shevchenko
Quoted 1 line

+ struct platform_device *pdev;

Do you really need platform_defice reference?

Perhaps

struct device *hdev; // hardware device

Quoted 7 lines

data->hdev = &pdev->dev;

Another idea

dev->dev.parent = &pdev->dev;

No new member needed.

Maybe. But what I've done is the simplest change in a long obsolete driver that I don't understand at all. I'd rather keep it simple.

#6 lore raw

Re: [PATCH 3/4] tsi108_eth: use dma API properly

In reply to Christoph Hellwig

[+cc David, FYI, I plan to merge this via PCI along with the rest of Christoph's series]

Quoted 108 lines · Christoph Hellwig

We need to pass a struct device to the dma API, even if some architectures still support that for legacy reasons, and should not mix it with the old PCI dma API.

Note that the driver also seems to never actually unmap its dma mappings, but to fix that we'll need someone more familar with the driver.

---
 drivers/net/ethernet/tundra/tsi108_eth.c | 36 ++++++++++++++++++--------------
 1 file changed, 20 insertions(+), 16 deletions(-)
drivers/net/ethernet/tundra/tsi108_eth.c +20 -16
index 0624b71ab5d4..edcd1e60b30d 100644
@@ -152,6 +152,8 @@ struct tsi108_prv_data {
 	u32 msg_enable;			/* debug message level */
 	struct mii_if_info mii_if;
 	unsigned int init_media;
+
+	struct platform_device *pdev;
 };
 
 /* Structure for a device driver */
@@ -703,17 +705,18 @@ static int tsi108_send_packet(struct sk_buff * skb, struct net_device *dev)
 		data->txskbs[tx] = skb;
 
 		if (i == 0) {
-			data->txring[tx].buf0 = dma_map_single(NULL, skb->data,
-					skb_headlen(skb), DMA_TO_DEVICE);
+			data->txring[tx].buf0 = dma_map_single(&data->pdev->dev,
+					skb->data, skb_headlen(skb),
+					DMA_TO_DEVICE);
 			data->txring[tx].len = skb_headlen(skb);
 			misc |= TSI108_TX_SOF;
 		} else {
 			const skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1];
 
-			data->txring[tx].buf0 = skb_frag_dma_map(NULL, frag,
-								 0,
-								 skb_frag_size(frag),
-								 DMA_TO_DEVICE);
+			data->txring[tx].buf0 =
+				skb_frag_dma_map(&data->pdev->dev, frag,
+						0, skb_frag_size(frag),
+						DMA_TO_DEVICE);
 			data->txring[tx].len = skb_frag_size(frag);
 		}
 
@@ -808,9 +811,9 @@ static int tsi108_refill_rx(struct net_device *dev, int budget)
 		if (!skb)
 			break;
 
-		data->rxring[rx].buf0 = dma_map_single(NULL, skb->data,
-							TSI108_RX_SKB_SIZE,
-							DMA_FROM_DEVICE);
+		data->rxring[rx].buf0 = dma_map_single(&data->pdev->dev,
+				skb->data, TSI108_RX_SKB_SIZE,
+				DMA_FROM_DEVICE);
 
 		/* Sometimes the hardware sets blen to zero after packet
 		 * reception, even though the manual says that it's only ever
@@ -1308,15 +1311,15 @@ static int tsi108_open(struct net_device *dev)
 		       data->id, dev->irq, dev->name);
 	}
 
-	data->rxring = dma_zalloc_coherent(NULL, rxring_size, &data->rxdma,
-					   GFP_KERNEL);
+	data->rxring = dma_zalloc_coherent(&data->pdev->dev, rxring_size,
+			&data->rxdma, GFP_KERNEL);
 	if (!data->rxring)
 		return -ENOMEM;
 
-	data->txring = dma_zalloc_coherent(NULL, txring_size, &data->txdma,
-					   GFP_KERNEL);
+	data->txring = dma_zalloc_coherent(&data->pdev->dev, txring_size,
+			&data->txdma, GFP_KERNEL);
 	if (!data->txring) {
-		pci_free_consistent(NULL, rxring_size, data->rxring,
+		dma_free_coherent(&data->pdev->dev, rxring_size, data->rxring,
 				    data->rxdma);
 		return -ENOMEM;
 	}
@@ -1428,10 +1431,10 @@ static int tsi108_close(struct net_device *dev)
 		dev_kfree_skb(skb);
 	}
 
-	dma_free_coherent(0,
+	dma_free_coherent(&data->pdev->dev,
 			    TSI108_RXRING_LEN * sizeof(rx_desc),
 			    data->rxring, data->rxdma);
-	dma_free_coherent(0,
+	dma_free_coherent(&data->pdev->dev,
 			    TSI108_TXRING_LEN * sizeof(tx_desc),
 			    data->txring, data->txdma);
 
@@ -1576,6 +1579,7 @@ tsi108_init_one(struct platform_device *pdev)
 	printk("tsi108_eth%d: probe...\n", pdev->id);
 	data = netdev_priv(dev);
 	data->dev = dev;
+	data->pdev = pdev;
 
 	pr_debug("tsi108_eth%d:regs:phyresgs:phy:irq_num=0x%x:0x%x:0x%x:0x%x\n",
 			pdev->id, einfo->regs, einfo->phyregs,
Signature · 1 line
2.14.2
maintainer
#7 lore raw

Re: [PATCH 3/4] tsi108_eth: use dma API properly

From: Bjorn Helgaas <[email protected]>
Date: Wed, 17 Jan 2018 18:08:18 -0600

Quoted 2 lines

[+cc David, FYI, I plan to merge this via PCI along with the rest of Christoph's series]

No problem.

#8 lore raw

PATCH 4/4 PCI: Remove NULL device handling from PCI DMA API

In reply to Christoph Hellwig

Historically some ISA drivers used the old PCI DMA API with a NULL pdev argument, but these days this isn't used and not too useful due to the per-device DMA ops, so remove it.

---
 include/linux/pci-dma-compat.h | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)
include/linux/pci-dma-compat.h +13 -14
index d1f9fdade1e0..0dd1a3f7b309 100644
@@ -17,91 +17,90 @@ static inline void *
 pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
 		     dma_addr_t *dma_handle)
 {
-	return dma_alloc_coherent(hwdev == NULL ? NULL : &hwdev->dev, size, dma_handle, GFP_ATOMIC);
+	return dma_alloc_coherent(&hwdev->dev, size, dma_handle, GFP_ATOMIC);
 }
 
 static inline void *
 pci_zalloc_consistent(struct pci_dev *hwdev, size_t size,
 		      dma_addr_t *dma_handle)
 {
-	return dma_zalloc_coherent(hwdev == NULL ? NULL : &hwdev->dev,
-				   size, dma_handle, GFP_ATOMIC);
+	return dma_zalloc_coherent(&hwdev->dev, size, dma_handle, GFP_ATOMIC);
 }
 
 static inline void
 pci_free_consistent(struct pci_dev *hwdev, size_t size,
 		    void *vaddr, dma_addr_t dma_handle)
 {
-	dma_free_coherent(hwdev == NULL ? NULL : &hwdev->dev, size, vaddr, dma_handle);
+	dma_free_coherent(&hwdev->dev, size, vaddr, dma_handle);
 }
 
 static inline dma_addr_t
 pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
 {
-	return dma_map_single(hwdev == NULL ? NULL : &hwdev->dev, ptr, size, (enum dma_data_direction)direction);
+	return dma_map_single(&hwdev->dev, ptr, size, (enum dma_data_direction)direction);
 }
 
 static inline void
 pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
 		 size_t size, int direction)
 {
-	dma_unmap_single(hwdev == NULL ? NULL : &hwdev->dev, dma_addr, size, (enum dma_data_direction)direction);
+	dma_unmap_single(&hwdev->dev, dma_addr, size, (enum dma_data_direction)direction);
 }
 
 static inline dma_addr_t
 pci_map_page(struct pci_dev *hwdev, struct page *page,
 	     unsigned long offset, size_t size, int direction)
 {
-	return dma_map_page(hwdev == NULL ? NULL : &hwdev->dev, page, offset, size, (enum dma_data_direction)direction);
+	return dma_map_page(&hwdev->dev, page, offset, size, (enum dma_data_direction)direction);
 }
 
 static inline void
 pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
 	       size_t size, int direction)
 {
-	dma_unmap_page(hwdev == NULL ? NULL : &hwdev->dev, dma_address, size, (enum dma_data_direction)direction);
+	dma_unmap_page(&hwdev->dev, dma_address, size, (enum dma_data_direction)direction);
 }
 
 static inline int
 pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
 	   int nents, int direction)
 {
-	return dma_map_sg(hwdev == NULL ? NULL : &hwdev->dev, sg, nents, (enum dma_data_direction)direction);
+	return dma_map_sg(&hwdev->dev, sg, nents, (enum dma_data_direction)direction);
 }
 
 static inline void
 pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
 	     int nents, int direction)
 {
-	dma_unmap_sg(hwdev == NULL ? NULL : &hwdev->dev, sg, nents, (enum dma_data_direction)direction);
+	dma_unmap_sg(&hwdev->dev, sg, nents, (enum dma_data_direction)direction);
 }
 
 static inline void
 pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t dma_handle,
 		    size_t size, int direction)
 {
-	dma_sync_single_for_cpu(hwdev == NULL ? NULL : &hwdev->dev, dma_handle, size, (enum dma_data_direction)direction);
+	dma_sync_single_for_cpu(&hwdev->dev, dma_handle, size, (enum dma_data_direction)direction);
 }
 
 static inline void
 pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t dma_handle,
 		    size_t size, int direction)
 {
-	dma_sync_single_for_device(hwdev == NULL ? NULL : &hwdev->dev, dma_handle, size, (enum dma_data_direction)direction);
+	dma_sync_single_for_device(&hwdev->dev, dma_handle, size, (enum dma_data_direction)direction);
 }
 
 static inline void
 pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg,
 		int nelems, int direction)
 {
-	dma_sync_sg_for_cpu(hwdev == NULL ? NULL : &hwdev->dev, sg, nelems, (enum dma_data_direction)direction);
+	dma_sync_sg_for_cpu(&hwdev->dev, sg, nelems, (enum dma_data_direction)direction);
 }
 
 static inline void
 pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg,
 		int nelems, int direction)
 {
-	dma_sync_sg_for_device(hwdev == NULL ? NULL : &hwdev->dev, sg, nelems, (enum dma_data_direction)direction);
+	dma_sync_sg_for_device(&hwdev->dev, sg, nelems, (enum dma_data_direction)direction);
 }
 
 static inline int
Signature · 1 line
2.14.2
#9 lore raw
In reply to Christoph Hellwig

[+cc David]

Quoted 13 lines · Christoph Hellwig

Back before the dawn of time pci_dma_* with a NULL pci_dev argument was used for all kinds of things, e.g. dma mapping for non-PCI devices. All this has been long removed, but it turns out we still care for a NULL pci_dev in the wrappers, and we still have two odd USB drivers that use pci_dma_alloc_consistent for allocating memory while ignoring the dma_addr_t entirely, and a network driver mixing the already wrong usage of dma_* with a NULL device with a single call to pci_free_consistent.

This series switches the two usb drivers to use plain kzalloc, the net driver to properly use the dma API and then removes the handling of the NULL pci_dev in the pci_dma_* wrappers.

Quoted 5 lines

Changes since V1:
- remove allocation failure printks
- use kcalloc
- fix tsi108_eth
- improve changelogs

Applied to pci/dma for v4.16, thanks!