WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [linux-2.6.18-xen] [IA64] Issue ioremap hypercall in pci

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [linux-2.6.18-xen] [IA64] Issue ioremap hypercall in pci_acpi_scan_root()
From: "Xen patchbot-linux-2.6.18-xen" <patchbot-linux-2.6.18-xen@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 07 Sep 2007 09:10:21 -0700
Delivery-date: Fri, 07 Sep 2007 09:11:21 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1185814887 21600
# Node ID 8f0c93df3e113058f0b582b06ce7d3d897ccc9d6
# Parent  f017328288ea42600509b62882f687d7331ce194
[IA64] Issue ioremap hypercall in pci_acpi_scan_root()

This setups up mapping in /dev/mem.

Signed-off-by: Jun Kamada <kama@xxxxxxxxxxxxxx>
---
 arch/ia64/pci/pci.c |  184 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 184 insertions(+)

diff -r f017328288ea -r 8f0c93df3e11 arch/ia64/pci/pci.c
--- a/arch/ia64/pci/pci.c       Mon Jul 30 10:53:36 2007 -0600
+++ b/arch/ia64/pci/pci.c       Mon Jul 30 11:01:27 2007 -0600
@@ -29,6 +29,15 @@
 #include <asm/smp.h>
 #include <asm/irq.h>
 #include <asm/hw_irq.h>
+
+#ifdef CONFIG_XEN
+struct ioremap_issue_list {
+       struct list_head                listp;
+       unsigned long                   start;
+       unsigned long                   end;
+};
+typedef struct ioremap_issue_list      ioremap_issue_list_t;
+#endif /* CONFIG_XEN */
 
 /*
  * Low-level SAL-based PCI configuration access functions. Note that SAL
@@ -337,6 +346,169 @@ pcibios_setup_root_windows(struct pci_bu
        }
 }
 
+#ifdef CONFIG_XEN
+static void
+__cleanup_issue_list(struct list_head *top)
+{
+       ioremap_issue_list_t *ptr, *tmp_ptr;
+
+       list_for_each_entry_safe(ptr, tmp_ptr, top, listp) {
+               list_del(&(ptr->listp));
+               kfree(ptr);
+       }
+}
+
+static int
+__add_issue_list(unsigned long start, unsigned long end, struct list_head *top)
+{
+       ioremap_issue_list_t *ptr, *new;
+
+       if (start > end) {
+               printk(KERN_ERR "%s: Internal error (start addr > end addr)\n",
+                      __FUNCTION__);
+               return 0;
+       }
+
+       /*
+        * Head of the resource structure list contains
+        * dummy val.(start=0, end=~0), so skip it
+        */
+       if ((start == 0) && (end == ~0))
+               return 0;
+
+       start &= PAGE_MASK;
+       end |= ~PAGE_MASK;
+
+       /* We can merge specified address range into existing entry */
+       list_for_each_entry(ptr, top, listp) {
+               if ((ptr->start > end + 1) || (ptr->end + 1 < start))
+                       continue;
+               ptr->start = min(start, ptr->start);
+               ptr->end = max(end, ptr->end);
+               return 0;
+       }
+
+       /* We could not merge, so create new entry */
+       new = kmalloc(sizeof(ioremap_issue_list_t), GFP_KERNEL);
+       if (new == NULL) {
+               printk(KERN_ERR "%s: Could not allocate memory. "
+                      "HYPERVISOR_ioremap will not be issued\n",
+                      __FUNCTION__);
+               return -ENOMEM;
+       }
+
+       new->start = start;
+       new->end = end;
+
+       /* Insert the new entry to the list by ascending order */
+       if (list_empty(top)) {
+               list_add_tail(&(new->listp), top);
+               return 0;
+       }
+       list_for_each_entry(ptr, top, listp) {
+               if (new->start > ptr->start)
+                       continue;
+               list_add(&(new->listp), ((struct list_head *)ptr)->prev);
+               return 0;
+       }
+       list_add_tail(&(new->listp), top);
+
+       return 0;
+}
+
+static int
+__make_issue_list(struct resource *ptr, struct list_head *top)
+{
+       int ret;
+
+       if (ptr->child) {
+               ret = __make_issue_list(ptr->child, top);
+               if (ret)
+                       return ret;
+       }
+       if (ptr->sibling) {
+               ret = __make_issue_list(ptr->sibling, top);
+               if (ret)
+                       return ret;
+       }
+
+       if (ptr->flags & IORESOURCE_MEM) {
+               ret = __add_issue_list(ptr->start, ptr->end, top);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static void
+__compress_issue_list(struct list_head *top)
+{
+       ioremap_issue_list_t *ptr, *tmp_ptr, *next;
+       int compressed;
+
+       /*
+        * Merge adjacent entries, if overlapped
+        * (entries are sorted by ascending order)
+        */
+       list_for_each_entry_safe(ptr, tmp_ptr, top, listp) {
+               if (list_is_last((struct list_head *)ptr, top))
+                       continue;
+
+               next = (ioremap_issue_list_t *)
+                       (((struct list_head *)ptr)->next);
+               if (next->start <= (ptr->end) + 1) {
+                       next->start = min(ptr->start, next->start);
+                       next->end   = max(ptr->end, next->end);
+
+                       list_del(&(ptr->listp));
+                       kfree(ptr);
+               }
+       }
+}
+
+static int
+__issue_ioremap(struct list_head *top)
+{
+       ioremap_issue_list_t *ptr, *tmp_ptr;
+       unsigned int offset;
+
+       list_for_each_entry_safe(ptr, tmp_ptr, top, listp) {
+               offset = HYPERVISOR_ioremap(ptr->start,
+                                           ptr->end - ptr->start + 1);
+               if (offset == ~0) {
+                       printk(KERN_ERR "%s: HYPERVISOR_ioremap() failed. "
+                              "Address Range: 0x%016lx-0x%016lx\n",
+                              __FUNCTION__, ptr->start, ptr->end);
+               }
+
+               list_del(&(ptr->listp));
+               kfree(ptr);
+       }
+       
+       return 0;
+}
+
+static int
+do_ioremap_on_resource_list(struct resource *top)
+{
+       LIST_HEAD(ioremap_issue_list_top);
+       int ret;
+
+       ret = __make_issue_list(top, &ioremap_issue_list_top);
+       if (ret) {
+               __cleanup_issue_list(&ioremap_issue_list_top);
+               return ret;
+       }
+
+       __compress_issue_list(&ioremap_issue_list_top);
+
+       (void)__issue_ioremap(&ioremap_issue_list_top);
+
+       return 0;
+}
+#endif /* CONFIG_XEN */
+
 struct pci_bus * __devinit
 pci_acpi_scan_root(struct acpi_device *device, int domain, int bus)
 {
@@ -379,6 +551,18 @@ pci_acpi_scan_root(struct acpi_device *d
        pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller);
        if (pbus)
                pcibios_setup_root_windows(pbus, controller);
+
+#ifdef CONFIG_XEN
+       if (is_initial_xendomain()) {
+               if (do_ioremap_on_resource_list(&iomem_resource) != 0) {
+                       printk(KERN_ERR
+                              "%s: Counld not issue HYPERVISOR_ioremap "
+                              "due to lack of memory or hypercall failure\n",
+                              __FUNCTION__);
+                       goto out3;
+               }
+       }
+#endif /* CONFIG_XEN */
 
        return pbus;
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [linux-2.6.18-xen] [IA64] Issue ioremap hypercall in pci_acpi_scan_root(), Xen patchbot-linux-2.6.18-xen <=