Commit 912b24c333843514ff77ed88961c6945f0f286ce

Authored by Sean Young
Committed by Greg Kroah-Hartman
1 parent d5176b413d

USB: Put phidgets driver in a sysfs class

This patch creates a device class phidget and add the phidget drivers to
them.

Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

Showing 7 changed files with 334 additions and 190 deletions Side-by-side Diff

drivers/usb/misc/Kconfig
... ... @@ -115,9 +115,16 @@
115 115 To compile this driver as a module, choose M here: the
116 116 module will be called cytherm.
117 117  
  118 +config USB_PHIDGET
  119 + tristate "USB Phidgets drivers"
  120 + depends on USB
  121 + help
  122 + Say Y here to enable the various drivers for devices from
  123 + Phidgets inc.
  124 +
118 125 config USB_PHIDGETKIT
119 126 tristate "USB PhidgetInterfaceKit support"
120   - depends on USB
  127 + depends on USB_PHIDGET
121 128 help
122 129 Say Y here if you want to connect a PhidgetInterfaceKit USB device
123 130 from Phidgets Inc.
... ... @@ -127,7 +134,7 @@
127 134  
128 135 config USB_PHIDGETMOTORCONTROL
129 136 tristate "USB PhidgetMotorControl support"
130   - depends on USB
  137 + depends on USB_PHIDGET
131 138 help
132 139 Say Y here if you want to connect a PhidgetMotorControl USB device
133 140 from Phidgets Inc.
... ... @@ -137,7 +144,7 @@
137 144  
138 145 config USB_PHIDGETSERVO
139 146 tristate "USB PhidgetServo support"
140   - depends on USB
  147 + depends on USB_PHIDGET
141 148 help
142 149 Say Y here if you want to connect an 1 or 4 Motor PhidgetServo
143 150 servo controller version 2.0 or 3.0.
drivers/usb/misc/Makefile
... ... @@ -13,6 +13,7 @@
13 13 obj-$(CONFIG_USB_LD) += ldusb.o
14 14 obj-$(CONFIG_USB_LED) += usbled.o
15 15 obj-$(CONFIG_USB_LEGOTOWER) += legousbtower.o
  16 +obj-$(CONFIG_USB_PHIDGET) += phidget.o
16 17 obj-$(CONFIG_USB_PHIDGETKIT) += phidgetkit.o
17 18 obj-$(CONFIG_USB_PHIDGETMOTORCONTROL) += phidgetmotorcontrol.o
18 19 obj-$(CONFIG_USB_PHIDGETSERVO) += phidgetservo.o
drivers/usb/misc/phidget.c
  1 +/*
  2 + * USB Phidgets class
  3 + *
  4 + * Copyright (C) 2006 Sean Young <sean@mess.org>
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify
  7 + * it under the terms of the GNU General Public License as published by
  8 + * the Free Software Foundation; either version 2 of the License, or
  9 + * (at your option) any later version.
  10 + */
  11 +
  12 +#include <linux/kernel.h>
  13 +#include <linux/module.h>
  14 +#include <linux/init.h>
  15 +#include <linux/err.h>
  16 +#include <linux/device.h>
  17 +
  18 +struct class *phidget_class;
  19 +
  20 +static int __init init_phidget(void)
  21 +{
  22 + phidget_class = class_create(THIS_MODULE, "phidget");
  23 +
  24 + if (IS_ERR(phidget_class))
  25 + return PTR_ERR(phidget_class);
  26 +
  27 + return 0;
  28 +}
  29 +
  30 +static void __exit cleanup_phidget(void)
  31 +{
  32 + class_destroy(phidget_class);
  33 +}
  34 +
  35 +EXPORT_SYMBOL_GPL(phidget_class);
  36 +
  37 +module_init(init_phidget);
  38 +module_exit(cleanup_phidget);
  39 +
  40 +MODULE_LICENSE("GPL");
  41 +MODULE_AUTHOR("Sean Young <sean@mess.org>");
  42 +MODULE_DESCRIPTION("Container module for phidget class");
drivers/usb/misc/phidget.h
  1 +/*
  2 + * USB Phidgets class
  3 + *
  4 + * Copyright (C) 2006 Sean Young <sean@mess.org>
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify
  7 + * it under the terms of the GNU General Public License as published by
  8 + * the Free Software Foundation; either version 2 of the License, or
  9 + * (at your option) any later version.
  10 + */
  11 +
  12 +extern struct class *phidget_class;
drivers/usb/misc/phidgetkit.c
... ... @@ -20,6 +20,8 @@
20 20 #include <linux/module.h>
21 21 #include <linux/usb.h>
22 22  
  23 +#include "phidget.h"
  24 +
23 25 #define DRIVER_AUTHOR "Sean Young <sean@mess.org>"
24 26 #define DRIVER_DESC "USB PhidgetInterfaceKit Driver"
25 27  
26 28  
27 29  
... ... @@ -57,11 +59,15 @@
57 59 ifkit(0, 8, 8, 1);
58 60 ifkit(0, 16, 16, 0);
59 61  
  62 +static unsigned long device_no;
  63 +
60 64 struct interfacekit {
61 65 struct usb_device *udev;
62 66 struct usb_interface *intf;
63 67 struct driver_interfacekit *ifkit;
  68 + struct device *dev;
64 69 unsigned long outputs;
  70 + int dev_no;
65 71 u8 inputs[MAX_INTERFACES];
66 72 u16 sensors[MAX_INTERFACES];
67 73 u8 lcd_files_on;
68 74  
... ... @@ -180,21 +186,21 @@
180 186 }
181 187  
182 188 #define set_lcd_line(number) \
183   -static ssize_t lcd_line_##number(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
184   -{ \
185   - struct usb_interface *intf = to_usb_interface(dev); \
186   - struct interfacekit *kit = usb_get_intfdata(intf); \
187   - change_string(kit, buf, number - 1); \
188   - return count; \
189   -} \
  189 +static ssize_t lcd_line_##number(struct device *dev, \
  190 + struct device_attribute *attr, \
  191 + const char *buf, size_t count) \
  192 +{ \
  193 + struct interfacekit *kit = dev_get_drvdata(dev); \
  194 + change_string(kit, buf, number - 1); \
  195 + return count; \
  196 +} \
