aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-core.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-01-23 10:05:14 -0500
committerJeff Garzik <jgarzik@redhat.com>2008-04-17 15:44:15 -0400
commitcf48062658e7ab3bc55e10c65676c3c73c16f8bf (patch)
tree9a50a016ceb6051d8a30a43ea39f2a4d3d25570e /drivers/ata/libata-core.c
parent4b119e21d0c66c22e8ca03df05d9de623d0eb50f (diff)
libata: prefer hardreset
When both soft and hard resets are available, libata preferred softreset till now. The logic behind it was to be softer to devices; however, this doesn't really help much. Rationales for the change: * BIOS may freeze lock certain things during boot and softreset can't unlock those. This by itself is okay but during operation PHY event or other error conditions can trigger hardreset and the device may end up with different configuration. For example, after a hardreset, previously unlockable HPA can be unlocked resulting in different device size and thus revalidation failure. Similar condition can occur during or after resume. * Certain ATAPI devices require hardreset to recover after certain error conditions. On PATA, this is done by issuing the DEVICE RESET command. On SATA, COMRESET has equivalent effect. The problem is that DEVICE RESET needs its own execution protocol. For SFF controllers with bare TF access, it can be easily implemented but more advanced controllers (e.g. ahci and sata_sil24) require specialized implementations. Simply using hardreset solves the problem nicely. * COMRESET initialization sequence is the norm in SATA land and many SATA devices don't work properly if only SRST is used. For example, some PMPs behave this way and libata works around by always issuing hardreset if the host supports PMP. Like the above example, libata has developed a number of mechanisms aiming to promote softreset to hardreset if softreset is not going to work. This approach is time consuming and error prone. Also, note that, dependingon how you read the specs, it could be argued that PMP fan-out ports require COMRESET to start operation. In fact, all the PMPs on the market except one don't work properly if COMRESET is not issued to fan-out ports after PMP reset. * COMRESET is an integral part of SATA connection and any working device should be able to handle COMRESET properly. After all, it's the way to signal hardreset during reboot. This is the most used and recommended (at least by the ahci spec) method of resetting devices. So, this patch makes libata prefer hardreset over softreset by making the following changes. * Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is now only used to tell prereset whether soft or hard reset will be issued. * Strip out now unneeded promote-to-hardreset logics from ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and other places. Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r--drivers/ata/libata-core.c19
1 files changed, 4 insertions, 15 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index be95fdb6972..02e7ba43a3b 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -3949,17 +3949,6 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline)
3949 const unsigned long *timing = sata_ehc_deb_timing(ehc); 3949 const unsigned long *timing = sata_ehc_deb_timing(ehc);
3950 int rc; 3950 int rc;
3951 3951
3952 /* handle link resume */
3953 if ((ehc->i.flags & ATA_EHI_RESUME_LINK) &&
3954 (link->flags & ATA_LFLAG_HRST_TO_RESUME))
3955 ehc->i.action |= ATA_EH_HARDRESET;
3956
3957 /* Some PMPs don't work with only SRST, force hardreset if PMP
3958 * is supported.
3959 */
3960 if (ap->flags & ATA_FLAG_PMP)
3961 ehc->i.action |= ATA_EH_HARDRESET;
3962
3963 /* if we're about to do hardreset, nothing more to do */ 3952 /* if we're about to do hardreset, nothing more to do */
3964 if (ehc->i.action & ATA_EH_HARDRESET) 3953 if (ehc->i.action & ATA_EH_HARDRESET)
3965 return 0; 3954 return 0;
@@ -6055,9 +6044,9 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
6055 if (ata_sg_setup(qc)) 6044 if (ata_sg_setup(qc))
6056 goto sg_err; 6045 goto sg_err;
6057 6046
6058 /* if device is sleeping, schedule softreset and abort the link */ 6047 /* if device is sleeping, schedule reset and abort the link */
6059 if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) { 6048 if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) {
6060 link->eh_info.action |= ATA_EH_SOFTRESET; 6049 link->eh_info.action |= ATA_EH_RESET;
6061 ata_ehi_push_desc(&link->eh_info, "waking up from sleep"); 6050 ata_ehi_push_desc(&link->eh_info, "waking up from sleep");
6062 ata_link_abort(link); 6051 ata_link_abort(link);
6063 return; 6052 return;
@@ -6634,7 +6623,7 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
6634 */ 6623 */
6635void ata_host_resume(struct ata_host *host) 6624void ata_host_resume(struct ata_host *host)
6636{ 6625{
6637 ata_host_request_pm(host, PMSG_ON, ATA_EH_SOFTRESET, 6626 ata_host_request_pm(host, PMSG_ON, ATA_EH_RESET,
6638 ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0); 6627 ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0);
6639 host->dev->power.power_state = PMSG_ON; 6628 host->dev->power.power_state = PMSG_ON;
6640 6629
@@ -7171,7 +7160,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
7171 7160
7172 ehi->probe_mask = 7161 ehi->probe_mask =
7173 (1 << ata_link_max_devices(&ap->link)) - 1; 7162 (1 << ata_link_max_devices(&ap->link)) - 1;
7174 ehi->action |= ATA_EH_SOFTRESET; 7163 ehi->action |= ATA_EH_RESET;
7175 ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET; 7164 ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
7176 7165
7177 ap->pflags &= ~ATA_PFLAG_INITIALIZING; 7166 ap->pflags &= ~ATA_PFLAG_INITIALIZING;