diff options
Diffstat (limited to 'drivers/firewire/fw-device.c')
-rw-r--r-- | drivers/firewire/fw-device.c | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c index de9066e69adf..2ab13e0f3469 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/fw-device.c | |||
@@ -358,12 +358,9 @@ static ssize_t | |||
358 | guid_show(struct device *dev, struct device_attribute *attr, char *buf) | 358 | guid_show(struct device *dev, struct device_attribute *attr, char *buf) |
359 | { | 359 | { |
360 | struct fw_device *device = fw_device(dev); | 360 | struct fw_device *device = fw_device(dev); |
361 | u64 guid; | ||
362 | 361 | ||
363 | guid = ((u64)device->config_rom[3] << 32) | device->config_rom[4]; | 362 | return snprintf(buf, PAGE_SIZE, "0x%08x%08x\n", |
364 | 363 | device->config_rom[3], device->config_rom[4]); | |
365 | return snprintf(buf, PAGE_SIZE, "0x%016llx\n", | ||
366 | (unsigned long long)guid); | ||
367 | } | 364 | } |
368 | 365 | ||
369 | static struct device_attribute fw_device_attributes[] = { | 366 | static struct device_attribute fw_device_attributes[] = { |
@@ -610,12 +607,14 @@ static DECLARE_RWSEM(idr_rwsem); | |||
610 | static DEFINE_IDR(fw_device_idr); | 607 | static DEFINE_IDR(fw_device_idr); |
611 | int fw_cdev_major; | 608 | int fw_cdev_major; |
612 | 609 | ||
613 | struct fw_device *fw_device_from_devt(dev_t devt) | 610 | struct fw_device *fw_device_get_by_devt(dev_t devt) |
614 | { | 611 | { |
615 | struct fw_device *device; | 612 | struct fw_device *device; |
616 | 613 | ||
617 | down_read(&idr_rwsem); | 614 | down_read(&idr_rwsem); |
618 | device = idr_find(&fw_device_idr, MINOR(devt)); | 615 | device = idr_find(&fw_device_idr, MINOR(devt)); |
616 | if (device) | ||
617 | fw_device_get(device); | ||
619 | up_read(&idr_rwsem); | 618 | up_read(&idr_rwsem); |
620 | 619 | ||
621 | return device; | 620 | return device; |
@@ -627,13 +626,14 @@ static void fw_device_shutdown(struct work_struct *work) | |||
627 | container_of(work, struct fw_device, work.work); | 626 | container_of(work, struct fw_device, work.work); |
628 | int minor = MINOR(device->device.devt); | 627 | int minor = MINOR(device->device.devt); |
629 | 628 | ||
630 | down_write(&idr_rwsem); | ||
631 | idr_remove(&fw_device_idr, minor); | ||
632 | up_write(&idr_rwsem); | ||
633 | |||
634 | fw_device_cdev_remove(device); | 629 | fw_device_cdev_remove(device); |
635 | device_for_each_child(&device->device, NULL, shutdown_unit); | 630 | device_for_each_child(&device->device, NULL, shutdown_unit); |
636 | device_unregister(&device->device); | 631 | device_unregister(&device->device); |
632 | |||
633 | down_write(&idr_rwsem); | ||
634 | idr_remove(&fw_device_idr, minor); | ||
635 | up_write(&idr_rwsem); | ||
636 | fw_device_put(device); | ||
637 | } | 637 | } |
638 | 638 | ||
639 | static struct device_type fw_device_type = { | 639 | static struct device_type fw_device_type = { |
@@ -682,10 +682,13 @@ static void fw_device_init(struct work_struct *work) | |||
682 | } | 682 | } |
683 | 683 | ||
684 | err = -ENOMEM; | 684 | err = -ENOMEM; |
685 | |||
686 | fw_device_get(device); | ||
685 | down_write(&idr_rwsem); | 687 | down_write(&idr_rwsem); |
686 | if (idr_pre_get(&fw_device_idr, GFP_KERNEL)) | 688 | if (idr_pre_get(&fw_device_idr, GFP_KERNEL)) |
687 | err = idr_get_new(&fw_device_idr, device, &minor); | 689 | err = idr_get_new(&fw_device_idr, device, &minor); |
688 | up_write(&idr_rwsem); | 690 | up_write(&idr_rwsem); |
691 | |||
689 | if (err < 0) | 692 | if (err < 0) |
690 | goto error; | 693 | goto error; |
691 | 694 | ||
@@ -717,13 +720,22 @@ static void fw_device_init(struct work_struct *work) | |||
717 | */ | 720 | */ |
718 | if (atomic_cmpxchg(&device->state, | 721 | if (atomic_cmpxchg(&device->state, |
719 | FW_DEVICE_INITIALIZING, | 722 | FW_DEVICE_INITIALIZING, |
720 | FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) | 723 | FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) { |
721 | fw_device_shutdown(&device->work.work); | 724 | fw_device_shutdown(&device->work.work); |
722 | else | 725 | } else { |
723 | fw_notify("created new fw device %s " | 726 | if (device->config_rom_retries) |
724 | "(%d config rom retries, S%d00)\n", | 727 | fw_notify("created device %s: GUID %08x%08x, S%d00, " |
725 | device->device.bus_id, device->config_rom_retries, | 728 | "%d config ROM retries\n", |
726 | 1 << device->max_speed); | 729 | device->device.bus_id, |
730 | device->config_rom[3], device->config_rom[4], | ||
731 | 1 << device->max_speed, | ||
732 | device->config_rom_retries); | ||
733 | else | ||
734 | fw_notify("created device %s: GUID %08x%08x, S%d00\n", | ||
735 | device->device.bus_id, | ||
736 | device->config_rom[3], device->config_rom[4], | ||
737 | 1 << device->max_speed); | ||
738 | } | ||
727 | 739 | ||
728 | /* | 740 | /* |
729 | * Reschedule the IRM work if we just finished reading the | 741 | * Reschedule the IRM work if we just finished reading the |
@@ -741,7 +753,9 @@ static void fw_device_init(struct work_struct *work) | |||
741 | idr_remove(&fw_device_idr, minor); | 753 | idr_remove(&fw_device_idr, minor); |
742 | up_write(&idr_rwsem); | 754 | up_write(&idr_rwsem); |
743 | error: | 755 | error: |
744 | put_device(&device->device); | 756 | fw_device_put(device); /* fw_device_idr's reference */ |
757 | |||
758 | put_device(&device->device); /* our reference */ | ||
745 | } | 759 | } |
746 | 760 | ||
747 | static int update_unit(struct device *dev, void *data) | 761 | static int update_unit(struct device *dev, void *data) |