I8K and Toshiba legacy driver cleanup
cover I8K and Toshiba legacy driver cleanup
Hi Andrew,
I have several patches cleaning up Toshiba and I8K drivers a bit and I was wondering if you could add them to -mm. I8K patches have been sent to LKML earlier and were tested (although I have dropped sysfs export patch, there were some objections from Greg).
01-toshiba-cleanup
Toshiba legacy driver cleanup:
- use module_init/module_exit for initialization instead of using
#ifdef MODULE and calling tosh_init manually from drivers/char/misc.c
- do not explicitly initialize static variables
- some whitespace and formatting cleanups
02-i8k-lindent.patch
- pass through Lindent to change 4 spaces identation to TABs
03-i8k-use-dmi.patch
- Change to use stock dmi infrastructure instead of homegrown parsing code. The driver now requires box's DMI data to match list of supported models so driver can be safely compiled-in by default without fear of it poking into random SMM BIOS code. DMI checks can be ignored with i8k.ignore_dmi option.
04-i8k-seqfile.patch
- Change proc code to use seq_file.
05-i8k-cleanup.patch
- use module_{init|exit} instead of old style #ifdef MODULE code, some formatting changes
06-i8k-new-signatures.patch
- add BIOS signatures of a newer Dell laptops, also there can be more than one temperature sensor reported by BIOS.
Thanks!
Signature · 1 line
Dmitry
PATCH 1/6 Toshiba driver cleanup
Toshiba legacy driver cleanup:
- use module_init/module_exit for initialization instead of using #ifdef MODULE and calling tosh_init manually from drivers/char/misc.c
- do not explicitly initialize static variables
- some whitespace and formatting cleanups
---
misc.c | 4 ---- toshiba.c | 60 ++++++++++++++++++++++++------------------------------------ 2 files changed, 24 insertions(+), 40 deletions(-)
drivers/char/toshiba.c +24 -36
@@ -73,16 +73,20 @@#define TOSH_MINOR_DEV 181 -static int tosh_id =0x0000 ; -static int tosh_bios =0x0000 ; -static int tosh_date =0x0000 ; -static int tosh_sci =0x0000 ; -static int tosh_fan =0 ; - -static int tosh_fn =0 ; +MODULE_LICENSE ("GPL" ); +MODULE_AUTHOR ("Jonathan Buzzard <[email protected]>" ); +MODULE_DESCRIPTION ("Toshiba laptop SMM driver" ); +MODULE_SUPPORTED_DEVICE ("toshiba" ); -module_param (tosh_fn, int,0 ); +static int tosh_fn; +module_param (fn, int,0 ); +MODULE_PARM_DESC (tosh_fn,"User specified Fn key detection port" ); +static int tosh_id; +static int tosh_bios; +static int tosh_date; +static int tosh_sci; +static int tosh_fan;static int tosh_ioctl (struct inode *,struct file *,unsigned int ,unsigned long );
@@ -359,7 +363,7 @@ static int tosh_get_machine_id(void)unsigned long address; id = (0x100 *(int )isa_readb (0xffffe ))+((int )isa_readb (0xffffa )); - +/* do we have a SCTTable machine identication number on our hands */ if (id==0xfc2f ) {
@@ -424,7 +428,7 @@ static int tosh_probe(void) }/* call the Toshiba SCI support check routine */ - + regs.eax =0xf0f0 ; regs.ebx =0x0000 ; regs.ecx =0x0000 ;
@@ -440,7 +444,7 @@ static int tosh_probe(void)/* if we get this far then we are running on a Toshiba (probably)! */ tosh_sci = regs.edx &0xffff ; - +/* next get the machine ID of the current laptop */ tosh_id =tosh_get_machine_id ();
@@ -475,16 +479,15 @@ static int tosh_probe(void)return 0 ; } -int __init tosh_init (void ) +static int __init toshiba_init (void ) {int retval;/* are we running on a Toshiba laptop */ -if (tosh_probe ()!=0 ) -return -EIO ; +if (tosh_probe ()) +return -ENODEV ; -printk (KERN_INFO "Toshiba System Managment Mode driver v" -TOSH_VERSION "\n" ); +printk (KERN_INFO "Toshiba System Managment Mode driver v" TOSH_VERSION "\n" );/* set the port to use for Fn status if not specified as a parameter */ if (tosh_fn==0x00 )
@@ -492,12 +495,12 @@ int __init tosh_init(void)/* register the device file */ retval =misc_register (&tosh_device); -if (retval <0 ) +if (retval <0 )return retval;#ifdef CONFIG_PROC_FS /* register the proc entry */ -if (create_proc_info_entry ("toshiba" ,0 ,NULL , tosh_get_info) ==NULL ){ +if (create_proc_info_entry ("toshiba" ,0 ,NULL , tosh_get_info) ==NULL ) {misc_deregister (&tosh_device);return -ENOMEM ; }
@@ -506,27 +509,12 @@ int __init tosh_init(void)return 0 ; } -#ifdef MODULE -int init_module (void ) -{ -return tosh_init (); -} - -void cleanup_module (void ) +static void __exit toshiba_exit(void) { -/* remove the proc entry */ -remove_proc_entry ("toshiba" ,NULL ); - -/* unregister the device file */ -misc_deregister (&tosh_device); } -#endif -MODULE_LICENSE ("GPL" ); -MODULE_PARM_DESC (tosh_fn,"User specified Fn key detection port" ); -MODULE_AUTHOR ("Jonathan Buzzard <[email protected]>" ); -MODULE_DESCRIPTION ("Toshiba laptop SMM driver" ); -MODULE_SUPPORTED_DEVICE ("toshiba" ); +module_init (toshiba_init); +module_exit (toshiba_exit);
drivers/char/misc.c +0 -4
@@ -66,7 +66,6 @@ static unsigned char misc_minors[DYNAMICextern int rtc_DP8570A_init (void );extern int rtc_MK48T08_init (void );extern int pmu_device_init (void ); -extern int tosh_init (void );extern int i8k_init (void );#ifdef CONFIG_PROC_FS
@@ -314,9 +313,6 @@ static int __init misc_init(void)#ifdef CONFIG_PMAC_PBOOK pmu_device_init ();#endif -#ifdef CONFIG_TOSHIBA -tosh_init (); -#endif #ifdef CONFIG_I8K i8k_init ();#endif
Re: [PATCH 1/6] Toshiba driver cleanup
Quoted 2 lines · Dmitry Torokhov
Toshiba legacy driver cleanup:
drivers/char/toshiba.c renamed from drivers/char/toshiba.c~toshiba-driver-cleanup-fix +1 -1
@@ -79,7 +79,7 @@ MODULE_DESCRIPTION("Toshiba laptop SMM dMODULE_SUPPORTED_DEVICE ("toshiba" );static int tosh_fn; -module_param (fn, int,0 ); +module_param (tosh_fn, int,0 );MODULE_PARM_DESC (tosh_fn,"User specified Fn key detection port" );static int tosh_id;
_
Re: [PATCH 1/6] Toshiba driver cleanup
Quoted 7 lines · Andrew Morton
Quoted 2 lines · Dmitry Torokhov
Toshiba legacy driver cleanup:
drivers/char/toshiba.c 2005-04-27 00:32:51.521871360 -0700 MODULE_DESCRIPTION("Toshiba laptop SMM d · line 84
Quoted 7 lines
drivers/char/toshiba.c 2005-04-27 00:32:51.521871360 -0700 renamed from drivers/char/toshiba.c~toshiba-driver-cleanup-fix 2005-04-27 00:32:47.306512192 -0700 +1
-1@@ -79,7 +79,7 @@ MODULE_DESCRIPTION("Toshiba laptop SMM d MODULE_SUPPORTED_DEVICE("toshiba"); static int tosh_fn; -module_param(fn, int, 0); +module_param(tosh_fn, int, 0); MODULE_PARM_DESC(tosh_fn, "User specified Fn key detection port");
Ahem, sorry, somehow picked up bad version... It was supposed to be module_param_named(). I will send an updated patch tonight.
Signature · 1 line
Dmitry
Re: [PATCH 1/6] Toshiba driver cleanup
Quoted 10 lines · Dmitry Torokhov
Quoted 9 lines · Andrew Morton
Quoted 2 lines · Dmitry Torokhov
Toshiba legacy driver cleanup:
drivers/char/toshiba.c 2005-04-27 00:32:51.521871360 -0700 renamed from drivers/char/toshiba.c~toshiba-driver-cleanup-fix 2005-04-27 00:32:47.306512192 -0700 +0
-0@@ -79,7 +79,7 @@ MODULE_DESCRIPTION("Toshiba laptop SMM d MODULE_SUPPORTED_DEVICE("toshiba");
Quoted 9 lines
drivers/char/toshiba.c 2005-04-27 00:32:51.521871360 -0700 MODULE_DESCRIPTION("Toshiba laptop SMM d · line 84
Quoted 5 lines
drivers/char/toshiba.c 2005-04-27 00:32:51.521871360 -0700 renamed from drivers/char/toshiba.c~toshiba-driver-cleanup-fix 2005-04-27 00:32:47.306512192 -0700 +1
-1static int tosh_fn; -module_param(fn, int, 0); +module_param(tosh_fn, int, 0); MODULE_PARM_DESC(tosh_fn, "User specified Fn key detection port");Ahem, sorry, somehow picked up bad version... It was supposed to be
module_param_named(). I will send an updated patch tonight.
Ok, this is the right one. Parameter is changed to "toshiba.fn" and documented in kernel-parameters.txt
Signature · 186 lines
Dmitry =================================================================== Toshiba legacy driver cleanup: - use module_init/module_exit for initialization instead of using #ifdef MODULE and calling tosh_init manually from drivers/char/misc.c - do not explicitly initialize static variables - some whitespace and formatting cleanups - rename module parameter tosh_fn to toshiba.fn and document in kernel-parameters.txt Signed-off-by: Dmitry Torokhov <[email protected]> --- Documentation/kernel-parameters.txt | 5 ++ drivers/char/misc.c | 4 -- drivers/char/toshiba.c | 62 ++++++++++++++---------------------- 3 files changed, 30 insertions(+), 41 deletions(-) Index: dtor/drivers/char/toshiba.c =================================================================== --- dtor.orig/drivers/char/toshiba.c +++ dtor/drivers/char/toshiba.c @@ -73,16 +73,20 @@ #define TOSH_MINOR_DEV 181 -static int tosh_id = 0x0000; -static int tosh_bios = 0x0000; -static int tosh_date = 0x0000; -static int tosh_sci = 0x0000; -static int tosh_fan = 0; - -static int tosh_fn = 0; - -module_param(tosh_fn, int, 0); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jonathan Buzzard <[email protected]>"); +MODULE_DESCRIPTION("Toshiba laptop SMM driver"); +MODULE_SUPPORTED_DEVICE("toshiba"); +static int tosh_fn; +module_param_named(fn, tosh_fn, int, 0); +MODULE_PARM_DESC(fn, "User specified Fn key detection port"); + +static int tosh_id; +static int tosh_bios; +static int tosh_date; +static int tosh_sci; +static int tosh_fan; static int tosh_ioctl(struct inode *, struct file *, unsigned int, unsigned long); @@ -359,7 +363,7 @@ static int tosh_get_machine_id(void) unsigned long address; id = (0x100*(int) isa_readb(0xffffe))+((int) isa_readb(0xffffa)); - + /* do we have a SCTTable machine identication number on our hands */ if (id==0xfc2f) { @@ -424,7 +428,7 @@ static int tosh_probe(void) } /* call the Toshiba SCI support check routine */ - + regs.eax = 0xf0f0; regs.ebx = 0x0000; regs.ecx = 0x0000; @@ -440,7 +444,7 @@ static int tosh_probe(void) /* if we get this far then we are running on a Toshiba (probably)! */ tosh_sci = regs.edx & 0xffff; - + /* next get the machine ID of the current laptop */ tosh_id = tosh_get_machine_id(); @@ -475,16 +479,15 @@ static int tosh_probe(void) return 0; } -int __init tosh_init(void) +static int __init toshiba_init(void) { int retval; /* are we running on a Toshiba laptop */ - if (tosh_probe()!=0) - return -EIO; + if (tosh_probe()) + return -ENODEV; - printk(KERN_INFO "Toshiba System Managment Mode driver v" - TOSH_VERSION"\n"); + printk(KERN_INFO "Toshiba System Managment Mode driver v" TOSH_VERSION "\n"); /* set the port to use for Fn status if not specified as a parameter */ if (tosh_fn==0x00) @@ -492,12 +495,12 @@ int __init tosh_init(void) /* register the device file */ retval = misc_register(&tosh_device); - if(retval < 0) + if (retval < 0) return retval; #ifdef CONFIG_PROC_FS /* register the proc entry */ - if(create_proc_info_entry("toshiba", 0, NULL, tosh_get_info) == NULL){ + if (create_proc_info_entry("toshiba", 0, NULL, tosh_get_info) == NULL) { misc_deregister(&tosh_device); return -ENOMEM; } @@ -506,27 +509,12 @@ int __init tosh_init(void) return 0; } -#ifdef MODULE -int init_module(void) +static void __exit toshiba_exit(void) { - return tosh_init(); -} - -void cleanup_module(void) -{ - /* remove the proc entry */ - remove_proc_entry("toshiba", NULL); - - /* unregister the device file */ - misc_deregister(&tosh_device); } -#endif -MODULE_LICENSE("GPL"); -MODULE_PARM_DESC(tosh_fn, "User specified Fn key detection port"); -MODULE_AUTHOR("Jonathan Buzzard <[email protected]>"); -MODULE_DESCRIPTION("Toshiba laptop SMM driver"); -MODULE_SUPPORTED_DEVICE("toshiba"); +module_init(toshiba_init); +module_exit(toshiba_exit); Index: dtor/drivers/char/misc.c =================================================================== --- dtor.orig/drivers/char/misc.c +++ dtor/drivers/char/misc.c @@ -66,7 +66,6 @@ static unsigned char misc_minors[DYNAMIC extern int rtc_DP8570A_init(void); extern int rtc_MK48T08_init(void); extern int pmu_device_init(void); -extern int tosh_init(void); extern int i8k_init(void); #ifdef CONFIG_PROC_FS @@ -314,9 +313,6 @@ static int __init misc_init(void) #ifdef CONFIG_PMAC_PBOOK pmu_device_init(); #endif -#ifdef CONFIG_TOSHIBA - tosh_init(); -#endif #ifdef CONFIG_I8K i8k_init(); #endif Index: dtor/Documentation/kernel-parameters.txt =================================================================== --- dtor.orig/Documentation/kernel-parameters.txt +++ dtor/Documentation/kernel-parameters.txt @@ -1427,6 +1427,11 @@ running once the system is up. See comment before function dc390_setup() in drivers/scsi/tmscsim.c. + toshiba.fn= [HW] Specifies port Toshiba laptop SMM driver should + use to read status of Fn key. 0 (default value) tells + the driver to automatically select appropriate port + depending on the model of the laptop. + tp720= [HW,PS2] trix= [HW,OSS] MediaTrix AudioTrix Pro
PATCH 2/6 I8K: pass through lindent
In reply to Dmitry TorokhovI8K: pass through Lindent to change 4 spaces identation to TABs
---
i8k.c | 954 +++++++++++++++++++++++++++++++++--------------------------------- 1 files changed, 477 insertions(+), 477 deletions(-)
drivers/char/i8k.c +477 -477
@@ -55,14 +55,14 @@#define DELL_SIGNATURE "Dell Computer"static char *supported_models[] = { -"Inspiron" , -"Latitude" , -NULL +"Inspiron" , +"Latitude" , +NULL };static char system_vendor[48 ] ="?" ; -static char product_name [48 ] ="?" ; -static char bios_version [4 ] ="?" ; +static char product_name[48 ] ="?" ; +static char bios_version[4 ] ="?" ;static char serial_number[16 ] ="?" ;MODULE_AUTHOR ("Massimo Dal Zotto ([email protected])" );
@@ -86,64 +86,63 @@ static int i8k_ioctl(struct inode *, str unsigned long);static struct file_operations i8k_fops = { - .read = i8k_read, - .ioctl = i8k_ioctl, + .read = i8k_read, + .ioctl = i8k_ioctl, };typedef struct { -unsigned int eax; -unsigned int ebx __attribute__ ((packed)); -unsigned int ecx __attribute__ ((packed)); -unsigned int edx __attribute__ ((packed)); -unsigned int esi __attribute__ ((packed)); -unsigned int edi __attribute__ ((packed)); +unsigned int eax; +unsigned int ebx __attribute__ ((packed)); +unsigned int ecx __attribute__ ((packed)); +unsigned int edx __attribute__ ((packed)); +unsigned int esi __attribute__ ((packed)); +unsigned int edi __attribute__ ((packed)); }SMMRegisters ;typedef struct { -u8 type; -u8 length; -u16 handle; +u8 type; +u8 length; +u16 handle; }DMIHeader ;/* * Call the System Management Mode BIOS. Code provided by Jonathan Buzzard. */ -static int i8k_smm (SMMRegisters *regs) +static int i8k_smm (SMMRegisters * regs) { -int rc; -int eax = regs->eax; +int rc; +int eax = regs->eax; - asm("pushl %%eax\n\t" \ -"movl 0(%%eax),%%edx\n\t" \ -"push %%edx\n\t" \ -"movl 4(%%eax),%%ebx\n\t" \ -"movl 8(%%eax),%%ecx\n\t" \ -"movl 12(%%eax),%%edx\n\t" \ -"movl 16(%%eax),%%esi\n\t" \ -"movl 20(%%eax),%%edi\n\t" \ -"popl %%eax\n\t" \ -"out %%al,$0xb2\n\t" \ -"out %%al,$0x84\n\t" \ -"xchgl %%eax,(%%esp)\n\t" -"movl %%ebx,4(%%eax)\n\t" \ -"movl %%ecx,8(%%eax)\n\t" \ -"movl %%edx,12(%%eax)\n\t" \ -"movl %%esi,16(%%eax)\n\t" \ -"movl %%edi,20(%%eax)\n\t" \ -"popl %%edx\n\t" \ -"movl %%edx,0(%%eax)\n\t" \ -"lahf\n\t" \ -"shrl $8,%%eax\n\t" \ -"andl $1,%%eax\n" \ - :"=a" (rc) - :"a" (regs) - :"%ebx" ,"%ecx" ,"%edx" ,"%esi" ,"%edi" ,"memory" ); - -if ((rc !=0 ) || ((regs->eax &0xffff ) ==0xffff ) || (regs->eax == eax)) { -return -EINVAL ; - } + asm("pushl %%eax\n\t" +"movl 0(%%eax),%%edx\n\t" +"push %%edx\n\t" +"movl 4(%%eax),%%ebx\n\t" +"movl 8(%%eax),%%ecx\n\t" +"movl 12(%%eax),%%edx\n\t" +"movl 16(%%eax),%%esi\n\t" +"movl 20(%%eax),%%edi\n\t" +"popl %%eax\n\t" +"out %%al,$0xb2\n\t" +"out %%al,$0x84\n\t" +"xchgl %%eax,(%%esp)\n\t" +"movl %%ebx,4(%%eax)\n\t" +"movl %%ecx,8(%%eax)\n\t" +"movl %%edx,12(%%eax)\n\t" +"movl %%esi,16(%%eax)\n\t" +"movl %%edi,20(%%eax)\n\t" +"popl %%edx\n\t" +"movl %%edx,0(%%eax)\n\t" +"lahf\n\t" +"shrl $8,%%eax\n\t" +"andl $1,%%eax\n" :"=a" (rc) + :"a" (regs) + :"%ebx" ,"%ecx" ,"%edx" ,"%esi" ,"%edi" ,"memory" ); -return 0 ; +if ((rc !=0 ) || ((regs->eax &0xffff ) ==0xffff ) || (regs->eax == eax)) { +return -EINVAL ; + } + +return 0 ; }/*
@@ -152,15 +151,15 @@ static int i8k_smm(SMMRegisters *regs)*/ static int i8k_get_bios_version (void ) { -SMMRegisters regs = {0 ,0 ,0 ,0 ,0 ,0 }; -int rc; +SMMRegisters regs = {0 ,0 ,0 ,0 ,0 ,0 }; +int rc; - regs.eax =I8K_SMM_BIOS_VERSION ; -if ((rc=i8k_smm (®s)) <0 ) { -return rc; - } + regs.eax =I8K_SMM_BIOS_VERSION ; +if ((rc =i8k_smm (®s)) <0 ) { +return rc; + } -return regs.eax; +return regs.eax; }/*
@@ -168,8 +167,8 @@ static int i8k_get_bios_version(void)*/ static int i8k_get_serial_number (unsigned char *buff) { -strlcpy (buff, serial_number,sizeof (serial_number)); -return 0 ; +strlcpy (buff, serial_number,sizeof (serial_number)); +return 0 ; }/*
@@ -177,24 +176,24 @@ static int i8k_get_serial_number(unsigne*/ static int i8k_get_fn_status (void ) { -SMMRegisters regs = {0 ,0 ,0 ,0 ,0 ,0 }; -int rc; +SMMRegisters regs = {0 ,0 ,0 ,0 ,0 ,0 }; +int rc; - regs.eax =I8K_SMM_FN_STATUS ; -if ((rc=i8k_smm (®s)) <0 ) { -return rc; - } - -switch ((regs.eax >>I8K_FN_SHIFT ) &I8K_FN_MASK ) { -case I8K_FN_UP : -return I8K_VOL_UP ; -case I8K_FN_DOWN : -return I8K_VOL_DOWN ; -case I8K_FN_MUTE : -return I8K_VOL_MUTE ; -default : -return 0 ; - } + regs.eax =I8K_SMM_FN_STATUS ; +if ((rc =i8k_smm (®s)) <0 ) { +return rc; + } + +switch ((regs.eax >>I8K_FN_SHIFT ) &I8K_FN_MASK ) { +case I8K_FN_UP : +return I8K_VOL_UP ; +case I8K_FN_DOWN : +return I8K_VOL_DOWN ; +case I8K_FN_MUTE : +return I8K_VOL_MUTE ; +default : +return 0 ; + } }/*
@@ -202,20 +201,20 @@ static int i8k_get_fn_status(void)*/ static int i8k_get_power_status (void ) { -SMMRegisters regs = {0 ,0 ,0 ,0 ,0 ,0 }; -int rc; +SMMRegisters regs = {0 ,0 ,0 ,0 ,0 ,0 }; +int rc; + + regs.eax =I8K_SMM_POWER_STATUS ; +if ((rc =i8k_smm (®s)) <0 ) { +return rc; + } - regs.eax =I8K_SMM_POWER_STATUS ; -if ((rc=i8k_smm (®s)) <0 ) { -return rc; - } - -switch (regs.eax &0xff ) { -case I8K_POWER_AC : -return I8K_AC ; -default : -return I8K_BATTERY ; - } +switch (regs.eax &0xff ) { +case I8K_POWER_AC : +return I8K_AC ; +default : +return I8K_BATTERY ; + } }/*
@@ -223,16 +222,16 @@ static int i8k_get_power_status(void)*/ static int i8k_get_fan_status (int fan) { -SMMRegisters regs = {0 ,0 ,0 ,0 ,0 ,0 }; -int rc; +SMMRegisters regs = {0 ,0 ,0 ,0 ,0 ,0 }; +int rc; - regs.eax =I8K_SMM_GET_FAN ; - regs.ebx = fan &0xff ; -if ((rc=i8k_smm (®s)) <0 ) { -return rc; - } + regs.eax =I8K_SMM_GET_FAN ; + regs.ebx = fan &0xff ; +if ((rc =i8k_smm (®s)) <0 ) { +return rc; + } -return (regs.eax &0xff ); +return (regs.eax &0xff ); }/*
@@ -240,16 +239,16 @@ static int i8k_get_fan_status(int fan)*/ static int i8k_get_fan_speed (int fan) { -SMMRegisters regs = {0 ,0 ,0 ,0 ,0 ,0 }; -int rc; +SMMRegisters regs = {0 ,0 ,0 ,0 ,0 ,0 }; +int rc; - regs.eax =I8K_SMM_GET_SPEED ; - regs.ebx = fan &0xff ; -if ((rc=i8k_smm (®s)) <0 ) { -return rc; - } + regs.eax =I8K_SMM_GET_SPEED ; + regs.ebx = fan &0xff ; +if ((rc =i8k_smm (®s)) <0 ) { +return rc; + } -return (regs.eax &0xffff ) *I8K_FAN_MULT ; +return (regs.eax &0xffff ) *I8K_FAN_MULT ; }/*
@@ -257,18 +256,18 @@ static int i8k_get_fan_speed(int fan)*/ static int i8k_set_fan (int fan,int speed) { -SMMRegisters regs = {0 ,0 ,0 ,0 ,0 ,0 }; -int rc; +SMMRegisters regs = {0 ,0 ,0 ,0 ,0 ,0 }; +int rc; - speed = (speed <0 ) ?0 : ((speed >I8K_FAN_MAX ) ?I8K_FAN_MAX : speed); + speed = (speed <0 ) ?0 : ((speed >I8K_FAN_MAX ) ?I8K_FAN_MAX : speed); - regs.eax =I8K_SMM_SET_FAN ; - regs.ebx = (fan &0xff ) | (speed <<8 ); -if ((rc=i8k_smm (®s)) <0 ) { -return rc; - } + regs.eax =I8K_SMM_SET_FAN ; + regs.ebx = (fan &0xff ) | (speed <<8 ); +if ((rc =i8k_smm (®s)) <0 ) { +return rc; + } -return (i8k_get_fan_status (fan)); +return (i8k_get_fan_status (fan)); }/*
@@ -276,143 +275,143 @@ static int i8k_set_fan(int fan, int spee*/ static int i8k_get_cpu_temp (void ) { -SMMRegisters regs = {0 ,0 ,0 ,0 ,0 ,0 }; -int rc; -int temp; +SMMRegisters regs = {0 ,0 ,0 ,0 ,0 ,0 }; +int rc; +int temp;#ifdef I8K_TEMPERATURE_BUG -static int prev =0 ; +static int prev =0 ;#endif - regs.eax =I8K_SMM_GET_TEMP ; -if ((rc=i8k_smm (®s)) <0 ) { -return rc; - } - temp = regs.eax &0xff ; + regs.eax =I8K_SMM_GET_TEMP ; +if ((rc =i8k_smm (®s)) <0 ) { +return rc; + } + temp = regs.eax &0xff ;#ifdef I8K_TEMPERATURE_BUG -/* -* Sometimes the temperature sensor returns 0x99, which is out of range. -* In this case we return (once) the previous cached value. For example: -# 1003655137 00000058 00005a4b -# 1003655138 00000099 00003a80 <--- 0x99 = 153 degrees -# 1003655139 00000054 00005c52 -*/ -if (temp >I8K_MAX_TEMP ) { - temp = prev; - prev =I8K_MAX_TEMP ; - }else { - prev = temp; - } +/* +* Sometimes the temperature sensor returns 0x99, which is out of range. +* In this case we return (once) the previous cached value. For example: +# 1003655137 00000058 00005a4b +# 1003655138 00000099 00003a80 <--- 0x99 = 153 degrees +# 1003655139 00000054 00005c52 +*/ +if (temp >I8K_MAX_TEMP ) { + temp = prev; + prev =I8K_MAX_TEMP ; + }else { + prev = temp; + }#endif -return temp; +return temp; }static int i8k_get_dell_signature (void ) { -SMMRegisters regs = {0 ,0 ,0 ,0 ,0 ,0 }; -int rc; +SMMRegisters regs = {0 ,0 ,0 ,0 ,0 ,0 }; +int rc; - regs.eax =I8K_SMM_GET_DELL_SIG ; -if ((rc=i8k_smm (®s)) <0 ) { -return rc; - } + regs.eax =I8K_SMM_GET_DELL_SIG ; +if ((rc =i8k_smm (®s)) <0 ) { +return rc; + } -if ((regs.eax ==1145651527 ) && (regs.edx ==1145392204 )) { -return 0 ; - }else { -return -1 ; - } +if ((regs.eax ==1145651527 ) && (regs.edx ==1145392204 )) { +return 0 ; + }else { +return -1 ; + } }static int i8k_ioctl (struct inode *ip,struct file *fp,unsigned int cmd,unsigned long arg) { -int val; -int speed; -unsigned char buff[16 ]; -int __user *argp = (int __user *)arg; - -if (!argp) -return -EINVAL ; - -switch (cmd) { -case I8K_BIOS_VERSION : - val =i8k_get_bios_version (); -break ; - -case I8K_MACHINE_ID : -memset (buff,0 ,16 ); - val =i8k_get_serial_number (buff); -break ; - -case I8K_FN_STATUS : - val =i8k_get_fn_status (); -break ; - -case I8K_POWER_STATUS : - val =i8k_get_power_status (); -break ; - -case I8K_GET_TEMP : - val =i8k_get_cpu_temp (); -break ; - -case I8K_GET_SPEED : -if (copy_from_user (&val, argp,sizeof (int ))) { -return -EFAULT ; - } - val =i8k_get_fan_speed (val); -break ; - -case I8K_GET_FAN : -if (copy_from_user (&val, argp,sizeof (int ))) { -return -EFAULT ; - } - val =i8k_get_fan_status (val); -break ; - -case I8K_SET_FAN : -if (restricted && !capable (CAP_SYS_ADMIN )) { -return -EPERM ; - } -if (copy_from_user (&val, argp,sizeof (int ))) { -return -EFAULT ; - } -if (copy_from_user (&speed, argp+1 ,sizeof (int ))) { -return -EFAULT ; - } - val =i8k_set_fan (val, speed); -break ; - -default : -return -EINVAL ; - } - -if (val <0 ) { -return val; - } - -switch (cmd) { -case I8K_BIOS_VERSION : -if (copy_to_user (argp, &val,4 )) { -return -EFAULT ; - } -break ; -case I8K_MACHINE_ID : -if (copy_to_user (argp, buff,16 )) { -return -EFAULT ; - } -break ; -default : -if (copy_to_user (argp, &val,sizeof (int ))) { -return -EFAULT ; +int val; +int speed; +unsigned char buff[16 ]; +int __user *argp = (int __user *)arg; + +if (!argp) +return -EINVAL ; + +switch (cmd) { +case I8K_BIOS_VERSION : + val =i8k_get_bios_version (); +break ; + +case I8K_MACHINE_ID : +memset (buff,0 ,16 ); + val =i8k_get_serial_number (buff); +break ; + +case I8K_FN_STATUS : + val =i8k_get_fn_status (); +break ; + +case I8K_POWER_STATUS : + val =i8k_get_power_status (); +break ; + +case I8K_GET_TEMP : + val =i8k_get_cpu_temp (); +break ; + +case I8K_GET_SPEED : +if (copy_from_user (&val, argp,sizeof (int ))) { +return -EFAULT ; + } + val =i8k_get_fan_speed (val); +break ; + +case I8K_GET_FAN : +if (copy_from_user (&val, argp,sizeof (int ))) { +return -EFAULT ; + } + val =i8k_get_fan_status (val); +break ; + +case I8K_SET_FAN : +if (restricted && !capable (CAP_SYS_ADMIN )) { +return -EPERM ; + } +if (copy_from_user (&val, argp,sizeof (int ))) { +return -EFAULT ; + } +if (copy_from_user (&speed, argp +1 ,sizeof (int ))) { +return -EFAULT ; + } + val =i8k_set_fan (val, speed); +break ; + +default : +return -EINVAL ; } -break ; - } -return 0 ; +if (val <0 ) { +return val; + } + +switch (cmd) { +case I8K_BIOS_VERSION : +if (copy_to_user (argp, &val,4 )) { +return -EFAULT ; + } +break ; +case I8K_MACHINE_ID : +if (copy_to_user (argp, buff,16 )) { +return -EFAULT ; + } +break ; +default : +if (copy_to_user (argp, &val,sizeof (int ))) { +return -EFAULT ; + } +break ; + } + +return 0 ; }/*
@@ -420,90 +419,87 @@ static int i8k_ioctl(struct inode *ip, s*/ static int i8k_get_info (char *buffer,char **start,off_t fpos,int length) { -int n, fn_key, cpu_temp, ac_power; -int left_fan, right_fan, left_speed, right_speed; +int n, fn_key, cpu_temp, ac_power; +int left_fan, right_fan, left_speed, right_speed; + + cpu_temp =i8k_get_cpu_temp ();/* 11100 �s */ + left_fan =i8k_get_fan_status (I8K_FAN_LEFT );/* 580 �s */ + right_fan =i8k_get_fan_status (I8K_FAN_RIGHT );/* 580 �s */ + left_speed =i8k_get_fan_speed (I8K_FAN_LEFT );/* 580 �s */ + right_speed =i8k_get_fan_speed (I8K_FAN_RIGHT );/* 580 �s */ + fn_key =i8k_get_fn_status ();/* 750 �s */ +if (power_status) { + ac_power =i8k_get_power_status ();/* 14700 �s */ + }else { + ac_power =-1 ; + } - cpu_temp =i8k_get_cpu_temp ();/* 11100 �s */ - left_fan =i8k_get_fan_status (I8K_FAN_LEFT );/* 580 �s */ - right_fan =i8k_get_fan_status (I8K_FAN_RIGHT );/* 580 �s */ - left_speed =i8k_get_fan_speed (I8K_FAN_LEFT );/* 580 �s */ - right_speed =i8k_get_fan_speed (I8K_FAN_RIGHT );/* 580 �s */ - fn_key =i8k_get_fn_status ();/* 750 �s */ -if (power_status) { - ac_power =i8k_get_power_status ();/* 14700 �s */ - }else { - ac_power =-1 ; - } - -/* -* Info: -* -* 1) Format version (this will change if format changes) -* 2) BIOS version -* 3) BIOS machine ID -* 4) Cpu temperature -* 5) Left fan status -* 6) Right fan status -* 7) Left fan speed -* 8) Right fan speed -* 9) AC power -* 10) Fn Key status -*/ - n =sprintf (buffer,"%s %s %s %d %d %d %d %d %d %d\n" , -I8K_PROC_FMT , - bios_version, - serial_number, - cpu_temp, - left_fan, - right_fan, - left_speed, - right_speed, - ac_power, - fn_key); - -return n; +/* +* Info: +* +* 1) Format version (this will change if format changes) +* 2) BIOS version +* 3) BIOS machine ID +* 4) Cpu temperature +* 5) Left fan status +* 6) Right fan status +* 7) Left fan speed +* 8) Right fan speed +* 9) AC power +* 10) Fn Key status +*/ + n =sprintf (buffer,"%s %s %s %d %d %d %d %d %d %d\n" , +I8K_PROC_FMT , + bios_version, + serial_number, + cpu_temp, + left_fan, + right_fan, left_speed, right_speed, ac_power, fn_key); + +return n; } -static ssize_t i8k_read (struct file *f,char __user *buffer,size_t len,loff_t *fpos) +static ssize_t i8k_read (struct file *f,char __user * buffer,size_t len, +loff_t * fpos) { -int n; -char info[128 ]; +int n; +char info[128 ]; - n =i8k_get_info (info,NULL ,0 ,128 ); -if (n <=0 ) { -return n; - } + n =i8k_get_info (info,NULL ,0 ,128 ); +if (n <=0 ) { +return n; + } -if (*fpos >= n) { -return 0 ; - } +if (*fpos >= n) { +return 0 ; + } -if ((*fpos + len) >= n) { - len = n - *fpos; - } +if ((*fpos + len) >= n) { + len = n - *fpos; + } -if (copy_to_user (buffer, info, len) !=0 ) { -return -EFAULT ; - } +if (copy_to_user (buffer, info, len) !=0 ) { +return -EFAULT ; + } - *fpos += len; -return len; + *fpos += len; +return len; } -static char *__init string_trim (char *s,int size) +static char *__init string_trim (char *s,int size) { -int len; -char *p; +int len; +char *p; -if ((len =strlen (s)) > size) { - len = size; - } +if ((len =strlen (s)) > size) { + len = size; + } -for (p=s+len-1 ; len && (*p==' ' ); len--,p--) { - *p ='\0' ; - } +for (p = s + len -1 ; len && (*p ==' ' ); len--, p--) { + *p ='\0' ; + } -return s; +return s; }/* DMI code, stolen from arch/i386/kernel/dmi_scan.c */
@@ -515,111 +511,112 @@ static char* __init string_trim(char *s,* | | * +-----------------------+ */ -static char *__init dmi_string (DMIHeader *dmi,u8 s) +static char *__init dmi_string (DMIHeader * dmi,u8 s) { -u8 *p; +u8 *p; -if (!s) { -return "" ; - } - s--; - - p = (u8 *)dmi + dmi->length; -while (s >0 ) { - p +=strlen (p); - p++; +if (!s) { +return "" ; + } s--; - } -return p; + p = (u8 *) dmi + dmi->length; +while (s >0 ) { + p +=strlen (p); + p++; + s--; + } + +return p; } -static void __init dmi_decode (DMIHeader *dmi) +static void __init dmi_decode (DMIHeader * dmi) { -u8 *data = (u8 *) dmi; -char *p; +u8 *data = (u8 *) dmi; +char *p;#ifdef I8K_DEBUG -int i; -printk ("%08x " , (int )data); -for (i=0 ; i<data[1 ] && i<64 ; i++) { -printk ("%02x " , data[i]); - } -printk ("\n" ); +int i; +printk ("%08x " , (int )data); +for (i =0 ; i < data[1 ] && i <64 ; i++) { +printk ("%02x " , data[i]); + } +printk ("\n" );#endif -switch (dmi->type) { -case 0 :/* BIOS Information */ - p =dmi_string (dmi,data[5 ]); -if (*p) { -strlcpy (bios_version, p,sizeof (bios_version)); -string_trim (bios_version,sizeof (bios_version)); - } -break ; -case 1 :/* System Information */ - p =dmi_string (dmi,data[4 ]); -if (*p) { -strlcpy (system_vendor, p,sizeof (system_vendor)); -string_trim (system_vendor,sizeof (system_vendor)); - } - p =dmi_string (dmi,data[5 ]); -if (*p) { -strlcpy (product_name, p,sizeof (product_name)); -string_trim (product_name,sizeof (product_name)); - } - p =dmi_string (dmi,data[7 ]); -if (*p) { -strlcpy (serial_number, p,sizeof (serial_number)); -string_trim (serial_number,sizeof (serial_number)); - } -break ; - } -} - -static int __init dmi_table (u32 base,int len,int num,void (*fn)(DMIHeader *)) -{ -u8 *buf; -u8 *data; -DMIHeader *dmi; -int i =1 ; +switch (dmi->type) { +case 0 :/* BIOS Information */ + p =dmi_string (dmi, data[5 ]); +if (*p) { +strlcpy (bios_version, p,sizeof (bios_version)); +string_trim (bios_version,sizeof (bios_version)); + } +break ; +case 1 :/* System Information */ + p =dmi_string (dmi, data[4 ]); +if (*p) { +strlcpy (system_vendor, p,sizeof (system_vendor)); +string_trim (system_vendor,sizeof (system_vendor)); + } + p =dmi_string (dmi, data[5 ]); +if (*p) { +strlcpy (product_name, p,sizeof (product_name)); +string_trim (product_name,sizeof (product_name)); + } + p =dmi_string (dmi, data[7 ]); +if (*p) { +strlcpy (serial_number, p,sizeof (serial_number)); +string_trim (serial_number,sizeof (serial_number)); + } +break ; + } +} - buf =ioremap (base, len); -if (buf ==NULL ) { -return -1 ; - } - data = buf; +static int __init dmi_table (u32 base,int len,int num, +void (*fn) (DMIHeader *)) +{ +u8 *buf; +u8 *data; +DMIHeader *dmi; +int i =1 ; -/* -* Stop when we see al the items the table claimed to have -* or we run off the end of the table (also happens) -*/ -while ((i<num) && ((data-buf) < len)) { - dmi = (DMIHeader *)data; -/* -* Avoid misparsing crud if the length of the last -* record is crap -*/ -if ((data-buf+dmi->length) >= len) { -break ; + buf =ioremap (base, len); +if (buf ==NULL ) { +return -1 ; } -fn (dmi); - data += dmi->length; + data = buf; +/* -* Don't go off the end of the data if there is -* stuff looking like string fill past the end +* Stop when we see al the items the table claimed to have +* or we run off the end of the table (also happens) */ -while (((data-buf) < len) && (*data || data[1 ])) { - data++; +while ((i < num) && ((data - buf) < len)) { + dmi = (DMIHeader *) data; +/* +* Avoid misparsing crud if the length of the last +* record is crap +*/ +if ((data - buf + dmi->length) >= len) { +break ; + } +fn (dmi); + data += dmi->length; +/* +* Don't go off the end of the data if there is +* stuff looking like string fill past the end +*/ +while (((data - buf) < len) && (*data || data[1 ])) { + data++; + } + data +=2 ; + i++; } - data +=2 ; - i++; - } -iounmap (buf); +iounmap (buf); -return 0 ; +return 0 ; } -static int __init dmi_iterate (void (*decode)(DMIHeader *)) +static int __init dmi_iterate (void (*decode) (DMIHeader *)) {unsigned char buf[20 ];void __iomem *p =ioremap (0xe0000 ,0x20000 ), *q;
@@ -629,20 +626,20 @@ static int __init dmi_iterate(void (*decfor (q = p; q < p +0x20000 ; q +=16 ) {memcpy_fromio (buf, q,20 ); -if (memcmp (buf,"_DMI_" ,5 )==0 ) { -u16 num = buf[13 ]<<8 | buf[12 ]; -u16 len = buf [7 ]<<8 | buf [6 ]; -u32 base = buf[11 ]<<24 | buf[10 ]<<16 | buf[9 ]<<8 | buf[8 ]; +if (memcmp (buf,"_DMI_" ,5 ) ==0 ) { +u16 num = buf[13 ] <<8 | buf[12 ]; +u16 len = buf[7 ] <<8 | buf[6 ]; +u32 base = buf[11 ] <<24 | buf[10 ] <<16 | buf[9 ] <<8 | buf[8 ];#ifdef I8K_DEBUG printk (KERN_INFO "DMI %d.%d present.\n" , - buf[14 ]>>4 , buf[14 ]&0x0F ); + buf[14 ] >>4 , buf[14 ] &0x0F );printk (KERN_INFO "%d structures occupying %d bytes.\n" , - buf[13 ]<<8 | buf[12 ], - buf [7 ]<<8 | buf[6 ]); + buf[13 ] <<8 | buf[12 ], buf[7 ] <<8 | buf[6 ]);printk (KERN_INFO "DMI table at 0x%08X.\n" , - buf[11 ]<<24 | buf[10 ]<<16 | buf[9 ]<<8 | buf[8 ]); + buf[11 ] <<24 | buf[10 ] <<16 | buf[9 ] <<8 | + buf[8 ]);#endif -if (dmi_table (base, len, num, decode)==0 ) { +if (dmi_table (base, len, num, decode) ==0 ) {iounmap (p);return 0 ; }
@@ -651,6 +648,7 @@ static int __init dmi_iterate(void (*deciounmap (p);return -1 ; } +/* end of DMI code */ /*
@@ -658,29 +656,30 @@ static int __init dmi_iterate(void (*dec*/ static int __init i8k_dmi_probe (void ) { -char **p; - -if (dmi_iterate (dmi_decode) !=0 ) { -printk (KERN_INFO "i8k: unable to get DMI information\n" ); -return -ENODEV ; - } +char **p; -if (strncmp (system_vendor,DELL_SIGNATURE ,strlen (DELL_SIGNATURE )) !=0 ) { -printk (KERN_INFO "i8k: not running on a Dell system\n" ); -return -ENODEV ; - } +if (dmi_iterate (dmi_decode) !=0 ) { +printk (KERN_INFO "i8k: unable to get DMI information\n" ); +return -ENODEV ; + } -for (p=supported_models; ; p++) { -if (!*p) { -printk (KERN_INFO "i8k: unsupported model: %s\n" , product_name); -return -ENODEV ; +if (strncmp (system_vendor,DELL_SIGNATURE ,strlen (DELL_SIGNATURE )) !=0 ) { +printk (KERN_INFO "i8k: not running on a Dell system\n" ); +return -ENODEV ; } -if (strncmp (product_name,*p,strlen (*p)) ==0 ) { -break ; + +for (p = supported_models;; p++) { +if (!*p) { +printk (KERN_INFO "i8k: unsupported model: %s\n" , + product_name); +return -ENODEV ; + } +if (strncmp (product_name, *p,strlen (*p)) ==0 ) { +break ; + } } - } -return 0 ; +return 0 ; }/*
@@ -688,59 +687,60 @@ static int __init i8k_dmi_probe(void)*/ static int __init i8k_probe (void ) { -char buff[4 ]; -int version; -int smm_found =0 ; - -/* -* Get DMI information -*/ -if (i8k_dmi_probe () !=0 ) { -printk (KERN_INFO "i8k: vendor=%s, model=%s, version=%s\n" , - system_vendor, product_name, bios_version); - } - -/* -* Get SMM Dell signature -*/ -if (i8k_get_dell_signature () !=0 ) { -printk (KERN_INFO "i8k: unable to get SMM Dell signature\n" ); - }else { - smm_found =1 ; - } - -/* -* Get SMM BIOS version. -*/ - version =i8k_get_bios_version (); -if (version <=0 ) { -printk (KERN_INFO "i8k: unable to get SMM BIOS version\n" ); - }else { - smm_found =1 ; - buff[0 ] = (version >>16 ) &0xff ; - buff[1 ] = (version >>8 ) &0xff ; - buff[2 ] = (version) &0xff ; - buff[3 ] ='\0' ; +char buff[4 ]; +int version; +int smm_found =0 ; +/* -* If DMI BIOS version is unknown use SMM BIOS version. +* Get DMI information */ -if (bios_version[0 ] =='?' ) { -strcpy (bios_version, buff); +if (i8k_dmi_probe () !=0 ) { +printk (KERN_INFO "i8k: vendor=%s, model=%s, version=%s\n" , + system_vendor, product_name, bios_version); } +/* -* Check if the two versions match. +* Get SMM Dell signature */ -if (strncmp (buff,bios_version,sizeof (bios_version)) !=0 ) { -printk (KERN_INFO "i8k: BIOS version mismatch: %s != %s\n" , - buff, bios_version); +if (i8k_get_dell_signature () !=0 ) { +printk (KERN_INFO "i8k: unable to get SMM Dell signature\n" ); + }else { + smm_found =1 ; } - } -if (!smm_found && !force) { -return -ENODEV ; - } +/* +* Get SMM BIOS version. +*/ + version =i8k_get_bios_version (); +if (version <=0 ) { +printk (KERN_INFO "i8k: unable to get SMM BIOS version\n" ); + }else { + smm_found =1 ; + buff[0 ] = (version >>16 ) &0xff ; + buff[1 ] = (version >>8 ) &0xff ; + buff[2 ] = (version) &0xff ; + buff[3 ] ='\0' ; +/* +* If DMI BIOS version is unknown use SMM BIOS version. +*/ +if (bios_version[0 ] =='?' ) { +strcpy (bios_version, buff); + } +/* +* Check if the two versions match. +*/ +if (strncmp (buff, bios_version,sizeof (bios_version)) !=0 ) { +printk (KERN_INFO +"i8k: BIOS version mismatch: %s != %s\n" , buff, + bios_version); + } + } -return 0 ; +if (!smm_found && !force) { +return -ENODEV ; + } + +return 0 ; }#ifdef MODULE
@@ -748,40 +748,40 @@ static#endif int __init i8k_init (void ) { -struct proc_dir_entry *proc_i8k; +struct proc_dir_entry *proc_i8k; -/* Are we running on an supported laptop? */ -if (i8k_probe () !=0 ) { -return -ENODEV ; - } - -/* Register the proc entry */ - proc_i8k =create_proc_info_entry ("i8k" ,0 ,NULL , i8k_get_info); -if (!proc_i8k) { -return -ENOENT ; - } - proc_i8k->proc_fops = &i8k_fops; - proc_i8k->owner =THIS_MODULE ; - -printk (KERN_INFO -"Dell laptop SMM driver v%s Massimo Dal Zotto ([email protected])\n" , -I8K_VERSION ); +/* Are we running on an supported laptop? */ +if (i8k_probe () !=0 ) { +return -ENODEV ; + } + +/* Register the proc entry */ + proc_i8k =create_proc_info_entry ("i8k" ,0 ,NULL , i8k_get_info); +if (!proc_i8k) { +return -ENOENT ; + } + proc_i8k->proc_fops = &i8k_fops; + proc_i8k->owner =THIS_MODULE ; -return 0 ; +printk (KERN_INFO +"Dell laptop SMM driver v%s Massimo Dal Zotto ([email protected])\n" , +I8K_VERSION ); + +return 0 ; }#ifdef MODULE int init_module (void ) { -return i8k_init (); +return i8k_init (); }void cleanup_module (void ) { -/* Remove the proc entry */ -remove_proc_entry ("i8k" ,NULL ); +/* Remove the proc entry */ +remove_proc_entry ("i8k" ,NULL ); -printk (KERN_INFO "i8k: module unloaded\n" ); +printk (KERN_INFO "i8k: module unloaded\n" ); }#endif
PATCH 3/6 I8K: use standard DMI interface
In reply to Dmitry TorokhovI8K: Change to use stock dmi infrastructure instead of homegrown
parsing code. The driver now requires box's DMI data to match list of supported models so driver can be safely compiled-in by default without fear of it poking into random SMM BIOS code. DMI checks can be ignored with i8k.ignore_dmi option.
---
Documentation/kernel-parameters.txt | 3 arch/i386/kernel/dmi_scan.c | 1 drivers/char/i8k.c | 302 ++++++------------------------------ include/linux/dmi.h | 1 4 files changed, 58 insertions(+), 249 deletions(-)
arch/i386/kernel/dmi_scan.c +1 -0
@@ -414,6 +414,7 @@ static void __init dmi_decode(struct dmidmi_save_ident (dm,DMI_PRODUCT_VERSION ,6 );dmi_printk (("Serial Number: %s\n" ,dmi_string (dm, data[7 ]))); +dmi_save_ident (dm,DMI_PRODUCT_SERIAL ,7 );break ;case 2 : dmi_printk(("Board Vendor: %s\n",
include/linux/dmi.h +1 -0
@@ -9,6 +9,7 @@ enum dmi_field {DMI_SYS_VENDOR ,DMI_PRODUCT_NAME ,DMI_PRODUCT_VERSION , +DMI_PRODUCT_SERIAL ,DMI_BOARD_VENDOR ,DMI_BOARD_NAME , DMI_BOARD_VERSION,
drivers/char/i8k.c +53 -249
397 lines not on this page · raw message
Documentation/kernel-parameters.txt +3 -0
@@ -548,6 +548,9 @@ running once the system is up. i810= [HW,DRM] + i8k.ignore_dmi [HW] Continue probing hardware even if DMI data + indicates that the driver is running on unsupported + hardware. i8k.force [HW] Activate i8k driver even if SMM BIOS signature does not match list of supported models. i8k.power_status
Re: [PATCH 3/6] I8K: use standard DMI interface
Andrew brought to my attention yet again that I forgot to export dmi_get_system_info.
Signature · 482 lines
Dmitry
=============================================================
I8K: Change to use stock dmi infrastructure instead of homegrown
parsing code. The driver now requires box's DMI data to match
list of supported models so driver can be safely compiled-in
by default without fear of it poking into random SMM BIOS
code. DMI checks can be ignored with i8k.ignore_dmi option.
Signed-off-by: Dmitry Torokhov <[email protected]>
---
Documentation/kernel-parameters.txt | 3
arch/i386/kernel/dmi_scan.c | 4
drivers/char/i8k.c | 302 ++++++------------------------------
include/linux/dmi.h | 1
4 files changed, 60 insertions(+), 250 deletions(-)
Index: dtor/arch/i386/kernel/dmi_scan.c
===================================================================
--- dtor.orig/arch/i386/kernel/dmi_scan.c
+++ dtor/arch/i386/kernel/dmi_scan.c
@@ -414,6 +414,7 @@ static void __init dmi_decode(struct dmi
dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
dmi_printk(("Serial Number: %s\n",
dmi_string(dm, data[7])));
+ dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7);
break;
case 2:
dmi_printk(("Board Vendor: %s\n",
@@ -480,8 +481,9 @@ EXPORT_SYMBOL(dmi_check_system);
* Returns one DMI data value, can be used to perform
* complex DMI data checks.
*/
-char * dmi_get_system_info(int field)
+char *dmi_get_system_info(int field)
{
return dmi_ident[field];
}
+EXPORT_SYMBOL(dmi_get_system_info);
Index: dtor/include/linux/dmi.h
===================================================================
--- dtor.orig/include/linux/dmi.h
+++ dtor/include/linux/dmi.h
@@ -9,6 +9,7 @@ enum dmi_field {
DMI_SYS_VENDOR,
DMI_PRODUCT_NAME,
DMI_PRODUCT_VERSION,
+ DMI_PRODUCT_SERIAL,
DMI_BOARD_VENDOR,
DMI_BOARD_NAME,
DMI_BOARD_VERSION,
Index: dtor/drivers/char/i8k.c
===================================================================
--- dtor.orig/drivers/char/i8k.c
+++ dtor/drivers/char/i8k.c
@@ -20,7 +20,7 @@
#include <linux/types.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
-#include <linux/apm_bios.h>
+#include <linux/dmi.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -52,18 +52,7 @@
#define I8K_TEMPERATURE_BUG 1
-#define DELL_SIGNATURE "Dell Computer"
-
-static char *supported_models[] = {
- "Inspiron",
- "Latitude",
- NULL
-};
-
-static char system_vendor[48] = "?";
-static char product_name[48] = "?";
-static char bios_version[4] = "?";
-static char serial_number[16] = "?";
+static char bios_version[4];
MODULE_AUTHOR("Massimo Dal Zotto ([email protected])");
MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops");
@@ -73,6 +62,10 @@ static int force;
module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Force loading without checking for supported models");
+static int ignore_dmi;
+module_param(ignore_dmi, bool, 0);
+MODULE_PARM_DESC(ignore_dmi, "Continue probing hardware even if DMI data does not match");
+
static int restricted;
module_param(restricted, bool, 0);
MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set");
@@ -99,11 +92,10 @@ typedef struct {
unsigned int edi __attribute__ ((packed));
} SMMRegisters;
-typedef struct {
- u8 type;
- u8 length;
- u16 handle;
-} DMIHeader;
+static inline char *i8k_get_dmi_data(int field)
+{
+ return dmi_get_system_info(field) ? : "N/A";
+}
/*
* Call the System Management Mode BIOS. Code provided by Jonathan Buzzard.
@@ -163,15 +155,6 @@ static int i8k_get_bios_version(void)
}
/*
- * Read the machine id.
- */
-static int i8k_get_serial_number(unsigned char *buff)
-{
- strlcpy(buff, serial_number, sizeof(serial_number));
- return 0;
-}
-
-/*
* Read the Fn key status.
*/
static int i8k_get_fn_status(void)
@@ -328,7 +311,7 @@ static int i8k_get_dell_signature(void)
static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
unsigned long arg)
{
- int val;
+ int val = 0;
int speed;
unsigned char buff[16];
int __user *argp = (int __user *)arg;
@@ -343,7 +326,7 @@ static int i8k_ioctl(struct inode *ip, s
case I8K_MACHINE_ID:
memset(buff, 0, 16);
- val = i8k_get_serial_number(buff);
+ strlcpy(buff, i8k_get_dmi_data(DMI_PRODUCT_SERIAL), sizeof(buff));
break;
case I8K_FN_STATUS:
@@ -451,10 +434,10 @@ static int i8k_get_info(char *buffer, ch
n = sprintf(buffer, "%s %s %s %d %d %d %d %d %d %d\n",
I8K_PROC_FMT,
bios_version,
- serial_number,
+ dmi_get_system_info(DMI_PRODUCT_SERIAL) ? : "N/A",
cpu_temp,
- left_fan,
- right_fan, left_speed, right_speed, ac_power, fn_key);
+ left_fan, right_fan, left_speed, right_speed,
+ ac_power, fn_key);
return n;
}
@@ -486,201 +469,23 @@ static ssize_t i8k_read(struct file *f,
return len;
}
-static char *__init string_trim(char *s, int size)
-{
- int len;
- char *p;
-
- if ((len = strlen(s)) > size) {
- len = size;
- }
-
- for (p = s + len - 1; len && (*p == ' '); len--, p--) {
- *p = '\0';
- }
-
- return s;
-}
-
-/* DMI code, stolen from arch/i386/kernel/dmi_scan.c */
-
-/*
- * |<-- dmi->length -->|
- * | |
- * |dmi header s=N | string1,\0, ..., stringN,\0, ..., \0
- * | |
- * +-----------------------+
- */
-static char *__init dmi_string(DMIHeader * dmi, u8 s)
-{
- u8 *p;
-
- if (!s) {
- return "";
- }
- s--;
-
- p = (u8 *) dmi + dmi->length;
- while (s > 0) {
- p += strlen(p);
- p++;
- s--;
- }
-
- return p;
-}
-
-static void __init dmi_decode(DMIHeader * dmi)
-{
- u8 *data = (u8 *) dmi;
- char *p;
-
-#ifdef I8K_DEBUG
- int i;
- printk("%08x ", (int)data);
- for (i = 0; i < data[1] && i < 64; i++) {
- printk("%02x ", data[i]);
- }
- printk("\n");
-#endif
-
- switch (dmi->type) {
- case 0: /* BIOS Information */
- p = dmi_string(dmi, data[5]);
- if (*p) {
- strlcpy(bios_version, p, sizeof(bios_version));
- string_trim(bios_version, sizeof(bios_version));
- }
- break;
- case 1: /* System Information */
- p = dmi_string(dmi, data[4]);
- if (*p) {
- strlcpy(system_vendor, p, sizeof(system_vendor));
- string_trim(system_vendor, sizeof(system_vendor));
- }
- p = dmi_string(dmi, data[5]);
- if (*p) {
- strlcpy(product_name, p, sizeof(product_name));
- string_trim(product_name, sizeof(product_name));
- }
- p = dmi_string(dmi, data[7]);
- if (*p) {
- strlcpy(serial_number, p, sizeof(serial_number));
- string_trim(serial_number, sizeof(serial_number));
- }
- break;
- }
-}
-
-static int __init dmi_table(u32 base, int len, int num,
- void (*fn) (DMIHeader *))
-{
- u8 *buf;
- u8 *data;
- DMIHeader *dmi;
- int i = 1;
-
- buf = ioremap(base, len);
- if (buf == NULL) {
- return -1;
- }
- data = buf;
-
- /*
- * Stop when we see al the items the table claimed to have
- * or we run off the end of the table (also happens)
- */
- while ((i < num) && ((data - buf) < len)) {
- dmi = (DMIHeader *) data;
- /*
- * Avoid misparsing crud if the length of the last
- * record is crap
- */
- if ((data - buf + dmi->length) >= len) {
- break;
- }
- fn(dmi);
- data += dmi->length;
- /*
- * Don't go off the end of the data if there is
- * stuff looking like string fill past the end
- */
- while (((data - buf) < len) && (*data || data[1])) {
- data++;
- }
- data += 2;
- i++;
- }
- iounmap(buf);
-
- return 0;
-}
-
-static int __init dmi_iterate(void (*decode) (DMIHeader *))
-{
- unsigned char buf[20];
- void __iomem *p = ioremap(0xe0000, 0x20000), *q;
-
- if (!p)
- return -1;
-
- for (q = p; q < p + 0x20000; q += 16) {
- memcpy_fromio(buf, q, 20);
- if (memcmp(buf, "_DMI_", 5) == 0) {
- u16 num = buf[13] << 8 | buf[12];
- u16 len = buf[7] << 8 | buf[6];
- u32 base = buf[11] << 24 | buf[10] << 16 | buf[9] << 8 | buf[8];
-#ifdef I8K_DEBUG
- printk(KERN_INFO "DMI %d.%d present.\n",
- buf[14] >> 4, buf[14] & 0x0F);
- printk(KERN_INFO "%d structures occupying %d bytes.\n",
- buf[13] << 8 | buf[12], buf[7] << 8 | buf[6]);
- printk(KERN_INFO "DMI table at 0x%08X.\n",
- buf[11] << 24 | buf[10] << 16 | buf[9] << 8 |
- buf[8]);
-#endif
- if (dmi_table(base, len, num, decode) == 0) {
- iounmap(p);
- return 0;
- }
- }
- }
- iounmap(p);
- return -1;
-}
-
-/* end of DMI code */
-
-/*
- * Get DMI information.
- */
-static int __init i8k_dmi_probe(void)
-{
- char **p;
-
- if (dmi_iterate(dmi_decode) != 0) {
- printk(KERN_INFO "i8k: unable to get DMI information\n");
- return -ENODEV;
- }
-
- if (strncmp(system_vendor, DELL_SIGNATURE, strlen(DELL_SIGNATURE)) != 0) {
- printk(KERN_INFO "i8k: not running on a Dell system\n");
- return -ENODEV;
- }
-
- for (p = supported_models;; p++) {
- if (!*p) {
- printk(KERN_INFO "i8k: unsupported model: %s\n",
- product_name);
- return -ENODEV;
- }
- if (strncmp(product_name, *p, strlen(*p)) == 0) {
- break;
- }
- }
-
- return 0;
-}
+static struct dmi_system_id __initdata i8k_dmi_table[] = {
+ {
+ .ident = "Dell Inspiron",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"),
+ },
+ },
+ {
+ .ident = "Dell Latitude",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
+ },
+ },
+ { }
+};
/*
* Probe for the presence of a supported laptop.
@@ -689,23 +494,30 @@ static int __init i8k_probe(void)
{
char buff[4];
int version;
- int smm_found = 0;
/*
* Get DMI information
*/
- if (i8k_dmi_probe() != 0) {
+ if (!dmi_check_system(i8k_dmi_table)) {
+ if (!ignore_dmi && !force)
+ return -ENODEV;
+
+ printk(KERN_INFO "i8k: not running on a supported Dell system.\n");
printk(KERN_INFO "i8k: vendor=%s, model=%s, version=%s\n",
- system_vendor, product_name, bios_version);
+ i8k_get_dmi_data(DMI_SYS_VENDOR),
+ i8k_get_dmi_data(DMI_PRODUCT_NAME),
+ i8k_get_dmi_data(DMI_BIOS_VERSION));
}
+ strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION), sizeof(bios_version));
+
/*
* Get SMM Dell signature
*/
if (i8k_get_dell_signature() != 0) {
- printk(KERN_INFO "i8k: unable to get SMM Dell signature\n");
- } else {
- smm_found = 1;
+ printk(KERN_ERR "i8k: unable to get SMM Dell signature\n");
+ if (!force)
+ return -ENODEV;
}
/*
@@ -713,9 +525,8 @@ static int __init i8k_probe(void)
*/
version = i8k_get_bios_version();
if (version <= 0) {
- printk(KERN_INFO "i8k: unable to get SMM BIOS version\n");
+ printk(KERN_WARNING "i8k: unable to get SMM BIOS version\n");
} else {
- smm_found = 1;
buff[0] = (version >> 16) & 0xff;
buff[1] = (version >> 8) & 0xff;
buff[2] = (version) & 0xff;
@@ -723,21 +534,15 @@ static int __init i8k_probe(void)
/*
* If DMI BIOS version is unknown use SMM BIOS version.
*/
- if (bios_version[0] == '?') {
- strcpy(bios_version, buff);
- }
+ if (!dmi_get_system_info(DMI_BIOS_VERSION))
+ strlcpy(bios_version, buff, sizeof(bios_version));
+
/*
* Check if the two versions match.
*/
- if (strncmp(buff, bios_version, sizeof(bios_version)) != 0) {
- printk(KERN_INFO
- "i8k: BIOS version mismatch: %s != %s\n", buff,
- bios_version);
- }
- }
-
- if (!smm_found && !force) {
- return -ENODEV;
+ if (strncmp(buff, bios_version, sizeof(bios_version)) != 0)
+ printk(KERN_WARNING "i8k: BIOS version mismatch: %s != %s\n",
+ buff, bios_version);
}
return 0;
@@ -751,9 +556,8 @@ int __init i8k_init(void)
struct proc_dir_entry *proc_i8k;
/* Are we running on an supported laptop? */
- if (i8k_probe() != 0) {
+ if (i8k_probe())
return -ENODEV;
- }
/* Register the proc entry */
proc_i8k = create_proc_info_entry("i8k", 0, NULL, i8k_get_info);
Index: dtor/Documentation/kernel-parameters.txt
===================================================================
--- dtor.orig/Documentation/kernel-parameters.txt
+++ dtor/Documentation/kernel-parameters.txt
@@ -548,6 +548,9 @@ running once the system is up.
i810= [HW,DRM]
+ i8k.ignore_dmi [HW] Continue probing hardware even if DMI data
+ indicates that the driver is running on unsupported
+ hardware.
i8k.force [HW] Activate i8k driver even if SMM BIOS signature
does not match list of supported models.
i8k.power_statusPATCH 4/6 I8K: convert to seqfile
In reply to Dmitry TorokhovI8K: Change proc code to use seq_file.
---
i8k.c | 64 ++++++++++++++++++++++------------------------------------------ 1 files changed, 22 insertions(+), 42 deletions(-)
drivers/char/i8k.c +22 -42
@@ -20,13 +20,14 @@#include <linux/types.h> #include <linux/init.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/dmi.h> #include <asm/uaccess.h> #include <asm/io.h> #include <linux/i8k.h> -#define I8K_VERSION "1.13 14/05/2002" +#define I8K_VERSION "1.14 21/02/2005"#define I8K_SMM_FN_STATUS 0x0025#define I8K_SMM_POWER_STATUS 0x0069
@@ -74,13 +75,16 @@ static int power_status;module_param (power_status, bool,0600 );MODULE_PARM_DESC (power_status,"Report power status in /proc/i8k" ); -static ssize_t i8k_read (struct file *,char __user *,size_t ,loff_t *); +static int i8k_open_fs (struct inode *inode,struct file *file);static int i8k_ioctl (struct inode *,struct file *,unsigned int ,unsigned long );static struct file_operations i8k_fops = { - .read = i8k_read, - .ioctl = i8k_ioctl, + .open = i8k_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .ioctl = i8k_ioctl, }; typedef struct {
@@ -400,9 +404,9 @@ static int i8k_ioctl(struct inode *ip, s/* * Print the information for /proc/i8k. */ -static int i8k_get_info (char *buffer,char **start,off_t fpos,int length) +static int i8k_proc_show (struct seq_file *seq,void *offset) { -int n, fn_key, cpu_temp, ac_power; +int fn_key, cpu_temp, ac_power;int left_fan, right_fan, left_speed, right_speed; cpu_temp =i8k_get_cpu_temp ();/* 11100 �s */
@@ -431,42 +435,18 @@ static int i8k_get_info(char *buffer, ch* 9) AC power * 10) Fn Key status */ - n =sprintf (buffer,"%s %s %s %d %d %d %d %d %d %d\n" , -I8K_PROC_FMT , - bios_version, -dmi_get_system_info (DMI_PRODUCT_SERIAL ) ? :"N/A" , - cpu_temp, - left_fan, right_fan, left_speed, right_speed, - ac_power, fn_key); - -return n; +return seq_printf (seq,"%s %s %s %d %d %d %d %d %d %d\n" , +I8K_PROC_FMT , + bios_version, +dmi_get_system_info (DMI_PRODUCT_SERIAL ) ? :"N/A" , + cpu_temp, + left_fan, right_fan, left_speed, right_speed, + ac_power, fn_key); } -static ssize_t i8k_read (struct file *f,char __user * buffer,size_t len, -loff_t * fpos) +static int i8k_open_fs (struct inode *inode,struct file *file) { -int n; -char info[128 ]; - - n =i8k_get_info (info,NULL ,0 ,128 ); -if (n <=0 ) { -return n; - } - -if (*fpos >= n) { -return 0 ; - } - -if ((*fpos + len) >= n) { - len = n - *fpos; - } - -if (copy_to_user (buffer, info, len) !=0 ) { -return -EFAULT ; - } - - *fpos += len; -return len; +return single_open (file, i8k_proc_show,NULL ); }static struct dmi_system_id __initdata i8k_dmi_table[] = {
@@ -560,10 +540,10 @@ int __init i8k_init(void)return -ENODEV ;/* Register the proc entry */ - proc_i8k =create_proc_info_entry ("i8k" ,0 ,NULL , i8k_get_info); -if (!proc_i8k) { + proc_i8k =create_proc_entry ("i8k" ,0 ,NULL ); +if (!proc_i8k)return -ENOENT ; - } + proc_i8k->proc_fops = &i8k_fops; proc_i8k->owner =THIS_MODULE ;
PATCH 5/6 I8K: initialization code cleanup; formatting
In reply to Dmitry TorokhovI8K: use module_{init|exit} instead of old style #ifdef MODULE
code, some formatting changes.
---
i8k.c | 149 ++++++++++++++++++++--------------------------------------------- misc.c | 4 - 2 files changed, 47 insertions(+), 106 deletions(-)
drivers/char/misc.c +0 -4
@@ -66,7 +66,6 @@ static unsigned char misc_minors[DYNAMICextern int rtc_DP8570A_init (void );extern int rtc_MK48T08_init (void );extern int pmu_device_init (void ); -extern int i8k_init (void );#ifdef CONFIG_PROC_FS static void *misc_seq_start (struct seq_file *seq,loff_t *pos)
@@ -313,9 +312,6 @@ static int __init misc_init(void)#ifdef CONFIG_PMAC_PBOOK pmu_device_init ();#endif -#ifdef CONFIG_I8K -i8k_init (); -#endif if (register_chrdev (MISC_MAJOR ,"misc" ,&misc_fops)) {printk ("unable to get major %d for misc devices\n" ,MISC_MAJOR );
drivers/char/i8k.c +47 -102
306 lines not on this page · raw message
PATCH 6/6 I8K: add new BIOS signatures
In reply to Dmitry TorokhovI8K: add BIOS signatures of a newer Dell laptops, also there can be
more than one temperature sensor reported by BIOS. Lifted from driver 1.25 on Massimo Dal Zotto's site.
---
i8k.c | 32 ++++++++++++++++++++++++-------- 1 files changed, 24 insertions(+), 8 deletions(-)
drivers/char/i8k.c +24 -8
@@ -35,7 +35,8 @@#define I8K_SMM_GET_FAN 0x00a3#define I8K_SMM_GET_SPEED 0x02a3#define I8K_SMM_GET_TEMP 0x10a3 -#define I8K_SMM_GET_DELL_SIG 0xffa3 +#define I8K_SMM_GET_DELL_SIG1 0xfea3 +#define I8K_SMM_GET_DELL_SIG2 0xffa3#define I8K_SMM_BIOS_VERSION 0x00a6#define I8K_FAN_MULT 30
@@ -226,7 +227,7 @@ static int i8k_set_fan(int fan, int spee/* * Read the cpu temperature. */ -static int i8k_get_cpu_temp (void ) +static int i8k_get_temp (int sensor) {struct smm_regs regs = { .eax =I8K_SMM_GET_TEMP , };int rc;
@@ -235,7 +236,7 @@ static int i8k_get_cpu_temp(void)#ifdef I8K_TEMPERATURE_BUG static int prev;#endif - + regs.ebx = sensor &0xff ;if ((rc =i8k_smm (®s)) <0 )return rc;
@@ -260,9 +261,9 @@ static int i8k_get_cpu_temp(void)return temp; } -static int i8k_get_dell_signature (void ) +static int i8k_get_dell_signature (int req_fn) { -struct smm_regs regs = { .eax =I8K_SMM_GET_DELL_SIG , }; +struct smm_regs regs = { .eax = req_fn, };int rc;if ((rc =i8k_smm (®s)) <0 )
@@ -301,7 +302,7 @@ static int i8k_ioctl(struct inode *ip, sbreak ;case I8K_GET_TEMP : - val =i8k_get_cpu_temp (); + val =i8k_get_temp (0 );break ;case I8K_GET_SPEED :
@@ -367,7 +368,7 @@ static int i8k_proc_show(struct seq_fileint fn_key, cpu_temp, ac_power;int left_fan, right_fan, left_speed, right_speed; - cpu_temp =i8k_get_cpu_temp ();/* 11100 �s */ + cpu_temp =i8k_get_temp (0 );/* 11100 �s */ left_fan =i8k_get_fan_status (I8K_FAN_LEFT );/* 580 �s */ right_fan =i8k_get_fan_status (I8K_FAN_RIGHT );/* 580 �s */ left_speed =i8k_get_fan_speed (I8K_FAN_LEFT );/* 580 �s */
@@ -421,6 +422,20 @@ static struct dmi_system_id __initdata i DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"), }, }, + { + .ident = "Dell Inspiron 2", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"), + }, + }, + { + .ident = "Dell Latitude 2", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"), + }, + }, { } };
@@ -451,7 +466,8 @@ static int __init i8k_probe(void)/* * Get SMM Dell signature */ -if (i8k_get_dell_signature () !=0 ) { +if (i8k_get_dell_signature (I8K_SMM_GET_DELL_SIG1 ) && +i8k_get_dell_signature (I8K_SMM_GET_DELL_SIG2 )) {printk (KERN_ERR "i8k: unable to get SMM Dell signature\n" );if (!force)return -ENODEV ;