pci_iomap.c 4.2 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
M
Michael S. Tsirkin 已提交
2 3 4 5 6 7 8 9 10 11 12 13
/*
 * Implement the default iomap interfaces
 *
 * (C) Copyright 2004 Linus Torvalds
 */
#include <linux/pci.h>
#include <linux/io.h>

#include <linux/export.h>

#ifdef CONFIG_PCI
/**
M
Michael S. Tsirkin 已提交
14
 * pci_iomap_range - create a virtual mapping cookie for a PCI BAR
M
Michael S. Tsirkin 已提交
15 16
 * @dev: PCI device that owns the BAR
 * @bar: BAR number
M
Michael S. Tsirkin 已提交
17 18
 * @offset: map memory at the given offset in BAR
 * @maxlen: max length of the memory to map
M
Michael S. Tsirkin 已提交
19 20 21 22 23 24 25
 *
 * Using this function you will get a __iomem address to your device BAR.
 * You can access it using ioread*() and iowrite*(). These functions hide
 * the details if this is a MMIO or PIO address space and will just do what
 * you expect from them in the correct way.
 *
 * @maxlen specifies the maximum length to map. If you want to get access to
M
Michael S. Tsirkin 已提交
26
 * the complete BAR from offset to the end, pass %0 here.
M
Michael S. Tsirkin 已提交
27
 * */
M
Michael S. Tsirkin 已提交
28 29 30 31
void __iomem *pci_iomap_range(struct pci_dev *dev,
			      int bar,
			      unsigned long offset,
			      unsigned long maxlen)
M
Michael S. Tsirkin 已提交
32 33 34 35 36
{
	resource_size_t start = pci_resource_start(dev, bar);
	resource_size_t len = pci_resource_len(dev, bar);
	unsigned long flags = pci_resource_flags(dev, bar);

M
Michael S. Tsirkin 已提交
37
	if (len <= offset || !start)
M
Michael S. Tsirkin 已提交
38
		return NULL;
M
Michael S. Tsirkin 已提交
39 40
	len -= offset;
	start += offset;
M
Michael S. Tsirkin 已提交
41 42 43
	if (maxlen && len > maxlen)
		len = maxlen;
	if (flags & IORESOURCE_IO)
44
		return __pci_ioport_map(dev, start, len);
45 46
	if (flags & IORESOURCE_MEM)
		return ioremap(start, len);
M
Michael S. Tsirkin 已提交
47 48 49
	/* What? */
	return NULL;
}
M
Michael S. Tsirkin 已提交
50
EXPORT_SYMBOL(pci_iomap_range);
M
Michael S. Tsirkin 已提交
51

52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
/**
 * pci_iomap_wc_range - create a virtual WC mapping cookie for a PCI BAR
 * @dev: PCI device that owns the BAR
 * @bar: BAR number
 * @offset: map memory at the given offset in BAR
 * @maxlen: max length of the memory to map
 *
 * Using this function you will get a __iomem address to your device BAR.
 * You can access it using ioread*() and iowrite*(). These functions hide
 * the details if this is a MMIO or PIO address space and will just do what
 * you expect from them in the correct way. When possible write combining
 * is used.
 *
 * @maxlen specifies the maximum length to map. If you want to get access to
 * the complete BAR from offset to the end, pass %0 here.
 * */
void __iomem *pci_iomap_wc_range(struct pci_dev *dev,
				 int bar,
				 unsigned long offset,
				 unsigned long maxlen)
{
	resource_size_t start = pci_resource_start(dev, bar);
	resource_size_t len = pci_resource_len(dev, bar);
	unsigned long flags = pci_resource_flags(dev, bar);


	if (flags & IORESOURCE_IO)
		return NULL;

	if (len <= offset || !start)
		return NULL;

	len -= offset;
	start += offset;
	if (maxlen && len > maxlen)
		len = maxlen;

	if (flags & IORESOURCE_MEM)
		return ioremap_wc(start, len);

	/* What? */
	return NULL;
}
EXPORT_SYMBOL_GPL(pci_iomap_wc_range);

M
Michael S. Tsirkin 已提交
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
/**
 * pci_iomap - create a virtual mapping cookie for a PCI BAR
 * @dev: PCI device that owns the BAR
 * @bar: BAR number
 * @maxlen: length of the memory to map
 *
 * Using this function you will get a __iomem address to your device BAR.
 * You can access it using ioread*() and iowrite*(). These functions hide
 * the details if this is a MMIO or PIO address space and will just do what
 * you expect from them in the correct way.
 *
 * @maxlen specifies the maximum length to map. If you want to get access to
 * the complete BAR without checking for its length first, pass %0 here.
 * */
void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
{
	return pci_iomap_range(dev, bar, 0, maxlen);
}
M
Michael S. Tsirkin 已提交
115
EXPORT_SYMBOL(pci_iomap);
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136

/**
 * pci_iomap_wc - create a virtual WC mapping cookie for a PCI BAR
 * @dev: PCI device that owns the BAR
 * @bar: BAR number
 * @maxlen: length of the memory to map
 *
 * Using this function you will get a __iomem address to your device BAR.
 * You can access it using ioread*() and iowrite*(). These functions hide
 * the details if this is a MMIO or PIO address space and will just do what
 * you expect from them in the correct way. When possible write combining
 * is used.
 *
 * @maxlen specifies the maximum length to map. If you want to get access to
 * the complete BAR without checking for its length first, pass %0 here.
 * */
void __iomem *pci_iomap_wc(struct pci_dev *dev, int bar, unsigned long maxlen)
{
	return pci_iomap_wc_range(dev, bar, 0, maxlen);
}
EXPORT_SYMBOL_GPL(pci_iomap_wc);
M
Michael S. Tsirkin 已提交
137
#endif /* CONFIG_PCI */