aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/misc/phidgetkit.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/misc/phidgetkit.c')
-rw-r--r--drivers/usb/misc/phidgetkit.c316
1 files changed, 161 insertions, 155 deletions
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c
index bfbbbfbb92bc..9a8d137d39f9 100644
--- a/drivers/usb/misc/phidgetkit.c
+++ b/drivers/usb/misc/phidgetkit.c
@@ -20,6 +20,8 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/usb.h> 21#include <linux/usb.h>
22 22
23#include "phidget.h"
24
23#define DRIVER_AUTHOR "Sean Young <sean@mess.org>" 25#define DRIVER_AUTHOR "Sean Young <sean@mess.org>"
24#define DRIVER_DESC "USB PhidgetInterfaceKit Driver" 26#define DRIVER_DESC "USB PhidgetInterfaceKit Driver"
25 27
@@ -57,11 +59,15 @@ ifkit(8, 8, 4, 0);
57ifkit(0, 8, 8, 1); 59ifkit(0, 8, 8, 1);
58ifkit(0, 16, 16, 0); 60ifkit(0, 16, 16, 0);
59 61
62static unsigned long device_no;
63
60struct interfacekit { 64struct interfacekit {
61 struct usb_device *udev; 65 struct usb_device *udev;
62 struct usb_interface *intf; 66 struct usb_interface *intf;
63 struct driver_interfacekit *ifkit; 67 struct driver_interfacekit *ifkit;
68 struct device *dev;
64 unsigned long outputs; 69 unsigned long outputs;
70 int dev_no;
65 u8 inputs[MAX_INTERFACES]; 71 u8 inputs[MAX_INTERFACES];
66 u16 sensors[MAX_INTERFACES]; 72 u16 sensors[MAX_INTERFACES];
67 u8 lcd_files_on; 73 u8 lcd_files_on;
@@ -180,21 +186,24 @@ exit:
180} 186}
181 187
182#define set_lcd_line(number) \ 188#define set_lcd_line(number) \
183static ssize_t lcd_line_##number(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ 189static ssize_t lcd_line_##number(struct device *dev, \
184{ \ 190 struct device_attribute *attr, \
185 struct usb_interface *intf = to_usb_interface(dev); \ 191 const char *buf, size_t count) \
186 struct interfacekit *kit = usb_get_intfdata(intf); \ 192{ \
187 change_string(kit, buf, number - 1); \ 193 struct interfacekit *kit = dev_get_drvdata(dev); \
188 return count; \ 194 change_string(kit, buf, number - 1); \
189} \ 195 return count; \
190static DEVICE_ATTR(lcd_line_##number, S_IWUGO, NULL, lcd_line_##number); 196}
197
198#define lcd_line_attr(number) \
199 __ATTR(lcd_line_##number, S_IWUGO, NULL, lcd_line_##number)
200
191set_lcd_line(1); 201set_lcd_line(1);
192set_lcd_line(2); 202set_lcd_line(2);
193 203
194static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 204static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
195{ 205{
196 struct usb_interface *intf = to_usb_interface(dev); 206 struct interfacekit *kit = dev_get_drvdata(dev);
197 struct interfacekit *kit = usb_get_intfdata(intf);
198 int enabled; 207 int enabled;
199 unsigned char *buffer; 208 unsigned char *buffer;
200 int retval = -ENOMEM; 209 int retval = -ENOMEM;
@@ -226,23 +235,30 @@ exit:
226 kfree(buffer); 235 kfree(buffer);
227 return retval; 236 return retval;
228} 237}
229static DEVICE_ATTR(backlight, S_IWUGO, NULL, set_backlight); 238
239static struct device_attribute dev_lcd_line_attrs[] = {
240 lcd_line_attr(1),
241 lcd_line_attr(2),
242 __ATTR(backlight, S_IWUGO, NULL, set_backlight)
243};
230 244
231static void remove_lcd_files(struct interfacekit *kit) 245static void remove_lcd_files(struct interfacekit *kit)
232{ 246{
247 int i;
248
233 if (kit->lcd_files_on) { 249 if (kit->lcd_files_on) {
234 dev_dbg(&kit->udev->dev, "Removing lcd files\n"); 250 dev_dbg(&kit->udev->dev, "Removing lcd files\n");
235 device_remove_file(&kit->intf->dev, &dev_attr_lcd_line_1); 251
236 device_remove_file(&kit->intf->dev, &dev_attr_lcd_line_2); 252 for (i=0; i<ARRAY_SIZE(dev_lcd_line_attrs); i++)
237 device_remove_file(&kit->intf->dev, &dev_attr_backlight); 253 device_remove_file(kit->dev, &dev_lcd_line_attrs[i]);
238 } 254 }
239} 255}
240 256
241static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 257static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
242{ 258{
243 struct usb_interface *intf = to_usb_interface(dev); 259 struct interfacekit *kit = dev_get_drvdata(dev);
244 struct interfacekit *kit = usb_get_intfdata(intf);
245 int enable; 260 int enable;
261 int i, rc;
246 262
247 if (kit->ifkit->has_lcd == 0) 263 if (kit->ifkit->has_lcd == 0)
248 return -ENODEV; 264 return -ENODEV;
@@ -253,9 +269,12 @@ static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *att
253 if (enable) { 269 if (enable) {
254 if (!kit->lcd_files_on) { 270 if (!kit->lcd_files_on) {
255 dev_dbg(&kit->udev->dev, "Adding lcd files\n"); 271 dev_dbg(&kit->udev->dev, "Adding lcd files\n");
256 device_create_file(&kit->intf->dev, &dev_attr_lcd_line_1); 272 for (i=0; i<ARRAY_SIZE(dev_lcd_line_attrs); i++) {
257 device_create_file(&kit->intf->dev, &dev_attr_lcd_line_2); 273 rc = device_create_file(kit->dev,
258 device_create_file(&kit->intf->dev, &dev_attr_backlight); 274 &dev_lcd_line_attrs[i]);
275 if (rc)
276 goto out;
277 }
259 kit->lcd_files_on = 1; 278 kit->lcd_files_on = 1;
260 } 279 }
261 } else { 280 } else {
@@ -266,7 +285,13 @@ static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *att
266 } 285 }
267 286
268 return count; 287 return count;
288out:
289 while (i-- > 0)
290 device_remove_file(kit->dev, &dev_lcd_line_attrs[i]);
291
292 return rc;
269} 293}
294
270static DEVICE_ATTR(lcd, S_IWUGO, NULL, enable_lcd_files); 295static DEVICE_ATTR(lcd, S_IWUGO, NULL, enable_lcd_files);
271 296
272static void interfacekit_irq(struct urb *urb, struct pt_regs *regs) 297static void interfacekit_irq(struct urb *urb, struct pt_regs *regs)
@@ -362,24 +387,24 @@ static void do_notify(void *data)
362 for (i=0; i<kit->ifkit->inputs; i++) { 387 for (i=0; i<kit->ifkit->inputs; i++) {
363 if (test_and_clear_bit(i, &kit->input_events)) { 388 if (test_and_clear_bit(i, &kit->input_events)) {
364 sprintf(sysfs_file, "input%d", i + 1); 389 sprintf(sysfs_file, "input%d", i + 1);
365 sysfs_notify(&kit->intf->dev.kobj, NULL, sysfs_file); 390 sysfs_notify(&kit->dev->kobj, NULL, sysfs_file);
366 } 391 }
367 } 392 }
368 393
369 for (i=0; i<kit->ifkit->sensors; i++) { 394 for (i=0; i<kit->ifkit->sensors; i++) {
370 if (test_and_clear_bit(i, &kit->sensor_events)) { 395 if (test_and_clear_bit(i, &kit->sensor_events)) {
371 sprintf(sysfs_file, "sensor%d", i + 1); 396 sprintf(sysfs_file, "sensor%d", i + 1);
372 sysfs_notify(&kit->intf->dev.kobj, NULL, sysfs_file); 397 sysfs_notify(&kit->dev->kobj, NULL, sysfs_file);
373 } 398 }
374 } 399 }
375} 400}
376 401
377#define show_set_output(value) \ 402#define show_set_output(value) \
378static ssize_t set_output##value(struct device *dev, struct device_attribute *attr, const char *buf, \ 403static ssize_t set_output##value(struct device *dev, \
379 size_t count) \ 404 struct device_attribute *attr, \
405 const char *buf, size_t count) \
380{ \ 406{ \
381 struct usb_interface *intf = to_usb_interface(dev); \ 407 struct interfacekit *kit = dev_get_drvdata(dev); \
382 struct interfacekit *kit = usb_get_intfdata(intf); \
383 int enabled; \ 408 int enabled; \
384 int retval; \ 409 int retval; \
385 \ 410 \
@@ -391,15 +416,19 @@ static ssize_t set_output##value(struct device *dev, struct device_attribute *at
391 return retval ? retval : count; \ 416 return retval ? retval : count; \
392} \ 417} \
393 \ 418 \
394static ssize_t show_output##value(struct device *dev, struct device_attribute *attr, char *buf) \ 419static ssize_t show_output##value(struct device *dev, \
420 struct device_attribute *attr, \
421 char *buf) \
395{ \ 422{ \
396 struct usb_interface *intf = to_usb_interface(dev); \ 423 struct interfacekit *kit = dev_get_drvdata(dev); \
397 struct interfacekit *kit = usb_get_intfdata(intf); \
398 \ 424 \
399 return sprintf(buf, "%d\n", !!test_bit(value - 1, &kit->outputs));\ 425 return sprintf(buf, "%d\n", !!test_bit(value - 1, &kit->outputs));\
400} \ 426}
401static DEVICE_ATTR(output##value, S_IWUGO | S_IRUGO, \ 427
402 show_output##value, set_output##value); 428#define output_attr(value) \
429 __ATTR(output##value, S_IWUGO | S_IRUGO, \
430 show_output##value, set_output##value)
431
403show_set_output(1); 432show_set_output(1);
404show_set_output(2); 433show_set_output(2);
405show_set_output(3); 434show_set_output(3);
@@ -417,15 +446,24 @@ show_set_output(14);
417show_set_output(15); 446show_set_output(15);
418show_set_output(16); 447show_set_output(16);
419 448
449static struct device_attribute dev_output_attrs[] = {
450 output_attr(1), output_attr(2), output_attr(3), output_attr(4),
451 output_attr(5), output_attr(6), output_attr(7), output_attr(8),
452 output_attr(9), output_attr(10), output_attr(11), output_attr(12),
453 output_attr(13), output_attr(14), output_attr(15), output_attr(16)
454};
455
420#define show_input(value) \ 456#define show_input(value) \
421static ssize_t show_input##value(struct device *dev, struct device_attribute *attr, char *buf) \ 457static ssize_t show_input##value(struct device *dev, \
458 struct device_attribute *attr, char *buf) \
422{ \ 459{ \
423 struct usb_interface *intf = to_usb_interface(dev); \ 460 struct interfacekit *kit = dev_get_drvdata(dev); \
424 struct interfacekit *kit = usb_get_intfdata(intf); \
425 \ 461 \
426 return sprintf(buf, "%d\n", (int)kit->inputs[value - 1]); \ 462 return sprintf(buf, "%d\n", (int)kit->inputs[value - 1]); \
427} \ 463}
428static DEVICE_ATTR(input##value, S_IRUGO, show_input##value, NULL); 464
465#define input_attr(value) \
466 __ATTR(input##value, S_IRUGO, show_input##value, NULL)
429 467
430show_input(1); 468show_input(1);
431show_input(2); 469show_input(2);
@@ -444,15 +482,25 @@ show_input(14);
444show_input(15); 482show_input(15);
445show_input(16); 483show_input(16);
446 484
485static struct device_attribute dev_input_attrs[] = {
486 input_attr(1), input_attr(2), input_attr(3), input_attr(4),
487 input_attr(5), input_attr(6), input_attr(7), input_attr(8),
488 input_attr(9), input_attr(10), input_attr(11), input_attr(12),
489 input_attr(13), input_attr(14), input_attr(15), input_attr(16)
490};
491
447#define show_sensor(value) \ 492#define show_sensor(value) \
448static ssize_t show_sensor##value(struct device *dev, struct device_attribute *attr, char *buf) \ 493static ssize_t show_sensor##value(struct device *dev, \
494 struct device_attribute *attr, \
495 char *buf) \
449{ \ 496{ \
450 struct usb_interface *intf = to_usb_interface(dev); \ 497 struct interfacekit *kit = dev_get_drvdata(dev); \
451 struct interfacekit *kit = usb_get_intfdata(intf); \
452 \ 498 \
453 return sprintf(buf, "%d\n", (int)kit->sensors[value - 1]); \ 499 return sprintf(buf, "%d\n", (int)kit->sensors[value - 1]); \
454} \ 500}
455static DEVICE_ATTR(sensor##value, S_IRUGO, show_sensor##value, NULL); 501
502#define sensor_attr(value) \
503 __ATTR(sensor##value, S_IRUGO, show_sensor##value, NULL)
456 504
457show_sensor(1); 505show_sensor(1);
458show_sensor(2); 506show_sensor(2);
@@ -463,6 +511,11 @@ show_sensor(6);
463show_sensor(7); 511show_sensor(7);
464show_sensor(8); 512show_sensor(8);
465 513
514static struct device_attribute dev_sensor_attrs[] = {
515 sensor_attr(1), sensor_attr(2), sensor_attr(3), sensor_attr(4),
516 sensor_attr(5), sensor_attr(6), sensor_attr(7), sensor_attr(8)
517};
518
466static int interfacekit_probe(struct usb_interface *intf, const struct usb_device_id *id) 519static int interfacekit_probe(struct usb_interface *intf, const struct usb_device_id *id)
467{ 520{
468 struct usb_device *dev = interface_to_usbdev(intf); 521 struct usb_device *dev = interface_to_usbdev(intf);
@@ -471,6 +524,7 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
471 struct interfacekit *kit; 524 struct interfacekit *kit;
472 struct driver_interfacekit *ifkit; 525 struct driver_interfacekit *ifkit;
473 int pipe, maxp, rc = -ENOMEM; 526 int pipe, maxp, rc = -ENOMEM;
527 int bit, value, i;
474 528
475 ifkit = (struct driver_interfacekit *)id->driver_info; 529 ifkit = (struct driver_interfacekit *)id->driver_info;
476 if (!ifkit) 530 if (!ifkit)
@@ -493,6 +547,7 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
493 if (!kit) 547 if (!kit)
494 goto out; 548 goto out;
495 549
550 kit->dev_no = -1;
496 kit->ifkit = ifkit; 551 kit->ifkit = ifkit;
497 kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, SLAB_ATOMIC, &kit->data_dma); 552 kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, SLAB_ATOMIC, &kit->data_dma);
498 if (!kit->data) 553 if (!kit->data)
@@ -513,85 +568,80 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
513 568
514 usb_set_intfdata(intf, kit); 569 usb_set_intfdata(intf, kit);
515 570
571 do {
572 bit = find_first_zero_bit(&device_no, sizeof(device_no));
573 value = test_and_set_bit(bit, &device_no);
574 } while(value);
575 kit->dev_no = bit;
576
577 kit->dev = device_create(phidget_class, &kit->udev->dev, 0,
578 "interfacekit%d", kit->dev_no);
579 if (IS_ERR(kit->dev)) {
580 rc = PTR_ERR(kit->dev);
581 kit->dev = NULL;
582 goto out;
583 }
584 dev_set_drvdata(kit->dev, kit);
585
516 if (usb_submit_urb(kit->irq, GFP_KERNEL)) { 586 if (usb_submit_urb(kit->irq, GFP_KERNEL)) {
517 rc = -EIO; 587 rc = -EIO;
518 goto out; 588 goto out;
519 } 589 }
520 590
521 if (ifkit->outputs >= 4) { 591 for (i=0; i<ifkit->outputs; i++ ) {
522 device_create_file(&intf->dev, &dev_attr_output1); 592 rc = device_create_file(kit->dev, &dev_output_attrs[i]);
523 device_create_file(&intf->dev, &dev_attr_output2); 593 if (rc)
524 device_create_file(&intf->dev, &dev_attr_output3); 594 goto out2;
525 device_create_file(&intf->dev, &dev_attr_output4);
526 }
527 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);
532 }
533 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);
542 } 595 }
543 596
544 if (ifkit->inputs >= 4) { 597 for (i=0; i<ifkit->inputs; i++ ) {
545 device_create_file(&intf->dev, &dev_attr_input1); 598 rc = device_create_file(kit->dev, &dev_input_attrs[i]);
546 device_create_file(&intf->dev, &dev_attr_input2); 599 if (rc)
547 device_create_file(&intf->dev, &dev_attr_input3); 600 goto out3;
548 device_create_file(&intf->dev, &dev_attr_input4);
549 }
550 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);
555 }
556 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);
565 } 601 }
566 602
567 if (ifkit->sensors >= 4) { 603 for (i=0; i<ifkit->sensors; i++ ) {
568 device_create_file(&intf->dev, &dev_attr_sensor1); 604 rc = device_create_file(kit->dev, &dev_sensor_attrs[i]);
569 device_create_file(&intf->dev, &dev_attr_sensor2); 605 if (rc)
570 device_create_file(&intf->dev, &dev_attr_sensor3); 606 goto out4;
571 device_create_file(&intf->dev, &dev_attr_sensor4);
572 }
573 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);
577 } 607 }
578 if (ifkit->sensors == 8)
579 device_create_file(&intf->dev, &dev_attr_sensor8);
580 608
581 if (ifkit->has_lcd) 609 if (ifkit->has_lcd) {
582 device_create_file(&intf->dev, &dev_attr_lcd); 610 rc = device_create_file(kit->dev, &dev_attr_lcd);
611 if (rc)
612 goto out4;
613
614 }
583 615
584 dev_info(&intf->dev, "USB PhidgetInterfaceKit %d/%d/%d attached\n", 616 dev_info(&intf->dev, "USB PhidgetInterfaceKit %d/%d/%d attached\n",
585 ifkit->sensors, ifkit->inputs, ifkit->outputs); 617 ifkit->sensors, ifkit->inputs, ifkit->outputs);
586 618
587 return 0; 619 return 0;
588 620
621out4:
622 while (i-- > 0)
623 device_remove_file(kit->dev, &dev_sensor_attrs[i]);
624
625 i = ifkit->inputs;
626out3:
627 while (i-- > 0)
628 device_remove_file(kit->dev, &dev_input_attrs[i]);
629
630 i = ifkit->outputs;
631out2:
632 while (i-- > 0)
633 device_remove_file(kit->dev, &dev_output_attrs[i]);
589out: 634out:
590 if (kit) { 635 if (kit) {
591 if (kit->irq) 636 if (kit->irq)
592 usb_free_urb(kit->irq); 637 usb_free_urb(kit->irq);
593 if (kit->data) 638 if (kit->data)
594 usb_buffer_free(dev, URB_INT_SIZE, kit->data, kit->data_dma); 639 usb_buffer_free(dev, URB_INT_SIZE, kit->data, kit->data_dma);
640 if (kit->dev)
641 device_unregister(kit->dev);
642 if (kit->dev_no >= 0)
643 clear_bit(kit->dev_no, &device_no);
644
595 kfree(kit); 645 kfree(kit);
596 } 646 }
597 647
@@ -601,6 +651,7 @@ out:
601static void interfacekit_disconnect(struct usb_interface *interface) 651static void interfacekit_disconnect(struct usb_interface *interface)
602{ 652{
603 struct interfacekit *kit; 653 struct interfacekit *kit;
654 int i;
604 655
605 kit = usb_get_intfdata(interface); 656 kit = usb_get_intfdata(interface);
606 usb_set_intfdata(interface, NULL); 657 usb_set_intfdata(interface, NULL);
@@ -613,73 +664,28 @@ static void interfacekit_disconnect(struct usb_interface *interface)
613 664
614 cancel_delayed_work(&kit->do_notify); 665 cancel_delayed_work(&kit->do_notify);
615 666
616 if (kit->ifkit->outputs >= 4) { 667 for (i=0; i<kit->ifkit->outputs; i++)
617 device_remove_file(&interface->dev, &dev_attr_output1); 668 device_remove_file(kit->dev, &dev_output_attrs[i]);
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);
621 }
622 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);
627 }
628 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);
637 }
638 669
639 if (kit->ifkit->inputs >= 4) { 670 for (i=0; i<kit->ifkit->inputs; i++)
640 device_remove_file(&interface->dev, &dev_attr_input1); 671 device_remove_file(kit->dev, &dev_input_attrs[i]);
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);
644 }
645 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);
650 }
651 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);
660 }
661 672
662 if (kit->ifkit->sensors >= 4) { 673 for (i=0; i<kit->ifkit->sensors; i++)
663 device_remove_file(&interface->dev, &dev_attr_sensor1); 674 device_remove_file(kit->dev, &dev_sensor_attrs[i]);
664 device_remove_file(&interface->dev, &dev_attr_sensor2); 675
665 device_remove_file(&interface->dev, &dev_attr_sensor3); 676 if (kit->ifkit->has_lcd) {
666 device_remove_file(&interface->dev, &dev_attr_sensor4); 677 device_remove_file(kit->dev, &dev_attr_lcd);
667 } 678 remove_lcd_files(kit);
668 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);
672 } 679 }
673 if (kit->ifkit->sensors == 8)
674 device_remove_file(&interface->dev, &dev_attr_sensor8);
675 680
676 if (kit->ifkit->has_lcd) 681 device_unregister(kit->dev);
677 device_remove_file(&interface->dev, &dev_attr_lcd);
678 682
679 dev_info(&interface->dev, "USB PhidgetInterfaceKit %d/%d/%d detached\n", 683 dev_info(&interface->dev, "USB PhidgetInterfaceKit %d/%d/%d detached\n",
680 kit->ifkit->sensors, kit->ifkit->inputs, kit->ifkit->outputs); 684 kit->ifkit->sensors, kit->ifkit->inputs, kit->ifkit->outputs);
681 685
682 usb_put_dev(kit->udev); 686 usb_put_dev(kit->udev);
687 clear_bit(kit->dev_no, &device_no);
688
683 kfree(kit); 689 kfree(kit);
684} 690}
685 691