xref: /libpciaccess/src/common_interface.c (revision 206e2921)
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 <[email protected]>
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 /* linux */
52 
53 #elif defined(__sun)
54 #define	LETOH_16(x)	(x)
55 #define	HTOLE_16(x)	(x)
56 #define	LETOH_32(x)	(x)
57 #define	HTOLE_32(x)	(x)
58 
59 #else
60 
61 #include <sys/endian.h>
62 
63 #define LETOH_16(x)	le16toh(x)
64 #define HTOLE_16(x)	htole16(x)
65 #define LETOH_32(x)	le32toh(x)
66 #define HTOLE_32(x)	htole32(x)
67 
68 #endif /* others */
69 
70 /**
71  * Read a device's expansion ROM.
72  *
73  * Reads the device's expansion ROM and stores the data in the memory pointed
74  * to by \c buffer.  The buffer must be at least \c pci_device::rom_size
75  * bytes.
76  *
77  * \param dev    Device whose expansion ROM is to be read.
78  * \param buffer Memory in which to store the ROM.
79  *
80  * \return
81  * Zero on success or an \c errno value on failure.
82  */
83 int
84 pci_device_read_rom( struct pci_device * dev, void * buffer )
85 {
86     if ( (dev == NULL) || (buffer == NULL) ) {
87 	return EFAULT;
88     }
89 
90 
91     return (pci_sys->methods->read_rom)( dev, buffer );
92 }
93 
94 
95 /**
96  * Probe a PCI device to learn information about the device.
97  *
98  * Probes a PCI device to learn various information about the device.  Before
99  * calling this function, the only public fields in the \c pci_device
100  * structure that have valid values are \c pci_device::domain,
101  * \c pci_device::bus, \c pci_device::dev, and \c pci_device::func.
102  *
103  * \param dev  Device to be probed.
104  *
105  * \return
106  * Zero on succes or an \c errno value on failure.
107  */
108 int
109 pci_device_probe( struct pci_device * dev )
110 {
111     if ( dev == NULL ) {
112 	return EFAULT;
113     }
114 
115 
116     return (pci_sys->methods->probe)( dev );
117 }
118 
119 
120 /**
121  * Map the specified BAR so that it can be accessed by the CPU.
122  *
123  * Maps the specified BAR for acces by the processor.  The pointer to the
124  * mapped region is stored in the \c pci_mem_region::memory pointer for the
125  * BAR.
126  *
127  * \param dev          Device whose memory region is to be mapped.
128  * \param region       Region, on the range [0, 5], that is to be mapped.
129  * \param write_enable Map for writing (non-zero).
130  *
131  * \return
132  * Zero on success or an \c errno value on failure.
133  *
134  * \sa pci_device_unmap_region
135  */
136 int
137 pci_device_map_region( struct pci_device * dev, unsigned region,
138 		       int write_enable )
139 {
140     if ( dev == NULL ) {
141 	return EFAULT;
142     }
143 
144     if ( (region > 5) || (dev->regions[ region ].size == 0) ) {
145 	return ENOENT;
146     }
147 
148     if ( dev->regions[ region ].memory != NULL ) {
149 	return 0;
150     }
151 
152     return (pci_sys->methods->map)( dev, region, write_enable );
153 }
154 
155 
156 /**
157  * Map the specified memory range so that it can be accessed by the CPU.
158  *
159  * Maps the specified memory range for access by the processor.  The pointer
160  * to the mapped region is stored in \c addr.  In addtion, the
161  * \c pci_mem_region::memory pointer for the BAR will be updated.
162  *
163  * \param dev          Device whose memory region is to be mapped.
164  * \param base         Base address of the range to be mapped.
165  * \param size         Size of the range to be mapped.
166  * \param write_enable Map for writing (non-zero).
167  * \param addr         Location to store the mapped address.
168  *
169  * \return
170  * Zero on success or an \c errno value on failure.
171  *
172  * \sa pci_device_unmap_memory_range, pci_device_map_region
173  */
174 int
175 pci_device_map_memory_range(struct pci_device *dev, pciaddr_t base,
176 			    pciaddr_t size, int write_enable,
177 			    void **addr)
178 {
179     unsigned region;
180     int err = 0;
181 
182 
183     *addr = NULL;
184 
185     if (dev == NULL) {
186 	return EFAULT;
187     }
188 
189 
190     for (region = 0; region < 6; region++) {
191 	const struct pci_mem_region const* r = &dev->regions[region];
192 
193 	if (r->size != 0) {
194 	    if ((r->base_addr <= base) && ((r->base_addr + r->size) > base)) {
195 		if ((base + size) > (r->base_addr + r->size)) {
196 		    return E2BIG;
197 		}
198 
199 		break;
200 	    }
201 	}
202     }
203 
204     if (region > 5) {
205 	return ENOENT;
206     }
207 
208     if (dev->regions[region].memory == NULL) {
209 	err = (*pci_sys->methods->map)(dev, region, write_enable);
210     }
211 
212     if (err == 0) {
213 	const pciaddr_t offset = base - dev->regions[region].base_addr;
214 
215 	*addr = ((uint8_t *)dev->regions[region].memory) + offset;
216     }
217 
218     return err;
219 }
220 
221 
222 /**
223  * Unmap the specified BAR so that it can no longer be accessed by the CPU.
224  *
225  * Unmaps the specified BAR that was previously mapped via
226  * \c pci_device_map_region.
227  *
228  * \param dev          Device whose memory region is to be mapped.
229  * \param region       Region, on the range [0, 5], that is to be mapped.
230  *
231  * \return
232  * Zero on success or an \c errno value on failure.
233  *
234  * \sa pci_device_map_region
235  */
236 int
237 pci_device_unmap_region( struct pci_device * dev, unsigned region )
238 {
239     if ( dev == NULL ) {
240 	return EFAULT;
241     }
242 
243     if ( (region > 5) || (dev->regions[ region ].size == 0) ) {
244 	return ENOENT;
245     }
246 
247     if ( dev->regions[ region ].memory == NULL ) {
248 	return 0;
249     }
250 
251     return (pci_sys->methods->unmap)( dev, region );
252 }
253 
254 
255 /**
256  * Unmap the specified memory range so that it can no longer be accessed by the CPU.
257  *
258  * Unmaps the specified memory range that was previously mapped via
259  * \c pci_device_map_memory_range.
260  *
261  * \param dev          Device whose memory is to be unmapped.
262  * \param memory       Pointer to the base of the mapped range.
263  * \param size         Size, in bytes, of the range to be unmapped.
264  *
265  * \return
266  * Zero on success or an \c errno value on failure.
267  *
268  * \sa pci_device_map_memory_range, pci_device_unmap_region
269  */
270 int
271 pci_device_unmap_memory_range(struct pci_device *dev, void *memory,
272 			      pciaddr_t size)
273 {
274     unsigned region;
275 
276 
277     if (dev == NULL) {
278 	return EFAULT;
279     }
280 
281     for (region = 0; region < 6; region++) {
282 	const struct pci_mem_region const* r = &dev->regions[region];
283 	const uint8_t *const mem = r->memory;
284 
285 	if (r->size != 0) {
286 	    if ((mem <= memory) && ((mem + r->size) > memory)) {
287 		if ((memory + size) > (mem + r->size)) {
288 		    return E2BIG;
289 		}
290 
291 		break;
292 	    }
293 	}
294     }
295 
296     if (region > 5) {
297 	return ENOENT;
298     }
299 
300     return (dev->regions[region].memory != NULL)
301 	? (*pci_sys->methods->unmap)(dev, region)
302 	: 0;
303 }
304 
305 
306 /**
307  * Read arbitrary bytes from device's PCI config space
308  *
309  * Reads data from the device's PCI configuration space.  As with the system
310  * read command, less data may be returned, without an error, than was
311  * requested.  This is particuarly the case if a non-root user tries to read
312  * beyond the first 64-bytes of configuration space.
313  *
314  * \param dev         Device whose PCI configuration data is to be read.
315  * \param data        Location to store the data
316  * \param offset      Initial byte offset to read
317  * \param size        Total number of bytes to read
318  * \param bytes_read  Location to store the actual number of bytes read.  This
319  *                    pointer may be \c NULL.
320  *
321  * \returns
322  * Zero on success or an errno value on failure.
323  *
324  * \note
325  * Data read from PCI configuartion space using this routine is \b not
326  * byte-swapped to the host's byte order.  PCI configuration data is always
327  * stored in little-endian order, and that is what this routine returns.
328  */
329 int
330 pci_device_cfg_read( struct pci_device * dev, void * data,
331 		     pciaddr_t offset, pciaddr_t size,
332 		     pciaddr_t * bytes_read )
333 {
334     pciaddr_t  scratch;
335 
336     if ( (dev == NULL) || (data == NULL) ) {
337 	return EFAULT;
338     }
339 
340     return pci_sys->methods->read( dev, data, offset, size,
341 				   (bytes_read == NULL)
342 				   ? & scratch : bytes_read );
343 }
344 
345 
346 int
347 pci_device_cfg_read_u8( struct pci_device * dev, uint8_t * data,
348 			pciaddr_t offset )
349 {
350     pciaddr_t bytes;
351     int err = pci_device_cfg_read( dev, data, offset, 1, & bytes );
352 
353     if ( (err == 0) && (bytes != 1) ) {
354 	err = ENXIO;
355     }
356 
357     return err;
358 }
359 
360 
361 int
362 pci_device_cfg_read_u16( struct pci_device * dev, uint16_t * data,
363 			 pciaddr_t offset )
364 {
365     pciaddr_t bytes;
366     int err = pci_device_cfg_read( dev, data, offset, 2, & bytes );
367 
368     if ( (err == 0) && (bytes != 2) ) {
369 	err = ENXIO;
370     }
371 
372     *data = LETOH_16( *data );
373     return err;
374 }
375 
376 
377 int
378 pci_device_cfg_read_u32( struct pci_device * dev, uint32_t * data,
379 			 pciaddr_t offset )
380 {
381     pciaddr_t bytes;
382     int err = pci_device_cfg_read( dev, data, offset, 4, & bytes );
383 
384     if ( (err == 0) && (bytes != 4) ) {
385 	err = ENXIO;
386     }
387 
388     *data = LETOH_32( *data );
389     return err;
390 }
391 
392 
393 /**
394  * Write arbitrary bytes to device's PCI config space
395  *
396  * Writess data to the device's PCI configuration space.  As with the system
397  * write command, less data may be written, without an error, than was
398  * requested.
399  *
400  * \param dev         Device whose PCI configuration data is to be written.
401  * \param data        Location of the source data
402  * \param offset      Initial byte offset to write
403  * \param size        Total number of bytes to write
404  * \param bytes_read  Location to store the actual number of bytes written.
405  *                    This pointer may be \c NULL.
406  *
407  * \returns
408  * Zero on success or an errno value on failure.
409  *
410  * \note
411  * Data written to PCI configuartion space using this routine is \b not
412  * byte-swapped from the host's byte order.  PCI configuration data is always
413  * stored in little-endian order, so data written with this routine should be
414  * put in that order in advance.
415  */
416 int
417 pci_device_cfg_write( struct pci_device * dev, const void * data,
418 		      pciaddr_t offset, pciaddr_t size,
419 		      pciaddr_t * bytes_written )
420 {
421     pciaddr_t  scratch;
422 
423     if ( (dev == NULL) || (data == NULL) ) {
424 	return EFAULT;
425     }
426 
427     return pci_sys->methods->write( dev, data, offset, size,
428 				    (bytes_written == NULL)
429 				    ? & scratch : bytes_written );
430 }
431 
432 
433 int
434 pci_device_cfg_write_u8(struct pci_device *dev, uint8_t data,
435 			pciaddr_t offset)
436 {
437     pciaddr_t bytes;
438     int err = pci_device_cfg_write(dev, & data, offset, 1, & bytes);
439 
440     if ( (err == 0) && (bytes != 1) ) {
441 	err = ENOSPC;
442     }
443 
444 
445     return err;
446 }
447 
448 
449 int
450 pci_device_cfg_write_u16(struct pci_device *dev, uint16_t data,
451 			 pciaddr_t offset)
452 {
453     pciaddr_t bytes;
454     const uint16_t temp = HTOLE_16(data);
455     int err = pci_device_cfg_write( dev, & temp, offset, 2, & bytes );
456 
457     if ( (err == 0) && (bytes != 2) ) {
458 	err = ENOSPC;
459     }
460 
461 
462     return err;
463 }
464 
465 
466 int
467 pci_device_cfg_write_u32(struct pci_device *dev, uint32_t data,
468 			 pciaddr_t offset)
469 {
470     pciaddr_t bytes;
471     const uint32_t temp = HTOLE_32(data);
472     int err = pci_device_cfg_write( dev, & temp, offset, 4, & bytes );
473 
474     if ( (err == 0) && (bytes != 4) ) {
475 	err = ENOSPC;
476     }
477 
478 
479     return err;
480 }
481 
482 
483 int
484 pci_device_cfg_write_bits( struct pci_device * dev, uint32_t mask,
485 			   uint32_t data, pciaddr_t offset )
486 {
487     uint32_t  temp;
488     int err;
489 
490     err = pci_device_cfg_read_u32( dev, & temp, offset );
491     if ( ! err ) {
492 	temp &= ~mask;
493 	temp |= data;
494 
495 	err = pci_device_cfg_write_u32(dev, temp, offset);
496     }
497 
498     return err;
499 }
500