Skip to contentSkip to conversation

IOAT: Add support for version 2 of ioatdma device

RFC PATCH In review Shannon Nelson 2 participants 3 messages Sep 6, 2007 – Sep 7, 2007

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

RFC PATCH 1/1 IOAT: Add support for version 2 of ioatdma device

Add support for version 2 of the ioatdma device. This device handles the descriptor chain and DCA services slightly differently:
- Instead of using a busy chain and an idle chain for the dma descriptors, this new version uses a single chain that loops back to itself. One of the benefits is that we don't have rewrite the next_descriptor pointers as we add new requests, so the device doesn't need to re-read the last descriptor.
- The new device has CPUs' DCA tags defined internally, instead of needing them defined statically in the code.

This patch applies on the recent DCA patches currently in the -mm tree.

---

 drivers/dma/ioat.c              |   33 +-
 drivers/dma/ioat_dca.c          |  164 +++++++++
 drivers/dma/ioat_dma.c          |  699 +++++++++++++++++++++++++++++++++------
 drivers/dma/ioatdma.h           |   33 +-
 drivers/dma/ioatdma_hw.h        |    1 
 drivers/dma/ioatdma_registers.h |  104 +++++-
 include/linux/pci_ids.h         |    1 
 7 files changed, 890 insertions(+), 145 deletions(-)
drivers/dma/ioat.c +23 -10
index f7276bf..e00acba 100644
@@ -34,15 +34,19 @@
 #include "ioatdma_registers.h"
 #include "ioatdma_hw.h"
 
-MODULE_VERSION("1.24");
+MODULE_VERSION("2.02");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Intel Corporation");
 
 static struct pci_device_id ioat_pci_tbl[] = {
+	/* I/OAT v1 platforms */
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB)  },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SCNB) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_UNISYS, PCI_DEVICE_ID_UNISYS_DMA_DIRECTOR) },
+
+	/* I/OAT v2 platforms */
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB) },
 	{ 0, }
 };
 
@@ -53,16 +57,18 @@ struct ioat_device {
 	struct dca_provider	*dca;
 };
 
+static int ioat_dca_enabled = 1;
+module_param(ioat_dca_enabled, int, 0644);
+MODULE_PARM_DESC(ioat_dca_enabled,
+		 "control support of dca service (default: 1)");
+
+
 static int __devinit ioat_probe(struct pci_dev *pdev,
 				const struct pci_device_id *id);
 #ifdef IOAT_DMA_REMOVE
 static void __devexit ioat_remove(struct pci_dev *pdev);
 #endif
 
-static int ioat_dca_enabled = 1;
-module_param(ioat_dca_enabled, int, 0644);
-MODULE_PARM_DESC(ioat_dca_enabled, "control support of dca service (default: 1)");
-
 static int ioat_setup_functionality(struct pci_dev *pdev, void __iomem *iobase)
 {
 	struct ioat_device *device = pci_get_drvdata(pdev);
@@ -73,13 +79,20 @@ static int ioat_setup_functionality(struct pci_dev *pdev, void __iomem *iobase)
 	switch (version) {
 	case IOAT_VER_1_2:
 		device->dma = ioat_dma_probe(pdev, iobase);
-		if (ioat_dca_enabled)
+		if (device->dma && ioat_dca_enabled)
 			device->dca = ioat_dca_init(pdev, iobase);
 		break;
+	case IOAT_VER_2_0:
+		device->dma = ioat_dma_probe(pdev, iobase);
+		if (device->dma && ioat_dca_enabled)
+			device->dca = ioat2_dca_init(pdev, iobase);
+		break;
 	default:
 		err = -ENODEV;
 		break;
 	}
+	if (!device->dma)
+		err = -ENODEV;
 	return err;
 }
 
@@ -100,7 +113,7 @@ static void ioat_shutdown_functionality(struct pci_dev *pdev)
 
 }
 