190 197 static DEVICE_ATTR(lcd_line_##number, S_IWUGO, NULL, lcd_line_##number);
191 198 set_lcd_line(1);
192 199 set_lcd_line(2);
193 200  
194 201 static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
195 202 {
196   - struct usb_interface *intf = to_usb_interface(dev);
197   - struct interfacekit *kit = usb_get_intfdata(intf);
  203 + struct interfacekit *kit = dev_get_drvdata(dev);
198 204 int enabled;
199 205 unsigned char *buffer;
200 206 int retval = -ENOMEM;
201 207  
... ... @@ -232,16 +238,15 @@
232 238 {
233 239 if (kit->lcd_files_on) {
234 240 dev_dbg(&kit->udev->dev, "Removing lcd files\n");
235   - device_remove_file(&kit->intf->dev, &dev_attr_lcd_line_1);
236   - device_remove_file(&kit->intf->dev, &dev_attr_lcd_line_2);
237   - device_remove_file(&kit->intf->dev, &dev_attr_backlight);
  241 + device_remove_file(kit->dev, &dev_attr_lcd_line_1);
  242 + device_remove_file(kit->dev, &dev_attr_lcd_line_2);
  243 + device_remove_file(kit->dev, &dev_attr_backlight);
238 244 }
239 245 }
240 246  
241 247 static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
242 248 {
243   - struct usb_interface *intf = to_usb_interface(dev);
244   - struct interfacekit *kit = usb_get_intfdata(intf);
  249 + struct interfacekit *kit = dev_get_drvdata(dev);
245 250 int enable;
246 251  
247 252 if (kit->ifkit->has_lcd == 0)
... ... @@ -253,9 +258,9 @@
253 258 if (enable) {
254 259 if (!kit->lcd_files_on) {
255 260 dev_dbg(&kit->udev->dev, "Adding lcd files\n");
256   - device_create_file(&kit->intf->dev, &dev_attr_lcd_line_1);
257   - device_create_file(&kit->intf->dev, &dev_attr_lcd_line_2);
258   - device_create_file(&kit->intf->dev, &dev_attr_backlight);
  261 + device_create_file(kit->dev, &dev_attr_lcd_line_1);
  262 + device_create_file(kit->dev, &dev_attr_lcd_line_2);
  263 + device_create_file(kit->dev, &dev_attr_backlight);
259 264 kit->lcd_files_on = 1;
260 265 }
261 266 } else {
262 267  
263 268  
264 269  
... ... @@ -362,24 +367,24 @@
362 367 for (i=0; i<kit->ifkit->inputs; i++) {
363 368 if (test_and_clear_bit(i, &kit->input_events)) {
364 369 sprintf(sysfs_file, "input%d", i + 1);
365   - sysfs_notify(&kit->intf->dev.kobj, NULL, sysfs_file);
  370 + sysfs_notify(&kit->dev->kobj, NULL, sysfs_file);
366 371 }
367 372 }
368 373  
369 374 for (i=0; i<kit->ifkit->sensors; i++) {
370 375 if (test_and_clear_bit(i, &kit->sensor_events)) {
371 376 sprintf(sysfs_file, "sensor%d", i + 1);
372   - sysfs_notify(&kit->intf->dev.kobj, NULL, sysfs_file);
  377 + sysfs_notify(&kit->dev->kobj, NULL, sysfs_file);
373 378 }
374 379 }
375 380 }
376 381  
377 382 #define show_set_output(value) \
378   -static ssize_t set_output##value(struct device *dev, struct device_attribute *attr, const char *buf, \
379   - size_t count) \
  383 +static ssize_t set_output##value(struct device *dev, \
  384 + struct device_attribute *attr, \
  385 + const char *buf, size_t count) \
380 386 { \
381   - struct usb_interface *intf = to_usb_interface(dev); \
382   - struct interfacekit *kit = usb_get_intfdata(intf); \
  387 + struct interfacekit *kit = dev_get_drvdata(dev); \
383 388 int enabled; \
384 389 int retval; \
385 390 \
386 391  
... ... @@ -391,10 +396,11 @@
391 396 return retval ? retval : count; \
392 397 } \
393 398 \
394   -static ssize_t show_output##value(struct device *dev, struct device_attribute *attr, char *buf) \
  399 +static ssize_t show_output##value(struct device *dev, \
  400 + struct device_attribute *attr, \
  401 + char *buf) \
395 402 { \
396   - struct usb_interface *intf = to_usb_interface(dev); \
397   - struct interfacekit *kit = usb_get_intfdata(intf); \
  403 + struct interfacekit *kit = dev_get_drvdata(dev); \
398 404 \
399 405 return sprintf(buf, "%d\n", !!test_bit(value - 1, &kit->outputs));\
400 406 } \
... ... @@ -420,8 +426,7 @@
420 426 #define show_input(value) \
421 427 static ssize_t show_input##value(struct device *dev, struct device_attribute *attr, char *buf) \
422 428 { \
423   - struct usb_interface *intf = to_usb_interface(dev); \
424   - struct interfacekit *kit = usb_get_intfdata(intf); \
  429 + struct interfacekit *kit = dev_get_drvdata(dev); \
425 430 \
426 431 return sprintf(buf, "%d\n", (int)kit->inputs[value - 1]); \
427 432 } \
428 433  
... ... @@ -445,10 +450,11 @@
445 450 show_input(16);
446 451  
447 452 #define show_sensor(value) \
448   -static ssize_t show_sensor##value(struct device *dev, struct device_attribute *attr, char *buf) \
  453 +static ssize_t show_sensor##value(struct device *dev, \
  454 + struct device_attribute *attr, \
  455 + char *buf) \
