OSDN Git Service

Add endian macros for BSD.
[android-x86/external-libpciaccess.git] / src / common_interface.c
1 /*
2  * (C) Copyright IBM Corporation 2006
3  * All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * on the rights to use, copy, modify, merge, publish, distribute, sub
9  * license, and/or sell copies of the Software, and to permit persons to whom
10  * the Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
19  * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24
25 /**
26  * \file common_interface.c
27  * Platform independent interface glue.
28  *
29  * \author Ian Romanick <idr@us.ibm.com>
30  */
31
32 #include <stdlib.h>
33 #include <errno.h>
34
35 #include "pciaccess.h"
36 #include "pciaccess_private.h"
37
38 #ifdef __linux__
39 #include <byteswap.h>
40
41 #if __BYTE_ORDER == __BIG_ENDIAN
42 # define LETOH_16(x)   bswap_16(x)
43 # define HTOLE_16(x)   bswap_16(x)
44 # define LETOH_32(x)   bswap_32(x)
45 # define HTOLE_32(x)   bswap_32(x)
46 #else
47 # define LETOH_16(x)   (x)
48 # define HTOLE_16(x)   (x)
49 # define LETOH_32(x)   (x)
50 # define HTOLE_32(x)   (x)
51 #endif
52
53 #else
54
55 #include <sys/endian.h>
56
57 #define LETOH_16(x)     le16toh(x)
58 #define HTOLE_16(x)     htole16(x)
59 #define LETOH_32(x)     le32toh(x)
60 #define HTOLE_32(x)     htole32(x)
61
62 #endif
63
64 /**
65  * Read a device's expansion ROM.
66  * 
67  * Reads the device's expansion ROM and stores the data in the memory pointed
68  * to by \c buffer.  The buffer must be at least \c pci_device::rom_size
69  * bytes.
70  *
71  * \param dev    Device whose expansion ROM is to be read.
72  * \param buffer Memory in which to store the ROM.
73  * 
74  * \return
75  * Zero on success or an \c errno value on failure.
76  */
77 int
78 pci_device_read_rom( struct pci_device * dev, void * buffer )
79 {
80     if ( (dev == NULL) || (buffer == NULL) ) {
81         return EFAULT;
82     }
83
84
85     return (pci_sys->methods->read_rom)( dev, buffer );
86 }
87
88
89 /**
90  * Probe a PCI device to learn information about the device.
91  * 
92  * Probes a PCI device to learn various information about the device.  Before
93  * calling this function, the only public fields in the \c pci_device
94  * structure that have valid values are \c pci_device::domain,
95  * \c pci_device::bus, \c pci_device::dev, and \c pci_device::func.
96  * 
97  * \param dev  Device to be probed.
98  * 
99  * \return
100  * Zero on succes or an \c errno value on failure.
101  */
102 int
103 pci_device_probe( struct pci_device * dev )
104 {
105     if ( dev == NULL ) {
106         return EFAULT;
107     }
108
109
110     return (pci_sys->methods->probe)( dev );
111 }
112
113
114 /**
115  * Map the specified BAR so that it can be accessed by the CPU.
116  *
117  * Maps the specified BAR for acces by the processor.  The pointer to the
118  * mapped region is stored in the \c pci_mem_region::memory pointer for the
119  * BAR.
120  *
121  * \param dev          Device whose memory region is to be mapped.
122  * \param region       Region, on the range [0, 5], that is to be mapped.
123  * \param write_enable Map for writing (non-zero).
124  * 
125  * \return
126  * Zero on success or an \c errno value on failure.
127  *
128  * \sa pci_device_unmap_region
129  */
130 int
131 pci_device_map_region( struct pci_device * dev, unsigned region,
132                        int write_enable )
133 {
134     if ( dev == NULL ) {
135         return EFAULT;
136     }
137
138     if ( (region > 5) || (dev->regions[ region ].size == 0) ) {
139         return ENOENT;
140     }
141
142     if ( dev->regions[ region ].memory != NULL ) {
143         return 0;
144     }
145     
146     return (pci_sys->methods->map)( dev, region, write_enable );
147 }
148
149
150 /**
151  * Unmap the specified BAR so that it can no longer be accessed by the CPU.
152  *
153  * Unmaps the specified BAR that was previously mapped via
154  * \c pci_device_map_region.
155  *
156  * \param dev          Device whose memory region is to be mapped.
157  * \param region       Region, on the range [0, 5], that is to be mapped.
158  * 
159  * \return
160  * Zero on success or an \c errno value on failure.
161  *
162  * \sa pci_device_map_region
163  */
164 int
165 pci_device_unmap_region( struct pci_device * dev, unsigned region )
166 {
167     if ( dev == NULL ) {
168         return EFAULT;
169     }
170
171     if ( (region > 5) || (dev->regions[ region ].size == 0) ) {
172         return ENOENT;
173     }
174
175     if ( dev->regions[ region ].memory == NULL ) {
176         return 0;
177     }
178     
179     return (pci_sys->methods->unmap)( dev, region );
180 }
181
182
183 /**
184  * Read arbitrary bytes from device's PCI config space
185  *
186  * Reads data from the device's PCI configuration space.  As with the system
187  * read command, less data may be returned, without an error, than was
188  * requested.  This is particuarly the case if a non-root user tries to read
189  * beyond the first 64-bytes of configuration space.
190  *
191  * \param dev         Device whose PCI configuration data is to be read.
192  * \param data        Location to store the data
193  * \param offset      Initial byte offset to read
194  * \param size        Total number of bytes to read
195  * \param bytes_read  Location to store the actual number of bytes read.  This
196  *                    pointer may be \c NULL.
197  *
198  * \returns
199  * Zero on success or an errno value on failure.
200  *
201  * \note
202  * Data read from PCI configuartion space using this routine is \b not
203  * byte-swapped to the host's byte order.  PCI configuration data is always
204  * stored in little-endian order, and that is what this routine returns.
205  */
206 int
207 pci_device_cfg_read( struct pci_device * dev, void * data,
208                      pciaddr_t offset, pciaddr_t size, 
209                      pciaddr_t * bytes_read )
210 {
211     pciaddr_t  scratch;
212
213     if ( (dev == NULL) || (data == NULL) ) {
214         return EFAULT;
215     }
216
217     return pci_sys->methods->read( dev, data, offset, size,
218                                    (bytes_read == NULL) 
219                                    ? & scratch : bytes_read );
220 }
221
222
223 int
224 pci_device_cfg_read_u8( struct pci_device * dev, uint8_t * data,
225                         pciaddr_t offset )
226 {
227     pciaddr_t bytes;
228     int err = pci_device_cfg_read( dev, data, offset, 1, & bytes );
229     
230     if ( (err == 0) && (bytes != 1) ) {
231         err = ENXIO;
232     }
233
234     return err;
235 }
236
237
238 int
239 pci_device_cfg_read_u16( struct pci_device * dev, uint16_t * data,
240                          pciaddr_t offset )
241 {
242     pciaddr_t bytes;
243     int err = pci_device_cfg_read( dev, data, offset, 2, & bytes );
244     
245     if ( (err == 0) && (bytes != 2) ) {
246         err = ENXIO;
247     }
248
249     *data = LETOH_16( *data );
250     return err;
251 }
252
253
254 int
255 pci_device_cfg_read_u32( struct pci_device * dev, uint32_t * data,
256                          pciaddr_t offset )
257 {
258     pciaddr_t bytes;
259     int err = pci_device_cfg_read( dev, data, offset, 4, & bytes );
260
261     if ( (err == 0) && (bytes != 4) ) {
262         err = ENXIO;
263     }
264
265     *data = LETOH_32( *data );
266     return err;
267 }
268
269
270 /**
271  * Write arbitrary bytes to device's PCI config space
272  *
273  * Writess data to the device's PCI configuration space.  As with the system
274  * write command, less data may be written, without an error, than was
275  * requested.
276  *
277  * \param dev         Device whose PCI configuration data is to be written.
278  * \param data        Location of the source data
279  * \param offset      Initial byte offset to write
280  * \param size        Total number of bytes to write
281  * \param bytes_read  Location to store the actual number of bytes written.
282  *                    This pointer may be \c NULL.
283  *
284  * \returns
285  * Zero on success or an errno value on failure.
286  *
287  * \note
288  * Data written to PCI configuartion space using this routine is \b not
289  * byte-swapped from the host's byte order.  PCI configuration data is always
290  * stored in little-endian order, so data written with this routine should be
291  * put in that order in advance.
292  */
293 int
294 pci_device_cfg_write( struct pci_device * dev, const void * data,
295                       pciaddr_t offset, pciaddr_t size, 
296                       pciaddr_t * bytes_written )
297 {
298     pciaddr_t  scratch;
299
300     if ( (dev == NULL) || (data == NULL) ) {
301         return EFAULT;
302     }
303
304     return pci_sys->methods->write( dev, data, offset, size,
305                                     (bytes_written == NULL) 
306                                     ? & scratch : bytes_written );
307 }
308
309
310 int
311 pci_device_cfg_write_u8( struct pci_device * dev, const uint8_t * data,
312                          pciaddr_t offset )
313 {
314     pciaddr_t bytes;
315     int err = pci_device_cfg_write( dev, data, offset, 1, & bytes );
316
317     if ( (err == 0) && (bytes != 1) ) {
318         err = ENOSPC;
319     }
320
321
322     return err;
323 }
324   
325
326 int
327 pci_device_cfg_write_u16( struct pci_device * dev, const uint16_t * data,
328                           pciaddr_t offset )
329 {
330     pciaddr_t bytes;
331     const uint16_t temp = HTOLE_16( *data );
332     int err = pci_device_cfg_write( dev, & temp, offset, 2, & bytes );
333
334     if ( (err == 0) && (bytes != 2) ) {
335         err = ENOSPC;
336     }
337
338
339     return err;
340 }
341
342
343 int
344 pci_device_cfg_write_u32( struct pci_device * dev, const uint32_t * data,
345                           pciaddr_t offset )
346 {
347     pciaddr_t bytes;
348     const uint32_t temp = HTOLE_32( *data );
349     int err = pci_device_cfg_write( dev, & temp, offset, 4, & bytes );
350
351     if ( (err == 0) && (bytes != 4) ) {
352         err = ENOSPC;
353     }
354
355
356     return err;
357 }
358
359
360 int
361 pci_device_cfg_write_bits( struct pci_device * dev, uint32_t mask, 
362                            uint32_t data, pciaddr_t offset )
363 {
364     uint32_t  temp;
365     int err;
366
367     err = pci_device_cfg_read_u32( dev, & temp, offset );
368     if ( ! err ) {
369         temp &= ~mask;
370         temp |= data;
371
372         err = pci_device_cfg_write_u32( dev, & temp, offset );
373     }
374
375     return err;
376 }