Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 9 Jul 2005 09:23:18 -0400
From:      John Baldwin <jhb@FreeBSD.org>
To:        freebsd-current@FreeBSD.org
Cc:        Fabian Keil <freebsd-listen@fabiankeil.de>, Stefan Ehmann <shoesoft@gmx.net>, current@FreeBSD.org
Subject:   Re: Suspend broken ?
Message-ID:  <200507090923.20212.jhb@FreeBSD.org>
In-Reply-To: <1120585020.679.4.camel@localhost>
References:  <42C92DC5.3060101@gddsn.org.cn> <20050704204804.37a82e4e@localhost> <1120585020.679.4.camel@localhost>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tuesday 05 July 2005 01:37 pm, Stefan Ehmann wrote:
> On Mon, 2005-07-04 at 20:48 +0200, Fabian Keil wrote:
> > Stefan Ehmann <shoesoft@gmx.net> wrote:
> > > On Mon, 2005-07-04 at 21:33 +0800, Huang wen hui wrote:
> > > > Huang wen hui =C3=A5=E2=80=A0=E2=84=A2=C3=A9=E2=80=9C:
> > > > >Hi,
> > > > >For my T42p, suspend operation could not work from jun 2,
> > > > >It does work under CURRENT using Jun 1 cvsup.
> > > > >/sys/i386/isa/clock.c revert to v1.220.
> > > >
> > > > but /sys/i386/isa/clock.c revert to v1.220 help that.
> > >
> > > Thanks for tracking that down, helps in my case too.
> > >
> > > I'm running a Toshiba M-30X notebook. For me, resume basically worked
> > > but everything was as slow as if it was running on my old calculator.
> > > (e.g. it takes several seconds from typing a character until it is
> > > displayed on the console).
> >
> > I had these symptoms before I put "device pmtimer" in the kernel.
> > I'm still on 5.4, therefore I don't know if this has anything to
> > do with your problem.
>
> Does not seem to be related. I already had pmtimer in my kernel. And
> this problem also hasn't occured before /sys/i386/isa/clock.c rev 221.

Try this patch:  I'm going to try to get it committed soon.

=2D-- //depot/vendor/freebsd/src/sys/amd64/isa/clock.c	2005/07/05 20:15:24
+++ //depot/user/jhb/acpipci/amd64/isa/clock.c	2005/07/08 14:53:31
@@ -101,6 +101,7 @@
 #endif
 u_int	timer_freq =3D TIMER_FREQ;
 int	timer0_max_count;
+int	timer0_real_max_count;
 int	wall_cmos_clock;	/* wall CMOS clock assumed if !=3D 0 */
 struct mtx clock_lock;
 #define	RTC_LOCK	mtx_lock_spin(&clock_lock)
@@ -108,7 +109,6 @@
=20
 static	int	beeping =3D 0;
 static	const u_char daysinmonth[] =3D {31,28,31,30,31,30,31,31,30,31,30,31=
};
=2Dstatic	u_int	hardclock_max_count;
 static	struct intsrc *i8254_intsrc;
 static	u_int32_t i8254_lastcount;
 static	u_int32_t i8254_offset;
@@ -517,21 +517,23 @@
 static void
 set_timer_freq(u_int freq, int intr_freq)
 {
=2D	int new_timer0_max_count;
+	int new_timer0_real_max_count;
=20
 	i8254_timecounter.tc_frequency =3D freq;
 	mtx_lock_spin(&clock_lock);
 	timer_freq =3D freq;
=2D	new_timer0_max_count =3D hardclock_max_count =3D TIMER_DIV(intr_freq);
 	if (using_lapic_timer) {
+		new_timer0_real_max_count =3D 0x10000;
+	else
+		new_timer0_real_max_count =3D TIMER_DIV(intr_freq);
+	if (new_timer0_real_max_count !=3D timer0_real_max_count) {
+		if (timer0_real_max_count =3D=3D 0x10000)
+			timer0_max_count =3D 0xffff;
+		else
+			timer0_max_count =3D timer0_max_real_count;
 		outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
=2D		outb(TIMER_CNTR0, 0);
=2D		outb(TIMER_CNTR0, 0);
=2D	} else if (new_timer0_max_count !=3D timer0_max_count) {
=2D		timer0_max_count =3D new_timer0_max_count;
=2D		outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
=2D		outb(TIMER_CNTR0, timer0_max_count & 0xff);
=2D		outb(TIMER_CNTR0, timer0_max_count >> 8);
+		outb(TIMER_CNTR0, timer0_real_max_count & 0xff);
+		outb(TIMER_CNTR0, timer0_real_max_count >> 8);
 	}
 	mtx_unlock_spin(&clock_lock);
 }
@@ -826,19 +828,8 @@
 static unsigned
 i8254_simple_get_timecount(struct timecounter *tc)
 {
=2D	u_int count;
=2D	u_int high, low;
=20
=2D	mtx_lock_spin(&clock_lock);
=2D
=2D	/* Select timer0 and latch counter value. */
=2D	outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
=2D
=2D	low =3D inb(TIMER_CNTR0);
=2D	high =3D inb(TIMER_CNTR0);
=2D	count =3D 0xffff - ((high << 8) | low);
=2D	mtx_unlock_spin(&clock_lock);
=2D	return (count);
+	return (timer0_max_count - getit());
 }
=20
 static unsigned
=2D-- //depot/vendor/freebsd/src/sys/dev/acpica/acpi_resource.c	2005/03/18=
=20
12:00:41
+++ //depot/user/jhb/acpipci/dev/acpica/acpi_resource.c	2005/04/01 20:55:40
@@ -77,6 +77,12 @@
 	    req->counter++;
 	    break;
 	}
