# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1258961567 0
# Node ID 1db1bb63824b25f97d127449faeb3a56f1272c97
# Parent c5c40e80bd7d1b5b26d2729806bfd4a2459c6952
dell rbu: 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.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
Tested-by: Douglas Warzecha <Douglas_Warzecha@xxxxxxxx>
---
drivers/firmware/dell_rbu.c | 48 +++++++++++++++++++++++++++++++++++++++-----
1 files changed, 43 insertions(+), 5 deletions(-)
diff -r c5c40e80bd7d -r 1db1bb63824b drivers/firmware/dell_rbu.c
--- a/drivers/firmware/dell_rbu.c Fri Nov 13 22:01:54 2009 +0000
+++ b/drivers/firmware/dell_rbu.c Mon Nov 23 07:32:47 2009 +0000
@@ -169,9 +169,28 @@ static int create_packet(void *data, siz
spin_lock(&rbu_data.lock);
goto out_alloc_packet_array;
}
-
- if ((unsigned long)virt_to_phys(packet_data_temp_buf)
+#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_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 int __init dcdrbu_init(void)
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();
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|