diff options
Diffstat (limited to 'drivers/firewire/fw-device.c')
-rw-r--r-- | drivers/firewire/fw-device.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c index de9066e69adf..c04c28800f1d 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/fw-device.c | |||
@@ -610,12 +610,14 @@ static DECLARE_RWSEM(idr_rwsem); | |||
610 | static DEFINE_IDR(fw_device_idr); | 610 | static DEFINE_IDR(fw_device_idr); |
611 | int fw_cdev_major; | 611 | int fw_cdev_major; |
612 | 612 | ||
613 | struct fw_device *fw_device_from_devt(dev_t devt) | 613 | struct fw_device *fw_device_get_by_devt(dev_t devt) |
614 | { | 614 | { |
615 | struct fw_device *device; | 615 | struct fw_device *device; |
616 | 616 | ||
617 | down_read(&idr_rwsem); | 617 | down_read(&idr_rwsem); |
618 | device = idr_find(&fw_device_idr, MINOR(devt)); | 618 | device = idr_find(&fw_device_idr, MINOR(devt)); |
619 | if (device) | ||
620 | fw_device_get(device); | ||
619 | up_read(&idr_rwsem); | 621 | up_read(&idr_rwsem); |
620 | 622 | ||
621 | return device; | 623 | return device; |
@@ -627,13 +629,14 @@ static void fw_device_shutdown(struct work_struct *work) | |||
627 | container_of(work, struct fw_device, work.work); | 629 | container_of(work, struct fw_device, work.work); |
628 | int minor = MINOR(device->device.devt); | 630 | int minor = MINOR(device->device.devt); |
629 | 631 | ||
630 | down_write(&idr_rwsem); | ||
631 | idr_remove(&fw_device_idr, minor); | ||
632 | up_write(&idr_rwsem); | ||
633 | |||
634 | fw_device_cdev_remove(device); | 632 | fw_device_cdev_remove(device); |
635 | device_for_each_child(&device->device, NULL, shutdown_unit); | 633 | device_for_each_child(&device->device, NULL, shutdown_unit); |
636 | device_unregister(&device->device); | 634 | device_unregister(&device->device); |
635 | |||
636 | down_write(&idr_rwsem); | ||
637 | idr_remove(&fw_device_idr, minor); | ||
638 | up_write(&idr_rwsem); | ||
639 | fw_device_put(device); | ||
637 | } | 640 | } |
638 | 641 | ||
639 | static struct device_type fw_device_type = { | 642 | static struct device_type fw_device_type = { |
@@ -682,10 +685,13 @@ static void fw_device_init(struct work_struct *work) | |||
682 | } | 685 | } |
683 | 686 | ||
684 | err = -ENOMEM; | 687 | err = -ENOMEM; |
688 | |||
689 | fw_device_get(device); | ||
685 | down_write(&idr_rwsem); | 690 | down_write(&idr_rwsem); |
686 | if (idr_pre_get(&fw_device_idr, GFP_KERNEL)) | 691 | if (idr_pre_get(&fw_device_idr, GFP_KERNEL)) |
687 | err = idr_get_new(&fw_device_idr, device, &minor); | 692 | err = idr_get_new(&fw_device_idr, device, &minor); |
688 | up_write(&idr_rwsem); | 693 | up_write(&idr_rwsem); |
694 | |||
689 | if (err < 0) | 695 | if (err < 0) |
690 | goto error; | 696 | goto error; |
691 | 697 | ||
@@ -741,7 +747,9 @@ static void fw_device_init(struct work_struct *work) | |||
741 | idr_remove(&fw_device_idr, minor); | 747 | idr_remove(&fw_device_idr, minor); |
742 | up_write(&idr_rwsem); | 748 | up_write(&idr_rwsem); |
743 | error: | 749 | error: |
744 | put_device(&device->device); | 750 | fw_device_put(device); /* fw_device_idr's reference */ |
751 | |||
752 | put_device(&device->device); /* our reference */ | ||
745 | } | 753 | } |
746 | 754 | ||
747 | static int update_unit(struct device *dev, void *data) | 755 | static int update_unit(struct device *dev, void *data) |