aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/agp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/agp')
-rw-r--r--drivers/char/agp/intel-agp.c118
1 files changed, 57 insertions, 61 deletions
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 07141c914df1..fe6fc382190f 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -35,11 +35,19 @@
35#define PCI_DEVICE_ID_INTEL_IGD_HB 0x2A40 35#define PCI_DEVICE_ID_INTEL_IGD_HB 0x2A40
36#define PCI_DEVICE_ID_INTEL_IGD_IG 0x2A42 36#define PCI_DEVICE_ID_INTEL_IGD_IG 0x2A42
37 37
38/* cover 915 and 945 variants */
39#define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \
40 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || \
41 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || \
42 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB || \
43 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || \
44 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB)
45
38#define IS_I965 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82946GZ_HB || \ 46#define IS_I965 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82946GZ_HB || \
39 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82G35_HB || \ 47 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82G35_HB || \
40 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \ 48 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \
41 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \ 49 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \
42 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \ 50 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \
43 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB || \ 51 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB || \
44 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_HB) 52 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_HB)
45 53
@@ -216,7 +224,7 @@ static void intel_i810_agp_enable(struct agp_bridge_data *bridge, u32 mode)
216/* Exists to support ARGB cursors */ 224/* Exists to support ARGB cursors */
217static void *i8xx_alloc_pages(void) 225static void *i8xx_alloc_pages(void)
218{ 226{
219 struct page * page; 227 struct page *page;
220 228
221 page = alloc_pages(GFP_KERNEL | GFP_DMA32, 2); 229 page = alloc_pages(GFP_KERNEL | GFP_DMA32, 2);
222 if (page == NULL) 230 if (page == NULL)
@@ -445,7 +453,7 @@ static void intel_i830_init_gtt_entries(void)
445 static const int ddt[4] = { 0, 16, 32, 64 }; 453 static const int ddt[4] = { 0, 16, 32, 64 };
446 int size; /* reserved space (in kb) at the top of stolen memory */ 454 int size; /* reserved space (in kb) at the top of stolen memory */
447 455
448 pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl); 456 pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl);
449 457
450 if (IS_I965) { 458 if (IS_I965) {
451 u32 pgetbl_ctl; 459 u32 pgetbl_ctl;
@@ -544,26 +552,14 @@ static void intel_i830_init_gtt_entries(void)
544 break; 552 break;
545 case I915_GMCH_GMS_STOLEN_48M: 553 case I915_GMCH_GMS_STOLEN_48M:
546 /* Check it's really I915G */ 554 /* Check it's really I915G */
547 if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || 555 if (IS_I915 || IS_I965 || IS_G33)
548 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
549 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
550 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
551 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||
552 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB ||
553 IS_I965 || IS_G33)
554 gtt_entries = MB(48) - KB(size); 556 gtt_entries = MB(48) - KB(size);
555 else 557 else
556 gtt_entries = 0; 558 gtt_entries = 0;
557 break; 559 break;
558 case I915_GMCH_GMS_STOLEN_64M: 560 case I915_GMCH_GMS_STOLEN_64M:
559 /* Check it's really I915G */ 561 /* Check it's really I915G */
560 if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || 562 if (IS_I915 || IS_I965 || IS_G33)
561 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
562 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
563 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
564 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||
565 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB ||
566 IS_I965 || IS_G33)
567 gtt_entries = MB(64) - KB(size); 563 gtt_entries = MB(64) - KB(size);
568 else 564 else
569 gtt_entries = 0; 565 gtt_entries = 0;
@@ -614,9 +610,8 @@ static void intel_i830_setup_flush(void)
614 return; 610 return;
615 611
616 intel_private.i8xx_page = alloc_page(GFP_KERNEL | __GFP_ZERO | GFP_DMA32); 612 intel_private.i8xx_page = alloc_page(GFP_KERNEL | __GFP_ZERO | GFP_DMA32);
617 if (!intel_private.i8xx_page) { 613 if (!intel_private.i8xx_page)
618 return; 614 return;
619 }
620 615
621 /* make page uncached */ 616 /* make page uncached */
622 map_page_into_agp(intel_private.i8xx_page); 617 map_page_into_agp(intel_private.i8xx_page);
@@ -632,9 +627,9 @@ static void intel_i830_chipset_flush(struct agp_bridge_data *bridge)
632 unsigned int *pg = intel_private.i8xx_flush_page; 627 unsigned int *pg = intel_private.i8xx_flush_page;
633 int i; 628 int i;
634 629
635 for (i = 0; i < 256; i+=2) 630 for (i = 0; i < 256; i += 2)
636 *(pg + i) = i; 631 *(pg + i) = i;
637 632
638 wmb(); 633 wmb();
639} 634}
640 635
@@ -653,10 +648,10 @@ static int intel_i830_create_gatt_table(struct agp_bridge_data *bridge)
653 num_entries = size->num_entries; 648 num_entries = size->num_entries;
654 agp_bridge->gatt_table_real = NULL; 649 agp_bridge->gatt_table_real = NULL;
655 650
656 pci_read_config_dword(intel_private.pcidev,I810_MMADDR,&temp); 651 pci_read_config_dword(intel_private.pcidev, I810_MMADDR, &temp);
657 temp &= 0xfff80000; 652 temp &= 0xfff80000;
658 653
659 intel_private.registers = ioremap(temp,128 * 4096); 654 intel_private.registers = ioremap(temp, 128 * 4096);
660 if (!intel_private.registers) 655 if (!intel_private.registers)
661 return -ENOMEM; 656 return -ENOMEM;
662 657
@@ -696,7 +691,7 @@ static int intel_i830_fetch_size(void)
696 return values[0].size; 691 return values[0].size;
697 } 692 }
698 693
699 pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl); 694 pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl);
700 695
701 if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { 696 if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
702 agp_bridge->previous_size = agp_bridge->current_size = (void *) values; 697 agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
@@ -720,12 +715,12 @@ static int intel_i830_configure(void)
720 715
721 current_size = A_SIZE_FIX(agp_bridge->current_size); 716 current_size = A_SIZE_FIX(agp_bridge->current_size);
722 717
723 pci_read_config_dword(intel_private.pcidev,I810_GMADDR,&temp); 718 pci_read_config_dword(intel_private.pcidev, I810_GMADDR, &temp);
724 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); 719 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
725 720
726 pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl); 721 pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl);
727 gmch_ctrl |= I830_GMCH_ENABLED; 722 gmch_ctrl |= I830_GMCH_ENABLED;
728 pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl); 723 pci_write_config_word(agp_bridge->dev, I830_GMCH_CTRL, gmch_ctrl);
729 724
730 writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL); 725 writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL);
731 readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ 726 readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
@@ -748,9 +743,10 @@ static void intel_i830_cleanup(void)
748 iounmap(intel_private.registers); 743 iounmap(intel_private.registers);
749} 744}
750 745
751static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int type) 746static int intel_i830_insert_entries(struct agp_memory *mem, off_t pg_start,
747 int type)
752{ 748{
753 int i,j,num_entries; 749 int i, j, num_entries;
754 void *temp; 750 void *temp;
755 int ret = -EINVAL; 751 int ret = -EINVAL;
756 int mask_type; 752 int mask_type;
@@ -762,10 +758,10 @@ static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int
762 num_entries = A_SIZE_FIX(temp)->num_entries; 758 num_entries = A_SIZE_FIX(temp)->num_entries;
763 759
764 if (pg_start < intel_private.gtt_entries) { 760 if (pg_start < intel_private.gtt_entries) {
765 printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n", 761 printk(KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n",
766 pg_start,intel_private.gtt_entries); 762 pg_start, intel_private.gtt_entries);
767 763
768 printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n"); 764 printk(KERN_INFO PFX "Trying to insert into local/stolen memory\n");
769 goto out_err; 765 goto out_err;
770 } 766 }
771 767
@@ -803,8 +799,8 @@ out_err:
803 return ret; 799 return ret;
804} 800}
805 801
806static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start, 802static int intel_i830_remove_entries(struct agp_memory *mem, off_t pg_start,
807 int type) 803 int type)
808{ 804{
809 int i; 805 int i;
810 806
@@ -812,7 +808,7 @@ static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
812 return 0; 808 return 0;
813 809
814 if (pg_start < intel_private.gtt_entries) { 810 if (pg_start < intel_private.gtt_entries) {
815 printk (KERN_INFO PFX "Trying to disable local/stolen memory\n"); 811 printk(KERN_INFO PFX "Trying to disable local/stolen memory\n");
816 return -EINVAL; 812 return -EINVAL;
817 } 813 }
818 814
@@ -825,7 +821,7 @@ static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
825 return 0; 821 return 0;
826} 822}
827 823
828static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type) 824static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count, int type)
829{ 825{
830 if (type == AGP_PHYS_MEMORY) 826 if (type == AGP_PHYS_MEMORY)
831 return alloc_agpphysmem_i8xx(pg_count, type); 827 return alloc_agpphysmem_i8xx(pg_count, type);
@@ -884,7 +880,7 @@ static void intel_i965_g33_setup_chipset_flush(void)
884 pci_write_config_dword(agp_bridge->dev, I965_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1); 880 pci_write_config_dword(agp_bridge->dev, I965_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1);
885 } else { 881 } else {
886 u64 l64; 882 u64 l64;
887 883
888 temp_lo &= ~0x1; 884 temp_lo &= ~0x1;
889 l64 = ((u64)temp_hi << 32) | temp_lo; 885 l64 = ((u64)temp_hi << 32) | temp_lo;
890 886
@@ -918,7 +914,7 @@ static void intel_i9xx_setup_flush(void)
918 if (intel_private.ifp_resource.start) { 914 if (intel_private.ifp_resource.start) {
919 intel_private.i9xx_flush_page = ioremap_nocache(intel_private.ifp_resource.start, PAGE_SIZE); 915 intel_private.i9xx_flush_page = ioremap_nocache(intel_private.ifp_resource.start, PAGE_SIZE);
920 if (!intel_private.i9xx_flush_page) 916 if (!intel_private.i9xx_flush_page)
921 printk("unable to ioremap flush page - no chipset flushing"); 917 printk(KERN_INFO "unable to ioremap flush page - no chipset flushing");
922 } 918 }
923} 919}
924 920
@@ -935,9 +931,9 @@ static int intel_i915_configure(void)
935 931
936 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); 932 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
937 933
938 pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl); 934 pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl);
939 gmch_ctrl |= I830_GMCH_ENABLED; 935 gmch_ctrl |= I830_GMCH_ENABLED;
940 pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl); 936 pci_write_config_word(agp_bridge->dev, I830_GMCH_CTRL, gmch_ctrl);
941 937
942 writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL); 938 writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL);
943 readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ 939 readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
@@ -952,7 +948,7 @@ static int intel_i915_configure(void)
952 global_cache_flush(); 948 global_cache_flush();
953 949
954 intel_i9xx_setup_flush(); 950 intel_i9xx_setup_flush();
955 951
956 return 0; 952 return 0;
957} 953}
958 954
@@ -974,10 +970,10 @@ static void intel_i915_chipset_flush(struct agp_bridge_data *bridge)
974 writel(1, intel_private.i9xx_flush_page); 970 writel(1, intel_private.i9xx_flush_page);
975} 971}
976 972
977static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start, 973static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start,
978 int type) 974 int type)
979{ 975{
980 int i,j,num_entries; 976 int i, j, num_entries;
981 void *temp; 977 void *temp;
982 int ret = -EINVAL; 978 int ret = -EINVAL;
983 int mask_type; 979 int mask_type;
@@ -989,10 +985,10 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
989 num_entries = A_SIZE_FIX(temp)->num_entries; 985 num_entries = A_SIZE_FIX(temp)->num_entries;
990 986
991 if (pg_start < intel_private.gtt_entries) { 987 if (pg_start < intel_private.gtt_entries) {
992 printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n", 988 printk(KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n",
993 pg_start,intel_private.gtt_entries); 989 pg_start, intel_private.gtt_entries);
994 990
995 printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n"); 991 printk(KERN_INFO PFX "Trying to insert into local/stolen memory\n");
996 goto out_err; 992 goto out_err;
997 } 993 }
998 994
@@ -1030,8 +1026,8 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
1030 return ret; 1026 return ret;
1031} 1027}
1032 1028
1033static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start, 1029static int intel_i915_remove_entries(struct agp_memory *mem, off_t pg_start,
1034 int type) 1030 int type)
1035{ 1031{
1036 int i; 1032 int i;
1037 1033
@@ -1039,13 +1035,13 @@ static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start,
1039 return 0; 1035 return 0;
1040 1036
1041 if (pg_start < intel_private.gtt_entries) { 1037 if (pg_start < intel_private.gtt_entries) {
1042 printk (KERN_INFO PFX "Trying to disable local/stolen memory\n"); 1038 printk(KERN_INFO PFX "Trying to disable local/stolen memory\n");
1043 return -EINVAL; 1039 return -EINVAL;
1044 } 1040 }
1045 1041
1046 for (i = pg_start; i < (mem->page_count + pg_start); i++) { 1042 for (i = pg_start; i < (mem->page_count + pg_start); i++)
1047 writel(agp_bridge->scratch_page, intel_private.gtt+i); 1043 writel(agp_bridge->scratch_page, intel_private.gtt+i);
1048 } 1044
1049 readl(intel_private.gtt+i-1); 1045 readl(intel_private.gtt+i-1);
1050 1046
1051 agp_bridge->driver->tlb_flush(mem); 1047 agp_bridge->driver->tlb_flush(mem);
@@ -1092,7 +1088,7 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
1092 agp_bridge->gatt_table_real = NULL; 1088 agp_bridge->gatt_table_real = NULL;
1093 1089
1094 pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); 1090 pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp);
1095 pci_read_config_dword(intel_private.pcidev, I915_PTEADDR,&temp2); 1091 pci_read_config_dword(intel_private.pcidev, I915_PTEADDR, &temp2);
1096 1092
1097 if (IS_G33) 1093 if (IS_G33)
1098 gtt_map_size = 1024 * 1024; /* 1M on G33 */ 1094 gtt_map_size = 1024 * 1024; /* 1M on G33 */
@@ -1102,7 +1098,7 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
1102 1098
1103 temp &= 0xfff80000; 1099 temp &= 0xfff80000;
1104 1100
1105 intel_private.registers = ioremap(temp,128 * 4096); 1101 intel_private.registers = ioremap(temp, 128 * 4096);
1106 if (!intel_private.registers) { 1102 if (!intel_private.registers) {
1107 iounmap(intel_private.gtt); 1103 iounmap(intel_private.gtt);
1108 return -ENOMEM; 1104 return -ENOMEM;
@@ -1329,7 +1325,7 @@ static int intel_815_configure(void)
1329 /* the Intel 815 chipset spec. says that bits 29-31 in the 1325 /* the Intel 815 chipset spec. says that bits 29-31 in the
1330 * ATTBASE register are reserved -> try not to write them */ 1326 * ATTBASE register are reserved -> try not to write them */
1331 if (agp_bridge->gatt_bus_addr & INTEL_815_ATTBASE_MASK) { 1327 if (agp_bridge->gatt_bus_addr & INTEL_815_ATTBASE_MASK) {
1332 printk (KERN_EMERG PFX "gatt bus addr too high"); 1328 printk(KERN_EMERG PFX "gatt bus addr too high");
1333 return -EINVAL; 1329 return -EINVAL;
1334 } 1330 }
1335 1331
@@ -1986,7 +1982,7 @@ static int find_gmch(u16 device)
1986 gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL); 1982 gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
1987 if (gmch_device && PCI_FUNC(gmch_device->devfn) != 0) { 1983 if (gmch_device && PCI_FUNC(gmch_device->devfn) != 0) {
1988 gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, 1984 gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL,
1989 device, gmch_device); 1985 device, gmch_device);
1990 } 1986 }
1991 1987
1992 if (!gmch_device) 1988 if (!gmch_device)
@@ -2108,7 +2104,7 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
2108 if (intel_agp_chipsets[i].name == NULL) { 2104 if (intel_agp_chipsets[i].name == NULL) {
2109 if (cap_ptr) 2105 if (cap_ptr)
2110 printk(KERN_WARNING PFX "Unsupported Intel chipset" 2106 printk(KERN_WARNING PFX "Unsupported Intel chipset"
2111 "(device id: %04x)\n", pdev->device); 2107 "(device id: %04x)\n", pdev->device);
2112 agp_put_bridge(bridge); 2108 agp_put_bridge(bridge);
2113 return -ENODEV; 2109 return -ENODEV;
2114 } 2110 }
@@ -2121,7 +2117,7 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
2121 intel_agp_chipsets[i].gmch_chip_id); 2117 intel_agp_chipsets[i].gmch_chip_id);
2122 agp_put_bridge(bridge); 2118 agp_put_bridge(bridge);
2123 return -ENODEV; 2119 return -ENODEV;
2124 } 2120 }
2125 2121
2126 bridge->dev = pdev; 2122 bridge->dev = pdev;
2127 bridge->capndx = cap_ptr; 2123 bridge->capndx = cap_ptr;