+	if (irq !=3D rman_get_start(req->res) && irq =3D=3D 0) {
+		if (bootverbose)
+			printf("IRQ is %u, resource is %lu\n", irq,
+			    rman_get_start(req->res));
+		return (AE_CTRL_TERMINATE);
+	}
 	req->found =3D 1;
 	KASSERT(irq =3D=3D rman_get_start(req->res),
 	    ("IRQ resources do not match"));
=2D-- //depot/vendor/freebsd/src/sys/i386/i386/io_apic.c	2005/04/14 18:01:23
+++ //depot/user/jhb/acpipci/i386/i386/io_apic.c	2005/06/24 18:08:09
@@ -89,6 +89,7 @@
 	u_int io_masked:1;
 	int io_dest:5;
 	int io_bus:4;
+	uint32_t io_lowreg;
 };
=20
 struct ioapic {
@@ -201,9 +202,7 @@
=20
 	mtx_lock_spin(&icu_lock);
 	if (intpin->io_masked) {
=2D		flags =3D ioapic_read(io->io_addr,
=2D		    IOAPIC_REDTBL_LO(intpin->io_intpin));
=2D		flags &=3D ~(IOART_INTMASK);
+		flags =3D intpin->io_lowreg & ~IOART_INTMASK;
 		ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin),
 		    flags);
 		intpin->io_masked =3D 0;
@@ -220,9 +219,7 @@
=20
 	mtx_lock_spin(&icu_lock);
 	if (!intpin->io_masked && !intpin->io_edgetrigger) {
=2D		flags =3D ioapic_read(io->io_addr,
=2D		    IOAPIC_REDTBL_LO(intpin->io_intpin));
=2D		flags |=3D IOART_INTMSET;
+		flags =3D intpin->io_lowreg | IOART_INTMSET;
 		ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin),
 		    flags);
 		intpin->io_masked =3D 1;
@@ -305,6 +302,7 @@
=20
 	/* Write the values to the APIC. */
 	mtx_lock_spin(&icu_lock);
+	intpin->io_lowreg =3D low;
 	ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), low);
 	value =3D ioapic_read(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin));
 	value &=3D ~IOART_DEST;
=2D-- //depot/vendor/freebsd/src/sys/i386/isa/clock.c	2005/07/05 20:15:24
+++ //depot/user/jhb/acpipci/i386/isa/clock.c	2005/07/07 21:28:18
@@ -110,6 +110,7 @@
 #endif
 u_int	timer_freq =3D TIMER_FREQ;
 int	timer0_max_count;
+int	timer0_real_max_count;
 int	wall_cmos_clock;	/* wall CMOS clock assumed if !=3D 0 */
 struct mtx clock_lock;
 #define	RTC_LOCK	mtx_lock_spin(&clock_lock)
@@ -117,7 +118,6 @@
=20
 static	int	beeping =3D 0;
 static	const u_char daysinmonth[] =3D {31,28,31,30,31,30,31,31,30,31,30,31=
};
=2Dstatic	u_int	hardclock_max_count;
 static	struct intsrc *i8254_intsrc;
 static	u_int32_t i8254_lastcount;
 static	u_int32_t i8254_offset;
