Suspend broken ?
John Baldwin
jhb at FreeBSD.org
Sat Jul 9 13:34:44 GMT 2005
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 at gmx.net> wrote:
> > > On Mon, 2005-07-04 at 21:33 +0800, Huang wen hui wrote:
> > > > Huang wen hui 写é“:
> > > > >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.
--- //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 = TIMER_FREQ;
int timer0_max_count;
+int timer0_real_max_count;
int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
struct mtx clock_lock;
#define RTC_LOCK mtx_lock_spin(&clock_lock)
@@ -108,7 +109,6 @@
static int beeping = 0;
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
-static 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)
{
- int new_timer0_max_count;
+ int new_timer0_real_max_count;
i8254_timecounter.tc_frequency = freq;
mtx_lock_spin(&clock_lock);
timer_freq = freq;
- new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
if (using_lapic_timer) {
+ new_timer0_real_max_count = 0x10000;
+ else
+ new_timer0_real_max_count = TIMER_DIV(intr_freq);
+ if (new_timer0_real_max_count != timer0_real_max_count) {
+ if (timer0_real_max_count == 0x10000)
+ timer0_max_count = 0xffff;
+ else
+ timer0_max_count = timer0_max_real_count;
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
- outb(TIMER_CNTR0, 0);
- outb(TIMER_CNTR0, 0);
- } else if (new_timer0_max_count != timer0_max_count) {
- timer0_max_count = new_timer0_max_count;
- outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
- outb(TIMER_CNTR0, timer0_max_count & 0xff);
- 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)
{
- u_int count;
- u_int high, low;
- mtx_lock_spin(&clock_lock);
-
- /* Select timer0 and latch counter value. */
- outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
-
- low = inb(TIMER_CNTR0);
- high = inb(TIMER_CNTR0);
- count = 0xffff - ((high << 8) | low);
- mtx_unlock_spin(&clock_lock);
- return (count);
+ return (timer0_max_count - getit());
}
static unsigned
--- //depot/vendor/freebsd/src/sys/dev/acpica/acpi_resource.c 2005/03/18
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 != rman_get_start(req->res) && irq == 0) {
+ if (bootverbose)
+ printf("IRQ is %u, resource is %lu\n", irq,
+ rman_get_start(req->res));
+ return (AE_CTRL_TERMINATE);
+ }
req->found = 1;
KASSERT(irq == rman_get_start(req->res),
("IRQ resources do not match"));
--- //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;
};
struct ioapic {
@@ -201,9 +202,7 @@
mtx_lock_spin(&icu_lock);
if (intpin->io_masked) {
- flags = ioapic_read(io->io_addr,
- IOAPIC_REDTBL_LO(intpin->io_intpin));
- flags &= ~(IOART_INTMASK);
+ flags = intpin->io_lowreg & ~IOART_INTMASK;
ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin),
flags);
intpin->io_masked = 0;
@@ -220,9 +219,7 @@
mtx_lock_spin(&icu_lock);
if (!intpin->io_masked && !intpin->io_edgetrigger) {
- flags = ioapic_read(io->io_addr,
- IOAPIC_REDTBL_LO(intpin->io_intpin));
- flags |= IOART_INTMSET;
+ flags = intpin->io_lowreg | IOART_INTMSET;
ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin),
flags);
intpin->io_masked = 1;
@@ -305,6 +302,7 @@
/* Write the values to the APIC. */
mtx_lock_spin(&icu_lock);
+ intpin->io_lowreg = low;
ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), low);
value = ioapic_read(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin));
value &= ~IOART_DEST;
--- //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 = TIMER_FREQ;
int timer0_max_count;
+int timer0_real_max_count;
int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
struct mtx clock_lock;
#define RTC_LOCK mtx_lock_spin(&clock_lock)
@@ -117,7 +118,6 @@
static int beeping = 0;
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
-static 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)
{
- int new_timer0_max_count;
+ int new_timer0_real_max_count;
i8254_timecounter.tc_frequency = freq;
mtx_lock_spin(&clock_lock);
timer_freq = freq;
- new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
if (using_lapic_timer) {
+ new_timer0_real_max_count = 0x10000;
+ else
+ new_timer0_real_max_count = TIMER_DIV(intr_freq);
+ if (new_timer0_real_max_count != timer0_real_max_count) {
+ if (timer0_real_max_count == 0x10000)
+ timer0_max_count = 0xffff;
+ else
+ timer0_max_count = timer0_max_real_count;
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
- outb(TIMER_CNTR0, 0);
- outb(TIMER_CNTR0, 0);
- } else if (new_timer0_max_count != timer0_max_count) {
- timer0_max_count = new_timer0_max_count;
- outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
- outb(TIMER_CNTR0, timer0_max_count & 0xff);
- 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)
{
- 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);
}
static void
@@ -876,19 +882,8 @@
static unsigned
i8254_simple_get_timecount(struct timecounter *tc)
{
- u_int count;
- u_int high, low;
- mtx_lock_spin(&clock_lock);
-
- /* Select timer0 and latch counter value. */
- outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
-
- low = inb(TIMER_CNTR0);
- high = inb(TIMER_CNTR0);
- count = 0xffff - ((high << 8) | low);
- mtx_unlock_spin(&clock_lock);
- return (count);
+ return (timer0_max_count - getit());
}
static unsigned
--- //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 = TIMER_FREQ;
int timer0_max_count;
+int timer0_real_max_count;
int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
struct mtx clock_lock;
static int beeping = 0;
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
-static 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)
{
- int new_timer0_max_count;
+ int new_timer0_real_max_count;
i8254_timecounter.tc_frequency = freq;
mtx_lock_spin(&clock_lock);
timer_freq = freq;
- new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
if (using_lapic_timer) {
+ new_timer0_real_max_count = 0x10000;
+ else
+ new_timer0_real_max_count = TIMER_DIV(intr_freq);
+ if (new_timer0_real_max_count != timer0_real_max_count) {
+ if (timer0_real_max_count == 0x10000)
+ timer0_max_count = 0xffff;
+ else
+ timer0_max_count = timer0_max_real_count;
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
- outb(TIMER_CNTR0, 0);
- outb(TIMER_CNTR0, 0);
- } else if (new_timer0_max_count != timer0_max_count) {
- timer0_max_count = new_timer0_max_count;
- outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
- outb(TIMER_CNTR0, timer0_max_count & 0xff);
- 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)
{
- 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);
}
@@ -815,19 +821,8 @@
static unsigned
i8254_simple_get_timecount(struct timecounter *tc)
{
- u_int count;
- u_int high, low;
- mtx_lock_spin(&clock_lock);
-
- /* Select timer0 and latch counter value. */
- outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
-
- low = inb(TIMER_CNTR0);
- high = inb(TIMER_CNTR0);
- count = 0xffff - ((high << 8) | low);
- mtx_unlock_spin(&clock_lock);
- return (count);
+ return (timer0_max_count - getit());
}
static unsigned
--
John Baldwin <jhb at FreeBSD.org> <>< http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve" = http://www.FreeBSD.org
More information about the freebsd-current
mailing list