449 456 { \
450   - struct usb_interface *intf = to_usb_interface(dev); \
451   - struct interfacekit *kit = usb_get_intfdata(intf); \
  457 + struct interfacekit *kit = dev_get_drvdata(dev); \
452 458 \
453 459 return sprintf(buf, "%d\n", (int)kit->sensors[value - 1]); \
454 460 } \
... ... @@ -471,6 +477,7 @@
471 477 struct interfacekit *kit;
472 478 struct driver_interfacekit *ifkit;
473 479 int pipe, maxp, rc = -ENOMEM;
  480 + int bit, value;
474 481  
475 482 ifkit = (struct driver_interfacekit *)id->driver_info;
476 483 if (!ifkit)
... ... @@ -493,6 +500,7 @@
493 500 if (!kit)
494 501 goto out;
495 502  
  503 + kit->dev_no = -1;
496 504 kit->ifkit = ifkit;
497 505 kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, SLAB_ATOMIC, &kit->data_dma);
498 506 if (!kit->data)
499 507  
500 508  
501 509  
502 510  
503 511  
504 512  
505 513  
506 514  
507 515  
508 516  
... ... @@ -513,73 +521,88 @@
513 521  
514 522 usb_set_intfdata(intf, kit);
515 523  
  524 + do {
  525 + bit = find_first_zero_bit(&device_no, sizeof(device_no));
  526 + value = test_and_set_bit(bit, &device_no);
  527 + } while(value);
  528 + kit->dev_no = bit;
  529 +
  530 + kit->dev = device_create(phidget_class, &kit->udev->dev, 0,
  531 + "interfacekit%d", kit->dev_no);
  532 + if (IS_ERR(kit->dev)) {
  533 + rc = PTR_ERR(kit->dev);
  534 + kit->dev = NULL;
  535 + goto out;
  536 + }
  537 + dev_set_drvdata(kit->dev, kit);
  538 +
516 539 if (usb_submit_urb(kit->irq, GFP_KERNEL)) {
517 540 rc = -EIO;
518 541 goto out;
519 542 }
520 543  
521 544 if (ifkit->outputs >= 4) {
522   - device_create_file(&intf->dev, &dev_attr_output1);
523   - device_create_file(&intf->dev, &dev_attr_output2);
524   - device_create_file(&intf->dev, &dev_attr_output3);
525   - device_create_file(&intf->dev, &dev_attr_output4);
  545 + device_create_file(kit->dev, &dev_attr_output1);
  546 + device_create_file(kit->dev, &dev_attr_output2);
  547 + device_create_file(kit->dev, &dev_attr_output3);
  548 + device_create_file(kit->dev, &dev_attr_output4);
526 549 }
527 550 if (ifkit->outputs >= 8) {
528   - device_create_file(&intf->dev, &dev_attr_output5);
529   - device_create_file(&intf->dev, &dev_attr_output6);
530   - device_create_file(&intf->dev, &dev_attr_output7);
531   - device_create_file(&intf->dev, &dev_attr_output8);
  551 + device_create_file(kit->dev, &dev_attr_output5);
  552 + device_create_file(kit->dev, &dev_attr_output6);
  553 + device_create_file(kit->dev, &dev_attr_output7);
  554 + device_create_file(kit->dev, &dev_attr_output8);
532 555 }
533 556 if (ifkit->outputs == 16) {
534   - device_create_file(&intf->dev, &dev_attr_output9);
535   - device_create_file(&intf->dev, &dev_attr_output10);
536   - device_create_file(&intf->dev, &dev_attr_output11);
537   - device_create_file(&intf->dev, &dev_attr_output12);
538   - device_create_file(&intf->dev, &dev_attr_output13);
539   - device_create_file(&intf->dev, &dev_attr_output14);
540   - device_create_file(&intf->dev, &dev_attr_output15);
541   - device_create_file(&intf->dev, &dev_attr_output16);
  557 + device_create_file(kit->dev, &dev_attr_output9);
  558 + device_create_file(kit->dev, &dev_attr_output10);
  559 + device_create_file(kit->dev, &dev_attr_output11);
  560 + device_create_file(kit->dev, &dev_attr_output12);
  561 + device_create_file(kit->dev, &dev_attr_output13);
  562 + device_create_file(kit->dev, &dev_attr_output14);
  563 + device_create_file(kit->dev, &dev_attr_output15);
  564 + device_create_file(kit->dev, &dev_attr_output16);
542 565 }
543 566  
544 567 if (ifkit->inputs >= 4) {
545   - device_create_file(&intf->dev, &dev_attr_input1);
546   - device_create_file(&intf->dev, &dev_attr_input2);
547   - device_create_file(&intf->dev, &dev_attr_input3);
548   - device_create_file(&intf->dev, &dev_attr_input4);
  568 + device_create_file(kit->dev, &dev_attr_input1);
  569 + device_create_file(kit->dev, &dev_attr_input2);
  570 + device_create_file(kit->dev, &dev_attr_input3);
  571 + device_create_file(kit->dev, &dev_attr_input4);
549 572 }
550 573 if (ifkit->inputs >= 8) {
551   - device_create_file(&intf->dev, &dev_attr_input5);
552   - device_create_file(&intf->dev, &dev_attr_input6);
553   - device_create_file(&intf->dev, &dev_attr_input7);
554   - device_create_file(&intf->dev, &dev_attr_input8);
  574 + device_create_file(kit->dev, &dev_attr_input5);
  575 + device_create_file(kit->dev, &dev_attr_input6);
  576 + device_create_file(kit->dev, &dev_attr_input7);
  577 + device_create_file(kit->dev, &dev_attr_input8);
555 578 }
556 579 if (ifkit->inputs == 16) {
557   - device_create_file(&intf->dev, &dev_attr_input9);
558   - device_create_file(&intf->dev, &dev_attr_input10);
559   - device_create_file(&intf->dev, &dev_attr_input11);
560   - device_create_file(&intf->dev, &dev_attr_input12);
561   - device_create_file(&intf->dev, &dev_attr_input13);
562   - device_create_file(&intf->dev, &dev_attr_input14);
563   - device_create_file(&intf->dev, &dev_attr_input15);
564   - device_create_file(&intf->dev, &dev_attr_input16);
  580 + device_create_file(kit->dev, &dev_attr_input9);
  581 + device_create_file(kit->dev, &dev_attr_input10);
  582 + device_create_file(kit->dev, &dev_attr_input11);
  583 + device_create_file(kit->dev, &dev_attr_input12);
  584 + device_create_file(kit->dev, &dev_attr_input13);
  585 + device_create_file(kit->dev, &dev_attr_input14);
  586 + device_create_file(kit->dev, &dev_attr_input15);
  587 + device_create_file(kit->dev, &dev_attr_input16);
565 588 }
566 589  
567 590 if (ifkit->sensors >= 4) {
568   - device_create_file(&intf->dev, &dev_attr_sensor1);
569   - device_create_file(&intf->dev, &dev_attr_sensor2);
570   - device_create_file(&intf->dev, &dev_attr_sensor3);
571   - device_create_file(&intf->dev, &dev_attr_sensor4);
  591 + device_create_file(kit->dev, &dev_attr_sensor1);
  592 + device_create_file(kit->dev, &dev_attr_sensor2);
  593 + device_create_file(kit->dev, &dev_attr_sensor3);
  594 + device_create_file(kit->dev, &dev_attr_sensor4);
572 595 }
573 596 if (ifkit->sensors >= 7) {
574   - device_create_file(&intf->dev, &dev_attr_sensor5);
575   - device_create_file(&intf->dev, &dev_attr_sensor6);
576   - device_create_file(&intf->dev, &dev_attr_sensor7);
  597 + device_create_file(kit->dev, &dev_attr_sensor5);
  598 + device_create_file(kit->dev, &dev_attr_sensor6);
  599 + device_create_file(kit->dev, &dev_attr_sensor7);
577 600 }
578 601 if (ifkit->sensors == 8)
579   - device_create_file(&intf->dev, &dev_attr_sensor8);
  602 + device_create_file(kit->dev, &dev_attr_sensor8);
