aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2006-06-26 14:19:59 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-06-27 12:01:46 -0400
commit3bdad7bd253f17ead00b4af2e82f84e9522c95ac (patch)
tree2f25e9ec91e76a19ceb939552ef21ee9713fb4b5 /drivers/scsi
parent1c9e16e47a22c61d99aabb1c154e5106ddbf3575 (diff)
[SCSI] fc transport: bug fix: correct references
Original post was incorrect as it didn't realize that we already had a self-referenc due to device_initialize(), and we were really only missing the put on our own reference. This was hidden by the other bug which had the midlayer reusing stargets after they were already free, which was doing too many puts on our rport. Updating FC transport for: - Add put in fc_rport_final_delete(), to release the rport. Prior, we were leaving the rport with a reference, thus the shost with references, etc. If the driver was unloaded, shosts and rports remained, along with work threads, etc - Fix fc_rport_create failure path - too many put's on parent - Add commenting to easily track ref taking. Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/scsi_transport_fc.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index df6263dfd791..b03aa85108e5 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -1476,7 +1476,8 @@ fc_rport_final_delete(void *data)
1476 transport_remove_device(dev); 1476 transport_remove_device(dev);
1477 device_del(dev); 1477 device_del(dev);
1478 transport_destroy_device(dev); 1478 transport_destroy_device(dev);
1479 put_device(&shost->shost_gendev); 1479 put_device(&shost->shost_gendev); /* for fc_host->rport list */
1480 put_device(dev); /* for self-reference */
1480} 1481}
1481 1482
1482 1483
@@ -1537,13 +1538,13 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
1537 else 1538 else
1538 rport->scsi_target_id = -1; 1539 rport->scsi_target_id = -1;
1539 list_add_tail(&rport->peers, &fc_host->rports); 1540 list_add_tail(&rport->peers, &fc_host->rports);
1540 get_device(&shost->shost_gendev); 1541 get_device(&shost->shost_gendev); /* for fc_host->rport list */
1541 1542
1542 spin_unlock_irqrestore(shost->host_lock, flags); 1543 spin_unlock_irqrestore(shost->host_lock, flags);
1543 1544
1544 dev = &rport->dev; 1545 dev = &rport->dev;
1545 device_initialize(dev); 1546 device_initialize(dev); /* takes self reference */
1546 dev->parent = get_device(&shost->shost_gendev); 1547 dev->parent = get_device(&shost->shost_gendev); /* parent reference */
1547 dev->release = fc_rport_dev_release; 1548 dev->release = fc_rport_dev_release;
1548 sprintf(dev->bus_id, "rport-%d:%d-%d", 1549 sprintf(dev->bus_id, "rport-%d:%d-%d",
1549 shost->host_no, channel, rport->number); 1550 shost->host_no, channel, rport->number);
@@ -1567,10 +1568,9 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
1567 1568
1568delete_rport: 1569delete_rport:
1569 transport_destroy_device(dev); 1570 transport_destroy_device(dev);
1570 put_device(dev->parent);
1571 spin_lock_irqsave(shost->host_lock, flags); 1571 spin_lock_irqsave(shost->host_lock, flags);
1572 list_del(&rport->peers); 1572 list_del(&rport->peers);
1573 put_device(&shost->shost_gendev); 1573 put_device(&shost->shost_gendev); /* for fc_host->rport list */
1574 spin_unlock_irqrestore(shost->host_lock, flags); 1574 spin_unlock_irqrestore(shost->host_lock, flags);
1575 put_device(dev->parent); 1575 put_device(dev->parent);
1576 kfree(rport); 1576 kfree(rport);