Source-Changes-HG archive

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

[src/jdolecek-ncq]: src/sys/dev/ata make PMP working great again



details:   https://anonhg.NetBSD.org/src/rev/d47e50053080
branches:  jdolecek-ncq
changeset: 822925:d47e50053080
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Sat Jun 17 14:01:36 2017 +0000

description:
make PMP working great again

tested with mvsata(4), my ahcisata(4) controller unfortunately doesn't
support PMP

diffstat:

 sys/dev/ata/TODO.ncq       |   4 ++--
 sys/dev/ata/ata.c          |   6 ++----
 sys/dev/ata/satapmp_subr.c |  37 +++++++++++++++++++++++++------------
 3 files changed, 29 insertions(+), 18 deletions(-)

diffs (169 lines):

diff -r 2ae4f97bb5a3 -r d47e50053080 sys/dev/ata/TODO.ncq
--- a/sys/dev/ata/TODO.ncq      Fri Jun 16 20:40:49 2017 +0000
+++ b/sys/dev/ata/TODO.ncq      Sat Jun 17 14:01:36 2017 +0000
@@ -13,8 +13,6 @@
 is ata_exec_xfer() + POLL safe wrt. more outstanding I/Os? why is it waiting
 until xfer is head of queue? also layer violation with the ata_xfer_free() call
 
-further test port multipliers (currently appears to not work)
-
 test device error handling (currently appears to not work well, at least in NCQ case)
 
 do proper NCQ error recovery (currently not even really attempted)
@@ -24,6 +22,8 @@
 
 atabus(4) queue depth can only shrink, causing NCQ to not be available if NCQ
 drive rescaned after detach of non-NCQ drive
+- careful with PMP, must be minimum of openings supported by drives
+  attached to the same channel
 
 Other random notes (do outside the NCQ branch):
 -----------------------------------------------------
diff -r 2ae4f97bb5a3 -r d47e50053080 sys/dev/ata/ata.c
--- a/sys/dev/ata/ata.c Fri Jun 16 20:40:49 2017 +0000
+++ b/sys/dev/ata/ata.c Sat Jun 17 14:01:36 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ata.c,v 1.132.8.9 2017/06/16 20:40:49 jdolecek Exp $   */
+/*     $NetBSD: ata.c,v 1.132.8.10 2017/06/17 14:01:36 jdolecek Exp $  */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.9 2017/06/16 20:40:49 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.10 2017/06/17 14:01:36 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -1083,8 +1083,6 @@
        if ((xfer = TAILQ_FIRST(&chp->ch_queue->queue_xfer)) == NULL)
                return;
 
-       KASSERT(chp->ch_ndrives == 1 || chq->queue_openings == 1);
-
        /*
         * Can only take NCQ command if there are no current active
         * commands, or if the active commands are NCQ. Need only check
diff -r 2ae4f97bb5a3 -r d47e50053080 sys/dev/ata/satapmp_subr.c
--- a/sys/dev/ata/satapmp_subr.c        Fri Jun 16 20:40:49 2017 +0000
+++ b/sys/dev/ata/satapmp_subr.c        Sat Jun 17 14:01:36 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: satapmp_subr.c,v 1.12.24.1 2017/04/15 17:14:11 jdolecek Exp $  */
+/*     $NetBSD: satapmp_subr.c,v 1.12.24.2 2017/06/17 14:01:36 jdolecek Exp $  */
 
 /*
  * Copyright (c) 2012 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: satapmp_subr.c,v 1.12.24.1 2017/04/15 17:14:11 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: satapmp_subr.c,v 1.12.24.2 2017/06/17 14:01:36 jdolecek Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -53,6 +53,7 @@
        struct ata_xfer xfer;
        struct atac_softc *atac = chp->ch_atac;
        struct ata_drive_datas *drvp;
+       int error = 0;
 
        KASSERT(port < PMP_MAX_DRIVES);
        KASSERT(reg < PMP_GSCR_NREGS);
@@ -60,7 +61,7 @@
        drvp = &chp->ch_drive[PMP_PORT_CTL];
        KASSERT(drvp->drive == PMP_PORT_CTL);
 
-       memset(&xfer, 0, sizeof(xfer));
+       ata_xfer_init(&xfer, true);
 
        xfer.c_ata_c.r_command = PMPC_READ_PORT;
        xfer.c_ata_c.r_features = reg;
@@ -74,19 +75,22 @@
            &xfer) != ATACMD_COMPLETE) {
                aprint_error_dev(chp->atabus,
                    "PMP port %d register %d read failed\n", port, reg);
-               return EIO;
+               error = EIO;
+               goto out;
        }
        if (xfer.c_ata_c.flags & (AT_TIMEOU | AT_DF)) {
                aprint_error_dev(chp->atabus,
                    "PMP port %d register %d read failed, flags 0x%x\n",
                    port, reg, xfer.c_ata_c.flags);
-               return EIO;
+               error = EIO;
+               goto out;
        }
        if (xfer.c_ata_c.flags & AT_ERROR) {
                aprint_verbose_dev(chp->atabus,
                    "PMP port %d register %d read failed, error 0x%x\n",
                    port, reg, xfer.c_ata_c.r_error);
-               return EIO;
+               error = EIO;
+               goto out;
        }
 
        *value = ((uint64_t)((xfer.c_ata_c.r_lba >> 24) & 0xffffff) << 40) |
@@ -94,7 +98,9 @@
                ((uint64_t)((xfer.c_ata_c.r_lba >> 0) & 0xffffff) << 8) |
                ((uint64_t)((xfer.c_ata_c.r_count >> 0) & 0xff) << 0);
 
-       return 0;
+out:
+       ata_xfer_destroy(&xfer);
+       return error;
 }
 
 static inline int
@@ -117,6 +123,7 @@
        struct ata_xfer xfer;
        struct atac_softc *atac = chp->ch_atac;
        struct ata_drive_datas *drvp;
+       int error = 0;
 
        KASSERT(port < PMP_MAX_DRIVES);
        KASSERT(reg < PMP_GSCR_NREGS);
@@ -124,7 +131,7 @@
        drvp = &chp->ch_drive[PMP_PORT_CTL];
        KASSERT(drvp->drive == PMP_PORT_CTL);
 
-       memset(&xfer, 0, sizeof(xfer));
+       ata_xfer_init(&xfer, true);
 
        xfer.c_ata_c.r_command = PMPC_WRITE_PORT;
        xfer.c_ata_c.r_features = reg;
@@ -142,21 +149,27 @@
            &xfer) != ATACMD_COMPLETE) {
                aprint_error_dev(chp->atabus,
                    "PMP port %d register %d write failed\n", port, reg);
-               return EIO;
+               error = EIO;
+               goto out;
        }
        if (xfer.c_ata_c.flags & (AT_TIMEOU | AT_DF)) {
                aprint_error_dev(chp->atabus,
                    "PMP port %d register %d write failed, flags 0x%x\n",
                    port, reg, xfer.c_ata_c.flags);
-               return EIO;
+               error = EIO;
+               goto out;
        }
        if (xfer.c_ata_c.flags & AT_ERROR) {
                aprint_verbose_dev(chp->atabus,
                    "PMP port %d register %d write failed, error 0x%x\n",
                    port, reg, xfer.c_ata_c.r_error);
-               return EIO;
+               error = EIO;
+               goto out;
        }
-       return 0;
+
+out:
+       ata_xfer_destroy(&xfer);
+       return error;
 }
 
 static inline int



Home | Main Index | Thread Index | Old Index