580 603  
581 604 if (ifkit->has_lcd)
582   - device_create_file(&intf->dev, &dev_attr_lcd);
  605 + device_create_file(kit->dev, &dev_attr_lcd);
583 606  
584 607 dev_info(&intf->dev, "USB PhidgetInterfaceKit %d/%d/%d attached\n",
585 608 ifkit->sensors, ifkit->inputs, ifkit->outputs);
... ... @@ -592,6 +615,11 @@
592 615 usb_free_urb(kit->irq);
593 616 if (kit->data)
594 617 usb_buffer_free(dev, URB_INT_SIZE, kit->data, kit->data_dma);
  618 + if (kit->dev)
  619 + device_unregister(kit->dev);
  620 + if (kit->dev_no >= 0)
  621 + clear_bit(kit->dev_no, &device_no);
  622 +
595 623 kfree(kit);
596 624 }
597 625  
598 626  
599 627  
600 628  
601 629  
602 630  
603 631  
604 632  
605 633  
606 634  
607 635  
608 636  
... ... @@ -614,72 +642,76 @@
614 642 cancel_delayed_work(&kit->do_notify);
615 643  
616 644 if (kit->ifkit->outputs >= 4) {
617   - device_remove_file(&interface->dev, &dev_attr_output1);
618   - device_remove_file(&interface->dev, &dev_attr_output2);
619   - device_remove_file(&interface->dev, &dev_attr_output3);
620   - device_remove_file(&interface->dev, &dev_attr_output4);
  645 + device_remove_file(kit->dev, &dev_attr_output1);
  646 + device_remove_file(kit->dev, &dev_attr_output2);
  647 + device_remove_file(kit->dev, &dev_attr_output3);
  648 + device_remove_file(kit->dev, &dev_attr_output4);
621 649 }
622 650 if (kit->ifkit->outputs >= 8) {
623   - device_remove_file(&interface->dev, &dev_attr_output5);
624   - device_remove_file(&interface->dev, &dev_attr_output6);
625   - device_remove_file(&interface->dev, &dev_attr_output7);
626   - device_remove_file(&interface->dev, &dev_attr_output8);
  651 + device_remove_file(kit->dev, &dev_attr_output5);
  652 + device_remove_file(kit->dev, &dev_attr_output6);
  653 + device_remove_file(kit->dev, &dev_attr_output7);
  654 + device_remove_file(kit->dev, &dev_attr_output8);
627 655 }
628 656 if (kit->ifkit->outputs == 16) {
629   - device_remove_file(&interface->dev, &dev_attr_output9);
630   - device_remove_file(&interface->dev, &dev_attr_output10);
631   - device_remove_file(&interface->dev, &dev_attr_output11);
632   - device_remove_file(&interface->dev, &dev_attr_output12);
633   - device_remove_file(&interface->dev, &dev_attr_output13);
634   - device_remove_file(&interface->dev, &dev_attr_output14);
635   - device_remove_file(&interface->dev, &dev_attr_output15);
636   - device_remove_file(&interface->dev, &dev_attr_output16);
  657 + device_remove_file(kit->dev, &dev_attr_output9);
  658 + device_remove_file(kit->dev, &dev_attr_output10);
  659 + device_remove_file(kit->dev, &dev_attr_output11);
  660 + device_remove_file(kit->dev, &dev_attr_output12);
  661 + device_remove_file(kit->dev, &dev_attr_output13);
  662 + device_remove_file(kit->dev, &dev_attr_output14);
  663 + device_remove_file(kit->dev, &dev_attr_output15);
  664 + device_remove_file(kit->dev, &dev_attr_output16);
637 665 }
638 666  
639 667 if (kit->ifkit->inputs >= 4) {
640   - device_remove_file(&interface->dev, &dev_attr_input1);
641   - device_remove_file(&interface->dev, &dev_attr_input2);
642   - device_remove_file(&interface->dev, &dev_attr_input3);
643   - device_remove_file(&interface->dev, &dev_attr_input4);
  668 + device_remove_file(kit->dev, &dev_attr_input1);
  669 + device_remove_file(kit->dev, &dev_attr_input2);
  670 + device_remove_file(kit->dev, &dev_attr_input3);
  671 + device_remove_file(kit->dev, &dev_attr_input4);
644 672 }
645 673 if (kit->ifkit->inputs >= 8) {
646   - device_remove_file(&interface->dev, &dev_attr_input5);
647   - device_remove_file(&interface->dev, &dev_attr_input6);
648   - device_remove_file(&interface->dev, &dev_attr_input7);
649   - device_remove_file(&interface->dev, &dev_attr_input8);
  674 + device_remove_file(kit->dev, &dev_attr_input5);
  675 + device_remove_file(kit->dev, &dev_attr_input6);
  676 + device_remove_file(kit->dev, &dev_attr_input7);
  677 + device_remove_file(kit->dev, &dev_attr_input8);
650 678 }
651 679 if (kit->ifkit->inputs == 16) {
652   - device_remove_file(&interface->dev, &dev_attr_input9);
653   - device_remove_file(&interface->dev, &dev_attr_input10);
654   - device_remove_file(&interface->dev, &dev_attr_input11);
655   - device_remove_file(&interface->dev, &dev_attr_input12);
656   - device_remove_file(&interface->dev, &dev_attr_input13);
657   - device_remove_file(&interface->dev, &dev_attr_input14);
658   - device_remove_file(&interface->dev, &dev_attr_input15);
659   - device_remove_file(&interface->dev, &dev_attr_input16);
  680 + device_remove_file(kit->dev, &dev_attr_input9);
  681 + device_remove_file(kit->dev, &dev_attr_input10);
  682 + device_remove_file(kit->dev, &dev_attr_input11);
  683 + device_remove_file(kit->dev, &dev_attr_input12);
  684 + device_remove_file(kit->dev, &dev_attr_input13);
  685 + device_remove_file(kit->dev, &dev_attr_input14);
  686 + device_remove_file(kit->dev, &dev_attr_input15);
  687 + device_remove_file(kit->dev, &dev_attr_input16);
660 688 }
661 689  
662 690 if (kit->ifkit->sensors >= 4) {
663   - device_remove_file(&interface->dev, &dev_attr_sensor1);
664   - device_remove_file(&interface->dev, &dev_attr_sensor2);
665   - device_remove_file(&interface->dev, &dev_attr_sensor3);
666   - device_remove_file(&interface->dev, &dev_attr_sensor4);
  691 + device_remove_file(kit->dev, &dev_attr_sensor1);
  692 + device_remove_file(kit->dev, &dev_attr_sensor2);
  693 + device_remove_file(kit->dev, &dev_attr_sensor3);
  694 + device_remove_file(kit->dev, &dev_attr_sensor4);
667 695 }
668 696 if (kit->ifkit->sensors >= 7) {
669   - device_remove_file(&interface->dev, &dev_attr_sensor5);
670   - device_remove_file(&interface->dev, &dev_attr_sensor6);
671   - device_remove_file(&interface->dev, &dev_attr_sensor7);
  697 + device_remove_file(kit->dev, &dev_attr_sensor5);
  698 + device_remove_file(kit->dev, &dev_attr_sensor6);
  699 + device_remove_file(kit->dev, &dev_attr_sensor7);
672 700 }
673 701 if (kit->ifkit->sensors == 8)
674   - device_remove_file(&interface->dev, &dev_attr_sensor8);
  702 + device_remove_file(kit->dev, &dev_attr_sensor8);
