diff options
Diffstat (limited to 'arch/um/drivers/mconsole_kern.c')
-rw-r--r-- | arch/um/drivers/mconsole_kern.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index d08bd036ccb8..96f0189327af 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c | |||
@@ -56,7 +56,7 @@ static struct notifier_block reboot_notifier = { | |||
56 | 56 | ||
57 | static LIST_HEAD(mc_requests); | 57 | static LIST_HEAD(mc_requests); |
58 | 58 | ||
59 | static void mc_work_proc(void *unused) | 59 | static void mc_work_proc(struct work_struct *unused) |
60 | { | 60 | { |
61 | struct mconsole_entry *req; | 61 | struct mconsole_entry *req; |
62 | unsigned long flags; | 62 | unsigned long flags; |
@@ -72,14 +72,14 @@ static void mc_work_proc(void *unused) | |||
72 | } | 72 | } |
73 | } | 73 | } |
74 | 74 | ||
75 | static DECLARE_WORK(mconsole_work, mc_work_proc, NULL); | 75 | static DECLARE_WORK(mconsole_work, mc_work_proc); |
76 | 76 | ||
77 | static irqreturn_t mconsole_interrupt(int irq, void *dev_id) | 77 | static irqreturn_t mconsole_interrupt(int irq, void *dev_id) |
78 | { | 78 | { |
79 | /* long to avoid size mismatch warnings from gcc */ | 79 | /* long to avoid size mismatch warnings from gcc */ |
80 | long fd; | 80 | long fd; |
81 | struct mconsole_entry *new; | 81 | struct mconsole_entry *new; |
82 | struct mc_request req; | 82 | static struct mc_request req; /* that's OK */ |
83 | 83 | ||
84 | fd = (long) dev_id; | 84 | fd = (long) dev_id; |
85 | while (mconsole_get_request(fd, &req)){ | 85 | while (mconsole_get_request(fd, &req)){ |
@@ -91,6 +91,7 @@ static irqreturn_t mconsole_interrupt(int irq, void *dev_id) | |||
91 | mconsole_reply(&req, "Out of memory", 1, 0); | 91 | mconsole_reply(&req, "Out of memory", 1, 0); |
92 | else { | 92 | else { |
93 | new->request = req; | 93 | new->request = req; |
94 | new->request.regs = get_irq_regs()->regs; | ||
94 | list_add(&new->list, &mc_requests); | 95 | list_add(&new->list, &mc_requests); |
95 | } | 96 | } |
96 | } | 97 | } |
@@ -314,9 +315,21 @@ void mconsole_stop(struct mc_request *req) | |||
314 | { | 315 | { |
315 | deactivate_fd(req->originating_fd, MCONSOLE_IRQ); | 316 | deactivate_fd(req->originating_fd, MCONSOLE_IRQ); |
316 | os_set_fd_block(req->originating_fd, 1); | 317 | os_set_fd_block(req->originating_fd, 1); |
317 | mconsole_reply(req, "", 0, 0); | 318 | mconsole_reply(req, "stopped", 0, 0); |
318 | while(mconsole_get_request(req->originating_fd, req)){ | 319 | while (mconsole_get_request(req->originating_fd, req)) { |
319 | if(req->cmd->handler == mconsole_go) break; | 320 | if (req->cmd->handler == mconsole_go) |
321 | break; | ||
322 | if (req->cmd->handler == mconsole_stop) { | ||
323 | mconsole_reply(req, "Already stopped", 1, 0); | ||
324 | continue; | ||
325 | } | ||
326 | if (req->cmd->handler == mconsole_sysrq) { | ||
327 | struct pt_regs *old_regs; | ||
328 | old_regs = set_irq_regs((struct pt_regs *)&req->regs); | ||
329 | mconsole_sysrq(req); | ||
330 | set_irq_regs(old_regs); | ||
331 | continue; | ||
332 | } | ||
320 | (*req->cmd->handler)(req); | 333 | (*req->cmd->handler)(req); |
321 | } | 334 | } |
322 | os_set_fd_block(req->originating_fd, 0); | 335 | os_set_fd_block(req->originating_fd, 0); |
@@ -673,9 +686,7 @@ static void with_console(struct mc_request *req, void (*proc)(void *), | |||
673 | static void sysrq_proc(void *arg) | 686 | static void sysrq_proc(void *arg) |
674 | { | 687 | { |
675 | char *op = arg; | 688 | char *op = arg; |
676 | struct pt_regs *old_regs = set_irq_regs(¤t->thread.regs); | ||
677 | handle_sysrq(*op, NULL); | 689 | handle_sysrq(*op, NULL); |
678 | set_irq_regs(old_regs); | ||
679 | } | 690 | } |
680 | 691 | ||
681 | void mconsole_sysrq(struct mc_request *req) | 692 | void mconsole_sysrq(struct mc_request *req) |