* [PATCH #upstream] libata: track SLEEP state and issue SRST to wake it up
@ 2007-10-25 9:30 Tejun Heo
2007-10-25 9:38 ` Jeff Garzik
0 siblings, 1 reply; 2+ messages in thread
From: Tejun Heo @ 2007-10-25 9:30 UTC (permalink / raw)
To: Jeff Garzik, linux-ide, andrew.m.paprocki, ballen
ATA devices in SLEEP mode don't respond to any commands. SRST is
necessary to wake it up. Till now, when a command is issued to a
device in SLEEP mode, the command times out, which makes EH reset the
device and retry the command after that, causing a long delay.
This patch makes libata track SLEEP state and issue SRST automatically
if a command is about to be issued to a device in SLEEP.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Cc: Bruce Allen <ballen@gravity.phys.uwm.edu>
Cc: Andrew Paprocki <andrew@ishiboo.com>
---
This patch is against
#upstream
+ relocate-and-fix-post-command-processing patch
(http://article.gmane.org/gmane.linux.ide/24001)
The infinite loop with the previous patch wasn't caused by bug in
sleep state tracking. It was happening because post-command
processing was being performed for commands which are being retried
from EH, so what happened was.
1. device is flagged SLEEPING
2. SLEEP is issued, as device is sleeping, EH is rescheduled against
the qc for SLEEP.
3. EH kicks in and wakes up the device and clears SLEEPING.
4. EH finishes up failed qc which triggers post-command processing and
sets SLEEPING.
5. SCSI command is retried, go back to #2.
relocate-and-fix-post-command-processing patch fixes the original bug
in post-command processing and this patch doesn't cause infinite loop
anymore.
drivers/ata/libata-core.c | 12 ++++++++++++
drivers/ata/libata-eh.c | 4 +++-
include/linux/ata.h | 1 +
include/linux/libata.h | 1 +
4 files changed, 17 insertions(+), 1 deletion(-)
Index: work/include/linux/ata.h
===================================================================
--- work.orig/include/linux/ata.h
+++ work/include/linux/ata.h
@@ -180,6 +180,7 @@ enum {
ATA_CMD_VERIFY_EXT = 0x42,
ATA_CMD_STANDBYNOW1 = 0xE0,
ATA_CMD_IDLEIMMEDIATE = 0xE1,
+ ATA_CMD_SLEEP = 0xE6,
ATA_CMD_INIT_DEV_PARAMS = 0x91,
ATA_CMD_READ_NATIVE_MAX = 0xF8,
ATA_CMD_READ_NATIVE_MAX_EXT = 0x27,
Index: work/include/linux/libata.h
===================================================================
--- work.orig/include/linux/libata.h
+++ work/include/linux/libata.h
@@ -138,6 +138,7 @@ enum {
ATA_DFLAG_PIO = (1 << 12), /* device limited to PIO mode */
ATA_DFLAG_NCQ_OFF = (1 << 13), /* device limited to non-NCQ mode */
ATA_DFLAG_SPUNDOWN = (1 << 14), /* XXX: for spindown_compat */
+ ATA_DFLAG_SLEEPING = (1 << 15), /* device is sleeping */
ATA_DFLAG_INIT_MASK = (1 << 16) - 1,
ATA_DFLAG_DETACH = (1 << 16),
Index: work/drivers/ata/libata-core.c
===================================================================
--- work.orig/drivers/ata/libata-core.c
+++ work/drivers/ata/libata-core.c
@@ -5630,6 +5630,10 @@ void ata_qc_complete(struct ata_queued_c
ehi->dev_action[dev->devno] |= ATA_EH_REVALIDATE;
ata_port_schedule_eh(ap);
break;
+
+ case ATA_CMD_SLEEP:
+ dev->flags |= ATA_DFLAG_SLEEPING;
+ break;
}
__ata_qc_complete(qc);
@@ -5769,6 +5773,14 @@ void ata_qc_issue(struct ata_queued_cmd
qc->flags &= ~ATA_QCFLAG_DMAMAP;
}
+ /* if device is sleeping, schedule softreset and abort the link */
+ if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) {
+ link->eh_info.action |= ATA_EH_SOFTRESET;
+ ata_ehi_push_desc(&link->eh_info, "waking up from sleep");
+ ata_link_abort(link);
+ return;
+ }
+
ap->ops->qc_prep(qc);
qc->err_mask |= ap->ops->qc_issue(qc);
Index: work/drivers/ata/libata-eh.c
===================================================================
--- work.orig/drivers/ata/libata-eh.c
+++ work/drivers/ata/libata-eh.c
@@ -2208,9 +2208,11 @@ int ata_eh_reset(struct ata_link *link,
ata_link_for_each_dev(dev, link) {
/* After the reset, the device state is PIO 0
* and the controller state is undefined.
- * Record the mode.
+ * Reset also wakes up drives from sleeping
+ * mode.
*/
dev->pio_mode = XFER_PIO_0;
+ dev->flags &= ~ATA_DFLAG_SLEEPING;
if (ata_link_offline(link))
continue;
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [PATCH #upstream] libata: track SLEEP state and issue SRST to wake it up
2007-10-25 9:30 [PATCH #upstream] libata: track SLEEP state and issue SRST to wake it up Tejun Heo
@ 2007-10-25 9:38 ` Jeff Garzik
0 siblings, 0 replies; 2+ messages in thread
From: Jeff Garzik @ 2007-10-25 9:38 UTC (permalink / raw)
To: Tejun Heo; +Cc: linux-ide, andrew.m.paprocki, ballen
Tejun Heo wrote:
> ATA devices in SLEEP mode don't respond to any commands. SRST is
> necessary to wake it up. Till now, when a command is issued to a
> device in SLEEP mode, the command times out, which makes EH reset the
> device and retry the command after that, causing a long delay.
>
> This patch makes libata track SLEEP state and issue SRST automatically
> if a command is about to be issued to a device in SLEEP.
>
> Signed-off-by: Tejun Heo <htejun@gmail.com>
> Cc: Bruce Allen <ballen@gravity.phys.uwm.edu>
> Cc: Andrew Paprocki <andrew@ishiboo.com>
> ---
> This patch is against
>
> #upstream
> + relocate-and-fix-post-command-processing patch
> (http://article.gmane.org/gmane.linux.ide/24001)
>
> The infinite loop with the previous patch wasn't caused by bug in
> sleep state tracking. It was happening because post-command
> processing was being performed for commands which are being retried
> from EH, so what happened was.
>
> 1. device is flagged SLEEPING
>
> 2. SLEEP is issued, as device is sleeping, EH is rescheduled against
> the qc for SLEEP.
>
> 3. EH kicks in and wakes up the device and clears SLEEPING.
>
> 4. EH finishes up failed qc which triggers post-command processing and
> sets SLEEPING.
>
> 5. SCSI command is retried, go back to #2.
>
> relocate-and-fix-post-command-processing patch fixes the original bug
> in post-command processing and this patch doesn't cause infinite loop
> anymore.
>
> drivers/ata/libata-core.c | 12 ++++++++++++
> drivers/ata/libata-eh.c | 4 +++-
> include/linux/ata.h | 1 +
> include/linux/libata.h | 1 +
> 4 files changed, 17 insertions(+), 1 deletion(-)
applied, both of these changes were nice improvements, as well as fixing
problems
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-10-25 9:38 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-25 9:30 [PATCH #upstream] libata: track SLEEP state and issue SRST to wake it up Tejun Heo
2007-10-25 9:38 ` Jeff Garzik
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).