static void ps2_debug_sysrq(int c) { printk("\n%02ld:%02ld.%02ld: sysrq:%c ...\n", jiffies / (HZ *60) % 60, jiffies / HZ % 60, jiffies % HZ, c); handle_sysrq(c, 0, 0, 0); printk("%02ld:%02ld.%02ld: sysrq:%c done.\n", jiffies / (HZ *60) % 60, jiffies / HZ % 60, jiffies % HZ, c); }
static void hvc_poll(int index) { struct hvc_struct *hp = &hvc_struct[index]; struct tty_struct *tty; int i, n; char buf[16] __ALIGNED__; unsigned long flags; spin_lock_irqsave(&hp->lock, flags); if (hp->n_outbuf > 0) hvc_push(hp); tty = hp->tty; if (tty) { for (;;) { if (TTY_FLIPBUF_SIZE - tty->flip.count < sizeof(buf)) break; n = hvc_get_chars(index + hvc_offset, buf, sizeof(buf)); if (n <= 0) break; for (i = 0; i < n; ++i) { #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */ if (buf[i] == '\x0f') { /* ^O -- should support a sequence */ sysrq_pressed = 1; continue; } else if (sysrq_pressed) { handle_sysrq(buf[i], NULL, NULL, tty); sysrq_pressed = 0; continue; } #endif tty_insert_flip_char(tty, buf[i], 0); } } if (tty->flip.count) tty_schedule_flip(tty); if (hp->do_wakeup) { hp->do_wakeup = 0; if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) (tty->ldisc.write_wakeup)(tty); wake_up_interruptible(&tty->write_wait); } } spin_unlock_irqrestore(&hp->lock, flags); }
static irqreturn_t s3c2410wdt_irq(int irqno, void *param) { dev_info(wdt_dev, "watchdog timer expired (irq)\n"); s3c2410wdt_keepalive(&s3c2410_wdd); /* Clear the interrupt */ s3c2410wdt_int_clear(&s3c2410_wdd); /* Print backtrace of all cpus. */ handle_sysrq('l'); /* Restart for availability */ pr_info("%s: emergency reboot\n", __func__); emergency_restart(); return IRQ_HANDLED; }
static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len) { int i; for (i=0; i < len; i++) { char c = buf[i]; #ifdef CONFIG_MAGIC_SYSRQ if (c == '\0') { hp->sysrq = 1; continue; } else if (hp->sysrq) { handle_sysrq(c, NULL, hp->tty); hp->sysrq = 0; continue; } #endif /* CONFIG_MAGIC_SYSRQ */ tty_insert_flip_char(hp->tty, c, 0); } }
void xencons_rx(char *buf, unsigned len, struct pt_regs *regs) { int i; unsigned long flags; spin_lock_irqsave(&xencons_lock, flags); if (xencons_tty == NULL) goto out; for (i = 0; i < len; i++) { #ifdef CONFIG_MAGIC_SYSRQ if (sysrq_enabled) { if (buf[i] == '\x0f') { /* ^O */ sysrq_requested = jiffies; continue; /* don't print the sysrq key */ } else if (sysrq_requested) { unsigned long sysrq_timeout = sysrq_requested + HZ*2; sysrq_requested = 0; if (time_before(jiffies, sysrq_timeout)) { spin_unlock_irqrestore( &xencons_lock, flags); handle_sysrq( buf[i], regs, xencons_tty); spin_lock_irqsave( &xencons_lock, flags); continue; } } } #endif tty_insert_flip_char(xencons_tty, buf[i], 0); } tty_flip_buffer_push(xencons_tty); out: spin_unlock_irqrestore(&xencons_lock, flags); }
static void receive_chars(struct tty_struct *tty, struct pt_regs *regs) { unsigned char ch; static unsigned char seen_esc = 0; while ( (ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR)) ) { if ( ch == 27 && seen_esc == 0 ) { seen_esc = 1; continue; } else { if ( seen_esc==1 && ch == 'O' ) { seen_esc = 2; continue; } else if ( seen_esc == 2 ) { if ( ch == 'P' ) /* F1 */ show_state(); #ifdef CONFIG_MAGIC_SYSRQ if ( ch == 'S' ) { /* F4 */ do ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR); while (!ch); handle_sysrq(ch, regs, NULL); } #endif seen_esc = 0; continue; } } seen_esc = 0; if (tty_insert_flip_char(tty, ch, TTY_NORMAL) == 0) break; } tty_flip_buffer_push(tty); }
/* This is our keyboard 'interrupt' routine. * Must run under sunkbd_lock. */ static void __sunkbd_inchar(unsigned char ch, struct pt_regs *regs) { unsigned char keycode; char up_flag; /* 0 or SUNKBD_UBIT */ char raw_mode; if(ch == SKBD_RESET) { kbd_reset_pending = 1; goto out; } if(ch == SKBD_LYOUT) { kbd_layout_pending = 1; goto out; } if(kbd_reset_pending) { sunkbd_type = ch; kbd_reset_pending = 0; if(ch == SUNKBD_TYPE4) send_cmd(SKBDCMD_GLAYOUT); goto out; } else if(kbd_layout_pending) { sunkbd_layout = ch; kbd_layout_pending = 0; goto out; } else if(ch == SKBD_ALLUP) { del_timer (&auto_repeat_timer); memset(key_down, 0, sizeof(key_down)); sun_compute_shiftstate(); goto out; } #ifdef SKBD_DEBUG if(ch == 0x7f) printk("KBD<ALL KEYS UP>"); else printk("KBD<%x %s>", ch, ((ch&0x80) ? "UP" : "DOWN")); #endif /* Whee, a real character. */ if(regs) { pt_regs = regs; last_keycode = keycode = ch; } else { keycode = ch; } do_poke_blanked_console = 1; tasklet_schedule(&console_tasklet); add_keyboard_randomness(keycode); tty = ttytab? ttytab[fg_console]: NULL; if (tty && (!tty->driver_data)) { /* This is to workaround ugly bug in tty_io.c, which does not do locking when it should */ tty = NULL; } kbd = kbd_table + fg_console; if((raw_mode = (kbd->kbdmode == VC_RAW))) { if (kbd_redirected == fg_console+1) push_kbd (keycode); else put_queue(keycode); /* we do not return yet, because we want to maintain * the key_down array, so that we have the correct * values when finishing RAW mode or when changing VT's. */ } up_flag = (keycode & SUNKBD_UBIT); /* The 'up' bit */ keycode &= SUNKBD_KMASK; /* all the rest */ del_timer (&auto_repeat_timer); if(up_flag) { rep = 0; clear_bit(keycode, key_down); } else { if (!norepeat_keys[keycode]) { if (kbd_rate_ticks) { auto_repeat_timer.expires = jiffies + kbd_delay_ticks; add_timer (&auto_repeat_timer); } } rep = test_and_set_bit(keycode, key_down); } #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq hack */ if (l1a_state.l1_down) { if (!up_flag) handle_sysrq(sun_sysrq_xlate[keycode], pt_regs, kbd, tty); goto out; } #endif if(raw_mode) goto out; if(kbd->kbdmode == VC_MEDIUMRAW) { put_queue(keycode + up_flag); goto out; } /* * Small change in philosophy: earlier we defined repetition by * rep = keycode == prev_keycode; * prev_keycode = keycode; * but now by the fact that the depressed key was down already. * Does this ever make a difference? Yes. */ /* * Repeat a key only if the input buffers are empty or the * characters get echoed locally. This makes key repeat usable * with slow applications and under heavy loads. */ if (!rep || (vc_kbd_mode(kbd,VC_REPEAT) && tty && (L_ECHO(tty) || (tty->driver.chars_in_buffer(tty) == 0)))) { u_short keysym; u_char type; /* the XOR below used to be an OR */ int shift_final = shift_state ^ kbd->lockstate ^ kbd->slockstate; ushort *key_map = key_maps[shift_final]; if (key_map != NULL) { keysym = key_map[keycode]; type = KTYP(keysym); if (type >= 0xf0) { type -= 0xf0; if (type == KT_LETTER) { type = KT_LATIN; if (vc_kbd_led(kbd, VC_CAPSLOCK)) { key_map = key_maps[shift_final ^ (1<<KG_SHIFT)]; if (key_map) keysym = key_map[keycode]; } } (*key_handler[type])(keysym & 0xff, up_flag); if (type != KT_SLOCK) kbd->slockstate = 0; } } else { /* maybe beep? */ /* we have at least to update shift_state */ sun_compute_shiftstate(); } } out: tasklet_schedule(&keyboard_tasklet); }
static irqreturn_t sci_keypad_isr(int irq, void *dev_id) { unsigned short key = 0; unsigned long value; struct sci_keypad_t *sci_kpd = dev_id; unsigned long int_status = keypad_readl(KPD_INT_MASK_STATUS); unsigned long key_status = keypad_readl(KPD_KEY_STATUS); unsigned short *keycodes = sci_kpd->input_dev->keycode; unsigned int row_shift = get_count_order(sci_kpd->cols); int col, row; value = keypad_readl(KPD_INT_CLR); value |= KPD_INT_ALL; keypad_writel(KPD_INT_CLR, value); if ((int_status & KPD_PRESS_INT0)) { col = KPD_INT0_COL(key_status); row = KPD_INT0_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); printk("%03dD\n", key); } if (int_status & KPD_RELEASE_INT0) { col = KPD_INT0_COL(key_status); row = KPD_INT0_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); printk("%03dU\n", key); } if ((int_status & KPD_PRESS_INT1)) { col = KPD_INT1_COL(key_status); row = KPD_INT1_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); printk("%03dD\n", key); } if (int_status & KPD_RELEASE_INT1) { col = KPD_INT1_COL(key_status); row = KPD_INT1_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); printk("%03dU\n", key); } if ((int_status & KPD_PRESS_INT2)) { col = KPD_INT2_COL(key_status); row = KPD_INT2_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); printk("%03d\n", key); } if (int_status & KPD_RELEASE_INT2) { col = KPD_INT2_COL(key_status); row = KPD_INT2_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); printk("%03d\n", key); } if (int_status & KPD_PRESS_INT3) { col = KPD_INT3_COL(key_status); row = KPD_INT3_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); printk("%03d\n", key); } if (int_status & KPD_RELEASE_INT3) { col = KPD_INT3_COL(key_status); row = KPD_INT3_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); printk("%03d\n", key); } #ifdef CONFIG_MAGIC_SYSRQ { static unsigned long key_status_prev = 0; if (check_key_down(sci_kpd, key_status, SPRD_CAMERA_KEY) && check_key_down(sci_kpd, key_status, SPRD_VOL_DOWN_KEY) && key_status != key_status_prev) { key_status_prev = key_status; panic("!!!! Combine key: vol_down + camera !!!!\n"); } if (check_key_down(sci_kpd, key_status, SPRD_CAMERA_KEY) && check_key_down(sci_kpd, key_status, SPRD_VOL_UP_KEY) && key_status != key_status_prev) { unsigned long flags; static int rebooted = 0; key_status_prev = key_status; local_irq_save(flags); if (rebooted == 0) { rebooted = 1; pr_warn("!!!!!! Combine Key : vol_up + camera is Down !!!!!!\n"); /* handle_sysrq('t'); */ handle_sysrq('m'); handle_sysrq('w'); handle_sysrq('b'); pr_warn("!!!!!! /proc/sys/kernel/sysrq is disabled !!!!!!\n"); rebooted = 0; } local_irq_restore(flags); } } #endif return IRQ_HANDLED; }
/* * Handle a data charLpEvent. */ static void vioHandleData(struct HvLpEvent *event) { struct tty_struct *tty; unsigned long flags; struct viocharlpevent *cevent = (struct viocharlpevent *)event; struct port_info *pi; int index; u8 port = cevent->virtual_device; if (port >= VTTY_PORTS) { printk(VIOCONS_KERN_WARN "data on invalid virtual device %d\n", port); return; } /* * Hold the spinlock so that we don't take an interrupt that * changes tty between the time we fetch the port_info * pointer and the time we paranoia check. */ spin_lock_irqsave(&consolelock, flags); pi = &port_info[port]; /* * Change 05/01/2003 - Ryan Arnold: If a partition other than * the current exclusive partition tries to send us data * events then just drop them on the floor because we don't * want his stinking data. He isn't authorized to receive * data because he wasn't the first one to get the console, * therefore he shouldn't be allowed to send data either. * This will work without an iSeries fix. */ if (pi->lp != event->xSourceLp) { spin_unlock_irqrestore(&consolelock, flags); return; } tty = pi->tty; if (tty == NULL) { spin_unlock_irqrestore(&consolelock, flags); printk(VIOCONS_KERN_WARN "no tty for virtual device %d\n", port); return; } if (tty->magic != TTY_MAGIC) { spin_unlock_irqrestore(&consolelock, flags); printk(VIOCONS_KERN_WARN "tty bad magic\n"); return; } /* * Just to be paranoid, make sure the tty points back to this port */ pi = (struct port_info *)tty->driver_data; if (!pi || viotty_paranoia_check(pi, tty->name, "vioHandleData")) { spin_unlock_irqrestore(&consolelock, flags); return; } spin_unlock_irqrestore(&consolelock, flags); /* * Change 07/21/2003 - Ryan Arnold: functionality added to * support sysrq utilizing ^O as the sysrq key. The sysrq * functionality will only work if built into the kernel and * then only if sysrq is enabled through the proc filesystem. */ for (index = 0; index < cevent->len; index++) { #ifdef CONFIG_MAGIC_SYSRQ if (sysrq_enabled) { /* 0x0f is the ascii character for ^O */ if (cevent->data[index] == '\x0f') { vio_sysrq_pressed = 1; /* * continue because we don't want to add * the sysrq key into the data string. */ continue; } else if (vio_sysrq_pressed) { handle_sysrq(cevent->data[index], NULL, tty); vio_sysrq_pressed = 0; /* * continue because we don't want to add * the sysrq sequence into the data string. */ continue; } } #endif /* * The sysrq sequence isn't included in this check if * sysrq is enabled and compiled into the kernel because * the sequence will never get inserted into the buffer. * Don't attempt to copy more data into the buffer than we * have room for because it would fail without indication. */ if ((tty->flip.count + 1) > TTY_FLIPBUF_SIZE) { printk(VIOCONS_KERN_WARN "input buffer overflow!\n"); break; } tty_insert_flip_char(tty, cevent->data[index], TTY_NORMAL); } /* if cevent->len == 0 then no data was added to the buffer and flip.count == 0 */ if (tty->flip.count) /* The next call resets flip.count when the data is flushed. */ tty_flip_buffer_push(tty); }
static void ctrlchar_handle_sysrq(struct work_struct *work) { handle_sysrq(ctrlchar_sysrq_key, sysrq_tty); }