DragonFly kernel List (threaded) for 2007-05
DragonFly BSD
DragonFly kernel List (threaded) for 2007-05
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

Crash while iterating over devices and resource


From: Martin <dragonfly@xxxxxxxx>
Date: Thu, 03 May 2007 23:50:23 +0200

Hi all,

Since the old ndisulator code (which is in DragonFly) doesn't recognize my wireless card I've taken a shot at converting the current ndisulator code of FreeBSD to DragonFly.

The code now correctly identifies my wireless card however the win-driver want to map io space. In the function where ndisulator does this it recursively iterate over all devices and resources to select the correct device to map to. The driver crashes in this code.

Attached is a minimal example of the code which crashes (it crashes in the SLIST_FOREACH [macro]call) and a dump of the output just prior to crashing and after the crash.

Since I don't now much about hardware I'm not sure whether it is normal that pci1 is a child of pci0, and I also would have thought the resource_list pointer of pci1 (which it crashes on) would be more in sequentual to the pointer of the resource_list pointers of agp0 and pcib1.

Hope one of you can help.


Martin
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/malloc.h>

#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/conf.h>

#include <sys/bus.h>
#include <sys/rman.h>

static void
print_spaces(int len)
{
	int		i;

	for (i = 0; i < len; i++) {
		kprintf(" ");
	}
}

static void
walk_tree(device_t dev, int depth)
{
	int 				i;
	struct resource			*r;
	struct resource_list		*rl;
	struct resource_list_entry	*rle;
	device_t			*children;
	int				child_cnt;

	print_spaces(depth * 2);
	device_print_prettyname(dev);
	kprintf(" %sactive", (device_is_alive(dev) == FALSE ? "in" : ""));

	rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev);

	kprintf(" (resource head: %p)\n", rl);
	if (rl != NULL) {
		SLIST_FOREACH(rle, rl, link) {
			r = rle->res;
			print_spaces(depth * 2 + 2);
			kprintf("resource: type = %x, start = %X, end = %X\n",
			    rle->type, rman_get_start(r), rman_get_end(r));
		}
	}

	device_get_children(dev, &children, &child_cnt);
	for (i = 0; i < child_cnt; i++) {
		walk_tree(children[i], depth + 1);
	}
	kfree(children, M_TEMP);
}

static int
res_modevent(module_t mod, int cmd, void *arg)
{
	int			i;
	int			error = 0;
	devclass_t		nexus_class;
	device_t		*nexus_devs;
	int			nexus_cnt = 0;;

	switch (cmd) {
	case MOD_LOAD:
		nexus_class = devclass_find("nexus");
		devclass_get_devices(nexus_class, &nexus_devs, &nexus_cnt);
		for (i = 0; i < nexus_cnt; i++) {
			walk_tree(nexus_devs[i], 0);
		}

		kfree(nexus_devs, M_TEMP);

		error = EINVAL;
		break;
	case MOD_SHUTDOWN:
		break;
	case MOD_UNLOAD:
		break;
	default:
		error = EINVAL;
		break;
	}

	return(error);
}

DEV_MODULE(resources, res_modevent, NULL);
MODULE_VERSION(resources, 1);
Unread portion of the kernel message buffer:
nexus0:  active (resource head: 0)
  apm0:  inactive (resource head: 0)
  npx0:  active (resource head: 0)
  acpi0:  active (resource head: 0)
    acpi_timer0:  active (resource head: 0)
    cpu0:  active (resource head: 0)
    unknown:  inactive (resource head: 0)
    acpi_tz0:  active (resource head: 0)
    acpi_button0:  active (resource head: 0)
    acpi_button1:  active (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    acpi_sysresource0:  active (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
    unknown:  inactive (resource head: 0)
  eisa0:  inactive (resource head: 0)
  legacypci0:  active (resource head: 0)
    pcib0:  active (resource head: 0)
      pci0:  active (resource head: 0)
        agp0:  active (resource head: 0xc0d061d4)
          resource: type = 3, start = E0000000, end = E3FFFFFF
        pcib1:  active (resource head: 0xc0d06234)
          pci1:  active (resource head: 0x4)


Fatal trap 12: page fault while in kernel mode
fault virtual address	= 0x4
fault code		= supervisor read, page not present
instruction pointer	= 0x8:0xcc796616
stack pointer	        = 0x10:0xcc76aae4
frame pointer	        = 0x10:0xcc76ab08
code segment		= base 0x0, limit 0xfffff, type 0x1b
			= DPL 0, pres 1, def32 1, gran 1
processor eflags	= interrupt enabled, resume, IOPL = 0
current process		= 691 (kldload)
current thread          = pri 10 

panic: from debugger


Fatal trap 3: breakpoint instruction fault while in kernel mode
instruction pointer	= 0x8:0xc04f5089
stack pointer	        = 0x10:0xcc76a8a0
frame pointer	        = 0x10:0xcc76a8a8
code segment		= base 0x0, limit 0xfffff, type 0x1b
			= DPL 0, pres 1, def32 1, gran 1
processor eflags	= interrupt enabled, IOPL = 0
current process		= 691 (kldload)
current thread          = pri 10 

panic: from debugger
Uptime: 1m46s

dumping to dev #ad/0x20009, offset 1835008
dump 128 127 126 125 124 123 122 121 120 119 118 117 116 115 114 113 112 111 110 109 108 107 106 105 104 103 102 101 100 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 

GNU gdb 6.2.1
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-dragonfly".
(kgdb) quit


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