OSDN Git Service

Add interfaces to map / unmap specific memory ranges, bump lib version to 0.7.0.
authorIan Romanick <idr@us.ibm.com>
Fri, 12 Jan 2007 05:40:57 +0000 (21:40 -0800)
committerIan Romanick <idr@us.ibm.com>
Fri, 12 Jan 2007 05:40:57 +0000 (21:40 -0800)
Add pci_device_map_memory_range and pci_device_unmap_memory_range to
map and unmap specific memory ranges.  The unmap bit is still a bit
hinkey (unmaps the whole BAR).  Works so far for initial conversion of
VESA driver.  Will need to be revisited.

configure.ac
include/pciaccess.h
src/Makefile.am
src/common_interface.c

index 99ea0cf..1c99739 100644 (file)
@@ -41,7 +41,7 @@ dnl refers to ${prefix}.  Thus we have to use `eval' twice.
 
 AC_PREREQ([2.57])
 
-AC_INIT(libpciaccess, 0.6.0, [none yet], libpciaccess)
+AC_INIT(libpciaccess, 0.7.0, [none yet], libpciaccess)
 AM_INIT_AUTOMAKE([dist-bzip2])
 AM_MAINTAINER_MODE
 
index 4078f0f..a0cf067 100644 (file)
@@ -47,6 +47,12 @@ int pci_device_map_region( struct pci_device * dev, unsigned region,
 
 int pci_device_unmap_region( struct pci_device * dev, unsigned region );
 
+int pci_device_map_memory_range(struct pci_device *dev, pciaddr_t base,
+    pciaddr_t size, int write_enable, void **addr);
+
+int pci_device_unmap_memory_range(struct pci_device *dev, void *memory,
+    pciaddr_t size);
+
 int pci_device_probe( struct pci_device * dev );
 
 const struct pci_agp_info * pci_device_get_agp_info( struct pci_device * dev );
index da20076..de4e52a 100644 (file)
@@ -43,7 +43,7 @@ INCLUDES = -I$(top_srcdir)/include
 
 libpciaccess_la_LIBADD = @PCIACCESS_LIBS@
 
-libpciaccess_la_LDFLAGS = -version-number 0:6:0 -no-undefined
+libpciaccess_la_LDFLAGS = -version-number 0:7:0 -no-undefined
 
 libpciaccessincludedir = $(includedir)
 libpciaccessinclude_HEADERS = \
index 67e8e9a..54c8b26 100644 (file)
@@ -148,6 +148,72 @@ pci_device_map_region( struct pci_device * dev, unsigned region,
 
 
 /**
+ * Map the specified memory range so that it can be accessed by the CPU.
+ *
+ * Maps the specified memory range for access by the processor.  The pointer
+ * to the mapped region is stored in \c addr.  In addtion, the
+ * \c pci_mem_region::memory pointer for the BAR will be updated.
+ *
+ * \param dev          Device whose memory region is to be mapped.
+ * \param base         Base address of the range to be mapped.
+ * \param size         Size of the range to be mapped.
+ * \param write_enable Map for writing (non-zero).
+ * \param addr         Location to store the mapped address.
+ * 
+ * \return
+ * Zero on success or an \c errno value on failure.
+ *
+ * \sa pci_device_unmap_memory_range, pci_device_map_region
+ */
+int
+pci_device_map_memory_range(struct pci_device *dev, pciaddr_t base,
+                           pciaddr_t size, int write_enable, 
+                           void **addr)
+{
+    unsigned region;
+    int err = 0;
+
+
+    *addr = NULL;
+
+    if (dev == NULL) {
+       return EFAULT;
+    }
+
+
+    for (region = 0; region < 6; region++) {
+       const struct pci_mem_region const* r = &dev->regions[region];
+
+       if (r->size != 0) {
+           if ((r->base_addr <= base) && ((r->base_addr + r->size) > base)) {
+               if ((base + size) > (r->base_addr + r->size)) {
+                   return E2BIG;
+               }
+
+               break;
+           }
+       }
+    }
+
+    if (region > 5) {
+       return ENOENT;
+    }
+
+    if (dev->regions[region].memory == NULL) {
+       err = (*pci_sys->methods->map)(dev, region, write_enable);
+    }
+    
+    if (err == 0) {
+       const pciaddr_t offset = base - dev->regions[region].base_addr;
+
+       *addr = ((uint8_t *)dev->regions[region].memory) + offset;
+    }
+
+    return err;
+}
+
+
+/**
  * Unmap the specified BAR so that it can no longer be accessed by the CPU.
  *
  * Unmaps the specified BAR that was previously mapped via
@@ -181,6 +247,57 @@ pci_device_unmap_region( struct pci_device * dev, unsigned region )
 
 
 /**
+ * Unmap the specified memory range so that it can no longer be accessed by the CPU.
+ *
+ * Unmaps the specified memory range that was previously mapped via
+ * \c pci_device_map_memory_range.
+ *
+ * \param dev          Device whose memory is to be unmapped.
+ * \param memory       Pointer to the base of the mapped range.
+ * \param size         Size, in bytes, of the range to be unmapped.
+ * 
+ * \return
+ * Zero on success or an \c errno value on failure.
+ *
+ * \sa pci_device_map_memory_range, pci_device_unmap_region
+ */
+int
+pci_device_unmap_memory_range(struct pci_device *dev, void *memory,
+                             pciaddr_t size)
+{
+    unsigned region;
+
+
+    if (dev == NULL) {
+       return EFAULT;
+    }
+
+    for (region = 0; region < 6; region++) {
+       const struct pci_mem_region const* r = &dev->regions[region];
+       const uint8_t *const mem = r->memory;
+
+       if (r->size != 0) {
+           if ((mem <= memory) && ((mem + r->size) > memory)) {
+               if ((memory + size) > (mem + r->size)) {
+                   return E2BIG;
+               }
+
+               break;
+           }
+       }
+    }
+
+    if (region > 5) {
+       return ENOENT;
+    }
+
+    return (dev->regions[region].memory != NULL)
+       ? (*pci_sys->methods->unmap)(dev, region)
+       : 0;
+}
+
+
+/**
  * Read arbitrary bytes from device's PCI config space
  *
  * Reads data from the device's PCI configuration space.  As with the system