亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? psaux.c

?? LINUX1.0源代碼,代碼條理清晰
?? C
字號:
/*
 * linux/kernel/chr_drv/psaux.c
 *
 * Driver for PS/2 type mouse by Johan Myreen.
 *
 * Supports pointing devices attached to a PS/2 type
 * Keyboard and Auxiliary Device Controller.
 *
 * Corrections in device setup for some laptop mice & trackballs.
 * 02Feb93  (troyer@saifr00.cfsat.Honeywell.COM,mch@wimsey.bc.ca)
 *
 * Changed to prevent keyboard lockups on AST Power Exec.
 * 28Jul93  Brad Bosch - brad@lachman.com
 *
 * Modified by Johan Myreen (jem@cs.hut.fi) 04Aug93
 *   to include support for QuickPort mouse.
 *
 * Changed references to "QuickPort" with "82C710" since "QuickPort"
 * is not what this driver is all about -- QuickPort is just a
 * connector type, and this driver is for the mouse port on the Chips
 * & Technologies 82C710 interface chip. 15Nov93 jem@cs.hut.fi
 */

/* Uncomment the following line if your mouse needs initialization. */

/* #define INITIALIZE_DEVICE */

#include <linux/timer.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/fcntl.h>
#include <linux/errno.h>

#include <asm/io.h>
#include <asm/segment.h>
#include <asm/system.h>

#include <linux/config.h>

/* aux controller ports */
#define AUX_INPUT_PORT	0x60		/* Aux device output buffer */
#define AUX_OUTPUT_PORT	0x60		/* Aux device input buffer */
#define AUX_COMMAND	0x64		/* Aux device command buffer */
#define AUX_STATUS	0x64		/* Aux device status reg */

/* aux controller status bits */
#define AUX_OBUF_FULL	0x21		/* output buffer (from device) full */
#define AUX_IBUF_FULL	0x02		/* input buffer (to device) full */

/* aux controller commands */
#define AUX_CMD_WRITE	0x60		/* value to write to controller */
#define AUX_MAGIC_WRITE	0xd4		/* value to send aux device data */

#define AUX_INTS_ON	0x47		/* enable controller interrupts */
#define AUX_INTS_OFF	0x65		/* disable controller interrupts */

#define AUX_DISABLE	0xa7		/* disable aux */
#define AUX_ENABLE	0xa8		/* enable aux */

/* aux device commands */
#define AUX_SET_RES	0xe8		/* set resolution */
#define AUX_SET_SCALE11	0xe6		/* set 1:1 scaling */
#define AUX_SET_SCALE21	0xe7		/* set 2:1 scaling */
#define AUX_GET_SCALE	0xe9		/* get scaling factor */
#define AUX_SET_STREAM	0xea		/* set stream mode */
#define AUX_SET_SAMPLE	0xf3		/* set sample rate */
#define AUX_ENABLE_DEV	0xf4		/* enable aux device */
#define AUX_DISABLE_DEV	0xf5		/* disable aux device */
#define AUX_RESET	0xff		/* reset aux device */

#define MAX_RETRIES	60		/* some aux operations take long time*/
#define AUX_IRQ		12
#define AUX_BUF_SIZE	2048

/* 82C710 definitions */

#define QP_DATA         0x310		/* Data Port I/O Address */
#define QP_STATUS       0x311		/* Status Port I/O Address */

#define QP_DEV_IDLE     0x01	        /* Device Idle */
#define QP_RX_FULL      0x02		/* Device Char received */
#define QP_TX_IDLE      0x04		/* Device XMIT Idle */
#define QP_RESET        0x08		/* Device Reset */
#define QP_INTS_ON      0x10		/* Device Interrupt On */
#define QP_ERROR_FLAG   0x20		/* Device Error */
#define QP_CLEAR        0x40		/* Device Clear */
#define QP_ENABLE       0x80		/* Device Enable */

#define QP_IRQ          12

