diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-03-22 23:42:27 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-04-22 16:16:31 -0400 |
commit | 643eb2d932c97a0583381629d632d486934cf7ee (patch) | |
tree | 514d860d8b6c22f50b8fdd7afd25047707321650 /drivers/scsi/scsi_sysfs.c | |
parent | f7120a4f75168df3c02efacd10403a4ba0bcb29d (diff) |
[SCSI] rework scsi_target allocation
The current target allocation code registeres each possible target
with sysfs; it will be deleted again if no useable LUN on this target
was found. This results in a string of 'target add/target remove' uevents.
Based on a patch by Hannes Reinecke <hare@suse.de> this patch reworks
the target allocation code so that only uevents for existing targets
are sent. The sysfs registration is split off from the existing
scsi_target_alloc() into a in a new scsi_add_target() function, which
should be called whenever an existing target is found. Only then a
uevent is sent, so we'll be generating events for existing targets
only.
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/scsi_sysfs.c')
-rw-r--r-- | drivers/scsi/scsi_sysfs.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 84e2a8ad83c9..198aa4571e35 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -809,6 +809,27 @@ sdev_store_queue_type_rw(struct device *dev, struct device_attribute *attr, | |||
809 | return count; | 809 | return count; |
810 | } | 810 | } |
811 | 811 | ||
812 | static int scsi_target_add(struct scsi_target *starget) | ||
813 | { | ||
814 | int error; | ||
815 | |||
816 | if (starget->state != STARGET_CREATED) | ||
817 | return 0; | ||
818 | |||
819 | error = device_add(&starget->dev); | ||
820 | if (error) { | ||
821 | dev_err(&starget->dev, "target device_add failed, error %d\n", error); | ||
822 | get_device(&starget->dev); | ||
823 | scsi_target_reap(starget); | ||
824 | put_device(&starget->dev); | ||
825 | return error; | ||
826 | } | ||
827 | transport_add_device(&starget->dev); | ||
828 | starget->state = STARGET_RUNNING; | ||
829 | |||
830 | return 0; | ||
831 | } | ||
832 | |||
812 | static struct device_attribute sdev_attr_queue_type_rw = | 833 | static struct device_attribute sdev_attr_queue_type_rw = |
813 | __ATTR(queue_type, S_IRUGO | S_IWUSR, show_queue_type_field, | 834 | __ATTR(queue_type, S_IRUGO | S_IWUSR, show_queue_type_field, |
814 | sdev_store_queue_type_rw); | 835 | sdev_store_queue_type_rw); |
@@ -824,10 +845,16 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) | |||
824 | { | 845 | { |
825 | int error, i; | 846 | int error, i; |
826 | struct request_queue *rq = sdev->request_queue; | 847 | struct request_queue *rq = sdev->request_queue; |
848 | struct scsi_target *starget = sdev->sdev_target; | ||
827 | 849 | ||
828 | if ((error = scsi_device_set_state(sdev, SDEV_RUNNING)) != 0) | 850 | if ((error = scsi_device_set_state(sdev, SDEV_RUNNING)) != 0) |
829 | return error; | 851 | return error; |
830 | 852 | ||
853 | error = scsi_target_add(starget); | ||
854 | if (error) | ||
855 | return error; | ||
856 | |||
857 | transport_configure_device(&starget->dev); | ||
831 | error = device_add(&sdev->sdev_gendev); | 858 | error = device_add(&sdev->sdev_gendev); |
832 | if (error) { | 859 | if (error) { |
833 | put_device(sdev->sdev_gendev.parent); | 860 | put_device(sdev->sdev_gendev.parent); |