diff options
author | Dan Williams <dan.j.williams@intel.com> | 2012-03-22 00:09:07 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-04-23 07:11:47 -0400 |
commit | b2024459252a9d2d312ee562f86f332a1498f412 (patch) | |
tree | 751987779eee44a601a68c766ba2ff258b77d25a /drivers/ata | |
parent | 0f3fce5cc77e1f35758ef0e46a989e76e5046a7b (diff) |
[SCSI] libsas, libata: fix start of life for a sas ata_port
This changes the ordering of initialization and probing events from:
1/ allocate rphy in PORTE_BYTES_DMAED, DISCE_REVALIDATE_DOMAIN
2/ allocate ata_port and schedule port probe in DISCE_PROBE
...to:
1/ allocate ata_port in PORTE_BYTES_DMAED, DISCE_REVALIDATE_DOMAIN
2/ allocate rphy in PORTE_BYTES_DMAED, DISCE_REVALIDATE_DOMAIN
3/ schedule port probe in DISCE_PROBE
This ordering prevents PHYE_SIGNAL_LOSS_EVENTS from sneaking in to
destrory ata devices before they have been fully initialized:
BUG: unable to handle kernel paging request at 0000000000003b10
IP: [<ffffffffa0053d7e>] sas_ata_end_eh+0x12/0x5e [libsas]
...
[<ffffffffa004d1af>] sas_unregister_common_dev+0x78/0xc9 [libsas]
[<ffffffffa004d4d4>] sas_unregister_dev+0x4f/0xad [libsas]
[<ffffffffa004d5b1>] sas_unregister_domain_devices+0x7f/0xbf [libsas]
[<ffffffffa004c487>] sas_deform_port+0x61/0x1b8 [libsas]
[<ffffffffa004bed0>] sas_phye_loss_of_signal+0x29/0x2b [libsas]
...and kills the awkward "sata domain_device briefly existing in the
domain without an ata_port" state.
Reported-by: Michal Kosciowski <michal.kosciowski@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Acked-by: Jeff Garzik <jgarzik@redhat.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-scsi.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 7832b1ad2327..22226350cd0c 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -3839,18 +3839,25 @@ void ata_sas_port_stop(struct ata_port *ap) | |||
3839 | } | 3839 | } |
3840 | EXPORT_SYMBOL_GPL(ata_sas_port_stop); | 3840 | EXPORT_SYMBOL_GPL(ata_sas_port_stop); |
3841 | 3841 | ||
3842 | int ata_sas_async_port_init(struct ata_port *ap) | 3842 | /** |
3843 | * ata_sas_async_probe - simply schedule probing and return | ||
3844 | * @ap: Port to probe | ||
3845 | * | ||
3846 | * For batch scheduling of probe for sas attached ata devices, assumes | ||
3847 | * the port has already been through ata_sas_port_init() | ||
3848 | */ | ||
3849 | void ata_sas_async_probe(struct ata_port *ap) | ||
3843 | { | 3850 | { |
3844 | int rc = ap->ops->port_start(ap); | 3851 | __ata_port_probe(ap); |
3845 | 3852 | } | |
3846 | if (!rc) { | 3853 | EXPORT_SYMBOL_GPL(ata_sas_async_probe); |
3847 | ap->print_id = atomic_inc_return(&ata_print_id); | ||
3848 | __ata_port_probe(ap); | ||
3849 | } | ||
3850 | 3854 | ||
3851 | return rc; | 3855 | int ata_sas_sync_probe(struct ata_port *ap) |
3856 | { | ||
3857 | return ata_port_probe(ap); | ||
3852 | } | 3858 | } |
3853 | EXPORT_SYMBOL_GPL(ata_sas_async_port_init); | 3859 | EXPORT_SYMBOL_GPL(ata_sas_sync_probe); |
3860 | |||
3854 | 3861 | ||
3855 | /** | 3862 | /** |
3856 | * ata_sas_port_init - Initialize a SATA device | 3863 | * ata_sas_port_init - Initialize a SATA device |
@@ -3867,12 +3874,10 @@ int ata_sas_port_init(struct ata_port *ap) | |||
3867 | { | 3874 | { |
3868 | int rc = ap->ops->port_start(ap); | 3875 | int rc = ap->ops->port_start(ap); |
3869 | 3876 | ||
3870 | if (!rc) { | 3877 | if (rc) |
3871 | ap->print_id = atomic_inc_return(&ata_print_id); | 3878 | return rc; |
3872 | rc = ata_port_probe(ap); | 3879 | ap->print_id = atomic_inc_return(&ata_print_id); |
3873 | } | 3880 | return 0; |
3874 | |||
3875 | return rc; | ||
3876 | } | 3881 | } |
3877 | EXPORT_SYMBOL_GPL(ata_sas_port_init); | 3882 | EXPORT_SYMBOL_GPL(ata_sas_port_init); |
3878 | 3883 | ||