* [PATCH 0/6] I8K and Toshiba legacy driver cleanup
@ 2005-04-27 6:49 Dmitry Torokhov
2005-04-27 6:50 ` [PATCH 1/6] Toshiba " Dmitry Torokhov
` (5 more replies)
0 siblings, 6 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2005-04-27 6:49 UTC (permalink / raw)
To: Andrew Morton, LKML
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!
--
Dmitry
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/6] Toshiba driver cleanup
2005-04-27 6:49 [PATCH 0/6] I8K and Toshiba legacy driver cleanup Dmitry Torokhov
@ 2005-04-27 6:50 ` Dmitry Torokhov
2005-04-27 7:33 ` Andrew Morton
2005-04-27 6:52 ` [PATCH 2/6] I8K: pass through lindent Dmitry Torokhov
` (4 subsequent siblings)
5 siblings, 1 reply; 11+ messages in thread
From: Dmitry Torokhov @ 2005-04-27 6:50 UTC (permalink / raw)
To: Andrew Morton; +Cc: LKML
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
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---
misc.c | 4 ----
toshiba.c | 60 ++++++++++++++++++++++++------------------------------------
2 files changed, 24 insertions(+), 40 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_LICENSE("GPL");
+MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>");
+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 <jonathan@buzzard.org.uk>");
-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
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 2/6] I8K: pass through lindent
2005-04-27 6:49 [PATCH 0/6] I8K and Toshiba legacy driver cleanup Dmitry Torokhov
2005-04-27 6:50 ` [PATCH 1/6] Toshiba " Dmitry Torokhov
@ 2005-04-27 6:52 ` Dmitry Torokhov
2005-04-27 6:52 ` [PATCH 3/6] I8K: use standard DMI interface Dmitry Torokhov
` (3 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2005-04-27 6:52 UTC (permalink / raw)
To: Andrew Morton; +Cc: LKML
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 27392 bytes --]
I8K: pass through Lindent to change 4 spaces identation to TABs
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---
i8k.c | 954 +++++++++++++++++++++++++++++++++---------------------------------
1 files changed, 477 insertions(+), 477 deletions(-)
Index: dtor/drivers/char/i8k.c
===================================================================
--- dtor.orig/drivers/char/i8k.c
+++ dtor/drivers/char/i8k.c
@@ -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 (dz@debian.org)");
@@ -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 (*dec
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];
+ 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 (*dec
iounmap(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 (dz@debian.org)\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 (dz@debian.org)\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
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 3/6] I8K: use standard DMI interface
2005-04-27 6:49 [PATCH 0/6] I8K and Toshiba legacy driver cleanup Dmitry Torokhov
2005-04-27 6:50 ` [PATCH 1/6] Toshiba " Dmitry Torokhov
2005-04-27 6:52 ` [PATCH 2/6] I8K: pass through lindent Dmitry Torokhov
@ 2005-04-27 6:52 ` Dmitry Torokhov
2005-04-28 5:02 ` Dmitry Torokhov
2005-04-27 6:53 ` [PATCH 4/6] I8K: convert to seqfile Dmitry Torokhov
` (2 subsequent siblings)
5 siblings, 1 reply; 11+ messages in thread
From: Dmitry Torokhov @ 2005-04-27 6:52 UTC (permalink / raw)
To: Andrew Morton; +Cc: LKML
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 <dtor@mail.ru>
---
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(-)
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",
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 (dz@debian.org)");
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_status
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 4/6] I8K: convert to seqfile
2005-04-27 6:49 [PATCH 0/6] I8K and Toshiba legacy driver cleanup Dmitry Torokhov
` (2 preceding siblings ...)
2005-04-27 6:52 ` [PATCH 3/6] I8K: use standard DMI interface Dmitry Torokhov
@ 2005-04-27 6:53 ` Dmitry Torokhov
2005-04-27 6:54 ` [PATCH 5/6] I8K: initialization code cleanup; formatting Dmitry Torokhov
2005-04-27 6:55 ` [PATCH 6/6] I8K: add new BIOS signatures Dmitry Torokhov
5 siblings, 0 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2005-04-27 6:53 UTC (permalink / raw)
To: Andrew Morton; +Cc: LKML
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 3363 bytes --]
I8K: Change proc code to use seq_file.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---
i8k.c | 64 ++++++++++++++++++++++------------------------------------------
1 files changed, 22 insertions(+), 42 deletions(-)
Index: dtor/drivers/char/i8k.c
===================================================================
--- dtor.orig/drivers/char/i8k.c
+++ dtor/drivers/char/i8k.c
@@ -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;
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 5/6] I8K: initialization code cleanup; formatting
2005-04-27 6:49 [PATCH 0/6] I8K and Toshiba legacy driver cleanup Dmitry Torokhov
` (3 preceding siblings ...)
2005-04-27 6:53 ` [PATCH 4/6] I8K: convert to seqfile Dmitry Torokhov
@ 2005-04-27 6:54 ` Dmitry Torokhov
2005-04-27 6:55 ` [PATCH 6/6] I8K: add new BIOS signatures Dmitry Torokhov
5 siblings, 0 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2005-04-27 6:54 UTC (permalink / raw)
To: Andrew Morton; +Cc: LKML
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 8480 bytes --]
I8K: use module_{init|exit} instead of old style #ifdef MODULE
code, some formatting changes.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---
i8k.c | 149 ++++++++++++++++++++---------------------------------------------
misc.c | 4 -
2 files changed, 47 insertions(+), 106 deletions(-)
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 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);
Index: dtor/drivers/char/i8k.c
===================================================================
--- dtor.orig/drivers/char/i8k.c
+++ dtor/drivers/char/i8k.c
@@ -87,14 +87,14 @@ static struct file_operations i8k_fops =
.ioctl = i8k_ioctl,
};
-typedef struct {
+struct smm_regs {
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;
+};
static inline char *i8k_get_dmi_data(int field)
{
@@ -104,7 +104,7 @@ static inline char *i8k_get_dmi_data(int
/*
* Call the System Management Mode BIOS. Code provided by Jonathan Buzzard.
*/
-static int i8k_smm(SMMRegisters * regs)
+static int i8k_smm(struct smm_regs *regs)
{
int rc;
int eax = regs->eax;
@@ -134,9 +134,8 @@ static int i8k_smm(SMMRegisters * regs)
: "a"(regs)
: "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
- if ((rc != 0) || ((regs->eax & 0xffff) == 0xffff) || (regs->eax == eax)) {
+ if (rc != 0 || (regs->eax & 0xffff) == 0xffff || regs->eax == eax)
return -EINVAL;
- }
return 0;
}
@@ -147,15 +146,9 @@ static int i8k_smm(SMMRegisters * regs)
*/
static int i8k_get_bios_version(void)
{
- SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
- int rc;
-
- regs.eax = I8K_SMM_BIOS_VERSION;
- if ((rc = i8k_smm(®s)) < 0) {
- return rc;
- }
+ struct smm_regs regs = { .eax = I8K_SMM_BIOS_VERSION, };
- return regs.eax;
+ return i8k_smm(®s) ? : regs.eax;
}
/*
@@ -163,13 +156,11 @@ static int i8k_get_bios_version(void)
*/
static int i8k_get_fn_status(void)
{
- SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
+ struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, };
int rc;
- regs.eax = I8K_SMM_FN_STATUS;
- if ((rc = i8k_smm(®s)) < 0) {
+ if ((rc = i8k_smm(®s)) < 0)
return rc;
- }
switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) {
case I8K_FN_UP:
@@ -188,20 +179,13 @@ static int i8k_get_fn_status(void)
*/
static int i8k_get_power_status(void)
{
- SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
+ struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, };
int rc;
- regs.eax = I8K_SMM_POWER_STATUS;
- if ((rc = i8k_smm(®s)) < 0) {
+ if ((rc = i8k_smm(®s)) < 0)
return rc;
- }
- switch (regs.eax & 0xff) {
- case I8K_POWER_AC:
- return I8K_AC;
- default:
- return I8K_BATTERY;
- }
+ return (regs.eax & 0xff) == I8K_POWER_AC ? I8K_AC : I8K_BATTERY;
}
/*
@@ -209,16 +193,10 @@ 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;
+ struct smm_regs regs = { .eax = I8K_SMM_GET_FAN, };
- regs.eax = I8K_SMM_GET_FAN;
regs.ebx = fan & 0xff;
- if ((rc = i8k_smm(®s)) < 0) {
- return rc;
- }
-
- return (regs.eax & 0xff);
+ return i8k_smm(®s) ? : regs.eax & 0xff;
}
/*
@@ -226,16 +204,10 @@ 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;
+ struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, };
- 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 i8k_smm(®s) ? : (regs.eax & 0xffff) * I8K_FAN_MULT;
}
/*
@@ -243,18 +215,12 @@ 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;
+ struct smm_regs regs = { .eax = I8K_SMM_SET_FAN, };
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;
- }
- return (i8k_get_fan_status(fan));
+ return i8k_smm(®s) ? : i8k_get_fan_status(fan);
}
/*
@@ -262,18 +228,17 @@ static int i8k_set_fan(int fan, int spee
*/
static int i8k_get_cpu_temp(void)
{
- SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
+ struct smm_regs regs = { .eax = I8K_SMM_GET_TEMP, };
int rc;
int temp;
#ifdef I8K_TEMPERATURE_BUG
- static int prev = 0;
+ static int prev;
#endif
- regs.eax = I8K_SMM_GET_TEMP;
- if ((rc = i8k_smm(®s)) < 0) {
+ if ((rc = i8k_smm(®s)) < 0)
return rc;
- }
+
temp = regs.eax & 0xff;
#ifdef I8K_TEMPERATURE_BUG
@@ -297,19 +262,13 @@ static int i8k_get_cpu_temp(void)
static int i8k_get_dell_signature(void)
{
- SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
+ struct smm_regs regs = { .eax = I8K_SMM_GET_DELL_SIG, };
int rc;
- regs.eax = I8K_SMM_GET_DELL_SIG;
- if ((rc = i8k_smm(®s)) < 0) {
+ if ((rc = i8k_smm(®s)) < 0)
return rc;
- }
- if ((regs.eax == 1145651527) && (regs.edx == 1145392204)) {
- return 0;
- } else {
- return -1;
- }
+ return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1;
}
static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
@@ -346,29 +305,29 @@ static int i8k_ioctl(struct inode *ip, s
break;
case I8K_GET_SPEED:
- if (copy_from_user(&val, argp, sizeof(int))) {
+ 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))) {
+ 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)) {
+ if (restricted && !capable(CAP_SYS_ADMIN))
return -EPERM;
- }
- if (copy_from_user(&val, argp, sizeof(int))) {
+
+ if (copy_from_user(&val, argp, sizeof(int)))
return -EFAULT;
- }
- if (copy_from_user(&speed, argp + 1, sizeof(int))) {
+
+ if (copy_from_user(&speed, argp + 1, sizeof(int)))
return -EFAULT;
- }
+
val = i8k_set_fan(val, speed);
break;
@@ -376,25 +335,24 @@ static int i8k_ioctl(struct inode *ip, s
return -EINVAL;
}
- if (val < 0) {
+ if (val < 0)
return val;
- }
switch (cmd) {
case I8K_BIOS_VERSION:
- if (copy_to_user(argp, &val, 4)) {
+ if (copy_to_user(argp, &val, 4))
return -EFAULT;
- }
+
break;
case I8K_MACHINE_ID:
- if (copy_to_user(argp, buff, 16)) {
+ if (copy_to_user(argp, buff, 16))
return -EFAULT;
- }
+
break;
default:
- if (copy_to_user(argp, &val, sizeof(int))) {
+ if (copy_to_user(argp, &val, sizeof(int)))
return -EFAULT;
- }
+
break;
}
@@ -415,11 +373,10 @@ static int i8k_proc_show(struct seq_file
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) {
+ if (power_status)
ac_power = i8k_get_power_status(); /* 14700 µs */
- } else {
+ else
ac_power = -1;
- }
/*
* Info:
@@ -528,10 +485,7 @@ static int __init i8k_probe(void)
return 0;
}
-#ifdef MODULE
-static
-#endif
-int __init i8k_init(void)
+static int __init i8k_init(void)
{
struct proc_dir_entry *proc_i8k;
@@ -554,19 +508,10 @@ int __init i8k_init(void)
return 0;
}
-#ifdef MODULE
-int init_module(void)
+static void __exit i8k_exit(void)
{
- return i8k_init();
-}
-
-void cleanup_module(void)
-{
- /* Remove the proc entry */
remove_proc_entry("i8k", NULL);
-
- printk(KERN_INFO "i8k: module unloaded\n");
}
-#endif
-/* end of file */
+module_init(i8k_init);
+module_exit(i8k_exit);
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 6/6] I8K: add new BIOS signatures
2005-04-27 6:49 [PATCH 0/6] I8K and Toshiba legacy driver cleanup Dmitry Torokhov
` (4 preceding siblings ...)
2005-04-27 6:54 ` [PATCH 5/6] I8K: initialization code cleanup; formatting Dmitry Torokhov
@ 2005-04-27 6:55 ` Dmitry Torokhov
5 siblings, 0 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2005-04-27 6:55 UTC (permalink / raw)
To: Andrew Morton; +Cc: LKML
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 2921 bytes --]
I8K: 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.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---
i8k.c | 32 ++++++++++++++++++++++++--------
1 files changed, 24 insertions(+), 8 deletions(-)
Index: dtor/drivers/char/i8k.c
===================================================================
--- dtor.orig/drivers/char/i8k.c
+++ dtor/drivers/char/i8k.c
@@ -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, s
break;
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_file
int 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;
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/6] Toshiba driver cleanup
2005-04-27 6:50 ` [PATCH 1/6] Toshiba " Dmitry Torokhov
@ 2005-04-27 7:33 ` Andrew Morton
2005-04-27 13:42 ` Dmitry Torokhov
0 siblings, 1 reply; 11+ messages in thread
From: Andrew Morton @ 2005-04-27 7:33 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-kernel
Dmitry Torokhov <dtor_core@ameritech.net> wrote:
>
> Toshiba legacy driver cleanup:
--- 25/drivers/char/toshiba.c~toshiba-driver-cleanup-fix 2005-04-27 00:32:47.306512192 -0700
+++ 25-akpm/drivers/char/toshiba.c 2005-04-27 00:32:51.521871360 -0700
@@ -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");
static int tosh_id;
_
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/6] Toshiba driver cleanup
2005-04-27 7:33 ` Andrew Morton
@ 2005-04-27 13:42 ` Dmitry Torokhov
2005-04-28 4:58 ` Dmitry Torokhov
0 siblings, 1 reply; 11+ messages in thread
From: Dmitry Torokhov @ 2005-04-27 13:42 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel
On 4/27/05, Andrew Morton <akpm@osdl.org> wrote:
> Dmitry Torokhov <dtor_core@ameritech.net> wrote:
> >
> > Toshiba legacy driver cleanup:
>
> --- 25/drivers/char/toshiba.c~toshiba-driver-cleanup-fix 2005-04-27 00:32:47.306512192 -0700
> +++ 25-akpm/drivers/char/toshiba.c 2005-04-27 00:32:51.521871360 -0700
> @@ -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.
--
Dmitry
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/6] Toshiba driver cleanup
2005-04-27 13:42 ` Dmitry Torokhov
@ 2005-04-28 4:58 ` Dmitry Torokhov
0 siblings, 0 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2005-04-28 4:58 UTC (permalink / raw)
To: linux-kernel; +Cc: Andrew Morton
On Wednesday 27 April 2005 08:42, Dmitry Torokhov wrote:
> On 4/27/05, Andrew Morton <akpm@osdl.org> wrote:
> > Dmitry Torokhov <dtor_core@ameritech.net> wrote:
> > >
> > > Toshiba legacy driver cleanup:
> >
> > --- 25/drivers/char/toshiba.c~toshiba-driver-cleanup-fix 2005-04-27 00:32:47.306512192 -0700
> > +++ 25-akpm/drivers/char/toshiba.c 2005-04-27 00:32:51.521871360 -0700
> > @@ -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.
>
Ok, this is the right one. Parameter is changed to "toshiba.fn" and
documented in kernel-parameters.txt
--
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 <dtor@mail.ru>
---
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 <jonathan@buzzard.org.uk>");
+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 <jonathan@buzzard.org.uk>");
-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
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 3/6] I8K: use standard DMI interface
2005-04-27 6:52 ` [PATCH 3/6] I8K: use standard DMI interface Dmitry Torokhov
@ 2005-04-28 5:02 ` Dmitry Torokhov
0 siblings, 0 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2005-04-28 5:02 UTC (permalink / raw)
To: linux-kernel; +Cc: Andrew Morton
Andrew brought to my attention yet again that I forgot to
export dmi_get_system_info.
--
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 <dtor@mail.ru>
---
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 (dz@debian.org)");
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_status
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2005-04-28 5:03 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-04-27 6:49 [PATCH 0/6] I8K and Toshiba legacy driver cleanup Dmitry Torokhov
2005-04-27 6:50 ` [PATCH 1/6] Toshiba " Dmitry Torokhov
2005-04-27 7:33 ` Andrew Morton
2005-04-27 13:42 ` Dmitry Torokhov
2005-04-28 4:58 ` Dmitry Torokhov
2005-04-27 6:52 ` [PATCH 2/6] I8K: pass through lindent Dmitry Torokhov
2005-04-27 6:52 ` [PATCH 3/6] I8K: use standard DMI interface Dmitry Torokhov
2005-04-28 5:02 ` Dmitry Torokhov
2005-04-27 6:53 ` [PATCH 4/6] I8K: convert to seqfile Dmitry Torokhov
2005-04-27 6:54 ` [PATCH 5/6] I8K: initialization code cleanup; formatting Dmitry Torokhov
2005-04-27 6:55 ` [PATCH 6/6] I8K: add new BIOS signatures Dmitry Torokhov
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.