c - Linux USB driver with multiple read operations, ioctl or fops? -
i writing driver usb device has 3 different read/write operations (flash, eeprom, , i2c), each different implementation. i've been scratching head this, since i'm new whole world of linux kernel development. i've read should avoid ioctl @ costs, cannot tell how implement this. since in linux file, create multiple endpoints write each location? how go doing this? define multiple usb_class_driver structs?
on flip side, should include functionality in single endpoint , use ioctl? better split work same driver or consolidate functionality in 1 place?
i cannot use libusb due limitations on isochronous transfers , lack of direct control on dma transfers (both needed product final product).
update: after trying use multiple generic file operations each endpoint , getting response code of -98 (already registered), think going have use single endpoint ioctl. code isn't working follows:
in adriver.h
static struct usb_class_driver adriver_eeprom_class = { .name = "usb/adriver_eeprom%d", .fops = &adriver_eeprom_fops, .minor_base = usb_skel_minor_base, }; static struct usb_class_driver adriver_flash_class = { .name = "usb/adriver_flash%d", .fops = &adriver_flash_fops, .minor_base = usb_skel_minor_base, }; static struct usb_class_driver adriver_i2c_class = { .name = "usb/adriver_i2c%d", .fops = &adriver_i2c_fops, .minor_base = usb_skel_minor_base, }; static struct usb_class_driver driver_fifo_class = { .name = "usb/driver_fifo%d", .fops = &driver_fifo_fops, .minor_base = usb_skel_minor_base, }; static struct usb_class_driver adriver_class = { .name = "usb/adriver%d", .fops = &adriver_fops, .minor_base = usb_skel_minor_base, }; in adriver.c
static int adriver_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(interface); struct usb_adriver *gdev; int retval = -enomem; gdev = kmalloc(sizeof(struct usb_adriver), gfp_kernel); if(gdev == null) { dev_err(&interface->dev, "out of memory\n"); goto error; } memset(gdev, 0x00, sizeof(*gdev)); kref_init(&gdev->kref); gdev->udev = usb_get_dev(udev); usb_set_intfdata(interface,gdev); retval = usb_register_dev(interface, &adriver_eeprom_class); if (retval) { /* prevented registering driver */ pr_err("not able minor device."); usb_set_intfdata(interface, null); goto error; } retval = usb_register_dev(interface, &adriver_flash_class); if (retval) { /* prevented registering driver */ pr_err("not able minor device."); usb_set_intfdata(interface, null); goto error; } retval = usb_register_dev(interface, &adriver_i2c_class); if (retval) { /* prevented registering driver */ pr_err("not able minor device."); usb_set_intfdata(interface, null); goto error; } retval = usb_register_dev(interface, &adriver_fifo_class); if (retval) { /* prevented registering driver */ pr_err("not able minor device."); usb_set_intfdata(interface, null); goto error; } retval = usb_register_dev(interface, &adriver_class); if (retval) { /* prevented registering driver */ pr_err("not able minor device."); usb_set_intfdata(interface, null); goto error; } dev_info(&interface->dev, "usb adriver device attached\n"); return 0; error: if (gdev) kref_put(&gdev->kref, adriver_delete); return retval; }
the device driver can create 3 devices proposed. if there single irq on device, model more apropos.
with bit of luck , skill (probably more of latter), driver's read , write routines need implemented 1 function read , 1 write parameter passed, or read/write routine infers device inspecting struct file * parameter (if named f, minor(f -> f_dentry -> d_inode -> i_rdev) gives device's minor device i.d. since control minor device assignment in probe() function device_create(), can leverage have useful type information associated.
in way, easy avoid ioctl should avoided simple read , write operations. makes easy use device bash scripts, command line, etc. if ioctl involved, means programming language required use it.
man page ioctl() says
the [ioctl] call used catch-all operations don't cleanly fit unix stream i/o model.
Comments
Post a Comment