示例#1
0
asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count)
{
	char *p, *q, *r;
	char buffer[256];
	int len;
	
	/* Again, we cheat :)) */
	switch (cmd) {
	case SI_SYSNAME: r = "SunOS"; break;
	case SI_HOSTNAME:
		r = buffer + 256;
		for (p = system_utsname.nodename, q = buffer; 
		     q < r && *p && *p != '.'; *q++ = *p++);
		*q = 0;
		r = buffer;
		break;
	case SI_RELEASE: r = "5.6"; break;
	case SI_MACHINE: r = machine(); break;
	case SI_ARCHITECTURE: r = "sparc"; break;
	case SI_HW_PROVIDER: r = "Sun_Microsystems"; break;
	case SI_HW_SERIAL: r = serial(buffer); break;
	case SI_PLATFORM: r = platform(buffer); break;
	case SI_SRPC_DOMAIN: r = ""; break;
	case SI_VERSION: r = "Generic"; break;
	default: return -EINVAL;
	}
	len = strlen(r) + 1;
	if (count < len) {
		copy_to_user_ret((char *)A(buf), r, count - 1, -EFAULT);
		__put_user_ret(0, (char *)A(buf) + count - 1, -EFAULT);
	} else
		copy_to_user_ret((char *)A(buf), r, len, -EFAULT);
	return len;
}
示例#2
0
static ssize_t
kbd_read (struct file *f, char *buffer, size_t count, loff_t *ppos)
{
	struct wait_queue wait = { current, NULL };
	char *end, *p;

	/* Return EWOULDBLOCK, because this is what the X server expects */
	if (kbd_head == kbd_tail){
		if (f->f_flags & O_NONBLOCK)
			return -EWOULDBLOCK;
		add_wait_queue (&kbd_wait, &wait);
		while (kbd_head == kbd_tail && !signal_pending(current)) {
			current->state = TASK_INTERRUPTIBLE;
			schedule ();
		}
		current->state = TASK_RUNNING;
		remove_wait_queue (&kbd_wait, &wait);
	}
	/* There is data in the keyboard, fill the user buffer */
	end = buffer+count;
	p = buffer;
	for (; p < end && kbd_head != kbd_tail;){
#ifdef CONFIG_SPARC32_COMPAT
		if (current->tss.flags & SPARC_FLAG_32BIT) {
			copy_to_user_ret((Firm_event *)p, &kbd_queue [kbd_tail], 
					 sizeof(Firm_event)-sizeof(struct timeval), -EFAULT);
			p += sizeof(Firm_event)-sizeof(struct timeval);
			__put_user_ret(kbd_queue[kbd_tail].time.tv_sec, (u32 *)p, -EFAULT);
			p += sizeof(u32);
			__put_user_ret(kbd_queue[kbd_tail].time.tv_usec, (u32 *)p, -EFAULT);
			p += sizeof(u32);
		} else
#endif
		{
			copy_to_user_ret((Firm_event *)p, &kbd_queue [kbd_tail], 
					 sizeof(Firm_event), -EFAULT);
			p += sizeof (Firm_event);
		}
#ifdef KBD_DEBUG
		printk ("[%s]", kbd_queue [kbd_tail].value == VKEY_UP ? "UP" : "DOWN");
#endif
		kbd_tail++;
		kbd_tail %= KBD_QSIZE;
	}
	return p-buffer;
}
示例#3
0
ci_noinline int
ioctl_resource_alloc (ci_private_char_t *priv, ulong arg)
{
  int rc;
  ci_resource_alloc_t local;
  copy_from_user_ret(&local, (caddr_t) arg, sizeof(local), -EFAULT);
  rc = efch_resource_alloc(&priv->rt, &local);
  if( rc < 0 )  return rc;
  copy_to_user_ret((caddr_t) arg, &local, sizeof(local), -EFAULT);
  return rc;
}
示例#4
0
ci_noinline int
ioctl_resource_op (ci_private_char_t *priv, ulong arg)
{
  ci_resource_op_t local;
  int rc, copy_out = 0;
  copy_from_user_ret(&local, (caddr_t) arg, sizeof(local), -EFAULT);
  rc = efch_resource_op(&priv->rt, &local, &copy_out);
  if( copy_out )
    copy_to_user_ret((caddr_t) arg, &local, sizeof(local), -EFAULT);

  return rc;
}
示例#5
0
ci_noinline int
ioctl_license_challenge (ci_private_char_t *priv, ulong arg)
{
  struct ci_license_challenge_op_s local;
  int rc, copy_out = 0;
  copy_from_user_ret(&local, (caddr_t) arg, sizeof(local), -EFAULT);
  rc = efch_license_challenge(&priv->rt, &local, &copy_out);
  if( copy_out )
    copy_to_user_ret((caddr_t) arg, &local, sizeof(local), -EFAULT);

  return rc;
}
示例#6
0
static ssize_t state_read(struct file *filp, char *dest, size_t count,
			  loff_t *ppos)
{
	struct state_dev *dev = filp->private_data;

	if (count > STATE_BLOCK_SIZE || count <= 0)
		count = STATE_BLOCK_SIZE;

	if (hijack_force_pause_player) {
		hijack_force_pause_player = 0;
		dev->read_buffer[0x0c] &= ~0x02;
	}

	copy_to_user_ret(dest, dev->read_buffer, count, -EFAULT);

	return count;
}
示例#7
0
static long read_ecp(unsigned minor, char *c, unsigned long cnt)
{
      unsigned long remaining;
      long rc;

        /* Turn ECP mode from forward to reverse if needed. */
      if (! instances[minor].direction) {
          unsigned short pins = get_pins(minor);

            /* Event 38: Turn the bus around */
          instances[minor].direction = 0x20;
          pins &= ~BPP_PP_nAutoFd;
          set_pins(pins, minor);

            /* Event 39: Set pins for reverse mode. */
          snooze(TIME_PSetup, minor);
          set_pins(BPP_PP_nStrobe|BPP_PP_nSelectIn, minor);

            /* Wait for event 40: Peripheral ready to be strobed */
          rc = wait_for(0, BPP_GP_PError, TIME_PResponse, minor);
          if (rc == -1) return -ETIMEDOUT;
      }

      remaining = cnt;

      while (remaining > 0) {

            /* If there is a run length for a repeated byte, repeat */
            /* that byte a few times. */
          if (instances[minor].run_length && !instances[minor].run_flag) {

              char buffer[128];
              unsigned idx;
              unsigned repeat = remaining < instances[minor].run_length
                                     ? remaining
                               : instances[minor].run_length;

              for (idx = 0 ;  idx < repeat ;  idx += 1)
                buffer[idx] = instances[minor].repeat_byte;

              copy_to_user_ret(c, buffer, repeat, -EFAULT);
              remaining -= repeat;
              c += repeat;
              instances[minor].run_length -= repeat;
          }

          if (remaining == 0) break;


            /* Wait for Event 43: Data active on the bus. */
          rc = wait_for(0, BPP_GP_nAck, TIME_IDLE_LIMIT, minor);
          if (rc == -1) break;

          if (rc & BPP_GP_Busy) {
                /* OK, this is data. read it in. */
              unsigned char byte = bpp_inb(base_addrs[minor]);
              put_user_ret(byte, c, -EFAULT);
              c += 1;
              remaining -= 1;

              if (instances[minor].run_flag) {
                  instances[minor].repeat_byte = byte;
                  instances[minor].run_flag = 0;
              }

          } else {
              unsigned char byte = bpp_inb(base_addrs[minor]);
              if (byte & 0x80) {
                  printk("bpp%d: "
                         "Ignoring ECP channel %u from device.\n",
                         minor, byte & 0x7f);
              } else {
                  instances[minor].run_length = byte;
                  instances[minor].run_flag = 1;
              }
          }

            /* Event 44: I got it. */
          set_pins(BPP_PP_nStrobe|BPP_PP_nAutoFd|BPP_PP_nSelectIn, minor);

            /* Wait for event 45: peripheral handshake */
          rc = wait_for(BPP_GP_nAck, 0, TIME_PResponse, minor);
          if (rc == -1) return -ETIMEDOUT;

             /* Event 46: Finish handshake */
          set_pins(BPP_PP_nStrobe|BPP_PP_nSelectIn, minor);

      }


      return cnt - remaining;
}
示例#8
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;
}
示例#9
0
static ssize_t
sun_mouse_read(struct file *file, char *buffer,
	       size_t count, loff_t *ppos)
{
	struct wait_queue wait = { current, NULL };

	if (queue_empty ()){
		if (file->f_flags & O_NONBLOCK)
			return -EWOULDBLOCK;
		add_wait_queue (&sunmouse.proc_list, &wait);
		while (queue_empty () && !signal_pending(current)) {
			current->state = TASK_INTERRUPTIBLE;
			schedule ();
		}
		current->state = TASK_RUNNING;
		remove_wait_queue (&sunmouse.proc_list, &wait);
	}
	if (gen_events){
		char *p = buffer, *end = buffer+count;
		
		while (p < end && !queue_empty ()){
#ifdef CONFIG_SPARC32_COMPAT
			if (current->tss.flags & SPARC_FLAG_32BIT) {
				Firm_event *q = get_from_queue();
				
				if ((end - p) <
				    ((sizeof(Firm_event) - sizeof(struct timeval) +
				      (sizeof(u32) * 2))))
					break;
				copy_to_user_ret((Firm_event *)p, q, 
						 sizeof(Firm_event)-sizeof(struct timeval),
						 -EFAULT);
				p += sizeof(Firm_event)-sizeof(struct timeval);
				__put_user_ret(q->time.tv_sec, (u32 *)p, -EFAULT);
				p += sizeof(u32);
				__put_user_ret(q->time.tv_usec, (u32 *)p, -EFAULT);
				p += sizeof(u32);
			} else
#endif	
			{	
				if ((end - p) < sizeof(Firm_event))
					break;
				copy_to_user_ret((Firm_event *)p, get_from_queue(),
				     		 sizeof(Firm_event), -EFAULT);
				p += sizeof (Firm_event);
			}
		}
		sunmouse.ready = !queue_empty ();
		file->f_dentry->d_inode->i_atime = CURRENT_TIME;
		return p-buffer;
	} else {
		int c, limit = 3;

		if (count < limit)
			limit = count;
		for (c = 0; c < limit; c++) {
			put_user(sunmouse.queue.stream[sunmouse.tail], buffer);
			buffer++;
			sunmouse.tail = (sunmouse.tail + 1) % STREAM_SIZE;
		}
		while (c < count) {
			if (c >= 5)
				break;
			put_user(0, buffer);
			buffer++;
			c++;
		}
		sunmouse.ready = !queue_empty();
		file->f_dentry->d_inode->i_atime = CURRENT_TIME;
		return c;
	}
	/* Only called if nothing was sent */
	if (signal_pending(current))
		return -ERESTARTSYS;
	return 0;
}