
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
---

 memhotplug-dave/drivers/base/memory.c |   41 ++++++++++++++++++----------------
 memhotplug-dave/mm/memory_hotplug.c   |   24 ++++++++++++++++---
 2 files changed, 42 insertions(+), 23 deletions(-)

diff -puN mm/memory_hotplug.c~N2-sysfs-REMOVE-event mm/memory_hotplug.c
--- memhotplug/mm/memory_hotplug.c~N2-sysfs-REMOVE-event	2004-12-10 13:52:59.000000000 -0800
+++ memhotplug-dave/mm/memory_hotplug.c	2004-12-10 13:52:59.000000000 -0800
@@ -58,7 +58,7 @@ int __add_section(struct zone *zone, uns
 
 	down(&zone->resize_sem);
 
-	printk(KERN_DEBUG "%s() phys_start_pfn: %08lx\n", __func__, phys_start_pf);
+	printk(KERN_DEBUG "%s() phys_start_pfn: %08lx\n", __func__, phys_start_pfn);
 	if (phys_section[pfn_to_section(phys_start_pfn)] != INVALID_PHYS_SECTION) {
 		printk(KERN_DEBUG "%s(): phys_section[%d] already online\n",
 			__func__, pfn_to_section(phys_start_pfn));
@@ -73,7 +73,7 @@ int __add_section(struct zone *zone, uns
 	if (!memmap)
 		return -ENOMEM;
 
-	alloc_memmap(memmap, phys_start_pfn,, nr_pages);
+	alloc_memmap(memmap, phys_start_pfn, nr_pages);
 	memmap_init_zone(nr_pages, 0, zone - pgdat->node_zones, phys_start_pfn);
 
 	/*
@@ -143,11 +143,27 @@ int online_pages(unsigned long pfn, unsi
 int __remove_pages(struct zone *zone, unsigned long start_pfn,
 		unsigned long nr_pages, unsigned long attr)
 {
+	int i;
+	int order = get_order(nr_pages<<PAGE_SHIFT);
 	/*
 	 * for now, only handle 2^x sized areas
 	 */
 	if (nr_pages != 1<<get_order(nr_pages))
 		return -EINVAL;
-	return capture_page_range(start_pfn, get_order(nr_pages));
-}
 
+	if (capture_page_range(start_pfn, order)) {
+		printk(KERN_WARNING "%s(): failed to capture page range: %ld -> %ld\n",
+				__func__, start_pfn, start_pfn + nr_pages);
+
+		return -EAGAIN;
+	}
+
+	for (i = 0; i < nr_pages; i += SECTION_SIZE) {
+		unsigned int phys_section = pfn_to_section(start_pfn + i);
+		unregister_memory_section(phys_section);
+	}
+
+	invalidate_phys_mapping(start_pfn, nr_pages);
+
+	return 0;
+}
diff -puN drivers/base/memory.c~N2-sysfs-REMOVE-event drivers/base/memory.c
--- memhotplug/drivers/base/memory.c~N2-sysfs-REMOVE-event	2004-12-10 13:52:59.000000000 -0800
+++ memhotplug-dave/drivers/base/memory.c	2004-12-10 13:52:59.000000000 -0800
@@ -15,8 +15,10 @@
 #include <asm/atomic.h>
 #include <asm/uaccess.h>
 
+#define MEMORY_CLASS_NAME	"memory"
+
 struct sysdev_class memory_sysdev_class = {
-	set_kset_name("memory"),
+	set_kset_name(MEMORY_CLASS_NAME),
 };
 EXPORT_SYMBOL(memory_sysdev_class);
 
@@ -32,7 +34,7 @@ static int memory_hotplug_filter(struct 
 
 static char *memory_hotplug_name(struct kset *kset, struct kobject *kobj)
 {
-        return "memory";
+        return MEMORY_CLASS_NAME;
 }
 
 static int memory_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
@@ -270,6 +272,8 @@ SYSDEV_ATTR(phys_device, 0444, show_phys
 
 #define mem_create_simple_file(mem, attr_name)	\
 	sysdev_create_file(&mem->sysdev, &attr_##attr_name)
+#define mem_remove_simple_file(mem, attr_name)	\
+	sysdev_remove_file(&mem->sysdev, &attr_##attr_name)
 
 /*
  * Block size attribute stuff
@@ -420,30 +424,30 @@ struct memory_block *find_memory_block(u
 {
 	struct kobject *kobj;
 	struct sys_device *sysdev;
-	struct memory_block *mem
+	struct memory_block *mem;
 	char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1];
 
 	/*
 	 * This only works because we know that section == sysdev->id
 	 * slightly redundant with sysdev_register()
 	 */
-	sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, section);
+	sprintf(&name[0], "%s%ld", MEMORY_CLASS_NAME, section);
+	printk(KERN_DEBUG "%s() looking for name: \"%s\"\n", __func__, name);
 
 	kobj = kset_find_obj(&memory_sysdev_class.kset, name);
-	sysdev = to_sysdev(kobj);
-	mem = container_of(dev, struct memory_block, sysdev);
+	if (!kobj)
+		return NULL;
+
+	sysdev = container_of(kobj, struct sys_device, kobj);
+	mem = container_of(sysdev, struct memory_block, sysdev);
 
 	return mem;
 }
 
 int remove_memory_block(unsigned long node_id, unsigned int section,
-		unsigned int phys_index, unsigned long state,
-		int phys_device)
+		unsigned int phys_index, int phys_device)
 {
-	struct memory_block *mem, *tmp;
-	int ret0, ret1, ret2, ret3;
-
-	printk("Hit %s\n", __func__);
+	struct memory_block *mem;
 
 	mem = find_memory_block(section);
 
@@ -480,19 +484,18 @@ int register_new_memory(unsigned int sec
 	return add_memory_block(0, section, phys_index, MEM_OFFLINE, 0);
 }
 
-int unregister_memory_section(unsigned int section)
+int unregister_memory_section(unsigned int phys_section_nr)
 {
-	unsigned int phys_index = mem_section[section].phys_section;
+	unsigned short section = phys_section[phys_section_nr];
 
-	printk("Hit %s\n", __func__);
-
-	if (phys_index == INVALID_SECTION) {
-		printk("%s: phys_index 0x%x is BOGUS!\n", __func__, phys_index);
+	if (section == INVALID_PHYS_SECTION) {
+		printk(KERN_WARNING "%s: phys_section[%d] is BOGUS!\n",
+					__func__, phys_section_nr);
 		return -EINVAL;
 	}
 
 	/* need some node info here and some sort of callback .... */
-	return remove_memory_block(0, section, phys_index, 0);
+	return remove_memory_block(0, section, phys_section_nr, 0);
 }
 
 /*
_
