patch-2.4.0-test6 linux/drivers/char/agp/agpgart_be.c

Next file: linux/drivers/char/bttv-cards.c
Previous file: linux/drivers/char/agp/agp.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test5/linux/drivers/char/agp/agpgart_be.c linux/drivers/char/agp/agpgart_be.c
@@ -108,6 +108,9 @@
 
 int agp_backend_acquire(void)
 {
+	if (agp_bridge.type == NOT_SUPPORTED) {
+		return -EINVAL;
+	}
 	atomic_inc(&agp_bridge.agp_in_use);
 
 	if (atomic_read(&agp_bridge.agp_in_use) != 1) {
@@ -120,6 +123,9 @@
 
 void agp_backend_release(void)
 {
+	if (agp_bridge.type == NOT_SUPPORTED) {
+		return;
+	}
 	atomic_dec(&agp_bridge.agp_in_use);
 	MOD_DEC_USE_COUNT;
 }
@@ -141,8 +147,8 @@
 	if (pt == NULL) {
 		return 0;
 	}
-	atomic_inc(&mem_map[MAP_NR(pt)].count);
-	set_bit(PG_locked, &mem_map[MAP_NR(pt)].flags);
+	atomic_inc(&virt_to_page(pt)->count);
+	set_bit(PG_locked, &virt_to_page(pt)->flags);
 	atomic_inc(&agp_bridge.current_memory_agp);
 	return (unsigned long) pt;
 }
@@ -154,9 +160,9 @@
 	if (pt == NULL) {
 		return;
 	}
-	atomic_dec(&mem_map[MAP_NR(pt)].count);
-	clear_bit(PG_locked, &mem_map[MAP_NR(pt)].flags);
-	wake_up(&mem_map[MAP_NR(pt)].wait);
+	atomic_dec(&virt_to_page(pt)->count);
+	clear_bit(PG_locked, &virt_to_page(pt)->flags);
+	wake_up(&virt_to_page(pt)->wait);
 	free_page((unsigned long) pt);
 	atomic_dec(&agp_bridge.current_memory_agp);
 }
