Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 21 May 2008 21:23:25 +0400
From:      Vladimir Grebenschikov <vova@fbsd.ru>
To:        takawata@init-main.com
Cc:        freebsd-acpi@freebsd.org
Subject:   Re: SMP suspend/resume.
Message-ID:  <1211390605.1794.15.camel@localhost>
In-Reply-To: <1211379715.2851.2.camel@localhost>
References:  <200805131125.m4DBPu1q092741@sana.init-main.com> <1211379715.2851.2.camel@localhost>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 2008-05-21 at 18:21 +0400, Vladimir Grebenschikov wrote:
> On Tue, 2008-05-13 at 20:25 +0900, takawata@init-main.com wrote:
> > Hi, I managed to make suspend and resume work on SMP system.
> > The patch following is a bit crude patch, but it begin=20
> > to work on my ThinkPad X61 (core2duo system).
>=20
> Tried patch on T60, from text console,=20
> on acpiconf -s3
> it shows multiple times "forward_wakeup: Idle processor not found" on
> console and then friezed hard (even DDB does not works). But nothing was
> suspended actually ( before system goes to sleep but did not awakes)
>=20
> Any hints ?

In some conditions (single-user, no additional drivers) it shows:

forward_wakeup: Idle processor not found
PREP_WALK
LEAVE_SLEEP_STATE
DEVICE_RESUME
=EF=BB=BFforward_wakeup: Idle processor not found
ENABLE_FIXED_EVENT
=EF=BB=BFforward_wakeup: Idle processor not found
=EF=BB=BFforward_wakeup: Idle processor not found
=EF=BB=BFforward_wakeup: Idle processor not found
=EF=BB=BFforward_wakeup: Idle processor not found
=EF=BB=BFforward_wakeup: Idle processor not found
... etc ...

sometimes it shows just many
=EF=BB=BFforward_wakeup: Idle processor not found


and in any case locks hard and did not enter S3

But RELENG_7 (without patch) normally enters to S3, but failed to wake.

