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

📄 usbdrv.c

📁 usb接口的scanner的驱动,稍加修改就可以使用了. 测试过了,可以使用
💻 C
📖 第 1 页 / 共 2 页
字号:
		db("SINODATA_HP_OPEN :Device is open now!");        return retval;}static inline void sn_delete (struct scn_usb_data *dev){        minor_table[dev->scn_minor] = NULL;        if (dev->bulk_in_buffer != NULL)                kfree (dev->bulk_in_buffer);        if (dev->bulk_out_buffer != NULL)                kfree (dev->bulk_out_buffer);        if (dev->write_urb != NULL)                usb_free_urb (dev->write_urb);        kfree (dev);}static int sn_release (struct inode *inode, struct file *file){	struct scn_usb_data *dev;	kdev_t minor;	minor = USB_SN_MINOR (inode);	db("SINODATA-HP close: scn_minor:%d\n", minor);	if (!minor_table[minor]) {		db("SINODATA-HP close: (%d): invalid scn_minor\n", minor);		return -ENODEV;	}	down(&minor_table_mutex);	dev = minor_table[minor];	down(&(dev->sem));	dev->isopen = 0;	file->private_data = NULL;	up(&minor_table_mutex);	up(&(dev->sem));	return 0;}static int sn_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg){	struct scn_usb_data *scn;	struct usb_device *dev;	int retval = -ENOTTY;	char status =0;	struct {			   unsigned short value;			   unsigned short status;			}args;	struct {			        int buf_len;			        char buf[100];		      	}codes;    db("SINODATA-HP :ioctrl ! Cmd is % \n, cmd");	scn = file->private_data;	down(&(scn->sem));	dev = scn->scn_dev;	switch (cmd)	{		case SNUSB_IOCTL_READ_STATUS:			if (copy_from_user(&args, (void *)arg, sizeof(args)))			{		 		retval = -EFAULT;				break;			}    		printk ("<1>value=%d,status=%d\n",args.value, args.status);			retval = usb_control_msg(dev, usb_rcvctrlpipe(dev,scn->bulk_out_ep),					 CMD_READ_STATE, USB_TYPE_VENDOR| USB_RECIP_DEVICE|USB_DIR_IN,									0,args.value, &args.status,sizeof(args.status), HZ*5);		    printk ("<1>value=%d,status=%d\n",args.value,args.status);    	       		  		if (copy_to_user((void*)arg, &args, sizeof(args)))					retval = -EFAULT;		   printk ("<1>IOCTL_READ_STATUS ioctl cmd=%d\n",cmd);			break;		case SNUSB_IOCTL_USER_CODE:      			if (copy_from_user(&codes, (void *)arg, sizeof(codes)))				{		 			retval = -EFAULT;						break;				}				retval = usb_control_msg(dev, usb_rcvctrlpipe(dev, scn->bulk_out_ep),					 				CMD_READ_DATA, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN,										0, 0, codes.buf,codes.buf_len, HZ*5);				if (copy_to_user((void *)arg, &codes,sizeof(codes)))					retval = -EFAULT;      			printk ("<1> IOCTL_USER_CODE ioctl cmd=%d\n",cmd);				printk ("<1>Code is %s\n", codes.buf);				break;		default:			printk ("<1>nvilidata IO ctrl\n");			break;	}		}static ssize_t sn_write(struct file * file, const char * buffer,size_t count, loff_t *ppos){	return 0;}static ssize_t sn_read(struct file * file, char * buffer,size_t count, loff_t *ppos){	return 0;}static struct file_operations sn_fops = {        owner:	   THIS_MODULE,        read:          sn_read,        write:         sn_write,        ioctl:          sn_ioctl,        open:         sn_open,        release:      sn_release,};static void * sn_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id){	struct scn_usb_data *dev = NULL;    struct usb_interface *interface;    struct usb_interface_descriptor *iface_desc;    struct usb_endpoint_descriptor *endpoint;    int minor;    int buffer_size;    int i;    char name[10];	char have_bulk_in, have_bulk_out, have_intr;	int ep_count;    printk ("<1>Device Probe");	if ((udev->descriptor.idVendor != USB_SN_VENDOR_ID) ||            (udev->descriptor.idProduct != USB_SN_PRODUCT_ID))	{		return NULL;    }	//Check idVendor And idProduct	if (udev->descriptor.bNumConfigurations != 1)	{		info("SINODATA-HP: Only one device configuration is supported.\n");		return NULL;	}	interface =&(udev->actconfig->interface[ifnum]);	//iface_desc =&(interface->altsetting[0]);	iface_desc = udev->config[0].interface[ifnum].altsetting;	//endpoint =iface_desc->endpoint;	endpoint = iface_desc[0].endpoint;	usb_show_interface_descriptor(iface_desc);	usb_show_device_descriptor(&udev->descriptor);	usb_show_config_descriptor(udev->config);	printk ("<1>SINODATA-HP : Device endpoint count is %d", iface_desc->bNumEndpoints);    ep_count =have_bulk_in =have_bulk_out =have_intr =0;	while (ep_count < iface_desc->bNumEndpoints)	{		if (!have_bulk_in && IS_EP_BULK_IN(endpoint[ep_count]))		{			ep_count++;			have_bulk_in=0x2;			printk ("<1>SINODATA-HP : probe_snusb: bulk_in_ep:%d\n", have_bulk_in);			continue;		}		if (!have_bulk_out && IS_EP_BULK_OUT(endpoint[ep_count]))		{			ep_count++;			have_bulk_out=0;			printk ("<1>SINODATA-HP :  probe_snusb: bulk_out_ep:%d\n", have_bulk_out);			continue;		}		if (!have_intr && IS_EP_INTR(endpoint[ep_count]))		{			ep_count++;			have_intr=1;			printk ("<1>SINODATA-HP :  probe_snusb: intr_ep:%d\n", have_intr);			continue;		}		info("probe_snusb: Undetected endpoint -- consult Documentation/usb/snusb.txt.\n");		return NULL;	}	switch(iface_desc->bNumEndpoints)	{	case 1:		if (!have_bulk_in)		{			info("SINODATA-HP :  One bulk-in endpoint required.\n");			return NULL;		}		break;	case 2:		if (!have_bulk_in || !have_bulk_out)		{			info("SINODATA-HP :  Two bulk endpoints required.\n");			return NULL;		}		break;	case 3:		if (!have_bulk_in || !have_bulk_out || !have_intr)		{			db("SINODATA-HP-Probe :  Two bulk endpoint and one interrupt endpoint required.\n");			info("SINODATA-HP-Probe :  Two bulk endpoints and one interrupt endpoint required.\n");		}		break;	default:		info("SINODATA-HP-Probe :  Endpoint determination failed --  consult Documentation/usb/snusb.txt\n");		return NULL;	}	down (&minor_table_mutex);    for (minor = 0; minor < MAX_DEVICES; ++minor)	{    	if (minor_table[minor] == NULL)      		break;	}	//get the minor    if (minor >= MAX_DEVICES)	{		info ("Too many devices plugged in, can not handle this device.");		goto exit;    }// allocate memory for our device state and intialize it     dev = kmalloc (sizeof (struct scn_usb_data), GFP_KERNEL);    if (dev == NULL)	{		err ("Out of memory");		goto exit;	}	dev->write_urb = usb_alloc_urb(0);	if (have_intr)	{		db("SINODATA-HP-Probe :  (%d): Configuring IRQ handler for intr EP:%d\n", minor, have_intr);		FILL_INT_URB(dev->write_urb, udev,usb_rcvintpipe(udev, have_intr), &dev->button, 1, \						sn_write_bulk_callback, dev, 250);       if (usb_submit_urb(dev->write_urb))		{			err("probe_snusb(%d): Unable to allocate INT URB.\n", minor);            kfree(dev);			up(&minor_table_mutex);			return NULL;      	}	}	if (!(dev->bulk_out_buffer = (char *)kmalloc(OBUF_SIZE, GFP_KERNEL)))	{		db("probe_snusb(%d): Not enough memory for the output buffer.\n", minor);		kfree(dev);		up(&minor_table_mutex);		return NULL;	}	db("SINODATA-HP-Probe :  (%d): obuf address:%p\n", minor, dev->bulk_out_buffer);	if (!(dev->bulk_in_buffer = (char *)kmalloc(ibuf_size, GFP_KERNEL)))	{		db("probe_snusb(%d): Not enough memory for the input buffer.\n", minor);		kfree(dev->bulk_out_buffer);		kfree(dev);		up(&minor_table_mutex);		return NULL;	}	db("SINODATA-HP-Probe :  (%d): ibuf address:%p\n", minor, dev->bulk_in_buffer);	//interface = &udev->actconfig->interface[ifnum];	init_MUTEX (&(dev->sem));	dev->scn_dev = udev;	dev->interface = interface;	dev->scn_minor = minor;	dev->bulk_in_ep = have_bulk_in;	dev->bulk_out_ep = have_bulk_out;	dev->intr_ep = have_intr;	dev->present = 1;	dev->scn_minor = minor;	dev->isopen = 0;	//iface_desc = &interface->altsetting[0];        // initialize the devfs node for this device and register it	sprintf(name, "snusb");    db("SINODATA-HP-Probe : Dev Name is %s , Minor is %d \n", name, dev->scn_minor);        //if (register_chrdev (128, "snusb", &sn_fops) <0)    	//db("SINODATA-HP-Probe : Register Char Dev Failt\n", minor);     	dev->devfs = devfs_register (usb_devfs_handle, name,                                     DEVFS_FL_DEFAULT, USB_MAJOR,                                     SCN_BASE_MNR + dev->scn_minor,                                     S_IFCHR | S_IRUSR | S_IWUSR |                                     S_IRGRP | S_IWGRP | S_IROTH,                                     &sn_fops, NULL); 	if (dev->devfs == NULL)		db("SINODATA-HP-Probe : snusb%d: device node registration failed\n", minor);	   db("SINODATA-HP-Probe : name=%s,devfs=%d, Handle is % d\n",name,dev->devfs, usb_devfs_handle);	   	   	 minor_table[minor] = dev;        // let the user know what node this device is now attached to	db ("SINODATA-HP-Probe :  USB SinoData device now attached to USBSn%d", dev->scn_minor);	goto exit;error:	//skel_delete (dev);	dev = NULL;exit:	up (&minor_table_mutex);	return dev;}static void sn_disconnect(struct usb_device *udev, void *ptr);static struct usb_driver sn_driver = {        name:           "SnUsbDrv",        probe:          sn_probe,        disconnect:     sn_disconnect,        fops:           &sn_fops,        minor:          SCN_BASE_MNR,        id_table:       sn_table,};static void sn_disconnect(struct usb_device *udev, void *ptr){	struct scn_usb_data *dev;	int minor;	dev = (struct scn_usb_data *)ptr;	db("SINODATA-HP-disconnect\n");	down (&minor_table_mutex);	down (&dev->sem);	if (dev->intr_ep)	{		db("SINODATA-HP-disconnect_snusb(%d): Unlinking IRQ URB\n", minor);		usb_unlink_urb(dev->write_urb);	}	usb_driver_release_interface(&sn_driver, dev->interface);	minor = dev->scn_minor;	if (dev->bulk_in_buffer != NULL)		kfree (dev->bulk_in_buffer);	if (dev->bulk_out_buffer != NULL)   		kfree (dev->bulk_out_buffer);	if (dev->write_urb != NULL)		usb_free_urb (dev->write_urb);    db("disconnect_snusb: De-allocating minor:%d\n", minor);    up (&dev->sem);    /* remove our devfs node */	devfs_unregister(dev->devfs);	//unregister_chrdev(128, "snusb");		minor_table[minor] =NULL; 	/* if the device is not opened, then we clean up right now */	dev->scn_dev = NULL;	kfree (dev);	up (&minor_table_mutex);}int init_module(void){	printk ("<1>SnUsb Init module");    if (usb_register(&sn_driver) < 0)	{		printk ("error to registry");        return -1;	}	//info(DRIVER_VERSION ":" DRIVER_DESC "\n");	printk ("<1>Sinodata Usb Driver V2.0 \n");	return 0;}void cleanup_module(void){	printk ("<1>SnUsb Exit module");	usb_deregister(&sn_driver);}

⌨️ 快捷键说明

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