675 703  
676 704 if (kit->ifkit->has_lcd)
677   - device_remove_file(&interface->dev, &dev_attr_lcd);
  705 + device_remove_file(kit->dev, &dev_attr_lcd);
678 706  
  707 + device_unregister(kit->dev);
  708 +
679 709 dev_info(&interface->dev, "USB PhidgetInterfaceKit %d/%d/%d detached\n",
680 710 kit->ifkit->sensors, kit->ifkit->inputs, kit->ifkit->outputs);
681 711  
682 712 usb_put_dev(kit->udev);
  713 + clear_bit(kit->dev_no, &device_no);
  714 +
683 715 kfree(kit);
684 716 }
685 717  
drivers/usb/misc/phidgetmotorcontrol.c
... ... @@ -15,6 +15,8 @@
15 15 #include <linux/module.h>
16 16 #include <linux/usb.h>
17 17  
  18 +#include "phidget.h"
  19 +
18 20 #define DRIVER_AUTHOR "Sean Young <sean@mess.org>"
19 21 #define DRIVER_DESC "USB PhidgetMotorControl Driver"
20 22  
21 23  
... ... @@ -23,9 +25,13 @@
23 25  
24 26 #define URB_INT_SIZE 8
25 27  
  28 +static unsigned long device_no;
  29 +
26 30 struct motorcontrol {
27 31 struct usb_device *udev;
28 32 struct usb_interface *intf;
  33 + struct device *dev;
  34 + int dev_no;
29 35 u8 inputs[4];
30 36 s8 desired_speed[2];
31 37 s8 speed[2];
32 38  
... ... @@ -162,14 +168,14 @@
162 168 for (i=0; i<4; i++) {
163 169 if (test_and_clear_bit(i, &mc->input_events)) {
164 170 sprintf(sysfs_file, "input%d", i);
165   - sysfs_notify(&mc->intf->dev.kobj, NULL, sysfs_file);
  171 + sysfs_notify(&mc->dev->kobj, NULL, sysfs_file);
166 172 }
167 173 }
168 174  
169 175 for (i=0; i<2; i++) {
170 176 if (test_and_clear_bit(i, &mc->speed_events)) {
171 177 sprintf(sysfs_file, "speed%d", i);
172   - sysfs_notify(&mc->intf->dev.kobj, NULL, sysfs_file);
  178 + sysfs_notify(&mc->dev->kobj, NULL, sysfs_file);
173 179 }
174 180 }
175 181  
176 182  
... ... @@ -181,11 +187,11 @@
181 187 }
182 188  
183 189 #define show_set_speed(value) \
184   -static ssize_t set_speed##value(struct device *dev, \
185   - struct device_attribute *attr, const char *buf, size_t count) \
  190 +static ssize_t set_speed##value(struct device *dev, \
  191 + struct device_attribute *attr, \
  192 + const char *buf, size_t count) \
