Date: Wed, 14 Mar 2001 06:32:46 -0800 From: Ben Lovett <blovett@bsdguru.com> To: Dann Lunsford <dann@greycat.com> Cc: mobile@FreeBSD.ORG Subject: Re: Tosh 2595XDVD -- fan control? Message-ID: <20010314063246.A12367@bsdguru.com> In-Reply-To: <20010313234128.A70849@greycat.com>; from dann@greycat.com on Tue, Mar 13, 2001 at 11:41:28PM -0800 References: <20010313234128.A70849@greycat.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
I believe I saw Dann Lunsford (dann@greycat.com) write this:
> Have a ${SUBJECT}, running 4.2-STABLE as of Jan 5. Looking for data
> on turning on the cooling fan (as it gets a bit warm in there). Natch,
> Toshiba's reaction on hearing "FreeBSD" or "UNIX" is "Huh?", Anyone got
> a clue? Ideally, I'd just like to type "fan on" or "fan off", but I'll
> take whatever I can get. I've seen some references to Linux based
> utils of this type, but my experience has been that porting Linux
> hardware utils is pure torture.
>
> Thanks!
>
>
> --
> Dann Lunsford The only thing necessary for the triumph of evil
> dann@greycat.com is that men of good will do nothing. -- Cicero
>
> To Unsubscribe: send mail to majordomo@FreeBSD.org
> with "unsubscribe freebsd-mobile" in the body of the message
>
Hello Dann,
I had this very same problem on my Satellite 2505CDS and 2515CDS and
someone was kind enough to port the Linux fan util to FreeBSD so it
works great ;)
I have attached the fan util and here are some instructions on how to
use it. It *may* need to be modified slightly for a new laptop but I'm
not sure (not being a coder myself).
To start run: fan -n
to stop: fan -f (both must be done as root)
HTH
--
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Ben Lovett printf("Hello world!);
blovett@bsdguru.com return 0;
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
The dark ages were caused by the Y1K problem.
[-- Attachment #2 --]
/* fan.c -- turn the internal fan on/off in a Toshiba Pentium(tm) laptop.
*
* Copyright (c) 1996/98 Jonathan A. Buzzard (jonathan@buzzard.org.uk)
*
* $Log: fan.c,v $
* Revision 3.1 1999/07/24 13:52:37 jab
* updates for glibc
*
* Revision 3.0 1998/07/11 14:01:38 jab
* New selective switching method based on the return from GetMachineID,
* should work on all known models
*
* Revision 2.2 1998/05/30 22:50:03 jab
* hopefully fixed problems with reporting of fan status
*
* Revision 2.1 1998/05/08 22:52:17 jab
* now drop root priveleges as soon as permision on the ports granted
*
* Revision 2.0 1998/01/31 16:00:23 jab
* Changed to new method of turning the fan on/off, which should
* work on a wider range of Toshiba laptops
*
* Revision 1.5 1997/05/23 13:17:25 jab
* change the command line option processing to only deal with the first
*
* Revision 1.4 1997/04/29 21:26:11 jab
* changed the name of the port variables to reflect their real status
*
* Revision 1.3 1996/08/01 14:25:36 jab
* Added logging of changes in fan status via syslogd(8)
*
* Revision 1.2 1996/07/30 18:11:16 jab
* fixed reporting of unknown command line options
*
* Revision 1.1 1996/06/25 21:47:42 jab
* Initial revision
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
static const char rcsid[]="$Id: fan.c,v 3.1 1999/07/24 13:52:37 jab Exp jab $";
#include<unistd.h>
#include<syslog.h>
#include<pwd.h>
/* #include<features.h> */
#ifdef __GLIBC__
#include<sys/perm.h>
#endif
#include<stdio.h>
#include<stdlib.h>
#include<machine/sysarch.h>
#define DEFAULT 0
#define PORTAGE 1
#define TECRA 2
int GetMachineID(int *id)
{
unsigned short lsb,msb;
unsigned char fl1,fl2;
return 0;
asm ("movw $0xfe00,%%ax\n\t" \
"movw $0x0070,%%bx\n\t" \
"movl $0x000ffffa,%%edx\n\t" \
"inb $0xb2,%%al\n\t" \
"movw %%cx,%0\n\t" \
"lahf\n\t" \
"movb %%ah,%1\n\t" \
"movw $0xfe00,%%ax\n\t" \
"movw $0x0070,%%bx\n\t" \
"movl $0x000ffffe,%%edx\n\t" \
"inb $0xb2,%%al\n\t" \
"movw %%cx,%2\n\t" \
"lahf\n\t" \
"movb %%ah,%3\n"
:"=m" (lsb), "=m" (fl1), "=m" (msb), "=m" (fl2) \
: \
: "memory" );
*id = (lsb & 0xff) + 0x100*(msb & 0xff);
return ((fl1 & 0x01)==1) || ((fl2 & 0x01)==1);
}
void FanOn(int method)
{
switch (method) {
case PORTAGE:
asm("cli\n\t" \
"movb $0xbe,%al\n\t" \
"outb %al,$0xe4\n\t" \
"inb $0xe5,%al\n\t" \
"andb $0xfe,%al\n\t" \
"movb %al,%ah\n\t" \
"movb $0xbe,%al\n\t" \
"outb %al,$0xe4\n\t" \
"movb %ah,%al\n\t" \
"outb %al,$0xe5\n\t" \
"sti");
break;
case TECRA:
asm("cli\n\t" \
"movw $0x00e4,%dx\n\t" \
"movb $0xe0,%al\n\t" \
"outb %al,%dx\n\t" \
"incw %dx\n\t" \
"inb %dx,%al\n\t" \
"orw $0x0001,%ax\n\t" \
"decw %dx\n\t" \
"movb %al,%ah\n\t" \
"movb $0xe0,%al\n\t" \
"outw %ax,%dx\n\t" \
"sti");
break;
default:
asm ("movw $0xffff,%ax\n\t" \
"movw $0x0004,%bx\n\t" \
"movw $0x0001,%cx\n\t" \
"inb $0xb2,%al");
break;
}
return;
}
void FanOff(int method)
{
switch (method) {
case PORTAGE:
asm("cli\n\t" \
"movb $0xbe,%al\n\t" \
"outb %al,$0xe4\n\t" \
"inb $0xe5,%al\n\t" \
"orb $0x01,%al\n\t" \
"movb %al,%ah\n\t" \
"movb $0xbe,%al\n\t" \
"outb %al,$0xe4\n\t" \
"movb %ah,%al\n\t" \
"outb %al,$0xe5\n\t" \
"sti");
break;
case TECRA:
asm("cli\n\t" \
"movw $0x00e4,%dx\n\t" \
"movb $0xe0,%al\n\t" \
"outb %al,%dx\n\t" \
"incw %dx\n\t" \
"inb %dx,%al\n\t" \
"andw $0xfffe,%ax\n\t" \
"decw %dx\n\t" \
"movb %al,%ah\n\t" \
"movb $0xe0,%al\n\t" \
"outw %ax,%dx\n\t" \
"sti");
break;
default:
asm ("movw $0xffff,%ax\n\t" \
"movw $0x0004,%bx\n\t" \
"movw $0x0000,%cx\n\t" \
"inb $0xb2,%al");
break;
}
return;
}
int FanStatus(int method)
{
unsigned short status;
switch(method) {
case PORTAGE:
asm("cli\n\t" \
"movb $0xbe,%%al\n\t" \
"outb %%al,$0xe4\n\t" \
"inb $0xe5,%%al\n\t" \
"andw $0x0001,%%ax\n\t" \
"movw %%ax,%0\n\t" \
"sti\n"
:"=m" (status) : : "memory" );
status = (status==0x00) ? 0x01:0x00;
break;
case TECRA:
asm("cli\n\t" \
"movw $0x00e4,%%dx\n\t" \
"movb $0xe0,%%al\n\t" \
"outb %%al,%%dx\n\t" \
"incw %%dx\n\t" \
"inb %%dx,%%al\n\t" \
"andw $0x0001,%%ax\n\t"
"movw %%ax,%0\n\t" \
"sti\n"
:"=m" (status) : : "memory" );
break;
default:
asm ("pushl %%eax\n\t" \
"pushl %%ebx\n\t" \
"pushl %%ecx\n\t" \
"movw $0xfefe,%%ax\n\t" \
"movw $0x0004,%%bx\n\t" \
"movw $0x0000,%%cx\n\t" \
"inb $0xb2,%%al\n\t" \
"andw $0x0001,%%cx\n\t" \
"movw %%cx,%0\n\t" \
"popl %%ecx\n\t" \
"popl %%ebx\n\t" \
"popl %%eax\n"
:"=m" (status) : : "memory" );
break;
}
return (int) status;
}
int main(int argc, char *argv[])
{
int method,id;
struct passwd *pw;
char *name;
/* get the necessary I/O permissions */
#ifdef NONONO
if (iopl(3)) {
printf("fan: can't get I/O permissions.\n");
exit (1);
}
#endif /* NONONO */
if ( i386_set_ioperm( 0xb2, 4, 1) )
perror("ioperm()");
/* drop root priveleges to minimize security risk of running suid root */
/* seteuid(getuid());
setegid(getgid()); */
/* open connection to system logger */
openlog("fan", LOG_PID | LOG_CONS, LOG_USER);
/* get user name */
pw = getpwuid(getuid());
name = pw ? pw->pw_name : getenv("LOGNAME");
/* select a method based on the model we are running on */
method = DEFAULT;
if (GetMachineID(&id)==0x00) {
if (id==0xfccb)
method = PORTAGE;
else if (id==0xfccc)
method = TECRA;
}
/* process command line arguments */
if ((--argc>0) && ((*++argv)[0]=='-'))
switch (*++argv[0]) {
case 'n': /* turn the fan on */
FanOn(method);
syslog(LOG_INFO, "cooling fan turned on by %s", name);
break;
case 'f': /* turn the fan off */
FanOff(method);
syslog(LOG_INFO, "cooling fan turned off by %s", name);
break;
default:
printf("fan: illegal option %s\nUsage: fan [-n|f]\n", argv[0]);
exit(1);
}
/* Toshiba's fan.exe waits here for 0.1 seconds, so we do the same */
usleep(100000);
/* print the current status of the fan */
if (FanStatus(method)==0x00)
printf("Fan is off.\n");
else
printf("Fan is on.\n");
return 0;
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010314063246.A12367>
