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

📄 usbdrv.c

📁 usb接口的scanner的驱动,稍加修改就可以使用了. 测试过了,可以使用
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************                          usbdrv.cpp  -  description                             -------------------    begin                : 五  9月 9 2005    copyright            : (C) 2005 by root    email                : root@localhost.localdomain ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/#define __KERNEL__#define MODULE#include <linux/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <asm/uaccess.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/delay.h>#include <linux/ioctl.h>#include <linux/fs.h>#include <linux/sched.h>#include <linux/smp_lock.h>#include <linux/devfs_fs_kernel.h>#include <linux/config.h>#include <linux/mm.h>#include <linux/slab.h>//#include <linux/devfs_fs_kernel.h>#include <linux/version.h>#include <linux/usb.h>//#define DEBUG//#ifdef DEBUG	#define db printk   //#define warn printk //  #define err printk//#else	//#define db dbg//#endif#define USB_SN_VENDOR_ID      0x7890#define USB_SN_PRODUCT_ID     0x0002/* Get a minor range for your devices from the usb maintainer */#define SCN_BASE_MNR     128/* we can have up to this number of device plugged in at once */#define MAX_DEVICES             16#define IBUF_SIZE 16384*2//32768#define OBUF_SIZE 4096#define CMD_READ_STATE		6#define CMD_READ_DATA			8#define IS_EP_BULK(ep)  ((ep).bmAttributes == USB_ENDPOINT_XFER_BULK ? 1 : 0)#define IS_EP_BULK_IN(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)#define IS_EP_BULK_OUT(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)#define IS_EP_INTR(ep) ((ep).bmAttributes == USB_ENDPOINT_XFER_INT ? 1 : 0)#define USB_SN_MINOR(X) MINOR((X)->i_rdev) - SCN_BASE_MNR#define SNUSB_IOCTL_READ_STATUS _IOWR('U', 0x26, void*)#define SNUSB_IOCTL_USER_CODE _IOWR('U', 0x27, void*)#define ENDPOINT_IN     0x2#define ENDPOINT_OUT 0x0#define ENDPOINT_INIR 0x1//#define COMPANY "SinoData"//#define DESCRIPTION  "SinoData Usb Linux Driver by HP"MODULE_AUTHOR("SinoData");MODULE_DESCRIPTION("SinoData Usb Linux Driver by HP");MODULE_LICENSE("GPL");int ibuf_size=IBUF_SIZE;struct scn_usb_data {	struct usb_device *scn_dev;	devfs_handle_t devfs;	/* devfs device */	struct usb_interface* interface;	struct urb* write_urb;	unsigned int ifnum;	/* Interface number of the USB device */	kdev_t scn_minor;	/* sn minor - used in disconnect() */	unsigned char button;	/* Front panel buffer */	char isopen;		/* Not zero if the device is open */	char present;		/* Not zero if device is present */	char *bulk_out_buffer;	char *bulk_in_buffer;	/* transfer buffers */	char bulk_in_ep;	char bulk_out_ep;	char intr_ep; /* Endpoint assignments */	int    bulk_in_size;	int    bulk_out_size;	int    open_count;	wait_queue_head_t rd_wait_q; /* read timeouts */	struct semaphore sem; /* lock to prevent concurrent reads or writes */	unsigned int rd_nak_timeout; /* Seconds to wait before read() timeout. */};/* the global usb devfs handle */extern devfs_handle_t usb_devfs_handle;static struct scn_usb_data  *minor_table[MAX_DEVICES];/* lock to protect the minor_table structure */static DECLARE_MUTEX (minor_table_mutex);static struct usb_device_id sn_table [] ={		//{USB_DEVICE(0x7890,0x0002)},		{USB_DEVICE(USB_SN_VENDOR_ID, USB_SN_PRODUCT_ID)},		{}};MODULE_DEVICE_TABLE (usb, sn_table);////////////////////////-----------------------------------------------------------------static void usb_show_endpoint(struct usb_endpoint_descriptor *endpoint)/* [<][>][^][v][top][bottom][index][help] */{        usb_show_endpoint_descriptor(endpoint);}static void usb_show_interface(struct usb_interface_descriptor *altsetting)/* [<][>][^][v][top][bottom][index][help] */{        int i;        usb_show_interface_descriptor(altsetting);        for (i = 0; i < altsetting->bNumEndpoints; i++)                usb_show_endpoint(altsetting->endpoint + i);}static void usb_show_config(struct usb_config_descriptor *config)/* [<][>][^][v][top][bottom][index][help] */{        int i, j;        struct usb_interface *ifp;        usb_show_config_descriptor(config);        for (i = 0; i < config->bNumInterfaces; i++) {                ifp = config->interface + i;                if (!ifp)                        break;                printk("\n  Interface: %d\n", i);                for (j = 0; j < ifp->num_altsetting; j++)                        usb_show_interface(ifp->altsetting + j);        }}void usb_show_device(struct usb_device *dev)/* [<][>][^][v][top][bottom][index][help] */{        int i;        usb_show_device_descriptor(&dev->descriptor);        for (i = 0; i < dev->descriptor.bNumConfigurations; i++)                usb_show_config(dev->config + i);}/* * Parse and show the different USB descriptors. */void usb_show_device_descriptor(struct usb_device_descriptor *desc)/* [<][>][^][v][top][bottom][index][help] */{        if (!desc)        {                db("Invalid USB device descriptor (NULL POINTER)\n");                return;        }        db("  Length              = %2d%s\n", desc->bLength,                desc->bLength == USB_DT_DEVICE_SIZE ? "" : " (!!!)");        db("  DescriptorType      = %02x\n", desc->bDescriptorType);        db("  USB version         = %x.%02x\n",                desc->bcdUSB >> 8, desc->bcdUSB & 0xff);        db("  Vendor:Product      = %04x:%04x\n",                desc->idVendor, desc->idProduct);        db("  MaxPacketSize0      = %d\n", desc->bMaxPacketSize0);        db("  NumConfigurations   = %d\n", desc->bNumConfigurations);        db("  Device version      = %x.%02x\n",                desc->bcdDevice >> 8, desc->bcdDevice & 0xff);        db("  Device Class:SubClass:Protocol = %02x:%02x:%02x\n",                desc->bDeviceClass, desc->bDeviceSubClass, desc->bDeviceProtocol);        switch (desc->bDeviceClass) {        case 0:                db("    Per-interface classes\n");                break;        case USB_CLASS_AUDIO:                db("    Audio device class\n");                break;        case USB_CLASS_COMM:                db("    Communications class\n");                break;        case USB_CLASS_HID:                db("    Human Interface Devices class\n");                break;        case USB_CLASS_PRINTER:                db("    Printer device class\n");                break;        case USB_CLASS_MASS_STORAGE:                db("    Mass Storage device class\n");                break;        case USB_CLASS_HUB:                db("    Hub device class\n");                break;        case USB_CLASS_VENDOR_SPEC:                db("    Vendor class\n");                break;        default:                db("    Unknown class\n");        }}void usb_show_config_descriptor(struct usb_config_descriptor *desc)/* [<][>][^][v][top][bottom][index][help] */{        db("Configuration:\n");        db("  bLength             = %4d%s\n", desc->bLength,                desc->bLength == USB_DT_CONFIG_SIZE ? "" : " (!!!)");        db("  bDescriptorType     =   %02x\n", desc->bDescriptorType);        db("  wTotalLength        = %04x\n", desc->wTotalLength);        db("  bNumInterfaces      =   %02x\n", desc->bNumInterfaces);        db("  bConfigurationValue =   %02x\n", desc->bConfigurationValue);        db("  iConfiguration      =   %02x\n", desc->iConfiguration);        db("  bmAttributes        =   %02x\n", desc->bmAttributes);        db("  MaxPower            = %4dmA\n", desc->MaxPower * 2);}void usb_show_interface_descriptor(struct usb_interface_descriptor *desc)/* [<][>][^][v][top][bottom][index][help] */{        db("  Alternate Setting: %2d\n", desc->bAlternateSetting);        db("    bLength             = %4d%s\n", desc->bLength,                desc->bLength == USB_DT_INTERFACE_SIZE ? "" : " (!!!)");        db("    bDescriptorType     =   %02x\n", desc->bDescriptorType);        db("    bInterfaceNumber    =   %02x\n", desc->bInterfaceNumber);        db("    bAlternateSetting   =   %02x\n", desc->bAlternateSetting);        db("    bNumEndpoints       =   %02x\n", desc->bNumEndpoints);        db("    bInterface Class:SubClass:Protocol =   %02x:%02x:%02x\n",                desc->bInterfaceClass, desc->bInterfaceSubClass, desc->bInterfaceProtocol);        db("    iInterface          =   %02x\n", desc->iInterface);}void usb_show_endpoint_descriptor(struct usb_endpoint_descriptor *desc)/* [<][>][^][v][top][bottom][index][help] */{        char *LengthCommentString = (desc->bLength ==                USB_DT_ENDPOINT_AUDIO_SIZE) ? " (Audio)" : (desc->bLength ==                USB_DT_ENDPOINT_SIZE) ? "" : " (!!!)";        char *EndpointType[4] = { "Control", "Isochronous", "Bulk", "Interrupt" };        db("    Endpoint:\n");        db("      bLength             = %4d%s\n",                desc->bLength, LengthCommentString);        db("      bDescriptorType     =   %02x\n", desc->bDescriptorType);        db("      bEndpointAddress    =   %02x (%s)\n", desc->bEndpointAddress,                (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==                        USB_ENDPOINT_XFER_CONTROL ? "i/o" :                (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ? "in" : "out");        db("      bmAttributes        =   %02x (%s)\n", desc->bmAttributes,                EndpointType[USB_ENDPOINT_XFERTYPE_MASK & desc->bmAttributes]);        db("      wMaxPacketSize      = %04x\n", desc->wMaxPacketSize);        db("      bInterval           =   %02x\n", desc->bInterval);        /* Audio extensions to the endpoint descriptor */        if (desc->bLength == USB_DT_ENDPOINT_AUDIO_SIZE) {                db("      bRefresh            =   %02x\n", desc->bRefresh);                db("      bSynchAddress       =   %02x\n", desc->bSynchAddress);        }}void usb_show_string(struct usb_device *dev, char *id, int index)/* [<][>][^][v][top][bottom][index][help] */{        char *buf;        if (!index)                return;        if (!(buf = kmalloc(256, GFP_KERNEL)))                return;        if (usb_string(dev, index, buf, 256) > 0)                printk(KERN_INFO "%s: %s\n", id, buf);        kfree(buf);}/*void usb_dump_urb (purb_t purb){        printk ("urb                   :%p\n", purb);        printk ("next                  :%p\n", purb->next);        printk ("dev                   :%p\n", purb->dev);        printk ("pipe                  :%08X\n", purb->pipe);        printk ("status                :%d\n", purb->status);        printk ("transfer_flags        :%08X\n", purb->transfer_flags);        printk ("transfer_buffer       :%p\n", purb->transfer_buffer);        printk ("transfer_buffer_length:%d\n", purb->transfer_buffer_length);        printk ("actual_length         :%d\n", purb->actual_length);        printk ("setup_packet          :%p\n", purb->setup_packet);        printk ("start_frame           :%d\n", purb->start_frame);        printk ("number_of_packets     :%d\n", purb->number_of_packets);        printk ("interval              :%d\n", purb->interval);        printk ("error_count           :%d\n", purb->error_count);        printk ("context               :%p\n", purb->context);        printk ("complete              :%p\n", purb->complete);} *///////--------------------------------------------------------static void sn_write_bulk_callback (struct urb *urb){        struct usb_skel *dev = (struct usb_skel *)urb->context;        dbg(__FUNCTION__ " - minor %d", dev->minor);        if ((urb->status != -ENOENT) &&            (urb->status != -ECONNRESET)) {                dbg(__FUNCTION__ " - nonzero write bulk status received: %d",                    urb->status);                return;        }        return;}static int sn_open (struct inode *inode, struct file *file){        struct scn_usb_data *dev = NULL;        int subminor;        int retval = 0;        db("SINODATA_HP_OPEN :Begin Open Function");        dbg(__FUNCTION__);        subminor = MINOR (inode->i_rdev) - SCN_BASE_MNR;        if ((subminor < 0) || (subminor >= MAX_DEVICES))		{	        db("SINODATA_HP_OPEN :minor %d error", subminor);			return -ENODEV;        }		db("SINODATA_HP_OPEN :minor %d ", subminor);        /* Increment our usage count for the module.         * This is redundant here, because "struct file_operations"         * has an "owner" field. This line is included here soley as         * a reference for drivers using lesser structures... ;-)         */		MOD_INC_USE_COUNT;        /* lock our minor table and get our local data for this minor */        down (&minor_table_mutex);        dev = minor_table[subminor];        if (dev == NULL)		{                up (&minor_table_mutex);				db("SINODATA_HP_OPEN :No device data");                MOD_DEC_USE_COUNT;                return -ENODEV;        }        /* lock this device */        down (&dev->sem);        /* unlock the minor table */        up (&minor_table_mutex);		if (!dev->present)		{			db ("SINODATA_HP_OPEN :Device is not present!");			up (&dev->sem);			MOD_DEC_USE_COUNT;			return -ENODEV;		}		db ("SINODATA_HP_OPEN :Device is present!");		if (dev->isopen)		{			db("SINODATA_HP_OPEN :Device is opened before!");			up (&dev->sem);			MOD_DEC_USE_COUNT;			return -EBUSY;		}        /* increment our usage count for the driver */        ++dev->open_count;       db ("SINODATA_HP_OPEN :Device open count is %d", dev->open_count);        /* save our object in the file's private structure */        file->private_data = dev;		usb_reset_device ((struct usb_device*)dev);        /* unlock this device */        up (&dev->sem);

⌨️ 快捷键说明

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