186 193 { \
187   - struct usb_interface *intf = to_usb_interface(dev); \
188   - struct motorcontrol *mc = usb_get_intfdata(intf); \
  194 + struct motorcontrol *mc = dev_get_drvdata(dev); \
189 195 int speed; \
190 196 int retval; \
191 197 \
192 198  
... ... @@ -202,11 +208,11 @@
202 208 return retval ? retval : count; \
203 209 } \
204 210 \
205   -static ssize_t show_speed##value(struct device *dev, \
206   - struct device_attribute *attr, char *buf) \
  211 +static ssize_t show_speed##value(struct device *dev, \
  212 + struct device_attribute *attr, \
  213 + char *buf) \
207 214 { \
208   - struct usb_interface *intf = to_usb_interface(dev); \
209   - struct motorcontrol *mc = usb_get_intfdata(intf); \
  215 + struct motorcontrol *mc = dev_get_drvdata(dev); \
210 216 \
211 217 return sprintf(buf, "%d\n", mc->speed[value]); \
212 218 } \
213 219  
... ... @@ -217,10 +223,10 @@
217 223  
218 224 #define show_set_acceleration(value) \
219 225 static ssize_t set_acceleration##value(struct device *dev, \
220   - struct device_attribute *attr, const char *buf, size_t count) \
  226 + struct device_attribute *attr, \
  227 + const char *buf, size_t count) \
221 228 { \
222   - struct usb_interface *intf = to_usb_interface(dev); \
223   - struct motorcontrol *mc = usb_get_intfdata(intf); \
  229 + struct motorcontrol *mc = dev_get_drvdata(dev); \
224 230 int acceleration; \
225 231 int retval; \
226 232 \
227 233  
... ... @@ -237,11 +243,11 @@
237 243 return retval ? retval : count; \
238 244 } \
239 245 \
240   -static ssize_t show_acceleration##value(struct device *dev, \
241   - struct device_attribute *attr, char *buf) \
  246 +static ssize_t show_acceleration##value(struct device *dev, \
  247 + struct device_attribute *attr, \
  248 + char *buf) \
242 249 { \
243   - struct usb_interface *intf = to_usb_interface(dev); \
244   - struct motorcontrol *mc = usb_get_intfdata(intf); \
  250 + struct motorcontrol *mc = dev_get_drvdata(dev); \
245 251 \
246 252 return sprintf(buf, "%d\n", mc->acceleration[value]); \
247 253 } \
248 254  
... ... @@ -251,11 +257,11 @@
251 257 show_set_acceleration(1);
252 258  
253 259 #define show_current(value) \
254   -static ssize_t show_current##value(struct device *dev, \
255   - struct device_attribute *attr, char *buf) \
  260 +static ssize_t show_current##value(struct device *dev, \
  261 + struct device_attribute *attr, \
  262 + char *buf) \
256 263 { \
257   - struct usb_interface *intf = to_usb_interface(dev); \
258   - struct motorcontrol *mc = usb_get_intfdata(intf); \
  264 + struct motorcontrol *mc = dev_get_drvdata(dev); \
259 265 \
260 266 return sprintf(buf, "%dmA\n", (int)mc->_current[value]); \
261 267 } \
262 268  
... ... @@ -265,11 +271,11 @@
265 271 show_current(1);
266 272  
267 273 #define show_input(value) \
268   -static ssize_t show_input##value(struct device *dev, \
269   - struct device_attribute *attr, char *buf) \
  274 +static ssize_t show_input##value(struct device *dev, \
  275 + struct device_attribute *attr, \
  276 + char *buf) \
270 277 { \
271   - struct usb_interface *intf = to_usb_interface(dev); \
272   - struct motorcontrol *mc = usb_get_intfdata(intf); \
  278 + struct motorcontrol *mc = dev_get_drvdata(dev); \
273 279 \
274 280 return sprintf(buf, "%d\n", (int)mc->inputs[value]); \
275 281 } \
... ... @@ -287,6 +293,7 @@
287 293 struct usb_endpoint_descriptor *endpoint;
288 294 struct motorcontrol *mc;
289 295 int pipe, maxp, rc = -ENOMEM;
  296 + int bit, value;
290 297  
291 298 interface = intf->cur_altsetting;
292 299 if (interface->desc.bNumEndpoints != 1)
... ... @@ -306,6 +313,7 @@
306 313 if (!mc)
307 314 goto out;
308 315  
  316 + mc->dev_no = -1;
309 317 mc->data = usb_buffer_alloc(dev, URB_INT_SIZE, SLAB_ATOMIC, &mc->data_dma);
310 318 if (!mc->data)
311 319 goto out;
312 320  
313 321  
314 322  
315 323  
316 324  
... ... @@ -326,26 +334,42 @@
326 334  
327 335 usb_set_intfdata(intf, mc);
328 336  
  337 + do {
  338 + bit = find_first_zero_bit(&device_no, sizeof(device_no));
  339 + value = test_and_set_bit(bit, &device_no);
  340 + } while(value);
  341 + mc->dev_no = bit;
  342 +
  343 + mc->dev = device_create(phidget_class, &mc->udev->dev, 0,
  344 + "motorcontrol%d", mc->dev_no);
  345 + if (IS_ERR(mc->dev)) {
  346 + rc = PTR_ERR(mc->dev);
  347 + mc->dev = NULL;
  348 + goto out;
  349 + }
  350 +
  351 + dev_set_drvdata(mc->dev, mc);
  352 +
