write usb drive from scratch but facing problem in reading (writing not implented)
Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
write usb drive from scratch but facing problem in reading (writing not implented)
Purpose: i want to write my usb driver to read data from the Flash drive.
Fedora Version is 17 with kernel 3.3.4-5.fc17.x86_64
Problem: facing problem to read data from usb.
Code:
#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");
No, you did NOT...your original post isn't wrapped in CODE tags, as requested. Further, you haven't actually asked a question. Just saying "facing problem" tells us nothing...you don't say what version/distro of Linux, what kind of hardware, architecture, etc., or what your actual goal is. We can't guess.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.