aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-device.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firewire/fw-device.c')
-rw-r--r--drivers/firewire/fw-device.c48
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
358guid_show(struct device *dev, struct device_attribute *attr, char *buf) 358guid_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
369static struct device_attribute fw_device_attributes[] = { 366static struct device_attribute fw_device_attributes[] = {
@@ -610,12 +607,14 @@ static DECLARE_RWSEM(idr_rwsem);
610static DEFINE_IDR(fw_device_idr); 607static DEFINE_IDR(fw_device_idr);
611int fw_cdev_major; 608int fw_cdev_major;
612 609
613struct fw_device *fw_device_from_devt(dev_t devt) 610struct 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
639static struct device_type fw_device_type = { 639static 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
747static int update_unit(struct device *dev, void *data) 761static int update_unit(struct device *dev, void *data)