|
@@ -106,8 +106,12 @@ setup_io_tlb_npages(char *str)
|
|
}
|
|
}
|
|
if (*str == ',')
|
|
if (*str == ',')
|
|
++str;
|
|
++str;
|
|
- if (!strcmp(str, "force"))
|
|
|
|
|
|
+ if (!strcmp(str, "force")) {
|
|
swiotlb_force = SWIOTLB_FORCE;
|
|
swiotlb_force = SWIOTLB_FORCE;
|
|
|
|
+ } else if (!strcmp(str, "noforce")) {
|
|
|
|
+ swiotlb_force = SWIOTLB_NO_FORCE;
|
|
|
|
+ io_tlb_nslabs = 1;
|
|
|
|
+ }
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -543,8 +547,15 @@ static phys_addr_t
|
|
map_single(struct device *hwdev, phys_addr_t phys, size_t size,
|
|
map_single(struct device *hwdev, phys_addr_t phys, size_t size,
|
|
enum dma_data_direction dir, unsigned long attrs)
|
|
enum dma_data_direction dir, unsigned long attrs)
|
|
{
|
|
{
|
|
- dma_addr_t start_dma_addr = phys_to_dma(hwdev, io_tlb_start);
|
|
|
|
|
|
+ dma_addr_t start_dma_addr;
|
|
|
|
+
|
|
|
|
+ if (swiotlb_force == SWIOTLB_NO_FORCE) {
|
|
|
|
+ dev_warn_ratelimited(hwdev, "Cannot do DMA to address %pa\n",
|
|
|
|
+ &phys);
|
|
|
|
+ return SWIOTLB_MAP_ERROR;
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ start_dma_addr = phys_to_dma(hwdev, io_tlb_start);
|
|
return swiotlb_tbl_map_single(hwdev, start_dma_addr, phys, size,
|
|
return swiotlb_tbl_map_single(hwdev, start_dma_addr, phys, size,
|
|
dir, attrs);
|
|
dir, attrs);
|
|
}
|
|
}
|
|
@@ -721,6 +732,9 @@ static void
|
|
swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir,
|
|
swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir,
|
|
int do_panic)
|
|
int do_panic)
|
|
{
|
|
{
|
|
|
|
+ if (swiotlb_force == SWIOTLB_NO_FORCE)
|
|
|
|
+ return;
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Ran out of IOMMU space for this operation. This is very bad.
|
|
* Ran out of IOMMU space for this operation. This is very bad.
|
|
* Unfortunately the drivers cannot handle this operation properly.
|
|
* Unfortunately the drivers cannot handle this operation properly.
|