Commit 6c3c58d9 authored by James Bottomley's avatar James Bottomley

SCSI: Add transport destructors

From: 	James.Smart@Emulex.Com

This patch adds host/target/sdev destructor functions to the transport
template. The FC transport is updated to utilize them to cancel any
outstanding timer. It slightly rearranges the slave_xxx functions so
the transport is always involved prior to the LLDD.

Minor rejection fixes and
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent e2a65cc5
......@@ -81,6 +81,8 @@ void scsi_remove_host(struct Scsi_Host *shost)
set_bit(SHOST_DEL, &shost->shost_state);
if (shost->transportt->host_destroy)
shost->transportt->host_destroy(shost);
class_device_unregister(&shost->shost_classdev);
if (shost->transport_classdev.class)
class_device_unregister(&shost->transport_classdev);
......@@ -135,11 +137,14 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
error = scsi_sysfs_add_host(shost);
if (error)
goto out_del_classdev;
goto out_destroy_host;
scsi_proc_host_add(shost);
return error;
out_destroy_host:
if (shost->transportt->host_destroy)
shost->transportt->host_destroy(shost);
out_del_classdev:
class_device_del(&shost->shost_classdev);
out_del_gendev:
......
......@@ -253,6 +253,11 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
sdev->request_queue->queuedata = sdev;
scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
if (shost->transportt->device_setup) {
if (shost->transportt->device_setup(sdev))
goto out_free_queue;
}
if (shost->hostt->slave_alloc) {
ret = shost->hostt->slave_alloc(sdev);
if (ret) {
......@@ -262,15 +267,10 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
*/
if (ret == -ENXIO)
display_failure_msg = 0;
goto out_free_queue;
goto out_device_destroy;
}
}
if (shost->transportt->device_setup) {
if (shost->transportt->device_setup(sdev))
goto out_cleanup_slave;
}
if (scsi_sysfs_device_initialize(sdev) != 0)
goto out_cleanup_slave;
......@@ -290,6 +290,9 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
out_cleanup_slave:
if (shost->hostt->slave_destroy)
shost->hostt->slave_destroy(sdev);
out_device_destroy:
if (shost->transportt->device_destroy)
shost->transportt->device_destroy(sdev);
out_free_queue:
scsi_free_queue(sdev->request_queue);
out_free_dev:
......@@ -741,6 +744,8 @@ static int scsi_probe_and_add_lun(struct Scsi_Host *host,
} else {
if (sdev->host->hostt->slave_destroy)
sdev->host->hostt->slave_destroy(sdev);
if (sdev->host->transportt->device_destroy)
sdev->host->transportt->device_destroy(sdev);
put_device(&sdev->sdev_gendev);
}
out:
......@@ -1299,5 +1304,7 @@ void scsi_free_host_dev(struct scsi_device *sdev)
if (sdev->host->hostt->slave_destroy)
sdev->host->hostt->slave_destroy(sdev);
if (sdev->host->transportt->device_destroy)
sdev->host->transportt->device_destroy(sdev);
put_device(&sdev->sdev_gendev);
}
......@@ -169,7 +169,10 @@ void scsi_device_dev_release(struct device *dev)
if (delete) {
struct scsi_target *starget = to_scsi_target(parent);
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
if (!starget->create) {
if (shost->transportt->target_destroy)
shost->transportt->target_destroy(starget);
device_del(parent);
if (starget->transport_classdev.class)
class_device_unregister(&starget->transport_classdev);
......@@ -601,6 +604,8 @@ void scsi_remove_device(struct scsi_device *sdev)
scsi_device_set_state(sdev, SDEV_DEL);
if (sdev->host->hostt->slave_destroy)
sdev->host->hostt->slave_destroy(sdev);
if (sdev->host->transportt->device_destroy)
sdev->host->transportt->device_destroy(sdev);
put_device(&sdev->sdev_gendev);
out:
......
......@@ -94,6 +94,13 @@ static int fc_setup_starget_transport_attrs(struct scsi_target *starget)
return 0;
}
static void fc_destroy_starget(struct scsi_target *starget)
{
/* Stop the target timer */
if (cancel_delayed_work(&fc_starget_dev_loss_work(starget)))
flush_scheduled_work();
}
static int fc_setup_host_transport_attrs(struct Scsi_Host *shost)
{
/*
......@@ -107,6 +114,13 @@ static int fc_setup_host_transport_attrs(struct Scsi_Host *shost)
return 0;
}
static void fc_destroy_host(struct Scsi_Host *shost)
{
/* Stop the host timer */
if (cancel_delayed_work(&fc_host_link_down_work(shost)))
flush_scheduled_work();
}
static void transport_class_release(struct class_device *class_dev)
{
struct scsi_target *starget = transport_class_to_starget(class_dev);
......@@ -281,11 +295,13 @@ fc_attach_transport(struct fc_function_template *ft)
i->t.target_attrs = &i->starget_attrs[0];
i->t.target_class = &fc_transport_class;
i->t.target_setup = &fc_setup_starget_transport_attrs;
i->t.target_destroy = &fc_destroy_starget;
i->t.target_size = sizeof(struct fc_starget_attrs);
i->t.host_attrs = &i->host_attrs[0];
i->t.host_class = &fc_host_class;
i->t.host_setup = &fc_setup_host_transport_attrs;
i->t.host_destroy = &fc_destroy_host;
i->t.host_size = sizeof(struct fc_host_attrs);
i->f = ft;
......
......@@ -40,6 +40,11 @@ struct scsi_transport_template {
int (*target_setup)(struct scsi_target *);
int (*host_setup)(struct Scsi_Host *);
/* Destructor functions */
void (*device_destroy)(struct scsi_device *);
void (*target_destroy)(struct scsi_target *);
void (*host_destroy)(struct Scsi_Host *);
/* The size of the specific transport attribute structure (a
* space of this size will be left at the end of the
* scsi_* structure */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment