/* * Alarm timer expired: * Send an alarm exception to the target task. */ static void alarm_expire(void *arg) { task_t task = (task_t)arg; exception_post(task, SIGALRM); }
/* * PM event notification. */ void pm_notify(int event) { struct pm_softc *sc = pm_softc; int s; if (event == PME_USER_ACTIVITY) { /* * Reload suspend timer for user activity. */ s = splhigh(); sc->idlecnt = 0; splx(s); if (!sc->lcd_on) pm_lcd_on(); return; } DPRINTF(("pm: notify %d\n", event)); if (sc->powtask != TASK_NULL) { /* * Power server exists. */ switch (event) { case PME_PWRBTN_PRESS: case PME_SLPBTN_PRESS: case PME_LOW_BATTERY: case PME_LCD_CLOSE: /* * Post an exception to the power server. * Then, the power server will query PM event. */ sc->lastevt = event; DPRINTF(("pm: post %d\n", event)); exception_post(sc->powtask, SIGPWR); break; case PME_LCD_OPEN: sc->lastevt = PME_NO_EVENT; pm_lcd_on(); break; } } else { /* * No power server. * Map power event to default action. */ switch (event) { case PME_PWRBTN_PRESS: pm_poweroff(); break; case PME_SLPBTN_PRESS: case PME_LOW_BATTERY: pm_suspend(); break; case PME_LCD_OPEN: pm_lcd_on(); break; case PME_LCD_CLOSE: pm_lcd_off(); break; } } }
/* * Process input of a single character received on a tty. * echo if required. * This may be called with interrupt level. */ void tty_input(int c, struct tty *tp) { unsigned char *cc; tcflag_t iflag, lflag; int sig = -1; #ifdef CONFIG_CPUFREQ /* Reload power management timer */ pm_active(); #endif lflag = tp->t_lflag; iflag = tp->t_iflag; cc = tp->t_cc; /* IGNCR, ICRNL, INLCR */ if (c == '\r') { if (iflag & IGNCR) goto endcase; else if (iflag & ICRNL) c = '\n'; } else if (c == '\n' && (iflag & INLCR)) c = '\r'; if (iflag & IXON) { /* stop (^S) */ if (c == cc[VSTOP]) { if (!(tp->t_state & TS_TTSTOP)) { tp->t_state |= TS_TTSTOP; return; } if (c != cc[VSTART]) return; /* if VSTART == VSTOP then toggle */ goto endcase; } /* start (^Q) */ if (c == cc[VSTART]) goto restartoutput; } if (lflag & ICANON) { /* erase (^H / ^?) or backspace */ if (c == cc[VERASE] || c == '\b') { if (!ttyq_empty(&tp->t_rawq)) { ttyq_unputc(&tp->t_rawq); tty_rubout(tp); } goto endcase; } /* kill (^U) */ if (c == cc[VKILL]) { while (!ttyq_empty(&tp->t_rawq)) { ttyq_unputc(&tp->t_rawq); tty_rubout(tp); } goto endcase; } } if (lflag & ISIG) { /* quit (^C) */ if (c == cc[VINTR] || c == cc[VQUIT]) { if (!(lflag & NOFLSH)) tty_flush(tp, FREAD | FWRITE); tty_echo(c, tp); sig = (c == cc[VINTR]) ? SIGINT : SIGQUIT; goto endcase; } /* suspend (^Z) */ if (c == cc[VSUSP]) { if (!(lflag & NOFLSH)) tty_flush(tp, FREAD | FWRITE); tty_echo(c, tp); sig = SIGTSTP; goto endcase; } } /* * Check for input buffer overflow */ if (ttyq_full(&tp->t_rawq)) { tty_flush(tp, FREAD | FWRITE); goto endcase; } ttyq_putc(c, &tp->t_rawq); if (lflag & ICANON) { if (c == '\n' || c == cc[VEOF] || c == cc[VEOL]) { tty_catq(&tp->t_rawq, &tp->t_canq); sched_wakeup(&tp->t_input); } } else sched_wakeup(&tp->t_input); if (lflag & ECHO) tty_echo(c, tp); endcase: /* * IXANY means allow any character to restart output. */ if ((tp->t_state & TS_TTSTOP) && (iflag & IXANY) == 0 && cc[VSTART] != cc[VSTOP]) return; restartoutput: tp->t_state &= ~TS_TTSTOP; if (sig != -1) { if (sig_task) exception_post(sig_task, sig); } tty_start(tp); }