usbdmc.c
来自「一份介绍在S3C2410上液晶屏驱动程序的实现」· C语言 代码 · 共 734 行 · 第 1/2 页
C
734 行
case USBDMC_SETUP: res = usbdmc_setup(pdata); break; case USBDMC_READ_EEPROM: if( (res = usbdmc_read_eeprom(pdata,buf)) != -1 ) { res = copy_to_user((char *)arg,(char *)buf,res); res = true; } else res = false; break; case USBDMC_WRITE_EEPROM: res = copy_from_user((char *)buf,(char *)arg,39*2); res = usbdmc_write_eeprom(pdata,buf) != -1 ? true : false; break; case USBDMC_READ_STAT: res = usbdmc_get_stat(pdata,&b); put_user(b,(u_short *)arg); break; default: return(-ENOIOCTLCMD); } if( !res ) return(-EIO); return(0);}static ssize_t usbdmc_read(struct file * file, char * buffer, size_t count, loff_t *ppos){int i,getp,putp;usbdmc_data_t *p; #if DEBUG_HON printk(KERN_ERR "usbdmc_read entry size %d\n",count); #endif p = file->private_data; getp = p->rxgetp; for( i=0 ; i < count ; ) { putp = p->rxputp; if( getp == putp ) { if( file->f_flags & O_NONBLOCK ) { //printk(KERN_ERR "usbdmc_read non-block\n"); if( i > 0 ) break; return(-EAGAIN); } //printk(KERN_ERR "usbdmc_read irq wait...\n");#if KER26 wait_event_interruptible(p->wait,getp!=p->rxputp);#else interruptible_sleep_on(&p->wait);#endif p = file->private_data; if( p->dev == NULL ) { printk(KERN_ERR "usbdmc_read dev-null\n"); return(-ENOTCONN); } //printk(KERN_ERR "usbdmc_read irq wakeup\n"); if( signal_pending(current) ) return(-EINTR); } //printk(KERN_ERR "usbdmc_read data %x\n",p->rxbuf[getp]); put_user(p->rxbuf[getp++],&buffer[i]); getp = getp >= MAX_RXBUF ? 0 : getp; i++; } p->rxgetp = getp; #if DEBUG_HON printk(KERN_ERR "usbdmc_read exit %d \n",i); #endif return(i);}static unsigned int usbdmc_poll(struct file *file, poll_table * wait){usbdmc_data_t *p; #if 0 printk(KERN_ERR "usbdmc_poll\n"); #endif p = file->private_data; poll_wait(file,&p->wait,wait); p = file->private_data; if( p->dev == NULL ) { printk(KERN_ERR "usbdmc_poll dev-null\n"); return(-ENOTCONN); } if( p->rxgetp != p->rxputp ) return(POLLIN|POLLRDNORM); return(0);}#if KER26static struct file_operations usbdmc_fileopes = { .owner= THIS_MODULE, .read= usbdmc_read, .open= usbdmc_open, .release= usbdmc_close, .ioctl= usbdmc_ioctl, .poll= usbdmc_poll,};static struct usb_class_driver usbdmc_class = { .name = "usb/dmc%d", .fops = &usbdmc_fileopes, .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, .minor_base = USBDMC_MINOR,};#elsestatic struct file_operations usbdmc_fileopes = { owner: THIS_MODULE, ioctl: usbdmc_ioctl, open: usbdmc_open, read: usbdmc_read, poll: usbdmc_poll, release: usbdmc_close,};#endif#if KER26static int usbdmc_probe(struct usb_interface *intface,const struct usb_device_id *id){ struct usb_device *dev = NULL; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; unsigned int pipe; int n, intr_interval, len; dev = usb_get_dev(interface_to_usbdev(intface)); printk(KERN_ERR "DMC USB-Driver %s\n",TBUSB_VERSION); printk(KERN_ERR "usbdmc_probe vendor=$%x product=$%x\n" ,dev->descriptor.idVendor ,dev->descriptor.idProduct ); if( dev->descriptor.idVendor != VID_USBDMC ) { printk(KERN_INFO "USBDMC: unknown vendor id.\n"); return -ENODEV; } if( g_usbdmc_data ) { printk(KERN_INFO "USBDMC: no more probe.\n"); return -EIO; } iface_desc = intface->cur_altsetting; if( (g_usbdmc_data = kmalloc(sizeof(usbdmc_data_t), GFP_KERNEL)) == NULL ) { printk(KERN_INFO "no memory\n"); return -EIO; } memset(g_usbdmc_data,0,sizeof(usbdmc_data_t)); if( (g_usbdmc_data->irq = usb_alloc_urb(0, GFP_KERNEL)) == NULL ) { printk(KERN_INFO "no memory\n"); return -EIO; } //memset(g_usbdmc_data->irq,0,sizeof(struct urb)); intr_interval = 0; g_usbdmc_data->ep_intr_in = -1; g_usbdmc_data->ep_bulk_out = -1; g_usbdmc_data->ep_bulk_in = -1; for(n = 0; n < iface_desc->desc.bNumEndpoints; n++) { endpoint = &iface_desc->endpoint[n].desc; switch(endpoint->bEndpointAddress&USB_ENDPOINT_NUMBER_MASK) { case 1: /* INT-IN */ if( ! (endpoint->bEndpointAddress&USB_ENDPOINT_DIR_MASK) ) break; if( (endpoint->bmAttributes&USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT ) { g_usbdmc_data->ep_intr_in = 1; intr_interval = endpoint->bInterval; printk("usbdmc_probe: endpoint irq-in 1 ,interval=%d\n",intr_interval); } break; } } if( g_usbdmc_data->ep_intr_in == -1 ) { printk("endpoint error!!\n"); return -EIO; } g_usbdmc_data->dev = dev; g_usbdmc_data->isopen = 0; g_usbdmc_data->rxputp = 0; g_usbdmc_data->rxgetp = 0; usb_set_intfdata(intface,g_usbdmc_data); if( usb_register_dev(intface,&usbdmc_class) ) { usb_set_intfdata(intface,NULL); printk("regster error!!\n"); return -EIO; } pipe = usb_rcvintpipe(g_usbdmc_data->dev, g_usbdmc_data->ep_intr_in); len = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); //printk("usb_packet len=%d!!\n",len); usb_fill_int_urb(g_usbdmc_data->irq, dev, pipe, g_usbdmc_data->data, len, usbdmc_irq, g_usbdmc_data, intr_interval); g_usbdmc_data->irq->transfer_flags = 0;//URB_ISO_ASAP; return 0;}static void usbdmc_disconnect(struct usb_interface *intface){ printk(KERN_ERR "usbdmc_disconnect\n"); if( g_usbdmc_data ) { if( g_usbdmc_data->isopen ) { g_usbdmc_data->dev = NULL; wake_up_interruptible(&g_usbdmc_data->wait); //sleep_on(&g_usbdmc_data->remove_ok); } if( g_usbdmc_data->irq ) usb_free_urb(g_usbdmc_data->irq); usb_deregister_dev(intface,&usbdmc_class); kfree(g_usbdmc_data); g_usbdmc_data = NULL; }}#else // else of KER26static void* usbdmc_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id){ struct usb_interface_descriptor *inf; struct usb_config_descriptor *config; unsigned int pipe; int n, intr_interval, len; printk(KERN_ERR "DMC USB-Driver %s\n",TBUSB_VERSION); printk(KERN_ERR "usbdmc_probe ifnum=$%x vendor=$%x product=$%x\n" ,ifnum ,dev->descriptor.idVendor ,dev->descriptor.idProduct ); if( dev->descriptor.idVendor != VID_USBDMC ) { printk(KERN_INFO "USBDMC: unknown vendor id.\n"); return NULL; } if( g_usbdmc_data ) { printk(KERN_INFO "USBDMC: no more probe.\n"); return NULL; } config = dev->actconfig; inf = &config->interface[ifnum].altsetting[0]; if( (g_usbdmc_data = kmalloc(sizeof(usbdmc_data_t), GFP_KERNEL)) == NULL ) { printk(KERN_INFO "no memory\n"); return NULL; } memset(g_usbdmc_data,0,sizeof(usbdmc_data_t)); intr_interval = 0; g_usbdmc_data->ep_intr_in = -1; g_usbdmc_data->ep_bulk_out = -1; g_usbdmc_data->ep_bulk_in = -1; for(n = 0; n < inf->bNumEndpoints; n++) { switch(inf->endpoint[n].bEndpointAddress&USB_ENDPOINT_NUMBER_MASK) { case 1: /* INT-IN */ if( ! (inf->endpoint[n].bEndpointAddress&USB_ENDPOINT_DIR_MASK) ) break; if( (inf->endpoint[n].bmAttributes&USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT ) { g_usbdmc_data->ep_intr_in = 1; intr_interval = inf->endpoint[n].bInterval; printk("usbdmc_probe: endpoint irq-in 1 ,interval=%d\n",intr_interval); } break; } } if( g_usbdmc_data->ep_intr_in == -1 ) { printk("endpoint error!!\n"); return NULL; } g_usbdmc_data->dev = dev; g_usbdmc_data->isopen = 0; g_usbdmc_data->rxputp = 0; g_usbdmc_data->rxgetp = 0; pipe = usb_rcvintpipe(g_usbdmc_data->dev, g_usbdmc_data->ep_intr_in); len = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); usb_set_idle(dev, inf->bInterfaceNumber, 0, 0); FILL_INT_URB(&g_usbdmc_data->irq, dev, pipe, g_usbdmc_data->data, len, usbdmc_irq, g_usbdmc_data, intr_interval); return g_usbdmc_data;}static void usbdmc_disconnect(struct usb_device *dev, void *ptr){ printk(KERN_ERR "usbdmc_disconnect\n"); if( g_usbdmc_data ) { if( g_usbdmc_data->isopen ) { g_usbdmc_data->dev = NULL; wake_up_interruptible(&g_usbdmc_data->wait); sleep_on(&g_usbdmc_data->remove_ok); } kfree(g_usbdmc_data); g_usbdmc_data = NULL; }}#endif // end of KER26static struct usb_device_id usbdmc_table [] = { { USB_DEVICE(VID_USBDMC, PID_USBDMC) }, { }};MODULE_DEVICE_TABLE (usb, usbdmc_table);#if KER26static struct usb_driver usbdmc_data = { .owner = THIS_MODULE, .name = "usbdmc", .probe = usbdmc_probe, .disconnect = usbdmc_disconnect, .id_table = usbdmc_table,};#elsestatic struct usb_driver usbdmc_data = { name: "usbdmc", probe: usbdmc_probe, disconnect: usbdmc_disconnect, fops: &usbdmc_fileopes, minor: USBDMC_MINOR, id_table: usbdmc_table,};#endifint __init usbdmc_init(void){ printk(KERN_ERR "usbdmc_init\n"); if (usb_register(&usbdmc_data) < 0) { return -1; } return 0;}void __exit usbdmc_exit(void){ printk(KERN_ERR "usbdmc_exit\n"); usb_deregister(&usbdmc_data);}module_init(usbdmc_init);module_exit(usbdmc_exit);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?