aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_nv.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/sata_nv.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/sata_nv.c')
-rw-r--r--drivers/ata/sata_nv.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index ed5473bf7a0a..ce02e15c857c 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -929,7 +929,7 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
929 "notifier for tag %d with no cmd?\n", 929 "notifier for tag %d with no cmd?\n",
930 cpb_num); 930 cpb_num);
931 ehi->err_mask |= AC_ERR_HSM; 931 ehi->err_mask |= AC_ERR_HSM;
932 ehi->action |= ATA_EH_SOFTRESET; 932 ehi->action |= ATA_EH_RESET;
933 ata_port_freeze(ap); 933 ata_port_freeze(ap);
934 return 1; 934 return 1;
935 } 935 }
@@ -1892,7 +1892,7 @@ static void nv_swncq_error_handler(struct ata_port *ap)
1892 1892
1893 if (ap->link.sactive) { 1893 if (ap->link.sactive) {
1894 nv_swncq_ncq_stop(ap); 1894 nv_swncq_ncq_stop(ap);
1895 ehc->i.action |= ATA_EH_HARDRESET; 1895 ehc->i.action |= ATA_EH_RESET;
1896 } 1896 }
1897 1897
1898 ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, 1898 ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset,
@@ -2173,7 +2173,7 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
2173 ata_ehi_clear_desc(ehi); 2173 ata_ehi_clear_desc(ehi);
2174 ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat); 2174 ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat);
2175 ehi->err_mask |= AC_ERR_HOST_BUS; 2175 ehi->err_mask |= AC_ERR_HOST_BUS;
2176 ehi->action |= ATA_EH_SOFTRESET; 2176 ehi->action |= ATA_EH_RESET;
2177 return -EINVAL; 2177 return -EINVAL;
2178 } 2178 }
2179 2179
@@ -2188,7 +2188,7 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
2188 ata_ehi_push_desc(ehi, "illegal SWNCQ:qc_active transition" 2188 ata_ehi_push_desc(ehi, "illegal SWNCQ:qc_active transition"
2189 "(%08x->%08x)", pp->qc_active, sactive); 2189 "(%08x->%08x)", pp->qc_active, sactive);
2190 ehi->err_mask |= AC_ERR_HSM; 2190 ehi->err_mask |= AC_ERR_HSM;
2191 ehi->action |= ATA_EH_HARDRESET; 2191 ehi->action |= ATA_EH_RESET;
2192 return -EINVAL; 2192 return -EINVAL;
2193 } 2193 }
2194 for (i = 0; i < ATA_MAX_QUEUE; i++) { 2194 for (i = 0; i < ATA_MAX_QUEUE; i++) {
@@ -2324,7 +2324,7 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis)
2324 ata_ehi_push_desc(ehi, "Ata error. fis:0x%X", fis); 2324 ata_ehi_push_desc(ehi, "Ata error. fis:0x%X", fis);
2325 ehi->err_mask |= AC_ERR_DEV; 2325 ehi->err_mask |= AC_ERR_DEV;
2326 ehi->serror |= serror; 2326 ehi->serror |= serror;
2327 ehi->action |= ATA_EH_SOFTRESET; 2327 ehi->action |= ATA_EH_RESET;
2328 ata_port_freeze(ap); 2328 ata_port_freeze(ap);
2329 return; 2329 return;
2330 } 2330 }
@@ -2356,7 +2356,7 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis)
2356 if (pp->ncq_flags & (ncq_saw_sdb | ncq_saw_backout)) { 2356 if (pp->ncq_flags & (ncq_saw_sdb | ncq_saw_backout)) {
2357 ata_ehi_push_desc(ehi, "illegal fis transaction"); 2357 ata_ehi_push_desc(ehi, "illegal fis transaction");
2358 ehi->err_mask |= AC_ERR_HSM; 2358 ehi->err_mask |= AC_ERR_HSM;
2359 ehi->action |= ATA_EH_HARDRESET; 2359 ehi->action |= ATA_EH_RESET;
2360 goto irq_error; 2360 goto irq_error;
2361 } 2361 }
2362 2362