[PATCH] uml: Add static initializations and declarations
[powerpc.git] / arch / um / drivers / mconsole_kern.c
index 404de41..b5217bd 100644 (file)
@@ -32,8 +32,9 @@
 #include "os.h"
 #include "umid.h"
 #include "irq_kern.h"
+#include "choose-mode.h"
 
-static int do_unlink_socket(struct notifier_block *notifier, 
+static int do_unlink_socket(struct notifier_block *notifier,
                            unsigned long what, void *data)
 {
        return(mconsole_unlink_socket());
@@ -45,12 +46,12 @@ static struct notifier_block reboot_notifier = {
        .priority               = 0,
 };
 
-/* Safe without explicit locking for now.  Tasklets provide their own 
+/* Safe without explicit locking for now.  Tasklets provide their own
  * locking, and the interrupt handler is safe because it can't interrupt
  * itself and it can only happen on CPU 0.
  */
 
-LIST_HEAD(mc_requests);
+static LIST_HEAD(mc_requests);
 
 static void mc_work_proc(void *unused)
 {
@@ -59,7 +60,7 @@ static void mc_work_proc(void *unused)
 
        while(!list_empty(&mc_requests)){
                local_save_flags(flags);
-               req = list_entry(mc_requests.next, struct mconsole_entry, 
+               req = list_entry(mc_requests.next, struct mconsole_entry,
                                 list);
                list_del(&req->list);
                local_irq_restore(flags);
@@ -68,7 +69,7 @@ static void mc_work_proc(void *unused)
        }
 }
 
-DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
+static DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
 
 static irqreturn_t mconsole_interrupt(int irq, void *dev_id,
                                      struct pt_regs *regs)
@@ -102,8 +103,8 @@ void mconsole_version(struct mc_request *req)
 {
        char version[256];
 
-       sprintf(version, "%s %s %s %s %s", system_utsname.sysname, 
-               system_utsname.nodename, system_utsname.release, 
+       sprintf(version, "%s %s %s %s %s", system_utsname.sysname,
+               system_utsname.nodename, system_utsname.release,
                system_utsname.version, system_utsname.machine);
        mconsole_reply(req, version, 0, 0);
 }
@@ -276,6 +277,7 @@ void mconsole_proc(struct mc_request *req)
     go - continue the UML after a 'stop' \n\
     log <string> - make UML enter <string> into the kernel log\n\
     proc <file> - returns the contents of the UML's /proc/<file>\n\
+    stack <pid> - returns the stack of the specified pid\n\
 "
 
 void mconsole_help(struct mc_request *req)
@@ -346,7 +348,7 @@ static struct mc_device *mconsole_find_dev(char *name)
 
 #define CONFIG_BUF_SIZE 64
 
-static void mconsole_get_config(int (*get_config)(char *, char *, int, 
+static void mconsole_get_config(int (*get_config)(char *, char *, int,
                                                  char **),
                                struct mc_request *req, char *name)
 {
@@ -387,7 +389,6 @@ static void mconsole_get_config(int (*get_config)(char *, char *, int,
  out:
        if(buf != default_buf)
                kfree(buf);
-       
 }
 
 void mconsole_config(struct mc_request *req)
@@ -418,7 +419,7 @@ void mconsole_config(struct mc_request *req)
 
 void mconsole_remove(struct mc_request *req)
 {
-       struct mc_device *dev;  
+       struct mc_device *dev;
        char *ptr = req->request.data, *err_msg = "";
         char error[256];
        int err, start, end, n;
@@ -479,12 +480,62 @@ void mconsole_sysrq(struct mc_request *req)
 }
 #endif
 
+/* Mconsole stack trace
+ *  Added by Allan Graves, Jeff Dike
+ *  Dumps a stacks registers to the linux console.
+ *  Usage stack <pid>.
+ */
+void do_stack(struct mc_request *req)
+{
+        char *ptr = req->request.data;
+        int pid_requested= -1;
+        struct task_struct *from = NULL;
+       struct task_struct *to = NULL;
+
+        /* Would be nice:
+         * 1) Send showregs output to mconsole.
+        * 2) Add a way to stack dump all pids.
+        */
+
+        ptr += strlen("stack");
+        while(isspace(*ptr)) ptr++;
+
+        /* Should really check for multiple pids or reject bad args here */
+        /* What do the arguments in mconsole_reply mean? */
+        if(sscanf(ptr, "%d", &pid_requested) == 0){
+                mconsole_reply(req, "Please specify a pid", 1, 0);
+                return;
+        }
+
+        from = current;
+        to = find_task_by_pid(pid_requested);
+
+        if((to == NULL) || (pid_requested == 0)) {
+                mconsole_reply(req, "Couldn't find that pid", 1, 0);
+                return;
+        }
+        to->thread.saved_task = current;
+
+        switch_to(from, to, from);
+        mconsole_reply(req, "Stack Dumped to console and message log", 0, 0);
+}
+
+void mconsole_stack(struct mc_request *req)
+{
+       /* This command doesn't work in TT mode, so let's check and then
+        * get out of here
+        */
+       CHOOSE_MODE(mconsole_reply(req, "Sorry, this doesn't work in TT mode",
+                                  1, 0),
+                   do_stack(req));
+}
+
 /* Changed by mconsole_setup, which is __setup, and called before SMP is
  * active.
  */
-static char *notify_socket = NULL; 
+static char *notify_socket = NULL;
 
-int mconsole_init(void)
+static int mconsole_init(void)
 {
        /* long to avoid size mismatch warnings from gcc */
        long sock;
@@ -511,16 +562,16 @@ int mconsole_init(void)
        }
 
        if(notify_socket != NULL){
-               notify_socket = uml_strdup(notify_socket);
+               notify_socket = kstrdup(notify_socket, GFP_KERNEL);
                if(notify_socket != NULL)
                        mconsole_notify(notify_socket, MCONSOLE_SOCKET,
-                                       mconsole_socket_name, 
+                                       mconsole_socket_name,
                                        strlen(mconsole_socket_name) + 1);
                else printk(KERN_ERR "mconsole_setup failed to strdup "
                            "string\n");
        }
 
-       printk("mconsole (version %d) initialized on %s\n", 
+       printk("mconsole (version %d) initialized on %s\n",
               MCONSOLE_VERSION, mconsole_socket_name);
        return(0);
 }
@@ -533,7 +584,7 @@ static int write_proc_mconsole(struct file *file, const char __user *buffer,
        char *buf;
 
        buf = kmalloc(count + 1, GFP_KERNEL);
-       if(buf == NULL) 
+       if(buf == NULL)
                return(-ENOMEM);
 
        if(copy_from_user(buf, buffer, count)){
@@ -557,7 +608,7 @@ static int create_proc_mconsole(void)
 
        ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL);
        if(ent == NULL){
-               printk("create_proc_mconsole : create_proc_entry failed\n");
+               printk(KERN_INFO "create_proc_mconsole : create_proc_entry failed\n");
                return(0);
        }
 
@@ -609,7 +660,7 @@ static int notify_panic(struct notifier_block *self, unsigned long unused1,
 
        if(notify_socket == NULL) return(0);
 
-       mconsole_notify(notify_socket, MCONSOLE_PANIC, message, 
+       mconsole_notify(notify_socket, MCONSOLE_PANIC, message,
                        strlen(message) + 1);
        return(0);
 }