1 --- linux-2.6/drivers/acpi/toshiba_acpi.c.orig 2008-08-30 22:12:50.000000000 -0700
2 +++ linux-2.6/drivers/acpi/toshiba_acpi.c 2008-08-31 12:03:07.000000000 -0700
4 * Yasushi Nagato - changes for linux kernel 2.4 -> 2.5
5 * Rob Miller - TV out and hotkeys help
9 + * This is an experimental version of toshiba_acpi which includes emulation
10 + * of the original toshiba driver's /proc/toshiba and /dev/toshiba,
11 + * allowing Toshiba userspace utilities to work. The relevant code was
12 + * based on toshiba.c (copyright 1996-2001 Jonathan A. Buzzard) and
13 + * incorporated into this driver with help from Gintautas Miliauskas,
14 + * Charles Schwieters, and Christoph Burger-Scheidlin.
17 + * * hotkey status in /proc/toshiba is not implemented
18 + * * to make accesses to /dev/toshiba load this driver instead of
19 + * the original driver, you will have to modify your module
20 + * auto-loading configuration
26 -#define TOSHIBA_ACPI_VERSION "0.18"
27 +#define TOSHIBA_ACPI_VERSION "experimental-dev-toshiba-test-5"
28 #define PROC_INTERFACE_VERSION 1
30 #include <linux/kernel.h>
32 #include <linux/init.h>
33 #include <linux/types.h>
34 #include <linux/proc_fs.h>
35 +#include <linux/seq_file.h>
36 +#include <linux/miscdevice.h>
37 +#include <linux/toshiba.h>
39 #include <linux/backlight.h>
41 #include <asm/uaccess.h>
46 +/* /dev/toshiba and /proc/toshiba handlers {{{
48 + * ISSUE: lots of magic numbers and mysterious code
51 +#define TOSH_MINOR_DEV 181
52 +#define OLD_PROC_TOSHIBA "toshiba"
55 +tosh_acpi_bridge(SMMRegisters* regs)
59 + /* assert(sizeof(SMMRegisters) == sizeof(u32)*HCI_WORDS); */
60 + status = hci_raw((u32*)regs, (u32*)regs);
61 + if (status == AE_OK && (regs->eax & 0xff00) == HCI_SUCCESS)
68 +tosh_ioctl(struct inode* ip, struct file* fp, unsigned int cmd,
72 + unsigned short ax,bx;
75 + if ((!arg) || (cmd != TOSH_SMM))
78 + if (copy_from_user(®s, (SMMRegisters*)arg, sizeof(SMMRegisters)))
81 + ax = regs.eax & 0xff00;
82 + bx = regs.ebx & 0xffff;
84 + /* block HCI calls to read/write memory & PCI devices */
85 + if (((ax==HCI_SET) || (ax==HCI_GET)) && (bx>0x0069))
88 + err = tosh_acpi_bridge(®s);
90 + if (copy_to_user((SMMRegisters*)arg, ®s, sizeof(SMMRegisters)))
97 +tosh_get_machine_id(void __iomem *bios)
100 + unsigned short bx,cx;
101 + unsigned long address;
103 + id = (0x100*(int) readb(bios+0xfffe))+((int) readb(bios+0xfffa));
105 + /* do we have a SCTTable machine identication number on our hands */
107 + bx = 0xe6f5; /* cheat */
108 + /* now twiddle with our pointer a bit */
109 + address = 0x00000000 + bx;
110 + cx = readw(bios + address);
111 + address = 0x00000009 + bx + cx;
112 + cx = readw(bios + address);
113 + address = 0x0000000a + cx;
114 + cx = readw(bios + address);
115 + /* now construct our machine identification number */
116 + id = ((cx & 0xff)<<8)+((cx & 0xff00)>>8);
123 +static int tosh_bios;
124 +static int tosh_date;
125 +static int tosh_sci;
127 +static struct file_operations tosh_fops = {
128 + .owner = THIS_MODULE,
129 + .ioctl = tosh_ioctl
132 +static struct miscdevice tosh_device = {
139 +setup_tosh_info(void __iomem *bios)
142 + int day, month, year;
144 + tosh_id = tosh_get_machine_id(bios);
146 + /* get the BIOS version */
147 + major = readb(bios + 0xe009)-'0';
148 + minor = ((readb(bios + 0xe00b)-'0')*10)+(readb(bios + 0xe00c)-'0');
149 + tosh_bios = (major*0x100)+minor;
151 + /* get the BIOS date */
152 + day = ((readb(bios + 0xfff5)-'0')*10)+(readb(bios + 0xfff6)-'0');
153 + month = ((readb(bios + 0xfff8)-'0')*10)+(readb(bios + 0xfff9)-'0');
154 + year = ((readb(bios + 0xfffb)-'0')*10)+(readb(bios + 0xfffc)-'0');
155 + tosh_date = (((year-90) & 0x1f)<<10) | ((month & 0xf)<<6)
156 + | ((day & 0x1f)<<1);
159 +/* /proc/toshiba read handler */
161 +tosh_proc_show(struct seq_file *m, void *v)
163 + /* TODO: tosh_fn_status() */
167 + * 0) Linux driver version (this will change if format changes)
170 + * 3) BIOS version (major, minor)
171 + * 4) BIOS date (in SCI date format)
175 + seq_printf(m, "1.1 0x%04x %d.%d %d.%d 0x%04x 0x%02x\n",
177 + (tosh_sci & 0xff00)>>8,
179 + (tosh_bios & 0xff00)>>8,
187 +static int tosh_proc_open(struct inode *inode, struct file *file)
189 + return single_open(file, tosh_proc_show, NULL);
192 +static const struct file_operations tosh_proc_fops = {
193 + .owner = THIS_MODULE,
194 + .open = tosh_proc_open,
196 + .llseek = seq_lseek,
197 + .release = single_release,
201 +old_driver_emulation_init(void)
204 + void __iomem *bios = ioremap(0xf0000, 0x10000);
208 + if ((status = misc_register(&tosh_device))) {
209 + printk(MY_ERR "failed to register misc device %d (\"%s\")\n",
210 + tosh_device.minor, tosh_device.name);
214 + setup_tosh_info(bios);
215 + proc_create(OLD_PROC_TOSHIBA, 0, NULL, &tosh_proc_fops);
223 +old_driver_emulation_exit(void)
225 + remove_proc_entry(OLD_PROC_TOSHIBA, NULL);
226 + misc_deregister(&tosh_device);
229 +/* }}} end of /dev/toshiba and /proc/toshiba handlers */
231 /* proc and module init
235 if (toshiba_proc_dir)
236 remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
238 + old_driver_emulation_exit();
245 acpi_status status = AE_OK;
252 TOSHIBA_ACPI_VERSION);
253 printk(MY_INFO " HCI method: %s\n", method_hci);
255 + if ((status2 = old_driver_emulation_init()))