From 244b2c5ca8b14627e4a17755e5922221e121c771 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 09 Oct 2024 06:15:07 +0000
Subject: [PATCH] change system file
---
kernel/arch/ia64/hp/common/sba_iommu.c | 216 +++++++++++++++++------------------------------------
1 files changed, 71 insertions(+), 145 deletions(-)
diff --git a/kernel/arch/ia64/hp/common/sba_iommu.c b/kernel/arch/ia64/hp/common/sba_iommu.c
index 671ce1e..9148ddb 100644
--- a/kernel/arch/ia64/hp/common/sba_iommu.c
+++ b/kernel/arch/ia64/hp/common/sba_iommu.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
** IA64 System Bus Adapter (SBA) I/O MMU manager
**
@@ -8,10 +9,6 @@
** Portions (c) 2000 Grant Grundler (from parisc I/O MMU code)
** Portions (c) 1999 Dave S. Miller (from sparc64 I/O MMU code)
**
-** 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 Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
**
**
** This module initializes the IOC (I/O Controller) found on HP
@@ -36,8 +33,9 @@
#include <linux/bitops.h> /* hweight64() */
#include <linux/crash_dump.h>
#include <linux/iommu-helper.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-map-ops.h>
#include <linux/prefetch.h>
+#include <linux/swiotlb.h>
#include <asm/delay.h> /* ia64_get_itc() */
#include <asm/io.h>
@@ -45,8 +43,6 @@
#include <asm/dma.h>
#include <asm/acpi-ext.h>
-
-extern int swiotlb_late_init_with_default_size (size_t size);
#define PFX "IOC: "
@@ -254,12 +250,8 @@
static u64 prefetch_spill_page;
#endif
-#ifdef CONFIG_PCI
-# define GET_IOC(dev) ((dev_is_pci(dev)) \
+#define GET_IOC(dev) ((dev_is_pci(dev)) \
? ((struct ioc *) PCI_CONTROLLER(to_pci_dev(dev))->iommu) : NULL)
-#else
-# define GET_IOC(dev) NULL
-#endif
/*
** DMA_CHUNK_SIZE is used by the SCSI mid-layer to break up
@@ -493,8 +485,7 @@
ASSERT(((unsigned long) ioc->res_hint & (sizeof(unsigned long) - 1UL)) == 0);
ASSERT(res_ptr < res_end);
- boundary_size = (unsigned long long)dma_get_seg_boundary(dev) + 1;
- boundary_size = ALIGN(boundary_size, 1ULL << iovp_shift) >> iovp_shift;
+ boundary_size = dma_get_seg_boundary_nr_pages(dev, iovp_shift);
BUG_ON(ioc->ibase & ~iovp_mask);
shift = ioc->ibase >> iovp_shift;
@@ -907,14 +898,15 @@
}
/**
- * sba_map_single_attrs - map one buffer and return IOVA for DMA
+ * sba_map_page - map one buffer and return IOVA for DMA
* @dev: instance of PCI owned by the driver that's asking.
- * @addr: driver buffer to map.
- * @size: number of bytes to map in driver buffer.
- * @dir: R/W or both.
+ * @page: page to map
+ * @poff: offset into page
+ * @size: number of bytes to map
+ * @dir: dma direction
* @attrs: optional dma attributes
*
- * See Documentation/DMA-API-HOWTO.txt
+ * See Documentation/core-api/dma-api-howto.rst
*/
static dma_addr_t sba_map_page(struct device *dev, struct page *page,
unsigned long poff, size_t size,
@@ -944,7 +936,7 @@
** Device is bit capable of DMA'ing to the buffer...
** just return the PCI address of ptr
*/
- DBG_BYPASS("sba_map_single_attrs() bypass mask/addr: "
+ DBG_BYPASS("sba_map_page() bypass mask/addr: "
"0x%lx/0x%lx\n",
to_pci_dev(dev)->dma_mask, pci_addr);
return pci_addr;
@@ -966,14 +958,14 @@
#ifdef ASSERT_PDIR_SANITY
spin_lock_irqsave(&ioc->res_lock, flags);
- if (sba_check_pdir(ioc,"Check before sba_map_single_attrs()"))
+ if (sba_check_pdir(ioc,"Check before sba_map_page()"))
panic("Sanity check failed");
spin_unlock_irqrestore(&ioc->res_lock, flags);
#endif
pide = sba_alloc_range(ioc, dev, size);
if (pide < 0)
- return 0;
+ return DMA_MAPPING_ERROR;
iovp = (dma_addr_t) pide << iovp_shift;
@@ -997,18 +989,10 @@
/* form complete address */
#ifdef ASSERT_PDIR_SANITY
spin_lock_irqsave(&ioc->res_lock, flags);
- sba_check_pdir(ioc,"Check after sba_map_single_attrs()");
+ sba_check_pdir(ioc,"Check after sba_map_page()");
spin_unlock_irqrestore(&ioc->res_lock, flags);
#endif
return SBA_IOVA(ioc, iovp, offset);
-}
-
-static dma_addr_t sba_map_single_attrs(struct device *dev, void *addr,
- size_t size, enum dma_data_direction dir,
- unsigned long attrs)
-{
- return sba_map_page(dev, virt_to_page(addr),
- (unsigned long)addr & ~PAGE_MASK, size, dir, attrs);
}
#ifdef ENABLE_MARK_CLEAN
@@ -1036,14 +1020,14 @@
#endif
/**
- * sba_unmap_single_attrs - unmap one IOVA and free resources
+ * sba_unmap_page - unmap one IOVA and free resources
* @dev: instance of PCI owned by the driver that's asking.
* @iova: IOVA of driver buffer previously mapped.
* @size: number of bytes mapped in driver buffer.
* @dir: R/W or both.
* @attrs: optional dma attributes
*
- * See Documentation/DMA-API-HOWTO.txt
+ * See Documentation/core-api/dma-api-howto.rst
*/
static void sba_unmap_page(struct device *dev, dma_addr_t iova, size_t size,
enum dma_data_direction dir, unsigned long attrs)
@@ -1063,7 +1047,7 @@
/*
** Address does not fall w/in IOVA, must be bypassing
*/
- DBG_BYPASS("sba_unmap_single_attrs() bypass addr: 0x%lx\n",
+ DBG_BYPASS("sba_unmap_page() bypass addr: 0x%lx\n",
iova);
#ifdef ENABLE_MARK_CLEAN
@@ -1114,48 +1098,36 @@
#endif /* DELAYED_RESOURCE_CNT == 0 */
}
-void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size,
- enum dma_data_direction dir, unsigned long attrs)
-{
- sba_unmap_page(dev, iova, size, dir, attrs);
-}
-
/**
* sba_alloc_coherent - allocate/map shared mem for DMA
* @dev: instance of PCI owned by the driver that's asking.
* @size: number of bytes mapped in driver buffer.
* @dma_handle: IOVA of new buffer.
*
- * See Documentation/DMA-API-HOWTO.txt
+ * See Documentation/core-api/dma-api-howto.rst
*/
static void *
sba_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
gfp_t flags, unsigned long attrs)
{
+ struct page *page;
struct ioc *ioc;
+ int node = -1;
void *addr;
ioc = GET_IOC(dev);
ASSERT(ioc);
-
#ifdef CONFIG_NUMA
- {
- struct page *page;
-
- page = alloc_pages_node(ioc->node, flags, get_order(size));
- if (unlikely(!page))
- return NULL;
-
- addr = page_address(page);
- }
-#else
- addr = (void *) __get_free_pages(flags, get_order(size));
+ node = ioc->node;
#endif
- if (unlikely(!addr))
+
+ page = alloc_pages_node(node, flags, get_order(size));
+ if (unlikely(!page))
return NULL;
+ addr = page_address(page);
memset(addr, 0, size);
- *dma_handle = virt_to_phys(addr);
+ *dma_handle = page_to_phys(page);
#ifdef ALLOW_IOV_BYPASS
ASSERT(dev->coherent_dma_mask);
@@ -1174,9 +1146,10 @@
* If device can't bypass or bypass is disabled, pass the 32bit fake
* device to map single to get an iova mapping.
*/
- *dma_handle = sba_map_single_attrs(&ioc->sac_only_dev->dev, addr,
- size, 0, 0);
-
+ *dma_handle = sba_map_page(&ioc->sac_only_dev->dev, page, 0, size,
+ DMA_BIDIRECTIONAL, 0);
+ if (dma_mapping_error(dev, *dma_handle))
+ return NULL;
return addr;
}
@@ -1188,12 +1161,12 @@
* @vaddr: virtual address IOVA of "consistent" buffer.
* @dma_handler: IO virtual address of "consistent" buffer.
*
- * See Documentation/DMA-API-HOWTO.txt
+ * See Documentation/core-api/dma-api-howto.rst
*/
static void sba_free_coherent(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle, unsigned long attrs)
{
- sba_unmap_single_attrs(dev, dma_handle, size, 0, 0);
+ sba_unmap_page(dev, dma_handle, size, 0, 0);
free_pages((unsigned long) vaddr, get_order(size));
}
@@ -1451,7 +1424,7 @@
* @dir: R/W or both.
* @attrs: optional dma attributes
*
- * See Documentation/DMA-API-HOWTO.txt
+ * See Documentation/core-api/dma-api-howto.rst
*/
static int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist,
int nents, enum dma_data_direction dir,
@@ -1483,7 +1456,10 @@
/* Fast path single entry scatterlists. */
if (nents == 1) {
sglist->dma_length = sglist->length;
- sglist->dma_address = sba_map_single_attrs(dev, sba_sg_address(sglist), sglist->length, dir, attrs);
+ sglist->dma_address = sba_map_page(dev, sg_page(sglist),
+ sglist->offset, sglist->length, dir, attrs);
+ if (dma_mapping_error(dev, sglist->dma_address))
+ return 0;
return 1;
}
@@ -1547,7 +1523,7 @@
* @dir: R/W or both.
* @attrs: optional dma attributes
*
- * See Documentation/DMA-API-HOWTO.txt
+ * See Documentation/core-api/dma-api-howto.rst
*/
static void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist,
int nents, enum dma_data_direction dir,
@@ -1572,8 +1548,8 @@
while (nents && sglist->dma_length) {
- sba_unmap_single_attrs(dev, sglist->dma_address,
- sglist->dma_length, dir, attrs);
+ sba_unmap_page(dev, sglist->dma_address, sglist->dma_length,
+ dir, attrs);
sglist = sg_next(sglist);
nents--;
}
@@ -1759,9 +1735,7 @@
controller->iommu = ioc;
sac->sysdata = controller;
sac->dma_mask = 0xFFFFFFFFUL;
-#ifdef CONFIG_PCI
sac->dev.bus = &pci_bus_type;
-#endif
ioc->sac_only_dev = sac;
}
@@ -2080,29 +2054,37 @@
/* This has to run before acpi_scan_init(). */
arch_initcall(acpi_sba_ioc_init_acpi);
-extern const struct dma_map_ops swiotlb_dma_ops;
+static int sba_dma_supported (struct device *dev, u64 mask)
+{
+ /* make sure it's at least 32bit capable */
+ return ((mask & 0xFFFFFFFFUL) == 0xFFFFFFFFUL);
+}
+
+static const struct dma_map_ops sba_dma_ops = {
+ .alloc = sba_alloc_coherent,
+ .free = sba_free_coherent,
+ .map_page = sba_map_page,
+ .unmap_page = sba_unmap_page,
+ .map_sg = sba_map_sg_attrs,
+ .unmap_sg = sba_unmap_sg_attrs,
+ .dma_supported = sba_dma_supported,
+ .mmap = dma_common_mmap,
+ .get_sgtable = dma_common_get_sgtable,
+ .alloc_pages = dma_common_alloc_pages,
+ .free_pages = dma_common_free_pages,
+};
static int __init
sba_init(void)
{
- if (!ia64_platform_is("hpzx1") && !ia64_platform_is("hpzx1_swiotlb"))
- return 0;
-
-#if defined(CONFIG_IA64_GENERIC)
- /* If we are booting a kdump kernel, the sba_iommu will
- * cause devices that were not shutdown properly to MCA
- * as soon as they are turned back on. Our only option for
- * a successful kdump kernel boot is to use the swiotlb.
+ /*
+ * If we are booting a kdump kernel, the sba_iommu will cause devices
+ * that were not shutdown properly to MCA as soon as they are turned
+ * back on. Our only option for a successful kdump kernel boot is to
+ * use swiotlb.
*/
- if (is_kdump_kernel()) {
- dma_ops = &swiotlb_dma_ops;
- if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0)
- panic("Unable to initialize software I/O TLB:"
- " Try machvec=dig boot option");
- machvec_init("dig");
+ if (is_kdump_kernel())
return 0;
- }
-#endif
/*
* ioc_found should be populated by the acpi_sba_ioc_handler's .attach()
@@ -2111,43 +2093,18 @@
while (ioc_found)
acpi_sba_ioc_add(ioc_found);
- if (!ioc_list) {
-#ifdef CONFIG_IA64_GENERIC
- /*
- * If we didn't find something sba_iommu can claim, we
- * need to setup the swiotlb and switch to the dig machvec.
- */
- dma_ops = &swiotlb_dma_ops;
- if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0)
- panic("Unable to find SBA IOMMU or initialize "
- "software I/O TLB: Try machvec=dig boot option");
- machvec_init("dig");
-#else
- panic("Unable to find SBA IOMMU: Try a generic or DIG kernel");
-#endif
+ if (!ioc_list)
return 0;
- }
-#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_HP_ZX1_SWIOTLB)
- /*
- * hpzx1_swiotlb needs to have a fairly small swiotlb bounce
- * buffer setup to support devices with smaller DMA masks than
- * sba_iommu can handle.
- */
- if (ia64_platform_is("hpzx1_swiotlb")) {
- extern void hwsw_init(void);
-
- hwsw_init();
- }
-#endif
-
-#ifdef CONFIG_PCI
{
struct pci_bus *b = NULL;
while ((b = pci_find_next_bus(b)) != NULL)
sba_connect_bus(b);
}
-#endif
+
+ /* no need for swiotlb with the iommu */
+ swiotlb_exit();
+ dma_ops = &sba_dma_ops;
#ifdef CONFIG_PROC_FS
ioc_proc_init();
@@ -2162,17 +2119,6 @@
{
reserve_sba_gart = 0;
return 1;
-}
-
-static int sba_dma_supported (struct device *dev, u64 mask)
-{
- /* make sure it's at least 32bit capable */
- return ((mask & 0xFFFFFFFFUL) == 0xFFFFFFFFUL);
-}
-
-static int sba_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
- return 0;
}
__setup("nosbagart", nosbagart);
@@ -2199,23 +2145,3 @@
}
__setup("sbapagesize=",sba_page_override);
-
-const struct dma_map_ops sba_dma_ops = {
- .alloc = sba_alloc_coherent,
- .free = sba_free_coherent,
- .map_page = sba_map_page,
- .unmap_page = sba_unmap_page,
- .map_sg = sba_map_sg_attrs,
- .unmap_sg = sba_unmap_sg_attrs,
- .sync_single_for_cpu = machvec_dma_sync_single,
- .sync_sg_for_cpu = machvec_dma_sync_sg,
- .sync_single_for_device = machvec_dma_sync_single,
- .sync_sg_for_device = machvec_dma_sync_sg,
- .dma_supported = sba_dma_supported,
- .mapping_error = sba_dma_mapping_error,
-};
-
-void sba_dma_init(void)
-{
- dma_ops = &sba_dma_ops;
-}
--
Gitblit v1.6.2