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

📄 vtplayer.c

📁 linux下的VTPplayer驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	dbg("%s: minor %d", __FUNCTION__, dev->minor);	/* lock our device */	down (&dev->sem);	if (dev->open <= 0) {		dbg ("%s: device not opened", __FUNCTION__);		retval = -ENODEV;		goto exit_not_opened;	}	--dev->open;	if (!dev->present) {		/* the device was unplugged before the file was released */		up (&dev->sem);		vtp_delete (dev);		return 0;	}exit_not_opened:	up (&dev->sem);	return retval;}/** *	vtp_ioctl * *	The only supported command is VTP_CMD_SET_PADS, which sets the *	configuration of the tactile pads. */static int vtp_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	struct vtplayer *dev;	int retval = 0;	unsigned char *buffer;	dev = (struct vtplayer *)file->private_data;	dbg("%s(%X, %lX)", __FUNCTION__, cmd, arg);	switch(cmd) {	    case VTP_CMD_SET_PADS:	/* Set pad configuration */		/* lock this object */		down (&dev->sem);		/* verify that the device wasn't unplugged */		if (!dev->present) {			retval = -ENODEV;			goto exit;		}		/* allocate buffer */		buffer = kmalloc (VTP_DATA_LENGTH, GFP_KERNEL);		/* copy the data from userspace into our transfer buffer;		 * this is the only copy required.		 */		if (copy_from_user(buffer, (unsigned char *)arg, VTP_DATA_LENGTH)) {			retval = -EFAULT;			goto exit;		}		retval = usb_control_msg(			dev->udev,			usb_sndctrlpipe(dev->udev, 0),	/* Default control pipe */			0x09,				/* bRequest */			0x21,				/* bmRequestType */			0x0200,				/* wValue */			0x0000,				/* wIndex */			buffer,				/* data */			VTP_DATA_LENGTH,		/* wLength */			HZ*10);				/* timeout */					/* we can deallocate "buffer" now because the call is synchronous */		kfree(buffer);		if (retval != VTP_DATA_LENGTH) {			err("%s - failed submitting write urb, error %d",			    __FUNCTION__, retval);			retval = -1;		} else {			retval = 0;		}		exit:		/* unlock the device */		up (&dev->sem);		break;	    default:		retval = -ENOTTY;	}	return retval;}/** *	vtp_probe * *	Called by the usb core when a new device is connected that it thinks *	this driver might be interested in. */static int vtp_probe(struct usb_interface *interface, const struct usb_device_id *id){	struct usb_device *udev = interface_to_usbdev(interface);	struct vtplayer *dev = NULL;	struct usb_host_interface *iface_desc;	struct usb_endpoint_descriptor *endpoint;	int i;	int retval = -ENOMEM;	char path[64];	char *buf;	int maxp = 0;	int irq_pipe = 0;	int pollInterval = 0;	dbg("probing: %04X:%04X", le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct));	/* See if the device offered us matches what we can accept */	if ((le16_to_cpu(udev->descriptor.idVendor) != VTP_VENDOR_ID) ||	    (le16_to_cpu(udev->descriptor.idProduct) != VTP_PRODUCT_ID)) {		return -ENODEV;	}	/* allocate memory for our device state and initialize it */	dev = kmalloc (sizeof(struct vtplayer), GFP_KERNEL);	if (dev == NULL) {		err ("Out of memory");		goto error;	}	memset (dev, 0x00, sizeof (*dev));	init_MUTEX (&dev->sem);	dev->udev = udev;	dev->interface = interface;	/* set up the endpoint information */	/* check out the endpoints */	/* use the first Interrupt endpoint */	/* (normally, the VTP-1 has only one endpoint (interrupt one), */	/* at 0x81) */	iface_desc = &interface->altsetting[0];	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {		endpoint = &iface_desc->endpoint[i].desc;		if ((endpoint->bEndpointAddress & USB_DIR_IN) &&		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)					== USB_ENDPOINT_XFER_INT)) {			/* we found an interrupt in endpoint */			dev->int_in_endpointAddr = endpoint->bEndpointAddress;			pollInterval = endpoint->bInterval;			dbg("%s: found interrupt-in endpoint at 0x%02X (mouse function)\n", __FUNCTION__, dev->int_in_endpointAddr);			irq_pipe = usb_rcvintpipe(udev, dev->int_in_endpointAddr);			maxp = usb_maxpacket(udev, irq_pipe, usb_pipeout(irq_pipe));			break;		}	}	if (!(dev->int_in_endpointAddr)) {		err("Couldn't find interrupt-in endpoint.\n");		goto error;	}	/* allow device read, write and ioctl */	dev->present = 1;	/********************** MOUSE INITIALIZATION *************************/	dev->mouse_data = usb_buffer_alloc(udev, 8, SLAB_GFP_ATOMIC, &dev->mouse_data_dma);	if (!dev->mouse_data) {		kfree(dev);		return -ENOMEM;	}	dev->mouse_irq = usb_alloc_urb(0, GFP_KERNEL);	if (!dev->mouse_irq) {		usb_buffer_free(udev, 8, dev->mouse_data, dev->mouse_data_dma);		kfree(dev);		return -ENODEV;	}	dev->udev = udev;	dev->mouse_dev = input_allocate_device();		dev->mouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);	dev->mouse_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);	dev->mouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);	dev->mouse_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);	dev->mouse_dev->private = dev;	dev->mouse_dev->open = vtp_mouse_open;	dev->mouse_dev->close = vtp_mouse_close;	usb_make_path(udev, path, 64);	sprintf(dev->mouse_phys, "%s/input0", path);	dev->mouse_dev->name = dev->mouse_name;	dev->mouse_dev->phys = dev->mouse_phys;	dev->mouse_dev->id.bustype = BUS_USB;	dev->mouse_dev->id.vendor = udev->descriptor.idVendor;	dev->mouse_dev->id.product = udev->descriptor.idProduct;	dev->mouse_dev->id.version = udev->descriptor.bcdDevice;	if (!(buf = kmalloc(63, GFP_KERNEL))) {		usb_buffer_free(udev, 8, dev->mouse_data, dev->mouse_data_dma);		kfree(dev);		return -ENOMEM;	}	if (udev->descriptor.iManufacturer &&		usb_string(udev, udev->descriptor.iManufacturer, buf, 63) > 0)			strcat(dev->mouse_name, buf);	if (udev->descriptor.iProduct &&		usb_string(udev, udev->descriptor.iProduct, buf, 63) > 0)			sprintf(dev->mouse_name, "%s %s", dev->mouse_name, buf);	if (!strlen(dev->mouse_name))		sprintf(dev->mouse_name, "USB VTPlayer Mouse %04x:%04x",			dev->mouse_dev->id.vendor, dev->mouse_dev->id.product);	kfree(buf);	dbg("%s: maxp = %i\n", __FUNCTION__, maxp);	usb_fill_int_urb(dev->mouse_irq, udev, irq_pipe, dev->mouse_data,			 (maxp > 8 ? 8 : maxp),			 vtp_mouse_irq, dev, pollInterval);	dev->mouse_irq->transfer_dma = dev->mouse_data_dma;	dev->mouse_irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;	input_register_device(dev->mouse_dev);	printk(KERN_INFO "input: %s on %s\n", dev->mouse_name, path);	usb_set_intfdata(interface, dev);	/*********************************************************************/	/* we can register the device now, as it is ready */	retval = usb_register_dev (interface, &vtp_class);	if (retval) {		/* something prevented us from registering this driver */		err ("Not able to get a minor for this device.");		usb_set_intfdata (interface, NULL);		goto error;	}	dev->minor = interface->minor;	/* let the user know what node this device is now attached to */	info ("VTPlayer now attached to /dev/vtplayer%d (180,%d)", dev->minor - VTP_MINOR_BASE, dev->minor);	return 0;error:	vtp_delete (dev);	return retval;}/** *	vtp_disconnect * *	Called by the usb core when the device is removed from the system. * *	This routine guarantees that the driver will not submit any more urbs *	by clearing dev->udev.  It is also supposed to terminate any currently *	active urbs.  Unfortunately, usb_bulk_msg(), used in skel_read(), does *	not provide any way to do this.  But at least we can cancel an active *	write. */static void vtp_disconnect(struct usb_interface *interface){	struct vtplayer *dev;	int minor;	/* prevent races with open() */	down (&disconnect_sem);	dev = usb_get_intfdata (interface);	usb_set_intfdata (interface, NULL);	down (&dev->sem);	minor = dev->minor;	/* give back our minor */	usb_deregister_dev (interface, &vtp_class);	/* Disconnecting the mouse part of the driver */	usb_unlink_urb(dev->mouse_irq);	input_unregister_device(dev->mouse_dev);	usb_free_urb(dev->mouse_irq);	usb_buffer_free(interface_to_usbdev(interface), 8, dev->mouse_data, dev->mouse_data_dma);	/* prevent device read, write and ioctl */	dev->present = 0;	up (&dev->sem);	/* if the device is opened, vtp_release will clean this up */	if (!dev->open)		vtp_delete (dev);	up (&disconnect_sem);	info("VTPlayer vtplayer%d now disconnected", minor - VTP_MINOR_BASE);}/** *	vtp_init */static int __init vtp_init(void){	int result;	/* register this driver with the USB subsystem */	result = usb_register(&vtp_driver);	if (result) {		err("usb_register failed. Error number %d",		    result);		return result;	}	info(DRIVER_DESC " " DRIVER_VERSION);	return 0;}/** *	vtp_exit */static void __exit vtp_exit(void){	/* deregister this driver with the USB subsystem */	usb_deregister(&vtp_driver);}module_init (vtp_init);module_exit (vtp_exit);MODULE_AUTHOR(DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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