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 + -
显示快捷键?