blob: 262d2c5b8fb9c630d13aa7251df5b1f6c36add63 [file] [log] [blame]
mridge8b64ae92003-06-10 19:29:56 +00001
2#include <linux/kernel.h>
3#include <linux/module.h>
4#include <linux/init.h>
5#include <linux/types.h>
6#include <linux/fs.h>
7#include <linux/ioctl.h>
8#include <linux/pm.h>
9#include <linux/acpi.h>
10#include <linux/genhd.h>
11#include <asm/uaccess.h>
12#include "LtpAcpi.h"
13
14static int ltpdev_open( struct inode *inode, struct file *pfile);
15static int ltpdev_release( struct inode *inode, struct file *pfile);
16static int ltpdev_ioctl ( struct inode *pinode, struct file *pfile, unsigned int cmd, unsigned long arg );
17static void acpi_bus_notify (acpi_handle handle, u32 type, void *data);
18static void acpi_ec_gpe_handler (void *data);
19static acpi_status ltp_get_dev_callback (acpi_handle obj, u32 depth, void *context, void **ret);
20static acpi_status acpi_ec_io_ports (struct acpi_resource *resource, void *context);
21static acpi_status acpi_ec_space_setup (acpi_handle region_handle,
22 u32 function,
23 void *handler_context,
24 void **return_context);
25static acpi_status acpi_ec_space_handler (u32 function,
26 acpi_physical_address address,
27 u32 bit_width,
28 acpi_integer *value,
29 void *handler_context,
30 void *region_context);
31
32static struct block_device_operations blkops = {
33open: ltpdev_open,
34release: ltpdev_release,
35ioctl: ltpdev_ioctl,
36};
37
38int ltp_acpi_major = LTPMAJOR;
39int test_iteration = 0;
40
41static char genhd_flags = 0;
42static struct gendisk * gd_ptr;
43
44struct acpi_ec {
45 acpi_handle handle;
46 unsigned long uid;
47 unsigned long gpe_bit;
48 struct acpi_generic_address status_addr;
49 struct acpi_generic_address command_addr;
50 struct acpi_generic_address data_addr;
51 unsigned long global_lock;
52 spinlock_t lock;
53};
54
55MODULE_AUTHOR("Martin Ridgeway <mridge@us.ibm.com>");
56MODULE_DESCRIPTION(ACPI_LTP_TEST_DRIVER_NAME);
57MODULE_LICENSE("GPL");
58
59/*
60 * Device operations for the virtual ACPI devices
61 */
62
63
64static struct pm_dev *ltp_pm_dev = NULL;
65
66extern struct acpi_device *acpi_root;
67
68
69static int ltpdev_open (struct inode *pinode, struct file *pfile)
70{
71 printk(KERN_ALERT "ltpdev_open \n");
72 return 0;
73}
74
75static int ltpdev_release (struct inode *pinode, struct file *pfile)
76{
77
78 printk(KERN_ALERT "ltpdev_release \n");
79 return 0;
80}
81
82static int ltpdev_ioctl ( struct inode *pinode, struct file *pfile, unsigned int cmd, unsigned long arg )
83{
84 acpi_status status;
85// acpi_handle sys_bus_handle;
86 acpi_handle start_handle = 0;
87 acpi_handle parent_handle;
88 acpi_handle child_handle;
89 acpi_handle next_child_handle;
90 acpi_handle tmp_handle;
91 acpi_status level;
92 struct acpi_buffer dsdt = {ACPI_ALLOCATE_BUFFER, NULL};
93 struct acpi_table_ecdt *ecdt_ptr;
94 struct acpi_ec *ec;
95 struct acpi_device *device;
96 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
97 struct acpi_buffer batt_buffer = {ACPI_ALLOCATE_BUFFER, NULL};
98 struct acpi_buffer format = {sizeof(ACPI_BATTERY_FORMAT_BIF),
99 ACPI_BATTERY_FORMAT_BIF};
100 struct acpi_buffer data = {0, NULL};
101 union acpi_object *package = NULL;
102
103 u32 start_ticks, stop_ticks, total_ticks, i, bm_status;
104 u8 type_a, type_b;
105
106 /*****************************************************************************/
107
108
109
110
111 printk(KERN_ALERT "ltpdev_ioctl \n");
112 switch (cmd) {
113 case LTPDEV_CMD:
114
115 parent_handle = start_handle;
116 child_handle = 0;
117 level = 1;
118 test_iteration++;
119
120 printk(KERN_ALERT "-- IOCTL called to start ACPI tests -- Iteration:%d\n",test_iteration);
121
122 printk(KERN_ALERT "TEST -- acpi_get_handle \n");
123
124 status = acpi_get_handle (0, ACPI_NS_SYSTEM_BUS, &parent_handle);
125
126 printk(KERN_ALERT "TEST -- acpi_get_next_object \n");
127
128 status = acpi_get_next_object (ACPI_TYPE_ANY, parent_handle,
129 child_handle, &next_child_handle);
130
131 printk(KERN_ALERT "TEST -- acpi_get_parent \n");
132
133 status = acpi_get_parent(parent_handle, &parent_handle);
134
135 printk(KERN_ALERT "TEST -- acpi_evaluate_object \n");
136
137 status = acpi_evaluate_object(parent_handle, "_ON", NULL, NULL);
138
139 printk(KERN_ALERT "TEST -- acpi_get_table \n");
140
141 status = acpi_get_table(ACPI_TABLE_RSDP, 1, &dsdt);
142 status = acpi_get_table(ACPI_TABLE_DSDT, 1, &dsdt);
143 status = acpi_get_table(ACPI_TABLE_FADT, 1, &dsdt);
144 status = acpi_get_table(ACPI_TABLE_FACS, 1, &dsdt);
145 status = acpi_get_table(ACPI_TABLE_PSDT, 1, &dsdt);
146 status = acpi_get_table(ACPI_TABLE_SSDT, 1, &dsdt);
147 status = acpi_get_table(ACPI_TABLE_XSDT, 1, &dsdt);
148
149 printk(KERN_ALERT "TEST -- acpi_get_firmware_table \n");
150
151 status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
152 (struct acpi_table_header **) &ecdt_ptr);
153
154 printk(KERN_ALERT "TEST -- acpi_install_notify_handler \n");
155
156 status = acpi_install_notify_handler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, &acpi_bus_notify, NULL);
157
158 printk(KERN_ALERT "TEST -- acpi_remove_notify_handler \n");
159
160 status = acpi_remove_notify_handler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, &acpi_bus_notify);
161
162 printk(KERN_ALERT "TEST -- acpi_bus_get_device \n");
163
164 status = acpi_bus_get_device(next_child_handle, &device);
165
166 printk(KERN_ALERT "TEST -- acpi_driver_data \n");
167
168 ec = acpi_driver_data(device);
169
170 if (!ec){
171 printk(KERN_ALERT "Failure getting device data \n");
172 }
173 else {
174
175 printk(KERN_ALERT "TEST -- acpi_install_gpe_handler \n");
176 ec->status_addr = ec->command_addr;
177 status = acpi_install_gpe_handler(ec->gpe_bit, ACPI_EVENT_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec);
178/*
179 status = acpi_install_address_space_handler (ACPI_ROOT_OBJECT,
180 ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
181 &acpi_ec_space_setup, ec);
182
183 if (status) {
184 printk(KERN_ALERT "Failed installing address space handler \n");
185 }
186
187 acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
188 ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
189*/
190 printk(KERN_ALERT "TEST -- acpi_remove_gpe_handler \n");
191 acpi_remove_gpe_handler(ec->gpe_bit, &acpi_ec_gpe_handler);
192 }
193
194 printk(KERN_ALERT "TEST -- acpi_get_current_resources \n");
195 status = acpi_get_current_resources (next_child_handle, &buffer);
196
197 if (status) {
198 printk(KERN_ALERT "Failed get_current_resources %d\n",status);
199 }
200
201 printk(KERN_ALERT "TEST -- acpi_get_possible_resources \n");
202 status = acpi_get_possible_resources (next_child_handle, &buffer);
203
204 if (status) {
205 printk(KERN_ALERT "Failed get_possible_resources %d\n",status);
206 }
207
208
209 printk(KERN_ALERT "TEST -- acpi_walk_resources \n");
210 status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS,
211 acpi_ec_io_ports, ec);
212
213 if (status) {
214 printk(KERN_ALERT "Failed walk_resources %d\n",status);
215 }
216
217 printk(KERN_ALERT "TEST -- acpi_get_timer \n");
218 status = acpi_get_timer(&total_ticks);
219
220 if (status) {
221 printk(KERN_ALERT "Failed get_timer %d\n",status);
222 }
223 else {
224 printk(KERN_ALERT "get_timer -- total_ticks %d\n",total_ticks);
225 }
226
227 start_ticks = 20;
228 stop_ticks = 30;
229
230 printk(KERN_ALERT "TEST -- acpi_get_timer_duration \n");
231 status = acpi_get_timer_duration(start_ticks, stop_ticks, &total_ticks);
232
233 if (status) {
234 printk(KERN_ALERT "Failed get_timer_duration %d\n",status);
235 }
236 else {
237 printk(KERN_ALERT "get_timer_duration total_ticks %d\n",total_ticks);
238 }
239
240 for (i = 0; i < ACPI_S_STATE_COUNT; i++) {
241 printk(KERN_ALERT "TEST -- acpi_get_sleep_type_data \n");
242 status = acpi_get_sleep_type_data(i, &type_a, &type_b);
243
244 if (status) {
245 printk(KERN_ALERT "Failed get_sleep_type_data %d\n",status);
246 }
247 else {
248 printk(KERN_ALERT "get_sleep_type_data [%d] type_a:%d type_b:%d\n",i, type_a,type_b);
249 }
250 }
251
252 printk(KERN_ALERT "TEST -- acpi_get_register \n");
253 acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS,
254 &bm_status, ACPI_MTX_DO_NOT_LOCK);
255
256 if (!bm_status) {
257 printk(KERN_ALERT "Failed get_register [%d]\n",bm_status);
258 }
259 else {
260 printk(KERN_ALERT "get_register [%d] \n",bm_status);
261 }
262
263// Puts system to sleep, permenately !!!
264// status = acpi_enter_sleep_state(ACPI_STATE_S1);
265
266 printk(KERN_ALERT "TEST -- acpi_get_system_info \n");
267 status = acpi_get_system_info(&buffer);
268
269
270 if (status) {
271 printk(KERN_ALERT "Failed get_system_info %d\n",status);
272 }
273 else {
274 printk(KERN_ALERT "get_system_info buffer.length:%d buffer.pointer:%p\n",buffer.length, buffer.pointer);
275
276 acpi_os_printf("os_printf OK %d\n",status);
277
278 if (buffer.pointer) {
279 acpi_os_free(buffer.pointer);
280 }
281 }
282
283 printk(KERN_ALERT "TEST -- acpi_get_devices \n");
284 status = acpi_get_devices(NULL, ltp_get_dev_callback, "LTP0001", NULL);
285
286 if (status) {
287 printk(KERN_ALERT "Failed get_devices %d\n",status);
288 }
289
290
291// status = acpi_os_create_semaphore(1, 1, &tmp_handle);
292
293 if (status) {
294 printk(KERN_ALERT "Failed os_create_semaphore %d\n",status);
295 }
296 else {
297 printk(KERN_ALERT "os_create_semaphore OK, no deleteing %d\n",status);
298// acpi_os_delete_semaphore(tmp_handle);
299
300 }
301
302 printk(KERN_ALERT "TEST -- acpi_get_system_info \n");
303 status = acpi_get_system_info(&batt_buffer);
304
305 if (status) {
306 printk(KERN_ALERT "Failed get_system_info %d\n",status);
307 }
308 else {
309 printk(KERN_ALERT "get_system_info buffer.length:%d buffer.pointer:%p\n",buffer.length, buffer.pointer);
310
311 package = (union acpi_object *) batt_buffer.pointer;
312
313 /* Extract Package Data */
314
315 printk(KERN_ALERT "TEST -- acpi_extract_package \n");
316 status = acpi_extract_package(package, &format, &data);
317
318 data.pointer = kmalloc(data.length, GFP_KERNEL);
319
320 if (!data.pointer) {
321 printk(KERN_ALERT "Failed getting memory kalloc \n");
322 }
323 else {
324 memset(data.pointer, 0, data.length);
325
326 printk(KERN_ALERT "TEST -- acpi_extract_package \n");
327 status = acpi_extract_package(package, &format, &data);
328
329 kfree(data.pointer);
330 }
331
332// acpi_os_free(buffer.pointer);
333 }
334
335 printk(KERN_ALERT "-- IOCTL ACPI tests Complete -- Iteration:%d\n",test_iteration);
336
337 break;
338 }
339
340
341 return 0;
342}
343
344static acpi_status ltp_get_dev_callback (acpi_handle obj, u32 depth, void *context, void **ret)
345{
346 acpi_status status;
347 char *name = context;
348 char fullname[20];
349
350 /*
351 * Only SBA shows up in ACPI namespace, so its CSR space
352 * includes both SBA and IOC. Make SBA and IOC show up
353 * separately in PCI space.
354 */
355 sprintf(fullname, "%s SBA", name);
356 printk(KERN_ALERT "get_dev_callback SBA name %s \n", fullname);
357 sprintf(fullname, "%s IOC", name);
358 printk(KERN_ALERT "get_dev_callback IOC name %s \n", fullname);
359
360 return 0;
361}
362
363static int ltp_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
364{
365 return 0;
366}
367
368/**
369 * acpi_bus_notify
370 * ---------------
371 * Callback for all 'system-level' device notifications (values 0x00-0x7F).
372 */
373static void acpi_bus_notify (acpi_handle handle,
374 u32 type,
375 void *data)
376{
377
378 printk(KERN_ALERT "Register ACPI Bus Notify callback function \n");
379
380}
381
382static void acpi_ec_gpe_handler (void *data)
383{
384 printk(KERN_ALERT "Register ACPI ec_gpe_handler callback function \n");
385}
386
387static acpi_status acpi_ec_io_ports (struct acpi_resource *resource, void *context)
388{
389 return 0;
390}
391
392static acpi_status acpi_ec_space_handler (u32 function,
393 acpi_physical_address address,
394 u32 bit_width,
395 acpi_integer *value,
396 void *handler_context,
397 void *region_context)
398{
399 int result = 0;
400 struct acpi_ec *ec = NULL;
401 u32 temp = 0;
402
403 ACPI_FUNCTION_TRACE("acpi_ec_space_handler");
404
405 if ((address > 0xFF) || (bit_width != 8) || !value || !handler_context)
406 return_VALUE(AE_BAD_PARAMETER);
407
408 ec = (struct acpi_ec *) handler_context;
409
410 switch (function) {
411 case ACPI_READ:
412 result = 0;
413 *value = (acpi_integer) temp;
414 break;
415 case ACPI_WRITE:
416 result = 0;
417 break;
418 default:
419 result = -EINVAL;
420 break;
421 }
422
423 switch (result) {
424 case -EINVAL:
425 return_VALUE(AE_BAD_PARAMETER);
426 break;
427 case -ENODEV:
428 return_VALUE(AE_NOT_FOUND);
429 break;
430 case -ETIME:
431 return_VALUE(AE_TIME);
432 break;
433 default:
434 return_VALUE(AE_OK);
435 }
436
437}
438static acpi_status acpi_ec_space_setup (
439 acpi_handle region_handle,
440 u32 function,
441 void *handler_context,
442 void **return_context)
443{
444 /*
445 * The EC object is in the handler context and is needed
446 * when calling the acpi_ec_space_handler.
447 */
448 *return_context = handler_context;
449
450 return AE_OK;
451}
452
453int init_module(void)
454{
455 int result;
456
457
458
459 printk(KERN_ALERT "ltpdev_init_module \n");
460
461 ltp_pm_dev = pm_register(PM_UNKNOWN_DEV, 0, ltp_pm_callback);
462
463
464 result = register_blkdev(ltp_acpi_major, LTP_ACPI_DEV_NAME);
465
466 printk(KERN_ALERT "LTP ACPI: register_blkdev result=%d major %d\n",result, ltp_acpi_major);
467
468 if (result < 0) {
469 printk(KERN_ALERT "LTP ACPI: can't get major %d\n",ltp_acpi_major);
470 return result;
471 }
472// if (ltp_acpi_major == 0)
473// ltp_acpi_major = result; /* dynamic */
474
475 gd_ptr = kmalloc(sizeof(struct gendisk *), GFP_KERNEL);
476
477 if (!gd_ptr) {
478 printk(KERN_ALERT "ERROR getting memory !!!\n");
479 return 0;
480 }
481
482 gd_ptr = alloc_disk(1);
483
484 printk(KERN_ALERT "gd_ptr after alloc = %p \n",gd_ptr);
485
486 gd_ptr->major = ltp_acpi_major;
487 gd_ptr->first_minor = 0;
488 gd_ptr->fops = &blkops;
489 gd_ptr->minor_shift = MINOR_SHIFT_BITS;
490 gd_ptr->driverfs_dev = NULL;
491 gd_ptr->capacity = MAX_NUM_DISKS;
492 gd_ptr->disk_de = NULL;
493 gd_ptr->flags = genhd_flags;
494
495
496 sprintf(gd_ptr->disk_name, LTP_ACPI_DEV_NAME);
497
498 add_disk(gd_ptr);
499
500 return 0;
501}
502
503void cleanup_module(void)
504{
505
506 printk(KERN_ALERT "Exiting module and cleaning up \n");
507
508 pm_unregister(ltp_pm_dev);
509
510 put_disk(gd_ptr);
511
512 del_gendisk(gd_ptr);
513
514 unregister_blkdev(ltp_acpi_major, LTP_ACPI_DEV_NAME);
515
516}
517