Blame view

lib/pci_iomap.c 4.21 KB
7328c8f48   Bjorn Helgaas   PCI: Add SPDX GPL...
1
  // SPDX-License-Identifier: GPL-2.0
66eab4df2   Michael S. Tsirkin   lib: add GENERIC_...
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
  /**
eb29d8d2a   Michael S. Tsirkin   pci: add pci_ioma...
14
   * pci_iomap_range - create a virtual mapping cookie for a PCI BAR
66eab4df2   Michael S. Tsirkin   lib: add GENERIC_...
15
16
   * @dev: PCI device that owns the BAR
   * @bar: BAR number
eb29d8d2a   Michael S. Tsirkin   pci: add pci_ioma...
17
18
   * @offset: map memory at the given offset in BAR
   * @maxlen: max length of the memory to map
66eab4df2   Michael S. Tsirkin   lib: add GENERIC_...
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
eb29d8d2a   Michael S. Tsirkin   pci: add pci_ioma...
26
   * the complete BAR from offset to the end, pass %0 here.
66eab4df2   Michael S. Tsirkin   lib: add GENERIC_...
27
   * */
eb29d8d2a   Michael S. Tsirkin   pci: add pci_ioma...
28
29
30
31
  void __iomem *pci_iomap_range(struct pci_dev *dev,
  			      int bar,
  			      unsigned long offset,
  			      unsigned long maxlen)
66eab4df2   Michael S. Tsirkin   lib: add GENERIC_...
32
33
34
35
  {
  	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);
eb29d8d2a   Michael S. Tsirkin   pci: add pci_ioma...
36
  	if (len <= offset || !start)
66eab4df2   Michael S. Tsirkin   lib: add GENERIC_...
37
  		return NULL;
eb29d8d2a   Michael S. Tsirkin   pci: add pci_ioma...
38
39
  	len -= offset;
  	start += offset;
66eab4df2   Michael S. Tsirkin   lib: add GENERIC_...
40
41
42
  	if (maxlen && len > maxlen)
  		len = maxlen;
  	if (flags & IORESOURCE_IO)
b923650b8   Michael S. Tsirkin   lib: add NO_GENER...
43
  		return __pci_ioport_map(dev, start, len);
92b19ff50   Dan Williams   cleanup IORESOURC...
44
45
  	if (flags & IORESOURCE_MEM)
  		return ioremap(start, len);
66eab4df2   Michael S. Tsirkin   lib: add GENERIC_...
46
47
48
  	/* What? */
  	return NULL;
  }
eb29d8d2a   Michael S. Tsirkin   pci: add pci_ioma...
49
  EXPORT_SYMBOL(pci_iomap_range);
66eab4df2   Michael S. Tsirkin   lib: add GENERIC_...
50

eb29d8d2a   Michael S. Tsirkin   pci: add pci_ioma...
51
  /**
1b3d4200c   Luis R. Rodriguez   PCI: Add pci_ioma...
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);
  
  /**
eb29d8d2a   Michael S. Tsirkin   pci: add pci_ioma...
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
   * 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);
  }
66eab4df2   Michael S. Tsirkin   lib: add GENERIC_...
114
  EXPORT_SYMBOL(pci_iomap);
1b3d4200c   Luis R. Rodriguez   PCI: Add pci_ioma...
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
  
  /**
   * 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);
66eab4df2   Michael S. Tsirkin   lib: add GENERIC_...
136
  #endif /* CONFIG_PCI */