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

📄 ums.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	void *p;{	struct ums_softc *sc = p;	DPRINTF(("ums_disco: sc=%p\n", sc));	usbd_abort_pipe(sc->sc_intrpipe);	sc->sc_disconnected = 1;}voidums_intr(reqh, addr, status)	usbd_request_handle reqh;	usbd_private_handle addr;	usbd_status status;{	struct ums_softc *sc = addr;	u_char *ibuf;	int dx, dy, dz;	u_char buttons = 0;	int i;#if defined(__NetBSD__)#define UMS_BUT(i) ((i) == 1 || (i) == 2 ? 3 - (i) : i)#elif defined(__FreeBSD__)#define UMS_BUT(i) ((i) < 3 ? (((i) + 2) % 3) : (i))#endif	DPRINTFN(5, ("ums_intr: sc=%p status=%d\n", sc, status));	DPRINTFN(5, ("ums_intr: data = %02x %02x %02x\n",		     sc->sc_ibuf[0], sc->sc_ibuf[1], sc->sc_ibuf[2]));	if (status == USBD_CANCELLED)		return;	if (status != USBD_NORMAL_COMPLETION) {		DPRINTF(("ums_intr: status=%d\n", status));		usbd_clear_endpoint_stall_async(sc->sc_intrpipe);		return;	}	ibuf = sc->sc_ibuf;	if (sc->sc_iid) {		if (*ibuf++ != sc->sc_iid)			return;	}	dx =  hid_get_data(ibuf, &sc->sc_loc_x);	dy = -hid_get_data(ibuf, &sc->sc_loc_y);	dz = -hid_get_data(ibuf, &sc->sc_loc_z);	for (i = 0; i < sc->nbuttons; i++)		if (hid_get_data(ibuf, &sc->sc_loc_btn[i]))			buttons |= (1 << UMS_BUT(i));#if defined(__NetBSD__)	if (dx || dy || buttons != sc->sc_buttons) {		DPRINTFN(10, ("ums_intr: x:%d y:%d z:%d buttons:0x%x\n",			dx, dy, dz, buttons));		sc->sc_buttons = buttons;		if (sc->sc_wsmousedev)			wsmouse_input(sc->sc_wsmousedev, buttons, dx, dy, dz);#elif defined(__FreeBSD__)	if (dx || dy || dz || (sc->flags & UMS_Z)	    || buttons != sc->status.button) {		DPRINTFN(5, ("ums_intr: x:%d y:%d z:%d buttons:0x%x\n",			dx, dy, dz, buttons));		sc->status.button = buttons;		sc->status.dx += dx;		sc->status.dy += dy;		sc->status.dz += dz;		/* Discard data in case of full buffer */		if (sc->qcount == sizeof(sc->qbuf)) {			DPRINTF(("Buffer full, discarded packet"));			return;		}		if (dx >  254)		dx =  254;		if (dx < -256)		dx = -256;		if (dy >  254)		dy =  254;		if (dy < -256)		dy = -256;		if (dz >  126)		dz =  126;		if (dz < -128)		dz = -128;		sc->qbuf[sc->qhead] = sc->mode.syncmask[1];		sc->qbuf[sc->qhead] |= ~buttons & MOUSE_MSC_BUTTONS;		sc->qbuf[sc->qhead+1] = dx >> 1;		sc->qbuf[sc->qhead+2] = dy >> 1;		sc->qbuf[sc->qhead+3] = dx - (dx >> 1);		sc->qbuf[sc->qhead+4] = dy - (dy >> 1);		if (sc->mode.level == 1) {			sc->qbuf[sc->qhead+5] = dz >> 1;			sc->qbuf[sc->qhead+6] = dz - (dz >> 1);			sc->qbuf[sc->qhead+7] = ((~buttons >> 3)						 & MOUSE_SYS_EXTBUTTONS);		}		sc->qhead += sc->mode.packetsize;		sc->qcount += sc->mode.packetsize;#ifdef UMS_DEBUG		if (sc->qhead > sizeof(sc->qbuf))			DPRINTF(("Buffer overrun! %d %d\n", 				 sc->qhead, sizeof(sc->qbuf)));#endif		/* wrap round at end of buffer */		if (sc->qhead >= sizeof(sc->qbuf))			sc->qhead = 0;		/* someone waiting for data */		if (sc->state & UMS_ASLEEP) {			sc->state &= ~UMS_ASLEEP;			wakeup(sc);		}		if (sc->state & UMS_SELECT) {			sc->state &= ~UMS_SELECT;			selwakeup(&sc->rsel);		}#endif	}}static intums_enable(v)	void *v;{	struct ums_softc *sc = v;	usbd_status r;	if (sc->sc_enabled)		return EBUSY;	sc->sc_enabled = 1;#if defined(__NetBSD__)	sc->sc_buttons = 0;#elif defined(__FreeBSD__)	sc->qcount = 0;	sc->qhead = sc->qtail = 0;	sc->status.flags = 0;	sc->status.button = sc->status.obutton = 0;	sc->status.dx = sc->status.dy = sc->status.dz = 0;#endif	/* Set up interrupt pipe. */	r = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr, 				USBD_SHORT_XFER_OK, &sc->sc_intrpipe, sc, 				sc->sc_ibuf, sc->sc_isize, ums_intr);	if (r != USBD_NORMAL_COMPLETION) {		DPRINTF(("ums_enable: usbd_open_pipe_intr failed, error=%d\n",			 r));		sc->sc_enabled = 0;		return (EIO);	}	usbd_set_disco(sc->sc_intrpipe, ums_disco, sc);	return (0);}static voidums_disable(v)	void *v;{	struct ums_softc *sc = v;	/* Disable interrupts. */	usbd_abort_pipe(sc->sc_intrpipe);	usbd_close_pipe(sc->sc_intrpipe);	sc->sc_enabled = 0;#if defined(__FreeBSD__)	if (sc->qcount != 0)		DPRINTF(("Discarded %d bytes in queue\n", sc->qcount));#endif}#if defined(__NetBSD__)static intums_ioctl(v, cmd, data, flag, p)	void *v;	u_long cmd;	caddr_t data;	int flag;	struct proc *p;{	switch (cmd) {	case WSMOUSEIO_GTYPE:		*(u_int *)data = WSMOUSE_TYPE_USB;		return (0);	}	return (-1);}#elif defined(__FreeBSD__)static intums_open(dev_t dev, int flag, int fmt, struct proc *p){	USB_GET_SC_OPEN(ums, UMSUNIT(dev), sc);	return ums_enable(sc);}static intums_close(dev_t dev, int flag, int fmt, struct proc *p){	USB_GET_SC(ums, UMSUNIT(dev), sc);	if (sc->sc_enabled)		ums_disable(sc);	return 0;}static intums_read(dev_t dev, struct uio *uio, int flag){	USB_GET_SC(ums, UMSUNIT(dev), sc);	int s;	char buf[sizeof(sc->qbuf)];	int l = 0;	int error;	s = splusb();	while (sc->qcount == 0 )  {		/* NWH XXX non blocking I/O ??		if (non blocking I/O ) {			splx(s);			return EWOULDBLOCK;		} else {		*/		sc->state |= UMS_ASLEEP;		error = tsleep(sc, PZERO | PCATCH, "umsrea", 0);		if (error) {			splx(s);			return error;		} else if (!sc->sc_enabled) {			splx(s);			return EINTR;		}	}	while ((sc->qcount > 0) && (uio->uio_resid > 0)) {		l = (sc->qcount < uio->uio_resid? sc->qcount:uio->uio_resid);		if (l > sizeof(buf))			l = sizeof(buf);		if (l > sizeof(sc->qbuf) - sc->qtail)		/* transfer till end of buf */			l = sizeof(sc->qbuf) - sc->qtail;		splx(s);		uiomove(&sc->qbuf[sc->qtail], l, uio);		s = splusb();		if ( sc->qcount - l < 0 ) {			DPRINTF(("qcount below 0, count=%d l=%d\n", sc->qcount, l));			sc->qcount = l;		}		sc->qcount -= l;	/* remove the bytes from the buffer */		sc->qtail = (sc->qtail + l) % sizeof(sc->qbuf);	}	splx(s);	return 0;}static intums_poll(dev_t dev, int events, struct proc *p){	USB_GET_SC(ums, UMSUNIT(dev), sc);	int revents = 0;	int s;	s = splusb();	if (events & (POLLIN | POLLRDNORM)) {		if (sc->qcount) {			revents = events & (POLLIN | POLLRDNORM);		} else {			sc->state |= UMS_SELECT;			selrecord(p, &sc->rsel);		}	}	splx(s);	return revents;}	intums_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p){	USB_GET_SC(ums, UMSUNIT(dev), sc);	int error = 0;	int s;	mousemode_t mode;	switch(cmd) {	case MOUSE_GETHWINFO:		*(mousehw_t *)addr = sc->hw;		break;	case MOUSE_GETMODE:		*(mousemode_t *)addr = sc->mode;		break;	case MOUSE_SETMODE:		mode = *(mousemode_t *)addr;		if (mode.level == -1)			/* don't change the current setting */			;		else if ((mode.level < 0) || (mode.level > 1))			return (EINVAL);		s = splusb();		sc->mode.level = mode.level;		if (sc->mode.level == 0) {			if (sc->nbuttons > MOUSE_MSC_MAXBUTTON)				sc->hw.buttons = MOUSE_MSC_MAXBUTTON;			else				sc->hw.buttons = sc->nbuttons;			sc->mode.protocol = MOUSE_PROTO_MSC;			sc->mode.packetsize = MOUSE_MSC_PACKETSIZE;			sc->mode.syncmask[0] = MOUSE_MSC_SYNCMASK;			sc->mode.syncmask[1] = MOUSE_MSC_SYNC;		} else if (sc->mode.level == 1) {			if (sc->nbuttons > MOUSE_SYS_MAXBUTTON)				sc->hw.buttons = MOUSE_SYS_MAXBUTTON;			else				sc->hw.buttons = sc->nbuttons;			sc->mode.protocol = MOUSE_PROTO_SYSMOUSE;			sc->mode.packetsize = MOUSE_SYS_PACKETSIZE;			sc->mode.syncmask[0] = MOUSE_SYS_SYNCMASK;			sc->mode.syncmask[1] = MOUSE_SYS_SYNC;		}		bzero(sc->qbuf, sizeof(sc->qbuf));		sc->qhead = sc->qtail = sc->qcount = 0;		splx(s);		break;	case MOUSE_GETLEVEL:		*(int *)addr = sc->mode.level;		break;	case MOUSE_SETLEVEL:		if (*(int *)addr < 0 || *(int *)addr > 1)			return (EINVAL);		s = splusb();		sc->mode.level = *(int *)addr;		if (sc->mode.level == 0) {			if (sc->nbuttons > MOUSE_MSC_MAXBUTTON)				sc->hw.buttons = MOUSE_MSC_MAXBUTTON;			else				sc->hw.buttons = sc->nbuttons;			sc->mode.protocol = MOUSE_PROTO_MSC;			sc->mode.packetsize = MOUSE_MSC_PACKETSIZE;			sc->mode.syncmask[0] = MOUSE_MSC_SYNCMASK;			sc->mode.syncmask[1] = MOUSE_MSC_SYNC;		} else if (sc->mode.level == 1) {			if (sc->nbuttons > MOUSE_SYS_MAXBUTTON)				sc->hw.buttons = MOUSE_SYS_MAXBUTTON;			else				sc->hw.buttons = sc->nbuttons;			sc->mode.protocol = MOUSE_PROTO_SYSMOUSE;			sc->mode.packetsize = MOUSE_SYS_PACKETSIZE;			sc->mode.syncmask[0] = MOUSE_SYS_SYNCMASK;			sc->mode.syncmask[1] = MOUSE_SYS_SYNC;		}		bzero(sc->qbuf, sizeof(sc->qbuf));		sc->qhead = sc->qtail = sc->qcount = 0;		splx(s);		break;	case MOUSE_GETSTATUS: {		mousestatus_t *status = (mousestatus_t *) addr;		s = splusb();		*status = sc->status;		sc->status.obutton = sc->status.button;		sc->status.button = 0;		sc->status.dx = sc->status.dy = sc->status.dz = 0;		splx(s);		if (status->dx || status->dy || status->dz)			status->flags |= MOUSE_POSCHANGED;		if (status->button != status->obutton)			status->flags |= MOUSE_BUTTONSCHANGED;		break;		}	default:		error = ENOTTY;	}	return error;}#endif#if defined(__FreeBSD__)CDEV_DRIVER_MODULE(ums, uhub, ums_driver, ums_devclass,			UMS_CDEV_MAJOR, ums_cdevsw, usbd_driver_load, 0);#endif

⌨️ 快捷键说明

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