329 353 if (usb_submit_urb(mc->irq, GFP_KERNEL)) {
330 354 rc = -EIO;
331 355 goto out;
332 356 }
333 357  
334   - device_create_file(&intf->dev, &dev_attr_input0);
335   - device_create_file(&intf->dev, &dev_attr_input1);
336   - device_create_file(&intf->dev, &dev_attr_input2);
337   - device_create_file(&intf->dev, &dev_attr_input3);
  358 + device_create_file(mc->dev, &dev_attr_input0);
  359 + device_create_file(mc->dev, &dev_attr_input1);
  360 + device_create_file(mc->dev, &dev_attr_input2);
  361 + device_create_file(mc->dev, &dev_attr_input3);
338 362  
339   - device_create_file(&intf->dev, &dev_attr_speed0);
340   - device_create_file(&intf->dev, &dev_attr_speed1);
  363 + device_create_file(mc->dev, &dev_attr_speed0);
  364 + device_create_file(mc->dev, &dev_attr_speed1);
341 365  
342   - device_create_file(&intf->dev, &dev_attr_acceleration0);
343   - device_create_file(&intf->dev, &dev_attr_acceleration1);
  366 + device_create_file(mc->dev, &dev_attr_acceleration0);
  367 + device_create_file(mc->dev, &dev_attr_acceleration1);
344 368  
345   - device_create_file(&intf->dev, &dev_attr_current0);
346   - device_create_file(&intf->dev, &dev_attr_current1);
  369 + device_create_file(mc->dev, &dev_attr_current0);
  370 + device_create_file(mc->dev, &dev_attr_current1);
347 371  
348   - dev_info(&intf->dev, "USB Phidget MotorControl attached\n");
  372 + dev_info(&intf->dev, "USB PhidgetMotorControl attached\n");
349 373  
350 374 return 0;
351 375  
... ... @@ -355,6 +379,11 @@
355 379 usb_free_urb(mc->irq);
356 380 if (mc->data)
357 381 usb_buffer_free(dev, URB_INT_SIZE, mc->data, mc->data_dma);
  382 + if (mc->dev)
  383 + device_unregister(mc->dev);
  384 + if (mc->dev_no >= 0)
  385 + clear_bit(mc->dev_no, &device_no);
  386 +
358 387 kfree(mc);
359 388 }
360 389  
361 390  
362 391  
363 392  
364 393  
365 394  
366 395  
... ... @@ -376,24 +405,27 @@
376 405  
377 406 cancel_delayed_work(&mc->do_notify);
378 407  
379   - device_remove_file(&interface->dev, &dev_attr_input0);
380   - device_remove_file(&interface->dev, &dev_attr_input1);
381   - device_remove_file(&interface->dev, &dev_attr_input2);
382   - device_remove_file(&interface->dev, &dev_attr_input3);
  408 + device_remove_file(mc->dev, &dev_attr_input0);
  409 + device_remove_file(mc->dev, &dev_attr_input1);
  410 + device_remove_file(mc->dev, &dev_attr_input2);
  411 + device_remove_file(mc->dev, &dev_attr_input3);
383 412  
384   - device_remove_file(&interface->dev, &dev_attr_speed0);
385   - device_remove_file(&interface->dev, &dev_attr_speed1);
  413 + device_remove_file(mc->dev, &dev_attr_speed0);
  414 + device_remove_file(mc->dev, &dev_attr_speed1);
386 415  
387   - device_remove_file(&interface->dev, &dev_attr_acceleration0);
388   - device_remove_file(&interface->dev, &dev_attr_acceleration1);
  416 + device_remove_file(mc->dev, &dev_attr_acceleration0);
  417 + device_remove_file(mc->dev, &dev_attr_acceleration1);
389 418  
390   - device_remove_file(&interface->dev, &dev_attr_current0);
391   - device_remove_file(&interface->dev, &dev_attr_current1);
  419 + device_remove_file(mc->dev, &dev_attr_current0);
  420 + device_remove_file(mc->dev, &dev_attr_current1);
392 421  
393   - dev_info(&interface->dev, "USB Phidget MotorControl disconnected\n");
  422 + device_unregister(mc->dev);
394 423  
395 424 usb_put_dev(mc->udev);
  425 + clear_bit(mc->dev_no, &device_no);
396 426 kfree(mc);
  427 +
  428 + dev_info(&interface->dev, "USB PhidgetMotorControl detached\n");
