Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ata Implement a DIRTY flag (copied from sd(4)) so av...



details:   https://anonhg.NetBSD.org/src/rev/900064d0974d
branches:  trunk
changeset: 455535:900064d0974d
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Fri Apr 05 18:23:45 2019 +0000

description:
Implement a DIRTY flag (copied from sd(4)) so avoid flushing the cache if
there has been no write. This avoids a (long) timeout on the flush cache
command triggered by atactl sleep, when the device is open only by the atactl
command itself.
If a drive has no partition open and goes to sleep, the WDF_LOADED
flag is clear, and the next open will issue  wd_get_params() command.
But to wake up the drive a reset is required, and wd_get_params() doens't
issue a reset on timeout, so there's no way to wake up the disk.
Add a retry after reset to wd_get_params().

Tested by Hauke Fath; fixes PR kern/49457

diffstat:

 sys/dev/ata/wd.c    |  14 ++++++++++++--
 sys/dev/ata/wdvar.h |   3 ++-
 2 files changed, 14 insertions(+), 3 deletions(-)

diffs (64 lines):

diff -r 2f10c6d84ec8 -r 900064d0974d sys/dev/ata/wd.c
--- a/sys/dev/ata/wd.c  Fri Apr 05 18:14:54 2019 +0000
+++ b/sys/dev/ata/wd.c  Fri Apr 05 18:23:45 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wd.c,v 1.446 2019/03/19 16:56:29 mlelstv Exp $ */
+/*     $NetBSD: wd.c,v 1.447 2019/04/05 18:23:45 bouyer Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.446 2019/03/19 16:56:29 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.447 2019/04/05 18:23:45 bouyer Exp $");
 
 #include "opt_ata.h"
 #include "opt_wd.h"
@@ -1638,11 +1638,20 @@
 int
 wd_get_params(struct wd_softc *wd, uint8_t flags, struct ataparams *params)
 {
+       int retry = 0;
 
+again:
        switch (wd->atabus->ata_get_params(wd->drvp, flags, params)) {
        case CMD_AGAIN:
                return 1;
        case CMD_ERR:
+               if (retry == 0) {
+                       retry++;
+                       (*wd->atabus->ata_reset_drive)(wd->drvp,
+                           flags | AT_RST_NOCMD, NULL);
+                       goto again;
+               }
+
                if (wd->drvp->drive_type != ATA_DRIVET_OLD)
                        return 1;
                /*
@@ -2227,6 +2236,7 @@
 
                atachannel_debug(wd->drvp->chnl_softc);
        }
+       wd->sc_flags &= ~WDF_DIRTY;
        return 0;
 }
 #endif /* ATADEBUG */
diff -r 2f10c6d84ec8 -r 900064d0974d sys/dev/ata/wdvar.h
--- a/sys/dev/ata/wdvar.h       Fri Apr 05 18:14:54 2019 +0000
+++ b/sys/dev/ata/wdvar.h       Fri Apr 05 18:23:45 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wdvar.h,v 1.48 2019/03/19 06:51:05 mlelstv Exp $       */
+/*     $NetBSD: wdvar.h,v 1.49 2019/04/05 18:23:45 bouyer Exp $        */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -53,6 +53,7 @@
 #define WDF_WAIT       0x020 /* waiting for resources */
 #define WDF_LBA                0x040 /* using LBA mode */
 #define WDF_LBA48      0x100 /* using 48-bit LBA mode */
+#define WDF_DIRTY      0x200 /* disk cache dirty */
 #define WDF_OPEN       0x400 /* device is open */
        uint64_t sc_capacity; /* full capacity of the device */
        uint64_t sc_capacity512; /* ... in DEV_BSIZE blocks */



Home | Main Index | Thread Index | Old Index