diff --git a/src/kernel/core/cbuf.c b/src/kernel/core/cbuf.c index fe1fef0da6..026e1ad073 100644 --- a/src/kernel/core/cbuf.c +++ b/src/kernel/core/cbuf.c @@ -763,7 +763,7 @@ int cbuf_truncate_tail(cbuf *buf, size_t trunc_bytes) return B_NO_ERROR; } -static void dbg_dump_cbuf_freelists(int argc, char **argv) +static int dbg_dump_cbuf_freelists(int argc, char **argv) { cbuf *buf; @@ -776,6 +776,7 @@ static void dbg_dump_cbuf_freelists(int argc, char **argv) for(buf = cbuf_free_noblock_list; buf; buf = buf->next) dprintf("%p ", buf); dprintf("\n"); + return 0; } void cbuf_test() @@ -832,7 +833,7 @@ int cbuf_init() cbuf_lowlevel_spinlock = 0; // add the debug command - dbg_add_command(&dbg_dump_cbuf_freelists, "cbuf_freelist", "Dumps the cbuf free lists"); + add_debugger_command("cbuf_freelist", &dbg_dump_cbuf_freelists, "Dumps the cbuf free lists"); free_list_sem = create_sem(1, "cbuf_free_list_sem"); if(free_list_sem < 0) { diff --git a/src/kernel/core/debug.c b/src/kernel/core/debug.c index 8d5e82e090..ed6c68ac4a 100644 --- a/src/kernel/core/debug.c +++ b/src/kernel/core/debug.c @@ -34,8 +34,8 @@ static int debugger_on_cpu = -1; struct debugger_command { struct debugger_command *next; - void (*func)(int, char **); - const char *cmd; + int (*func)(int, char **); + const char *name; const char *description; }; @@ -204,7 +204,7 @@ static void kernel_debugger_loop() debugger_on_cpu = smp_get_current_cpu(); for(;;) { - dprintf("> "); + dprintf("kdebug> "); debug_read_line(line_buf[cur_line], LINE_BUF_SIZE); debug_parse_line(line_buf[cur_line], args, &argc, MAX_ARGS); if(argc <= 0) @@ -214,8 +214,9 @@ static void kernel_debugger_loop() cmd = commands; while(cmd != NULL) { - if(strcmp(args[0], cmd->cmd) == 0) { + if(strcmp(args[0], cmd->name) == 0) { cmd->func(argc, args); + break; } cmd = cmd->next; } @@ -225,10 +226,16 @@ static void kernel_debugger_loop() } } -void kernel_debugger() +void kernel_debugger(const char * message) { dbg_save_registers(&(dbg_register_file[smp_get_current_cpu()][0])); + if (message) { + dprintf(message); + dprintf("\n"); + }; + + dprintf("Welcome to Kernel Debugging Land...\n"); kernel_debugger_loop(); } @@ -257,7 +264,7 @@ int panic(const char *fmt, ...) smp_send_broadcast_ici(SMP_MSG_CPU_HALT, 0, 0, 0, NULL, SMP_MSG_FLAG_SYNC); } - kernel_debugger(); + kernel_debugger(NULL); int_restore_interrupts(state); return ret; @@ -308,17 +315,17 @@ void dbg_puts(const char *s) int_restore_interrupts(flags); } -int dbg_add_command(void (*func)(int, char **), const char *name, const char *desc) +int add_debugger_command(const char * name, int (*func)(int, char **), const char * desc) { int flags; struct debugger_command *cmd; - cmd = (struct debugger_command *)kmalloc(sizeof(struct debugger_command)); - if(cmd == NULL) + cmd = (struct debugger_command *) kmalloc(sizeof(struct debugger_command)); + if (cmd == NULL) return ENOMEM; cmd->func = func; - cmd->cmd = name; + cmd->name = name; cmd->description = desc; flags = int_disable_interrupts(); @@ -333,21 +340,62 @@ int dbg_add_command(void (*func)(int, char **), const char *name, const char *de return B_NO_ERROR; } -static void cmd_reboot(int argc, char **argv) +int remove_debugger_command(const char * name, int (*func)(int, char **)) { - reboot(); + int flags; + struct debugger_command *cmd; + struct debugger_command *prev; + + flags = int_disable_interrupts(); + acquire_spinlock(&dbg_spinlock); + + prev = NULL; + cmd = commands; + while (cmd) { + if (strcmp(cmd->name, name) == 0 && + cmd->func == func) + break; + prev = cmd; + cmd = cmd->next; + }; + + if (cmd) { + if (cmd == commands) + commands = cmd->next; + else + prev->next = cmd->next; + }; + + release_spinlock(&dbg_spinlock); + int_restore_interrupts(flags); + + if (cmd) { + kfree(cmd); + return B_NO_ERROR; + }; + + return B_NAME_NOT_FOUND; } -static void cmd_help(int argc, char **argv) + +static int cmd_reboot(int argc, char **argv) +{ + reboot(); + return 0; // I'll be really suprised if this line ever run! ;-) +} + +static int cmd_help(int argc, char **argv) { struct debugger_command *cmd; dprintf("debugger commands:\n"); cmd = commands; while(cmd != NULL) { - dprintf("%-32s\t\t%s\n", cmd->cmd, cmd->description); + dprintf(" %-32s\t\t%s\n", cmd->name, cmd->description); cmd = cmd->next; } + + return 0; } int dbg_init(kernel_args *ka) @@ -359,9 +407,9 @@ int dbg_init(kernel_args *ka) int dbg_init2(kernel_args *ka) { - dbg_add_command(&cmd_help, "help", "List all debugger commands"); - dbg_add_command(&cmd_reboot, "reboot", "Reboot"); - dbg_add_command(&cmd_gdb, "gdb", "Connect to remote gdb"); + add_debugger_command("help", &cmd_help, "List all debugger commands"); + add_debugger_command("reboot", &cmd_reboot, "Reboot"); + add_debugger_command("gdb", &cmd_gdb, "Connect to remote gdb"); return B_NO_ERROR; } diff --git a/src/kernel/core/gdb.c b/src/kernel/core/gdb.c index 5dc3194e9d..c40c29947d 100644 --- a/src/kernel/core/gdb.c +++ b/src/kernel/core/gdb.c @@ -522,11 +522,11 @@ gdb_state_machine(void) return 0; } -void +int cmd_gdb(int argc, char **argv) { (void)(argc); (void)(argv); - gdb_state_machine(); + return gdb_state_machine(); } diff --git a/src/kernel/core/heap.c b/src/kernel/core/heap.c index a22a59a0c8..ced6ddf9a5 100644 --- a/src/kernel/core/heap.c +++ b/src/kernel/core/heap.c @@ -87,7 +87,7 @@ static void dump_bin(int bin_index) dprintf("NULL\n"); } -static void dump_bin_list(int argc, char **argv) +static int dump_bin_list(int argc, char **argv) { int i; @@ -96,6 +96,7 @@ static void dump_bin_list(int argc, char **argv) for(i=0; i MAX_PORTS assumed _dump_port_info((struct port_entry *)num); - return; + return 0; } else { unsigned slot = num % MAX_PORTS; if(ports[slot].id != (int)num) { dprintf("port 0x%lx doesn't exist!\n", num); - return; + return 0; } _dump_port_info(&ports[slot]); - return; + return 0; } } @@ -148,7 +149,7 @@ static void dump_port_info(int argc, char **argv) if (ports[i].name != NULL) if(strcmp(argv[1], ports[i].name) == 0) { _dump_port_info(&ports[i]); - return; + return 0; } } } diff --git a/src/kernel/core/sem.c b/src/kernel/core/sem.c index d9a1497a66..e9f7352cba 100644 --- a/src/kernel/core/sem.c +++ b/src/kernel/core/sem.c @@ -56,7 +56,7 @@ struct sem_timeout_args { int sem_count; }; -static void dump_sem_list(int argc, char **argv) +static int dump_sem_list(int argc, char **argv) { int i; @@ -65,6 +65,7 @@ static void dump_sem_list(int argc, char **argv) dprintf("%p\tid: 0x%x\t\tname: '%s'\n", &sems[i], sems[i].id, sems[i].name); } } + return 0; } static void _dump_sem_info(struct sem_entry *sem) @@ -76,13 +77,13 @@ static void _dump_sem_info(struct sem_entry *sem) dprintf("queue: head %p tail %p\n", sem->q.head, sem->q.tail); } -static void dump_sem_info(int argc, char **argv) +static int dump_sem_info(int argc, char **argv) { int i; if(argc < 2) { dprintf("sem: not enough arguments\n"); - return; + return 0; } // if the argument looks like a hex number, treat it as such @@ -92,15 +93,15 @@ static void dump_sem_info(int argc, char **argv) if(num > KERNEL_BASE && num <= (KERNEL_BASE + (KERNEL_SIZE - 1))) { // XXX semi-hack _dump_sem_info((struct sem_entry *)num); - return; + return 0; } else { unsigned slot = num % MAX_SEMS; if(sems[slot].id != (int)num) { dprintf("sem 0x%lx doesn't exist!\n", num); - return; + return 0; } _dump_sem_info(&sems[slot]); - return; + return 0; } } @@ -109,7 +110,7 @@ static void dump_sem_info(int argc, char **argv) if (sems[i].name != NULL) if(strcmp(argv[1], sems[i].name) == 0) { _dump_sem_info(&sems[i]); - return; + return 0; } } } @@ -132,8 +133,8 @@ int sem_init(kernel_args *ka) sems[i].id = -1; // add debugger commands - dbg_add_command(&dump_sem_list, "sems", "Dump a list of all active semaphores"); - dbg_add_command(&dump_sem_info, "sem", "Dump info about a particular semaphore"); + add_debugger_command("sems", &dump_sem_list, "Dump a list of all active semaphores"); + add_debugger_command("sem", &dump_sem_info, "Dump info about a particular semaphore"); dprintf("sem_init: exit\n"); diff --git a/src/kernel/core/thread.c b/src/kernel/core/thread.c index 00487b8733..538499739b 100644 --- a/src/kernel/core/thread.c +++ b/src/kernel/core/thread.c @@ -646,7 +646,7 @@ static void _dump_proc_info(struct proc *p) dprintf("thread_list: %p\n", p->thread_list); } -static void dump_proc_info(int argc, char **argv) +static int dump_proc_info(int argc, char **argv) { struct proc *p; int id = -1; @@ -655,7 +655,7 @@ static void dump_proc_info(int argc, char **argv) if(argc < 2) { dprintf("proc: not enough arguments\n"); - return; + return 0; } // if the argument looks like a hex number, treat it as such @@ -664,7 +664,7 @@ static void dump_proc_info(int argc, char **argv) if(num > vm_get_kernel_aspace()->virtual_map.base) { // XXX semi-hack _dump_proc_info((struct proc*)num); - return; + return 0; } else { id = num; } @@ -679,6 +679,7 @@ static void dump_proc_info(int argc, char **argv) } } hash_close(proc_hash, &i, false); + return 0; } @@ -743,7 +744,7 @@ static void _dump_thread_info(struct thread *t) last_thread_dumped = t; } -static void dump_thread_info(int argc, char **argv) +static int dump_thread_info(int argc, char **argv) { struct thread *t; int id = -1; @@ -752,7 +753,7 @@ static void dump_thread_info(int argc, char **argv) if(argc < 2) { dprintf("thread: not enough arguments\n"); - return; + return 0; } // if the argument looks like a hex number, treat it as such @@ -761,7 +762,7 @@ static void dump_thread_info(int argc, char **argv) if(num > vm_get_kernel_aspace()->virtual_map.base) { // XXX semi-hack _dump_thread_info((struct thread *)num); - return; + return 0; } else { id = num; } @@ -776,9 +777,10 @@ static void dump_thread_info(int argc, char **argv) } } hash_close(thread_hash, &i, false); + return 0; } -static void dump_thread_list(int argc, char **argv) +static int dump_thread_list(int argc, char **argv) { struct thread *t; struct hash_iterator i; @@ -799,15 +801,16 @@ static void dump_thread_list(int argc, char **argv) dprintf("\t0x%lx\n", t->kernel_stack_base); } hash_close(thread_hash, &i, false); + return 0; } -static void dump_next_thread_in_q(int argc, char **argv) +static int dump_next_thread_in_q(int argc, char **argv) { struct thread *t = last_thread_dumped; if(t == NULL) { dprintf("no thread previously dumped. Examine a thread first.\n"); - return; + return 0; } dprintf("next thread in queue after thread @ %p\n", t); @@ -816,15 +819,16 @@ static void dump_next_thread_in_q(int argc, char **argv) } else { dprintf("NULL\n"); } + return 0; } -static void dump_next_thread_in_all_list(int argc, char **argv) +static int dump_next_thread_in_all_list(int argc, char **argv) { struct thread *t = last_thread_dumped; if(t == NULL) { dprintf("no thread previously dumped. Examine a thread first.\n"); - return; + return 0; } dprintf("next thread in global list after thread @ %p\n", t); @@ -833,15 +837,16 @@ static void dump_next_thread_in_all_list(int argc, char **argv) } else { dprintf("NULL\n"); } + return 0; } -static void dump_next_thread_in_proc(int argc, char **argv) +static int dump_next_thread_in_proc(int argc, char **argv) { struct thread *t = last_thread_dumped; if(t == NULL) { dprintf("no thread previously dumped. Examine a thread first.\n"); - return; + return 0; } dprintf("next thread in proc after thread @ %p\n", t); @@ -850,6 +855,7 @@ static void dump_next_thread_in_proc(int argc, char **argv) } else { dprintf("NULL\n"); } + return 0; } static int get_death_stack(void) @@ -1016,12 +1022,12 @@ int thread_init(kernel_args *ka) death_stack_sem = create_sem(num_death_stacks, "death_stack_noavail_sem"); // set up some debugger commands - dbg_add_command(dump_thread_list, "threads", "list all threads"); - dbg_add_command(dump_thread_info, "thread", "list info about a particular thread"); - dbg_add_command(dump_next_thread_in_q, "next_q", "dump the next thread in the queue of last thread viewed"); - dbg_add_command(dump_next_thread_in_all_list, "next_all", "dump the next thread in the global list of the last thread viewed"); - dbg_add_command(dump_next_thread_in_proc, "next_proc", "dump the next thread in the process of the last thread viewed"); - dbg_add_command(dump_proc_info, "proc", "list info about a particular process"); + add_debugger_command("threads", &dump_thread_list, "list all threads"); + add_debugger_command("thread", &dump_thread_info, "list info about a particular thread"); + add_debugger_command("next_q", &dump_next_thread_in_q, "dump the next thread in the queue of last thread viewed"); + add_debugger_command("next_all", &dump_next_thread_in_all_list, "dump the next thread in the global list of the last thread viewed"); + add_debugger_command("next_proc", &dump_next_thread_in_proc, "dump the next thread in the process of the last thread viewed"); + add_debugger_command("proc", &dump_proc_info, "list info about a particular process"); return 0; } diff --git a/src/kernel/core/vm/vm.c b/src/kernel/core/vm/vm.c index 91298b5406..76046cf200 100755 --- a/src/kernel/core/vm/vm.c +++ b/src/kernel/core/vm/vm.c @@ -1066,7 +1066,7 @@ int vm_get_page_mapping(aspace_id aid, addr vaddr, addr *paddr) return err; } -static void display_mem(int argc, char **argv) +static int display_mem(int argc, char **argv) { int item_size; int display_width; @@ -1077,7 +1077,7 @@ static void display_mem(int argc, char **argv) if(argc < 2) { dprintf("not enough arguments\n"); - return; + return 0; } address = atoul(argv[1]); @@ -1099,7 +1099,7 @@ static void display_mem(int argc, char **argv) display_width = 4; } else { dprintf("display_mem called in an invalid way!\n"); - return; + return 0; } dprintf("[0x%lx] '", address); @@ -1139,9 +1139,10 @@ static void display_mem(int argc, char **argv) } } dprintf("\n"); + return 0; } -static void dump_cache_ref(int argc, char **argv) +static int dump_cache_ref(int argc, char **argv) { addr address; vm_region *region; @@ -1149,11 +1150,11 @@ static void dump_cache_ref(int argc, char **argv) if(argc < 2) { dprintf("cache_ref: not enough arguments\n"); - return; + return 0; } if(strlen(argv[1]) < 2 || argv[1][0] != '0' || argv[1][1] != 'x') { dprintf("cache_ref: invalid argument, pass address\n"); - return; + return 0; } address = atoul(argv[1]); @@ -1172,6 +1173,7 @@ static void dump_cache_ref(int argc, char **argv) dprintf("lock = 0x%x\n", region->lock); } dprintf("ref_count: %d\n", cache_ref->ref_count); + return 0; } static const char *page_state_to_text(int state) @@ -1198,7 +1200,7 @@ static const char *page_state_to_text(int state) } } -static void dump_cache(int argc, char **argv) +static int dump_cache(int argc, char **argv) { addr address; vm_cache *cache; @@ -1206,11 +1208,11 @@ static void dump_cache(int argc, char **argv) if(argc < 2) { dprintf("cache: not enough arguments\n"); - return; + return 0; } if(strlen(argv[1]) < 2 || argv[1][0] != '0' || argv[1][1] != 'x') { dprintf("cache: invalid argument, pass address\n"); - return; + return 0; } address = atoul(argv[1]); @@ -1235,6 +1237,7 @@ static void dump_cache(int argc, char **argv) else dprintf(" %p UNKNOWN PAGE type %d\n", page, page->type); } + return 0; } static void _dump_region(vm_region *region) @@ -1254,14 +1257,14 @@ static void _dump_region(vm_region *region) dprintf("cache_prev: %p\n", region->cache_prev); } -static void dump_region(int argc, char **argv) +static int dump_region(int argc, char **argv) { // int i; vm_region *region; if(argc < 2) { dprintf("region: not enough arguments\n"); - return; + return 0; } // if the argument looks like a hex number, treat it as such @@ -1275,7 +1278,7 @@ static void dump_region(int argc, char **argv) } else { _dump_region(region); } - return; + return 0; } else { // walk through the region list, looking for the arguments as a name struct hash_iterator iter; @@ -1287,6 +1290,7 @@ static void dump_region(int argc, char **argv) } } } + return 0; } region_id find_region_by_address (addr vaddress) @@ -1319,7 +1323,7 @@ region_id find_region_by_name(const char *name) return B_NAME_NOT_FOUND; } -static void dump_region_list(int argc, char **argv) +static int dump_region_list(int argc, char **argv) { vm_region *region; struct hash_iterator iter; @@ -1332,6 +1336,7 @@ static void dump_region_list(int argc, char **argv) region, region->id, region->name, region->base, region->size, region->lock, region->wiring); } hash_close(region_table, &iter, false); + return 0; } static void _dump_aspace(vm_address_space *aspace) @@ -1360,14 +1365,14 @@ static void _dump_aspace(vm_address_space *aspace) } } -static void dump_aspace(int argc, char **argv) +static int dump_aspace(int argc, char **argv) { // int i; vm_address_space *aspace; if(argc < 2) { dprintf("aspace: not enough arguments\n"); - return; + return 0; } // if the argument looks like a hex number, treat it as such @@ -1381,7 +1386,7 @@ static void dump_aspace(int argc, char **argv) } else { _dump_aspace(aspace); } - return; + return 0; } else { // walk through the aspace list, looking for the arguments as a name struct hash_iterator iter; @@ -1393,9 +1398,10 @@ static void dump_aspace(int argc, char **argv) } } } + return 0; } -static void dump_aspace_list(int argc, char **argv) +static int dump_aspace_list(int argc, char **argv) { vm_address_space *as; struct hash_iterator iter; @@ -1408,6 +1414,7 @@ static void dump_aspace_list(int argc, char **argv) as, as->id, as->name, as->virtual_map.base, as->virtual_map.size); } hash_close(aspace_table, &iter, false); + return 0; } vm_address_space *vm_get_kernel_aspace(void) @@ -1730,16 +1737,16 @@ int vm_init(kernel_args *ka) arch_vm_init_endvm(ka); // add some debugger commands - dbg_add_command(&dump_region_list, "regions", "Dump a list of all regions"); - dbg_add_command(&dump_region, "region", "Dump info about a particular region"); - dbg_add_command(&dump_aspace_list, "aspaces", "Dump a list of all address spaces"); - dbg_add_command(&dump_aspace, "aspace", "Dump info about a particular address space"); - dbg_add_command(&dump_cache_ref, "cache_ref", "Dump cache_ref data structure"); - dbg_add_command(&dump_cache, "cache", "Dump cache_ref data structure"); -// dbg_add_command(&display_mem, "dl", "dump memory long words (64-bit)"); - dbg_add_command(&display_mem, "dw", "dump memory words (32-bit)"); - dbg_add_command(&display_mem, "ds", "dump memory shorts (16-bit)"); - dbg_add_command(&display_mem, "db", "dump memory bytes (8-bit)"); + add_debugger_command("regions", &dump_region_list, "Dump a list of all regions"); + add_debugger_command("region", &dump_region, "Dump info about a particular region"); + add_debugger_command("aspaces", &dump_aspace_list, "Dump a list of all address spaces"); + add_debugger_command("aspace", &dump_aspace, "Dump info about a particular address space"); + add_debugger_command("cache_ref", &dump_cache_ref, "Dump cache_ref data structure"); + add_debugger_command("cache", &dump_cache, "Dump cache_ref data structure"); +// add_debugger_command("dl", &display_mem, "dump memory long words (64-bit)"); + add_debugger_command("dw", &display_mem, "dump memory words (32-bit)"); + add_debugger_command("ds", &display_mem, "dump memory shorts (16-bit)"); + add_debugger_command("db", &display_mem, "dump memory bytes (8-bit)"); dprintf("vm_init: exit\n"); diff --git a/src/kernel/core/vm/vm_page.c b/src/kernel/core/vm/vm_page.c index cf1ad1c5b6..d777a1aa32 100755 --- a/src/kernel/core/vm/vm_page.c +++ b/src/kernel/core/vm/vm_page.c @@ -40,8 +40,8 @@ static spinlock_t page_lock; static sem_id modified_pages_available; -void dump_page_stats(int argc, char **argv); -void dump_free_page_table(int argc, char **argv); +static int dump_page_stats(int argc, char **argv); +static int dump_free_page_table(int argc, char **argv); static int vm_page_set_state_nolock(vm_page *page, int page_state); static void clear_page(addr pa); static int page_scrubber(void *); @@ -251,8 +251,8 @@ int vm_page_init2(kernel_args *ka) vm_create_anonymous_region(vm_get_kernel_aspace_id(), "page_structures", &null, REGION_ADDR_EXACT_ADDRESS, PAGE_ALIGN(num_pages * sizeof(vm_page)), REGION_WIRING_WIRED_ALREADY, LOCK_RW|LOCK_KERNEL); - dbg_add_command(&dump_page_stats, "page_stats", "Dump statistics about page usage"); - dbg_add_command(&dump_free_page_table, "free_pages", "Dump list of free pages"); + add_debugger_command("page_stats", &dump_page_stats, "Dump statistics about page usage"); + add_debugger_command("free_pages", &dump_free_page_table, "Dump list of free pages"); return 0; } @@ -620,12 +620,13 @@ addr vm_page_num_free_pages() return page_free_queue.count + page_clear_queue.count; } -void dump_free_page_table(int argc, char **argv) +static int dump_free_page_table(int argc, char **argv) { dprintf("not finished\n"); + return 0; } -void dump_page_stats(int argc, char **argv) +static int dump_page_stats(int argc, char **argv) { unsigned int page_types[8]; addr i; @@ -641,11 +642,12 @@ void dump_page_stats(int argc, char **argv) page_types[PAGE_STATE_ACTIVE], page_types[PAGE_STATE_INACTIVE], page_types[PAGE_STATE_BUSY], page_types[PAGE_STATE_UNUSED]); dprintf("modified: %d\nfree: %d\nclear: %d\nwired: %d\n", page_types[PAGE_STATE_MODIFIED], page_types[PAGE_STATE_FREE], page_types[PAGE_STATE_CLEAR], page_types[PAGE_STATE_WIRED]); + return 0; } #if 0 -static void dump_free_page_table(int argc, char **argv) +static int dump_free_page_table(int argc, char **argv) { unsigned int i = 0; unsigned int free_start = END_OF_LIST; @@ -689,6 +691,7 @@ static void dump_free_page_table(int argc, char **argv) dprintf("%d->%d ", i, free_page_table[i]); } */ + return 0; } #endif static addr vm_alloc_vspace_from_ka_struct(kernel_args *ka, unsigned int size) diff --git a/src/kernel/drivers/dev.c b/src/kernel/drivers/dev.c index 37392137d7..70e1234f6a 100755 --- a/src/kernel/drivers/dev.c +++ b/src/kernel/drivers/dev.c @@ -160,12 +160,14 @@ image_id dev_load_dev_module(const char *name, const char *dirpath) if (keep_loaded) return id; - /* If the fucntion gets here then the following has happenned... + /* If the function gets here then the following has happenned... * - the driver has been loaded * - it has appeared valid * - init_hardware has returned saying it should be used * - init_driver has been run OK - * - devfs_publish_devices has for some reason failed. + * - publish_devices return empty paths list or + * devfs_publish_device has for some reason failed on each path. + * * The error value we're about to return is 0, which probably * means we're loosing error information here :( * XXX - what error code should we be returning