static char bios_version [4] = "?";
static char serial_number[16] = "?";
-static int force = 0;
-static int restricted = 0;
-static int power_status = 0;
-
MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)");
MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops");
MODULE_LICENSE("GPL");
-MODULE_PARM(force, "i");
-MODULE_PARM(restricted, "i");
-MODULE_PARM(power_status, "i");
+
+static int force;
+module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Force loading without checking for supported models");
+
+static int restricted;
+module_param(restricted, bool, 0);
MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set");
+
+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 *, size_t, loff_t *);
+static ssize_t i8k_read(struct file *, char __user *, size_t, loff_t *);
static int i8k_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
int val;
int speed;
unsigned char buff[16];
+ int __user *argp = (int __user *)arg;
- if (!arg) {
+ if (!argp)
return -EINVAL;
- }
switch (cmd) {
case I8K_BIOS_VERSION:
break;
case I8K_GET_SPEED:
- if (copy_from_user(&val, (int *)arg, 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, (int *)arg, sizeof(int))) {
+ if (copy_from_user(&val, argp, sizeof(int))) {
return -EFAULT;
}
val = i8k_get_fan_status(val);
if (restricted && !capable(CAP_SYS_ADMIN)) {
return -EPERM;
}
- if (copy_from_user(&val, (int *)arg, sizeof(int))) {
+ if (copy_from_user(&val, argp, sizeof(int))) {
return -EFAULT;
}
- if (copy_from_user(&speed, (int *)arg+1, sizeof(int))) {
+ if (copy_from_user(&speed, argp+1, sizeof(int))) {
return -EFAULT;
}
val = i8k_set_fan(val, speed);
switch (cmd) {
case I8K_BIOS_VERSION:
- if (copy_to_user((int *)arg, &val, 4)) {
+ if (copy_to_user(argp, &val, 4)) {
return -EFAULT;
}
break;
case I8K_MACHINE_ID:
- if (copy_to_user((int *)arg, buff, 16)) {
+ if (copy_to_user(argp, buff, 16)) {
return -EFAULT;
}
break;
default:
- if (copy_to_user((int *)arg, &val, sizeof(int))) {
+ if (copy_to_user(argp, &val, sizeof(int))) {
return -EFAULT;
}
break;
return n;
}
-static ssize_t i8k_read(struct file *f, char *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];
static int __init dmi_iterate(void (*decode)(DMIHeader *))
{
- unsigned char buf[20];
- long fp = 0x000e0000L;
- fp -= 16;
-
- while (fp < 0x000fffffL) {
- fp += 16;
- isa_memcpy_fromio(buf, fp, 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];
+ 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]);
+ 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) {
- return 0;
- }
+ if (dmi_table(base, len, num, decode)==0) {
+ iounmap(p);
+ return 0;
+ }
+ }
}
- }
- return -1;
+ iounmap(p);
+ return -1;
}
/* end of DMI code */