diff options
Diffstat (limited to 'drivers/usb/misc/phidgetkit.c')
-rw-r--r-- | drivers/usb/misc/phidgetkit.c | 258 |
1 files changed, 145 insertions, 113 deletions
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c index bfbbbfbb92bc..3f508957def9 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); | |||
57 | ifkit(0, 8, 8, 1); | 59 | ifkit(0, 8, 8, 1); |
58 | ifkit(0, 16, 16, 0); | 60 | ifkit(0, 16, 16, 0); |
59 | 61 | ||
62 | static unsigned long device_no; | ||
63 | |||
60 | struct interfacekit { | 64 | struct 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,21 @@ exit: | |||
180 | } | 186 | } |
181 | 187 | ||
182 | #define set_lcd_line(number) \ | 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) \ | 189 | static 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; \ |
196 | } \ | ||
190 | static DEVICE_ATTR(lcd_line_##number, S_IWUGO, NULL, lcd_line_##number); | 197 | static DEVICE_ATTR(lcd_line_##number, S_IWUGO, NULL, lcd_line_##number); |
191 | set_lcd_line(1); | 198 | set_lcd_line(1); |
192 | set_lcd_line(2); | 199 | set_lcd_line(2); |
193 | 200 | ||
194 | static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 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); | 203 | struct interfacekit *kit = dev_get_drvdata(dev); |
197 | struct interfacekit *kit = usb_get_intfdata(intf); | ||
198 | int enabled; | 204 | int enabled; |
199 | unsigned char *buffer; | 205 | unsigned char *buffer; |
200 | int retval = -ENOMEM; | 206 | int retval = -ENOMEM; |
@@ -232,16 +238,15 @@ static void remove_lcd_files(struct interfacekit *kit) | |||
232 | { | 238 | { |
233 | if (kit->lcd_files_on) { | 239 | if (kit->lcd_files_on) { |
234 | dev_dbg(&kit->udev->dev, "Removing lcd files\n"); | 240 | dev_dbg(&kit->udev->dev, "Removing lcd files\n"); |
235 | device_remove_file(&kit->intf->dev, &dev_attr_lcd_line_1); | 241 | device_remove_file(kit->dev, &dev_attr_lcd_line_1); |
236 | device_remove_file(&kit->intf->dev, &dev_attr_lcd_line_2); | 242 | device_remove_file(kit->dev, &dev_attr_lcd_line_2); |
237 | device_remove_file(&kit->intf->dev, &dev_attr_backlight); | 243 | device_remove_file(kit->dev, &dev_attr_backlight); |
238 | } | 244 | } |
239 | } | 245 | } |
240 | 246 | ||
241 | static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 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); | 249 | struct interfacekit *kit = dev_get_drvdata(dev); |
244 | struct interfacekit *kit = usb_get_intfdata(intf); | ||
245 | int enable; | 250 | int enable; |
246 | 251 | ||
247 | if (kit->ifkit->has_lcd == 0) | 252 | if (kit->ifkit->has_lcd == 0) |
@@ -253,9 +258,9 @@ static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *att | |||
253 | if (enable) { | 258 | if (enable) { |
254 | if (!kit->lcd_files_on) { | 259 | if (!kit->lcd_files_on) { |
255 | dev_dbg(&kit->udev->dev, "Adding lcd files\n"); | 260 | dev_dbg(&kit->udev->dev, "Adding lcd files\n"); |
256 | device_create_file(&kit->intf->dev, &dev_attr_lcd_line_1); | 261 | device_create_file(kit->dev, &dev_attr_lcd_line_1); |
257 | device_create_file(&kit->intf->dev, &dev_attr_lcd_line_2); | 262 | device_create_file(kit->dev, &dev_attr_lcd_line_2); |
258 | device_create_file(&kit->intf->dev, &dev_attr_backlight); | 263 | device_create_file(kit->dev, &dev_attr_backlight); |
259 | kit->lcd_files_on = 1; | 264 | kit->lcd_files_on = 1; |
260 | } | 265 | } |
261 | } else { | 266 | } else { |
@@ -362,24 +367,24 @@ static void do_notify(void *data) | |||
362 | for (i=0; i<kit->ifkit->inputs; i++) { | 367 | for (i=0; i<kit->ifkit->inputs; i++) { |
363 | if (test_and_clear_bit(i, &kit->input_events)) { | 368 | if (test_and_clear_bit(i, &kit->input_events)) { |
364 | sprintf(sysfs_file, "input%d", i + 1); | 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 | for (i=0; i<kit->ifkit->sensors; i++) { | 374 | for (i=0; i<kit->ifkit->sensors; i++) { |
370 | if (test_and_clear_bit(i, &kit->sensor_events)) { | 375 | if (test_and_clear_bit(i, &kit->sensor_events)) { |
371 | sprintf(sysfs_file, "sensor%d", i + 1); | 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 | #define show_set_output(value) \ | 382 | #define show_set_output(value) \ |
378 | static ssize_t set_output##value(struct device *dev, struct device_attribute *attr, const char *buf, \ | 383 | static ssize_t set_output##value(struct device *dev, \ |
379 | size_t count) \ | 384 | struct device_attribute *attr, \ |
385 | const char *buf, size_t count) \ | ||
380 | { \ | 386 | { \ |
381 | struct usb_interface *intf = to_usb_interface(dev); \ | 387 | struct interfacekit *kit = dev_get_drvdata(dev); \ |
382 | struct interfacekit *kit = usb_get_intfdata(intf); \ | ||
383 | int enabled; \ | 388 | int enabled; \ |
384 | int retval; \ | 389 | int retval; \ |
385 | \ | 390 | \ |
@@ -391,10 +396,11 @@ static ssize_t set_output##value(struct device *dev, struct device_attribute *at | |||
391 | return retval ? retval : count; \ | 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); \ | 403 | struct interfacekit *kit = dev_get_drvdata(dev); \ |
397 | struct interfacekit *kit = usb_get_intfdata(intf); \ | ||
398 | \ | 404 | \ |
399 | return sprintf(buf, "%d\n", !!test_bit(value - 1, &kit->outputs));\ | 405 | return sprintf(buf, "%d\n", !!test_bit(value - 1, &kit->outputs));\ |
400 | } \ | 406 | } \ |
@@ -420,8 +426,7 @@ show_set_output(16); | |||
420 | #define show_input(value) \ | 426 | #define show_input(value) \ |
421 | static ssize_t show_input##value(struct device *dev, struct device_attribute *attr, char *buf) \ | 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); \ | 429 | struct interfacekit *kit = dev_get_drvdata(dev); \ |
424 | struct interfacekit *kit = usb_get_intfdata(intf); \ | ||
425 | \ | 430 | \ |
426 | return sprintf(buf, "%d\n", (int)kit->inputs[value - 1]); \ | 431 | return sprintf(buf, "%d\n", (int)kit->inputs[value - 1]); \ |
427 | } \ | 432 | } \ |
@@ -445,10 +450,11 @@ show_input(15); | |||
445 | show_input(16); | 450 | show_input(16); |
446 | 451 | ||
447 | #define show_sensor(value) \ | 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); \ | 457 | struct interfacekit *kit = dev_get_drvdata(dev); \ |
451 | struct interfacekit *kit = usb_get_intfdata(intf); \ | ||
452 | \ | 458 | \ |
453 | return sprintf(buf, "%d\n", (int)kit->sensors[value - 1]); \ | 459 | return sprintf(buf, "%d\n", (int)kit->sensors[value - 1]); \ |
454 | } \ | 460 | } \ |
@@ -471,6 +477,7 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic | |||
471 | struct interfacekit *kit; | 477 | struct interfacekit *kit; |
472 | struct driver_interfacekit *ifkit; | 478 | struct driver_interfacekit *ifkit; |
473 | int pipe, maxp, rc = -ENOMEM; | 479 | int pipe, maxp, rc = -ENOMEM; |
480 | int bit, value; | ||
474 | 481 | ||
475 | ifkit = (struct driver_interfacekit *)id->driver_info; | 482 | ifkit = (struct driver_interfacekit *)id->driver_info; |
476 | if (!ifkit) | 483 | if (!ifkit) |
@@ -493,6 +500,7 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic | |||
493 | if (!kit) | 500 | if (!kit) |
494 | goto out; | 501 | goto out; |
495 | 502 | ||
503 | kit->dev_no = -1; | ||
496 | kit->ifkit = ifkit; | 504 | kit->ifkit = ifkit; |
497 | kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, SLAB_ATOMIC, &kit->data_dma); | 505 | kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, SLAB_ATOMIC, &kit->data_dma); |
498 | if (!kit->data) | 506 | if (!kit->data) |
@@ -513,73 +521,88 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic | |||
513 | 521 | ||
514 | usb_set_intfdata(intf, kit); | 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 | if (usb_submit_urb(kit->irq, GFP_KERNEL)) { | 539 | if (usb_submit_urb(kit->irq, GFP_KERNEL)) { |
517 | rc = -EIO; | 540 | rc = -EIO; |
518 | goto out; | 541 | goto out; |
519 | } | 542 | } |
520 | 543 | ||
521 | if (ifkit->outputs >= 4) { | 544 | if (ifkit->outputs >= 4) { |
522 | device_create_file(&intf->dev, &dev_attr_output1); | 545 | device_create_file(kit->dev, &dev_attr_output1); |
523 | device_create_file(&intf->dev, &dev_attr_output2); | 546 | device_create_file(kit->dev, &dev_attr_output2); |
524 | device_create_file(&intf->dev, &dev_attr_output3); | 547 | device_create_file(kit->dev, &dev_attr_output3); |
525 | device_create_file(&intf->dev, &dev_attr_output4); | 548 | device_create_file(kit->dev, &dev_attr_output4); |
526 | } | 549 | } |
527 | if (ifkit->outputs >= 8) { | 550 | if (ifkit->outputs >= 8) { |
528 | device_create_file(&intf->dev, &dev_attr_output5); | 551 | device_create_file(kit->dev, &dev_attr_output5); |
529 | device_create_file(&intf->dev, &dev_attr_output6); | 552 | device_create_file(kit->dev, &dev_attr_output6); |
530 | device_create_file(&intf->dev, &dev_attr_output7); | 553 | device_create_file(kit->dev, &dev_attr_output7); |
531 | device_create_file(&intf->dev, &dev_attr_output8); | 554 | device_create_file(kit->dev, &dev_attr_output8); |
532 | } | 555 | } |
533 | if (ifkit->outputs == 16) { | 556 | if (ifkit->outputs == 16) { |
534 | device_create_file(&intf->dev, &dev_attr_output9); | 557 | device_create_file(kit->dev, &dev_attr_output9); |
535 | device_create_file(&intf->dev, &dev_attr_output10); | 558 | device_create_file(kit->dev, &dev_attr_output10); |
536 | device_create_file(&intf->dev, &dev_attr_output11); | 559 | device_create_file(kit->dev, &dev_attr_output11); |
537 | device_create_file(&intf->dev, &dev_attr_output12); | 560 | device_create_file(kit->dev, &dev_attr_output12); |
538 | device_create_file(&intf->dev, &dev_attr_output13); | 561 | device_create_file(kit->dev, &dev_attr_output13); |
539 | device_create_file(&intf->dev, &dev_attr_output14); | 562 | device_create_file(kit->dev, &dev_attr_output14); |
540 | device_create_file(&intf->dev, &dev_attr_output15); | 563 | device_create_file(kit->dev, &dev_attr_output15); |
541 | device_create_file(&intf->dev, &dev_attr_output16); | 564 | device_create_file(kit->dev, &dev_attr_output16); |
542 | } | 565 | } |
543 | 566 | ||
544 | if (ifkit->inputs >= 4) { | 567 | if (ifkit->inputs >= 4) { |
545 | device_create_file(&intf->dev, &dev_attr_input1); | 568 | device_create_file(kit->dev, &dev_attr_input1); |
546 | device_create_file(&intf->dev, &dev_attr_input2); | 569 | device_create_file(kit->dev, &dev_attr_input2); |
547 | device_create_file(&intf->dev, &dev_attr_input3); | 570 | device_create_file(kit->dev, &dev_attr_input3); |
548 | device_create_file(&intf->dev, &dev_attr_input4); | 571 | device_create_file(kit->dev, &dev_attr_input4); |
549 | } | 572 | } |
550 | if (ifkit->inputs >= 8) { | 573 | if (ifkit->inputs >= 8) { |
551 | device_create_file(&intf->dev, &dev_attr_input5); | 574 | device_create_file(kit->dev, &dev_attr_input5); |
552 | device_create_file(&intf->dev, &dev_attr_input6); | 575 | device_create_file(kit->dev, &dev_attr_input6); |
553 | device_create_file(&intf->dev, &dev_attr_input7); | 576 | device_create_file(kit->dev, &dev_attr_input7); |
554 | device_create_file(&intf->dev, &dev_attr_input8); | 577 | device_create_file(kit->dev, &dev_attr_input8); |
555 | } | 578 | } |
556 | if (ifkit->inputs == 16) { | 579 | if (ifkit->inputs == 16) { |
557 | device_create_file(&intf->dev, &dev_attr_input9); | 580 | device_create_file(kit->dev, &dev_attr_input9); |
558 | device_create_file(&intf->dev, &dev_attr_input10); | 581 | device_create_file(kit->dev, &dev_attr_input10); |
559 | device_create_file(&intf->dev, &dev_attr_input11); | 582 | device_create_file(kit->dev, &dev_attr_input11); |
560 | device_create_file(&intf->dev, &dev_attr_input12); | 583 | device_create_file(kit->dev, &dev_attr_input12); |
561 | device_create_file(&intf->dev, &dev_attr_input13); | 584 | device_create_file(kit->dev, &dev_attr_input13); |
562 | device_create_file(&intf->dev, &dev_attr_input14); | 585 | device_create_file(kit->dev, &dev_attr_input14); |
563 | device_create_file(&intf->dev, &dev_attr_input15); | 586 | device_create_file(kit->dev, &dev_attr_input15); |
564 | device_create_file(&intf->dev, &dev_attr_input16); | 587 | device_create_file(kit->dev, &dev_attr_input16); |
565 | } | 588 | } |
566 | 589 | ||
567 | if (ifkit->sensors >= 4) { | 590 | if (ifkit->sensors >= 4) { |
568 | device_create_file(&intf->dev, &dev_attr_sensor1); | 591 | device_create_file(kit->dev, &dev_attr_sensor1); |
569 | device_create_file(&intf->dev, &dev_attr_sensor2); | 592 | device_create_file(kit->dev, &dev_attr_sensor2); |
570 | device_create_file(&intf->dev, &dev_attr_sensor3); | 593 | device_create_file(kit->dev, &dev_attr_sensor3); |
571 | device_create_file(&intf->dev, &dev_attr_sensor4); | 594 | device_create_file(kit->dev, &dev_attr_sensor4); |
572 | } | 595 | } |
573 | if (ifkit->sensors >= 7) { | 596 | if (ifkit->sensors >= 7) { |
574 | device_create_file(&intf->dev, &dev_attr_sensor5); | 597 | device_create_file(kit->dev, &dev_attr_sensor5); |
575 | device_create_file(&intf->dev, &dev_attr_sensor6); | 598 | device_create_file(kit->dev, &dev_attr_sensor6); |
576 | device_create_file(&intf->dev, &dev_attr_sensor7); | 599 | device_create_file(kit->dev, &dev_attr_sensor7); |
577 | } | 600 | } |
578 | if (ifkit->sensors == 8) | 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 | if (ifkit->has_lcd) | 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 | dev_info(&intf->dev, "USB PhidgetInterfaceKit %d/%d/%d attached\n", | 607 | dev_info(&intf->dev, "USB PhidgetInterfaceKit %d/%d/%d attached\n", |
585 | ifkit->sensors, ifkit->inputs, ifkit->outputs); | 608 | ifkit->sensors, ifkit->inputs, ifkit->outputs); |
@@ -592,6 +615,11 @@ out: | |||
592 | usb_free_urb(kit->irq); | 615 | usb_free_urb(kit->irq); |
593 | if (kit->data) | 616 | if (kit->data) |
594 | usb_buffer_free(dev, URB_INT_SIZE, kit->data, kit->data_dma); | 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 | kfree(kit); | 623 | kfree(kit); |
596 | } | 624 | } |
597 | 625 | ||
@@ -614,72 +642,76 @@ static void interfacekit_disconnect(struct usb_interface *interface) | |||
614 | cancel_delayed_work(&kit->do_notify); | 642 | cancel_delayed_work(&kit->do_notify); |
615 | 643 | ||
616 | if (kit->ifkit->outputs >= 4) { | 644 | if (kit->ifkit->outputs >= 4) { |
617 | device_remove_file(&interface->dev, &dev_attr_output1); | 645 | device_remove_file(kit->dev, &dev_attr_output1); |
618 | device_remove_file(&interface->dev, &dev_attr_output2); | 646 | device_remove_file(kit->dev, &dev_attr_output2); |
619 | device_remove_file(&interface->dev, &dev_attr_output3); | 647 | device_remove_file(kit->dev, &dev_attr_output3); |
620 | device_remove_file(&interface->dev, &dev_attr_output4); | 648 | device_remove_file(kit->dev, &dev_attr_output4); |
621 | } | 649 | } |
622 | if (kit->ifkit->outputs >= 8) { | 650 | if (kit->ifkit->outputs >= 8) { |
623 | device_remove_file(&interface->dev, &dev_attr_output5); | 651 | device_remove_file(kit->dev, &dev_attr_output5); |
624 | device_remove_file(&interface->dev, &dev_attr_output6); | 652 | device_remove_file(kit->dev, &dev_attr_output6); |
625 | device_remove_file(&interface->dev, &dev_attr_output7); | 653 | device_remove_file(kit->dev, &dev_attr_output7); |
626 | device_remove_file(&interface->dev, &dev_attr_output8); | 654 | device_remove_file(kit->dev, &dev_attr_output8); |
627 | } | 655 | } |
628 | if (kit->ifkit->outputs == 16) { | 656 | if (kit->ifkit->outputs == 16) { |
629 | device_remove_file(&interface->dev, &dev_attr_output9); | 657 | device_remove_file(kit->dev, &dev_attr_output9); |
630 | device_remove_file(&interface->dev, &dev_attr_output10); | 658 | device_remove_file(kit->dev, &dev_attr_output10); |
631 | device_remove_file(&interface->dev, &dev_attr_output11); | 659 | device_remove_file(kit->dev, &dev_attr_output11); |
632 | device_remove_file(&interface->dev, &dev_attr_output12); | 660 | device_remove_file(kit->dev, &dev_attr_output12); |
633 | device_remove_file(&interface->dev, &dev_attr_output13); | 661 | device_remove_file(kit->dev, &dev_attr_output13); |
634 | device_remove_file(&interface->dev, &dev_attr_output14); | 662 | device_remove_file(kit->dev, &dev_attr_output14); |
635 | device_remove_file(&interface->dev, &dev_attr_output15); | 663 | device_remove_file(kit->dev, &dev_attr_output15); |
636 | device_remove_file(&interface->dev, &dev_attr_output16); | 664 | device_remove_file(kit->dev, &dev_attr_output16); |
637 | } | 665 | } |
638 | 666 | ||
639 | if (kit->ifkit->inputs >= 4) { | 667 | if (kit->ifkit->inputs >= 4) { |
640 | device_remove_file(&interface->dev, &dev_attr_input1); | 668 | device_remove_file(kit->dev, &dev_attr_input1); |
641 | device_remove_file(&interface->dev, &dev_attr_input2); | 669 | device_remove_file(kit->dev, &dev_attr_input2); |
642 | device_remove_file(&interface->dev, &dev_attr_input3); | 670 | device_remove_file(kit->dev, &dev_attr_input3); |
643 | device_remove_file(&interface->dev, &dev_attr_input4); | 671 | device_remove_file(kit->dev, &dev_attr_input4); |
644 | } | 672 | } |
645 | if (kit->ifkit->inputs >= 8) { | 673 | if (kit->ifkit->inputs >= 8) { |
646 | device_remove_file(&interface->dev, &dev_attr_input5); | 674 | device_remove_file(kit->dev, &dev_attr_input5); |
647 | device_remove_file(&interface->dev, &dev_attr_input6); | 675 | device_remove_file(kit->dev, &dev_attr_input6); |
648 | device_remove_file(&interface->dev, &dev_attr_input7); | 676 | device_remove_file(kit->dev, &dev_attr_input7); |
649 | device_remove_file(&interface->dev, &dev_attr_input8); | 677 | device_remove_file(kit->dev, &dev_attr_input8); |
650 | } | 678 | } |
651 | if (kit->ifkit->inputs == 16) { | 679 | if (kit->ifkit->inputs == 16) { |
652 | device_remove_file(&interface->dev, &dev_attr_input9); | 680 | device_remove_file(kit->dev, &dev_attr_input9); |
653 | device_remove_file(&interface->dev, &dev_attr_input10); | 681 | device_remove_file(kit->dev, &dev_attr_input10); |
654 | device_remove_file(&interface->dev, &dev_attr_input11); | 682 | device_remove_file(kit->dev, &dev_attr_input11); |
655 | device_remove_file(&interface->dev, &dev_attr_input12); | 683 | device_remove_file(kit->dev, &dev_attr_input12); |
656 | device_remove_file(&interface->dev, &dev_attr_input13); | 684 | device_remove_file(kit->dev, &dev_attr_input13); |
657 | device_remove_file(&interface->dev, &dev_attr_input14); | 685 | device_remove_file(kit->dev, &dev_attr_input14); |
658 | device_remove_file(&interface->dev, &dev_attr_input15); | 686 | device_remove_file(kit->dev, &dev_attr_input15); |
659 | device_remove_file(&interface->dev, &dev_attr_input16); | 687 | device_remove_file(kit->dev, &dev_attr_input16); |
660 | } | 688 | } |
661 | 689 | ||
662 | if (kit->ifkit->sensors >= 4) { | 690 | if (kit->ifkit->sensors >= 4) { |
663 | device_remove_file(&interface->dev, &dev_attr_sensor1); | 691 | device_remove_file(kit->dev, &dev_attr_sensor1); |
664 | device_remove_file(&interface->dev, &dev_attr_sensor2); | 692 | device_remove_file(kit->dev, &dev_attr_sensor2); |
665 | device_remove_file(&interface->dev, &dev_attr_sensor3); | 693 | device_remove_file(kit->dev, &dev_attr_sensor3); |
666 | device_remove_file(&interface->dev, &dev_attr_sensor4); | 694 | device_remove_file(kit->dev, &dev_attr_sensor4); |
667 | } | 695 | } |
668 | if (kit->ifkit->sensors >= 7) { | 696 | if (kit->ifkit->sensors >= 7) { |
669 | device_remove_file(&interface->dev, &dev_attr_sensor5); | 697 | device_remove_file(kit->dev, &dev_attr_sensor5); |
670 | device_remove_file(&interface->dev, &dev_attr_sensor6); | 698 | device_remove_file(kit->dev, &dev_attr_sensor6); |
671 | device_remove_file(&interface->dev, &dev_attr_sensor7); | 699 | device_remove_file(kit->dev, &dev_attr_sensor7); |
672 | } | 700 | } |
673 | if (kit->ifkit->sensors == 8) | 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 | if (kit->ifkit->has_lcd) | 704 | if (kit->ifkit->has_lcd) |
677 | device_remove_file(&interface->dev, &dev_attr_lcd); | 705 | device_remove_file(kit->dev, &dev_attr_lcd); |
706 | |||
707 | device_unregister(kit->dev); | ||
678 | 708 | ||
679 | dev_info(&interface->dev, "USB PhidgetInterfaceKit %d/%d/%d detached\n", | 709 | dev_info(&interface->dev, "USB PhidgetInterfaceKit %d/%d/%d detached\n", |
680 | kit->ifkit->sensors, kit->ifkit->inputs, kit->ifkit->outputs); | 710 | kit->ifkit->sensors, kit->ifkit->inputs, kit->ifkit->outputs); |
681 | 711 | ||
682 | usb_put_dev(kit->udev); | 712 | usb_put_dev(kit->udev); |
713 | clear_bit(kit->dev_no, &device_no); | ||
714 | |||
683 | kfree(kit); | 715 | kfree(kit); |
684 | } | 716 | } |
685 | 717 | ||