diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-08-01 00:39:36 +0000 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-08-22 17:52:13 -0500 |
commit | 163f52b6cf3a639df6a72c7937e0eb88b20f1ef3 (patch) | |
tree | 68991096e7ff15e31db28fb0d7bf2e87b1bd01c2 /drivers/scsi/ses.c | |
parent | 0124ca9d8ee58b3cd028a23cef2fe225fcfee3b8 (diff) | |
download | linux-163f52b6cf3a639df6a72c7937e0eb88b20f1ef3.tar.gz linux-163f52b6cf3a639df6a72c7937e0eb88b20f1ef3.tar.bz2 linux-163f52b6cf3a639df6a72c7937e0eb88b20f1ef3.zip |
[SCSI] ses: fix hotplug with multiple devices and expanders
In a situation either with expanders or with multiple enclosure
devices, hot add doesn't always work. This is because we try to find
a single enclosure device attached to the host. Fix this by looping
over all enclosure devices attached to the host and also by making the
find loop recognise that the enclosure devices may be expander remote
(i.e. not parented by the host).
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/ses.c')
-rw-r--r-- | drivers/scsi/ses.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 4f618f487356..e1b8c828f03a 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -413,10 +413,11 @@ static int ses_intf_add(struct device *cdev, if (!scsi_device_enclosure(sdev)) { /* not an enclosure, but might be in one */ - edev = enclosure_find(&sdev->host->shost_gendev); - if (edev) { + struct enclosure_device *prev = NULL; + + while ((edev = enclosure_find(&sdev->host->shost_gendev, prev)) != NULL) { ses_match_to_enclosure(edev, sdev); - put_device(&edev->edev); + prev = edev; } return -ENODEV; } @@ -625,7 +626,8 @@ static void ses_intf_remove(struct device *cdev, if (!scsi_device_enclosure(sdev)) return; - edev = enclosure_find(cdev->parent); + /* exact match to this enclosure */ + edev = enclosure_find(cdev->parent, NULL); if (!edev) return; |