Hi, The attached patch removes vicam.c's proc interface and replaces it with a driverfs file called shutter_speed through which the shutter speed can be changed for each device.
This patch also removes the usb_put_dev call from the disconnect routine as well as adding the up call for the busy mutex that I forgot in my previous patch to the read function. I saw some discussion as to whether we want to break V4L "standard" by removing the proc interface, but the driverfs interface provides what was required of the proc interface: shutter_speed to be settable for each attached camera individually by a shell utility such as echo. If we want to wait, fine, otherwise please apply. Patch is against the current usb 2.5 bk tree Thanks, John --- linux-current/drivers/usb/media/vicam.c 2002-10-22 20:41:04.000000000 -0700 +++ linux-vicam/drivers/usb/media/vicam.c 2002-10-22 20:48:28.000000000 -0700 @@ -38,7 +38,7 @@ #include <linux/usb.h> #include <linux/vmalloc.h> #include <linux/slab.h> -#include <linux/proc_fs.h> +#include <linux/device.h> #include "usbvideo.h" // #define VICAM_DEBUG @@ -403,7 +403,7 @@ } vfree(mem); } - + struct vicam_camera { u16 shutter_speed; // capture shutter speed u16 gain; // capture gain @@ -420,13 +420,55 @@ u8 open_count; u8 bulkEndpoint; bool needsDummyRead; +}; -#ifdef CONFIG_PROC_FS - struct proc_dir_entry *proc_entry; -#endif +ssize_t vicam_shutter_show(struct device *dev, + char *buf, + size_t count, + loff_t off) +{ + + struct vicam_camera *cam; + MOD_INC_USE_COUNT; -}; + cam = dev_get_drvdata(dev); + count = off ? 0 : snprintf(buf, count, "%hu\n", cam->shutter_speed); + + MOD_DEC_USE_COUNT; + + return count; +} + +ssize_t vicam_shutter_store(struct device *dev, + const char *buf, + size_t count, + loff_t off) +{ + struct vicam_camera *cam = dev_get_drvdata(dev); + unsigned long value = simple_strtoul(buf, NULL,0); + + MOD_INC_USE_COUNT; + + cam = dev_get_drvdata(dev); + value = simple_strtoul(buf, NULL,0); + + if (value <= 4 || value >= 31500) { + count = -EINVAL; + } else { + cam->shutter_speed = (u16)(value); + cam->needsDummyRead = 1; + } + + MOD_DEC_USE_COUNT; + + return count; +} +static DEVICE_ATTR(shutter_speed, + S_IRUGO | S_IWUSR, + vicam_shutter_show, + vicam_shutter_store); + static int vicam_probe( struct usb_interface *intf, const struct usb_device_id *id); static void vicam_disconnect(struct usb_interface *intf); static void read_frame(struct vicam_camera *cam, int framenum); @@ -989,6 +1031,7 @@ if (*ppos >= VICAM_MAX_FRAME_SIZE) { *ppos = 0; + up(&cam->busy_lock); return 0; } @@ -1066,147 +1109,6 @@ return 0; } -#ifdef CONFIG_PROC_FS - -static struct proc_dir_entry *vicam_proc_root = NULL; - -static int -vicam_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *out = page; - int len; - struct vicam_camera *cam = (struct vicam_camera *) data; - - out += - sprintf(out, "Vicam-based WebCam Linux Driver.\n"); - out += sprintf(out, "(c) 2002 Joe Burks ([EMAIL PROTECTED])\n"); - out += sprintf(out, "vicam stats:\n"); - out += sprintf(out, " Shutter Speed: 1/%d\n", cam->shutter_speed); - out += sprintf(out, " Gain: %d\n", cam->gain); - - len = out - page; - len -= off; - if (len < count) { - *eof = 1; - if (len <= 0) - return 0; - } else - len = count; - - *start = page + off; - return len; -} - -static int -vicam_write_proc(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - char *in; - char *start; - struct vicam_camera *cam = (struct vicam_camera *) data; - - in = kmalloc(count + 1, GFP_KERNEL); - if (!in) - return -ENOMEM; - - in[count] = 0; // I'm not sure buffer is gauranteed to be null terminated - // so I do this to make sure I have a null in there. - - strncpy(in, buffer, count); - - start = strstr(in, "gain="); - if (start - && (start == in || *(start - 1) == ' ' || *(start - 1) == ',')) - cam->gain = simple_strtoul(start + 5, NULL, 10); - - start = strstr(in, "shutter="); - if (start - && (start == in || *(start - 1) == ' ' || *(start - 1) == ',')) - cam->shutter_speed = simple_strtoul(start + 8, NULL, 10); - - kfree(in); - return count; -} - -void -vicam_create_proc_root(void) -{ - vicam_proc_root = create_proc_entry("video/vicam", S_IFDIR, 0); - - if (vicam_proc_root) - vicam_proc_root->owner = THIS_MODULE; - else - printk(KERN_ERR - "could not create /proc entry for vicam!"); -} - -void -vicam_destroy_proc_root(void) -{ - if (vicam_proc_root) - remove_proc_entry("video/vicam", 0); -} - -void -vicam_create_proc_entry(void *ptr) -{ - struct vicam_camera *cam = (struct vicam_camera *) ptr; - - char name[7]; - struct proc_dir_entry *ent; - - DBG(KERN_INFO "vicam: creating proc entry\n"); - - if (!vicam_proc_root || !cam) { - printk(KERN_INFO - "vicam: could not create proc entry, %s pointer is null.\n", - (!cam ? "camera" : "root")); - return; - } - - sprintf(name, "video%d", cam->vdev.minor); - - ent = - create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR, - vicam_proc_root); - if (!ent) - return; - - ent->data = cam; - ent->read_proc = vicam_read_proc; - ent->write_proc = vicam_write_proc; - ent->size = 512; - cam->proc_entry = ent; -} - -void -vicam_destroy_proc_entry(void *ptr) -{ - struct vicam_camera *cam = (struct vicam_camera *) ptr; - char name[7]; - - if (!cam || !cam->proc_entry) - return; - - sprintf(name, "video%d", cam->vdev.minor); - remove_proc_entry(name, vicam_proc_root); - cam->proc_entry = NULL; - -} - -#endif - -int -vicam_video_init(struct video_device *vdev) -{ - // This would normally create the proc entry for this camera -#ifdef CONFIG_PROC_FS - vicam_create_proc_entry(vdev->priv); -#endif - return 0; -} - static struct file_operations vicam_fops = { .owner = THIS_MODULE, .open = vicam_open, @@ -1256,7 +1158,8 @@ const struct usb_interface_descriptor *interface; const struct usb_endpoint_descriptor *endpoint; struct vicam_camera *cam; - + int err; + /* See if the device offered us matches what we can accept */ if ((dev->descriptor.idVendor != USB_VICAM_VENDOR_ID) || (dev->descriptor.idProduct != USB_VICAM_PRODUCT_ID)) { @@ -1300,6 +1203,12 @@ cam->udev = dev; cam->bulkEndpoint = bulkEndpoint; + err = device_create_file(&intf->dev, &dev_attr_shutter_speed); + if (err) { + kfree(cam); + return err; + } + if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1) == -1) { kfree(cam); printk(KERN_WARNING "video_register_device failed\n"); @@ -1319,16 +1228,13 @@ struct vicam_camera *cam = dev_get_drvdata(&intf->dev); dev_set_drvdata ( &intf->dev, NULL ); - usb_put_dev(cam->udev); cam->udev = NULL; + + device_remove_file(&intf->dev, &dev_attr_shutter_speed); video_unregister_device(&cam->vdev); -#ifdef CONFIG_PROC_FS - vicam_destroy_proc_entry(cam); -#endif - if (cam->raw_image) kfree(cam->raw_image); if (cam->framebuf) @@ -1346,9 +1252,6 @@ usb_vicam_init(void) { DBG(KERN_INFO "ViCam-based WebCam driver startup\n"); -#ifdef CONFIG_PROC_FS - vicam_create_proc_root(); -#endif if (usb_register(&vicam_driver) != 0) printk(KERN_WARNING "usb_register failed!\n"); return 0; @@ -1361,9 +1264,6 @@ "ViCam-based WebCam driver shutdown\n"); usb_deregister(&vicam_driver); -#ifdef CONFIG_PROC_FS - vicam_destroy_proc_root(); -#endif } module_init(usb_vicam_init); ------------------------------------------------------- This sf.net emial is sponsored by: Influence the future of Java(TM) technology. Join the Java Community Process(SM) (JCP(SM)) program now. http://ad.doubleclick.net/clk;4699841;7576301;v?http://www.sun.com/javavote _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel