From: Brian King Date: Thu, 15 Mar 2012 02:20:06 +0000 (-0500) Subject: [SCSI] ipr: Fix target id allocation re-use problem X-Git-Tag: v3.4-rc1~6^2~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0ee1d714c285aabaadf7495bf5820114ad0959b1;p=platform%2Fkernel%2Flinux-exynos.git [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 Signed-off-by: James Bottomley --- diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index cdfe5a1..dcad238 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) list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { if ((res->bus == starget->channel) && - (res->target == starget->id) && - (res->lun == 0)) { + (res->target == starget->id)) { return res; } } @@ -4414,12 +4413,14 @@ static void ipr_target_destroy(struct scsi_target *starget) struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata; if (ioa_cfg->sis64) { - if (starget->channel == IPR_ARRAY_VIRTUAL_BUS) - clear_bit(starget->id, ioa_cfg->array_ids); - else if (starget->channel == IPR_VSET_VIRTUAL_BUS) - clear_bit(starget->id, ioa_cfg->vset_ids); - else if (starget->channel == 0) - clear_bit(starget->id, ioa_cfg->target_ids); + if (!ipr_find_starget(starget)) { + if (starget->channel == IPR_ARRAY_VIRTUAL_BUS) + clear_bit(starget->id, ioa_cfg->array_ids); + else if (starget->channel == IPR_VSET_VIRTUAL_BUS) + clear_bit(starget->id, ioa_cfg->vset_ids); + else if (starget->channel == 0) + clear_bit(starget->id, ioa_cfg->target_ids); + } } if (sata_port) {