2.6.34-rc2 kernel: Boot up on a common PC, then: modprobe physmap ; rmmod physmap and bang. [ 127.836202] calling init_mtd+0x0/0x88 [mtd] @ 3566 [ 127.841742] initcall init_mtd+0x0/0x88 [mtd] returned 0 after 514 usecs [ 127.863465] calling physmap_init+0x0/0x49 [physmap] @ 3566 [ 127.869454] physmap-flash.0: failed to claim resource 0 [ 127.874760] initcall physmap_init+0x0/0x49 [physmap] returned 0 after 5450 usecs [ 150.353495] BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 [ 150.354142] IP: [<ffffffff8137c655>] device_pm_remove+0xcb/0xff [ 150.354142] PGD 6d931067 PUD 6da98067 PMD 0 [ 150.354142] Oops: 0002 [#1] SMP [ 150.354142] last sysfs file: /sys/devices/pci0000:00/0000:00:1d.1/usb3/3-1/3-1.3/devnum [ 150.354142] CPU 1 [ 150.354142] Modules linked in: physmap(-) mtd chipreg map_funcs ipt_MASQUERADE iptable_nat nf_nat nfsd sco bridge lockd nfs_acl stp auth_rpcgss llc exportfs bnep l2cap crc16 bluetooth rfkill sunrpc ipt_REJECT nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_REJECT xt_tcpudp nf_conntrack_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables x_tables ipv6 p4_clockmod freq_table speedstep_lib dm_mirror dm_region_hash dm_log dm_multipath scsi_dh dm_mod kvm uinput snd_intel8x0 joydev snd_ac97_codec ac97_bus snd_seq snd_seq_device usbhid snd_pcm snd_timer led_class snd psmouse iTCO_wdt i2c_i801 rtc_cmos iTCO_vendor_support evdev ppdev parport_pc serio_raw parport sg rtc_core i2c_core rtc_lib pcspkr soundcore snd_page_alloc rng_core button thermal intel_agp thermal_sys agpgart hwmon sr_mod cdrom dcdbas ata_generic pata_acpi ata_piix libata ide_pci_generic ide_core sd_mod scsi_mod crc_t10dif ext3 jbd mbcache uhci_hcd ohci_hcd ssb mmc_core pcmcia pcmcia_core ehci_hcd! usbcore nls_base [last unloaded: processor] [ 150.354142] [ 150.354142] Pid: 3575, comm: rmmod Not tainted 2.6.34-rc2 #2 0HH807/OptiPlex GX620 [ 150.354142] RIP: 0010:[<ffffffff8137c655>] [<ffffffff8137c655>] ...
This is with close to an allmodconfig on x86_64, including: CONFIG_MTD_PHYSMAP=m CONFIG_MTD_PHYSMAP_COMPAT=y CONFIG_MTD_PHYSMAP_START=0x8000000 CONFIG_MTD_PHYSMAP_LEN=0 CONFIG_MTD_PHYSMAP_BANKWIDTH=2 --- ~Randy --
Forgive me if this sounds weird, but I was under the impression that most people who want to reflash their BIOS on x86 (most prominent physmap usecase on x86) are using a pure userspace solution with flashrom <http://www.flashrom.org/> nowadays. flashrom has the advantage of not needing a kernel recompile if you want support for new chips/chipsets. flashrom doesn't use MTD and accesses /dev/mem instead. AFAIK flashrom supports BIOS/EFI/... flashing on all x86 chipsets which are supported by MTD, and on a few other x86 chipsets (and network/storage/graphics cards) which are not supported by MTD. Regards, Carl-Daniel --
That's probably the cause of the BUG.
If your not run-time calling physmap_configure(), your resource will
be created as:
static struct physmap_flash_data physmap_flash_data = {
.width = CONFIG_MTD_PHYSMAP_BANKWIDTH,
};
static struct resource physmap_flash_resource = {
.start = CONFIG_MTD_PHYSMAP_START,
.end = CONFIG_MTD_PHYSMAP_START + CONFIG_MTD_PHYSMAP_LEN - 1,
.flags = IORESOURCE_MEM,
};
In other words:
static struct physmap_flash_data physmap_flash_data = {
.width = 2,
};
static struct resource physmap_flash_resource = {
.start = 0x8000000,
.end = 0x8000000 + 0 - 1,
.flags = IORESOURCE_MEM,
};
I don't think your even getting into the physmap_flash_probe routine.
Your probably getting the BUG after:
platform_device_register(&physmap_flash);
Which eventually gets to platform_device_add which is giving you the
Try this patch to see if it fixes your BUG.
---
mtd/maps/physmap: catch failure to register MTD_PHYSMAP_COMPAT device
If the default Kconfig values are used with MTD_PHYSMAP_COMPAT you end
up with a IORESOURCE_MEM of 0 size. This causes platform_device_add
to fail during the platform_device_register call.
Catch this failure during the physmap_init.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
---
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index d9603f7..426461a 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -264,8 +264,11 @@ static int __init physmap_init(void)
err = platform_driver_register(&physmap_flash_driver);
#ifdef CONFIG_MTD_PHYSMAP_COMPAT
- if (err == 0)
- platform_device_register(&physmap_flash);
+ if (err == 0) {
+ err = platform_device_register(&physmap_flash);
+ if (err)
+ platform_driver_unregister(&physmap_flash_driver);
+ }
#endif
return err;
--
I traced this down to kernel/resource.c. When __request_resource
is finally called, because of the platform_device_register, it ends
up returning a conflict due to:
resource_size_t start = new->start;
resource_size_t end = new->end;
struct resource *tmp, **p;
if (end < start)
return root;
This ends up causing an -EBUSY error code. The patch below should
be correct to fix this.
I changed the commit message a bit.
---
mtd/maps/physmap: catch failure to register MTD_PHYSMAP_COMPAT device
If the default Kconfig values are used with MTD_PHYSMAP_COMPAT you end
up with a resource where end < start. This causes __request_resource to
return a conflict which then returns an -EBUSY error code. The current
physmap.c code just assumes that the platfom_device_register will always
succeed.
Catch this failure during the physmap_init and propogate the error.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
---
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index d9603f7..426461a 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -264,8 +264,11 @@ static int __init physmap_init(void)
err = platform_driver_register(&physmap_flash_driver);
#ifdef CONFIG_MTD_PHYSMAP_COMPAT
- if (err == 0)
- platform_device_register(&physmap_flash);
+ if (err == 0) {
+ err = platform_device_register(&physmap_flash);
+ if (err)
+ platform_driver_unregister(&physmap_flash_driver);
+ }
#endif
return err;
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
--
