Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/ic add optional hook for intr establish when active ...



details:   https://anonhg.NetBSD.org/src/rev/d4cbdbafd1ef
branches:  trunk
changeset: 446493:d4cbdbafd1ef
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Fri Dec 07 22:22:12 2018 +0000

description:
add optional hook for intr establish when active port is attached, export
ahci_intr_port() in form suitable for interrupt hanlder, and probe for GHC
MRSM flag as courtesy for use by the intr hook

towards multi-vector MSI/MSI-X support

diffstat:

 sys/dev/ic/ahcisata_core.c |  35 +++++++++++++++++++++++++----------
 sys/dev/ic/ahcisatavar.h   |   5 ++++-
 2 files changed, 29 insertions(+), 11 deletions(-)

diffs (136 lines):

diff -r a2d3453e7acf -r d4cbdbafd1ef sys/dev/ic/ahcisata_core.c
--- a/sys/dev/ic/ahcisata_core.c        Fri Dec 07 21:28:03 2018 +0000
+++ b/sys/dev/ic/ahcisata_core.c        Fri Dec 07 22:22:12 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ahcisata_core.c,v 1.71 2018/11/20 19:19:21 jdolecek Exp $      */
+/*     $NetBSD: ahcisata_core.c,v 1.72 2018/12/07 22:22:12 jdolecek Exp $      */
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.71 2018/11/20 19:19:21 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.72 2018/12/07 22:22:12 jdolecek Exp $");
 
 #include <sys/types.h>
 #include <sys/malloc.h>
@@ -125,7 +125,6 @@
        ahci_channel_recover,
 };
 
-static void ahci_intr_port(struct ahci_softc *, struct ahci_channel *);
 static void ahci_setup_port(struct ahci_softc *sc, int i);
 
 static void
@@ -167,6 +166,9 @@
                AHCI_WRITE(sc, AHCI_PI, sc->sc_init_data.ports);
        }
 
+       /* Check if hardware reverted to single message MSI */
+       sc->sc_ghc_mrsm = ISSET(AHCI_READ(sc, AHCI_GHC), AHCI_GHC_MRSM);
+
        return 0;
 }
 
@@ -372,6 +374,14 @@
                            AHCINAME(sc));
                        break;
                }
+
+               /* Optional intr establish per active port */
+               if (sc->sc_intr_establish && sc->sc_intr_establish(sc, i) != 0){
+                       aprint_error("%s: intr establish hook failed\n",
+                           AHCINAME(sc));
+                       break;
+               }
+
                achp = &sc->sc_channels[i];
                chp = &achp->ata_channel;
                sc->sc_chanarray[i] = chp;
@@ -581,16 +591,19 @@
                AHCI_WRITE(sc, AHCI_IS, is);
                for (i = 0; i < AHCI_MAX_PORTS; i++)
                        if (is & (1U << i))
-                               ahci_intr_port(sc, &sc->sc_channels[i]);
+                               ahci_intr_port(&sc->sc_channels[i]);
        }
+
        return r;
 }
 
-static void
-ahci_intr_port(struct ahci_softc *sc, struct ahci_channel *achp)
+int
+ahci_intr_port(void *v)
 {
+       struct ahci_channel *achp = v;
+       struct ata_channel *chp = &achp->ata_channel;
+       struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
        uint32_t is, tfd, sact;
-       struct ata_channel *chp = &achp->ata_channel;
        struct ata_xfer *xfer;
        int slot = -1;
        bool recover = false;
@@ -703,6 +716,8 @@
                ata_thread_run(chp, 0, ATACH_TH_RECOVERY, tfd); 
                ata_channel_unlock(chp);
        }
+
+       return 1;
 }
 
 static void
@@ -1167,7 +1182,7 @@
                if (xfer->c_ata_c.flags & AT_DONE)
                        break;
                ata_channel_unlock(chp);
-               ahci_intr_port(sc, achp);
+               ahci_intr_port(achp);
                ata_channel_lock(chp);
                ata_delay(chp, 10, "ahcipl", xfer->c_ata_c.flags);
        }
@@ -1410,7 +1425,7 @@
        for (int i = 0; i < ATA_DELAY * 10; i++) {
                if (xfer->c_bio.flags & ATA_ITSDONE)
                        break;
-               ahci_intr_port(sc, achp);
+               ahci_intr_port(achp);
                delay(100);
        }
        AHCIDEBUG_PRINT(("%s port %d poll end GHC 0x%x IS 0x%x list 0x%x%x fis 0x%x%x CMD 0x%x CI 0x%x\n", AHCINAME(sc), chp->ch_channel, 
@@ -1907,7 +1922,7 @@
        for (int i = 0; i < ATA_DELAY / 10; i++) {
                if (xfer->c_scsipi->xs_status & XS_STS_DONE)
                        break;
-               ahci_intr_port(sc, achp);
+               ahci_intr_port(achp);
                delay(10000);
        }
        AHCIDEBUG_PRINT(("%s port %d poll end GHC 0x%x IS 0x%x list 0x%x%x fis 0x%x%x CMD 0x%x CI 0x%x\n", AHCINAME(sc), chp->ch_channel, 
diff -r a2d3453e7acf -r d4cbdbafd1ef sys/dev/ic/ahcisatavar.h
--- a/sys/dev/ic/ahcisatavar.h  Fri Dec 07 21:28:03 2018 +0000
+++ b/sys/dev/ic/ahcisatavar.h  Fri Dec 07 22:22:12 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ahcisatavar.h,v 1.20 2018/10/24 19:38:00 jdolecek Exp $        */
+/*     $NetBSD: ahcisatavar.h,v 1.21 2018/12/07 22:22:12 jdolecek Exp $        */
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -86,7 +86,9 @@
 
        void    (*sc_channel_start)(struct ahci_softc *, struct ata_channel *);
        void    (*sc_channel_stop)(struct ahci_softc *, struct ata_channel *);
+       int     (*sc_intr_establish)(struct ahci_softc *, int);
 
+       bool sc_ghc_mrsm;
        bool sc_save_init_data;
        struct {
                uint32_t cap;
@@ -121,4 +123,5 @@
 void ahci_resume(struct ahci_softc *);
 
 int  ahci_intr(void *);
+int  ahci_intr_port(void *);
 



Home | Main Index | Thread Index | Old Index