extern unsigned char aux_device_present;
extern unsigned char kbd_read_mask;	/* from keyboard.c */

struct aux_queue {
	unsigned long head;
	unsigned long tail;
	struct wait_queue *proc_list;
	unsigned char buf[AUX_BUF_SIZE];
};

static struct aux_queue *queue;
static int aux_ready = 0;
static int aux_busy = 0;
static int aux_present = 0;
static int poll_aux_status(void);

#ifdef CONFIG_82C710_MOUSE
static int qp_present = 0;
static int qp_busy = 0;
static int qp_data = QP_DATA;
static int qp_status = QP_STATUS;

static int poll_qp_status(void);
static int probe_qp(void);
#endif


/*
 * Write to aux device
 */

static void aux_write_dev(int val)
{
	poll_aux_status();
	outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);	/* write magic cookie */
	poll_aux_status();
	outb_p(val,AUX_OUTPUT_PORT);		/* write data */
}

/*
 * Write to device & handle returned ack
 */
 
#if defined INITIALIZE_DEVICE
static int aux_write_ack(int val)
{
        int retries = 0;

	aux_write_dev(val);		/* write the value to the device */
	while ((inb(AUX_STATUS) & AUX_OBUF_FULL) != AUX_OBUF_FULL
	            && retries < MAX_RETRIES) {          /* wait for ack */
       		current->state = TASK_INTERRUPTIBLE;
		current->timeout = jiffies + 5;
		schedule();
		retries++;
        }

	if ((inb(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
	{
		return (inb(AUX_INPUT_PORT));
	}
	return 0;
}
#endif /* INITIALIZE_DEVICE */

/*
 * Write aux device command
 */

static void aux_write_cmd(int val)
{
	poll_aux_status();
	outb_p(AUX_CMD_WRITE,AUX_COMMAND);
	poll_aux_status();
	outb_p(val,AUX_OUTPUT_PORT);
}


static unsigned int get_from_queue(void)
{
	unsigned int result;
	unsigned long flags;

	save_flags(flags);
	cli();
	result = queue->buf[queue->tail];
	queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
	restore_flags(flags);
	return result;
}


static inline int queue_empty(void)
{
	return queue->head == queue->tail;
}



/*
 * Interrupt from the auxiliary device: a character
 * is waiting in the keyboard/aux controller.
 */

static void aux_interrupt(int cpl)
{
	int head = queue->head;
	int maxhead = (queue->tail-1) & (AUX_BUF_SIZE-1);

	queue->buf[head] = inb(AUX_INPUT_PORT);
	if (head != maxhead) {
		head++;
		head &= AUX_BUF_SIZE-1;
	}
	queue->head = head;
	aux_ready = 1;
	wake_up_interruptible(&queue->proc_list);
}

/*
 * Interrupt handler for the 82C710 mouse port. A character
 * is waiting in the 82C710.
 */

#ifdef CONFIG_82C710_MOUSE
static void qp_interrupt(int cpl)
{
	int head = queue->head;
	int maxhead = (queue->tail-1) & (AUX_BUF_SIZE-1);

	queue->buf[head] = inb(qp_data);
	if (head != maxhead) {
		head++;
		head &= AUX_BUF_SIZE-1;
	}
	queue->head = head;
	aux_ready = 1;
	wake_up_interruptible(&queue->proc_list);
}
#endif


static void release_aux(struct inode * inode, struct file * file)
{
	aux_write_dev(AUX_DISABLE_DEV);		/* disable aux device */
	aux_write_cmd(AUX_INTS_OFF);		/* disable controller ints */
	poll_aux_status();
	outb_p(AUX_DISABLE,AUX_COMMAND);      	/* Disable Aux device */
	poll_aux_status();
	free_irq(AUX_IRQ);
	aux_busy = 0;
}

#ifdef CONFIG_82C710_MOUSE
static void release_qp(struct inode * inode, struct file * file)
{
	unsigned char status;

	if (!poll_qp_status())
	        printk("Warning: Mouse device busy in release_qp()\n");
	status = inb_p(qp_status);
	outb_p(status & ~(QP_ENABLE|QP_INTS_ON), qp_status);
	if (!poll_qp_status())
	        printk("Warning: Mouse device busy in release_qp()\n");
	free_irq(QP_IRQ);
	qp_busy = 0;
}
#endif

/*
 * Install interrupt handler.
 * Enable auxiliary device.
 */

static int open_aux(struct inode * inode, struct file * file)
{
	if (!aux_present)
		return -EINVAL;
	if (aux_busy)
		return -EBUSY;
	if (!poll_aux_status())
		return -EBUSY;
	aux_busy = 1;
	queue->head = queue->tail = 0;	        /* Flush input queue */
	if (request_irq(AUX_IRQ, aux_interrupt)) {
		aux_busy = 0;
		return -EBUSY;
	}
	poll_aux_status();
	outb_p(AUX_ENABLE,AUX_COMMAND);		/* Enable Aux */
	aux_write_dev(AUX_ENABLE_DEV);		/* enable aux device */
	aux_write_cmd(AUX_INTS_ON);		/* enable controller ints */
	poll_aux_status();
	aux_ready = 0;
	return 0;
}

#ifdef CONFIG_82C710_MOUSE
/*
 * Install interrupt handler.
 * Enable the device, enable interrupts. Set qp_busy
 * (allow only one opener at a time.)
 */

static int open_qp(struct inode * inode, struct file * file)
{
        unsigned char status;

	if (!qp_present)
		return -EINVAL;

	if (qp_busy)
		return -EBUSY;

	if (request_irq(QP_IRQ, qp_interrupt))
		return -EBUSY;

	qp_busy = 1;

	status = inb_p(qp_status);
	status |= (QP_ENABLE|QP_RESET);
	outb_p(status, qp_status);
	status &= ~(QP_RESET);
	outb_p(status, qp_status);

	queue->head = queue->tail = 0;          /* Flush input queue */
	status |= QP_INTS_ON;
	outb_p(status, qp_status);              /* Enable interrupts */

	while (!poll_qp_status()) {
	        printk("Error: Mouse device busy in open_qp()\n");
		return -EBUSY;
        }

	outb_p(AUX_ENABLE_DEV, qp_data);	/* Wake up mouse */

	return 0;
}
#endif

/*
 * Write to the aux device.
 */

static int write_aux(struct inode * inode, struct file * file, char * buffer, int count)
{
	int i = count;

	while (i--) {
		if (!poll_aux_status())
			return -EIO;
		outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);
		if (!poll_aux_status())
			return -EIO;
		outb_p(get_fs_byte(buffer++),AUX_OUTPUT_PORT);
	}
	inode->i_mtime = CURRENT_TIME;
	return count;
}


#ifdef CONFIG_82C710_MOUSE
/*
 * Write to the 82C710 mouse device.
 */

static int write_qp(struct inode * inode, struct file * file, char * buffer, int count)
{
	int i = count;

	while (i--) {
		if (!poll_qp_status())
			return -EIO;
		outb_p(get_fs_byte(buffer++), qp_data);
	}
	inode->i_mtime = CURRENT_TIME;
	return count;
}
#endif


/*
 * Put bytes from input queue to buffer.
 */

static int read_aux(struct inode * inode, struct file * file, char * buffer, int count)
{
	struct wait_queue wait = { current, NULL };
	int i = count;
	unsigned char c;

	if (queue_empty()) {
		if (file->f_flags & O_NONBLOCK)
			return -EAGAIN;
		add_wait_queue(&queue->proc_list, &wait);
repeat:
		current->state = TASK_INTERRUPTIBLE;
		if (queue_empty() && !(current->signal & ~current->blocked)) {
			schedule();
			goto repeat;
		}
		current->state = TASK_RUNNING;
		remove_wait_queue(&queue->proc_list, &wait);			
	}		
	while (i > 0 && !queue_empty()) {
		c = get_from_queue();
		put_fs_byte(c, buffer++);
		i--;
	}
	aux_ready = !queue_empty();
	if (count-i) {
		inode->i_atime = CURRENT_TIME;
		return count-i;
	}
	if (current->signal & ~current->blocked)
		return -ERESTARTSYS;
	return 0;
}


static int aux_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
{
	if (sel_type != SEL_IN)
		return 0;
	if (aux_ready)
		return 1;
	select_wait(&queue->proc_list, wait);
	return 0;
}


struct file_operations psaux_fops = {
	NULL,		/* seek */
	read_aux,
	write_aux,
	NULL, 		/* readdir */
	aux_select,
	NULL, 		/* ioctl */
	NULL,		/* mmap */
	open_aux,
	release_aux,
};


/*
 * Initialize driver. First check for a 82C710 chip; if found
 * forget about the Aux port and use the *_qp functions.
 */

unsigned long psaux_init(unsigned long kmem_start)
{
        int qp_found = 0;

#ifdef CONFIG_82C710_MOUSE
        if ((qp_found = probe_qp())) {
	        printk("82C710 type pointing device detected -- driver installed.\n");
/*		printk("82C710 address = %x (should be 0x310)\n", qp_data); */
		qp_present = 1;
		psaux_fops.write = write_qp;
		psaux_fops.open = open_qp;
		psaux_fops.release = release_qp;
		poll_qp_status();
	} else
#endif
	if (aux_device_present == 0xaa) {
	        printk("PS/2 auxiliary pointing device detected -- driver installed.\n");
         	aux_present = 1;
		kbd_read_mask = AUX_OBUF_FULL;
	        poll_aux_status();
	} else {
		return kmem_start;              /* No mouse at all */
	}
	queue = (struct aux_queue *) kmem_start;
	kmem_start += sizeof (struct aux_queue);
	queue->head = queue->tail = 0;
	queue->proc_list = NULL;
	if (!qp_found) {
#if defined INITIALIZE_DEVICE
                outb_p(AUX_ENABLE,AUX_COMMAND);		/* Enable Aux */
	        aux_write_ack(AUX_SET_SAMPLE);
	        aux_write_ack(100);			/* 100 samples/sec */
	        aux_write_ack(AUX_SET_RES);
	        aux_write_ack(3);			/* 8 counts per mm */
	        aux_write_ack(AUX_SET_SCALE21);		/* 2:1 scaling */
	        poll_aux_status();
#endif /* INITIALIZE_DEVICE */
        	outb_p(AUX_DISABLE,AUX_COMMAND);   /* Disable Aux device */
	        aux_write_cmd(AUX_INTS_OFF);    /* disable controller ints */
		poll_aux_status();
	}
	return kmem_start;
}

static int poll_aux_status(void)
{
	int retries=0;

	while ((inb(AUX_STATUS)&0x03) && retries < MAX_RETRIES) {
 		if (inb_p(AUX_STATUS) & AUX_OBUF_FULL == AUX_OBUF_FULL)
			inb_p(AUX_INPUT_PORT);
		current->state = TASK_INTERRUPTIBLE;
		current->timeout = jiffies + 5;
		schedule();
		retries++;
	}
	return !(retries==MAX_RETRIES);
}

#ifdef CONFIG_82C710_MOUSE
/*
 * Wait for device to send output char and flush any input char.
 */

static int poll_qp_status(void)
{
	int retries=0;

	while ((inb(qp_status)&(QP_RX_FULL|QP_TX_IDLE|QP_DEV_IDLE))
	               != (QP_DEV_IDLE|QP_TX_IDLE)
	               && retries < MAX_RETRIES) {

	        if (inb_p(qp_status)&(QP_RX_FULL))
		        inb_p(qp_data);
		current->state = TASK_INTERRUPTIBLE;
		current->timeout = jiffies + 5;
		schedule();
		retries++;
	}
	return !(retries==MAX_RETRIES);
}

/*
 * Function to read register in 82C710.
 */

static inline unsigned char read_710(unsigned char index)
{
        outb_p(index, 0x390);			/* Write index */
	return inb_p(0x391);			/* Read the data */
}

/*
 * See if we can find a 82C710 device. Read mouse address.
 */

static int probe_qp(void)
{
        outb_p(0x55, 0x2fa);			/* Any value except 9, ff or 36 */
	outb_p(0xaa, 0x3fa);			/* Inverse of 55 */
	outb_p(0x36, 0x3fa);			/* Address the chip */
	outb_p(0xe4, 0x3fa);			/* 390/4; 390 = config address */
	outb_p(0x1b, 0x2fa);			/* Inverse of e4 */
	if (read_710(0x0f) != 0xe4)		/* Config address found? */
	  return 0;				/* No: no 82C710 here */
	qp_data = read_710(0x0d)*4;		/* Get mouse I/O address */
	qp_status = qp_data+1;
	outb_p(0x0f, 0x390);
	outb_p(0x0f, 0x391);			/* Close config mode */
	return 1;
}
#endif

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
在线免费av一区| 亚洲成av人片| 奇米精品一区二区三区在线观看 | 欧美高清在线一区| 亚洲午夜一区二区| 国产伦精一区二区三区| 欧美日韩一本到| 中文字幕亚洲一区二区va在线| 青青草视频一区| 91高清视频在线| 国产精品久久久久久亚洲伦| 老汉av免费一区二区三区 | 欧美一区二区三区免费视频| 亚洲免费大片在线观看| 国产成人av一区二区| 欧美大黄免费观看| 污片在线观看一区二区| 欧美午夜精品理论片a级按摩| 亚洲欧洲国产日韩| www.欧美.com| 中文字幕av一区 二区| 国产乱码一区二区三区| 日韩区在线观看| 免费在线观看日韩欧美| 欧美日本高清视频在线观看| 亚洲视频在线观看一区| 风流少妇一区二区| 久久九九久精品国产免费直播| 久久国产精品99精品国产| 欧美一级片在线看| 日日摸夜夜添夜夜添精品视频| 91福利在线看| 亚洲国产一二三| 91精品国产综合久久久久| 婷婷夜色潮精品综合在线| 欧美人xxxx| 日本视频一区二区| 欧美一区永久视频免费观看| 日韩精品国产精品| 91精品国产综合久久久久久久久久| 香蕉久久一区二区不卡无毒影院 | 97se亚洲国产综合在线| 亚洲人123区| 欧美浪妇xxxx高跟鞋交| 美女网站在线免费欧美精品| 精品久久国产老人久久综合| 国产一本一道久久香蕉| 国产精品免费网站在线观看| 91一区二区在线观看| 亚洲一区二区三区激情| 欧美女孩性生活视频| 久久精品久久99精品久久| 久久久久久久久99精品| 99久久免费视频.com| 亚洲一区二区三区爽爽爽爽爽| 欧美日韩成人综合| 国产精品99久久久久久似苏梦涵| 国产精品女上位| 欧美日韩免费一区二区三区视频| 奇米精品一区二区三区四区| 久久精品视频免费| 色乱码一区二区三区88| 午夜久久久影院| 国产欧美一区二区三区在线看蜜臀 | 国产麻豆成人精品| 亚洲激情在线激情| 日韩欧美国产一区二区在线播放| 国产大陆精品国产| 亚洲成av人在线观看| 久久久久9999亚洲精品| 92国产精品观看| 色琪琪一区二区三区亚洲区| 久久亚洲一区二区三区明星换脸| 国产精品看片你懂得| 在线一区二区三区| 国产福利电影一区二区三区| 亚洲无人区一区| 国产精品国产自产拍在线| 欧美一区二区成人6969| 9人人澡人人爽人人精品| 久久精品国产秦先生| 亚洲一区二区在线播放相泽| 久久久无码精品亚洲日韩按摩| 欧美在线观看18| 不卡高清视频专区| 美日韩黄色大片| 午夜激情综合网| 亚洲乱码国产乱码精品精可以看| 精品va天堂亚洲国产| 91超碰这里只有精品国产| 91老师国产黑色丝袜在线| 国产精品一线二线三线精华| 久久精品理论片| 热久久国产精品| 日本三级韩国三级欧美三级| 亚洲一区二区精品3399| 亚洲免费色视频| 亚洲日本中文字幕区| 欧美国产激情二区三区| 精品88久久久久88久久久| 69堂国产成人免费视频| 欧美天堂亚洲电影院在线播放| voyeur盗摄精品| 99精品欧美一区二区蜜桃免费 | 精品国产免费一区二区三区香蕉| 欧美午夜精品久久久久久超碰 | 成人免费毛片app| 国产福利91精品| 国产麻豆成人传媒免费观看| 国产综合久久久久影院| 久色婷婷小香蕉久久| 精品一区二区久久| 加勒比av一区二区| 国产成人在线影院| 成人国产在线观看| aaa国产一区| 日本道色综合久久| 欧美伦理电影网| 91精品黄色片免费大全| 日韩午夜电影在线观看| 亚洲精品一区二区三区影院| 久久久久久久久一| 国产精品嫩草久久久久| 亚洲激情欧美激情| 性感美女久久精品| 经典三级在线一区| 成人性生交大合| 91久久精品日日躁夜夜躁欧美| 91福利在线免费观看| 9191国产精品| 久久精品夜色噜噜亚洲aⅴ| 中文字幕不卡的av| 亚洲第一av色| 激情五月播播久久久精品| 成人永久aaa| 91黄视频在线| 日韩精品影音先锋| 中文字幕一区在线观看| 天天免费综合色| 国产伦精品一区二区三区视频青涩 | 国产一区二区调教| gogo大胆日本视频一区| 欧美日韩激情一区二区| 久久综合久久综合亚洲| 亚洲精品亚洲人成人网在线播放| 婷婷开心激情综合| 国产高清精品网站| 亚洲色图制服丝袜| 国产精品久久久久久亚洲毛片| 国产专区综合网| 在线视频国产一区| 久久综合九色综合欧美就去吻| 成人欧美一区二区三区视频网页| 最新国产の精品合集bt伙计| 亚洲高清免费视频| 国产老女人精品毛片久久| 欧洲另类一二三四区| wwww国产精品欧美| 亚洲高清免费一级二级三级| 国产成人免费高清| 91麻豆精品国产91久久久使用方法 | 一区二区在线观看视频| 久久69国产一区二区蜜臀| 色婷婷精品大在线视频| 久久久精品一品道一区| 日韩电影在线观看电影| 国产精品女人毛片| 欧美日韩国产美| 国产精品一区二区男女羞羞无遮挡| 色综合色综合色综合| 久久久久久免费毛片精品| 亚洲图片一区二区| 91麻豆国产在线观看| 久久精品免视看| 蜜桃免费网站一区二区三区| 色噜噜狠狠成人中文综合| 国产精品视频一区二区三区不卡| 亚洲成av人片观看| 91黄色激情网站| 国产精品国产三级国产有无不卡| 麻豆国产91在线播放| 欧美精品黑人性xxxx| 樱花影视一区二区| 91同城在线观看| 中文字幕在线不卡国产视频| 国产剧情av麻豆香蕉精品| 日韩一区二区三| 石原莉奈在线亚洲二区| 欧美系列一区二区| 亚洲精品成a人| 色诱视频网站一区| 亚洲人妖av一区二区| 成人一区在线观看| 中文字幕欧美日本乱码一线二线| 国产乱码字幕精品高清av| 久久久久国产精品人| 久久99精品久久久久久国产越南| 日韩视频国产视频| 久久97超碰色| 欧美韩国一区二区|