]> git.pld-linux.org Git - packages/kernel.git/blame - linux-2.6-toshiba_acpi_0.18-dev_toshiba_test4.patch
- more strict values parser
[packages/kernel.git] / linux-2.6-toshiba_acpi_0.18-dev_toshiba_test4.patch
CommitLineData
e6625f32
MWP
1--- toshiba_acpi.c.orig 2006-06-22 21:39:40.000000000 -0400
2+++ toshiba_acpi.c 2006-06-22 21:48:07.000000000 -0400
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
26-#define TOSHIBA_ACPI_VERSION "0.18"
27+#define TOSHIBA_ACPI_VERSION "experimental-dev-toshiba-test-5"
28 #define PROC_INTERFACE_VERSION 1
29
30 #include <linux/kernel.h>
31@@ -41,6 +55,9 @@
32 #include <linux/init.h>
33 #include <linux/types.h>
34 #include <linux/proc_fs.h>
35+#include <linux/miscdevice.h>
36+#include <linux/toshiba.h>
37+#include <asm/io.h>
38 #include <asm/uaccess.h>
39
40 #include <acpi/acpi_drivers.h>
41@@ -463,6 +480,179 @@
42 return p;
43 }
44
45+/* /dev/toshiba and /proc/toshiba handlers {{{
46+ *
47+ * ISSUE: lots of magic numbers and mysterious code
48+ */
49+
50+#define TOSH_MINOR_DEV 181
51+#define OLD_PROC_TOSHIBA "toshiba"
52+
53+static int
54+tosh_acpi_bridge(SMMRegisters* regs)
55+{
56+ acpi_status status;
57+
58+ /* assert(sizeof(SMMRegisters) == sizeof(u32)*HCI_WORDS); */
59+ status = hci_raw((u32*)regs, (u32*)regs);
60+ if (status == AE_OK && (regs->eax & 0xff00) == HCI_SUCCESS)
61+ return 0;
62+
63+ return -EINVAL;
64+}
65+
66+static int
67+tosh_ioctl(struct inode* ip, struct file* fp, unsigned int cmd,
68+ unsigned long arg)
69+{
70+ SMMRegisters regs;
71+ unsigned short ax,bx;
72+ int err;
73+
74+ if ((!arg) || (cmd != TOSH_SMM))
75+ return -EINVAL;
76+
77+ if (copy_from_user(&regs, (SMMRegisters*)arg, sizeof(SMMRegisters)))
78+ return -EFAULT;
79+
80+ ax = regs.eax & 0xff00;
81+ bx = regs.ebx & 0xffff;
82+
83+ /* block HCI calls to read/write memory & PCI devices */
84+ if (((ax==HCI_SET) || (ax==HCI_GET)) && (bx>0x0069))
85+ return -EINVAL;
86+
87+ err = tosh_acpi_bridge(&regs);
88+
89+ if (copy_to_user((SMMRegisters*)arg, &regs, sizeof(SMMRegisters)))
90+ return -EFAULT;
91+
92+ return err;
93+}
94+
95+static int
96+tosh_get_machine_id(void __iomem *bios)
97+{
98+ int id;
99+ unsigned short bx,cx;
100+ unsigned long address;
101+
102+ id = (0x100*(int) readb(bios+0xfffe))+((int) readb(bios+0xfffa));
103+
104+ /* do we have a SCTTable machine identication number on our hands */
105+ if (id==0xfc2f) {
106+ bx = 0xe6f5; /* cheat */
107+ /* now twiddle with our pointer a bit */
108+ address = 0x00000000 + bx;
109+ cx = readw(bios + address);
110+ address = 0x00000009 + bx + cx;
111+ cx = readw(bios + address);
112+ address = 0x0000000a + cx;
113+ cx = readw(bios + address);
114+ /* now construct our machine identification number */
115+ id = ((cx & 0xff)<<8)+((cx & 0xff00)>>8);
116+ }
117+
118+ return id;
119+}
120+
121+static int tosh_id;
122+static int tosh_bios;
123+static int tosh_date;
124+static int tosh_sci;
125+
126+static struct file_operations tosh_fops = {
127+ .owner = THIS_MODULE,
128+ .ioctl = tosh_ioctl
129+};
130+
131+static struct miscdevice tosh_device = {
132+ TOSH_MINOR_DEV,
133+ "toshiba",
134+ &tosh_fops
135+};
136+
137+static void
138+setup_tosh_info(void __iomem *bios)
139+{
140+ int major, minor;
141+ int day, month, year;
142+
143+ tosh_id = tosh_get_machine_id(bios);
144+
145+ /* get the BIOS version */
146+ major = readb(bios + 0xe009)-'0';
147+ minor = ((readb(bios + 0xe00b)-'0')*10)+(readb(bios + 0xe00c)-'0');
148+ tosh_bios = (major*0x100)+minor;
149+
150+ /* get the BIOS date */
151+ day = ((readb(bios + 0xfff5)-'0')*10)+(readb(bios + 0xfff6)-'0');
152+ month = ((readb(bios + 0xfff8)-'0')*10)+(readb(bios + 0xfff9)-'0');
153+ year = ((readb(bios + 0xfffb)-'0')*10)+(readb(bios + 0xfffc)-'0');
154+ tosh_date = (((year-90) & 0x1f)<<10) | ((month & 0xf)<<6)
155+ | ((day & 0x1f)<<1);
156+}
157+
158+/* /proc/toshiba read handler */
159+static int
160+tosh_get_info(char* buffer, char** start, off_t fpos, int length)
161+{
162+ char* temp = buffer;
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+
175+ temp += sprintf(temp, "1.1 0x%04x %d.%d %d.%d 0x%04x 0x%02x\n",
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+
184+ return temp-buffer;
185+}
186+
187+static int __init
188+old_driver_emulation_init(void)
189+{
190+ int status;
191+ void __iomem *bios = ioremap(0xf0000, 0x10000);
192+ if (!bios)
193+ return -ENOMEM;
194+
195+ if ((status = misc_register(&tosh_device))) {
196+ printk(MY_ERR "failed to register misc device %d (\"%s\")\n",
197+ tosh_device.minor, tosh_device.name);
198+ return status;
199+ }
200+
201+ setup_tosh_info(bios);
202+ create_proc_info_entry(OLD_PROC_TOSHIBA, 0, NULL, tosh_get_info);
203+
204+ iounmap(bios);
205+
206+ return 0;
207+}
208+
209+static void __exit
210+old_driver_emulation_exit(void)
211+{
212+ remove_proc_entry(OLD_PROC_TOSHIBA, NULL);
213+ misc_deregister(&tosh_device);
214+}
215+
216+/* }}} end of /dev/toshiba and /proc/toshiba handlers */
217+
218 /* proc and module init
219 */
220
221@@ -510,6 +700,7 @@
222 {
223 acpi_status status = AE_OK;
224 u32 hci_result;
225+ int status2;
226
227 if (acpi_disabled)
228 return -ENODEV;
229@@ -530,6 +721,9 @@
230 TOSHIBA_ACPI_VERSION);
231 printk(MY_INFO " HCI method: %s\n", method_hci);
232
233+ if ((status2 = old_driver_emulation_init()))
234+ return status2;
235+
236 force_fan = 0;
237 key_event_valid = 0;
238
239@@ -556,6 +750,8 @@
240 if (toshiba_proc_dir)
241 remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
242
243+ old_driver_emulation_exit();
244+
245 return;
246 }
247
This page took 0.05671 seconds and 4 git commands to generate.