aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/agp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/agp')
-rw-r--r--drivers/char/agp/agp.h5
-rw-r--r--drivers/char/agp/generic.c97
-rw-r--r--drivers/char/agp/intel-agp.c28
3 files changed, 122 insertions, 8 deletions
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index 4bada0e8b812..46f507531177 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -116,7 +116,9 @@ 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);
121 void (*agp_destroy_pages)(struct agp_memory *);
120 int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); 122 int (*agp_type_to_mask_type) (struct agp_bridge_data *, int);
121 void (*chipset_flush)(struct agp_bridge_data *); 123 void (*chipset_flush)(struct agp_bridge_data *);
122}; 124};
@@ -277,7 +279,10 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type);
277struct agp_memory *agp_generic_alloc_by_type(size_t page_count, int type); 279struct agp_memory *agp_generic_alloc_by_type(size_t page_count, int type);
278void agp_generic_free_by_type(struct agp_memory *curr); 280void agp_generic_free_by_type(struct agp_memory *curr);
279void *agp_generic_alloc_page(struct agp_bridge_data *bridge); 281void *agp_generic_alloc_page(struct agp_bridge_data *bridge);
282int agp_generic_alloc_pages(struct agp_bridge_data *agp_bridge,
283 struct agp_memory *memory, size_t page_count);
280void agp_generic_destroy_page(void *addr, int flags); 284void agp_generic_destroy_page(void *addr, int flags);
285void agp_generic_destroy_pages(struct agp_memory *memory);
281void agp_free_key(int key); 286void agp_free_key(int key);
282int agp_num_entries(void); 287int agp_num_entries(void);
283u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 mode, u32 command); 288u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 mode, u32 command);
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 118dbde25dc7..10d6cbd7c05e 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -201,14 +201,22 @@ void agp_free_memory(struct agp_memory *curr)
201 return; 201 return;
202 } 202 }
203 if (curr->page_count != 0) { 203 if (curr->page_count != 0) {
204 for (i = 0; i < curr->page_count; i++) { 204 if (curr->bridge->driver->agp_destroy_pages) {
205 curr->memory[i] = (unsigned long)gart_to_virt(curr->memory[i]); 205 curr->bridge->driver->agp_destroy_pages(curr);
206 curr->bridge->driver->agp_destroy_page((void *)curr->memory[i], 206 } else {
207 AGP_PAGE_DESTROY_UNMAP); 207
208 } 208 for (i = 0; i < curr->page_count; i++) {
209 for (i = 0; i < curr->page_count; i++) { 209 curr->memory[i] = (unsigned long)gart_to_virt(
210 curr->bridge->driver->agp_destroy_page((void *)curr->memory[i], 210 curr->memory[i]);
211 AGP_PAGE_DESTROY_FREE); 211 curr->bridge->driver->agp_destroy_page(
212 (void *)curr->memory[i],
213 AGP_PAGE_DESTROY_UNMAP);
214 }
215 for (i = 0; i < curr->page_count; i++) {
216 curr->bridge->driver->agp_destroy_page(
217 (void *)curr->memory[i],
218 AGP_PAGE_DESTROY_FREE);
219 }
212 } 220 }
213 } 221 }
214 agp_free_key(curr->key); 222 agp_free_key(curr->key);
@@ -264,6 +272,15 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge,
264 if (new == NULL) 272 if (new == NULL)
265 return NULL; 273 return NULL;
266 274
275 if (bridge->driver->agp_alloc_pages) {
276 if (bridge->driver->agp_alloc_pages(bridge, new, page_count)) {
277 agp_free_memory(new);
278 return NULL;
279 }
280 new->bridge = bridge;
281 return new;
282 }
283
267 for (i = 0; i < page_count; i++) { 284 for (i = 0; i < page_count; i++) {
268 void *addr = bridge->driver->agp_alloc_page(bridge); 285 void *addr = bridge->driver->agp_alloc_page(bridge);
269 286
@@ -1203,6 +1220,39 @@ EXPORT_SYMBOL(agp_generic_alloc_user);
1203 * against a maximum value. 1220 * against a maximum value.
1204 */ 1221 */
1205 1222
1223int agp_generic_alloc_pages(struct agp_bridge_data *bridge, struct agp_memory *mem, size_t num_pages)
1224{
1225 struct page * page;
1226 int i, ret = -ENOMEM;
1227
1228 for (i = 0; i < num_pages; i++) {
1229 page = alloc_page(GFP_KERNEL | GFP_DMA32);
1230 /* agp_free_memory() needs gart address */
1231 if (page == NULL)
1232 goto out;
1233
1234#ifndef CONFIG_X86
1235 map_page_into_agp(page);
1236#endif
1237 get_page(page);
1238 atomic_inc(&agp_bridge->current_memory_agp);
1239
1240 /* set_memory_array_uc() needs virtual address */
1241 mem->memory[i] = (unsigned long)page_address(page);
1242 mem->page_count++;
1243 }
1244
1245#ifdef CONFIG_X86
1246 set_memory_array_uc(mem->memory, num_pages);
1247#endif
1248 ret = 0;
1249out:
1250 for (i = 0; i < mem->page_count; i++)
1251 mem->memory[i] = virt_to_gart((void *)mem->memory[i]);
1252 return ret;
1253}
1254EXPORT_SYMBOL(agp_generic_alloc_pages);
1255
1206void *agp_generic_alloc_page(struct agp_bridge_data *bridge) 1256void *agp_generic_alloc_page(struct agp_bridge_data *bridge)
1207{ 1257{
1208 struct page * page; 1258 struct page * page;
@@ -1219,6 +1269,37 @@ void *agp_generic_alloc_page(struct agp_bridge_data *bridge)
1219} 1269}
1220EXPORT_SYMBOL(agp_generic_alloc_page); 1270EXPORT_SYMBOL(agp_generic_alloc_page);
1221 1271
1272void agp_generic_destroy_pages(struct agp_memory *mem)
1273{
1274 int i;
1275 void *addr;
1276 struct page *page;
1277
1278 if (!mem)
1279 return;
1280
1281 for (i = 0; i < mem->page_count; i++)
1282 mem->memory[i] = (unsigned long)gart_to_virt(mem->memory[i]);
1283
1284#ifdef CONFIG_X86
1285 set_memory_array_wb(mem->memory, mem->page_count);
1286#endif
1287
1288 for (i = 0; i < mem->page_count; i++) {
1289 addr = (void *)mem->memory[i];
1290 page = virt_to_page(addr);
1291
1292#ifndef CONFIG_X86
1293 unmap_page_from_agp(page);
1294#endif
1295
1296 put_page(page);
1297 free_page((unsigned long)addr);
1298 atomic_dec(&agp_bridge->current_memory_agp);
1299 mem->memory[i] = 0;
1300 }
1301}
1302EXPORT_SYMBOL(agp_generic_destroy_pages);
1222 1303
1223void agp_generic_destroy_page(void *addr, int flags) 1304void agp_generic_destroy_page(void *addr, int flags)
1224{ 1305{
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 016fdf0623a4..043e36628d6d 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -1711,7 +1711,9 @@ static const struct agp_bridge_driver intel_generic_driver = {
1711 .alloc_by_type = agp_generic_alloc_by_type, 1711 .alloc_by_type = agp_generic_alloc_by_type,
1712 .free_by_type = agp_generic_free_by_type, 1712 .free_by_type = agp_generic_free_by_type,
1713 .agp_alloc_page = agp_generic_alloc_page, 1713 .agp_alloc_page = agp_generic_alloc_page,
1714 .agp_alloc_pages = agp_generic_alloc_pages,
1714 .agp_destroy_page = agp_generic_destroy_page, 1715 .agp_destroy_page = agp_generic_destroy_page,
1716 .agp_destroy_pages = agp_generic_destroy_pages,
1715 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 1717 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1716}; 1718};
1717 1719
@@ -1736,7 +1738,9 @@ static const struct agp_bridge_driver intel_810_driver = {
1736 .alloc_by_type = intel_i810_alloc_by_type, 1738 .alloc_by_type = intel_i810_alloc_by_type,
1737 .free_by_type = intel_i810_free_by_type, 1739 .free_by_type = intel_i810_free_by_type,
1738 .agp_alloc_page = agp_generic_alloc_page, 1740 .agp_alloc_page = agp_generic_alloc_page,
1741 .agp_alloc_pages = agp_generic_alloc_pages,
1739 .agp_destroy_page = agp_generic_destroy_page, 1742 .agp_destroy_page = agp_generic_destroy_page,
1743 .agp_destroy_pages = agp_generic_destroy_pages,
1740 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 1744 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1741}; 1745};
1742 1746
@@ -1760,7 +1764,9 @@ static const struct agp_bridge_driver intel_815_driver = {
1760 .alloc_by_type = agp_generic_alloc_by_type, 1764 .alloc_by_type = agp_generic_alloc_by_type,
1761 .free_by_type = agp_generic_free_by_type, 1765 .free_by_type = agp_generic_free_by_type,
1762 .agp_alloc_page = agp_generic_alloc_page, 1766 .agp_alloc_page = agp_generic_alloc_page,
1767 .agp_alloc_pages = agp_generic_alloc_pages,
1763 .agp_destroy_page = agp_generic_destroy_page, 1768 .agp_destroy_page = agp_generic_destroy_page,
1769 .agp_destroy_pages = agp_generic_destroy_pages,
1764 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 1770 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1765}; 1771};
1766 1772
@@ -1785,7 +1791,9 @@ static const struct agp_bridge_driver intel_830_driver = {
1785 .alloc_by_type = intel_i830_alloc_by_type, 1791 .alloc_by_type = intel_i830_alloc_by_type,
1786 .free_by_type = intel_i810_free_by_type, 1792 .free_by_type = intel_i810_free_by_type,
1787 .agp_alloc_page = agp_generic_alloc_page, 1793 .agp_alloc_page = agp_generic_alloc_page,
1794 .agp_alloc_pages = agp_generic_alloc_pages,
1788 .agp_destroy_page = agp_generic_destroy_page, 1795 .agp_destroy_page = agp_generic_destroy_page,
1796 .agp_destroy_pages = agp_generic_destroy_pages,
1789 .agp_type_to_mask_type = intel_i830_type_to_mask_type, 1797 .agp_type_to_mask_type = intel_i830_type_to_mask_type,
1790 .chipset_flush = intel_i830_chipset_flush, 1798 .chipset_flush = intel_i830_chipset_flush,
1791}; 1799};
@@ -1810,7 +1818,9 @@ static const struct agp_bridge_driver intel_820_driver = {
1810 .alloc_by_type = agp_generic_alloc_by_type, 1818 .alloc_by_type = agp_generic_alloc_by_type,
1811 .free_by_type = agp_generic_free_by_type, 1819 .free_by_type = agp_generic_free_by_type,
1812 .agp_alloc_page = agp_generic_alloc_page, 1820 .agp_alloc_page = agp_generic_alloc_page,
1821 .agp_alloc_pages = agp_generic_alloc_pages,
1813 .agp_destroy_page = agp_generic_destroy_page, 1822 .agp_destroy_page = agp_generic_destroy_page,
1823 .agp_destroy_pages = agp_generic_destroy_pages,
1814 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 1824 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1815}; 1825};
1816 1826
@@ -1834,7 +1844,9 @@ static const struct agp_bridge_driver intel_830mp_driver = {
1834 .alloc_by_type = agp_generic_alloc_by_type, 1844 .alloc_by_type = agp_generic_alloc_by_type,
1835 .free_by_type = agp_generic_free_by_type, 1845 .free_by_type = agp_generic_free_by_type,
1836 .agp_alloc_page = agp_generic_alloc_page, 1846 .agp_alloc_page = agp_generic_alloc_page,
1847 .agp_alloc_pages = agp_generic_alloc_pages,
1837 .agp_destroy_page = agp_generic_destroy_page, 1848 .agp_destroy_page = agp_generic_destroy_page,
1849 .agp_destroy_pages = agp_generic_destroy_pages,
1838 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 1850 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1839}; 1851};
1840 1852
@@ -1858,7 +1870,9 @@ static const struct agp_bridge_driver intel_840_driver = {
1858 .alloc_by_type = agp_generic_alloc_by_type, 1870 .alloc_by_type = agp_generic_alloc_by_type,
1859 .free_by_type = agp_generic_free_by_type, 1871 .free_by_type = agp_generic_free_by_type,
1860 .agp_alloc_page = agp_generic_alloc_page, 1872 .agp_alloc_page = agp_generic_alloc_page,
1873 .agp_alloc_pages = agp_generic_alloc_pages,
1861 .agp_destroy_page = agp_generic_destroy_page, 1874 .agp_destroy_page = agp_generic_destroy_page,
1875 .agp_destroy_pages = agp_generic_destroy_pages,
1862 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 1876 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1863}; 1877};
1864 1878
@@ -1882,7 +1896,9 @@ static const struct agp_bridge_driver intel_845_driver = {
1882 .alloc_by_type = agp_generic_alloc_by_type, 1896 .alloc_by_type = agp_generic_alloc_by_type,
1883 .free_by_type = agp_generic_free_by_type, 1897 .free_by_type = agp_generic_free_by_type,
1884 .agp_alloc_page = agp_generic_alloc_page, 1898 .agp_alloc_page = agp_generic_alloc_page,
1899 .agp_alloc_pages = agp_generic_alloc_pages,
1885 .agp_destroy_page = agp_generic_destroy_page, 1900 .agp_destroy_page = agp_generic_destroy_page,
1901 .agp_destroy_pages = agp_generic_destroy_pages,
1886 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 1902 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1887 .chipset_flush = intel_i830_chipset_flush, 1903 .chipset_flush = intel_i830_chipset_flush,
1888}; 1904};
@@ -1907,7 +1923,9 @@ static const struct agp_bridge_driver intel_850_driver = {
1907 .alloc_by_type = agp_generic_alloc_by_type, 1923 .alloc_by_type = agp_generic_alloc_by_type,
1908 .free_by_type = agp_generic_free_by_type, 1924 .free_by_type = agp_generic_free_by_type,
1909 .agp_alloc_page = agp_generic_alloc_page, 1925 .agp_alloc_page = agp_generic_alloc_page,
1926 .agp_alloc_pages = agp_generic_alloc_pages,
1910 .agp_destroy_page = agp_generic_destroy_page, 1927 .agp_destroy_page = agp_generic_destroy_page,
1928 .agp_destroy_pages = agp_generic_destroy_pages,
1911 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 1929 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1912}; 1930};
1913 1931
@@ -1931,7 +1949,9 @@ static const struct agp_bridge_driver intel_860_driver = {
1931 .alloc_by_type = agp_generic_alloc_by_type, 1949 .alloc_by_type = agp_generic_alloc_by_type,
1932 .free_by_type = agp_generic_free_by_type, 1950 .free_by_type = agp_generic_free_by_type,
1933 .agp_alloc_page = agp_generic_alloc_page, 1951 .agp_alloc_page = agp_generic_alloc_page,
1952 .agp_alloc_pages = agp_generic_alloc_pages,
1934 .agp_destroy_page = agp_generic_destroy_page, 1953 .agp_destroy_page = agp_generic_destroy_page,
1954 .agp_destroy_pages = agp_generic_destroy_pages,
1935 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 1955 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1936}; 1956};
1937 1957
@@ -1956,7 +1976,9 @@ static const struct agp_bridge_driver intel_915_driver = {
1956 .alloc_by_type = intel_i830_alloc_by_type, 1976 .alloc_by_type = intel_i830_alloc_by_type,
1957 .free_by_type = intel_i810_free_by_type, 1977 .free_by_type = intel_i810_free_by_type,
1958 .agp_alloc_page = agp_generic_alloc_page, 1978 .agp_alloc_page = agp_generic_alloc_page,
1979 .agp_alloc_pages = agp_generic_alloc_pages,
1959 .agp_destroy_page = agp_generic_destroy_page, 1980 .agp_destroy_page = agp_generic_destroy_page,
1981 .agp_destroy_pages = agp_generic_destroy_pages,
1960 .agp_type_to_mask_type = intel_i830_type_to_mask_type, 1982 .agp_type_to_mask_type = intel_i830_type_to_mask_type,
1961 .chipset_flush = intel_i915_chipset_flush, 1983 .chipset_flush = intel_i915_chipset_flush,
1962}; 1984};
@@ -1982,7 +2004,9 @@ static const struct agp_bridge_driver intel_i965_driver = {
1982 .alloc_by_type = intel_i830_alloc_by_type, 2004 .alloc_by_type = intel_i830_alloc_by_type,
1983 .free_by_type = intel_i810_free_by_type, 2005 .free_by_type = intel_i810_free_by_type,
1984 .agp_alloc_page = agp_generic_alloc_page, 2006 .agp_alloc_page = agp_generic_alloc_page,
2007 .agp_alloc_pages = agp_generic_alloc_pages,
1985 .agp_destroy_page = agp_generic_destroy_page, 2008 .agp_destroy_page = agp_generic_destroy_page,
2009 .agp_destroy_pages = agp_generic_destroy_pages,
1986 .agp_type_to_mask_type = intel_i830_type_to_mask_type, 2010 .agp_type_to_mask_type = intel_i830_type_to_mask_type,
1987 .chipset_flush = intel_i915_chipset_flush, 2011 .chipset_flush = intel_i915_chipset_flush,
1988}; 2012};
@@ -2007,7 +2031,9 @@ static const struct agp_bridge_driver intel_7505_driver = {
2007 .alloc_by_type = agp_generic_alloc_by_type, 2031 .alloc_by_type = agp_generic_alloc_by_type,
2008 .free_by_type = agp_generic_free_by_type, 2032 .free_by_type = agp_generic_free_by_type,
2009 .agp_alloc_page = agp_generic_alloc_page, 2033 .agp_alloc_page = agp_generic_alloc_page,
2034 .agp_alloc_pages = agp_generic_alloc_pages,
2010 .agp_destroy_page = agp_generic_destroy_page, 2035 .agp_destroy_page = agp_generic_destroy_page,
2036 .agp_destroy_pages = agp_generic_destroy_pages,
2011 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 2037 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
2012}; 2038};
2013 2039
@@ -2032,7 +2058,9 @@ static const struct agp_bridge_driver intel_g33_driver = {
2032 .alloc_by_type = intel_i830_alloc_by_type, 2058 .alloc_by_type = intel_i830_alloc_by_type,
2033 .free_by_type = intel_i810_free_by_type, 2059 .free_by_type = intel_i810_free_by_type,
2034 .agp_alloc_page = agp_generic_alloc_page, 2060 .agp_alloc_page = agp_generic_alloc_page,
2061 .agp_alloc_pages = agp_generic_alloc_pages,
2035 .agp_destroy_page = agp_generic_destroy_page, 2062 .agp_destroy_page = agp_generic_destroy_page,
2063 .agp_destroy_pages = agp_generic_destroy_pages,
2036 .agp_type_to_mask_type = intel_i830_type_to_mask_type, 2064 .agp_type_to_mask_type = intel_i830_type_to_mask_type,
2037 .chipset_flush = intel_i915_chipset_flush, 2065 .chipset_flush = intel_i915_chipset_flush,
2038}; 2066};