Blame view

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

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