⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hil.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	case HILRN:	case HILRS:	case HILED:	case HILP1:	case HILP2:	case HILP3:	case HILP4:	case HILP5:	case HILP6:	case HILP7:	case HILP:	case HILA1:	case HILA2:	case HILA3:	case HILA4:	case HILA5:	case HILA6:	case HILA7:	case HILA:		send_hildev_cmd(hilp, device, (cmd & 0xFF));		bcopy(hilp->hl_cmdbuf, data, hilp->hl_cmdbp-hilp->hl_cmdbuf);	  	break;        case HILDKR:        case HILER1:        case HILER2:		if (hilp->hl_kbddev) {			hilp->hl_cmddev = hilp->hl_kbddev;			send_hildev_cmd(hilp, hilp->hl_kbddev, (cmd & 0xFF));			hilp->hl_kbdflags &= ~(KBD_AR1|KBD_AR2);			if (cmd == HILIOCAR1)				hilp->hl_kbdflags |= KBD_AR1;			else if (cmd == HILIOCAR2)				hilp->hl_kbdflags |= KBD_AR2;		}		break;	case EFTSBP:		/* Send four data bytes to the tone gererator. */		send_hil_cmd(hilp->hl_addr, HIL_STARTCMD, data, 4, NULL);		/* Send the trigger beeper command to the 8042. */		send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL);		break;	case EFTRRT:		/* Transfer the real time to the 8042 data buffer */		send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL);		/* Read each byte of the real time */		for (i = 0; i < 5; i++) {			send_hil_cmd(hilp->hl_addr, HIL_READTIME + i, NULL,					0, &hold);			data[4-i] = hold;		}		break;			case EFTRT:		for (i = 0; i < 4; i++) {			send_hil_cmd(hilp->hl_addr, (cmd & 0xFF) + i,					NULL, 0, &hold);			data[i] = hold;		}		break;        case EFTRLC:        case EFTRCC:		send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, &hold);		*data = hold;		break;		        case EFTSRPG:        case EFTSRD:        case EFTSRR:		send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), data, 1, NULL);		break;			case EFTSBI:#ifdef hp800		/* XXX big magic */		hold = 7 - (*(u_char *)data >> 5);		*(int *)data = 0x84069008 | (hold << 8);		send_hil_cmd(hilp->hl_addr, HIL_STARTCMD, data, 4, NULL);		send_hil_cmd(hilp->hl_addr, 0xC4, NULL, 0, NULL);		break;#else		hilbeep(hilp, (struct _hilbell *)data);#endif		break;	case FIONBIO:		dptr = &hilp->hl_device[device];		if (*(int *)data)			dptr->hd_flags |= HIL_NOBLOCK;		else			dptr->hd_flags &= ~HIL_NOBLOCK;		break;	case FIOASYNC:		break;        default:		hilp->hl_cmddev = 0;		return(EINVAL);	}	hilp->hl_cmddev = 0;	return(0);}#endif/* ARGSUSED */hilmap(dev, off, prot)	dev_t dev;	int off, prot;{}/*ARGSUSED*/hilselect(dev, rw, p)	dev_t dev;	int rw;	struct proc *p;{	register struct hilloop *hilp = &hilloop[HILLOOP(dev)];	register struct hilloopdev *dptr;	register struct hiliqueue *qp;	register int mask;	int s, device;		if (rw == FWRITE)		return (1);	device = HILUNIT(dev);	/*	 * Read interface.	 * Return 1 if there is something in the queue, 0 ow.	 */	dptr = &hilp->hl_device[device];	if (dptr->hd_flags & HIL_READIN) {		s = splhil();		if (dptr->hd_queue.c_cc) {			splx(s);			return (1);		}		selrecord(p, &dptr->hd_selr);		splx(s);		return (0);	}	/*	 * Make sure device is alive and real (or the loop device).	 * Note that we do not do this for the read interface.	 * This is primarily to be consistant with HP-UX.	 */	if (device && (dptr->hd_flags & (HIL_ALIVE|HIL_PSEUDO)) != HIL_ALIVE)		return (1);	/*	 * Select on loop device is special.	 * Check to see if there are any data for any loop device	 * provided it is associated with a queue belonging to this user.	 */	if (device == 0)		mask = -1;	else		mask = hildevmask(device);	/*	 * Must check everybody with interrupts blocked to prevent races.	 */	s = splhil();	for (qp = hilp->hl_queue; qp < &hilp->hl_queue[NHILQ]; qp++)		if (qp->hq_procp == p && (mask & qp->hq_devmask) &&		    qp->hq_eventqueue->hil_evqueue.head !=		    qp->hq_eventqueue->hil_evqueue.tail) {			splx(s);			return (1);		}	selrecord(p, &dptr->hd_selr);	splx(s);	return (0);}/*ARGSUSED*/hilint(unit)	int unit;{#ifdef hp300	struct hilloop *hilp = &hilloop[0]; /* XXX how do we know on 300? */#else	struct hilloop *hilp = &hilloop[unit];#endif	register struct hil_dev *hildevice = hilp->hl_addr;	u_char c, stat;	stat = READHILSTAT(hildevice);	c = READHILDATA(hildevice);		/* clears interrupt */	hil_process_int(hilp, stat, c);}#include "ite.h"hil_process_int(hilp, stat, c)	register struct hilloop *hilp;	register u_char stat, c;{#ifdef DEBUG	if (hildebug & HDB_EVENTS)		printf("hilint: %x %x\n", stat, c);#endif	/* the shift enables the compiler to generate a jump table */	switch ((stat>>HIL_SSHIFT) & HIL_SMASK) {#if NITE > 0	case HIL_KEY:	case HIL_SHIFT:	case HIL_CTRL:	case HIL_CTRLSHIFT:		itefilter(stat, c);		return;#endif			case HIL_STATUS:			/* The status info. */		if (c & HIL_ERROR) {		  	hilp->hl_cmddone = TRUE;			if (c == HIL_RECONFIG)				hilconfig(hilp);			break;		}		if (c & HIL_COMMAND) {		  	if (c & HIL_POLLDATA)	/* End of data */				hilevent(hilp);			else			/* End of command */			  	hilp->hl_cmdending = TRUE;			hilp->hl_actdev = 0;		} else {		  	if (c & HIL_POLLDATA) {	/* Start of polled data */			  	if (hilp->hl_actdev != 0)					hilevent(hilp);				hilp->hl_actdev = (c & HIL_DEVMASK);				hilp->hl_pollbp = hilp->hl_pollbuf;			} else {		/* Start of command */				if (hilp->hl_cmddev == (c & HIL_DEVMASK)) {					hilp->hl_cmdbp = hilp->hl_cmdbuf;					hilp->hl_actdev = 0;				}			}		}	        return;	case HIL_DATA:		if (hilp->hl_actdev != 0)	/* Collecting poll data */			*hilp->hl_pollbp++ = c;		else if (hilp->hl_cmddev != 0)  /* Collecting cmd data */			if (hilp->hl_cmdending) {				hilp->hl_cmddone = TRUE;				hilp->hl_cmdending = FALSE;			} else  				*hilp->hl_cmdbp++ = c;		return;			case 0:		/* force full jump table */	default:		return;	}}#if defined(DEBUG) && !defined(PANICBUTTON)#define PANICBUTTON#endif/* * Optimized macro to compute: *	eq->head == (eq->tail + 1) % eq->size * i.e. has tail caught up with head.  We do this because 32 bit long * remaidering is expensive (a function call with our compiler). */#define HQFULL(eq)	(((eq)->head?(eq)->head:(eq)->size) == (eq)->tail+1)#define HQVALID(eq) \	((eq)->size == HEVQSIZE && (eq)->tail >= 0 && (eq)->tail < HEVQSIZE)hilevent(hilp)	struct hilloop *hilp;{	register struct hilloopdev *dptr = &hilp->hl_device[hilp->hl_actdev];	register int len, mask, qnum;	register u_char *cp, *pp;	register HILQ *hq;	struct timeval ourtime;	hil_packet *proto;	int s, len0;	long tenths;#ifdef PANICBUTTON	static int first;	extern int panicbutton;	cp = hilp->hl_pollbuf;	if (panicbutton && (*cp & HIL_KBDDATA)) {		if (*++cp == 0x4E)			first = 1;		else if (first && *cp == 0x46 && !panicstr)			panic("are we having fun yet?");		else			first = 0;	}#endif#ifdef DEBUG	if (hildebug & HDB_EVENTS) {		printf("hilevent: dev %d pollbuf: ", hilp->hl_actdev);		printhilpollbuf(hilp);		printf("\n");	}#endif	/*	 * Note that HIL_READIN effectively "shuts off" any queues	 * that may have been in use at the time of an HILIOCHPUX call.	 */	if (dptr->hd_flags & HIL_READIN) {		hpuxhilevent(hilp, dptr);		return;	}	/*	 * If this device isn't on any queue or there are no data	 * in the packet (can this happen?) do nothing.	 */	if (dptr->hd_qmask == 0 ||	    (len0 = hilp->hl_pollbp - hilp->hl_pollbuf) <= 0)		return;	/*	 * Everybody gets the same time stamp	 */	s = splclock();	ourtime = time;	splx(s);	tenths = (ourtime.tv_sec * 100) + (ourtime.tv_usec / 10000);	proto = NULL;	mask = dptr->hd_qmask;	for (qnum = 0; mask; qnum++) {		if ((mask & hilqmask(qnum)) == 0)			continue;		mask &= ~hilqmask(qnum);		hq = hilp->hl_queue[qnum].hq_eventqueue;				/*		 * Ensure that queue fields that we rely on are valid		 * and that there is space in the queue.  If either		 * test fails, we just skip this queue.		 */		if (!HQVALID(&hq->hil_evqueue) || HQFULL(&hq->hil_evqueue))			continue;		/*		 * Copy data to queue.		 * If this is the first queue we construct the packet		 * with length, timestamp and poll buffer data.		 * For second and sucessive packets we just duplicate		 * the first packet.		 */		pp = (u_char *) &hq->hil_event[hq->hil_evqueue.tail];		if (proto == NULL) {			proto = (hil_packet *)pp;			cp = hilp->hl_pollbuf;			len = len0;			*pp++ = len + 6;			*pp++ = hilp->hl_actdev;			*(long *)pp = tenths;			pp += sizeof(long);			do *pp++ = *cp++; while (--len);		} else			*(hil_packet *)pp = *proto;		if (++hq->hil_evqueue.tail == hq->hil_evqueue.size)			hq->hil_evqueue.tail = 0;	}	/*	 * Wake up anyone selecting on this device or the loop itself	 */	selwakeup(&dptr->hd_selr);	dptr = &hilp->hl_device[HILLOOPDEV];	selwakeup(&dptr->hd_selr);}#undef HQFULLhpuxhilevent(hilp, dptr)	register struct hilloop *hilp;	register struct hilloopdev *dptr;{	register int len;	struct timeval ourtime;	long tstamp;	int s;	/*	 * Everybody gets the same time stamp	 */	s = splclock();	ourtime = time;	splx(s);	tstamp = (ourtime.tv_sec * 100) + (ourtime.tv_usec / 10000);	/*	 * Each packet that goes into the buffer must be preceded by the	 * number of bytes in the packet, and the timestamp of the packet.	 * This adds 5 bytes to the packet size. Make sure there is enough	 * room in the buffer for it, and if not, toss the packet.	 */	len = hilp->hl_pollbp - hilp->hl_pollbuf;	if (dptr->hd_queue.c_cc <= (HILMAXCLIST - (len+5))) {		putc(len+5, &dptr->hd_queue);		(void) b_to_q((char *)&tstamp, sizeof tstamp, &dptr->hd_queue);		(void) b_to_q((char *)hilp->hl_pollbuf, len, &dptr->hd_queue);	}	/*	 * Wake up any one blocked on a read or select	 */	if (dptr->hd_flags & HIL_ASLEEP) {		dptr->hd_flags &= ~HIL_ASLEEP;		wakeup((caddr_t)dptr);	}	selwakeup(&dptr->hd_selr);}/* * Shared queue manipulation routines */hilqalloc(hilp, qip)	register struct hilloop *hilp;	struct hilqinfo *qip;{	struct proc *p = curproc;		/* XXX */#ifdef DEBUG	if (hildebug & HDB_FOLLOW)		printf("hilqalloc(%d): addr %x\n", p->p_pid, qip->addr);#endif	return(EINVAL);}hilqfree(hilp, qnum)	register struct hilloop *hilp;	register int qnum;{	struct proc *p = curproc;		/* XXX */#ifdef DEBUG	if (hildebug & HDB_FOLLOW)		printf("hilqfree(%d): qnum %d\n", p->p_pid, qnum);#endif	return(EINVAL);}hilqmap(hilp, qnum, device)	register struct hilloop *hilp;	register int qnum, device;{	struct proc *p = curproc;		/* XXX */	register struct hilloopdev *dptr = &hilp->hl_device[device];	int s;#ifdef DEBUG	if (hildebug & HDB_FOLLOW)		printf("hilqmap(%d): qnum %d device %x\n",		       p->p_pid, qnum, device);#endif	if (qnum >= NHILQ || hilp->hl_queue[qnum].hq_procp != p)		return(EINVAL);	if ((dptr->hd_flags & HIL_QUEUEIN) == 0)		return(EINVAL);	if (dptr->hd_qmask && p->p_ucred->cr_uid &&	    p->p_ucred->cr_uid != dptr->hd_uid)		return(EPERM);	hilp->hl_queue[qnum].hq_devmask |= hildevmask(device);	if (dptr->hd_qmask == 0)		dptr->hd_uid = p->p_ucred->cr_uid;	s = splhil();	dptr->hd_qmask |= hilqmask(qnum);	splx(s);#ifdef DEBUG	if (hildebug & HDB_MASK)		printf("hilqmap(%d): devmask %x qmask %x\n",		       p->p_pid, hilp->hl_queue[qnum].hq_devmask,		       dptr->hd_qmask);#endif	return(0);}hilqunmap(hilp, qnum, device)	register struct hilloop *hilp;	register int qnum, device;{	struct proc *p = curproc;		/* XXX */	int s;#ifdef DEBUG	if (hildebug & HDB_FOLLOW)		printf("hilqunmap(%d): qnum %d device %x\n",		       p->p_pid, qnum, device);#endif	if (qnum >= NHILQ || hilp->hl_queue[qnum].hq_procp != p)		return(EINVAL);	hilp->hl_queue[qnum].hq_devmask &= ~hildevmask(device);	s = splhil();	hilp->hl_device[device].hd_qmask &= ~hilqmask(qnum);	splx(s);#ifdef DEBUG	if (hildebug & HDB_MASK)		printf("hilqunmap(%d): devmask %x qmask %x\n",		       p->p_pid, hilp->hl_queue[qnum].hq_devmask,		       hilp->hl_device[device].hd_qmask);#endif	return(0);}/* * Cooked keyboard functions for ite driver. * There is only one "cooked" ITE keyboard (the first keyboard found) * per loop.  There may be other keyboards, but they will always be "raw". */kbdbell(unit)	int unit;{	struct hilloop *hilp = &hilloop[unit];	hilbeep(hilp, &default_bell);}kbdenable(unit)	int unit;{	struct hilloop *hilp = &hilloop[unit];	register struct hil_dev *hildevice = hilp->hl_addr;	char db;	/* Set the autorepeat rate register */	db = ar_format(KBD_ARR);	send_hil_cmd(hildevice, HIL_SETARR, &db, 1, NULL);	/* Set the autorepeat delay register */	db = ar_format(KBD_ARD);	send_hil_cmd(hildevice, HIL_SETARD, &db, 1, NULL);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -