LQ Newbie
Registered: May 2016
Posts: 6
Rep:
|
read write failed
this is my code . simple to understand . But as given in all the article the usb_bulk_msg is able to read. But i got -110 . may be i am sending raw data, but the device is a pen drive and expect data in the scsi format.
CAN ANYONE HELP How to read data from the pendrive
#include<linux/module.h> /* to run printk etc */
#include<linux/kernel.h> /* for the module related task mean to make the device driver to act as the module */
#include<linux/usb.h> /* contain the usb related function */
#include<linux/fs.h> /* for the file operations */
#include<linux/slab.h> /* for the kmalloc */
#define ENDPT_IN 0x02
#define ENDPT_OUT 0x81
#define MAX_PKT_SIZE 512
#define TELE_MINOR_BASE 0xAB
static unsigned char bulk_buf[MAX_PKT_SIZE];
static struct usb_driver pen_drive;
static struct usb_class_driver class;
/* this is the usb_skel structure called as the skelton structure of the USb device. The imformation about the USB device will be gathered into this structure so that these values can be use later*/
struct usb_skel{
/* struct usb device for this device */
struct usb_device *udev;
/* the buffer to read data with */
unsigned char *bulk_in_buffer;
/* address of the bulk in endpoint */
__u8 bulk_in_endpointAddr;
/* address of the bulk out endpoint */
__u8 bulk_out_endpointAddr;
/* size of the Receivved buffer*/
ssize_t bulk_in_size;
struct usb_interface *interface;
};
int pen_open(struct inode *inode, struct file *fp)
{
/* this is the open function here first we findout the
* interface using the minor number and the usb device
* then populate the usb device using the get interface
* data
*/
struct usb_interface *intf;
struct usb_skel *dev;
int subminor = 0;
printk(KERN_INFO"Pen drive open function\n");
subminor = iminor(inode);
printk(KERN_INFO"minor = %d\n", subminor);
intf = usb_find_interface(&pen_drive, subminor);
if(!intf)
{
printk(KERN_INFO"interface is not present\n");
}
printk(KERN_INFO"interface = %x\n", intf);
dev = usb_get_intfdata(intf);
if(!dev)
{
printk(KERN_INFO"usb device is not present\n");
}
#if 0
printk(KERN_INFO"dev->in endpoint address = %x\n", dev->bulk_in_endpointAddr);
printk(KERN_INFO"dev->out endpoint address = %x\n", dev->bulk_out_endpointAddr);
#endif
fp->private_data = dev;
return 0;
}
int pen_release(struct inode *inode, struct file *fp)
{
printk(KERN_INFO"Pen drive release function\n");
return 0;
}
ssize_t pen_read (struct file *fp, char __user *buffer, size_t size, loff_t *loff)
{
int read_count = 0;
int retval = 0;
struct usb_skel *dev = fp->private_data;
printk(KERN_INFO"Pen drive read function\n");
retval = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr), dev->bulk_in_buffer, MAX_PKT_SIZE, &read_count, 5000);
if(retval)
{
printk(KERN_ERR"usb_bulk_msg retval = %d\n", retval);
retval = copy_to_user(buffer, bulk_buf, size);
if(retval)
{
printk(KERN_INFO"retvall = %d\n", retval);
return -EFAULT;
}
}
printk(KERN_INFO"retval = %d\n", retval);
printk(KERN_INFO"buffer = %s\n", dev->bulk_in_buffer);
printk(KERN_INFO"count = %d\n", read_count);
return size;
}
ssize_t pen_write (struct file *fp, const char __user *buffer, size_t size, loff_t *loff)
{
printk(KERN_INFO"Pen drive write function\n");
}
struct file_operations fops = {
.open = pen_open,
.release = pen_release,
.read = pen_read,
.write = pen_write
};
static struct usb_class_driver tele_class = {
.name = "pen0",
.fops = &fops, /* Connect with /dev/tele */
.minor_base = TELE_MINOR_BASE, /* Minor number start */
};
int pen_probe(struct usb_interface *intf, const struct usb_device_id *id){
struct usb_skel *dev = kzalloc(sizeof(struct usb_skel), GFP_KERNEL);
struct usb_host_interface *iface;
struct usb_endpoint_descriptor *ept;
int i;
int retval;
int buffer_size;
/* for the use of the usb data the usb data is being converted
* into the usb device structure format, because by this the
* data can be transfered to many function*/
dev = kzalloc(sizeof(struct usb_skel), GFP_KERNEL);
/* the interface_to_usbdev give the same devie address
* here but in the usb-skeleton.c the usb_get_dev is
* used which give the same device address. so i am
* not using the extra functionm
dev->udev = usb_get_dev(interface_to_usbdev(intf));
*/
dev->udev = usb_get_dev(interface_to_usbdev(intf)) ;
/*
* filling the data into the local structure of mine that is
* the struct usb_skel
*/
dev->interface = intf;
iface = intf->cur_altsetting;
printk(KERN_INFO"pen probe function\n");
printk(KERN_DEBUG"interface = %p\n", intf);
printk(KERN_INFO"{product id:vendor id} = {%04x:%04x}\n", id->idProduct, id->idVendor);
#if 0
printk(KERN_INFO"dev->udev = %p\n", dev->udev);
#endif
for(i=0; i< iface->desc.bNumEndpoints; i++)
{
ept = &iface->endpoint[i].desc;
#if 0
printk(KERN_INFO"Endpoint[%d] Address = %x\n", i, ept->bEndpointAddress);
printk(KERN_INFO"packet size = %x\n", ept->wMaxPacketSize);
#endif
/*
* The below if condition is used to check wheather the
* endpoint is the IN Endpoint
*/
if(!dev->bulk_in_endpointAddr && usb_endpoint_is_bulk_in(ept))
{
printk(KERN_INFO"ept->EndpointAddres = %x is <In Endpoint Address>\n", ept->bEndpointAddress);
dev->bulk_in_endpointAddr = ept->bEndpointAddress;
/*maximu packet size that the endpoint can handle*/
buffer_size = ept->wMaxPacketSize;
dev->bulk_in_size = (unsigned char)buffer_size;
dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
if(!dev->bulk_in_buffer)
{
printk(KERN_ERR"usb device bulk in buffer is NULL\n");
}
}
if(!dev->bulk_out_endpointAddr && usb_endpoint_is_bulk_out(ept))
{
printk(KERN_INFO"ept->EndpointAddres = %x is <out Endpoint Address>\n", ept->bEndpointAddress);
dev->bulk_out_endpointAddr = ept->bEndpointAddress;
}
}
/*
* for the interface data that can be used later we will
* store it in our local structure
*/
usb_set_intfdata(intf, dev);
/* usb_register_dev is used to create a entry in the /dev directory. the entry is created as with the name pen0. Every time pen the pendrive get insert into thesystem then a pen drive entry created .*/
if((retval = usb_register_dev(intf, &tele_class)) < 0)
{
printk(KERN_INFO"usb_register_dev failed\n");
/* setting the interface to NULL*/
usb_set_intfdata(intf, NULL);
}
else
{
printk(KERN_INFO"Minor = %d\n", intf->minor);
}
printk(KERN_INFO"usb_register_dev retval = %d\n", retval);
return retval;
}
static void pen_disconnect (struct usb_interface *intf){
struct usb_skel *dev ;
printk(KERN_INFO" USB Device Removed\n");
/* The below function is the usb_deregister_dev(interface, class). it is used to clear the entry from the /dev directory. Note that if the usb_deregister_usb is not preset in the disconnect function, then every time the a new entry will be created in the /dev. ex pen0, pen1 etc.*/
dev = usb_get_intfdata(intf);
usb_set_intfdata(intf, NULL);
usb_deregister_dev(intf, &class);
dev->interface = NULL;
}
//idVendor 0x0781 SanDisk Corp.
//idProduct 0x5567 Cruzer Blade
//USB_DEVICE(vendor id, device id)
/* This is the device id structure, every time when the device with the vendor id 0781 nad product id 5567 is connected then this device driver get ivoked by the usb core
* if we want to register the same driver the in the usb_device_id enter the product id and the vendor id of the device.*/
const struct usb_device_id pen_id[] ={
{ USB_DEVICE(0x0781, 0x5567) },
{},
};
MODULE_DEVICE_TABLE(usb, pen_id);
static struct usb_driver pen_drive = {
.name = "Neeraj_USB_DRIVER",
.probe = pen_probe,
.disconnect = pen_disconnect,
.id_table = pen_id,
};
static int __init ped_init(void)
{
printk(KERN_INFO"Initialisation function\n");
usb_register(&pen_drive);
return 0;
}
static void __exit ped_exit(void)
{
printk(KERN_INFO"exit function\n");
usb_deregister(&pen_drive);
}
module_init(ped_init);
module_exit(ped_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("<Neeraj Dadhwal>");
MODULE_DESCRIPTION("USB Pen Driver Registration Driver");
|