-static struct pci_driver ioat_pci_drv = {
+static struct pci_driver ioat_pci_driver = {
 	.name		= "ioatdma",
 	.id_table	= ioat_pci_tbl,
 	.probe		= ioat_probe,
@@ -122,7 +135,7 @@ static int __devinit ioat_probe(struct pci_dev *pdev,
 	if (err)
 		goto err_enable_device;
 
-	err = pci_request_regions(pdev, ioat_pci_drv.name);
+	err = pci_request_regions(pdev, ioat_pci_driver.name);
 	if (err)
 		goto err_request_regions;
 
@@ -200,12 +213,12 @@ static void __devexit ioat_remove(struct pci_dev *pdev)
 
 static int __init ioat_init_module(void)
 {
-	return pci_register_driver(&ioat_pci_drv);
+	return pci_register_driver(&ioat_pci_driver);
 }
 module_init(ioat_init_module);
 
 static void __exit ioat_exit_module(void)
 {
-	pci_unregister_driver(&ioat_pci_drv);
+	pci_unregister_driver(&ioat_pci_driver);
 }
 module_exit(ioat_exit_module);
drivers/dma/ioat_dca.c +164 -0

167 lines not on this page · raw message

drivers/dma/ioat_dma.c +599 -100

955 lines not on this page · raw message

drivers/dma/ioatdma.h +13 -20
index 2a319e1..ac86705 100644
@@ -1,5 +1,5 @@
 /*
- * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved.
+ * Copyright(c) 2004 - 2007 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -45,6 +45,9 @@ enum ioat_interrupt {
  * @dma_pool: for allocating DMA descriptors
  * @common: embedded struct dma_device
  * @version: version of ioatdma device
+ * @irq_mode: which style irq to use
+ * @msix_entries: irq handlers
+ * @idx: per channel data
  */
 
 struct ioatdma_device {
@@ -61,23 +64,7 @@ struct ioatdma_device {
 
 /**
  * struct ioat_dma_chan - internal representation of a DMA channel
- * @device:
- * @reg_base:
- * @sw_in_use:
- * @completion:
- * @completion_low:
- * @completion_high:
- * @completed_cookie: last cookie seen completed on cleanup
- * @cookie: value of last cookie given to client
- * @last_completion:
- * @xfercap:
- * @desc_lock:
- * @free_desc:
- * @used_desc:
- * @resource:
- * @device_node:
  */
-
 struct ioat_dma_chan {
 
 	void __iomem *reg_base;
@@ -92,7 +79,12 @@ struct ioat_dma_chan {
 	struct list_head free_desc;
 	struct list_head used_desc;
 
-	int pending;
+	u32 pending;
+	u32 dmacount;
+	int desccount;
+	int check_count;
+	int old_cookie;
+	int reset_count;
 
 	struct ioatdma_device *device;
 	struct dma_chan common;
@@ -132,12 +124,13 @@ struct ioat_desc_sw {
 struct ioatdma_device *ioat_dma_probe(struct pci_dev *pdev,
 				      void __iomem *iobase);
 void ioat_dma_remove(struct ioatdma_device *device);
-struct dca_provider *ioat_dca_init(struct pci_dev *pdev,
-				   void __iomem *iobase);
+struct dca_provider *ioat_dca_init(struct pci_dev *pdev, void __iomem *iobase);
+struct dca_provider *ioat2_dca_init(struct pci_dev *pdev, void __iomem *iobase);
 #else
 #define ioat_dma_probe(pdev, iobase)    NULL
 #define ioat_dma_remove(device)         do { } while (0)
 #define ioat_dca_init(pdev, iobase)	NULL
+#define ioat2_dca_init(pdev, iobase)	NULL
 #endif
 
 #endif /* IOATDMA_H */
drivers/dma/ioatdma_hw.h +1 -0
index 9e7434e..b54c7b3 100644
@@ -28,6 +28,7 @@
 #define IOAT_PCI_SVID			0x8086
 #define IOAT_PCI_SID			0x8086
 #define IOAT_VER_1_2			0x12	/* Version 1.2 */
+#define IOAT_VER_2_0			0x20	/* Version 2.0 */
 
 struct ioat_dma_descriptor {
 	uint32_t	size;
drivers/dma/ioatdma_registers.h +89 -15

146 lines not on this page · raw message

include/linux/pci_ids.h +1 -0
index c82a964..83084a3 100644
@@ -2294,6 +2294,7 @@
 #define PCI_DEVICE_ID_INTEL_MCH_PC1	0x359a
 #define PCI_DEVICE_ID_INTEL_E7525_MCH	0x359e
 #define PCI_DEVICE_ID_INTEL_IOAT_CNB	0x360b
+#define PCI_DEVICE_ID_INTEL_IOAT_SNB	0x402f
 #define PCI_DEVICE_ID_INTEL_IOAT_SCNB	0x65ff
 #define PCI_DEVICE_ID_INTEL_82371SB_0	0x7000
 #define PCI_DEVICE_ID_INTEL_82371SB_1	0x7010
#1 lore raw
Quoted 14 lines · Shannon Nelson
drivers/dma/ioat_dma.c +4 -0
 	list_for_each_entry(iter, &desc->async_tx.tx_list, node) {
 		iter->hw->src_addr = addr;
 		addr += ioat_chan->xfercap;
+
+		if (--cnt == 0);
+			break;
 	}
 
 }
@@ -166,20 +177,28 @@ static void ioat_set_dest(dma_addr_t addr,
 {
 	struct ioat_desc_sw *iter, *desc = tx_to_ioat_desc(tx);
 	struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
+	int cnt = desc->tx_cnt;

drivers/dma/ioat_dma.c static void ioat_set_dest(dma_addr_t addr, · line 190

Quoted 10 lines
drivers/dma/ioat_dma.c +3 -0
 
 	pci_unmap_addr_set(desc, dst, addr);
 
 	list_for_each_entry(iter, &desc->async_tx.tx_list, node) {
 		iter->hw->dst_addr = addr;
 		addr += ioat_chan->xfercap;
+
+		if (--cnt == 0);
+			break;
 	}

Those two look suspect to checkpatch, and I have to agree with it.

WARNING: Trailing semicolon indicates no statements, indent implies otherwise
#346: FILE: drivers/dma/ioat_dma.c:168:
+ if (--cnt == 0);
+ break;
WARNING: Trailing semicolon indicates no statements, indent implies otherwise
#363: FILE: drivers/dma/ioat_dma.c:188:
+ if (--cnt == 0);
+ break;

-apw

#2 lore raw
Quoted 13 lines

From: Andy Whitcroft [mailto:[email protected]]

Those two look suspect to checkpatch, and I have to agree with it.

WARNING: Trailing semicolon indicates no statements, indent implies otherwise
#346: FILE: drivers/dma/ioat_dma.c:168:

(quoted diff) +2 -0
+               if (--cnt == 0);
+                       break;

WARNING: Trailing semicolon indicates no statements, indent implies otherwise
#363: FILE: drivers/dma/ioat_dma.c:188:

drivers/dma/ioat_dma.c static void ioat_set_src(dma_addr_t addr,

Quoted 4 lines
drivers/dma/ioat_dma.c +2 -1
+               if (--cnt == 0);
+                       break;
 
-apw

Ouch - how did I miss those? Thanks!

sln
--
======================================================================
Mr. Shannon Nelson LAN Access Division, Intel Corp.
[email protected] I don't speak for Intel
(503) 712-7659 Parents can't afford to be squeamish.