Ejemplo n.º 1
0
/* n_hdlc_tty_ioctl()
 *
 *	Process IOCTL system call for the tty device.
 *
 * Arguments:
 *
 *	tty		pointer to tty instance data
 *	file		pointer to open file object for device
 *	cmd		IOCTL command code
 *	arg		argument for IOCTL call (cmd dependent)
 *
 * Return Value:	Command dependent
 */
static int n_hdlc_tty_ioctl (struct tty_struct *tty, struct file * file,
               unsigned int cmd, unsigned long arg)
{
	struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
	int error = 0;
	int count;
	unsigned long flags;
	
	if (debuglevel >= DEBUG_LEVEL_INFO)	
		printk("%s(%d)n_hdlc_tty_ioctl() called %d\n",
			__FILE__,__LINE__,cmd);
		
	/* Verify the status of the device */
	if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC)
		return -EBADF;

	switch (cmd) {
	case FIONREAD:
		/* report count of read data available */
		/* in next available frame (if any) */
		spin_lock_irqsave(&n_hdlc->rx_buf_list.spinlock,flags);
		if (n_hdlc->rx_buf_list.head)
			count = n_hdlc->rx_buf_list.head->count;
		else
			count = 0;
		spin_unlock_irqrestore(&n_hdlc->rx_buf_list.spinlock,flags);
		PUT_USER (error, count, (int *) arg);
		break;

	case TIOCOUTQ:
		/* get the pending tx byte count in the driver */
		count = tty->driver.chars_in_buffer ?
				tty->driver.chars_in_buffer(tty) : 0;
		/* add size of next output frame in queue */
		spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags);
		if (n_hdlc->tx_buf_list.head)
			count += n_hdlc->tx_buf_list.head->count;
		spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock,flags);
		PUT_USER (error, count, (int*)arg);
		break;

	default:
		error = n_tty_ioctl (tty, file, cmd, arg);
		break;
	}
	return error;
	
}	/* end of n_hdlc_tty_ioctl() */
Ejemplo n.º 2
0
int m5249audio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
	long	val;
	int	rc = 0;

#ifdef DEBUG
        printk("m5249audio_ioctl(cmd=%x,arg=%x)\n", (int) cmd, (int) arg);
#endif

	switch (cmd) {

	case SNDCTL_DSP_SPEED:
		rc = verify_area(VERIFY_READ, (void *) arg, sizeof(val));
		if (rc == 0) {
			GET_USER(val, (unsigned long *) arg);
			m5249audio_txdrain();
			m5249audio_speed = val;
			/* FIXME: adjust replay speed?? */
		}
		break;

	case SNDCTL_DSP_SAMPLESIZE:
		rc = verify_area(VERIFY_READ, (void *) arg, sizeof(val));
		if (rc == 0) {
			GET_USER(val, (unsigned long *) arg);
			m5249audio_txdrain();
			m5249audio_setsamplesize(val);
		}
		break;

	case SNDCTL_DSP_CHANNELS:
		rc = verify_area(VERIFY_READ, (void *) arg, sizeof(val));
		if (rc == 0) {
			GET_USER(val, (unsigned long *) arg);
			m5249audio_txdrain();
			m5249audio_stereo = ((val == 1) ? 0 : 1);
		}
		break;

	case SNDCTL_DSP_STEREO:
		rc = verify_area(VERIFY_READ, (void *) arg, sizeof(val));
		if (rc == 0) {
			GET_USER(val, (unsigned long *) arg);
			m5249audio_txdrain();
			m5249audio_stereo = val;
		}
		break;

	case SNDCTL_DSP_GETBLKSIZE:
		rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long));
		if (rc == 0)
			PUT_USER(DMASIZE, (long *) arg);
		break;

	case SNDCTL_DSP_SYNC:
		m5249audio_txdrain();
		break;

	default:
		rc = -EINVAL;
		break;
	}

	return(rc);
}