diff options
-rw-r--r-- | drivers/char/agp/agp.h | 3 | ||||
-rw-r--r-- | drivers/char/agp/generic.c | 42 | ||||
-rw-r--r-- | drivers/char/agp/intel-agp.c | 14 |
3 files changed, 59 insertions, 0 deletions
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index 81e14bea54bd..55d2c9d14177 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h | |||
@@ -116,6 +116,7 @@ struct agp_bridge_driver { | |||
116 | struct agp_memory *(*alloc_by_type) (size_t, int); | 116 | struct agp_memory *(*alloc_by_type) (size_t, int); |
117 | void (*free_by_type)(struct agp_memory *); | 117 | void (*free_by_type)(struct agp_memory *); |
118 | void *(*agp_alloc_page)(struct agp_bridge_data *); | 118 | void *(*agp_alloc_page)(struct agp_bridge_data *); |
119 | int (*agp_alloc_pages)(struct agp_bridge_data *, struct agp_memory *, size_t); | ||
119 | void (*agp_destroy_page)(void *, int flags); | 120 | void (*agp_destroy_page)(void *, int flags); |
120 | int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); | 121 | int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); |
121 | void (*chipset_flush)(struct agp_bridge_data *); | 122 | void (*chipset_flush)(struct agp_bridge_data *); |
@@ -274,6 +275,8 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type); | |||
274 | struct agp_memory *agp_generic_alloc_by_type(size_t page_count, int type); | 275 | struct agp_memory *agp_generic_alloc_by_type(size_t page_count, int type); |
275 | void agp_generic_free_by_type(struct agp_memory *curr); | 276 | void agp_generic_free_by_type(struct agp_memory *curr); |
276 | void *agp_generic_alloc_page(struct agp_bridge_data *bridge); | 277 | void *agp_generic_alloc_page(struct agp_bridge_data *bridge); |
278 | int agp_generic_alloc_pages(struct agp_bridge_data *agp_bridge, | ||
279 | struct agp_memory *memory, size_t page_count); | ||
277 | void agp_generic_destroy_page(void *addr, int flags); | 280 | void agp_generic_destroy_page(void *addr, int flags); |
278 | void agp_free_key(int key); | 281 | void agp_free_key(int key); |
279 | int agp_num_entries(void); | 282 | int agp_num_entries(void); |
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index eaa1a355bb32..13a5577ee434 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c | |||
@@ -264,6 +264,15 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge, | |||
264 | if (new == NULL) | 264 | if (new == NULL) |
265 | return NULL; | 265 | return NULL; |
266 | 266 | ||
267 | if (bridge->driver->agp_alloc_pages) { | ||
268 | if (bridge->driver->agp_alloc_pages(bridge, new, page_count)) { | ||
269 | agp_free_memory(new); | ||
270 | return NULL; | ||
271 | } | ||
272 | new->bridge = bridge; | ||
273 | return new; | ||
274 | } | ||
275 | |||
267 | for (i = 0; i < page_count; i++) { | 276 | for (i = 0; i < page_count; i++) { |
268 | void *addr = bridge->driver->agp_alloc_page(bridge); | 277 | void *addr = bridge->driver->agp_alloc_page(bridge); |
269 | 278 | ||
@@ -1178,6 +1187,39 @@ EXPORT_SYMBOL(agp_generic_alloc_user); | |||
1178 | * against a maximum value. | 1187 | * against a maximum value. |
1179 | */ | 1188 | */ |
1180 | 1189 | ||
1190 | int agp_generic_alloc_pages(struct agp_bridge_data *bridge, struct agp_memory *mem, size_t num_pages) | ||
1191 | { | ||
1192 | struct page * page; | ||
1193 | int i, ret = -ENOMEM; | ||
1194 | |||
1195 | for (i = 0; i < num_pages; i++) { | ||
1196 | page = alloc_page(GFP_KERNEL | GFP_DMA32); | ||
1197 | /* agp_free_memory() needs gart address */ | ||
1198 | if (page == NULL) | ||
1199 | goto out; | ||
1200 | |||
1201 | #ifndef CONFIG_X86 | ||
1202 | map_page_into_agp(page); | ||
1203 | #endif | ||
1204 | get_page(page); | ||
1205 | atomic_inc(&agp_bridge->current_memory_agp); | ||
1206 | |||
1207 | /* set_memory_array_uc() needs virtual address */ | ||
1208 | mem->memory[i] = (unsigned long)page_address(page); | ||
1209 | mem->page_count++; | ||
1210 | } | ||
1211 | |||
1212 | #ifdef CONFIG_X86 | ||
1213 | set_memory_array_uc(mem->memory, num_pages); | ||
1214 | #endif | ||
1215 | ret = 0; | ||
1216 | out: | ||
1217 | for (i = 0; i < mem->page_count; i++) | ||
1218 | mem->memory[i] = virt_to_gart((void *)mem->memory[i]); | ||
1219 | return ret; | ||
1220 | } | ||
1221 | EXPORT_SYMBOL(agp_generic_alloc_pages); | ||
1222 | |||
1181 | void *agp_generic_alloc_page(struct agp_bridge_data *bridge) | 1223 | void *agp_generic_alloc_page(struct agp_bridge_data *bridge) |
1182 | { | 1224 | { |
1183 | struct page * page; | 1225 | struct page * page; |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index df702642ab8f..2cff0976a668 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -1703,6 +1703,7 @@ static const struct agp_bridge_driver intel_generic_driver = { | |||
1703 | .alloc_by_type = agp_generic_alloc_by_type, | 1703 | .alloc_by_type = agp_generic_alloc_by_type, |
1704 | .free_by_type = agp_generic_free_by_type, | 1704 | .free_by_type = agp_generic_free_by_type, |
1705 | .agp_alloc_page = agp_generic_alloc_page, | 1705 | .agp_alloc_page = agp_generic_alloc_page, |
1706 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1706 | .agp_destroy_page = agp_generic_destroy_page, | 1707 | .agp_destroy_page = agp_generic_destroy_page, |
1707 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1708 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1708 | }; | 1709 | }; |
@@ -1728,6 +1729,7 @@ static const struct agp_bridge_driver intel_810_driver = { | |||
1728 | .alloc_by_type = intel_i810_alloc_by_type, | 1729 | .alloc_by_type = intel_i810_alloc_by_type, |
1729 | .free_by_type = intel_i810_free_by_type, | 1730 | .free_by_type = intel_i810_free_by_type, |
1730 | .agp_alloc_page = agp_generic_alloc_page, | 1731 | .agp_alloc_page = agp_generic_alloc_page, |
1732 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1731 | .agp_destroy_page = agp_generic_destroy_page, | 1733 | .agp_destroy_page = agp_generic_destroy_page, |
1732 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1734 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1733 | }; | 1735 | }; |
@@ -1752,6 +1754,7 @@ static const struct agp_bridge_driver intel_815_driver = { | |||
1752 | .alloc_by_type = agp_generic_alloc_by_type, | 1754 | .alloc_by_type = agp_generic_alloc_by_type, |
1753 | .free_by_type = agp_generic_free_by_type, | 1755 | .free_by_type = agp_generic_free_by_type, |
1754 | .agp_alloc_page = agp_generic_alloc_page, | 1756 | .agp_alloc_page = agp_generic_alloc_page, |
1757 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1755 | .agp_destroy_page = agp_generic_destroy_page, | 1758 | .agp_destroy_page = agp_generic_destroy_page, |
1756 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1759 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1757 | }; | 1760 | }; |
@@ -1777,6 +1780,7 @@ static const struct agp_bridge_driver intel_830_driver = { | |||
1777 | .alloc_by_type = intel_i830_alloc_by_type, | 1780 | .alloc_by_type = intel_i830_alloc_by_type, |
1778 | .free_by_type = intel_i810_free_by_type, | 1781 | .free_by_type = intel_i810_free_by_type, |
1779 | .agp_alloc_page = agp_generic_alloc_page, | 1782 | .agp_alloc_page = agp_generic_alloc_page, |
1783 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1780 | .agp_destroy_page = agp_generic_destroy_page, | 1784 | .agp_destroy_page = agp_generic_destroy_page, |
1781 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 1785 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
1782 | .chipset_flush = intel_i830_chipset_flush, | 1786 | .chipset_flush = intel_i830_chipset_flush, |
@@ -1802,6 +1806,7 @@ static const struct agp_bridge_driver intel_820_driver = { | |||
1802 | .alloc_by_type = agp_generic_alloc_by_type, | 1806 | .alloc_by_type = agp_generic_alloc_by_type, |
1803 | .free_by_type = agp_generic_free_by_type, | 1807 | .free_by_type = agp_generic_free_by_type, |
1804 | .agp_alloc_page = agp_generic_alloc_page, | 1808 | .agp_alloc_page = agp_generic_alloc_page, |
1809 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1805 | .agp_destroy_page = agp_generic_destroy_page, | 1810 | .agp_destroy_page = agp_generic_destroy_page, |
1806 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1811 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1807 | }; | 1812 | }; |
@@ -1826,6 +1831,7 @@ static const struct agp_bridge_driver intel_830mp_driver = { | |||
1826 | .alloc_by_type = agp_generic_alloc_by_type, | 1831 | .alloc_by_type = agp_generic_alloc_by_type, |
1827 | .free_by_type = agp_generic_free_by_type, | 1832 | .free_by_type = agp_generic_free_by_type, |
1828 | .agp_alloc_page = agp_generic_alloc_page, | 1833 | .agp_alloc_page = agp_generic_alloc_page, |
1834 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1829 | .agp_destroy_page = agp_generic_destroy_page, | 1835 | .agp_destroy_page = agp_generic_destroy_page, |
1830 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1836 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1831 | }; | 1837 | }; |
@@ -1850,6 +1856,7 @@ static const struct agp_bridge_driver intel_840_driver = { | |||
1850 | .alloc_by_type = agp_generic_alloc_by_type, | 1856 | .alloc_by_type = agp_generic_alloc_by_type, |
1851 | .free_by_type = agp_generic_free_by_type, | 1857 | .free_by_type = agp_generic_free_by_type, |
1852 | .agp_alloc_page = agp_generic_alloc_page, | 1858 | .agp_alloc_page = agp_generic_alloc_page, |
1859 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1853 | .agp_destroy_page = agp_generic_destroy_page, | 1860 | .agp_destroy_page = agp_generic_destroy_page, |
1854 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1861 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1855 | }; | 1862 | }; |
@@ -1874,6 +1881,7 @@ static const struct agp_bridge_driver intel_845_driver = { | |||
1874 | .alloc_by_type = agp_generic_alloc_by_type, | 1881 | .alloc_by_type = agp_generic_alloc_by_type, |
1875 | .free_by_type = agp_generic_free_by_type, | 1882 | .free_by_type = agp_generic_free_by_type, |
1876 | .agp_alloc_page = agp_generic_alloc_page, | 1883 | .agp_alloc_page = agp_generic_alloc_page, |
1884 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1877 | .agp_destroy_page = agp_generic_destroy_page, | 1885 | .agp_destroy_page = agp_generic_destroy_page, |
1878 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1886 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1879 | .chipset_flush = intel_i830_chipset_flush, | 1887 | .chipset_flush = intel_i830_chipset_flush, |
@@ -1899,6 +1907,7 @@ static const struct agp_bridge_driver intel_850_driver = { | |||
1899 | .alloc_by_type = agp_generic_alloc_by_type, | 1907 | .alloc_by_type = agp_generic_alloc_by_type, |
1900 | .free_by_type = agp_generic_free_by_type, | 1908 | .free_by_type = agp_generic_free_by_type, |
1901 | .agp_alloc_page = agp_generic_alloc_page, | 1909 | .agp_alloc_page = agp_generic_alloc_page, |
1910 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1902 | .agp_destroy_page = agp_generic_destroy_page, | 1911 | .agp_destroy_page = agp_generic_destroy_page, |
1903 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1912 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1904 | }; | 1913 | }; |
@@ -1923,6 +1932,7 @@ static const struct agp_bridge_driver intel_860_driver = { | |||
1923 | .alloc_by_type = agp_generic_alloc_by_type, | 1932 | .alloc_by_type = agp_generic_alloc_by_type, |
1924 | .free_by_type = agp_generic_free_by_type, | 1933 | .free_by_type = agp_generic_free_by_type, |
1925 | .agp_alloc_page = agp_generic_alloc_page, | 1934 | .agp_alloc_page = agp_generic_alloc_page, |
1935 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1926 | .agp_destroy_page = agp_generic_destroy_page, | 1936 | .agp_destroy_page = agp_generic_destroy_page, |
1927 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1937 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1928 | }; | 1938 | }; |
@@ -1948,6 +1958,7 @@ static const struct agp_bridge_driver intel_915_driver = { | |||
1948 | .alloc_by_type = intel_i830_alloc_by_type, | 1958 | .alloc_by_type = intel_i830_alloc_by_type, |
1949 | .free_by_type = intel_i810_free_by_type, | 1959 | .free_by_type = intel_i810_free_by_type, |
1950 | .agp_alloc_page = agp_generic_alloc_page, | 1960 | .agp_alloc_page = agp_generic_alloc_page, |
1961 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1951 | .agp_destroy_page = agp_generic_destroy_page, | 1962 | .agp_destroy_page = agp_generic_destroy_page, |
1952 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 1963 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
1953 | .chipset_flush = intel_i915_chipset_flush, | 1964 | .chipset_flush = intel_i915_chipset_flush, |
@@ -1974,6 +1985,7 @@ static const struct agp_bridge_driver intel_i965_driver = { | |||
1974 | .alloc_by_type = intel_i830_alloc_by_type, | 1985 | .alloc_by_type = intel_i830_alloc_by_type, |
1975 | .free_by_type = intel_i810_free_by_type, | 1986 | .free_by_type = intel_i810_free_by_type, |
1976 | .agp_alloc_page = agp_generic_alloc_page, | 1987 | .agp_alloc_page = agp_generic_alloc_page, |
1988 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1977 | .agp_destroy_page = agp_generic_destroy_page, | 1989 | .agp_destroy_page = agp_generic_destroy_page, |
1978 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 1990 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
1979 | .chipset_flush = intel_i915_chipset_flush, | 1991 | .chipset_flush = intel_i915_chipset_flush, |
@@ -1999,6 +2011,7 @@ static const struct agp_bridge_driver intel_7505_driver = { | |||
1999 | .alloc_by_type = agp_generic_alloc_by_type, | 2011 | .alloc_by_type = agp_generic_alloc_by_type, |
2000 | .free_by_type = agp_generic_free_by_type, | 2012 | .free_by_type = agp_generic_free_by_type, |
2001 | .agp_alloc_page = agp_generic_alloc_page, | 2013 | .agp_alloc_page = agp_generic_alloc_page, |
2014 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
2002 | .agp_destroy_page = agp_generic_destroy_page, | 2015 | .agp_destroy_page = agp_generic_destroy_page, |
2003 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 2016 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
2004 | }; | 2017 | }; |
@@ -2024,6 +2037,7 @@ static const struct agp_bridge_driver intel_g33_driver = { | |||
2024 | .alloc_by_type = intel_i830_alloc_by_type, | 2037 | .alloc_by_type = intel_i830_alloc_by_type, |
2025 | .free_by_type = intel_i810_free_by_type, | 2038 | .free_by_type = intel_i810_free_by_type, |
2026 | .agp_alloc_page = agp_generic_alloc_page, | 2039 | .agp_alloc_page = agp_generic_alloc_page, |
2040 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
2027 | .agp_destroy_page = agp_generic_destroy_page, | 2041 | .agp_destroy_page = agp_generic_destroy_page, |
2028 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 2042 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
2029 | .chipset_flush = intel_i915_chipset_flush, | 2043 | .chipset_flush = intel_i915_chipset_flush, |