> > TODO:
> > 1. Suspend/resume path it self is simular to AP boot path.
> > Some of code may be integrated.
> > 2. More context, like MTRR or npx context should be saved on=20
> > suspend.
> > 3. Make acpi  suspend resume path more ABI aware: needless=20
> > register recoverly or special register context saving=20
> > (the value itself is usually constant) should be removed.
> > 4. Make same binary module work on both UP or SMP case.
> > (Or is it time to give up using acpi module on also on i386?)
> >=20
> >=20
> >=20
> >=20
> >=20
> > Index: i386/acpica/acpi_wakeup.c
> > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> > RCS file: /home/ncvs/src/sys/i386/acpica/acpi_wakeup.c,v
> > retrieving revision 1.47
> > diff -u -r1.47 acpi_wakeup.c
> > --- i386/acpica/acpi_wakeup.c	16 Mar 2008 10:58:03 -0000	1.47
> > +++ i386/acpica/acpi_wakeup.c	13 May 2008 09:12:18 -0000
> > @@ -27,6 +27,7 @@
> > =20
> >  #include <sys/cdefs.h>
> >  __FBSDID("$FreeBSD: src/sys/i386/acpica/acpi_wakeup.c,v 1.47 2008/03/1=
6 10:58:03 rwatson Exp $");
> > +#define SMP
> > =20
> >  #include <sys/param.h>
> >  #include <sys/systm.h>
> > @@ -49,6 +50,11 @@
> > =20
> >  #include <contrib/dev/acpica/acpi.h>
> >  #include <dev/acpica/acpivar.h>
> > +#include <sys/smp.h>
> > +#include <machine/apicreg.h>
> > +#include <machine/apicvar.h>
> > +#include <machine/smp.h>
> > +#include <sys/sched.h>
> > =20
> >  #include "acpi_wakecode.h"
> > =20
> > @@ -71,7 +77,9 @@
> > =20
> >  static uint16_t		r_cs, r_ds, r_es, r_fs, r_gs, r_ss, r_tr;
> >  static uint32_t		r_esp;
> > -
> > +extern void *bootstacks[];
> > +static char *bootSTK;
> > +void restore_sub(void);
> >  static void		acpi_printcpu(void);
> >  static void		acpi_realmodeinst(void *arg, bus_dma_segment_t *segs,
> >  					  int nsegs, int error);
> > @@ -80,6 +88,7 @@
> >  /* XXX shut gcc up */
> >  extern int		acpi_savecpu(void);
> >  extern int		acpi_restorecpu(void);
> > +extern void		acpi_kicksub(void);
> > =20
> >  #ifdef __GNUCLIKE_ASM
> >  __asm__("				\n\
> > @@ -104,6 +113,15 @@
> >  	movl	%eax,(%esp)		\n\
> >  	xorl	%eax,%eax		\n\
> >  	ret				\n\
> > +				\n\
> > +	.text				\n\
> > +	.p2align 2, 0x90		\n\
> > +	.type acpi_kicksub, @function  \n\
> > +acpi_kicksub:			\n\
> > +	.align 4			\n\
> > +	movl	bootSTK,%esp		\n\
> > +	jmp     restore_sub		\n\
> > +	ret				\n\
> >  					\n\
> >  	.text				\n\
> >  	.p2align 2, 0x90		\n\
> > @@ -149,6 +167,24 @@
> >  	ret				\n\
> >  ");
> >  #endif /* __GNUCLIKE_ASM */
> > +int acpi_cpu_resumed[MAXCPU];
> > +int acpi_curcpu;
> > +extern int switch_debug;
> > +
> > +void restore_sub()
> > +{
> > +	ACPI_DISABLE_IRQS();
> > +	printf("RESTORE_SUB\n");
> > +	lapic_disable();=09
> > +	printf("LAPIC_SETUP\n");
> > +	lapic_setup(0);=09
> > +	lapic_dump("RESTORE_SUB");
> > +	printf("RESTORE_SUB2\n");
> > +	ACPI_ENABLE_IRQS();
> > +
> > +	acpi_cpu_resumed[acpi_curcpu]=3D 1;
> > +	acpi_restorecpu();
> > +}
> > =20
> >  static void
> >  acpi_printcpu(void)
> > @@ -187,6 +223,119 @@
> >  	outb(0x61, inb(0x61) & ~0x3);
> >  }
> > =20
> > +
> > +int resume_other_cpu(struct acpi_softc *sc, int cpu);
> > +int resume_other_cpu(struct acpi_softc *sc, int cpu)
> > +{
> > +	int ms;
> > +	int apic_id =3D cpu_apic_ids[cpu];
> > +	int gsel_tss;
> > +
> > +	gsel_tss =3D GSEL(GPROC0_SEL, SEL_KPL);
> > +	acpi_curcpu =3D cpu;
> > +	bootSTK=3D (char *)bootstacks[cpu] + KSTACK_PAGES * PAGE_SIZE - 4;
> > +	printf("%p\n", bootSTK);=09
> > +	p_gdt =3D (struct region_descriptor *)
> > +		(sc->acpi_wakeaddr + physical_gdt);
> > +	saved_gdt.rd_limit =3D NGDT * sizeof(gdt[0]) -1;
> > +	saved_gdt.rd_base =3D (int )&gdt[cpu*NGDT];
> > +	p_gdt->rd_limit =3D saved_gdt.rd_limit;
> > + 	p_gdt->rd_base =3D vtophys(saved_gdt.rd_base);
> > +	r_esp =3D stoppcbs[cpu].pcb_esp;
> > +	r_ebp =3D stoppcbs[cpu].pcb_ebp;
> > +	r_esi =3D stoppcbs[cpu].pcb_esi;
> > +	r_edi =3D stoppcbs[cpu].pcb_edi;
> > +	r_efl =3D stoppcbs[cpu].pcb_psl;
> > +	ret_addr =3D stoppcbs[cpu].pcb_eip;
> > +	WAKECODE_FIXUP(physical_esp, uint32_t, vtophys(bootSTK) );
> > +	WAKECODE_FIXUP(previous_cr0, uint32_t, r_cr0);
> > +	WAKECODE_FIXUP(previous_cr2, uint32_t, r_cr2);
> > +	WAKECODE_FIXUP(previous_cr3, uint32_t, r_cr3);
> > +	WAKECODE_FIXUP(previous_cr4, uint32_t, r_cr4);
> > +=09
> > +	WAKECODE_FIXUP(resume_beep, uint32_t, 0);
> > +	WAKECODE_FIXUP(reset_video, uint32_t, 0);
> > +=09
> > +	WAKECODE_FIXUP(previous_tr,  uint16_t, gsel_tss);
> > +	WAKECODE_BCOPY(previous_gdt, struct region_descriptor, saved_gdt);
> > +	WAKECODE_FIXUP(previous_ldt, uint16_t, saved_ldt);
> > +	WAKECODE_BCOPY(previous_idt, struct region_descriptor, saved_idt);
> > +=09
> > +	WAKECODE_FIXUP(where_to_recover, void *, acpi_kicksub);
> > +=09
> > +	WAKECODE_FIXUP(previous_ds,  uint16_t, r_ds);
> > +	WAKECODE_FIXUP(previous_es,  uint16_t, r_es);
> > +	WAKECODE_FIXUP(previous_fs,  uint16_t, r_fs);
> > +	WAKECODE_FIXUP(previous_gs,  uint16_t, 0);
> > +	WAKECODE_FIXUP(previous_ss,  uint16_t, r_ss);
> > +
> > +	/* do an INIT IPI: assert RESET */
> > +	lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
> > +	    APIC_LEVEL_ASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT, apic_i=
d);
> > +
> > +	/* wait for pending status end */
> > +	lapic_ipi_wait(-1);
> > +
> > +	/* do an INIT IPI: deassert RESET */
> > +	lapic_ipi_raw(APIC_DEST_ALLESELF | APIC_TRIGMOD_LEVEL |
> > +	    APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT, 0);
> > +
> > +	/* wait for pending status end */
> > +	DELAY(10000);		/* wait ~10mS */
> > +	lapic_ipi_wait(-1);
> > +	/*
> > +	 * next we do a STARTUP IPI: the previous INIT IPI might still be
> > +	 * latched, (P5 bug) this 1st STARTUP would then terminate
> > +	 * immediately, and the previously started INIT IPI would continue. O=
R
> > +	 * the previous INIT IPI has already run. and this STARTUP IPI will
> > +	 * run. OR the previous INIT IPI was ignored. and this STARTUP IPI
> > +	 * will run.
> > +	 */
> > +
> > +	/* do a STARTUP IPI */
> > +	lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
> > +	    APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP |
> > +		      ((sc->acpi_wakephys >>12)&0xff), apic_id);
> > +	lapic_ipi_wait(-1);
> > +	DELAY(200);		/* wait ~200uS */
> > +
> > +	/*
> > +	 * finally we do a 2nd STARTUP IPI: this 2nd STARTUP IPI should run I=
F
> > +	 * the previous STARTUP IPI was cancelled by a latched INIT IPI. OR
> > +	 * this STARTUP IPI will be ignored, as only ONE STARTUP IPI is
> > +	 * recognized after hardware RESET or INIT IPI.
> > +	 */
> > +
> > +	lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
> > +	    APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP |
> > +	    ((sc->acpi_wakephys >>12)&0xff), apic_id);
> > +	lapic_ipi_wait(-1);
> > +	DELAY(200);		/* wait ~200uS */
> > +
> > +	/* Wait up to 5 seconds for it to start. */
> > +	for (ms =3D 0; ms < 5000; ms++) {
> > +		if(acpi_cpu_resumed[cpu]){
> > +			acpi_cpu_resumed[cpu]=3D 0;
> > +			return 0;
> > +		}
> > +		DELAY(1000);
> > +	}
> > +	return -1;		/* return FAILURE */
> > +
> > +}
> > +int resume_other_cpus(struct acpi_softc *sc);
> > +int resume_other_cpus(struct acpi_softc *sc)
> > +{
> > +	int i;
> > +	printf("RESUME_OTHER_CPUS");
> > +	*((volatile u_short *) 0x467) =3D 0;
> > +	*((volatile u_short *) 0x468) =3D (sc->acpi_wakephys&0xffff0)>>4;
> > +
> > +	for(i =3D 1; i < mp_ncpus; i++){
> > +		resume_other_cpu(sc, i);
> > +	}
> > +	return 0;
> > +}
> >  int
> >  acpi_sleep_machdep(struct acpi_softc *sc, int state)
> >  {
> > @@ -270,14 +419,15 @@
> >  		for (;;) ;
> >  	} else {
> >  		/* Execute Wakeup */
> > -		intr_resume();
> > -
> >  		if (bootverbose) {
> >  			acpi_savecpu();
> >  			acpi_printcpu();
> >  		}
> > +		resume_other_cpus(sc);
> > +		restart_cpus(stopped_cpus);
> > +		intr_resume();
> > +		lapic_dump("MAIN");
> >  	}
> > -
> >  out:
> >  	load_cr3(cr3);
> >  	write_eflags(ef);
> > @@ -285,7 +435,7 @@
> >  	/* If we beeped, turn it off after a delay. */
> >  	if (acpi_resume_beep)
> >  		timeout(acpi_stop_beep, NULL, 3 * hz);
> > -
> > +	printf("FUGAFUGA\n");
> >  	return (ret);
> >  }
> > =20
> > Index: i386/i386/io_apic.c
> > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> > RCS file: /home/ncvs/src/sys/i386/i386/io_apic.c,v
> > retrieving revision 1.35
> > diff -u -r1.35 io_apic.c
> > --- i386/i386/io_apic.c	5 Jun 2007 18:57:48 -0000	1.35
> > +++ i386/i386/io_apic.c	13 May 2008 08:22:55 -0000
> > @@ -444,8 +444,9 @@
> >  	struct ioapic *io =3D (struct ioapic *)pic;
> >  	int i;
> > =20
> > -	for (i =3D 0; i < io->io_numintr; i++)
> > +	for (i =3D 0; i < io->io_numintr; i++){
> >  		ioapic_program_intpin(&io->io_pins[i]);
> > +	}
> >  }
> > =20
> >  /*
> > Index: i386/i386/mp_machdep.c
> > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> > RCS file: /home/ncvs/src/sys/i386/i386/mp_machdep.c,v
> > retrieving revision 1.286
> > diff -u -r1.286 mp_machdep.c
> > --- i386/i386/mp_machdep.c	10 Apr 2008 18:38:31 -0000	1.286
> > +++ i386/i386/mp_machdep.c	13 May 2008 07:08:29 -0000
> > @@ -1299,18 +1299,19 @@
> >  	int cpu =3D PCPU_GET(cpuid);
> >  	int cpumask =3D PCPU_GET(cpumask);
> > =20
> > -	savectx(&stoppcbs[cpu]);
> > -
> > -	/* Indicate that we are stopped */
> > -	atomic_set_int(&stopped_cpus, cpumask);
> > +	if(savectx(&stoppcbs[cpu])){
> > +		/* Indicate that we are stopped */
> > +		atomic_set_int(&stopped_cpus, cpumask);
> > +		wbinvd();
> > +	}
> > =20
> >  	/* Wait for restart */
> > -	while (!(started_cpus & cpumask))
> > -	    ia32_pause();
> > -
> > +	while (!(started_cpus & cpumask)){
> > +		ia32_pause();
> > +	}
> >  	atomic_clear_int(&started_cpus, cpumask);
> >  	atomic_clear_int(&stopped_cpus, cpumask);
> > -
> > +=09
> >  	if (cpu =3D=3D 0 && cpustop_restartfunc !=3D NULL) {
> >  		cpustop_restartfunc();
> >  		cpustop_restartfunc =3D NULL;
> > Index: i386/i386/swtch.s
> > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> > RCS file: /home/ncvs/src/sys/i386/i386/swtch.s,v
> > retrieving revision 1.156
> > diff -u -r1.156 swtch.s
> > --- i386/i386/swtch.s	22 Aug 2007 05:06:14 -0000	1.156
> > +++ i386/i386/swtch.s	9 May 2008 15:16:03 -0000
> > @@ -413,6 +413,6 @@
> >  1:
> >  	popfl
> >  #endif	/* DEV_NPX */
> > -
> > +	movl  $1, %eax
> >  	ret
> >  END(savectx)
> > Index: i386/include/pcb.h
> > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> > RCS file: /home/ncvs/src/sys/i386/include/pcb.h,v
> > retrieving revision 1.56
> > diff -u -r1.56 pcb.h
> > --- i386/include/pcb.h	29 Dec 2005 13:23:48 -0000	1.56
> > +++ i386/include/pcb.h	24 Apr 2008 06:46:59 -0000
> > @@ -81,7 +81,7 @@
> >  struct trapframe;
> > =20
> >  void	makectx(struct trapframe *, struct pcb *);
> > -void	savectx(struct pcb *);
> > +int	savectx(struct pcb *);
> >  #endif
> > =20
> >  #endif /* _I386_PCB_H_ */
> > Index: dev/acpica/acpi.c
> > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> > RCS file: /home/ncvs/src/sys/dev/acpica/acpi.c,v
> > retrieving revision 1.247
> > diff -u -r1.247 acpi.c
> > --- dev/acpica/acpi.c	13 Mar 2008 20:39:03 -0000	1.247
> > +++ dev/acpica/acpi.c	30 Apr 2008 13:14:48 -0000
> > @@ -29,7 +29,7 @@
> > =20
> >  #include <sys/cdefs.h>
> >  __FBSDID("$FreeBSD: src/sys/dev/acpica/acpi.c,v 1.247 2008/03/13 20:39=
:03 jhb Exp $");
> > -
> > +#define SMP
> >  #include "opt_acpi.h"
> >  #include <sys/param.h>
> >  #include <sys/kernel.h>
> > @@ -47,6 +47,7 @@
> >  #include <sys/power.h>
> >  #include <sys/sbuf.h>
> >  #include <sys/smp.h>
> > +#include <sys/sched.h>
> > =20
> >  #include <machine/resource.h>
> >  #include <machine/bus.h>
> > @@ -2339,6 +2340,8 @@
> >       * drivers need this.
> >       */
> >      mtx_lock(&Giant);
> > +    sched_bind(curthread, 0);
> > +    stop_cpus(PCPU_GET(other_cpus));
> >      slp_state =3D ACPI_SS_NONE;
> >      switch (state) {
> >      case ACPI_STATE_S1:
> > @@ -2430,13 +2433,16 @@
> >  	acpi_wake_prep_walk(state);
> >  	sc->acpi_sstate =3D ACPI_STATE_S0;
> >      }
> > +    printf("PREP WALK\n");
> >      if (slp_state >=3D ACPI_SS_SLP_PREP)
> >  	AcpiLeaveSleepState(state);
> > +    printf("LEAVE_SLEEP_STATE\n");
> >      if (slp_state >=3D ACPI_SS_DEV_SUSPEND)
> >  	DEVICE_RESUME(root_bus);
> > +    printf("DEVICE_RESUME\n");
> >      if (slp_state >=3D ACPI_SS_SLEPT)
> >  	acpi_enable_fixed_events(sc);
> > -
> > +    printf("ENABLE_FIXED_EVENT\n");
> >      /* Allow another sleep request after a while. */
> >      if (state !=3D ACPI_STATE_S5)
> >  	timeout(acpi_sleep_enable, sc, hz * ACPI_MINIMUM_AWAKETIME);
> > @@ -2445,6 +2451,7 @@
> >      acpi_UserNotify("Resume", ACPI_ROOT_OBJECT, state);
> > =20
> >      mtx_unlock(&Giant);
> > +    sched_unbind(curthread);
> >      return_ACPI_STATUS (status);
> >  }
> > =20
> > Index: dev/acpica/acpi_ec.c
> > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> > RCS file: /home/ncvs/src/sys/dev/acpica/acpi_ec.c,v
> > retrieving revision 1.80
> > diff -u -r1.80 acpi_ec.c
> > --- dev/acpica/acpi_ec.c	8 Nov 2007 21:20:34 -0000	1.80
> > +++ dev/acpica/acpi_ec.c	7 May 2008 17:07:11 -0000
> > @@ -747,7 +747,7 @@
> >       * If booting, check if we need to run the query handler.  If so, =
we
> >       * we call it directly here since our thread taskq is not active y=
et.
> >       */
> > -    if (cold || rebooting) {
> > +    if (cold || rebooting||sc->ec_suspending) {
> >  	if ((EC_GET_CSR(sc) & EC_EVENT_SCI)) {
> >  	    CTR0(KTR_ACPI, "ec running gpe handler directly");
> >  	    EcGpeQueryHandler(sc);
> > _______________________________________________
> > freebsd-acpi@freebsd.org mailing list
> > http://lists.freebsd.org/mailman/listinfo/freebsd-acpi
> > To unsubscribe, send any mail to "freebsd-acpi-unsubscribe@freebsd.org"
--=20
Vladimir B. Grebenschikov
vova@fbsd.ru



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