Patch against 2.16.18-rc1 and relies on earlier patch for phidgetmotorcontrol.
From: Sean Young <[EMAIL PROTECTED]> This patch creates a class phidget and add the drivers to them. Signed-off-by: Sean Young <[EMAIL PROTECTED]> -- diff -urpN linux-2.6.16/drivers/usb/misc/Kconfig linux-2.6.16-mc/drivers/usb/misc/Kconfig --- linux-2.6.16/drivers/usb/misc/Kconfig 2006-07-09 22:40:42.000000000 +0100 +++ linux-2.6.16-mc/drivers/usb/misc/Kconfig 2006-07-09 16:06:14.000000000 +0100 @@ -115,9 +115,16 @@ config USB_CYTHERM To compile this driver as a module, choose M here: the module will be called cytherm. +config USB_PHIDGET + tristate "USB Phidgets drivers" + depends on USB + help + Say Y here to enable the various drivers for devices from + Phidgets inc. + config USB_PHIDGETKIT tristate "USB PhidgetInterfaceKit support" - depends on USB + depends on USB_PHIDGET help Say Y here if you want to connect a PhidgetInterfaceKit USB device from Phidgets Inc. @@ -127,7 +134,7 @@ config USB_PHIDGETKIT config USB_PHIDGETMOTORCONTROL tristate "USB PhidgetMotorControl support" - depends on USB + depends on USB_PHIDGET help Say Y here if you want to connect a PhidgetMotorControl USB device from Phidgets Inc. @@ -137,7 +144,7 @@ config USB_PHIDGETMOTORCONTROL config USB_PHIDGETSERVO tristate "USB PhidgetServo support" - depends on USB + depends on USB_PHIDGET help Say Y here if you want to connect an 1 or 4 Motor PhidgetServo servo controller version 2.0 or 3.0. diff -urpN linux-2.6.16/drivers/usb/misc/Makefile linux-2.6.16-mc/drivers/usb/misc/Makefile --- linux-2.6.16/drivers/usb/misc/Makefile 2006-07-09 22:40:42.000000000 +0100 +++ linux-2.6.16-mc/drivers/usb/misc/Makefile 2006-07-09 16:08:00.000000000 +0100 @@ -13,6 +13,7 @@ obj-$(CONFIG_USB_LCD) += usblcd.o obj-$(CONFIG_USB_LD) += ldusb.o obj-$(CONFIG_USB_LED) += usbled.o obj-$(CONFIG_USB_LEGOTOWER) += legousbtower.o +obj-$(CONFIG_USB_PHIDGET) += phidget.o obj-$(CONFIG_USB_PHIDGETKIT) += phidgetkit.o obj-$(CONFIG_USB_PHIDGETMOTORCONTROL) += phidgetmotorcontrol.o obj-$(CONFIG_USB_PHIDGETSERVO) += phidgetservo.o diff -urpN linux-2.6.16/drivers/usb/misc/phidget.c linux-2.6.16-mc/drivers/usb/misc/phidget.c --- linux-2.6.16/drivers/usb/misc/phidget.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.16-mc/drivers/usb/misc/phidget.c 2006-07-09 23:13:27.000000000 +0100 @@ -0,0 +1,43 @@ +/* + * USB Phidgets class + * + * Copyright (C) 2006 Sean Young <[EMAIL PROTECTED]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/err.h> +#include <linux/device.h> + +struct class *phidget_class; + +static int __init init_phidget(void) +{ + phidget_class = class_create(THIS_MODULE, "phidget"); + + if (IS_ERR(phidget_class)) + return PTR_ERR(phidget_class); + + return 0; +} + +static void __exit cleanup_phidget(void) +{ + class_destroy(phidget_class); +} + +EXPORT_SYMBOL_GPL(phidget_class); + +module_init(init_phidget); +module_exit(cleanup_phidget); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Sean Young <[EMAIL PROTECTED]>"); +MODULE_DESCRIPTION("Container module for phidget class"); + diff -urpN linux-2.6.16/drivers/usb/misc/phidget.h linux-2.6.16-mc/drivers/usb/misc/phidget.h --- linux-2.6.16/drivers/usb/misc/phidget.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.16-mc/drivers/usb/misc/phidget.h 2006-07-09 23:14:15.000000000 +0100 @@ -0,0 +1,12 @@ +/* + * USB Phidgets class + * + * Copyright (C) 2006 Sean Young <[EMAIL PROTECTED]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +extern struct class *phidget_class; diff -urpN linux-2.6.16/drivers/usb/misc/phidgetkit.c linux-2.6.16-mc/drivers/usb/misc/phidgetkit.c --- linux-2.6.16/drivers/usb/misc/phidgetkit.c 2006-07-08 12:23:06.000000000 +0100 +++ linux-2.6.16-mc/drivers/usb/misc/phidgetkit.c 2006-07-09 23:11:44.000000000 +0100 @@ -20,6 +20,8 @@ #include <linux/module.h> #include <linux/usb.h> +#include "phidget.h" + #define DRIVER_AUTHOR "Sean Young <[EMAIL PROTECTED]>" #define DRIVER_DESC "USB PhidgetInterfaceKit Driver" @@ -57,11 +59,15 @@ ifkit(8, 8, 4, 0); ifkit(0, 8, 8, 1); ifkit(0, 16, 16, 0); +static unsigned long device_no; + struct interfacekit { struct usb_device *udev; struct usb_interface *intf; struct driver_interfacekit *ifkit; + struct class_device *class_dev; unsigned long outputs; + int dev_no; u8 inputs[MAX_INTERFACES]; u16 sensors[MAX_INTERFACES]; u8 lcd_files_on; @@ -180,21 +186,20 @@ exit: } #define set_lcd_line(number) \ -static ssize_t lcd_line_##number(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ -{ \ - struct usb_interface *intf = to_usb_interface(dev); \ - struct interfacekit *kit = usb_get_intfdata(intf); \ - change_string(kit, buf, number - 1); \ - return count; \ -} \ -static DEVICE_ATTR(lcd_line_##number, S_IWUGO, NULL, lcd_line_##number); +static ssize_t lcd_line_##number(struct class_device *dev, \ + const char *buf, size_t count) \ +{ \ + struct interfacekit *kit = class_get_devdata(dev); \ + change_string(kit, buf, number - 1); \ + return count; \ +} \ +static CLASS_DEVICE_ATTR(lcd_line_##number, S_IWUGO, NULL, lcd_line_##number); set_lcd_line(1); set_lcd_line(2); -static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t set_backlight(struct class_device *dev, const char *buf, size_t count) { - struct usb_interface *intf = to_usb_interface(dev); - struct interfacekit *kit = usb_get_intfdata(intf); + struct interfacekit *kit = class_get_devdata(dev); int enabled; unsigned char *buffer; int retval = -ENOMEM; @@ -226,22 +231,21 @@ exit: kfree(buffer); return retval; } -static DEVICE_ATTR(backlight, S_IWUGO, NULL, set_backlight); +static CLASS_DEVICE_ATTR(backlight, S_IWUGO, NULL, set_backlight); static void remove_lcd_files(struct interfacekit *kit) { if (kit->lcd_files_on) { dev_dbg(&kit->udev->dev, "Removing lcd files\n"); - device_remove_file(&kit->intf->dev, &dev_attr_lcd_line_1); - device_remove_file(&kit->intf->dev, &dev_attr_lcd_line_2); - device_remove_file(&kit->intf->dev, &dev_attr_backlight); + class_device_remove_file(kit->class_dev, &class_device_attr_lcd_line_1); + class_device_remove_file(kit->class_dev, &class_device_attr_lcd_line_2); + class_device_remove_file(kit->class_dev, &class_device_attr_backlight); } } -static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t enable_lcd_files(struct class_device *dev, const char *buf, size_t count) { - struct usb_interface *intf = to_usb_interface(dev); - struct interfacekit *kit = usb_get_intfdata(intf); + struct interfacekit *kit = class_get_devdata(dev); int enable; if (kit->ifkit->has_lcd == 0) @@ -253,9 +257,9 @@ static ssize_t enable_lcd_files(struct d if (enable) { if (!kit->lcd_files_on) { dev_dbg(&kit->udev->dev, "Adding lcd files\n"); - device_create_file(&kit->intf->dev, &dev_attr_lcd_line_1); - device_create_file(&kit->intf->dev, &dev_attr_lcd_line_2); - device_create_file(&kit->intf->dev, &dev_attr_backlight); + class_device_create_file(kit->class_dev, &class_device_attr_lcd_line_1); + class_device_create_file(kit->class_dev, &class_device_attr_lcd_line_2); + class_device_create_file(kit->class_dev, &class_device_attr_backlight); kit->lcd_files_on = 1; } } else { @@ -267,7 +271,7 @@ static ssize_t enable_lcd_files(struct d return count; } -static DEVICE_ATTR(lcd, S_IWUGO, NULL, enable_lcd_files); +static CLASS_DEVICE_ATTR(lcd, S_IWUGO, NULL, enable_lcd_files); static void interfacekit_irq(struct urb *urb, struct pt_regs *regs) { @@ -375,11 +379,10 @@ static void do_notify(void *data) } #define show_set_output(value) \ -static ssize_t set_output##value(struct device *dev, struct device_attribute *attr, const char *buf, \ - size_t count) \ +static ssize_t set_output##value(struct class_device *dev, \ + const char *buf, size_t count) \ { \ - struct usb_interface *intf = to_usb_interface(dev); \ - struct interfacekit *kit = usb_get_intfdata(intf); \ + struct interfacekit *kit = class_get_devdata(dev); \ int enabled; \ int retval; \ \ @@ -391,14 +394,13 @@ static ssize_t set_output##value(struct return retval ? retval : count; \ } \ \ -static ssize_t show_output##value(struct device *dev, struct device_attribute *attr, char *buf) \ +static ssize_t show_output##value(struct class_device *dev, char *buf) \ { \ - struct usb_interface *intf = to_usb_interface(dev); \ - struct interfacekit *kit = usb_get_intfdata(intf); \ + struct interfacekit *kit = class_get_devdata(dev); \ \ return sprintf(buf, "%d\n", !!test_bit(value - 1, &kit->outputs));\ } \ -static DEVICE_ATTR(output##value, S_IWUGO | S_IRUGO, \ +static CLASS_DEVICE_ATTR(output##value, S_IWUGO | S_IRUGO, \ show_output##value, set_output##value); show_set_output(1); show_set_output(2); @@ -418,14 +420,13 @@ show_set_output(15); show_set_output(16); #define show_input(value) \ -static ssize_t show_input##value(struct device *dev, struct device_attribute *attr, char *buf) \ +static ssize_t show_input##value(struct class_device *dev, char *buf) \ { \ - struct usb_interface *intf = to_usb_interface(dev); \ - struct interfacekit *kit = usb_get_intfdata(intf); \ + struct interfacekit *kit = class_get_devdata(dev); \ \ return sprintf(buf, "%d\n", (int)kit->inputs[value - 1]); \ } \ -static DEVICE_ATTR(input##value, S_IRUGO, show_input##value, NULL); +static CLASS_DEVICE_ATTR(input##value, S_IRUGO, show_input##value, NULL); show_input(1); show_input(2); @@ -445,14 +446,13 @@ show_input(15); show_input(16); #define show_sensor(value) \ -static ssize_t show_sensor##value(struct device *dev, struct device_attribute *attr, char *buf) \ +static ssize_t show_sensor##value(struct class_device *dev, char *buf) \ { \ - struct usb_interface *intf = to_usb_interface(dev); \ - struct interfacekit *kit = usb_get_intfdata(intf); \ + struct interfacekit *kit = class_get_devdata(dev); \ \ return sprintf(buf, "%d\n", (int)kit->sensors[value - 1]); \ } \ -static DEVICE_ATTR(sensor##value, S_IRUGO, show_sensor##value, NULL); +static CLASS_DEVICE_ATTR(sensor##value, S_IRUGO, show_sensor##value, NULL); show_sensor(1); show_sensor(2); @@ -471,6 +471,7 @@ static int interfacekit_probe(struct usb struct interfacekit *kit; struct driver_interfacekit *ifkit; int pipe, maxp, rc = -ENOMEM; + int bit, value; ifkit = (struct driver_interfacekit *)id->driver_info; if (!ifkit) @@ -493,6 +494,7 @@ static int interfacekit_probe(struct usb if (!kit) goto out; + kit->dev_no = -1; kit->ifkit = ifkit; kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, SLAB_ATOMIC, &kit->data_dma); if (!kit->data) @@ -513,73 +515,88 @@ static int interfacekit_probe(struct usb usb_set_intfdata(intf, kit); + do { + bit = find_first_zero_bit(&device_no, sizeof(device_no)); + value = test_and_set_bit(bit, &device_no); + } while(value); + kit->dev_no = bit; + + kit->class_dev = class_device_create(phidget_class, NULL, 0, + &kit->udev->dev, "interfacekit%d", kit->dev_no); + if (IS_ERR(kit->class_dev)) { + rc = PTR_ERR(kit->class_dev); + kit->class_dev = NULL; + goto out; + } + class_set_devdata(kit->class_dev, kit); + if (usb_submit_urb(kit->irq, GFP_KERNEL)) { rc = -EIO; goto out; } if (ifkit->outputs >= 4) { - device_create_file(&intf->dev, &dev_attr_output1); - device_create_file(&intf->dev, &dev_attr_output2); - device_create_file(&intf->dev, &dev_attr_output3); - device_create_file(&intf->dev, &dev_attr_output4); + class_device_create_file(kit->class_dev, &class_device_attr_output1); + class_device_create_file(kit->class_dev, &class_device_attr_output2); + class_device_create_file(kit->class_dev, &class_device_attr_output3); + class_device_create_file(kit->class_dev, &class_device_attr_output4); } if (ifkit->outputs >= 8) { - device_create_file(&intf->dev, &dev_attr_output5); - device_create_file(&intf->dev, &dev_attr_output6); - device_create_file(&intf->dev, &dev_attr_output7); - device_create_file(&intf->dev, &dev_attr_output8); + class_device_create_file(kit->class_dev, &class_device_attr_output5); + class_device_create_file(kit->class_dev, &class_device_attr_output6); + class_device_create_file(kit->class_dev, &class_device_attr_output7); + class_device_create_file(kit->class_dev, &class_device_attr_output8); } if (ifkit->outputs == 16) { - device_create_file(&intf->dev, &dev_attr_output9); - device_create_file(&intf->dev, &dev_attr_output10); - device_create_file(&intf->dev, &dev_attr_output11); - device_create_file(&intf->dev, &dev_attr_output12); - device_create_file(&intf->dev, &dev_attr_output13); - device_create_file(&intf->dev, &dev_attr_output14); - device_create_file(&intf->dev, &dev_attr_output15); - device_create_file(&intf->dev, &dev_attr_output16); + class_device_create_file(kit->class_dev, &class_device_attr_output9); + class_device_create_file(kit->class_dev, &class_device_attr_output10); + class_device_create_file(kit->class_dev, &class_device_attr_output11); + class_device_create_file(kit->class_dev, &class_device_attr_output12); + class_device_create_file(kit->class_dev, &class_device_attr_output13); + class_device_create_file(kit->class_dev, &class_device_attr_output14); + class_device_create_file(kit->class_dev, &class_device_attr_output15); + class_device_create_file(kit->class_dev, &class_device_attr_output16); } if (ifkit->inputs >= 4) { - device_create_file(&intf->dev, &dev_attr_input1); - device_create_file(&intf->dev, &dev_attr_input2); - device_create_file(&intf->dev, &dev_attr_input3); - device_create_file(&intf->dev, &dev_attr_input4); + class_device_create_file(kit->class_dev, &class_device_attr_input1); + class_device_create_file(kit->class_dev, &class_device_attr_input2); + class_device_create_file(kit->class_dev, &class_device_attr_input3); + class_device_create_file(kit->class_dev, &class_device_attr_input4); } if (ifkit->inputs >= 8) { - device_create_file(&intf->dev, &dev_attr_input5); - device_create_file(&intf->dev, &dev_attr_input6); - device_create_file(&intf->dev, &dev_attr_input7); - device_create_file(&intf->dev, &dev_attr_input8); + class_device_create_file(kit->class_dev, &class_device_attr_input5); + class_device_create_file(kit->class_dev, &class_device_attr_input6); + class_device_create_file(kit->class_dev, &class_device_attr_input7); + class_device_create_file(kit->class_dev, &class_device_attr_input8); } if (ifkit->inputs == 16) { - device_create_file(&intf->dev, &dev_attr_input9); - device_create_file(&intf->dev, &dev_attr_input10); - device_create_file(&intf->dev, &dev_attr_input11); - device_create_file(&intf->dev, &dev_attr_input12); - device_create_file(&intf->dev, &dev_attr_input13); - device_create_file(&intf->dev, &dev_attr_input14); - device_create_file(&intf->dev, &dev_attr_input15); - device_create_file(&intf->dev, &dev_attr_input16); + class_device_create_file(kit->class_dev, &class_device_attr_input9); + class_device_create_file(kit->class_dev, &class_device_attr_input10); + class_device_create_file(kit->class_dev, &class_device_attr_input11); + class_device_create_file(kit->class_dev, &class_device_attr_input12); + class_device_create_file(kit->class_dev, &class_device_attr_input13); + class_device_create_file(kit->class_dev, &class_device_attr_input14); + class_device_create_file(kit->class_dev, &class_device_attr_input15); + class_device_create_file(kit->class_dev, &class_device_attr_input16); } if (ifkit->sensors >= 4) { - device_create_file(&intf->dev, &dev_attr_sensor1); - device_create_file(&intf->dev, &dev_attr_sensor2); - device_create_file(&intf->dev, &dev_attr_sensor3); - device_create_file(&intf->dev, &dev_attr_sensor4); + class_device_create_file(kit->class_dev, &class_device_attr_sensor1); + class_device_create_file(kit->class_dev, &class_device_attr_sensor2); + class_device_create_file(kit->class_dev, &class_device_attr_sensor3); + class_device_create_file(kit->class_dev, &class_device_attr_sensor4); } if (ifkit->sensors >= 7) { - device_create_file(&intf->dev, &dev_attr_sensor5); - device_create_file(&intf->dev, &dev_attr_sensor6); - device_create_file(&intf->dev, &dev_attr_sensor7); + class_device_create_file(kit->class_dev, &class_device_attr_sensor5); + class_device_create_file(kit->class_dev, &class_device_attr_sensor6); + class_device_create_file(kit->class_dev, &class_device_attr_sensor7); } if (ifkit->sensors == 8) - device_create_file(&intf->dev, &dev_attr_sensor8); + class_device_create_file(kit->class_dev, &class_device_attr_sensor8); if (ifkit->has_lcd) - device_create_file(&intf->dev, &dev_attr_lcd); + class_device_create_file(kit->class_dev, &class_device_attr_lcd); dev_info(&intf->dev, "USB PhidgetInterfaceKit %d/%d/%d attached\n", ifkit->sensors, ifkit->inputs, ifkit->outputs); @@ -592,6 +609,11 @@ out: usb_free_urb(kit->irq); if (kit->data) usb_buffer_free(dev, URB_INT_SIZE, kit->data, kit->data_dma); + if (kit->class_dev) + class_device_unregister(kit->class_dev); + if (kit->dev_no >= 0) + clear_bit(kit->dev_no, &device_no); + kfree(kit); } @@ -614,72 +636,76 @@ static void interfacekit_disconnect(stru cancel_delayed_work(&kit->do_notify); if (kit->ifkit->outputs >= 4) { - device_remove_file(&interface->dev, &dev_attr_output1); - device_remove_file(&interface->dev, &dev_attr_output2); - device_remove_file(&interface->dev, &dev_attr_output3); - device_remove_file(&interface->dev, &dev_attr_output4); + class_device_remove_file(kit->class_dev, &class_device_attr_output1); + class_device_remove_file(kit->class_dev, &class_device_attr_output2); + class_device_remove_file(kit->class_dev, &class_device_attr_output3); + class_device_remove_file(kit->class_dev, &class_device_attr_output4); } if (kit->ifkit->outputs >= 8) { - device_remove_file(&interface->dev, &dev_attr_output5); - device_remove_file(&interface->dev, &dev_attr_output6); - device_remove_file(&interface->dev, &dev_attr_output7); - device_remove_file(&interface->dev, &dev_attr_output8); + class_device_remove_file(kit->class_dev, &class_device_attr_output5); + class_device_remove_file(kit->class_dev, &class_device_attr_output6); + class_device_remove_file(kit->class_dev, &class_device_attr_output7); + class_device_remove_file(kit->class_dev, &class_device_attr_output8); } if (kit->ifkit->outputs == 16) { - device_remove_file(&interface->dev, &dev_attr_output9); - device_remove_file(&interface->dev, &dev_attr_output10); - device_remove_file(&interface->dev, &dev_attr_output11); - device_remove_file(&interface->dev, &dev_attr_output12); - device_remove_file(&interface->dev, &dev_attr_output13); - device_remove_file(&interface->dev, &dev_attr_output14); - device_remove_file(&interface->dev, &dev_attr_output15); - device_remove_file(&interface->dev, &dev_attr_output16); + class_device_remove_file(kit->class_dev, &class_device_attr_output9); + class_device_remove_file(kit->class_dev, &class_device_attr_output10); + class_device_remove_file(kit->class_dev, &class_device_attr_output11); + class_device_remove_file(kit->class_dev, &class_device_attr_output12); + class_device_remove_file(kit->class_dev, &class_device_attr_output13); + class_device_remove_file(kit->class_dev, &class_device_attr_output14); + class_device_remove_file(kit->class_dev, &class_device_attr_output15); + class_device_remove_file(kit->class_dev, &class_device_attr_output16); } if (kit->ifkit->inputs >= 4) { - device_remove_file(&interface->dev, &dev_attr_input1); - device_remove_file(&interface->dev, &dev_attr_input2); - device_remove_file(&interface->dev, &dev_attr_input3); - device_remove_file(&interface->dev, &dev_attr_input4); + class_device_remove_file(kit->class_dev, &class_device_attr_input1); + class_device_remove_file(kit->class_dev, &class_device_attr_input2); + class_device_remove_file(kit->class_dev, &class_device_attr_input3); + class_device_remove_file(kit->class_dev, &class_device_attr_input4); } if (kit->ifkit->inputs >= 8) { - device_remove_file(&interface->dev, &dev_attr_input5); - device_remove_file(&interface->dev, &dev_attr_input6); - device_remove_file(&interface->dev, &dev_attr_input7); - device_remove_file(&interface->dev, &dev_attr_input8); + class_device_remove_file(kit->class_dev, &class_device_attr_input5); + class_device_remove_file(kit->class_dev, &class_device_attr_input6); + class_device_remove_file(kit->class_dev, &class_device_attr_input7); + class_device_remove_file(kit->class_dev, &class_device_attr_input8); } if (kit->ifkit->inputs == 16) { - device_remove_file(&interface->dev, &dev_attr_input9); - device_remove_file(&interface->dev, &dev_attr_input10); - device_remove_file(&interface->dev, &dev_attr_input11); - device_remove_file(&interface->dev, &dev_attr_input12); - device_remove_file(&interface->dev, &dev_attr_input13); - device_remove_file(&interface->dev, &dev_attr_input14); - device_remove_file(&interface->dev, &dev_attr_input15); - device_remove_file(&interface->dev, &dev_attr_input16); + class_device_remove_file(kit->class_dev, &class_device_attr_input9); + class_device_remove_file(kit->class_dev, &class_device_attr_input10); + class_device_remove_file(kit->class_dev, &class_device_attr_input11); + class_device_remove_file(kit->class_dev, &class_device_attr_input12); + class_device_remove_file(kit->class_dev, &class_device_attr_input13); + class_device_remove_file(kit->class_dev, &class_device_attr_input14); + class_device_remove_file(kit->class_dev, &class_device_attr_input15); + class_device_remove_file(kit->class_dev, &class_device_attr_input16); } if (kit->ifkit->sensors >= 4) { - device_remove_file(&interface->dev, &dev_attr_sensor1); - device_remove_file(&interface->dev, &dev_attr_sensor2); - device_remove_file(&interface->dev, &dev_attr_sensor3); - device_remove_file(&interface->dev, &dev_attr_sensor4); + class_device_remove_file(kit->class_dev, &class_device_attr_sensor1); + class_device_remove_file(kit->class_dev, &class_device_attr_sensor2); + class_device_remove_file(kit->class_dev, &class_device_attr_sensor3); + class_device_remove_file(kit->class_dev, &class_device_attr_sensor4); } if (kit->ifkit->sensors >= 7) { - device_remove_file(&interface->dev, &dev_attr_sensor5); - device_remove_file(&interface->dev, &dev_attr_sensor6); - device_remove_file(&interface->dev, &dev_attr_sensor7); + class_device_remove_file(kit->class_dev, &class_device_attr_sensor5); + class_device_remove_file(kit->class_dev, &class_device_attr_sensor6); + class_device_remove_file(kit->class_dev, &class_device_attr_sensor7); } if (kit->ifkit->sensors == 8) - device_remove_file(&interface->dev, &dev_attr_sensor8); + class_device_remove_file(kit->class_dev, &class_device_attr_sensor8); if (kit->ifkit->has_lcd) - device_remove_file(&interface->dev, &dev_attr_lcd); + class_device_remove_file(kit->class_dev, &class_device_attr_lcd); + + class_device_unregister(kit->class_dev); dev_info(&interface->dev, "USB PhidgetInterfaceKit %d/%d/%d detached\n", kit->ifkit->sensors, kit->ifkit->inputs, kit->ifkit->outputs); usb_put_dev(kit->udev); + clear_bit(kit->dev_no, &device_no); + kfree(kit); } diff -urpN linux-2.6.16/drivers/usb/misc/phidgetmotorcontrol.c linux-2.6.16-mc/drivers/usb/misc/phidgetmotorcontrol.c --- linux-2.6.16/drivers/usb/misc/phidgetmotorcontrol.c 2006-07-09 22:40:42.000000000 +0100 +++ linux-2.6.16-mc/drivers/usb/misc/phidgetmotorcontrol.c 2006-07-09 23:46:39.000000000 +0100 @@ -15,6 +15,8 @@ #include <linux/module.h> #include <linux/usb.h> +#include "phidget.h" + #define DRIVER_AUTHOR "Sean Young <[EMAIL PROTECTED]>" #define DRIVER_DESC "USB PhidgetMotorControl Driver" @@ -23,9 +25,13 @@ #define URB_INT_SIZE 8 +static unsigned long device_no; + struct motorcontrol { struct usb_device *udev; struct usb_interface *intf; + struct class_device *class_dev; + int dev_no; u8 inputs[4]; s8 desired_speed[2]; s8 speed[2]; @@ -181,11 +187,10 @@ static void do_notify(void *data) } #define show_set_speed(value) \ -static ssize_t set_speed##value(struct device *dev, \ - struct device_attribute *attr, const char *buf, size_t count) \ +static ssize_t set_speed##value(struct class_device *dev, \ + const char *buf, size_t count) \ { \ - struct usb_interface *intf = to_usb_interface(dev); \ - struct motorcontrol *mc = usb_get_intfdata(intf); \ + struct motorcontrol *mc = class_get_devdata(dev); \ int speed; \ int retval; \ \ @@ -202,25 +207,22 @@ static ssize_t set_speed##value(struct d return retval ? retval : count; \ } \ \ -static ssize_t show_speed##value(struct device *dev, \ - struct device_attribute *attr, char *buf) \ +static ssize_t show_speed##value(struct class_device *dev, char *buf) \ { \ - struct usb_interface *intf = to_usb_interface(dev); \ - struct motorcontrol *mc = usb_get_intfdata(intf); \ + struct motorcontrol *mc = class_get_devdata(dev); \ \ return sprintf(buf, "%d\n", mc->speed[value]); \ } \ -static DEVICE_ATTR(speed##value, S_IWUGO | S_IRUGO, \ +static CLASS_DEVICE_ATTR(speed##value, S_IWUGO | S_IRUGO, \ show_speed##value, set_speed##value); show_set_speed(0); show_set_speed(1); #define show_set_acceleration(value) \ -static ssize_t set_acceleration##value(struct device *dev, \ - struct device_attribute *attr, const char *buf, size_t count) \ +static ssize_t set_acceleration##value(struct class_device *dev, \ + const char *buf, size_t count) \ { \ - struct usb_interface *intf = to_usb_interface(dev); \ - struct motorcontrol *mc = usb_get_intfdata(intf); \ + struct motorcontrol *mc = class_get_devdata(dev); \ int acceleration; \ int retval; \ \ @@ -237,43 +239,38 @@ static ssize_t set_acceleration##value(s return retval ? retval : count; \ } \ \ -static ssize_t show_acceleration##value(struct device *dev, \ - struct device_attribute *attr, char *buf) \ +static ssize_t show_acceleration##value(struct class_device *dev, \ + char *buf) \ { \ - struct usb_interface *intf = to_usb_interface(dev); \ - struct motorcontrol *mc = usb_get_intfdata(intf); \ + struct motorcontrol *mc = class_get_devdata(dev); \ \ return sprintf(buf, "%d\n", mc->acceleration[value]); \ } \ -static DEVICE_ATTR(acceleration##value, S_IWUGO | S_IRUGO, \ +static CLASS_DEVICE_ATTR(acceleration##value, S_IWUGO | S_IRUGO, \ show_acceleration##value, set_acceleration##value); show_set_acceleration(0); show_set_acceleration(1); #define show_current(value) \ -static ssize_t show_current##value(struct device *dev, \ - struct device_attribute *attr, char *buf) \ +static ssize_t show_current##value(struct class_device *dev, char *buf) \ { \ - struct usb_interface *intf = to_usb_interface(dev); \ - struct motorcontrol *mc = usb_get_intfdata(intf); \ + struct motorcontrol *mc = class_get_devdata(dev); \ \ return sprintf(buf, "%dmA\n", (int)mc->_current[value]); \ } \ -static DEVICE_ATTR(current##value, S_IRUGO, show_current##value, NULL); +static CLASS_DEVICE_ATTR(current##value, S_IRUGO, show_current##value, NULL); show_current(0); show_current(1); #define show_input(value) \ -static ssize_t show_input##value(struct device *dev, \ - struct device_attribute *attr, char *buf) \ +static ssize_t show_input##value(struct class_device *dev, char *buf) \ { \ - struct usb_interface *intf = to_usb_interface(dev); \ - struct motorcontrol *mc = usb_get_intfdata(intf); \ + struct motorcontrol *mc = class_get_devdata(dev); \ \ return sprintf(buf, "%d\n", (int)mc->inputs[value]); \ } \ -static DEVICE_ATTR(input##value, S_IRUGO, show_input##value, NULL); +static CLASS_DEVICE_ATTR(input##value, S_IRUGO, show_input##value, NULL); show_input(0); show_input(1); @@ -287,6 +284,7 @@ static int motorcontrol_probe(struct usb struct usb_endpoint_descriptor *endpoint; struct motorcontrol *mc; int pipe, maxp, rc = -ENOMEM; + int bit, value; interface = intf->cur_altsetting; if (interface->desc.bNumEndpoints != 1) @@ -306,6 +304,7 @@ static int motorcontrol_probe(struct usb if (!mc) goto out; + mc->dev_no = -1; mc->data = usb_buffer_alloc(dev, URB_INT_SIZE, SLAB_ATOMIC, &mc->data_dma); if (!mc->data) goto out; @@ -326,24 +325,40 @@ static int motorcontrol_probe(struct usb usb_set_intfdata(intf, mc); + do { + bit = find_first_zero_bit(&device_no, sizeof(device_no)); + value = test_and_set_bit(bit, &device_no); + } while(value); + mc->dev_no = bit; + + mc->class_dev = class_device_create(phidget_class, NULL, 0, + &mc->udev->dev, "motorcontrol%d", mc->dev_no); + if (IS_ERR(mc->class_dev)) { + rc = PTR_ERR(mc->class_dev); + mc->class_dev = NULL; + goto out; + } + + class_set_devdata(mc->class_dev, mc); + if (usb_submit_urb(mc->irq, GFP_KERNEL)) { rc = -EIO; goto out; } - device_create_file(&intf->dev, &dev_attr_input0); - device_create_file(&intf->dev, &dev_attr_input1); - device_create_file(&intf->dev, &dev_attr_input2); - device_create_file(&intf->dev, &dev_attr_input3); + class_device_create_file(mc->class_dev, &class_device_attr_input0); + class_device_create_file(mc->class_dev, &class_device_attr_input1); + class_device_create_file(mc->class_dev, &class_device_attr_input2); + class_device_create_file(mc->class_dev, &class_device_attr_input3); - device_create_file(&intf->dev, &dev_attr_speed0); - device_create_file(&intf->dev, &dev_attr_speed1); + class_device_create_file(mc->class_dev, &class_device_attr_speed0); + class_device_create_file(mc->class_dev, &class_device_attr_speed1); - device_create_file(&intf->dev, &dev_attr_acceleration0); - device_create_file(&intf->dev, &dev_attr_acceleration1); + class_device_create_file(mc->class_dev, &class_device_attr_acceleration0); + class_device_create_file(mc->class_dev, &class_device_attr_acceleration1); - device_create_file(&intf->dev, &dev_attr_current0); - device_create_file(&intf->dev, &dev_attr_current1); + class_device_create_file(mc->class_dev, &class_device_attr_current0); + class_device_create_file(mc->class_dev, &class_device_attr_current1); dev_info(&intf->dev, "USB Phidget MotorControl attached\n"); @@ -355,6 +370,11 @@ out: usb_free_urb(mc->irq); if (mc->data) usb_buffer_free(dev, URB_INT_SIZE, mc->data, mc->data_dma); + if (mc->class_dev) + class_device_unregister(mc->class_dev); + if (mc->dev_no) + clear_bit(mc->dev_no, &device_no); + kfree(mc); } @@ -376,24 +396,27 @@ static void motorcontrol_disconnect(stru cancel_delayed_work(&mc->do_notify); - device_remove_file(&interface->dev, &dev_attr_input0); - device_remove_file(&interface->dev, &dev_attr_input1); - device_remove_file(&interface->dev, &dev_attr_input2); - device_remove_file(&interface->dev, &dev_attr_input3); + class_device_remove_file(mc->class_dev, &class_device_attr_input0); + class_device_remove_file(mc->class_dev, &class_device_attr_input1); + class_device_remove_file(mc->class_dev, &class_device_attr_input2); + class_device_remove_file(mc->class_dev, &class_device_attr_input3); - device_remove_file(&interface->dev, &dev_attr_speed0); - device_remove_file(&interface->dev, &dev_attr_speed1); + class_device_remove_file(mc->class_dev, &class_device_attr_speed0); + class_device_remove_file(mc->class_dev, &class_device_attr_speed1); - device_remove_file(&interface->dev, &dev_attr_acceleration0); - device_remove_file(&interface->dev, &dev_attr_acceleration1); + class_device_remove_file(mc->class_dev, &class_device_attr_acceleration0); + class_device_remove_file(mc->class_dev, &class_device_attr_acceleration1); - device_remove_file(&interface->dev, &dev_attr_current0); - device_remove_file(&interface->dev, &dev_attr_current1); + class_device_remove_file(mc->class_dev, &class_device_attr_current0); + class_device_remove_file(mc->class_dev, &class_device_attr_current1); - dev_info(&interface->dev, "USB Phidget MotorControl disconnected\n"); + class_device_unregister(mc->class_dev); usb_put_dev(mc->udev); + clear_bit(mc->dev_no, &device_no); kfree(mc); + + dev_info(&interface->dev, "USB PhidgetMotorControl detached\n"); } static struct usb_driver motorcontrol_driver = { diff -urpN linux-2.6.16/drivers/usb/misc/phidgetservo.c linux-2.6.16-mc/drivers/usb/misc/phidgetservo.c --- linux-2.6.16/drivers/usb/misc/phidgetservo.c 2006-07-08 12:23:06.000000000 +0100 +++ linux-2.6.16-mc/drivers/usb/misc/phidgetservo.c 2006-07-09 23:12:02.000000000 +0100 @@ -15,14 +15,6 @@ * * CAUTION: Generally you should use 0 < degrees < 180 as anything else * is probably beyond the range of your servo and may damage it. - * - * Jun 16, 2004: Sean Young <[EMAIL PROTECTED]> - * - cleanups - * - was using memory after kfree() - * Aug 8, 2004: Sean Young <[EMAIL PROTECTED]> - * - set the highest angle as high as the hardware allows, there are - * some odd servos out there - * */ #include <linux/kernel.h> @@ -32,6 +24,8 @@ #include <linux/module.h> #include <linux/usb.h> +#include "phidget.h" + #define DRIVER_AUTHOR "Sean Young <[EMAIL PROTECTED]>" #define DRIVER_DESC "USB PhidgetServo Driver" @@ -70,8 +64,12 @@ static struct usb_device_id id_table[] = MODULE_DEVICE_TABLE(usb, id_table); +static int unsigned long device_no; + struct phidget_servo { struct usb_device *udev; + struct class_device *class_dev; + int dev_no; ulong type; int pulse[4]; int degrees[4]; @@ -203,16 +201,15 @@ change_position_v20(struct phidget_servo } #define show_set(value) \ -static ssize_t set_servo##value (struct device *dev, struct device_attribute *attr, \ +static ssize_t set_servo##value (struct class_device *dev, \ const char *buf, size_t count) \ { \ int degrees, minutes, retval; \ - struct usb_interface *intf = to_usb_interface (dev); \ - struct phidget_servo *servo = usb_get_intfdata (intf); \ + struct phidget_servo *servo = class_get_devdata(dev); \ \ minutes = 0; \ /* must at least convert degrees */ \ - if (sscanf (buf, "%d.%d", °rees, &minutes) < 1) { \ + if (sscanf(buf, "%d.%d", °rees, &minutes) < 1) { \ return -EINVAL; \ } \ \ @@ -220,24 +217,23 @@ static ssize_t set_servo##value (struct return -EINVAL; \ \ if (servo->type & SERVO_VERSION_30) \ - retval = change_position_v30 (servo, value, degrees, \ + retval = change_position_v30(servo, value, degrees, \ minutes); \ else \ - retval = change_position_v20 (servo, value, degrees, \ + retval = change_position_v20(servo, value, degrees, \ minutes); \ \ return retval < 0 ? retval : count; \ } \ \ -static ssize_t show_servo##value (struct device *dev, struct device_attribute *attr, char *buf) \ +static ssize_t show_servo##value (struct class_device *dev, char *buf) \ { \ - struct usb_interface *intf = to_usb_interface (dev); \ - struct phidget_servo *servo = usb_get_intfdata (intf); \ + struct phidget_servo *servo = class_get_devdata(dev); \ \ - return sprintf (buf, "%d.%02d\n", servo->degrees[value], \ + return sprintf(buf, "%d.%02d\n", servo->degrees[value], \ servo->minutes[value]); \ } \ -static DEVICE_ATTR(servo##value, S_IWUGO | S_IRUGO, \ +static CLASS_DEVICE_ATTR(servo##value, S_IWUGO | S_IRUGO, \ show_servo##value, set_servo##value); show_set(0); @@ -250,6 +246,7 @@ servo_probe(struct usb_interface *interf { struct usb_device *udev = interface_to_usbdev(interface); struct phidget_servo *dev; + int bit, value; dev = kzalloc(sizeof (struct phidget_servo), GFP_KERNEL); if (dev == NULL) { @@ -261,18 +258,33 @@ servo_probe(struct usb_interface *interf dev->type = id->driver_info; usb_set_intfdata(interface, dev); - device_create_file(&interface->dev, &dev_attr_servo0); + do { + bit = find_first_zero_bit(&device_no, sizeof(device_no)); + value = test_and_set_bit(bit, &device_no); + } while(value); + dev->dev_no = bit; + + dev->class_dev = class_device_create(phidget_class, NULL, 0, + &dev->udev->dev, "servo%d", dev->dev_no); + if (IS_ERR(dev->class_dev)) { + int rc = PTR_ERR(dev->class_dev); + clear_bit(dev->dev_no, &device_no); + kfree(dev); + return rc; + } + + class_device_create_file(dev->class_dev, &class_device_attr_servo0); if (dev->type & SERVO_COUNT_QUAD) { - device_create_file(&interface->dev, &dev_attr_servo1); - device_create_file(&interface->dev, &dev_attr_servo2); - device_create_file(&interface->dev, &dev_attr_servo3); + class_device_create_file(dev->class_dev, &class_device_attr_servo1); + class_device_create_file(dev->class_dev, &class_device_attr_servo2); + class_device_create_file(dev->class_dev, &class_device_attr_servo3); } dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 attached\n", dev->type & SERVO_COUNT_QUAD ? 4 : 1, dev->type & SERVO_VERSION_30 ? 3 : 2); - if(!(dev->type & SERVO_VERSION_30)) + if (!(dev->type & SERVO_VERSION_30)) dev_info(&interface->dev, "WARNING: v2.0 not tested! Please report if it works.\n"); @@ -287,19 +299,21 @@ servo_disconnect(struct usb_interface *i dev = usb_get_intfdata(interface); usb_set_intfdata(interface, NULL); - device_remove_file(&interface->dev, &dev_attr_servo0); + class_device_remove_file(dev->class_dev, &class_device_attr_servo0); if (dev->type & SERVO_COUNT_QUAD) { - device_remove_file(&interface->dev, &dev_attr_servo1); - device_remove_file(&interface->dev, &dev_attr_servo2); - device_remove_file(&interface->dev, &dev_attr_servo3); + class_device_remove_file(dev->class_dev, &class_device_attr_servo1); + class_device_remove_file(dev->class_dev, &class_device_attr_servo2); + class_device_remove_file(dev->class_dev, &class_device_attr_servo3); } + class_device_unregister(dev->class_dev); usb_put_dev(dev->udev); dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 detached\n", dev->type & SERVO_COUNT_QUAD ? 4 : 1, dev->type & SERVO_VERSION_30 ? 3 : 2); + clear_bit(dev->dev_no, &device_no); kfree(dev); } ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel