Module Name:    src
Committed By:   jdolecek
Date:           Fri Dec  7 22:22:12 UTC 2018

Modified Files:
        src/sys/dev/ic: ahcisata_core.c ahcisatavar.h

Log Message:
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


To generate a diff of this commit:
cvs rdiff -u -r1.71 -r1.72 src/sys/dev/ic/ahcisata_core.c
cvs rdiff -u -r1.20 -r1.21 src/sys/dev/ic/ahcisatavar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/ic/ahcisata_core.c
diff -u src/sys/dev/ic/ahcisata_core.c:1.71 src/sys/dev/ic/ahcisata_core.c:1.72
--- src/sys/dev/ic/ahcisata_core.c:1.71	Tue Nov 20 19:19:21 2018
+++ src/sys/dev/ic/ahcisata_core.c	Fri Dec  7 22:22:12 2018
@@ -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 @@ const struct ata_bustype ahci_ata_bustyp
 	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_reset(struct ahci_softc *sc)
 		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 @@ ahci_attach(struct ahci_softc *sc)
 			    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_intr(void *v)
 		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)
 {
-	uint32_t is, tfd, sact;
+	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_xfer *xfer;
 	int slot = -1;
 	bool recover = false;
@@ -703,6 +716,8 @@ ahci_intr_port(struct ahci_softc *sc, st
 		ata_thread_run(chp, 0, ATACH_TH_RECOVERY, tfd); 
 		ata_channel_unlock(chp);
 	}
+
+	return 1;
 }
 
 static void
@@ -1167,7 +1182,7 @@ ahci_cmd_poll(struct ata_channel *chp, s
 		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 @@ ahci_bio_poll(struct ata_channel *chp, s
 	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 @@ ahci_atapi_poll(struct ata_channel *chp,
 	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, 

Index: src/sys/dev/ic/ahcisatavar.h
diff -u src/sys/dev/ic/ahcisatavar.h:1.20 src/sys/dev/ic/ahcisatavar.h:1.21
--- src/sys/dev/ic/ahcisatavar.h:1.20	Wed Oct 24 19:38:00 2018
+++ src/sys/dev/ic/ahcisatavar.h	Fri Dec  7 22:22:12 2018
@@ -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 @@ struct ahci_softc {
 
 	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_childdetached(struct ahci_soft
 void ahci_resume(struct ahci_softc *);
 
 int  ahci_intr(void *);
+int  ahci_intr_port(void *);
 

Reply via email to