]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-toshiba_acpi.patch
- remove from HEAD
[packages/kernel.git] / kernel-toshiba_acpi.patch
CommitLineData
2380c486
JR
1---- linux-2.6/drivers/platform/x86/toshiba_acpi.c.orig 2008-08-30 22:12:50.000000000 -0700
2+++ linux-2.6/drivers/platform/x86/toshiba_acpi.c 2008-08-31 12:03:07.000000000 -0700
4a638a57
JR
3@@ -28,12 +28,26 @@
4 * Yasushi Nagato - changes for linux kernel 2.4 -> 2.5
5 * Rob Miller - TV out and hotkeys help
6 *
7+ * PLEASE NOTE
8+ *
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.
15+ *
16+ * Caveats:
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
21 *
22 * TODO
23 *
24 */
25
2380c486 26-#define TOSHIBA_ACPI_VERSION "0.19"
4a638a57
JR
27+#define TOSHIBA_ACPI_VERSION "experimental-dev-toshiba-test-5"
28 #define PROC_INTERFACE_VERSION 1
29
30 #include <linux/kernel.h>
5f2a5423 31@@ -41,6 +55,10 @@
4a638a57
JR
32 #include <linux/init.h>
33 #include <linux/types.h>
34 #include <linux/proc_fs.h>
5f2a5423 35+#include <linux/seq_file.h>
4a638a57
JR
36+#include <linux/miscdevice.h>
37+#include <linux/toshiba.h>
38+#include <asm/io.h>
39 #include <linux/backlight.h>
40
41 #include <asm/uaccess.h>
5f2a5423 42@@ -497,6 +515,191 @@
4a638a57
JR
43 return p;
44 }
45
46+/* /dev/toshiba and /proc/toshiba handlers {{{
47+ *
48+ * ISSUE: lots of magic numbers and mysterious code
49+ */
50+
51+#define TOSH_MINOR_DEV 181
52+#define OLD_PROC_TOSHIBA "toshiba"
53+
54+static int
55+tosh_acpi_bridge(SMMRegisters* regs)
56+{
57+ acpi_status status;
58+
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)
62+ return 0;
63+
64+ return -EINVAL;
65+}
66+
67+static int
68+tosh_ioctl(struct inode* ip, struct file* fp, unsigned int cmd,
69+ unsigned long arg)
70+{
71+ SMMRegisters regs;
72+ unsigned short ax,bx;
73+ int err;
74+
75+ if ((!arg) || (cmd != TOSH_SMM))
76+ return -EINVAL;
77+
78+ if (copy_from_user(&regs, (SMMRegisters*)arg, sizeof(SMMRegisters)))
79+ return -EFAULT;
80+
81+ ax = regs.eax & 0xff00;
82+ bx = regs.ebx & 0xffff;
83+
84+ /* block HCI calls to read/write memory & PCI devices */
85+ if (((ax==HCI_SET) || (ax==HCI_GET)) && (bx>0x0069))
86+ return -EINVAL;
87+
88+ err = tosh_acpi_bridge(&regs);
89+
90+ if (copy_to_user((SMMRegisters*)arg, &regs, sizeof(SMMRegisters)))
91+ return -EFAULT;
92+
93+ return err;
94+}
95+
96+static int
97+tosh_get_machine_id(void __iomem *bios)
98+{
99+ int id;
100+ unsigned short bx,cx;
101+ unsigned long address;
102+
103+ id = (0x100*(int) readb(bios+0xfffe))+((int) readb(bios+0xfffa));
104+
105+ /* do we have a SCTTable machine identication number on our hands */
106+ if (id==0xfc2f) {
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);
117+ }
118+
119+ return id;
120+}
121+
122+static int tosh_id;
123+static int tosh_bios;
124+static int tosh_date;
125+static int tosh_sci;
126+
127+static struct file_operations tosh_fops = {
128+ .owner = THIS_MODULE,
129+ .ioctl = tosh_ioctl
130+};
131+
132+static struct miscdevice tosh_device = {
133+ TOSH_MINOR_DEV,
134+ "toshiba",
135+ &tosh_fops
136+};
137+
138+static void
139+setup_tosh_info(void __iomem *bios)
140+{
141+ int major, minor;
142+ int day, month, year;
143+
144+ tosh_id = tosh_get_machine_id(bios);
145+
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;
150+
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);
157+}
158+
159+/* /proc/toshiba read handler */
160+static int
5f2a5423 161+tosh_proc_show(struct seq_file *m, void *v)
4a638a57 162+{
4a638a57
JR
163+ /* TODO: tosh_fn_status() */
164+ int key = 0;
165+
166+ /* Format:
167+ * 0) Linux driver version (this will change if format changes)
168+ * 1) Machine ID
169+ * 2) SCI version
170+ * 3) BIOS version (major, minor)
171+ * 4) BIOS date (in SCI date format)
172+ * 5) Fn Key status
173+ */
174+
5f2a5423 175+ seq_printf(m, "1.1 0x%04x %d.%d %d.%d 0x%04x 0x%02x\n",
4a638a57
JR
176+ tosh_id,
177+ (tosh_sci & 0xff00)>>8,
178+ tosh_sci & 0xff,
179+ (tosh_bios & 0xff00)>>8,
180+ tosh_bios & 0xff,
181+ tosh_date,
182+ key);
183+
5f2a5423
PS
184+ return 0;
185+}
186+
187+static int tosh_proc_open(struct inode *inode, struct file *file)
188+{
189+ return single_open(file, tosh_proc_show, NULL);
4a638a57
JR
190+}
191+
5f2a5423
PS
192+static const struct file_operations tosh_proc_fops = {
193+ .owner = THIS_MODULE,
194+ .open = tosh_proc_open,
195+ .read = seq_read,
196+ .llseek = seq_lseek,
197+ .release = single_release,
198+};
199+
4a638a57
JR
200+static int __init
201+old_driver_emulation_init(void)
202+{
203+ int status;
204+ void __iomem *bios = ioremap(0xf0000, 0x10000);
205+ if (!bios)
206+ return -ENOMEM;
207+
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);
211+ return status;
212+ }
213+
214+ setup_tosh_info(bios);
5f2a5423 215+ proc_create(OLD_PROC_TOSHIBA, 0, NULL, &tosh_proc_fops);
4a638a57
JR
216+
217+ iounmap(bios);
218+
219+ return 0;
220+}
221+
222+static void __exit
223+old_driver_emulation_exit(void)
224+{
225+ remove_proc_entry(OLD_PROC_TOSHIBA, NULL);
226+ misc_deregister(&tosh_device);
227+}
228+
229+/* }}} end of /dev/toshiba and /proc/toshiba handlers */
230+
231 /* proc and module init
232 */
233
5f2a5423 234@@ -555,6 +758,8 @@
4a638a57
JR
235 if (toshiba_proc_dir)
236 remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
237
238+ old_driver_emulation_exit();
239+
240 return;
241 }
242
5f2a5423 243@@ -562,6 +767,7 @@
4a638a57
JR
244 {
245 acpi_status status = AE_OK;
246 u32 hci_result;
247+ int status2;
2380c486
JR
248 bool bt_present;
249 bool bt_on;
250 bool radio_on;
5f2a5423 251@@ -578,6 +784,9 @@
4a638a57
JR
252 TOSHIBA_ACPI_VERSION);
253 printk(MY_INFO " HCI method: %s\n", method_hci);
254
255+ if ((status2 = old_driver_emulation_init()))
256+ return status2;
257+
258 force_fan = 0;
259 key_event_valid = 0;
260
This page took 3.035231 seconds and 4 git commands to generate.