diff options
Diffstat (limited to 'drivers/usb/misc/phidgetkit.c')
-rw-r--r-- | drivers/usb/misc/phidgetkit.c | 316 |
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); | |||
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,24 @@ 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; \ |
190 | static 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 | |||
191 | set_lcd_line(1); | 201 | set_lcd_line(1); |
192 | set_lcd_line(2); | 202 | set_lcd_line(2); |
193 | 203 | ||
194 | static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 204 | static 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 | } |
229 | static DEVICE_ATTR(backlight, S_IWUGO, NULL, set_backlight); | 238 | |
239 | static 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 | ||
231 | static void remove_lcd_files(struct interfacekit *kit) | 245 | static 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 | ||
241 | static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 257 | static 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; |
288 | out: | ||
289 | while (i-- > 0) | ||
290 | device_remove_file(kit->dev, &dev_lcd_line_attrs[i]); | ||
291 | |||
292 | return rc; | ||
269 | } | 293 | } |
294 | |||
270 | static DEVICE_ATTR(lcd, S_IWUGO, NULL, enable_lcd_files); | 295 | static DEVICE_ATTR(lcd, S_IWUGO, NULL, enable_lcd_files); |
271 | 296 | ||
272 | static void interfacekit_irq(struct urb *urb, struct pt_regs *regs) | 297 | static 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) \ |
378 | static ssize_t set_output##value(struct device *dev, struct device_attribute *attr, const char *buf, \ | 403 | static 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 | \ |
394 | static ssize_t show_output##value(struct device *dev, struct device_attribute *attr, char *buf) \ | 419 | static 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 | } |
401 | static 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 | |||
403 | show_set_output(1); | 432 | show_set_output(1); |
404 | show_set_output(2); | 433 | show_set_output(2); |
405 | show_set_output(3); | 434 | show_set_output(3); |
@@ -417,15 +446,24 @@ show_set_output(14); | |||
417 | show_set_output(15); | 446 | show_set_output(15); |
418 | show_set_output(16); | 447 | show_set_output(16); |
419 | 448 | ||
449 | static 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) \ |
421 | static ssize_t show_input##value(struct device *dev, struct device_attribute *attr, char *buf) \ | 457 | static 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 | } |
428 | static 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 | ||
430 | show_input(1); | 468 | show_input(1); |
431 | show_input(2); | 469 | show_input(2); |
@@ -444,15 +482,25 @@ show_input(14); | |||
444 | show_input(15); | 482 | show_input(15); |
445 | show_input(16); | 483 | show_input(16); |
446 | 484 | ||
485 | static 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) \ |
448 | static ssize_t show_sensor##value(struct device *dev, struct device_attribute *attr, char *buf) \ | 493 | static 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 | } |
455 | static 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 | ||
457 | show_sensor(1); | 505 | show_sensor(1); |
458 | show_sensor(2); | 506 | show_sensor(2); |
@@ -463,6 +511,11 @@ show_sensor(6); | |||
463 | show_sensor(7); | 511 | show_sensor(7); |
464 | show_sensor(8); | 512 | show_sensor(8); |
465 | 513 | ||
514 | static 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 | |||
466 | static int interfacekit_probe(struct usb_interface *intf, const struct usb_device_id *id) | 519 | static 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 | ||
621 | out4: | ||
622 | while (i-- > 0) | ||
623 | device_remove_file(kit->dev, &dev_sensor_attrs[i]); | ||
624 | |||
625 | i = ifkit->inputs; | ||
626 | out3: | ||
627 | while (i-- > 0) | ||
628 | device_remove_file(kit->dev, &dev_input_attrs[i]); | ||
629 | |||
630 | i = ifkit->outputs; | ||
631 | out2: | ||
632 | while (i-- > 0) | ||
633 | device_remove_file(kit->dev, &dev_output_attrs[i]); | ||
589 | out: | 634 | out: |
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: | |||
601 | static void interfacekit_disconnect(struct usb_interface *interface) | 651 | static 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 | ||