diff options
author | Sean Young <sean@mess.org> | 2006-08-11 05:28:28 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-09-27 14:58:49 -0400 |
commit | da308e8da700637d6271dddda08128094691b980 (patch) | |
tree | 07d132503e754915db98171cd00e106c27138b64 /drivers/usb/misc/phidgetkit.c | |
parent | 912b24c333843514ff77ed88961c6945f0f286ce (diff) |
USB: Phidgets should check create_device_file() return value
device_create_file() could fail, add proper error paths for this condition.
Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/misc/phidgetkit.c')
-rw-r--r-- | drivers/usb/misc/phidgetkit.c | 238 |
1 files changed, 106 insertions, 132 deletions
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c index 3f508957def9..9a8d137d39f9 100644 --- a/drivers/usb/misc/phidgetkit.c +++ b/drivers/usb/misc/phidgetkit.c | |||
@@ -193,8 +193,11 @@ static ssize_t lcd_line_##number(struct device *dev, \ | |||
193 | struct interfacekit *kit = dev_get_drvdata(dev); \ | 193 | struct interfacekit *kit = dev_get_drvdata(dev); \ |
194 | change_string(kit, buf, number - 1); \ | 194 | change_string(kit, buf, number - 1); \ |
195 | return count; \ | 195 | return count; \ |
196 | } \ | 196 | } |
197 | static DEVICE_ATTR(lcd_line_##number, S_IWUGO, NULL, lcd_line_##number); | 197 | |
198 | #define lcd_line_attr(number) \ | ||
199 | __ATTR(lcd_line_##number, S_IWUGO, NULL, lcd_line_##number) | ||
200 | |||
198 | set_lcd_line(1); | 201 | set_lcd_line(1); |
199 | set_lcd_line(2); | 202 | set_lcd_line(2); |
200 | 203 | ||
@@ -232,15 +235,22 @@ exit: | |||
232 | kfree(buffer); | 235 | kfree(buffer); |
233 | return retval; | 236 | return retval; |
234 | } | 237 | } |
235 | 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 | }; | ||
236 | 244 | ||
237 | static void remove_lcd_files(struct interfacekit *kit) | 245 | static void remove_lcd_files(struct interfacekit *kit) |
238 | { | 246 | { |
247 | int i; | ||
248 | |||
239 | if (kit->lcd_files_on) { | 249 | if (kit->lcd_files_on) { |
240 | dev_dbg(&kit->udev->dev, "Removing lcd files\n"); | 250 | dev_dbg(&kit->udev->dev, "Removing lcd files\n"); |
241 | device_remove_file(kit->dev, &dev_attr_lcd_line_1); | 251 | |
242 | device_remove_file(kit->dev, &dev_attr_lcd_line_2); | 252 | for (i=0; i<ARRAY_SIZE(dev_lcd_line_attrs); i++) |
243 | device_remove_file(kit->dev, &dev_attr_backlight); | 253 | device_remove_file(kit->dev, &dev_lcd_line_attrs[i]); |
244 | } | 254 | } |
245 | } | 255 | } |
246 | 256 | ||
@@ -248,6 +258,7 @@ static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *att | |||
248 | { | 258 | { |
249 | struct interfacekit *kit = dev_get_drvdata(dev); | 259 | struct interfacekit *kit = dev_get_drvdata(dev); |
250 | int enable; | 260 | int enable; |
261 | int i, rc; | ||
251 | 262 | ||
252 | if (kit->ifkit->has_lcd == 0) | 263 | if (kit->ifkit->has_lcd == 0) |
253 | return -ENODEV; | 264 | return -ENODEV; |
@@ -258,9 +269,12 @@ static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *att | |||
258 | if (enable) { | 269 | if (enable) { |
259 | if (!kit->lcd_files_on) { | 270 | if (!kit->lcd_files_on) { |
260 | dev_dbg(&kit->udev->dev, "Adding lcd files\n"); | 271 | dev_dbg(&kit->udev->dev, "Adding lcd files\n"); |
261 | device_create_file(kit->dev, &dev_attr_lcd_line_1); | 272 | for (i=0; i<ARRAY_SIZE(dev_lcd_line_attrs); i++) { |
262 | device_create_file(kit->dev, &dev_attr_lcd_line_2); | 273 | rc = device_create_file(kit->dev, |
263 | device_create_file(kit->dev, &dev_attr_backlight); | 274 | &dev_lcd_line_attrs[i]); |
275 | if (rc) | ||
276 | goto out; | ||
277 | } | ||
264 | kit->lcd_files_on = 1; | 278 | kit->lcd_files_on = 1; |
265 | } | 279 | } |
266 | } else { | 280 | } else { |
@@ -271,7 +285,13 @@ static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *att | |||
271 | } | 285 | } |
272 | 286 | ||
273 | 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; | ||
274 | } | 293 | } |
294 | |||
275 | static DEVICE_ATTR(lcd, S_IWUGO, NULL, enable_lcd_files); | 295 | static DEVICE_ATTR(lcd, S_IWUGO, NULL, enable_lcd_files); |
276 | 296 | ||
277 | static void interfacekit_irq(struct urb *urb, struct pt_regs *regs) | 297 | static void interfacekit_irq(struct urb *urb, struct pt_regs *regs) |
@@ -403,9 +423,12 @@ static ssize_t show_output##value(struct device *dev, \ | |||
403 | struct interfacekit *kit = dev_get_drvdata(dev); \ | 423 | struct interfacekit *kit = dev_get_drvdata(dev); \ |
404 | \ | 424 | \ |
405 | return sprintf(buf, "%d\n", !!test_bit(value - 1, &kit->outputs));\ | 425 | return sprintf(buf, "%d\n", !!test_bit(value - 1, &kit->outputs));\ |
406 | } \ | 426 | } |
407 | static DEVICE_ATTR(output##value, S_IWUGO | S_IRUGO, \ | 427 | |
408 | 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 | |||
409 | show_set_output(1); | 432 | show_set_output(1); |
410 | show_set_output(2); | 433 | show_set_output(2); |
411 | show_set_output(3); | 434 | show_set_output(3); |
@@ -423,14 +446,24 @@ show_set_output(14); | |||
423 | show_set_output(15); | 446 | show_set_output(15); |
424 | show_set_output(16); | 447 | show_set_output(16); |
425 | 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 | |||
426 | #define show_input(value) \ | 456 | #define show_input(value) \ |
427 | 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) \ | ||
428 | { \ | 459 | { \ |
429 | struct interfacekit *kit = dev_get_drvdata(dev); \ | 460 | struct interfacekit *kit = dev_get_drvdata(dev); \ |
430 | \ | 461 | \ |
431 | return sprintf(buf, "%d\n", (int)kit->inputs[value - 1]); \ | 462 | return sprintf(buf, "%d\n", (int)kit->inputs[value - 1]); \ |
432 | } \ | 463 | } |
433 | 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) | ||
434 | 467 | ||
435 | show_input(1); | 468 | show_input(1); |
436 | show_input(2); | 469 | show_input(2); |
@@ -449,6 +482,13 @@ show_input(14); | |||
449 | show_input(15); | 482 | show_input(15); |
450 | show_input(16); | 483 | show_input(16); |
451 | 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 | |||
452 | #define show_sensor(value) \ | 492 | #define show_sensor(value) \ |
453 | static ssize_t show_sensor##value(struct device *dev, \ | 493 | static ssize_t show_sensor##value(struct device *dev, \ |
454 | struct device_attribute *attr, \ | 494 | struct device_attribute *attr, \ |
@@ -457,8 +497,10 @@ static ssize_t show_sensor##value(struct device *dev, \ | |||
457 | struct interfacekit *kit = dev_get_drvdata(dev); \ | 497 | struct interfacekit *kit = dev_get_drvdata(dev); \ |
458 | \ | 498 | \ |
459 | return sprintf(buf, "%d\n", (int)kit->sensors[value - 1]); \ | 499 | return sprintf(buf, "%d\n", (int)kit->sensors[value - 1]); \ |
460 | } \ | 500 | } |
461 | 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) | ||
462 | 504 | ||
463 | show_sensor(1); | 505 | show_sensor(1); |
464 | show_sensor(2); | 506 | show_sensor(2); |
@@ -469,6 +511,11 @@ show_sensor(6); | |||
469 | show_sensor(7); | 511 | show_sensor(7); |
470 | show_sensor(8); | 512 | show_sensor(8); |
471 | 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 | |||
472 | 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) |
473 | { | 520 | { |
474 | struct usb_device *dev = interface_to_usbdev(intf); | 521 | struct usb_device *dev = interface_to_usbdev(intf); |
@@ -477,7 +524,7 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic | |||
477 | struct interfacekit *kit; | 524 | struct interfacekit *kit; |
478 | struct driver_interfacekit *ifkit; | 525 | struct driver_interfacekit *ifkit; |
479 | int pipe, maxp, rc = -ENOMEM; | 526 | int pipe, maxp, rc = -ENOMEM; |
480 | int bit, value; | 527 | int bit, value, i; |
481 | 528 | ||
482 | ifkit = (struct driver_interfacekit *)id->driver_info; | 529 | ifkit = (struct driver_interfacekit *)id->driver_info; |
483 | if (!ifkit) | 530 | if (!ifkit) |
@@ -541,74 +588,49 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic | |||
541 | goto out; | 588 | goto out; |
542 | } | 589 | } |
543 | 590 | ||
544 | if (ifkit->outputs >= 4) { | 591 | for (i=0; i<ifkit->outputs; i++ ) { |
545 | device_create_file(kit->dev, &dev_attr_output1); | 592 | rc = device_create_file(kit->dev, &dev_output_attrs[i]); |
546 | device_create_file(kit->dev, &dev_attr_output2); | 593 | if (rc) |
547 | device_create_file(kit->dev, &dev_attr_output3); | 594 | goto out2; |
548 | device_create_file(kit->dev, &dev_attr_output4); | ||
549 | } | ||
550 | if (ifkit->outputs >= 8) { | ||
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); | ||
555 | } | ||
556 | if (ifkit->outputs == 16) { | ||
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); | ||
565 | } | 595 | } |
566 | 596 | ||
567 | if (ifkit->inputs >= 4) { | 597 | for (i=0; i<ifkit->inputs; i++ ) { |
568 | device_create_file(kit->dev, &dev_attr_input1); | 598 | rc = device_create_file(kit->dev, &dev_input_attrs[i]); |
569 | device_create_file(kit->dev, &dev_attr_input2); | 599 | if (rc) |
570 | device_create_file(kit->dev, &dev_attr_input3); | 600 | goto out3; |
571 | device_create_file(kit->dev, &dev_attr_input4); | ||
572 | } | ||
573 | if (ifkit->inputs >= 8) { | ||
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); | ||
578 | } | ||
579 | if (ifkit->inputs == 16) { | ||
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); | ||
588 | } | 601 | } |
589 | 602 | ||
590 | if (ifkit->sensors >= 4) { | 603 | for (i=0; i<ifkit->sensors; i++ ) { |
591 | device_create_file(kit->dev, &dev_attr_sensor1); | 604 | rc = device_create_file(kit->dev, &dev_sensor_attrs[i]); |
592 | device_create_file(kit->dev, &dev_attr_sensor2); | 605 | if (rc) |
593 | device_create_file(kit->dev, &dev_attr_sensor3); | 606 | goto out4; |
594 | device_create_file(kit->dev, &dev_attr_sensor4); | ||
595 | } | ||
596 | if (ifkit->sensors >= 7) { | ||
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); | ||
600 | } | 607 | } |
601 | if (ifkit->sensors == 8) | ||
602 | device_create_file(kit->dev, &dev_attr_sensor8); | ||
603 | 608 | ||
604 | if (ifkit->has_lcd) | 609 | if (ifkit->has_lcd) { |
605 | device_create_file(kit->dev, &dev_attr_lcd); | 610 | rc = device_create_file(kit->dev, &dev_attr_lcd); |
611 | if (rc) | ||
612 | goto out4; | ||
613 | |||
614 | } | ||
606 | 615 | ||
607 | dev_info(&intf->dev, "USB PhidgetInterfaceKit %d/%d/%d attached\n", | 616 | dev_info(&intf->dev, "USB PhidgetInterfaceKit %d/%d/%d attached\n", |
608 | ifkit->sensors, ifkit->inputs, ifkit->outputs); | 617 | ifkit->sensors, ifkit->inputs, ifkit->outputs); |
609 | 618 | ||
610 | return 0; | 619 | return 0; |
611 | 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]); | ||
612 | out: | 634 | out: |
613 | if (kit) { | 635 | if (kit) { |
614 | if (kit->irq) | 636 | if (kit->irq) |
@@ -629,6 +651,7 @@ out: | |||
629 | static void interfacekit_disconnect(struct usb_interface *interface) | 651 | static void interfacekit_disconnect(struct usb_interface *interface) |
630 | { | 652 | { |
631 | struct interfacekit *kit; | 653 | struct interfacekit *kit; |
654 | int i; | ||
632 | 655 | ||
633 | kit = usb_get_intfdata(interface); | 656 | kit = usb_get_intfdata(interface); |
634 | usb_set_intfdata(interface, NULL); | 657 | usb_set_intfdata(interface, NULL); |
@@ -641,68 +664,19 @@ static void interfacekit_disconnect(struct usb_interface *interface) | |||
641 | 664 | ||
642 | cancel_delayed_work(&kit->do_notify); | 665 | cancel_delayed_work(&kit->do_notify); |
643 | 666 | ||
644 | if (kit->ifkit->outputs >= 4) { | 667 | for (i=0; i<kit->ifkit->outputs; i++) |
645 | device_remove_file(kit->dev, &dev_attr_output1); | 668 | device_remove_file(kit->dev, &dev_output_attrs[i]); |
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); | ||
649 | } | ||
650 | if (kit->ifkit->outputs >= 8) { | ||
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); | ||
655 | } | ||
656 | if (kit->ifkit->outputs == 16) { | ||
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); | ||
665 | } | ||
666 | 669 | ||
667 | if (kit->ifkit->inputs >= 4) { | 670 | for (i=0; i<kit->ifkit->inputs; i++) |
668 | device_remove_file(kit->dev, &dev_attr_input1); | 671 | device_remove_file(kit->dev, &dev_input_attrs[i]); |
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); | ||
672 | } | ||
673 | if (kit->ifkit->inputs >= 8) { | ||
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); | ||
678 | } | ||
679 | if (kit->ifkit->inputs == 16) { | ||
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); | ||
688 | } | ||
689 | 672 | ||
690 | if (kit->ifkit->sensors >= 4) { | 673 | for (i=0; i<kit->ifkit->sensors; i++) |
691 | device_remove_file(kit->dev, &dev_attr_sensor1); | 674 | device_remove_file(kit->dev, &dev_sensor_attrs[i]); |
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); | ||
695 | } | ||
696 | if (kit->ifkit->sensors >= 7) { | ||
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); | ||
700 | } | ||
701 | if (kit->ifkit->sensors == 8) | ||
702 | device_remove_file(kit->dev, &dev_attr_sensor8); | ||
703 | 675 | ||
704 | if (kit->ifkit->has_lcd) | 676 | if (kit->ifkit->has_lcd) { |
705 | device_remove_file(kit->dev, &dev_attr_lcd); | 677 | device_remove_file(kit->dev, &dev_attr_lcd); |
678 | remove_lcd_files(kit); | ||
679 | } | ||
706 | 680 | ||
707 | device_unregister(kit->dev); | 681 | device_unregister(kit->dev); |
708 | 682 | ||