]> git.pld-linux.org Git - packages/kernel.git/blob - linux-2.6-toshiba_acpi.patch
- up to 2.6.17.28
[packages/kernel.git] / linux-2.6-toshiba_acpi.patch
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
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,10 @@
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>
38 +#include <asm/io.h>
39  #include <linux/backlight.h>
40  
41  #include <asm/uaccess.h>
42 @@ -497,6 +515,191 @@
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
161 +tosh_proc_show(struct seq_file *m, void *v)
162 +{
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 +       seq_printf(m, "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 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);
190 +}
191 +
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 +
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);
215 +       proc_create(OLD_PROC_TOSHIBA, 0, NULL, &tosh_proc_fops);
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  
234 @@ -555,6 +758,8 @@
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  
243 @@ -562,6 +767,7 @@
244  {
245         acpi_status status = AE_OK;
246         u32 hci_result;
247 +       int status2;
248  
249         if (acpi_disabled)
250                 return -ENODEV;
251 @@ -578,6 +784,9 @@
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 0.155563 seconds and 3 git commands to generate.