예제 #1
0
/*
 * Compatibility mode handshaking is a matter of writing data,
 * strobing it, and waiting for the printer to stop being busy.
 */
static long write_compat(unsigned minor, const char *c, unsigned long cnt)
{
      long rc;
      unsigned short pins = get_pins(minor);

      unsigned long remaining = cnt;


      while (remaining > 0) {
            unsigned char byte;

            get_user_ret(byte, c, -EFAULT);
            c += 1;

            rc = wait_for(BPP_GP_nAck, BPP_GP_Busy, TIME_IDLE_LIMIT, minor);
            if (rc == -1) return -ETIMEDOUT;

            bpp_outb_p(byte, base_addrs[minor]);
            remaining -= 1;
          /* snooze(1, minor); */

          pins &= ~BPP_PP_nStrobe;
          set_pins(pins, minor);

          rc = wait_for(BPP_GP_Busy, 0, TIME_PResponse, minor);

          pins |= BPP_PP_nStrobe;
          set_pins(pins, minor);
      }

      return cnt - remaining;
}
예제 #2
0
int
sun_mouse_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
	int i;
	
	switch (cmd){
		/* VUIDGFORMAT - Get input device byte stream format */
	case _IOR('v', 2, int):
		put_user_ret(sunmouse.vuid_mode, (int *) arg, -EFAULT);
		break;

		/* VUIDSFORMAT - Set input device byte stream format*/
	case _IOW('v', 1, int):
		get_user_ret(i, (int *) arg, -EFAULT);
		if (i == VUID_NATIVE || i == VUID_FIRM_EVENT){
			int value;

			get_user_ret(value, (int *)arg, -EFAULT);
			sunmouse.vuid_mode = value;
			sunmouse.head = sunmouse.tail = 0;
		} else
			return -EINVAL;
		break;

	case 0x8024540b:
	case 0x40245408:
		/* This is a buggy application doing termios on the mouse driver */
		/* we ignore it.  I keep this check here so that we will notice   */
		/* future mouse vuid ioctls */
		return -ENOTTY;

		
	default:
#ifdef DEBUG
		printk ("[MOUSE-ioctl: %8.8x]\n", cmd);
#endif
		return -EINVAL;
	}
	return 0;
}
예제 #3
0
/*
 * Write data using ECP mode. Watch out that the port may be set up
 * for reading. If so, turn the port around.
 */
static long write_ecp(unsigned minor, const char *c, unsigned long cnt)
{
      unsigned short pins = get_pins(minor);
      unsigned long remaining = cnt;

      if (instances[minor].direction) {
          int rc;

            /* Event 47 Request bus be turned around */
          pins |= BPP_PP_nInit;
          set_pins(pins, minor);

            /* Wait for Event 49: Peripheral relinquished bus */
          rc = wait_for(BPP_GP_PError, 0, TIME_PResponse, minor);

          pins |= BPP_PP_nAutoFd;
          instances[minor].direction = 0;
          set_pins(pins, minor);
      }

      while (remaining > 0) {
          unsigned char byte;
          int rc;

          get_user_ret(byte, c, -EFAULT);

          rc = wait_for(0, BPP_GP_Busy, TIME_PResponse, minor);
          if (rc == -1) return -ETIMEDOUT;

          c += 1;

          bpp_outb_p(byte, base_addrs[minor]);

          pins &= ~BPP_PP_nStrobe;
          set_pins(pins, minor);

          pins |= BPP_PP_nStrobe;
          rc = wait_for(BPP_GP_Busy, 0, TIME_PResponse, minor);
          if (rc == -1) return -EIO;

          set_pins(pins, minor);
      }

      return cnt - remaining;
}
예제 #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;
}