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

📄 de1_drv.c

📁 linux嵌入式课程实践中的一个关于声卡驱动程序 。
💻 C
📖 第 1 页 / 共 2 页
字号:
		      usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),		      dev->bulk_out_buffer, bytes_written,		      otg_de1_write_bulk_callback, dev);	/* send the data out the bulk port */	retval = usb_submit_urb(dev->bulk_out_urb);	if (retval) {		err(__FUNCTION__ " - failed submitting bulk out urb, error %d",		    retval);	} else {		retval = bytes_written;	}exit:	/* unlock the device */	up (&dev->sem);	return retval;}/** *	otg_de1_ioctl */static int otg_de1_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	int count = 0;	int ret = 0;	int val;	unsigned char size;	if (dev == NULL) {		dbg (__FUNCTION__ " - object is NULL");		return -ENODEV;	}	/* lock this object */	down (&dev->sem);//	dbg(__FUNCTION__ " - cmd 0x%.4x, arg %ld", cmd, arg);    switch (cmd) {	case IOCTL_GET_DE_RPT:		if (dev->connect_state == DEVICE_CONNECTED) {			if (dev->de_rpt_valid == DE_REPORT_VALID) {                copy_from_user((void *) &size, (void *) arg, 1);//                printk(KERN_DEBUG"IOCTL_GET_DE_RPT size:%d\n", size);				if (copy_to_user ((void *) arg,				                  dev->de_rpt_buffer,				                  size)) {					ret = -EFAULT;				}								/* Clear report valid status */				dev->de_rpt_valid = DE_REPORT_INVALID;			} else {				ret = -EAGAIN;			}		} else {			ret = -ENOTCONN;		}		break;	case IOCTL_SEND_DE_RPT:		if (dev->connect_state == DEVICE_CONNECTED) {			copy_from_user((void *) &size, (void *) arg, 1);//            printk(KERN_DEBUG"IOCTL_SEND_DE_RPT size:%d\n", size);			if (copy_from_user (dev->int_out_buffer,							  (void *) arg,							  size)) {  		           	printk(KERN_DEBUG"IOCTL_SEND_DE_RPT efault\n");					ret = -EFAULT;			} else {				/* Do an immediate bulk write */				ret = usb_bulk_msg(dev->udev,				     			   usb_sndbulkpipe(dev->udev, dev->int_out_endpointAddr),								   dev->int_out_buffer, size,								   &count, HZ);//                printk(KERN_DEBUG"IOCTL_SEND_DE_RPT usb_bulkmsg ret: %d\n", ret);			}		} else {            printk(KERN_DEBUG"IOCTL_SEND_DE_RPT not connected\n");			ret = -ENOTCONN;		}		break;    case IOCTL_END_SESSION:	    hc_otg_end_session(dev->udev);		break;	case IOCTL_ENABLE_HNP:		if (dev->connect_state == DEVICE_CONNECTED) {			hc_otg_offer_hnp(dev->udev);		}		break;	case IOCTL_END_HNP:        hc_otg_end_hnp(dev->udev);		break;    case IOCTL_OTG_STATE:	    ret = usb_otg_state(dev->udev, &val);        if( ret || copy_to_user( (void *)arg, &val, sizeof(int) ) )        {            ret = -EFAULT;        }        break;    case IOCTL_REQUEST_SRP:        hc_otg_start_session(dev->udev);        break;    case IOCTL_OTG_DEBUG:        hc_otg_debug(dev->udev);        break;	default:		ret = -ENOIOCTLCMD;		break;	}   		/* unlock the device */	up (&dev->sem);		return ret;}/** *	otg_de1_write_bulk_callback */static void otg_de1_write_bulk_callback (struct urb *urb){	if (urb->status != 0) {  		dbg(__FUNCTION__ " - nonzero write bulk status received: %d",		    urb->status);		return;	}	return;}/** *	otg_de1_int_in_callback */static void otg_de1_int_in_callback (struct urb *urb){	if (urb->status) return;	if (dev->de_rpt_valid != DE_REPORT_VALID) {		/* Indicate a valid report */		dev->de_rpt_valid = DE_REPORT_VALID;		/* copy data */		memcpy(dev->de_rpt_buffer,			   dev->int_in_buffer, 			   (urb->actual_length > DE1_BUFFER_SIZE ? DE1_BUFFER_SIZE : urb->actual_length));	}}/** *	otg_de1_probe * *	Called by the usb core when a new device is connected that it thinks *	this driver might be interested in. */static void * otg_de1_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id){	struct usb_interface *interface;	struct usb_interface_descriptor *iface_desc;	struct usb_endpoint_descriptor *endpoint;	int pipe, maxp, size;	int i;	int ret;	if (dev == NULL) {		dbg (__FUNCTION__ " - object is NULL");		return NULL;	}	/* See if the device offered us matches what we can accept */	if ((udev->descriptor.idVendor != USB_OTG_DE1_VENDOR_ID) ||	    (udev->descriptor.idProduct != USB_OTG_DE1_PRODUCT_ID)) {		return NULL;	}	/* See if we are already connected to a de1 device */	if (dev->connect_state == DEVICE_CONNECTED) {		//info ("Too many devices plugged in, can not handle this device.");		return NULL;	}	interface = &udev->actconfig->interface[ifnum];	dev->udev = udev;	dev->interface = interface;	/* set up the endpoint information */	/* check out the endpoints */	iface_desc = &interface->altsetting[0];	for (i = 0; i < iface_desc->bNumEndpoints; ++i) {		endpoint = &iface_desc->endpoint[i];		if ((endpoint->bEndpointAddress & 0x80) &&		    ((endpoint->bmAttributes & 3) == 0x02)) {			/* we found a bulk in endpoint */			dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;		}				if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&		    ((endpoint->bmAttributes & 3) == 0x02)) {			/* we found a bulk out endpoint */			dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;		}				if ((endpoint->bEndpointAddress & 0x80) &&		    ((endpoint->bmAttributes & 3) == 0x03)) {			/* we found an interrupt in endpoint */			dev->int_in_endpointAddr = endpoint->bEndpointAddress;			/* Submit an interrupt in urb */			pipe = usb_rcvintpipe(dev->udev, endpoint->bEndpointAddress);			maxp = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));			size = maxp > DE1_BUFFER_SIZE ? DE1_BUFFER_SIZE : maxp;			FILL_INT_URB(dev->int_in_urb, dev->udev, pipe, dev->int_in_buffer,			             size, otg_de1_int_in_callback, dev, endpoint->bInterval);			if (ret = usb_submit_urb(dev->int_in_urb)) {				err(__FUNCTION__ " - failed submitting int in urb, error %d", ret);				return (-EIO);			}		}		if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&		    ((endpoint->bmAttributes & 3) == 0x03)) {			/* we found an interrupt out endpoint */			dev->int_out_endpointAddr = endpoint->bEndpointAddress;		}	}	/* Indicate that a device is connected */	dev->connect_state = DEVICE_CONNECTED;	/* let the user know what node this device is now attached to */	//info ("Cypress OTG device now attached (major %d - minor %d)", dev->major, USB_OTG_DE1_MINOR_BASE);	return dev;}/** *	otg_de1_disconnect * *	Called by the usb core when the device is removed from the system. */static void otg_de1_disconnect(struct usb_device *udev, void *ptr){	if (dev == NULL) {		dbg (__FUNCTION__ " - object is NULL");		return;	}	/* lock the device */	down (&dev->sem);	/* unlink the Int in URB */	usb_unlink_urb(dev->int_in_urb);	/* Indicate that a device is not connected */	dev->connect_state = DEVICE_NOTCONNECTED;	/* Indicate that any remaining report is not valid */	dev->de_rpt_valid = DE_REPORT_INVALID;	/* unlock the device */	up (&dev->sem);	//info("Cypress OTG device DE1 now disconnected");}/** *	USB_OTG_DE1_init */static int __init USB_OTG_DE1_init(void){	int result;	/* allocate memory for our device state and intialize it */	dev = kmalloc (sizeof(struct USB_OTG_DE1), GFP_KERNEL);	if (dev == NULL) {		err ("Out of memory");		return -1;	}	memset ((void *) dev, 0x00, sizeof (struct USB_OTG_DE1));	/* allocate memory for the bulk-in buffer */	dev->bulk_in_buffer = kmalloc (DE1_BUFFER_SIZE, GFP_KERNEL);	if (!dev->bulk_in_buffer) {		err("Couldn't allocate bulk_in_buffer");		return -1;	}	dev->bulk_in_size = DE1_BUFFER_SIZE;	/* allocate memory for the bulk-out URB */	dev->bulk_out_urb = usb_alloc_urb(0);	if (!dev->bulk_out_urb) {		err("No free urbs available");		return -1;	}	/* allocate memory for the bulk-out buffer */	dev->bulk_out_buffer = kmalloc (DE1_BUFFER_SIZE, GFP_KERNEL);				if (!dev->bulk_out_buffer) {		err("Couldn't allocate bulk_out_buffer");		return -1;	}	dev->bulk_out_size = DE1_BUFFER_SIZE;	/* allocate memory for the int-in URB */	dev->int_in_urb = usb_alloc_urb(0);	if (!dev->int_in_urb) {		err("No free urbs available");		return -1;	}	/* allocate memory for the int_in buffer */	dev->int_in_buffer = kmalloc (DE1_BUFFER_SIZE, GFP_KERNEL);				if (!dev->int_in_buffer) {		err("Couldn't allocate int_in_buffer");		return -1;	}	dev->int_in_size = DE1_BUFFER_SIZE;	/* allocate memory for the int_out buffer */	dev->int_out_buffer = kmalloc (DE1_BUFFER_SIZE, GFP_KERNEL);				if (!dev->int_out_buffer) {		err("Couldn't allocate int_out_buffer");		return -1;	}	dev->int_out_size = DE1_BUFFER_SIZE;	/* allocate memory for the int_out buffer */	dev->de_rpt_buffer = kmalloc (DE1_BUFFER_SIZE, GFP_KERNEL);				if (!dev->de_rpt_buffer) {		err("Couldn't allocate de_rpt_buffer");		return -1;	}	dev->de_rpt_valid = DE_REPORT_INVALID;	/* register this driver with the USB subsystem */	result = usb_register(&otg_de1_driver);	if (result < 0) {		err("usb_register failed for the "__FILE__" driver. Error number %d",		    result);		return -1;	}	dev->major = DE1_DEVICE_MAJOR;    result = register_chrdev( dev->major, DE1_DEVICE_NAME, &otg_de1_fops );    if( result != 0 )    {        err("register_chrdev() failed.");		return -1;    }	/* Indicate that a device is not connected */	dev->connect_state = DEVICE_NOTCONNECTED;	/* Initialize the driver semaphore */	init_MUTEX (&dev->sem);	//info(DRIVER_DESC " " DRIVER_VERSION " (Major = %d)", dev->major);	return 0;}/** *	USB_OTG_DE1_exit */static void __exit USB_OTG_DE1_exit(void){	if (dev == NULL) {		dbg (__FUNCTION__ " - object is NULL");		return;	}	/* deregister this driver with the USB subsystem */	usb_deregister(&otg_de1_driver);	/* Unregister device */    unregister_chrdev( dev->major, DE1_DEVICE_NAME );	/* Delete buffers */	otg_de1_delete (dev);}module_init (USB_OTG_DE1_init);module_exit (USB_OTG_DE1_exit);MODULE_AUTHOR(DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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