1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
| #include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <asm/current.h>
#include <asm/uaccess.h>
#define ID_VENDOR 0x2102
#define ID_PRODUCT 0x3046
MODULE_AUTHOR("dillinger,r.zenine@hotmail.Com");
MODULE_DESCRIPTION("dataman usb irda");
MODULE_SUPPORTED_DEVICE("0x2102,0x3046");
MODULE_LICENSE("GPL");
int test_probe (struct usb_interface *intf,const struct usb_device_id *id);
void test_disconnect (struct usb_interface *intf);
int test_open(struct inode *inode,struct file *filp);
int test_release(struct inode *inode,struct file *filp);
struct usb_priv
{
char* mess;
struct usb_device *udev;
wait_queue_head_t readwait;
struct urb *test_urb;
int plugged;
int opened;
};
struct usb_priv* ppriv=NULL;
static struct usb_device_id ID_Table[] = {
{USB_DEVICE(ID_VENDOR,ID_PRODUCT)},
{},
};
MODULE_DEVICE_TABLE(usb,ID_Table);
static struct usb_driver test_driver = {
.name = "irda usb",
.id_table = ID_Table,
.probe = test_probe,
.disconnect = test_disconnect,
};
struct file_operations test_fops={
.open = test_open,
.release = test_release,
};
struct usb_class_driver test_class ={
.name = "irda usb",
.fops = &test_fops,
.minor_base=0,
};
void test_read_interupt2(unsigned long param)
{
wake_up_interruptible(&(ppriv->readwait));
}
DECLARE_TASKLET(read_tasklet,test_read_interupt2,0);
void test_read_interupt1(struct urb *ptr)
{
tasklet_schedule(&read_tasklet);
}
int test_probe (struct usb_interface *intf,const struct usb_device_id *id)
{
int retval;
printk(KERN_DEBUG"data usb :entrée dans probe\n");
ppriv->udev=interface_to_usbdev(intf);
if(ppriv->udev->descriptor.iManufacturer != 1 || ppriv->udev->descriptor.idVendor != 0x2102)
{
printk(KERN_DEBUG"data usb : erreur lors de la verification des identifiants\n");
return -1;
}
retval = usb_register_dev(intf,&test_class);
printk(KERN_DEBUG"data usb retval:%d\n",retval);
if (retval==-EINVAL)
{
printk(KERN_DEBUG"usb test :no able to get minor for this interface\n");
usb_set_intfdata(intf,NULL);
return retval;
}
(ppriv->plugged)++;
return 0;
}
void test_disconnect (struct usb_interface *intf)
{
int minor = intf->minor;
printk(KERN_DEBUG"data usb :entrée dans probe\n");
lock_kernel();
usb_set_intfdata(intf,NULL);
usb_deregister_dev(intf,&test_class);
unlock_kernel();
printk (KERN_DEBUG"test_usb %d :diconnected\n",minor);
}
int test_open(struct inode *inode,struct file *filp)
{
int res;
if(ppriv->plugged==0){ return -ENODEV;}
printk(KERN_DEBUG"data usb :entrée dans open\n");
if(ppriv->opened ==0)
{
ppriv->test_urb=usb_alloc_urb(0,GFP_KERNEL);
if(ppriv->test_urb==0)
{
printk(KERN_DEBUG"data usb :echec d'allocation urb\n");
return -1;
}
usb_fill_int_urb(ppriv->test_urb,ppriv->udev,usb_rcvintpipe(ppriv->udev,0x81),(void*) ppriv->mess,8,test_read_interupt1,ppriv,0x01);
res=usb_submit_urb(ppriv->test_urb,GFP_KERNEL);
if(res!=0)
{
printk(KERN_DEBUG"data usb :allocation urb impossible erreur n%d\n",res);
return -1;
}
else {printk(KERN_DEBUG"data usb :allocation urb OK\n");}
(ppriv->opened)++;
return 0;
}
return 0;
}
int test_release(struct inode *inode,struct file *filp)
{
printk(KERN_DEBUG"data usb :entrée dans release\n");
(ppriv->opened)--;
if(ppriv->opened==0){usb_unlink_urb(ppriv->test_urb);}
return 0;
}
ssize_t test_read(struct file *filp,char* buf,size_t count,loff_t* pos)
{
printk(KERN_DEBUG"data usb :entrée dans read\n");
interruptible_sleep_on(&(ppriv->readwait));
if(copy_to_user(buf,ppriv->mess,ppriv->test_urb->actual_length)!=0){return -EFAULT;}
return (ppriv->test_urb->actual_length);
} |
Partager