1 /* 2 * 3 * Copyright (c) International Business Machines Corp., 2001 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 /* 21 * This example module shows how a test driver 22 * can be driven through various ioctl calls in 23 * a user space program that has attained the 24 * appropriate file descriptor for this device. 25 * 26 * author: Kai Zhao 27 * date: 08/25/2003 28 * 29 * module: tagp 30 */ 31 32 #include <linux/types.h> 33 #include <linux/kernel.h> 34 #include <linux/fs.h> 35 #include <linux/ioctl.h> 36 #include <linux/module.h> 37 #include <linux/init.h> 38 #include <asm/uaccess.h> 39 40 #include <linux/pci.h> 41 #include <linux/agp_backend.h> 42 #include <linux/gfp.h> 43 #include <linux/page-flags.h> 44 #include <linux/mm.h> 45 46 //#include "agp.h" 47 48 #include "tagp.h" 49 #include "str_agp.h" 50 51 MODULE_AUTHOR("kai zhao <ltcd3 (at) cn.ibm.com>"); 52 MODULE_DESCRIPTION(tagp_DRIVER_NAME); 53 MODULE_LICENSE("GPL"); 54 55 static int tagp_ioctl(struct inode *, struct file *, unsigned int, 56 unsigned long); 57 static int tagp_open(struct inode *, struct file *); 58 static int tagp_close(struct inode *, struct file *); 59 60 static int test_pci_find_device(void); 61 static int test_agp_backend_acquire(void); 62 static int test_agp_backend_release(void); 63 static int test_agp_alloc_bridge(void); 64 static int test_agp_put_bridge(void); 65 static int test_agp_create_and_free_memory(void); 66 //static int test_agp_free_memory(void); 67 static int test_agp_num_entries(void); 68 static int test_agp_copy_info(void); 69 //static int test_agp_allocate_memory(void); 70 static int test_get_agp_version(void); 71 static int test_agp_generic_enable(void); 72 static int test_agp_generic_create_gatt_table(void); 73 static int test_agp_generic_free_gatt_table(void); 74 static int test_agp_generic_insert_memory(void); 75 static int test_agp_generic_alloc_by_type(void); 76 static int test_agp_generic_alloc_page(void); 77 //static int test_agp_generic_destroy_page(void); 78 static int test_agp_enable(void); 79 static int test_global_cache_flush(void); 80 static int test_agp_generic_mask_memory(void); 81 82 static int Major = TAGP_MAJOR; 83 //static ltpmod_user_t ltp_mod; 84 85 /* 86 * File operations struct, to use operations find the 87 * correct file descriptor 88 */ 89 static struct file_operations tagp_fops = { 90 open: tagp_open, 91 release:tagp_close, 92 ioctl: tagp_ioctl, 93 }; 94 95 /* 96 * open and close operations, just return 0 for 97 * your test modules, need them for the file 98 * operations structure 99 */ 100 static int tagp_open(struct inode *ino, struct file *f) 101 { 102 return 0; 103 } 104 105 static int tagp_close(struct inode *ino, struct file *f) 106 { 107 return 0; 108 } 109 110 /* 111 * tagp_ioctl: 112 * a user space program can drive the test functions 113 * through a call to ioctl once the correct file 114 * descriptor has been attained 115 * 116 * in user space the file descriptor that you attain 117 * will represent the inode and file pointers in 118 * the kernel ioctl function, and only 3 variables 119 * will be passed in, linux/ioctl.h should be 120 * included 121 * 122 */ 123 static int tagp_ioctl(struct inode *ino, struct file *f, 124 unsigned int cmd, unsigned long l) 125 { 126 int rc; 127 tagp_interface_t tif; 128 caddr_t *inparms; 129 caddr_t *outparms; 130 131 printk("Enter tagp_ioctl\n"); 132 133 inparms = NULL; 134 outparms = NULL; 135 rc = 0; 136 137 /* 138 * the following calls are used to setup the 139 * parameters that might need to be passed 140 * between user and kernel space, using the tif 141 * pointer that is passed in as the last 142 * parameter to the ioctl 143 * 144 */ 145 if (copy_from_user(&tif, (void *)l, sizeof(tif))) { 146 /* Bad address */ 147 return (-EFAULT); 148 } 149 150 /* 151 * Setup inparms and outparms as needed 152 */ 153 if (tif.in_len > 0) { 154 inparms = (caddr_t *) kmalloc(tif.in_len, GFP_KERNEL); 155 if (!inparms) { 156 return (-ENOMEM); 157 } 158 159 rc = copy_from_user(inparms, tif.in_data, tif.in_len); 160 if (rc) { 161 kfree(inparms); 162 return (-EFAULT); 163 } 164 } 165 if (tif.out_len > 0) { 166 outparms = (caddr_t *) kmalloc(tif.out_len, GFP_KERNEL); 167 if (!outparms) { 168 kfree(inparms); 169 return (-ENOMEM); 170 } 171 } 172 173 /* 174 * Use a switch statement to determine which function 175 * to call, based on the cmd flag that is specified 176 * in user space. Pass in inparms or outparms as 177 * needed 178 * 179 */ 180 switch (cmd) { 181 case TEST_PCI_FIND_DEV: 182 rc = test_pci_find_device(); 183 break; 184 case TEST_BACKEND_ACQUIRE: 185 rc = test_agp_backend_acquire(); 186 break; 187 case TEST_BACKEND_RELEASE: 188 rc = test_agp_backend_release(); 189 break; 190 case TEST_ALLOC_BRIDGE: 191 rc = test_agp_alloc_bridge(); 192 break; 193 case TEST_PUT_BRIDGE: 194 rc = test_agp_put_bridge(); 195 break; 196 case TEST_CREATE_AND_FREE_MEMORY: 197 rc = test_agp_create_and_free_memory(); 198 break; 199 // case TEST_FREE_MEMORY: rc = test_agp_free_memory();break; 200 case TEST_NUM_ENTRIES: 201 rc = test_agp_num_entries(); 202 break; 203 case TEST_COPY_INFO: 204 rc = test_agp_copy_info(); 205 break; 206 // case TEST_ALLOC_MEMORY_AND_BAND_UNBAND: rc = test_agp_allocate_memory();break; 207 case TEST_GET_VERSION: 208 rc = test_get_agp_version(); 209 break; 210 case TEST_GENERIC_ENABLE: 211 rc = test_agp_generic_enable(); 212 break; 213 case TEST_GENERIC_CREATE_GATT_TABLE: 214 rc = test_agp_generic_create_gatt_table(); 215 break; 216 case TEST_GENERIC_FREE_GATT_TABLE: 217 rc = test_agp_generic_free_gatt_table(); 218 break; 219 case TEST_GENERIC_INSERT_MEMROY: 220 rc = test_agp_generic_insert_memory(); 221 break; 222 case TEST_GENERIC_ALLOC_BY_TYPE: 223 rc = test_agp_generic_alloc_by_type(); 224 break; 225 case TEST_GENERIC_ALLOC_PAGE: 226 rc = test_agp_generic_alloc_page(); 227 break; 228 case TEST_ENABLE: 229 rc = test_agp_enable(); 230 break; 231 case TEST_GLOBAL_CACHE_FLUSH: 232 rc = test_global_cache_flush(); 233 break; 234 case TEST_GENERIC_MASK_MEMORY: 235 rc = test_agp_generic_mask_memory(); 236 break; 237 238 default: 239 printk("Mismatching ioctl command\n"); 240 break; 241 } 242 243 /* 244 * copy in the test return code, the reason we 245 * this is so that in user space we can tell the 246 * difference between an error in one of our test 247 * calls or an error in the ioctl function 248 */ 249 tif.out_rc = rc; 250 rc = 0; 251 252 /* 253 * setup the rest of tif pointer for returning to 254 * to user space, using copy_to_user if needed 255 */ 256 257 /* if outparms then copy outparms into tif.out_data */ 258 if (outparms) { 259 if (copy_to_user(tif.out_data, outparms, tif.out_len)) { 260 printk("tpci: Unsuccessful copy_to_user of outparms\n"); 261 rc = -EFAULT; 262 } 263 } 264 265 /* copy tif structure into l so that can be used by user program */ 266 if (copy_to_user((void *)l, &tif, sizeof(tif))) { 267 printk("tpci: Unsuccessful copy_to_user of tif\n"); 268 rc = -EFAULT; 269 } 270 271 /* 272 * free inparms and outparms 273 */ 274 if (inparms) { 275 kfree(inparms); 276 } 277 if (outparms) { 278 kfree(outparms); 279 } 280 281 return rc; 282 } 283 284 /* 285 * Function and structure needed by agp_bridge. 286 */ 287 288 static struct aper_size_info_fixed test_core_agp_sizes[] = { 289 {0, 0, 0}, 290 }; 291 292 static int test_fetch_size(void) 293 { 294 printk("<1> tagp : Enter test fetch size\n"); 295 return 0; 296 297 } 298 299 static int test_configure(void) 300 { 301 /* Do not config test_core_agp_size */ 302 printk("<1> tagp : Enter test configure\n"); 303 return 0; 304 } 305 306 static void test_cleanup(void) 307 { 308 printk("<1> tagp : Enter test_cleanup\n"); 309 return; 310 } 311 312 static void test_tlbflush(struct agp_memory *temp) 313 { 314 printk("<1> tagp : Enter test tlbflush\n"); 315 return; 316 } 317 318 /* 319 * structure used by agp_bridge 320 */ 321 struct agp_bridge_driver test_driver = { 322 .owner = THIS_MODULE, 323 .aperture_sizes = test_core_agp_sizes, 324 .size_type = U8_APER_SIZE, 325 .num_aperture_sizes = 7, 326 .configure = test_configure, 327 .fetch_size = test_fetch_size, 328 .cleanup = test_cleanup, 329 .tlb_flush = test_tlbflush, 330 .mask_memory = agp_generic_mask_memory, 331 .masks = NULL, 332 .agp_enable = agp_generic_enable, 333 .cache_flush = global_cache_flush, 334 .create_gatt_table = agp_generic_create_gatt_table, 335 .free_gatt_table = agp_generic_free_gatt_table, 336 .insert_memory = agp_generic_insert_memory, 337 .remove_memory = agp_generic_remove_memory, 338 .alloc_by_type = agp_generic_alloc_by_type, 339 .free_by_type = agp_generic_free_by_type, 340 .agp_alloc_page = agp_generic_alloc_page, 341 .agp_destroy_page = agp_generic_destroy_page, 342 }; 343 344 /* 345 * test functions can go here or in a seperate file, 346 * remember that the makefile will have to be modified 347 * as well as the header file will need the function 348 * prototypes if the test calls go in another file 349 * 350 * functions should be static so that they may not 351 * be called by outside functions, in the kernel 352 * if a function is non_static and the symbol is 353 * exported using EXPORT_SYMBOL(function_name) 354 * then other parts of the kernel such as modules 355 * may use that function 356 * 357 */ 358 359 static int test_agp_backend_acquire(void) 360 { 361 printk("<1> tagp : Enter test_agp_backend_acquire\n"); 362 agp_backend_acquire(); 363 return 0; 364 } 365 366 static int test_agp_backend_release(void) 367 { 368 printk("<1> tagp : Enter test_agp_backend_release\n"); 369 agp_backend_release(); 370 return 0; 371 } 372 373 static int test_agp_alloc_bridge(void) 374 { 375 // struct agp_bridge_data *tmp_bridge; 376 tmp_bridge = agp_alloc_bridge(); 377 // agp_put_bridge (tmp_bridge); 378 // tmp_bridge = NULL; 379 return 0; 380 } 381 382 static int test_agp_put_bridge(void) 383 { 384 agp_put_bridge(tmp_bridge); 385 tmp_bridge = NULL; 386 return 0; 387 } 388 389 static int test_agp_create_and_free_memory(void) 390 { 391 struct agp_memory *tmp_agp_memory = NULL; 392 /* int scratch_pages */ 393 if (agp_bridge->scratch_page > 0) { 394 printk("<1> tagp : agp_bridge->scratch_page : %ld\n", 395 agp_bridge->scratch_page); 396 tmp_agp_memory = agp_create_memory(agp_bridge->scratch_page); 397 } else { 398 printk("<1> tagp : agp_bridge->scratch_page : %ld\n", 399 agp_bridge->scratch_page); 400 tmp_agp_memory = agp_create_memory(64); 401 } 402 if (tmp_agp_memory != NULL) { 403 agp_free_memory(tmp_agp_memory); 404 return 0; 405 } 406 return 1; 407 } 408 409 /* 410 static int test_agp_free_memory(void) 411 { 412 if (tmp_agp_memory != NULL) 413 { 414 agp_free_memory(tmp_agp_memory); 415 return 0; 416 } 417 return 1; 418 } 419 */ 420 static int test_agp_num_entries(void) 421 { 422 int ret = agp_num_entries(); 423 printk("<1> tagp : agp_num_entries return %d\n", ret); 424 return 0; 425 } 426 427 //////////////////////////////////////////////////////////////////////////// 428 static int test_agp_copy_info(void) 429 { 430 struct agp_kern_info *info; 431 int ret; 432 433 info = 434 (struct agp_kern_info *)kmalloc(sizeof(struct agp_kern_info), 435 GFP_KERNEL); 436 if (!info) { 437 printk("<1> tagp : can not alloc spece\n"); 438 return 1; 439 } 440 ret = agp_copy_info(info); 441 if (ret) { 442 printk("<1> tagp : agp_copy_info failed\n"); 443 return 1; 444 } 445 kfree(info); 446 447 return 0; 448 } 449 450 /* 451 static int test_agp_allocate_memory(void) 452 { 453 struct agp_memory * local_agp_memory = NULL; 454 int ret = 0 , i = 0; 455 456 local_agp_memory = agp_allocate_memory(8,AGP_NORMAL_MEMORY); 457 458 if (local_agp_memory == NULL) 459 { 460 printk("<1> tagp : agp_allocate_memory failed\n"); 461 return 1; 462 } 463 464 ret = agp_bind_memory(local_agp_memory, 64); 465 if (ret) 466 { 467 agp_free_memory(local_agp_memory); 468 printk("<1> tagp : agp bind memory failed\n"); 469 return 1; 470 } 471 printk("<1> tagp : agp bind memory success\n"); 472 ret = agp_unbind_memory(local_agp_memory); 473 if (ret) 474 { 475 agp_free_memory(local_agp_memory); 476 printk("<1> tagp : agp unband memory failed\n"); 477 } 478 479 for (i = 0; i < 8; i++) { 480 phys_to_virt(local_agp_memory->memory[i]);//virt_to_phys(addr); 481 local_agp_memory->page_count--; 482 } 483 484 agp_free_memory(local_agp_memory); 485 printk("<1> tagp : agp unband memory success\n"); 486 487 return 0; 488 } 489 */ 490 static int test_get_agp_version(void) 491 { 492 printk("<1> tagp : Enter test_get_agp_version\n"); 493 get_agp_version(agp_bridge); 494 return 0; 495 } 496 497 static int test_agp_generic_enable(void) 498 { 499 printk("<1> tagp : Enter test_agp_generic_enable\n"); 500 agp_generic_enable(agp_bridge->mode); 501 return 0; 502 } 503 504 static int test_agp_generic_create_gatt_table(void) 505 { 506 printk("<1> tagp : Enter test_agp_generic_create_gatt_table\n"); 507 return agp_generic_create_gatt_table(); 508 } 509 510 static int test_agp_generic_free_gatt_table(void) 511 { 512 printk("<1> tagp : Enter test_agp_generic_free_gatt_table\n"); 513 return agp_generic_free_gatt_table(); 514 } 515 516 static int test_agp_generic_insert_memory(void) 517 { 518 struct agp_memory *tmp_agp_memory = NULL; 519 /* int scratch_pages */ 520 if (agp_bridge->scratch_page > 0) 521 tmp_agp_memory = agp_create_memory(agp_bridge->scratch_page); 522 else 523 tmp_agp_memory = agp_create_memory(64); 524 if (tmp_agp_memory != NULL) { 525 if (agp_generic_insert_memory(tmp_agp_memory, 16, 0)) { 526 printk("<1> tagp : agp_generic_insert_memory failed\n"); 527 agp_free_memory(tmp_agp_memory); 528 return 1; 529 } else { 530 printk 531 ("<1> tagp : agp_generic_insert_memory success\n"); 532 agp_generic_remove_memory(tmp_agp_memory, 16, 0); 533 agp_free_memory(tmp_agp_memory); 534 } 535 } 536 return 0; 537 } 538 539 static int test_agp_generic_alloc_by_type(void) 540 { 541 /* size_t page_count, int type */ 542 agp_generic_alloc_by_type(0, 0); 543 return 0; 544 } 545 546 static int test_agp_generic_alloc_page(void) 547 { 548 printk("<1> tagp : Enter test_agp_generic_alloc_page\n"); 549 void *ppage = agp_generic_alloc_page(); 550 if (ppage != NULL) 551 agp_generic_destroy_page(ppage); 552 return 0; 553 } 554 555 static int test_agp_enable(void) 556 { 557 printk("<1> tagp : Enter test_agp_enable\n"); 558 agp_enable(agp_bridge->mode); 559 return 0; 560 } 561 562 static int test_global_cache_flush(void) 563 { 564 printk("<1> tagp : Enter test_global_cache_flush\n"); 565 global_cache_flush(); 566 return 0; 567 } 568 569 static int test_agp_generic_mask_memory(void) 570 { 571 printk("<1> tagp : Enter test_agp_generic_mask_memory\n"); 572 unsigned long temp; 573 temp = agp_generic_mask_memory(1000, agp_bridge->type); 574 return 0; 575 } 576 577 static int test_pci_find_device() 578 { 579 struct pci_dev *pdev; // = (struct pci_dev *)kmalloc(sizeof(struct pci_dev), GFP_KERNEL); 580 struct agp_bridge_data *bridge = NULL; 581 582 pdev = pci_find_device(PCI_VENDOR_ID_ATI, PCI_ANY_ID, NULL); 583 584 if (pdev) { 585 printk("<1> tagp : pci find device success\n"); 586 587 u8 cap_ptr; 588 589 cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); 590 if (!cap_ptr) { 591 printk("<1> tagp : pci find capability Failed\n"); 592 return -ENODEV; 593 } 594 595 printk("<1> tagp : pci find capability success \n"); 596 bridge = agp_alloc_bridge(); 597 if (!bridge) { 598 printk("<1> tagp : agp alloc bridge Failed\n"); 599 return -ENOMEM; 600 } 601 printk("<1> tagp : agp alloc bridge success\n"); 602 bridge->driver = &test_driver; 603 bridge->dev = pdev; 604 bridge->capndx = cap_ptr; 605 606 /* Fill in the mode register */ 607 pci_read_config_dword(pdev, 608 bridge->capndx + PCI_AGP_STATUS, 609 &bridge->mode); 610 printk("<1> tagp : agp read config dword success\n"); 611 pci_set_drvdata(pdev, bridge); 612 printk("<1> tagp : agp set drvdata success\n"); 613 return agp_add_bridge(bridge); 614 } 615 616 return 1; 617 } 618 619 static int __init agp_test_probe(struct pci_dev *pdev, 620 const struct pci_device_id *ent) 621 { 622 623 printk("<1> tagp :Enter agp test probe\n"); 624 return 0; 625 626 } 627 628 static void __devexit agp_test_remove(struct pci_dev *pdev) 629 { 630 printk("<1> tagp: Enter agp test remove\n"); 631 struct agp_bridge_data *bridge = pci_get_drvdata(pdev); 632 633 agp_remove_bridge(bridge); 634 agp_put_bridge(bridge); 635 } 636 637 static struct pci_device_id agp_test_pci_table[] __initdata = { 638 { 639 .class = (PCI_CLASS_BRIDGE_HOST << 8), 640 .class_mask = ~0, 641 .vendor = PCI_ANY_ID, //VENDOR_ID_ATI, 642 .device = PCI_ANY_ID, 643 .subvendor = PCI_ANY_ID, 644 .subdevice = PCI_ANY_ID, 645 }, 646 {} 647 }; 648 649 MODULE_DEVICE_TABLE(pci, agp_test_pci_table); 650 651 static struct pci_driver agp_test_pci_driver = { 652 .name = "agp_test", 653 .id_table = agp_test_pci_table, 654 .probe = agp_test_probe, 655 .remove = agp_test_remove, 656 }; 657 658 /* 659 * tagp_init_module 660 * set the owner of tagp_fops, register the module 661 * as a char device, and perform any necessary 662 * initialization for pci devices 663 */ 664 static int __init tagp_init_module(void) 665 { 666 int rc; 667 668 // SET_MODULE_OWNER(&tagp_fops); 669 tagp_fops.owner = THIS_MODULE; 670 671 rc = register_chrdev(Major, DEVICE_NAME, &tagp_fops); 672 if (rc < 0) { 673 printk("tagp: Failed to register device.\n"); 674 return rc; 675 } 676 677 if (Major == 0) 678 Major = rc; 679 680 rc = pci_module_init(&agp_test_pci_driver); 681 682 if (rc < 0) { 683 printk("tagp: pci_module_init failed.\n"); 684 return rc; 685 } 686 687 printk("tagp: PCI module init success.\n"); 688 printk("tagp: Registration success.\n"); 689 690 return 0; 691 } 692 693 /* 694 * tagp_exit_module 695 * unregister the device and any necessary 696 * operations to close devices 697 */ 698 static void __exit tagp_exit_module(void) 699 { 700 int rc; 701 702 /* free any pointers still allocated, using kfree */ 703 rc = unregister_chrdev(Major, DEVICE_NAME); 704 if (rc < 0) 705 printk("tagp: unregister failed\n"); 706 else 707 printk("tagp: unregister success\n"); 708 709 pci_unregister_driver(&agp_test_pci_driver); 710 } 711 712 /* specify what that init is run when the module is first 713 loaded and that exit is run when it is removed */ 714 715 module_init(tagp_init_module) 716 module_exit(tagp_exit_module) 717