diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-12-20 04:03:48 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-19 15:11:33 -0500 |
commit | 0b3e09da1350397f3f8b6fd839ab455b0b587451 (patch) | |
tree | f822bb4dcaa52d5d568104932ee55ee136dcf039 /drivers/scsi/scsi_transport_sas.c | |
parent | b52df4174dff7e587f6fbfb21e3c2cb57109e5cf (diff) |
[SCSI] libsas: perform sas-transport resets in shost->workq context
Extend the sas transport class to allow transport users to attach extra
data to a sas_phy (->hostdata). Use this area in libsas to move resets
to workq context in preparation for scheduling ata device resets through
libata-eh.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/scsi_transport_sas.c')
-rw-r--r-- | drivers/scsi/scsi_transport_sas.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index 9421bae8af1a..ab3bd0b5ffd9 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c | |||
@@ -652,9 +652,21 @@ sas_phy_linkerror_attr(running_disparity_error_count); | |||
652 | sas_phy_linkerror_attr(loss_of_dword_sync_count); | 652 | sas_phy_linkerror_attr(loss_of_dword_sync_count); |
653 | sas_phy_linkerror_attr(phy_reset_problem_count); | 653 | sas_phy_linkerror_attr(phy_reset_problem_count); |
654 | 654 | ||
655 | static int sas_phy_setup(struct transport_container *tc, struct device *dev, | ||
656 | struct device *cdev) | ||
657 | { | ||
658 | struct sas_phy *phy = dev_to_phy(dev); | ||
659 | struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); | ||
660 | struct sas_internal *i = to_sas_internal(shost->transportt); | ||
661 | |||
662 | if (i->f->phy_setup) | ||
663 | i->f->phy_setup(phy); | ||
664 | |||
665 | return 0; | ||
666 | } | ||
655 | 667 | ||
656 | static DECLARE_TRANSPORT_CLASS(sas_phy_class, | 668 | static DECLARE_TRANSPORT_CLASS(sas_phy_class, |
657 | "sas_phy", NULL, NULL, NULL); | 669 | "sas_phy", sas_phy_setup, NULL, NULL); |
658 | 670 | ||
659 | static int sas_phy_match(struct attribute_container *cont, struct device *dev) | 671 | static int sas_phy_match(struct attribute_container *cont, struct device *dev) |
660 | { | 672 | { |
@@ -678,7 +690,11 @@ static int sas_phy_match(struct attribute_container *cont, struct device *dev) | |||
678 | static void sas_phy_release(struct device *dev) | 690 | static void sas_phy_release(struct device *dev) |
679 | { | 691 | { |
680 | struct sas_phy *phy = dev_to_phy(dev); | 692 | struct sas_phy *phy = dev_to_phy(dev); |
693 | struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); | ||
694 | struct sas_internal *i = to_sas_internal(shost->transportt); | ||
681 | 695 | ||
696 | if (i->f->phy_release) | ||
697 | i->f->phy_release(phy); | ||
682 | put_device(dev->parent); | 698 | put_device(dev->parent); |
683 | kfree(phy); | 699 | kfree(phy); |
684 | } | 700 | } |