aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorBrian King <brking@linux.vnet.ibm.com>2012-03-14 22:20:06 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-03-28 09:58:11 -0400
commit0ee1d714c285aabaadf7495bf5820114ad0959b1 (patch)
treea5213395c887cb568943987c9b4aca1c18b8614f /drivers/scsi
parent7d7311c44567cd2001ca318e4de64b753d9d35f8 (diff)
[SCSI] ipr: Fix target id allocation re-use problem
For the latest ipr SAS adapters, target id's are a completely logical construct that are managed in the ipr driver. This fixes an issue that can arise if a device is deleted via sysfs. If a new device is then physically added, it will use the previous device's target id. If the host is then rescanned, the device that had been deleted, since it is using the same target id as the new device is using, will never be found, resulting in a missing device. Fix this by only freeing the target id only if the resource is actually gone. Signed-off-by: Brian King <brking@linux.vnet.ibm.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/ipr.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index cdfe5a16de2a..dcad2389be3d 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -4339,8 +4339,7 @@ static struct ipr_resource_entry *ipr_find_starget(struct scsi_target *starget)
4339 4339
4340 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { 4340 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
4341 if ((res->bus == starget->channel) && 4341 if ((res->bus == starget->channel) &&
4342 (res->target == starget->id) && 4342 (res->target == starget->id)) {
4343 (res->lun == 0)) {
4344 return res; 4343 return res;
4345 } 4344 }
4346 } 4345 }
@@ -4414,12 +4413,14 @@ static void ipr_target_destroy(struct scsi_target *starget)
4414 struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata; 4413 struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata;
4415 4414
4416 if (ioa_cfg->sis64) { 4415 if (ioa_cfg->sis64) {
4417 if (starget->channel == IPR_ARRAY_VIRTUAL_BUS) 4416 if (!ipr_find_starget(starget)) {
4418 clear_bit(starget->id, ioa_cfg->array_ids); 4417 if (starget->channel == IPR_ARRAY_VIRTUAL_BUS)
4419 else if (starget->channel == IPR_VSET_VIRTUAL_BUS) 4418 clear_bit(starget->id, ioa_cfg->array_ids);
4420 clear_bit(starget->id, ioa_cfg->vset_ids); 4419 else if (starget->channel == IPR_VSET_VIRTUAL_BUS)
4421 else if (starget->channel == 0) 4420 clear_bit(starget->id, ioa_cfg->vset_ids);
4422 clear_bit(starget->id, ioa_cfg->target_ids); 4421 else if (starget->channel == 0)
4422 clear_bit(starget->id, ioa_cfg->target_ids);
4423 }
4423 } 4424 }
4424 4425
4425 if (sata_port) { 4426 if (sata_port) {