Home | History | Annotate | Line # | Download | only in src
      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 (at) us.ibm.com>
     30  */
     31 #ifdef HAVE_CONFIG_H
     32 #include "config.h"
     33 #endif
     34 
     35 #include <stdlib.h>
     36 #include <string.h>
     37 #include <errno.h>
     38 
     39 #include "pciaccess.h"
     40 #include "pciaccess_private.h"
     41 
     42 #if defined(__linux__) || defined(__GLIBC__) || defined(__CYGWIN__)
     43 #include <byteswap.h>
     44 
     45 #if __BYTE_ORDER == __BIG_ENDIAN
     46 # define LETOH_16(x)   bswap_16(x)
     47 # define HTOLE_16(x)   bswap_16(x)
     48 # define LETOH_32(x)   bswap_32(x)
     49 # define HTOLE_32(x)   bswap_32(x)
     50 #else
     51 # define LETOH_16(x)   (x)
     52 # define HTOLE_16(x)   (x)
     53 # define LETOH_32(x)   (x)
     54 # define HTOLE_32(x)   (x)
     55 #endif /* linux */
     56 
     57 #elif defined(__sun)
     58 
     59 #include <sys/byteorder.h>
     60 
     61 #ifdef _BIG_ENDIAN
     62 # define LETOH_16(x)   BSWAP_16(x)
     63 # define HTOLE_16(x)   BSWAP_16(x)
     64 # define LETOH_32(x)   BSWAP_32(x)
     65 # define HTOLE_32(x)   BSWAP_32(x)
     66 #else
     67 # define LETOH_16(x)   (x)
     68 # define HTOLE_16(x)   (x)
     69 # define LETOH_32(x)   (x)
     70 # define HTOLE_32(x)   (x)
     71 #endif /* Solaris */
     72 
     73 #elif defined(__APPLE__)
     74 #include <libkern/OSByteOrder.h>
     75 
     76 #define htobe16(x) OSSwapHostToBigInt16(x)
     77 #define htole16(x) OSSwapHostToLittleInt16(x)
     78 #define be16toh(x) OSSwapBigToHostInt16(x)
     79 #define le16toh(x) OSSwapLittleToHostInt16(x)
     80 
     81 #define htobe32(x) OSSwapHostToBigInt32(x)
     82 #define htole32(x) OSSwapHostToLittleInt32(x)
     83 #define be32toh(x) OSSwapBigToHostInt32(x)
     84 #define le32toh(x) OSSwapLittleToHostInt32(x)
     85 
     86 #define htobe64(x) OSSwapHostToBigInt64(x)
     87 #define htole64(x) OSSwapHostToLittleInt64(x)
     88 #define be64toh(x) OSSwapBigToHostInt64(x)
     89 #define le64toh(x) OSSwapLittleToHostInt64(x)
     90 
     91 #else
     92 
     93 #include <sys/endian.h>
     94 
     95 #define HTOLE_16(x)	htole16(x)
     96 #define HTOLE_32(x)	htole32(x)
     97 
     98 #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__)
     99 #define LETOH_16(x)	le16toh(x)
    100 #define LETOH_32(x)	le32toh(x)
    101 #else
    102 #define LETOH_16(x)	letoh16(x)
    103 #define LETOH_32(x)	letoh32(x)
    104 #endif
    105 
    106 #endif /* others */
    107 
    108 /**
    109  * Read a device's expansion ROM.
    110  *
    111  * Reads the device's expansion ROM and stores the data in the memory pointed
    112  * to by \c buffer.  The buffer must be at least \c pci_device::rom_size
    113  * bytes.
    114  *
    115  * \param dev    Device whose expansion ROM is to be read.
    116  * \param buffer Memory in which to store the ROM.
    117  *
    118  * \return
    119  * Zero on success or an \c errno value on failure.
    120  */
    121 int
    122 pci_device_read_rom( struct pci_device * dev, void * buffer )
    123 {
    124     if ( (dev == NULL) || (buffer == NULL) ) {
    125 	return EFAULT;
    126     }
    127 
    128 
    129     return (pci_sys->methods->read_rom)( dev, buffer );
    130 }
    131 
    132 /**
    133  * Probe a PCI (VGA) device to determine if its the boot VGA device
    134  *
    135  * \param dev    Device whose VGA status to query
    136  * \return
    137  * Zero if not the boot VGA, 1 if the boot VGA.
    138  */
    139 int
    140 pci_device_is_boot_vga( struct pci_device * dev )
    141 {
    142 	if (!pci_sys->methods->boot_vga)
    143 		return 0;
    144 	return pci_sys->methods->boot_vga( dev );
    145 }
    146 
    147 /**
    148  * Probe a PCI device to determine if a kernel driver is attached.
    149  *
    150  * \param dev Device to query
    151  * \return
    152  * Zero if no driver attached, 1 if attached kernel drviver
    153  */
    154 int
    155 pci_device_has_kernel_driver( struct pci_device * dev )
    156 {
    157 	if (!pci_sys->methods->has_kernel_driver)
    158 		return 0;
    159 	return pci_sys->methods->has_kernel_driver( dev );
    160 }
    161 
    162 /**
    163  * Probe a PCI device to learn information about the device.
    164  *
    165  * Probes a PCI device to learn various information about the device.  Before
    166  * calling this function, the only public fields in the \c pci_device
    167  * structure that have valid values are \c pci_device::domain,
    168  * \c pci_device::bus, \c pci_device::dev, and \c pci_device::func.
    169  *
    170  * \param dev  Device to be probed.
    171  *
    172  * \return
    173  * Zero on success or an \c errno value on failure.
    174  */
    175 int
    176 pci_device_probe( struct pci_device * dev )
    177 {
    178     if ( dev == NULL ) {
    179 	return EFAULT;
    180     }
    181 
    182 
    183     return (pci_sys->methods->probe)( dev );
    184 }
    185 
    186 
    187 /**
    188  * Map the specified BAR so that it can be accessed by the CPU.
    189  *
    190  * Maps the specified BAR for access by the processor.  The pointer to the
    191  * mapped region is stored in the \c pci_mem_region::memory pointer for the
    192  * BAR.
    193  *
    194  * \param dev          Device whose memory region is to be mapped.
    195  * \param region       Region, on the range [0, 5], that is to be mapped.
    196  * \param write_enable Map for writing (non-zero).
    197  *
    198  * \return
    199  * Zero on success or an \c errno value on failure.
    200  *
    201  * \sa pci_device_map_range, pci_device_unmap_range
    202  * \deprecated
    203  */
    204 int
    205 pci_device_map_region(struct pci_device * dev, unsigned region,
    206                       int write_enable)
    207 {
    208     const unsigned map_flags =
    209         (write_enable) ? PCI_DEV_MAP_FLAG_WRITABLE : 0;
    210 
    211     if ((region > 5) || (dev->regions[region].size == 0))  {
    212         return ENOENT;
    213     }
    214 
    215     if (dev->regions[region].memory != NULL) {
    216         return 0;
    217     }
    218 
    219     return pci_device_map_range(dev, dev->regions[region].base_addr,
    220                                 dev->regions[region].size, map_flags,
    221                                 &dev->regions[region].memory);
    222 }
    223 
    224 
    225 /**
    226  * Map the specified memory range so that it can be accessed by the CPU.
    227  *
    228  * Maps the specified memory range for access by the processor.  The pointer
    229  * to the mapped region is stored in \c addr.  In addition, the
    230  * \c pci_mem_region::memory pointer for the BAR will be updated.
    231  *
    232  * \param dev          Device whose memory region is to be mapped.
    233  * \param base         Base address of the range to be mapped.
    234  * \param size         Size of the range to be mapped.
    235  * \param write_enable Map for writing (non-zero).
    236  * \param addr         Location to store the mapped address.
    237  *
    238  * \return
    239  * Zero on success or an \c errno value on failure.
    240  *
    241  * \sa pci_device_map_range
    242  */
    243 int pci_device_map_memory_range(struct pci_device *dev,
    244 				pciaddr_t base, pciaddr_t size,
    245 				int write_enable, void **addr)
    246 {
    247     return pci_device_map_range(dev, base, size,
    248 				(write_enable) ? PCI_DEV_MAP_FLAG_WRITABLE : 0,
    249 				addr);
    250 }
    251 
    252 
    253 /**
    254  * Map the specified memory range so that it can be accessed by the CPU.
    255  *
    256  * Maps the specified memory range for access by the processor.  The pointer
    257  * to the mapped region is stored in \c addr.  In addition, the
    258  * \c pci_mem_region::memory pointer for the BAR will be updated.
    259  *
    260  * \param dev          Device whose memory region is to be mapped.
    261  * \param base         Base address of the range to be mapped.
    262  * \param size         Size of the range to be mapped.
    263  * \param map_flags    Flag bits controlling how the mapping is accessed.
    264  * \param addr         Location to store the mapped address.
    265  *
    266  * \return
    267  * Zero on success or an \c errno value on failure.
    268  *
    269  * \sa pci_device_unmap_range
    270  */
    271 int
    272 pci_device_map_range(struct pci_device *dev, pciaddr_t base,
    273                      pciaddr_t size, unsigned map_flags,
    274                      void **addr)
    275 {
    276     struct pci_device_private *const devp =
    277         (struct pci_device_private *) dev;
    278     struct pci_device_mapping *mappings;
    279     unsigned region;
    280     unsigned i;
    281     int err = 0;
    282 
    283 
    284     *addr = NULL;
    285 
    286     if (dev == NULL) {
    287         return EFAULT;
    288     }
    289 
    290 
    291     for (region = 0; region < 6; region++) {
    292         const struct pci_mem_region * const r = &dev->regions[region];
    293 
    294         if (r->size != 0) {
    295             if ((r->base_addr <= base) && ((r->base_addr + r->size) > base)) {
    296                 if ((base + size) > (r->base_addr + r->size)) {
    297                     return E2BIG;
    298                 }
    299 
    300                 break;
    301             }
    302         }
    303     }
    304 
    305     if (region > 5) {
    306         return ENOENT;
    307     }
    308 
    309     /* Make sure that there isn't already a mapping with the same base and
    310      * size.
    311      */
    312     for (i = 0; i < devp->num_mappings; i++) {
    313         if ((devp->mappings[i].base == base)
    314             && (devp->mappings[i].size == size)) {
    315             return EINVAL;
    316         }
    317     }
    318 
    319 
    320     mappings = realloc(devp->mappings,
    321                        (sizeof(devp->mappings[0]) * (devp->num_mappings + 1)));
    322     if (mappings == NULL) {
    323         return ENOMEM;
    324     }
    325 
    326     mappings[devp->num_mappings].base = base;
    327     mappings[devp->num_mappings].size = size;
    328     mappings[devp->num_mappings].region = region;
    329     mappings[devp->num_mappings].flags = map_flags;
    330     mappings[devp->num_mappings].memory = NULL;
    331 
    332     if (dev->regions[region].memory == NULL) {
    333         err = (*pci_sys->methods->map_range)(dev,
    334                                              &mappings[devp->num_mappings]);
    335     }
    336 
    337     if (err == 0) {
    338         *addr =  mappings[devp->num_mappings].memory;
    339         devp->num_mappings++;
    340     } else {
    341         mappings = realloc(mappings,
    342                            (sizeof(mappings[0]) * devp->num_mappings));
    343     }
    344 
    345     devp->mappings = mappings;
    346 
    347     return err;
    348 }
    349 
    350 
    351 /**
    352  * Unmap the specified BAR so that it can no longer be accessed by the CPU.
    353  *
    354  * Unmaps the specified BAR that was previously mapped via
    355  * \c pci_device_map_region.
    356  *
    357  * \param dev          Device whose memory region is to be mapped.
    358  * \param region       Region, on the range [0, 5], that is to be mapped.
    359  *
    360  * \return
    361  * Zero on success or an \c errno value on failure.
    362  *
    363  * \sa pci_device_map_range, pci_device_unmap_range
    364  * \deprecated
    365  */
    366 int
    367 pci_device_unmap_region( struct pci_device * dev, unsigned region )
    368 {
    369     int err;
    370 
    371     if (dev == NULL) {
    372         return EFAULT;
    373     }
    374 
    375     if ((region > 5) || (dev->regions[region].size == 0)) {
    376         return ENOENT;
    377     }
    378 
    379     err = pci_device_unmap_range(dev, dev->regions[region].memory,
    380                                  dev->regions[region].size);
    381     if (!err) {
    382         dev->regions[region].memory = NULL;
    383     }
    384 
    385     return err;
    386 }
    387 
    388 
    389 /**
    390  * Unmap the specified memory range so that it can no longer be accessed by the CPU.
    391  *
    392  * Unmaps the specified memory range that was previously mapped via
    393  * \c pci_device_map_memory_range.
    394  *
    395  * \param dev          Device whose memory is to be unmapped.
    396  * \param memory       Pointer to the base of the mapped range.
    397  * \param size         Size, in bytes, of the range to be unmapped.
    398  *
    399  * \return
    400  * Zero on success or an \c errno value on failure.
    401  *
    402  * \sa pci_device_map_range, pci_device_unmap_range
    403  * \deprecated
    404  */
    405 int
    406 pci_device_unmap_memory_range(struct pci_device *dev, void *memory,
    407                               pciaddr_t size)
    408 {
    409     return pci_device_unmap_range(dev, memory, size);
    410 }
    411 
    412 
    413 /**
    414  * Unmap the specified memory range so that it can no longer be accessed by the CPU.
    415  *
    416  * Unmaps the specified memory range that was previously mapped via
    417  * \c pci_device_map_memory_range.
    418  *
    419  * \param dev          Device whose memory is to be unmapped.
    420  * \param memory       Pointer to the base of the mapped range.
    421  * \param size         Size, in bytes, of the range to be unmapped.
    422  *
    423  * \return
    424  * Zero on success or an \c errno value on failure.
    425  *
    426  * \sa pci_device_map_range
    427  */
    428 int
    429 pci_device_unmap_range(struct pci_device *dev, void *memory,
    430                        pciaddr_t size)
    431 {
    432     struct pci_device_private *const devp =
    433         (struct pci_device_private *) dev;
    434     unsigned i;
    435     int err;
    436 
    437 
    438     if (dev == NULL) {
    439         return EFAULT;
    440     }
    441 
    442     for (i = 0; i < devp->num_mappings; i++) {
    443         if ((devp->mappings[i].memory == memory)
    444             && (devp->mappings[i].size == size)) {
    445             break;
    446         }
    447     }
    448 
    449     if (i == devp->num_mappings) {
    450         return ENOENT;
    451     }
    452 
    453 
    454     err = (*pci_sys->methods->unmap_range)(dev, &devp->mappings[i]);
    455     if (!err) {
    456         const unsigned entries_to_move = (devp->num_mappings - i) - 1;
    457 
    458         if (entries_to_move > 0) {
    459             (void) memmove(&devp->mappings[i],
    460                            &devp->mappings[i + 1],
    461                            entries_to_move * sizeof(devp->mappings[0]));
    462         }
    463 
    464         devp->num_mappings--;
    465         devp->mappings = realloc(devp->mappings,
    466                                  (sizeof(devp->mappings[0]) * devp->num_mappings));
    467     }
    468 
    469     return err;
    470 }
    471 
    472 
    473 /**
    474  * Read arbitrary bytes from device's PCI config space
    475  *
    476  * Reads data from the device's PCI configuration space.  As with the system
    477  * read command, less data may be returned, without an error, than was
    478  * requested.  This is particularly the case if a non-root user tries to read
    479  * beyond the first 64-bytes of configuration space.
    480  *
    481  * \param dev         Device whose PCI configuration data is to be read.
    482  * \param data        Location to store the data
    483  * \param offset      Initial byte offset to read
    484  * \param size        Total number of bytes to read
    485  * \param bytes_read  Location to store the actual number of bytes read.  This
    486  *                    pointer may be \c NULL.
    487  *
    488  * \returns
    489  * Zero on success or an errno value on failure.
    490  *
    491  * \note
    492  * Data read from PCI configuration space using this routine is \b not
    493  * byte-swapped to the host's byte order.  PCI configuration data is always
    494  * stored in little-endian order, and that is what this routine returns.
    495  */
    496 int
    497 pci_device_cfg_read( struct pci_device * dev, void * data,
    498 		     pciaddr_t offset, pciaddr_t size,
    499 		     pciaddr_t * bytes_read )
    500 {
    501     pciaddr_t  scratch;
    502 
    503     if ( (dev == NULL) || (data == NULL) ) {
    504 	return EFAULT;
    505     }
    506 
    507     return pci_sys->methods->read( dev, data, offset, size,
    508 				   (bytes_read == NULL)
    509 				   ? & scratch : bytes_read );
    510 }
    511 
    512 
    513 int
    514 pci_device_cfg_read_u8( struct pci_device * dev, uint8_t * data,
    515 			pciaddr_t offset )
    516 {
    517     pciaddr_t bytes;
    518     int err = pci_device_cfg_read( dev, data, offset, 1, & bytes );
    519 
    520     if ( (err == 0) && (bytes != 1) ) {
    521 	err = ENXIO;
    522     }
    523 
    524     return err;
    525 }
    526 
    527 
    528 int
    529 pci_device_cfg_read_u16( struct pci_device * dev, uint16_t * data,
    530 			 pciaddr_t offset )
    531 {
    532     pciaddr_t bytes;
    533     int err = pci_device_cfg_read( dev, data, offset, 2, & bytes );
    534 
    535     if ( (err == 0) && (bytes != 2) ) {
    536 	err = ENXIO;
    537     }
    538 
    539     *data = LETOH_16( *data );
    540     return err;
    541 }
    542 
    543 
    544 int
    545 pci_device_cfg_read_u32( struct pci_device * dev, uint32_t * data,
    546 			 pciaddr_t offset )
    547 {
    548     pciaddr_t bytes;
    549     int err = pci_device_cfg_read( dev, data, offset, 4, & bytes );
    550 
    551     if ( (err == 0) && (bytes != 4) ) {
    552 	err = ENXIO;
    553     }
    554 
    555     *data = LETOH_32( *data );
    556     return err;
    557 }
    558 
    559 
    560 /**
    561  * Write arbitrary bytes to device's PCI config space
    562  *
    563  * Writes data to the device's PCI configuration space.  As with the system
    564  * write command, less data may be written, without an error, than was
    565  * requested.
    566  *
    567  * \param dev         Device whose PCI configuration data is to be written.
    568  * \param data        Location of the source data
    569  * \param offset      Initial byte offset to write
    570  * \param size        Total number of bytes to write
    571  * \param bytes_read  Location to store the actual number of bytes written.
    572  *                    This pointer may be \c NULL.
    573  *
    574  * \returns
    575  * Zero on success or an errno value on failure.
    576  *
    577  * \note
    578  * Data written to PCI configuration space using this routine is \b not
    579  * byte-swapped from the host's byte order.  PCI configuration data is always
    580  * stored in little-endian order, so data written with this routine should be
    581  * put in that order in advance.
    582  */
    583 int
    584 pci_device_cfg_write( struct pci_device * dev, const void * data,
    585 		      pciaddr_t offset, pciaddr_t size,
    586 		      pciaddr_t * bytes_written )
    587 {
    588     pciaddr_t  scratch;
    589 
    590     if ( (dev == NULL) || (data == NULL) ) {
    591 	return EFAULT;
    592     }
    593 
    594     return pci_sys->methods->write( dev, data, offset, size,
    595 				    (bytes_written == NULL)
    596 				    ? & scratch : bytes_written );
    597 }
    598 
    599 
    600 int
    601 pci_device_cfg_write_u8(struct pci_device *dev, uint8_t data,
    602 			pciaddr_t offset)
    603 {
    604     pciaddr_t bytes;
    605     int err = pci_device_cfg_write(dev, & data, offset, 1, & bytes);
    606 
    607     if ( (err == 0) && (bytes != 1) ) {
    608 	err = ENOSPC;
    609     }
    610 
    611 
    612     return err;
    613 }
    614 
    615 
    616 int
    617 pci_device_cfg_write_u16(struct pci_device *dev, uint16_t data,
    618 			 pciaddr_t offset)
    619 {
    620     pciaddr_t bytes;
    621     const uint16_t temp = HTOLE_16(data);
    622     int err = pci_device_cfg_write( dev, & temp, offset, 2, & bytes );
    623 
    624     if ( (err == 0) && (bytes != 2) ) {
    625 	err = ENOSPC;
    626     }
    627 
    628 
    629     return err;
    630 }
    631 
    632 
    633 int
    634 pci_device_cfg_write_u32(struct pci_device *dev, uint32_t data,
    635 			 pciaddr_t offset)
    636 {
    637     pciaddr_t bytes;
    638     const uint32_t temp = HTOLE_32(data);
    639     int err = pci_device_cfg_write( dev, & temp, offset, 4, & bytes );
    640 
    641     if ( (err == 0) && (bytes != 4) ) {
    642 	err = ENOSPC;
    643     }
    644 
    645 
    646     return err;
    647 }
    648 
    649 
    650 int
    651 pci_device_cfg_write_bits( struct pci_device * dev, uint32_t mask,
    652 			   uint32_t data, pciaddr_t offset )
    653 {
    654     uint32_t  temp;
    655     int err;
    656 
    657     err = pci_device_cfg_read_u32( dev, & temp, offset );
    658     if ( ! err ) {
    659 	temp &= ~mask;
    660 	temp |= data;
    661 
    662 	err = pci_device_cfg_write_u32(dev, temp, offset);
    663     }
    664 
    665     return err;
    666 }
    667 
    668 void
    669 pci_device_enable(struct pci_device *dev)
    670 {
    671     if (dev == NULL) {
    672 	return;
    673     }
    674 
    675     if (pci_sys->methods->enable)
    676 	pci_sys->methods->enable(dev);
    677 }
    678 
    679 void
    680 pci_device_disable(struct pci_device *dev)
    681 {
    682 	if (dev == NULL)
    683 		return;
    684 
    685 	if (pci_sys->methods->disable)
    686 		pci_sys->methods->disable(dev);
    687 }
    688 
    689 /**
    690  * Map the legacy memory space for the PCI domain containing \c dev.
    691  *
    692  * \param dev          Device whose memory region is to be mapped.
    693  * \param base         Base address of the range to be mapped.
    694  * \param size         Size of the range to be mapped.
    695  * \param map_flags    Flag bits controlling how the mapping is accessed.
    696  * \param addr         Location to store the mapped address.
    697  *
    698  * \returns
    699  * Zero on success or an \c errno value on failure.
    700  */
    701 int
    702 pci_device_map_legacy(struct pci_device *dev, pciaddr_t base, pciaddr_t size,
    703 		      unsigned map_flags, void **addr)
    704 {
    705     if (base > 0x100000 || base + size > 0x100000)
    706 	return EINVAL;
    707 
    708     if (!pci_sys->methods->map_legacy)
    709 	return ENOSYS;
    710 
    711     return pci_sys->methods->map_legacy(dev, base, size, map_flags, addr);
    712 }
    713 
    714 /**
    715  * Unmap the legacy memory space for the PCI domain containing \c dev.
    716  *
    717  * \param dev          Device whose memory region is to be unmapped.
    718  * \param addr         Location of the mapped address.
    719  * \param size         Size of the range to be unmapped.
    720  *
    721  * \returns
    722  * Zero on success or an \c errno value on failure.
    723  */
    724 int
    725 pci_device_unmap_legacy(struct pci_device *dev, void *addr, pciaddr_t size)
    726 {
    727     if (!pci_sys->methods->unmap_legacy)
    728 	return ENOSYS;
    729 
    730     return pci_sys->methods->unmap_legacy(dev, addr, size);
    731 }
    732