📄 de1_drv.c
字号:
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 + -