397 429 }
398 430  
399 431 static struct usb_driver motorcontrol_driver = {
drivers/usb/misc/phidgetservo.c
... ... @@ -15,14 +15,6 @@
15 15 *
16 16 * CAUTION: Generally you should use 0 < degrees < 180 as anything else
17 17 * is probably beyond the range of your servo and may damage it.
18   - *
19   - * Jun 16, 2004: Sean Young <sean@mess.org>
20   - * - cleanups
21   - * - was using memory after kfree()
22   - * Aug 8, 2004: Sean Young <sean@mess.org>
23   - * - set the highest angle as high as the hardware allows, there are
24   - * some odd servos out there
25   - *
26 18 */
27 19  
28 20 #include <linux/kernel.h>
... ... @@ -32,6 +24,8 @@
32 24 #include <linux/module.h>
33 25 #include <linux/usb.h>
34 26  
  27 +#include "phidget.h"
  28 +
35 29 #define DRIVER_AUTHOR "Sean Young <sean@mess.org>"
36 30 #define DRIVER_DESC "USB PhidgetServo Driver"
37 31  
38 32  
... ... @@ -70,8 +64,12 @@
70 64  
71 65 MODULE_DEVICE_TABLE(usb, id_table);
72 66  
  67 +static int unsigned long device_no;
  68 +
73 69 struct phidget_servo {
74 70 struct usb_device *udev;
  71 + struct device *dev;
  72 + int dev_no;
75 73 ulong type;
76 74 int pulse[4];
77 75 int degrees[4];
78 76  
79 77  
... ... @@ -203,16 +201,16 @@
203 201 }
204 202  
205 203 #define show_set(value) \
206   -static ssize_t set_servo##value (struct device *dev, struct device_attribute *attr, \
  204 +static ssize_t set_servo##value (struct device *dev, \
  205 + struct device_attribute *attr, \
207 206 const char *buf, size_t count) \
208 207 { \
209 208 int degrees, minutes, retval; \
210   - struct usb_interface *intf = to_usb_interface (dev); \
211   - struct phidget_servo *servo = usb_get_intfdata (intf); \
  209 + struct phidget_servo *servo = dev_get_drvdata(dev); \
212 210 \
213 211 minutes = 0; \
214 212 /* must at least convert degrees */ \
215   - if (sscanf (buf, "%d.%d", &degrees, &minutes) < 1) { \
  213 + if (sscanf(buf, "%d.%d", &degrees, &minutes) < 1) { \
216 214 return -EINVAL; \
217 215 } \
218 216 \
219 217  
220 218  
221 219  
222 220  
... ... @@ -220,21 +218,22 @@
220 218 return -EINVAL; \
221 219 \
222 220 if (servo->type & SERVO_VERSION_30) \
223   - retval = change_position_v30 (servo, value, degrees, \
  221 + retval = change_position_v30(servo, value, degrees, \
224 222 minutes); \
225 223 else \
226   - retval = change_position_v20 (servo, value, degrees, \
  224 + retval = change_position_v20(servo, value, degrees, \
227 225 minutes); \
228 226 \
229 227 return retval < 0 ? retval : count; \
230 228 } \
231 229 \
232   -static ssize_t show_servo##value (struct device *dev, struct device_attribute *attr, char *buf) \
  230 +static ssize_t show_servo##value (struct device *dev, \
  231 + struct device_attribute *attr, \
  232 + char *buf) \
233 233 { \
234   - struct usb_interface *intf = to_usb_interface (dev); \
235   - struct phidget_servo *servo = usb_get_intfdata (intf); \
  234 + struct phidget_servo *servo = dev_get_drvdata(dev); \
236 235 \
237   - return sprintf (buf, "%d.%02d\n", servo->degrees[value], \
  236 + return sprintf(buf, "%d.%02d\n", servo->degrees[value], \
238 237 servo->minutes[value]); \
239 238 } \
240 239 static DEVICE_ATTR(servo##value, S_IWUGO | S_IRUGO, \
... ... @@ -250,6 +249,7 @@
250 249 {
251 250 struct usb_device *udev = interface_to_usbdev(interface);
252 251 struct phidget_servo *dev;
  252 + int bit, value;
253 253  
254 254 dev = kzalloc(sizeof (struct phidget_servo), GFP_KERNEL);
255 255 if (dev == NULL) {
256 256  
257 257  
... ... @@ -261,18 +261,33 @@
261 261 dev->type = id->driver_info;
262 262 usb_set_intfdata(interface, dev);
263 263  
264   - device_create_file(&interface->dev, &dev_attr_servo0);
  264 + do {
  265 + bit = find_first_zero_bit(&device_no, sizeof(device_no));
  266 + value = test_and_set_bit(bit, &device_no);
  267 + } while(value);
  268 + dev->dev_no = bit;
  269 +
  270 + dev->dev = device_create(phidget_class, &dev->udev->dev, 0,
  271 + "servo%d", dev->dev_no);
  272 + if (IS_ERR(dev->dev)) {
  273 + int rc = PTR_ERR(dev->dev);
  274 + clear_bit(dev->dev_no, &device_no);
  275 + kfree(dev);
  276 + return rc;
  277 + }
  278 +
  279 + device_create_file(dev->dev, &dev_attr_servo0);
265 280 if (dev->type & SERVO_COUNT_QUAD) {
266   - device_create_file(&interface->dev, &dev_attr_servo1);
267   - device_create_file(&interface->dev, &dev_attr_servo2);
268   - device_create_file(&interface->dev, &dev_attr_servo3);
  281 + device_create_file(dev->dev, &dev_attr_servo1);
  282 + device_create_file(dev->dev, &dev_attr_servo2);
  283 + device_create_file(dev->dev, &dev_attr_servo3);
269 284 }
270 285  
271 286 dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 attached\n",
272 287 dev->type & SERVO_COUNT_QUAD ? 4 : 1,
273 288 dev->type & SERVO_VERSION_30 ? 3 : 2);
274 289  
275   - if(!(dev->type & SERVO_VERSION_30))
  290 + if (!(dev->type & SERVO_VERSION_30))
276 291 dev_info(&interface->dev,
277 292 "WARNING: v2.0 not tested! Please report if it works.\n");
278 293  
279 294  
280 295  
281 296  
... ... @@ -287,19 +302,21 @@
287 302 dev = usb_get_intfdata(interface);
288 303 usb_set_intfdata(interface, NULL);
289 304  
290   - device_remove_file(&interface->dev, &dev_attr_servo0);
  305 + device_remove_file(dev->dev, &dev_attr_servo0);
291 306 if (dev->type & SERVO_COUNT_QUAD) {
292   - device_remove_file(&interface->dev, &dev_attr_servo1);
293   - device_remove_file(&interface->dev, &dev_attr_servo2);
294   - device_remove_file(&interface->dev, &dev_attr_servo3);
  307 + device_remove_file(dev->dev, &dev_attr_servo1);
  308 + device_remove_file(dev->dev, &dev_attr_servo2);
  309 + device_remove_file(dev->dev, &dev_attr_servo3);
295 310 }
296 311  
  312 + device_unregister(dev->dev);
297 313 usb_put_dev(dev->udev);
298 314  
299 315 dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 detached\n",
300 316 dev->type & SERVO_COUNT_QUAD ? 4 : 1,
301 317 dev->type & SERVO_VERSION_30 ? 3 : 2);
302 318  
  319 + clear_bit(dev->dev_no, &device_no);
303 320 kfree(dev);
304 321 }
305 322