@@ -531,21 +531,23 @@
 static void
 set_timer_freq(u_int freq, int intr_freq)
 {
=2D	int new_timer0_max_count;
+	int new_timer0_real_max_count;
=20
 	i8254_timecounter.tc_frequency =3D freq;
 	mtx_lock_spin(&clock_lock);
 	timer_freq =3D freq;
=2D	new_timer0_max_count =3D hardclock_max_count =3D TIMER_DIV(intr_freq);
 	if (using_lapic_timer) {
+		new_timer0_real_max_count =3D 0x10000;
+	else
+		new_timer0_real_max_count =3D TIMER_DIV(intr_freq);
+	if (new_timer0_real_max_count !=3D timer0_real_max_count) {
+		if (timer0_real_max_count =3D=3D 0x10000)
+			timer0_max_count =3D 0xffff;
+		else
+			timer0_max_count =3D timer0_max_real_count;
 		outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
=2D		outb(TIMER_CNTR0, 0);
=2D		outb(TIMER_CNTR0, 0);
=2D	} else if (new_timer0_max_count !=3D timer0_max_count) {
=2D		timer0_max_count =3D new_timer0_max_count;
=2D		outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
=2D		outb(TIMER_CNTR0, timer0_max_count & 0xff);
=2D		outb(TIMER_CNTR0, timer0_max_count >> 8);
+		outb(TIMER_CNTR0, timer0_real_max_count & 0xff);
+		outb(TIMER_CNTR0, timer0_real_max_count >> 8);
 	}
 	mtx_unlock_spin(&clock_lock);
 }
@@ -554,7 +556,11 @@
 i8254_restore(void)
 {
=20
=2D	set_timer_freq(timer_freq, hz);
+	mtx_lock_spin(&clock_lock);
+	outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
+	outb(TIMER_CNTR0, timer0_real_max_count & 0xff);
+	outb(TIMER_CNTR0, timer0_real_max_count >> 8);
+	mtx_unlock_spin(&clock_lock);
 }
=20
 static void
@@ -876,19 +882,8 @@
 static unsigned
 i8254_simple_get_timecount(struct timecounter *tc)
 {
=2D	u_int count;
=2D	u_int high, low;
=20
=2D	mtx_lock_spin(&clock_lock);
=2D
=2D	/* Select timer0 and latch counter value. */
=2D	outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
=2D
=2D	low =3D inb(TIMER_CNTR0);
=2D	high =3D inb(TIMER_CNTR0);
=2D	count =3D 0xffff - ((high << 8) | low);
=2D	mtx_unlock_spin(&clock_lock);
=2D	return (count);
+	return (timer0_max_count - getit());
 }
=20
 static unsigned
=2D-- //depot/vendor/freebsd/src/sys/pc98/cbus/clock.c	2005/07/05 20:15:24
+++ //depot/user/jhb/acpipci/pc98/cbus/clock.c	2005/07/08 14:53:31
@@ -109,12 +109,12 @@
 #endif
 u_int	timer_freq =3D TIMER_FREQ;
 int	timer0_max_count;
+int	timer0_real_max_count;
 int	wall_cmos_clock;	/* wall CMOS clock assumed if !=3D 0 */
 struct mtx clock_lock;
=20
 static	int	beeping =3D 0;
 static	const u_char daysinmonth[] =3D {31,28,31,30,31,30,31,31,30,31,30,31=
};
=2Dstatic	u_int	hardclock_max_count;
 static	struct intsrc *i8254_intsrc;
 static	u_int32_t i8254_lastcount;
 static	u_int32_t i8254_offset;
@@ -472,21 +472,23 @@
 static void
 set_timer_freq(u_int freq, int intr_freq)
 {
=2D	int new_timer0_max_count;
+	int new_timer0_real_max_count;
=20
 	i8254_timecounter.tc_frequency =3D freq;
 	mtx_lock_spin(&clock_lock);
 	timer_freq =3D freq;
=2D	new_timer0_max_count =3D hardclock_max_count =3D TIMER_DIV(intr_freq);
 	if (using_lapic_timer) {
+		new_timer0_real_max_count =3D 0x10000;
+	else
+		new_timer0_real_max_count =3D TIMER_DIV(intr_freq);
+	if (new_timer0_real_max_count !=3D timer0_real_max_count) {
+		if (timer0_real_max_count =3D=3D 0x10000)
+			timer0_max_count =3D 0xffff;
+		else
+			timer0_max_count =3D timer0_max_real_count;
 		outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
=2D		outb(TIMER_CNTR0, 0);
=2D		outb(TIMER_CNTR0, 0);
=2D	} else if (new_timer0_max_count !=3D timer0_max_count) {
=2D		timer0_max_count =3D new_timer0_max_count;
=2D		outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
=2D		outb(TIMER_CNTR0, timer0_max_count & 0xff);
=2D		outb(TIMER_CNTR0, timer0_max_count >> 8);
+		outb(TIMER_CNTR0, timer0_real_max_count & 0xff);
+		outb(TIMER_CNTR0, timer0_real_max_count >> 8);
 	}
 	mtx_unlock_spin(&clock_lock);
 }
@@ -495,7 +497,11 @@
 i8254_restore(void)
 {
=20
=2D	set_timer_freq(timer_freq, hz);
+	mtx_lock_spin(&clock_lock);
+	outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
+	outb(TIMER_CNTR0, timer0_real_max_count & 0xff);
+	outb(TIMER_CNTR0, timer0_real_max_count >> 8);
+	mtx_unlock_spin(&clock_lock);
 }
=20
=20
@@ -815,19 +821,8 @@
 static unsigned
 i8254_simple_get_timecount(struct timecounter *tc)
 {
=2D	u_int count;
=2D	u_int high, low;
=20
=2D	mtx_lock_spin(&clock_lock);
=2D
=2D	/* Select timer0 and latch counter value. */
=2D	outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
=2D
=2D	low =3D inb(TIMER_CNTR0);
=2D	high =3D inb(TIMER_CNTR0);
=2D	count =3D 0xffff - ((high << 8) | low);
=2D	mtx_unlock_spin(&clock_lock);
=2D	return (count);
+	return (timer0_max_count - getit());
 }
=20
 static unsigned

=2D-=20
John Baldwin <jhb@FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve"  =3D  http://www.FreeBSD.org



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200507090923.20212.jhb>