@@ -224,7 +230,7 @@
 {
 	int i;
 
-	if (curr == NULL) {
+	if ((agp_bridge.type == NOT_SUPPORTED) || (curr == NULL)) {
 		return;
 	}
 	if (curr->is_bound == TRUE) {
@@ -255,6 +261,9 @@
 	agp_memory *new;
 	int i;
 
+	if (agp_bridge.type == NOT_SUPPORTED) {
+		return NULL;
+	}
 	if ((atomic_read(&agp_bridge.current_memory_agp) + page_count) >
 	    agp_bridge.max_memory_agp) {
 		return NULL;
@@ -334,6 +343,10 @@
 void agp_copy_info(agp_kern_info * info)
 {
 	memset(info, 0, sizeof(agp_kern_info));
+	if (agp_bridge.type == NOT_SUPPORTED) {
+		info->chipset = agp_bridge.type;
+		return;
+	}
 	info->version.major = agp_bridge.version->major;
 	info->version.minor = agp_bridge.version->minor;
 	info->device = agp_bridge.dev;
@@ -357,7 +370,8 @@
 {
 	int ret_val;
 
-	if ((curr == NULL) || (curr->is_bound == TRUE)) {
+	if ((agp_bridge.type == NOT_SUPPORTED) ||
+	    (curr == NULL) || (curr->is_bound == TRUE)) {
 		return -EINVAL;
 	}
 	if (curr->is_flushed == FALSE) {
@@ -378,7 +392,7 @@
 {
 	int ret_val;
 
-	if (curr == NULL) {
+	if ((agp_bridge.type == NOT_SUPPORTED) || (curr == NULL)) {
 		return -EINVAL;
 	}
 	if (curr->is_bound != TRUE) {
@@ -541,6 +555,7 @@
 	int num_entries;
 	int i;
 	void *temp;
+	struct page *page;
 
 	/* The generic routines can't handle 2 level gatt's */
 	if (agp_bridge.size_type == LVL2_APER_SIZE) {
@@ -622,9 +637,8 @@
 	}
 	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
 
-	for (i = MAP_NR(table); i < MAP_NR(table_end); i++) {
-		set_bit(PG_reserved, &mem_map[i].flags);
-	}
+	for (page = virt_to_page(table); page < virt_to_page(table_end); page++)
+		set_bit(PG_reserved, &page->flags);
 
 	agp_bridge.gatt_table_real = (unsigned long *) table;
 	CACHE_FLUSH();
@@ -633,9 +647,8 @@
 	CACHE_FLUSH();
 
 	if (agp_bridge.gatt_table == NULL) {
-		for (i = MAP_NR(table); i < MAP_NR(table_end); i++) {
-			clear_bit(PG_reserved, &mem_map[i].flags);
-		}
+		for (page = virt_to_page(table); page < virt_to_page(table_end); page++)
+			clear_bit(PG_reserved, &page->flags);
 
 		free_pages((unsigned long) table, page_order);
 
@@ -653,10 +666,10 @@
 
 static int agp_generic_free_gatt_table(void)
 {
-	int i;
 	int page_order;
 	char *table, *table_end;
 	void *temp;
+	struct page *page;
 
 	temp = agp_bridge.current_size;
 
@@ -691,9 +704,8 @@
 	table = (char *) agp_bridge.gatt_table_real;
 	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
 
-	for (i = MAP_NR(table); i < MAP_NR(table_end); i++) {
-		clear_bit(PG_reserved, &mem_map[i].flags);
-	}
+	for (page = virt_to_page(table); page < virt_to_page(table_end); page++)
+		clear_bit(PG_reserved, &page->flags);
 
 	free_pages((unsigned long) agp_bridge.gatt_table_real, page_order);
 	return 0;
@@ -791,6 +803,7 @@
 
 void agp_enable(u32 mode)
 {
+	if (agp_bridge.type == NOT_SUPPORTED) return;
 	agp_bridge.agp_enable(mode);
 }
 
@@ -1500,13 +1513,13 @@
 	if (page_map->real == NULL) {
 		return -ENOMEM;
 	}
-	set_bit(PG_reserved, &mem_map[MAP_NR(page_map->real)].flags);
+	set_bit(PG_reserved, &virt_to_page(page_map->real)->flags);
 	CACHE_FLUSH();
 	page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), 
 					    PAGE_SIZE);
 	if (page_map->remapped == NULL) {
 		clear_bit(PG_reserved, 
-			  &mem_map[MAP_NR(page_map->real)].flags);
+			  &virt_to_page(page_map->real)->flags);
 		free_page((unsigned long) page_map->real);
 		page_map->real = NULL;
 		return -ENOMEM;
@@ -1524,7 +1537,7 @@
 {
 	iounmap(page_map->remapped);
 	clear_bit(PG_reserved, 
-		  &mem_map[MAP_NR(page_map->real)].flags);
+		  &virt_to_page(page_map->real)->flags);
 	free_page((unsigned long) page_map->real);
 }
 
@@ -2114,6 +2127,12 @@
 #endif /* CONFIG_AGP_SIS */
 
 #ifdef CONFIG_AGP_VIA
+	{ PCI_DEVICE_ID_VIA_8371_0,
+		PCI_VENDOR_ID_VIA,
+		VIA_APOLLO_SUPER,
+		"Via",
+		"Apollo Super",
+		via_generic_setup },
 	{ PCI_DEVICE_ID_VIA_8501_0,
 		PCI_VENDOR_ID_VIA,
 		VIA_MVP4,
@@ -2183,16 +2202,15 @@
 	 * there is a 'generic' bridge entry for this vendor */
 	if (agp_try_unsupported && agp_bridge_info[i].device_id == 0) {
 		printk(KERN_WARNING PFX "Trying generic %s routines"
-		       " for device id: %x\n",
+		       " for device id: %04x\n",
 		       agp_bridge_info[i].vendor_name, pdev->device);
 		agp_bridge.type = agp_bridge_info[i].chipset;
 		return agp_bridge_info[i].chipset_setup (pdev);
 	}
 
-	printk(KERN_ERR PFX "Unsupported %s chipset,"
-	       " you might want to try "
-	       "agp_try_unsupported=1.\n",
-	       agp_bridge_info[i].vendor_name);
+	printk(KERN_ERR PFX "Unsupported %s chipset (device id: %04x),"
+	       " you might want to try agp_try_unsupported=1.\n",
+	       agp_bridge_info[i].vendor_name, pdev->device);
 	return -ENODEV;
 }
 
@@ -2261,6 +2279,27 @@
 			agp_bridge.type = INTEL_I810;
 			return intel_i810_setup(i810_dev);
 
+		 case PCI_DEVICE_ID_INTEL_815_0:
+		   /* The i815 can operate either as an i810 style
+		    * integrated device, or as an AGP4X motherboard.
+		    *
+		    * This only addresses the first mode:
+		    */
+			i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+						   PCI_DEVICE_ID_INTEL_815_1,
+						   NULL);
+			if (i810_dev == NULL) {
+				printk(KERN_ERR PFX "agpgart: Detected an "
+				       "Intel i815, but could not find the"
+				       " secondary device.\n");
+				agp_bridge.type = NOT_SUPPORTED;
+				return -ENODEV;
+			}
+			printk(KERN_INFO PFX "agpgart: Detected an Intel i815 "
+			       "Chipset.\n");
+			agp_bridge.type = INTEL_I810;
+			return intel_i810_setup(i810_dev);
+
 		default:
 			break;
 		}
@@ -2451,11 +2490,13 @@
 	       AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR);
 
 	ret_val = agp_backend_initialize();
-	if (ret_val)
+	if (ret_val) {
+		agp_bridge.type = NOT_SUPPORTED;
 		return ret_val;
-
+	}
 	ret_val = agp_frontend_initialize();
 	if (ret_val) {
+		agp_bridge.type = NOT_SUPPORTED;
 		agp_backend_cleanup();
 		return ret_val;
 	}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)