diff options
author | James Bottomley <James.Bottomley@steeleye.com> | 2005-05-24 21:06:38 +0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-05-26 19:27:53 +0400 |
commit | a283bd37d00e92e8874ca6325ae071691d4db388 (patch) | |
tree | 4c436d59fc326e3545c575a88b92fd31ace841a5 /drivers/scsi/scsi_scan.c | |
parent | 631e8a1398ce4cfef8b30678d51daf0c64313a09 (diff) | |
download | linux-a283bd37d00e92e8874ca6325ae071691d4db388.tar.xz |
[SCSI] Add target alloc/destroy callbacks to the host template
This gives the HBA driver notice when a target is created and
destroyed to allow it to manage its own target based allocations
accordingly.
This is a much reduced verson of the original patch sent in by
James.Smart@Emulex.com
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/scsi_scan.c')
-rw-r--r-- | drivers/scsi/scsi_scan.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 588611568d14..4d273ceb1d09 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -293,6 +293,10 @@ static void scsi_target_dev_release(struct device *dev) { struct device *parent = dev->parent; struct scsi_target *starget = to_scsi_target(dev); + struct Scsi_Host *shost = dev_to_shost(parent); + + if (shost->hostt->target_destroy) + shost->hostt->target_destroy(starget); kfree(starget); put_device(parent); } @@ -360,9 +364,23 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, list_add_tail(&starget->siblings, &shost->__targets); spin_unlock_irqrestore(shost->host_lock, flags); /* allocate and add */ - transport_setup_device(&starget->dev); - device_add(&starget->dev); - transport_add_device(&starget->dev); + transport_setup_device(dev); + device_add(dev); + transport_add_device(dev); + if (shost->hostt->target_alloc) { + int error = shost->hostt->target_alloc(starget); + + if(error) { + dev_printk(KERN_ERR, dev, "target allocation failed, error %d\n", error); + /* don't want scsi_target_reap to do the final + * put because it will be under the host lock */ + get_device(dev); + scsi_target_reap(starget); + put_device(dev); + return NULL; + } + } + return starget; found: |