1*af4a03dfSAugustin Cavalier /*-
2*af4a03dfSAugustin Cavalier * BSD LICENSE
3*af4a03dfSAugustin Cavalier *
4*af4a03dfSAugustin Cavalier * Copyright (c) Intel Corporation. All rights reserved.
5*af4a03dfSAugustin Cavalier * Copyright (c) 2017, Western Digital Corporation or its affiliates.
6*af4a03dfSAugustin Cavalier *
7*af4a03dfSAugustin Cavalier * Redistribution and use in source and binary forms, with or without
8*af4a03dfSAugustin Cavalier * modification, are permitted provided that the following conditions
9*af4a03dfSAugustin Cavalier * are met:
10*af4a03dfSAugustin Cavalier *
11*af4a03dfSAugustin Cavalier * * Redistributions of source code must retain the above copyright
12*af4a03dfSAugustin Cavalier * notice, this list of conditions and the following disclaimer.
13*af4a03dfSAugustin Cavalier * * Redistributions in binary form must reproduce the above copyright
14*af4a03dfSAugustin Cavalier * notice, this list of conditions and the following disclaimer in
15*af4a03dfSAugustin Cavalier * the documentation and/or other materials provided with the
16*af4a03dfSAugustin Cavalier * distribution.
17*af4a03dfSAugustin Cavalier * * Neither the name of Intel Corporation nor the names of its
18*af4a03dfSAugustin Cavalier * contributors may be used to endorse or promote products derived
19*af4a03dfSAugustin Cavalier * from this software without specific prior written permission.
20*af4a03dfSAugustin Cavalier *
21*af4a03dfSAugustin Cavalier * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22*af4a03dfSAugustin Cavalier * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23*af4a03dfSAugustin Cavalier * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24*af4a03dfSAugustin Cavalier * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25*af4a03dfSAugustin Cavalier * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26*af4a03dfSAugustin Cavalier * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27*af4a03dfSAugustin Cavalier * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28*af4a03dfSAugustin Cavalier * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29*af4a03dfSAugustin Cavalier * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30*af4a03dfSAugustin Cavalier * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31*af4a03dfSAugustin Cavalier * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32*af4a03dfSAugustin Cavalier */
33*af4a03dfSAugustin Cavalier
34*af4a03dfSAugustin Cavalier #ifndef __NVME_PCI_H__
35*af4a03dfSAugustin Cavalier #define __NVME_PCI_H__
36*af4a03dfSAugustin Cavalier
37*af4a03dfSAugustin Cavalier #include "nvme_common.h"
38*af4a03dfSAugustin Cavalier
39*af4a03dfSAugustin Cavalier #ifndef __HAIKU__
40*af4a03dfSAugustin Cavalier #include <pciaccess.h>
41*af4a03dfSAugustin Cavalier #endif
42*af4a03dfSAugustin Cavalier
43*af4a03dfSAugustin Cavalier #define NVME_PCI_PATH_MAX 256
44*af4a03dfSAugustin Cavalier #define NVME_PCI_CFG_SIZE 256
45*af4a03dfSAugustin Cavalier #define NVME_PCI_EXT_CAP_ID_SN 0x03
46*af4a03dfSAugustin Cavalier
47*af4a03dfSAugustin Cavalier #define NVME_PCI_ANY_ID 0xffff
48*af4a03dfSAugustin Cavalier #define NVME_PCI_VID_INTEL 0x8086
49*af4a03dfSAugustin Cavalier #define NVME_PCI_VID_MEMBLAZE 0x1c5f
50*af4a03dfSAugustin Cavalier
51*af4a03dfSAugustin Cavalier /*
52*af4a03dfSAugustin Cavalier * PCI class code for NVMe devices.
53*af4a03dfSAugustin Cavalier *
54*af4a03dfSAugustin Cavalier * Base class code 01h: mass storage
55*af4a03dfSAugustin Cavalier * Subclass code 08h: non-volatile memory
56*af4a03dfSAugustin Cavalier * Programming interface 02h: NVM Express
57*af4a03dfSAugustin Cavalier */
58*af4a03dfSAugustin Cavalier #define NVME_PCI_CLASS 0x010802
59*af4a03dfSAugustin Cavalier
60*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_SNB0 0x3c20
61*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_SNB1 0x3c21
62*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_SNB2 0x3c22
63*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_SNB3 0x3c23
64*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_SNB4 0x3c24
65*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_SNB5 0x3c25
66*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_SNB6 0x3c26
67*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_SNB7 0x3c27
68*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_SNB8 0x3c2e
69*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_SNB9 0x3c2f
70*af4a03dfSAugustin Cavalier
71*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_IVB0 0x0e20
72*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_IVB1 0x0e21
73*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_IVB2 0x0e22
74*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_IVB3 0x0e23
75*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_IVB4 0x0e24
76*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_IVB5 0x0e25
77*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_IVB6 0x0e26
78*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_IVB7 0x0e27
79*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_IVB8 0x0e2e
80*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_IVB9 0x0e2f
81*af4a03dfSAugustin Cavalier
82*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_HSW0 0x2f20
83*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_HSW1 0x2f21
84*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_HSW2 0x2f22
85*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_HSW3 0x2f23
86*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_HSW4 0x2f24
87*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_HSW5 0x2f25
88*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_HSW6 0x2f26
89*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_HSW7 0x2f27
90*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_HSW8 0x2f2e
91*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_HSW9 0x2f2f
92*af4a03dfSAugustin Cavalier
93*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_BWD0 0x0C50
94*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_BWD1 0x0C51
95*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_BWD2 0x0C52
96*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_BWD3 0x0C53
97*af4a03dfSAugustin Cavalier
98*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_BDXDE0 0x6f50
99*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_BDXDE1 0x6f51
100*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_BDXDE2 0x6f52
101*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_BDXDE3 0x6f53
102*af4a03dfSAugustin Cavalier
103*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_BDX0 0x6f20
104*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_BDX1 0x6f21
105*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_BDX2 0x6f22
106*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_BDX3 0x6f23
107*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_BDX4 0x6f24
108*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_BDX5 0x6f25
109*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_BDX6 0x6f26
110*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_BDX7 0x6f27
111*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_BDX8 0x6f2e
112*af4a03dfSAugustin Cavalier #define NVME_PCI_DEVICE_ID_INTEL_IOAT_BDX9 0x6f2f
113*af4a03dfSAugustin Cavalier
114*af4a03dfSAugustin Cavalier struct pci_slot_match;
115*af4a03dfSAugustin Cavalier
116*af4a03dfSAugustin Cavalier struct pci_id {
117*af4a03dfSAugustin Cavalier uint16_t vendor_id;
118*af4a03dfSAugustin Cavalier uint16_t device_id;
119*af4a03dfSAugustin Cavalier uint16_t subvendor_id;
120*af4a03dfSAugustin Cavalier uint16_t subdevice_id;
121*af4a03dfSAugustin Cavalier };
122*af4a03dfSAugustin Cavalier
123*af4a03dfSAugustin Cavalier /*
124*af4a03dfSAugustin Cavalier * Initialize PCI subsystem.
125*af4a03dfSAugustin Cavalier */
126*af4a03dfSAugustin Cavalier extern int nvme_pci_init(void);
127*af4a03dfSAugustin Cavalier
128*af4a03dfSAugustin Cavalier /*
129*af4a03dfSAugustin Cavalier * Search a PCI device and grab it if found.
130*af4a03dfSAugustin Cavalier */
131*af4a03dfSAugustin Cavalier extern struct pci_device *
132*af4a03dfSAugustin Cavalier nvme_pci_device_probe(const struct pci_slot_match *slot);
133*af4a03dfSAugustin Cavalier
134*af4a03dfSAugustin Cavalier /*
135*af4a03dfSAugustin Cavalier * Reset a PCI device.
136*af4a03dfSAugustin Cavalier */
137*af4a03dfSAugustin Cavalier extern int nvme_pci_device_reset(struct pci_device *dev);
138*af4a03dfSAugustin Cavalier
139*af4a03dfSAugustin Cavalier /*
140*af4a03dfSAugustin Cavalier * Get a device serial number.
141*af4a03dfSAugustin Cavalier */
142*af4a03dfSAugustin Cavalier extern int nvme_pci_device_get_serial_number(struct pci_device *dev,
143*af4a03dfSAugustin Cavalier char *sn, size_t len);
144*af4a03dfSAugustin Cavalier
145*af4a03dfSAugustin Cavalier /*
146*af4a03dfSAugustin Cavalier * Compare two devices.
147*af4a03dfSAugustin Cavalier * Return 0 if the devices are the same, 1 otherwise.
148*af4a03dfSAugustin Cavalier */
nvme_pci_dev_cmp(struct pci_device * pci_dev1,struct pci_device * pci_dev2)149*af4a03dfSAugustin Cavalier static inline int nvme_pci_dev_cmp(struct pci_device *pci_dev1,
150*af4a03dfSAugustin Cavalier struct pci_device *pci_dev2)
151*af4a03dfSAugustin Cavalier {
152*af4a03dfSAugustin Cavalier if (pci_dev1 == pci_dev2)
153*af4a03dfSAugustin Cavalier return 0;
154*af4a03dfSAugustin Cavalier
155*af4a03dfSAugustin Cavalier if (pci_dev1->domain == pci_dev2->domain &&
156*af4a03dfSAugustin Cavalier pci_dev1->bus == pci_dev2->bus &&
157*af4a03dfSAugustin Cavalier pci_dev1->dev == pci_dev2->dev &&
158*af4a03dfSAugustin Cavalier pci_dev1->func == pci_dev2->func)
159*af4a03dfSAugustin Cavalier return 0;
160*af4a03dfSAugustin Cavalier
161*af4a03dfSAugustin Cavalier return 1;
162*af4a03dfSAugustin Cavalier }
163*af4a03dfSAugustin Cavalier
164*af4a03dfSAugustin Cavalier /*
165*af4a03dfSAugustin Cavalier * Get a device PCI ID.
166*af4a03dfSAugustin Cavalier */
nvme_pci_get_pci_id(struct pci_device * pci_dev,struct pci_id * pci_id)167*af4a03dfSAugustin Cavalier static inline void nvme_pci_get_pci_id(struct pci_device *pci_dev,
168*af4a03dfSAugustin Cavalier struct pci_id *pci_id)
169*af4a03dfSAugustin Cavalier {
170*af4a03dfSAugustin Cavalier pci_id->vendor_id = pci_dev->vendor_id;
171*af4a03dfSAugustin Cavalier pci_id->device_id = pci_dev->device_id;
172*af4a03dfSAugustin Cavalier pci_id->subvendor_id = pci_dev->subvendor_id;
173*af4a03dfSAugustin Cavalier pci_id->subdevice_id = pci_dev->subdevice_id;
174*af4a03dfSAugustin Cavalier }
175*af4a03dfSAugustin Cavalier
176*af4a03dfSAugustin Cavalier #ifdef __HAIKU__
177*af4a03dfSAugustin Cavalier int nvme_pcicfg_read8(struct pci_device *dev, uint8_t *value, uint32_t offset);
178*af4a03dfSAugustin Cavalier int nvme_pcicfg_write8(struct pci_device *dev, uint8_t value, uint32_t offset);
179*af4a03dfSAugustin Cavalier int nvme_pcicfg_read16(struct pci_device *dev, uint16_t *value, uint32_t offset);
180*af4a03dfSAugustin Cavalier int nvme_pcicfg_write16(struct pci_device *dev, uint16_t value, uint32_t offset);
181*af4a03dfSAugustin Cavalier int nvme_pcicfg_read32(struct pci_device *dev, uint32_t *value, uint32_t offset);
182*af4a03dfSAugustin Cavalier int nvme_pcicfg_write32(struct pci_device *dev, uint32_t value, uint32_t offset);
183*af4a03dfSAugustin Cavalier int nvme_pcicfg_map_bar(void *devhandle, unsigned int bar, bool read_only,
184*af4a03dfSAugustin Cavalier void **mapped_addr);
185*af4a03dfSAugustin Cavalier int nvme_pcicfg_map_bar_write_combine(void *devhandle, unsigned int bar,
186*af4a03dfSAugustin Cavalier void **mapped_addr);
187*af4a03dfSAugustin Cavalier int nvme_pcicfg_unmap_bar(void *devhandle, unsigned int bar, void *addr);
188*af4a03dfSAugustin Cavalier void nvme_pcicfg_get_bar_addr_len(void *devhandle, unsigned int bar,
189*af4a03dfSAugustin Cavalier uint64_t *addr, uint64_t *size);
190*af4a03dfSAugustin Cavalier #else
191*af4a03dfSAugustin Cavalier /*
192*af4a03dfSAugustin Cavalier * Read a device config register.
193*af4a03dfSAugustin Cavalier */
nvme_pcicfg_read8(struct pci_device * dev,uint8_t * value,uint32_t offset)194*af4a03dfSAugustin Cavalier static inline int nvme_pcicfg_read8(struct pci_device *dev,
195*af4a03dfSAugustin Cavalier uint8_t *value, uint32_t offset)
196*af4a03dfSAugustin Cavalier {
197*af4a03dfSAugustin Cavalier return pci_device_cfg_read_u8(dev, value, offset);
198*af4a03dfSAugustin Cavalier }
199*af4a03dfSAugustin Cavalier
200*af4a03dfSAugustin Cavalier /*
201*af4a03dfSAugustin Cavalier * Write a device config register.
202*af4a03dfSAugustin Cavalier */
nvme_pcicfg_write8(struct pci_device * dev,uint8_t value,uint32_t offset)203*af4a03dfSAugustin Cavalier static inline int nvme_pcicfg_write8(struct pci_device *dev,
204*af4a03dfSAugustin Cavalier uint8_t value, uint32_t offset)
205*af4a03dfSAugustin Cavalier {
206*af4a03dfSAugustin Cavalier return pci_device_cfg_write_u8(dev, value, offset);
207*af4a03dfSAugustin Cavalier }
208*af4a03dfSAugustin Cavalier
209*af4a03dfSAugustin Cavalier /*
210*af4a03dfSAugustin Cavalier * Read a device config register.
211*af4a03dfSAugustin Cavalier */
nvme_pcicfg_read16(struct pci_device * dev,uint16_t * value,uint32_t offset)212*af4a03dfSAugustin Cavalier static inline int nvme_pcicfg_read16(struct pci_device *dev,
213*af4a03dfSAugustin Cavalier uint16_t *value, uint32_t offset)
214*af4a03dfSAugustin Cavalier {
215*af4a03dfSAugustin Cavalier return pci_device_cfg_read_u16(dev, value, offset);
216*af4a03dfSAugustin Cavalier }
217*af4a03dfSAugustin Cavalier
218*af4a03dfSAugustin Cavalier /*
219*af4a03dfSAugustin Cavalier * Write a device config register.
220*af4a03dfSAugustin Cavalier */
nvme_pcicfg_write16(struct pci_device * dev,uint16_t value,uint32_t offset)221*af4a03dfSAugustin Cavalier static inline int nvme_pcicfg_write16(struct pci_device *dev,
222*af4a03dfSAugustin Cavalier uint16_t value, uint32_t offset)
223*af4a03dfSAugustin Cavalier {
224*af4a03dfSAugustin Cavalier return pci_device_cfg_write_u16(dev, value, offset);
225*af4a03dfSAugustin Cavalier }
226*af4a03dfSAugustin Cavalier
227*af4a03dfSAugustin Cavalier /*
228*af4a03dfSAugustin Cavalier * Read a device config register.
229*af4a03dfSAugustin Cavalier */
nvme_pcicfg_read32(struct pci_device * dev,uint32_t * value,uint32_t offset)230*af4a03dfSAugustin Cavalier static inline int nvme_pcicfg_read32(struct pci_device *dev,
231*af4a03dfSAugustin Cavalier uint32_t *value, uint32_t offset)
232*af4a03dfSAugustin Cavalier {
233*af4a03dfSAugustin Cavalier return pci_device_cfg_read_u32(dev, value, offset);
234*af4a03dfSAugustin Cavalier }
235*af4a03dfSAugustin Cavalier
236*af4a03dfSAugustin Cavalier /*
237*af4a03dfSAugustin Cavalier * Write a device config register.
238*af4a03dfSAugustin Cavalier */
nvme_pcicfg_write32(struct pci_device * dev,uint32_t value,uint32_t offset)239*af4a03dfSAugustin Cavalier static inline int nvme_pcicfg_write32(struct pci_device *dev,
240*af4a03dfSAugustin Cavalier uint32_t value, uint32_t offset)
241*af4a03dfSAugustin Cavalier {
242*af4a03dfSAugustin Cavalier return pci_device_cfg_write_u32(dev, value, offset);
243*af4a03dfSAugustin Cavalier }
244*af4a03dfSAugustin Cavalier
245*af4a03dfSAugustin Cavalier /*
246*af4a03dfSAugustin Cavalier * Map a device PCI BAR.
247*af4a03dfSAugustin Cavalier */
nvme_pcicfg_map_bar(void * devhandle,unsigned int bar,bool read_only,void ** mapped_addr)248*af4a03dfSAugustin Cavalier static inline int nvme_pcicfg_map_bar(void *devhandle, unsigned int bar,
249*af4a03dfSAugustin Cavalier bool read_only, void **mapped_addr)
250*af4a03dfSAugustin Cavalier {
251*af4a03dfSAugustin Cavalier struct pci_device *dev = devhandle;
252*af4a03dfSAugustin Cavalier uint32_t flags = (read_only ? 0 : PCI_DEV_MAP_FLAG_WRITABLE);
253*af4a03dfSAugustin Cavalier
254*af4a03dfSAugustin Cavalier return pci_device_map_range(dev, dev->regions[bar].base_addr,
255*af4a03dfSAugustin Cavalier dev->regions[bar].size, flags, mapped_addr);
256*af4a03dfSAugustin Cavalier }
257*af4a03dfSAugustin Cavalier
258*af4a03dfSAugustin Cavalier /*
259*af4a03dfSAugustin Cavalier * Map a device PCI BAR (write combine).
260*af4a03dfSAugustin Cavalier */
nvme_pcicfg_map_bar_write_combine(void * devhandle,unsigned int bar,void ** mapped_addr)261*af4a03dfSAugustin Cavalier static inline int nvme_pcicfg_map_bar_write_combine(void *devhandle,
262*af4a03dfSAugustin Cavalier unsigned int bar,
263*af4a03dfSAugustin Cavalier void **mapped_addr)
264*af4a03dfSAugustin Cavalier {
265*af4a03dfSAugustin Cavalier struct pci_device *dev = devhandle;
266*af4a03dfSAugustin Cavalier uint32_t flags = PCI_DEV_MAP_FLAG_WRITABLE |
267*af4a03dfSAugustin Cavalier PCI_DEV_MAP_FLAG_WRITE_COMBINE;
268*af4a03dfSAugustin Cavalier
269*af4a03dfSAugustin Cavalier return pci_device_map_range(dev, dev->regions[bar].base_addr,
270*af4a03dfSAugustin Cavalier dev->regions[bar].size, flags, mapped_addr);
271*af4a03dfSAugustin Cavalier }
272*af4a03dfSAugustin Cavalier
273*af4a03dfSAugustin Cavalier /*
274*af4a03dfSAugustin Cavalier * Unmap a device PCI BAR.
275*af4a03dfSAugustin Cavalier */
nvme_pcicfg_unmap_bar(void * devhandle,unsigned int bar,void * addr)276*af4a03dfSAugustin Cavalier static inline int nvme_pcicfg_unmap_bar(void *devhandle, unsigned int bar,
277*af4a03dfSAugustin Cavalier void *addr)
278*af4a03dfSAugustin Cavalier {
279*af4a03dfSAugustin Cavalier struct pci_device *dev = devhandle;
280*af4a03dfSAugustin Cavalier
281*af4a03dfSAugustin Cavalier return pci_device_unmap_range(dev, addr, dev->regions[bar].size);
282*af4a03dfSAugustin Cavalier }
283*af4a03dfSAugustin Cavalier
284*af4a03dfSAugustin Cavalier /*
285*af4a03dfSAugustin Cavalier * Get a device PCI BAR address and length.
286*af4a03dfSAugustin Cavalier */
nvme_pcicfg_get_bar_addr_len(void * devhandle,unsigned int bar,uint64_t * addr,uint64_t * size)287*af4a03dfSAugustin Cavalier static inline void nvme_pcicfg_get_bar_addr_len(void *devhandle,
288*af4a03dfSAugustin Cavalier unsigned int bar,
289*af4a03dfSAugustin Cavalier uint64_t *addr, uint64_t *size)
290*af4a03dfSAugustin Cavalier {
291*af4a03dfSAugustin Cavalier struct pci_device *dev = devhandle;
292*af4a03dfSAugustin Cavalier
293*af4a03dfSAugustin Cavalier *addr = (uint64_t)dev->regions[bar].base_addr;
294*af4a03dfSAugustin Cavalier *size = (uint64_t)dev->regions[bar].size;
295*af4a03dfSAugustin Cavalier }
296*af4a03dfSAugustin Cavalier #endif
297*af4a03dfSAugustin Cavalier
298*af4a03dfSAugustin Cavalier #endif /* __NVME_PCI_H__ */
299