[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] linux: force proper address translation in Dell RBU



Replacing virt_to_phys() by virt_to_bus(), and adding code to ensure
contiguity as required by the firmware.

As usual, written and tested on 2.6.27.37 and made apply to the 2.6.18
tree without further testing.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
Tested-by: Douglas Warzecha <Douglas_Warzecha@xxxxxxxx>

--- sle11-2009-10-16.orig/drivers/firmware/dell_rbu.c   2009-02-02 
09:22:26.000000000 +0100
+++ sle11-2009-10-16/drivers/firmware/dell_rbu.c        2009-10-26 
16:34:16.000000000 +0100
@@ -169,9 +169,28 @@ static int create_packet(void *data, siz
                        spin_lock(&rbu_data.lock);
                        goto out_alloc_packet_array;
                }
+#ifdef CONFIG_XEN
+               if (ordernum && xen_create_contiguous_region(
+                       (unsigned long)packet_data_temp_buf, ordernum, 0)) {
+                       free_pages((unsigned long)packet_data_temp_buf,
+                                  ordernum);
+                       printk(KERN_WARNING
+                               "dell_rbu:%s: failed to adjust new "
+                               "packet\n", __func__);
+                       retval = -ENOMEM;
+                       spin_lock(&rbu_data.lock);
+                       goto out_alloc_packet_array;
+               }
+#endif
 
-               if ((unsigned long)virt_to_phys(packet_data_temp_buf)
+               if ((unsigned long)virt_to_bus(packet_data_temp_buf)
                                < allocation_floor) {
+#ifdef CONFIG_XEN
+                       if (ordernum)
+                               xen_destroy_contiguous_region(
+                                       (unsigned long)packet_data_temp_buf,
+                                       ordernum);
+#endif
                        pr_debug("packet 0x%lx below floor at 0x%lx.\n",
                                        (unsigned long)virt_to_phys(
                                                packet_data_temp_buf),
@@ -185,7 +204,7 @@ static int create_packet(void *data, siz
        newpacket->data = packet_data_temp_buf;
 
        pr_debug("create_packet: newpacket at physical addr %lx\n",
-               (unsigned long)virt_to_phys(newpacket->data));
+               (unsigned long)virt_to_bus(newpacket->data));
 
        /* packets may not have fixed size */
        newpacket->length = length;
@@ -204,7 +223,7 @@ out_alloc_packet_array:
        /* always free packet array */
        for (;idx>0;idx--) {
                pr_debug("freeing unused packet below floor 0x%lx.\n",
-                       (unsigned long)virt_to_phys(
+                       (unsigned long)virt_to_bus(
                                invalid_addr_packet_array[idx-1]));
                free_pages((unsigned long)invalid_addr_packet_array[idx-1],
                        ordernum);
@@ -348,6 +367,13 @@ static void packet_empty_list(void)
                 * to make sure there are no stale RBU packets left in memory
                 */
                memset(newpacket->data, 0, rbu_data.packetsize);
+#ifdef CONFIG_XEN
+               if (newpacket->ordernum)
+                       xen_destroy_contiguous_region(
+                               (unsigned long)newpacket->data,
+                               newpacket->ordernum);
+#endif
+
                free_pages((unsigned long) newpacket->data,
                        newpacket->ordernum);
                kfree(newpacket);
@@ -402,7 +428,9 @@ static int img_update_realloc(unsigned l
 {
        unsigned char *image_update_buffer = NULL;
        unsigned long rc;
+#ifndef CONFIG_XEN
        unsigned long img_buf_phys_addr;
+#endif
        int ordernum;
        int dma_alloc = 0;
 
@@ -433,15 +461,19 @@ static int img_update_realloc(unsigned l
 
        spin_unlock(&rbu_data.lock);
 
+#ifndef CONFIG_XEN
        ordernum = get_order(size);
        image_update_buffer =
                (unsigned char *) __get_free_pages(GFP_KERNEL, ordernum);
 
        img_buf_phys_addr =
-               (unsigned long) virt_to_phys(image_update_buffer);
+               (unsigned long) virt_to_bus(image_update_buffer);
 
        if (img_buf_phys_addr > BIOS_SCAN_LIMIT) {
                free_pages((unsigned long) image_update_buffer, ordernum);
+#else
+       {
+#endif
                ordernum = -1;
                image_update_buffer = dma_alloc_coherent(NULL, size,
                        &dell_rbu_dmaaddr, GFP_KERNEL);
@@ -706,6 +738,12 @@ static struct bin_attribute rbu_packet_s
 static int __init dcdrbu_init(void)
 {
        int rc = 0;
+
+#ifdef CONFIG_XEN
+       if (!is_initial_xendomain())
+               return -ENODEV;
+#endif
+
        spin_lock_init(&rbu_data.lock);
 
        init_packet_head();



Attachment: xenlinux-dell-rbu.patch
Description: Text document

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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.