Subject: viaide(4) patch for suspend/resume
To: None <current-users@netbsd.org>
From: Joerg Sonnenberger <joerg@britannica.bec.de>
List: current-users
Date: 12/21/2007 23:21:35
--0OAP2g/MAC+5xKAE
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi all,
can someone with viaide(4) test suspend/resume with the attached patch?
E.g. if reading uncached directories afterwards is still possible?

Joerg

--0OAP2g/MAC+5xKAE
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="viaide.diff"

Index: pciidevar.h
===================================================================
RCS file: /data/repo/netbsd/src/sys/dev/pci/pciidevar.h,v
retrieving revision 1.35
diff -u -p -r1.35 pciidevar.h
--- pciidevar.h	17 Oct 2006 13:45:05 -0000	1.35
+++ pciidevar.h	19 Dec 2007 14:25:34 -0000
@@ -150,12 +150,7 @@ struct pciide_softc {
 #endif	/* NATA_DMA */
 	} pciide_channels[PCIIDE_MAX_CHANNELS];
 
-	/* Power management */
-	void			*sc_powerhook;
-	struct pci_conf_state	sc_pciconf; /* Restore buffer */
-	/* Intel power management */
-	pcireg_t		sc_idetim;
-	pcireg_t		sc_udmatim;
+	pcireg_t		sc_pm_reg[4];
 };
 
 /* Given an ata_channel, get the pciide_softc. */
Index: piixide.c
===================================================================
RCS file: /data/repo/netbsd/src/sys/dev/pci/piixide.c,v
retrieving revision 1.42
diff -u -p -r1.42 piixide.c
--- piixide.c	9 Dec 2007 20:28:12 -0000	1.42
+++ piixide.c	19 Dec 2007 14:26:05 -0000
@@ -288,9 +288,9 @@ piixide_resume(device_t dv)
 	struct pciide_softc *sc = device_private(dv);
 
 	pci_conf_write(sc->sc_pc, sc->sc_tag, PIIX_IDETIM,
-	    sc->sc_idetim);
+	    sc->sc_pm_reg[0]);
 	pci_conf_write(sc->sc_pc, sc->sc_tag, PIIX_UDMATIM,
-	    sc->sc_udmatim);
+	    sc->sc_pm_reg[1]);
 
 	return true;
 }
@@ -300,9 +300,9 @@ piixide_suspend(device_t dv)
 {
 	struct pciide_softc *sc = device_private(dv);
 
-	sc->sc_idetim = pci_conf_read(sc->sc_pc, sc->sc_tag,
+	sc->sc_pm_reg[0] = pci_conf_read(sc->sc_pc, sc->sc_tag,
 	    PIIX_IDETIM);
-	sc->sc_udmatim = pci_conf_read(sc->sc_pc, sc->sc_tag,
+	sc->sc_pm_reg[1] = pci_conf_read(sc->sc_pc, sc->sc_tag,
 	    PIIX_UDMATIM);
 
 	return true;
Index: viaide.c
===================================================================
RCS file: /data/repo/netbsd/src/sys/dev/pci/viaide.c,v
retrieving revision 1.50
diff -u -p -r1.50 viaide.c
--- viaide.c	20 Dec 2007 22:24:40 -0000	1.50
+++ viaide.c	21 Dec 2007 16:08:30 -0000
@@ -67,6 +67,8 @@ static int	viaide_match(struct device *,
 static void	viaide_attach(struct device *, struct device *, void *);
 static const struct pciide_product_desc *
 		viaide_lookup(pcireg_t);
+static bool	viaide_suspend(device_t);
+static bool	viaide_resume(device_t);
 
 CFATTACH_DECL(viaide, sizeof(struct pciide_softc),
     viaide_match, viaide_attach, NULL, NULL);
@@ -374,6 +376,9 @@ viaide_attach(struct device *parent, str
 	if (pp == NULL)
 		panic("viaide_attach");
 	pciide_common_attach(sc, pa, pp);
+
+	if (!pmf_device_register(self, viaide_suspend, viaide_resume))
+		aprint_error_dev(self, "couldn't establish power handler\n");
 }
 
 static int
@@ -386,6 +391,39 @@ via_pcib_match(struct pci_attach_args *p
 	return 0;
 }
 
+static bool
+viaide_suspend(device_t dv)
+{
+	struct pciide_softc *sc = device_private(dv);
+
+	sc->sc_pm_reg[0] = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF(sc));
+	/* APO_DATATIM(sc) includes APO_UDMA(sc) */
+	sc->sc_pm_reg[0] = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc));
+	/* This two are VIA-only, but should be ignored by other devices. */
+	sc->sc_pm_reg[0] = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_CTLMISC(sc));
+	sc->sc_pm_reg[0] = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_MISCTIM(sc));
+
+	return true;
+}
+
+static bool
+viaide_resume(device_t dv)
+{
+	struct pciide_softc *sc = device_private(dv);
+
+	pci_conf_write(sc->sc_pc, sc->sc_tag, APO_IDECONF(sc),
+	    sc->sc_pm_reg[0]);
+	pci_conf_write(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc),
+	    sc->sc_pm_reg[1]);
+	/* This two are VIA-only, but should be ignored by other devices. */
+	pci_conf_write(sc->sc_pc, sc->sc_tag, APO_CTLMISC(sc),
+	    sc->sc_pm_reg[2]);
+	pci_conf_write(sc->sc_pc, sc->sc_tag, APO_MISCTIM(sc),
+	    sc->sc_pm_reg[3]);
+
+	return true;
+}
+
 static void
 via_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
 {

--0OAP2g/MAC+5xKAE--