示例#1
0
/*
 * This routine is the bottom half of the keyboard interrupt
 * routine, and runs with all interrupts enabled. It does
 * console changing, led setting and copy_to_cooked, which can
 * take a reasonably long time.
 *
 * Aside from timing (which isn't really that important for
 * keyboard interrupts as they happen often), using the software
 * interrupt routines for this thing allows us to easily mask
 * this when we don't want any of the above to happen. Not yet
 * used, but this allows for easy and efficient race-condition
 * prevention later on.
 */
static void kbd_bh(void)
{
	unsigned char leds = getleds();
	unsigned char kbd_leds = vcleds_to_sunkbd(leds);

	if (kbd_leds != sunkbd_ledstate) {
		ledstate = leds;
		sunkbd_ledstate = kbd_leds;
		send_cmd(SKBDCMD_SETLED);
		send_cmd(kbd_leds);
	}
}
示例#2
0
文件: akbd.c 项目: sofuture/bitrig
/*
 * Toggle all of the LED's on and off, just for show.
 */
void
blinkleds(struct akbd_softc *sc)
{
	u_char origleds;

	origleds = getleds(sc->adbaddr);
	setleds(sc, LED_NUMLOCK | LED_CAPSLOCK | LED_SCROLL_LOCK);
	delay(400000);
	setleds(sc, origleds);

	if (origleds & LED_NUMLOCK)
		sc->sc_leds |= WSKBD_LED_NUM;
	if (origleds & LED_CAPSLOCK)
		sc->sc_leds |= WSKBD_LED_CAPS;
	if (origleds & LED_SCROLL_LOCK)
		sc->sc_leds |= WSKBD_LED_SCROLL;
}
示例#3
0
/*
 * This routine is the bottom half of the keyboard interrupt
 * routine, and runs with all interrupts enabled. It does
 * console changing, led setting and copy_to_cooked, which can
 * take a reasonably long time.
 *
 * Aside from timing (which isn't really that important for
 * keyboard interrupts as they happen often), using the software
 * interrupt routines for this thing allows us to easily mask
 * this when we don't want any of the above to happen. Not yet
 * used, but this allows for easy and efficient race-condition
 * prevention later on.
 */
static unsigned char sunkbd_ledstate = 0xff; /* undefined */
void sun_kbd_bh(unsigned long dummy)
{
	unsigned long flags;
	unsigned char leds, kbd_leds;

	spin_lock_irqsave(&sunkbd_lock, flags);

	leds = getleds();
	kbd_leds = vcleds_to_sunkbd(leds);
	if (kbd_leds != sunkbd_ledstate) {
		ledstate = leds;
		sunkbd_ledstate = kbd_leds;
		send_cmd(SKBDCMD_SETLED);
		send_cmd(kbd_leds);
	}

	spin_unlock_irqrestore(&sunkbd_lock, flags);
}
示例#4
0
static int
kbd_ioctl (struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
{
	unsigned char c;
	unsigned char leds = 0;
	int value;

	switch (cmd){
	case KIOCTYPE:		  /* return keyboard type */
		put_user_ret(sunkbd_type, (int *) arg, -EFAULT);
		break;
	case KIOCGTRANS:
		put_user_ret(TR_UNTRANS_EVENT, (int *) arg, -EFAULT);
		break;
	case KIOCTRANS:
		get_user_ret(value, (int *) arg, -EFAULT);
		if (value != TR_UNTRANS_EVENT)
			return -EINVAL;
		break;
	case KIOCLAYOUT:
		put_user_ret(sunkbd_layout, (int *) arg, -EFAULT);
		break;
	case KIOCSDIRECT:
#ifndef CODING_NEW_DRIVER
		get_user_ret(value, (int *) arg, -EFAULT);
		if(value)
			kbd_redirected = fg_console + 1;
		else
			kbd_redirected = 0;
		kbd_table [fg_console].kbdmode = kbd_redirected ? VC_RAW : VC_XLATE;
#endif
		break;
	case KIOCCMD:
		get_user_ret(value, (int *) arg, -EFAULT);
		c = (unsigned char) value;
		switch (c) {
			case SKBDCMD_CLICK:
			case SKBDCMD_NOCLICK:
				send_cmd(c);
				return 0;
			case SKBDCMD_BELLON:
				kd_mksound(1,0);
				return 0;
			case SKBDCMD_BELLOFF:
				kd_mksound(0,0);
				return 0;
			default:
				return -EINVAL;
		}
	case KIOCSLED:
		get_user_ret(c, (unsigned char *) arg, -EFAULT);
			
		if (c & LED_SCRLCK) leds |= (1 << VC_SCROLLOCK);
		if (c & LED_NLOCK) leds |= (1 << VC_NUMLOCK);
		if (c & LED_CLOCK) leds |= (1 << VC_CAPSLOCK);
		compose_led_on = !!(c & LED_CMPOSE);
		sun_setledstate(kbd_table + fg_console, leds);
		break;
	case KIOCGLED:
		put_user_ret(vcleds_to_sunkbd(getleds()), (unsigned char *) arg, -EFAULT);
		break;
	case KIOCGRATE:
	{
		struct kbd_rate rate;

		rate.delay = kbd_delay_ticks;
		if (kbd_rate_ticks)
			rate.rate = HZ / kbd_rate_ticks;
		else
			rate.rate = 0;

		copy_to_user_ret((struct kbd_rate *)arg, &rate,
				 sizeof(struct kbd_rate), -EFAULT);

		return 0;
	}
	case KIOCSRATE:
	{
		struct kbd_rate rate;

		if (verify_area(VERIFY_READ, (void *)arg,
				sizeof(struct kbd_rate)))
			return -EFAULT;
		copy_from_user(&rate, (struct kbd_rate *)arg,
			       sizeof(struct kbd_rate));

		if (rate.rate > 50)
			return -EINVAL;
		if (rate.rate == 0)
			kbd_rate_ticks = 0;
		else
			kbd_rate_ticks = HZ / rate.rate;
		kbd_delay_ticks = rate.delay;

		return 0;
	}
	case FIONREAD:		/* return number of bytes in kbd queue */
	{
		int count;
		
		count = kbd_head - kbd_tail;
		put_user_ret((count < 0) ? KBD_QSIZE - count : count, (int *) arg, -EFAULT);
		return 0;
	}
	default:
		printk ("Unknown Keyboard ioctl: %8.8x\n", cmd);
		return -EINVAL;
	}
	return 0;
}