diff options
author | Paul Mackerras <paulus@samba.org> | 2007-05-07 23:37:51 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-05-07 23:37:51 -0400 |
commit | 02bbc0f09c90cefdb2837605c96a66c5ce4ba2e1 (patch) | |
tree | 04ef573cd4de095c500c9fc3477f4278c0b36300 /drivers/char | |
parent | 7487a2245b8841c77ba9db406cf99a483b9334e9 (diff) | |
parent | 5b94f675f57e4ff16c8fda09088d7480a84dcd91 (diff) |
Merge branch 'linux-2.6'
Diffstat (limited to 'drivers/char')
39 files changed, 598 insertions, 429 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index d0c978fbc204..a26d91743b24 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -905,8 +905,8 @@ config SONYPI | |||
905 | To compile this driver as a module, choose M here: the | 905 | To compile this driver as a module, choose M here: the |
906 | module will be called sonypi. | 906 | module will be called sonypi. |
907 | 907 | ||
908 | config TANBAC_TB0219 | 908 | config GPIO_TB0219 |
909 | tristate "TANBAC TB0219 base board support" | 909 | tristate "TANBAC TB0219 GPIO support" |
910 | depends on TANBAC_TB022X | 910 | depends on TANBAC_TB022X |
911 | select GPIO_VR41XX | 911 | select GPIO_VR41XX |
912 | 912 | ||
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index ae8567cc529c..2f56ecc035aa 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -91,7 +91,7 @@ obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o | |||
91 | obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o | 91 | obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o |
92 | obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o | 92 | obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o |
93 | obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o | 93 | obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o |
94 | obj-$(CONFIG_TANBAC_TB0219) += tb0219.o | 94 | obj-$(CONFIG_GPIO_TB0219) += tb0219.o |
95 | obj-$(CONFIG_TELCLOCK) += tlclk.o | 95 | obj-$(CONFIG_TELCLOCK) += tlclk.o |
96 | 96 | ||
97 | obj-$(CONFIG_WATCHDOG) += watchdog/ | 97 | obj-$(CONFIG_WATCHDOG) += watchdog/ |
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index 5b684fddcc03..4941ddb78939 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c | |||
@@ -145,6 +145,7 @@ static void *m1541_alloc_page(struct agp_bridge_data *bridge) | |||
145 | void *addr = agp_generic_alloc_page(agp_bridge); | 145 | void *addr = agp_generic_alloc_page(agp_bridge); |
146 | u32 temp; | 146 | u32 temp; |
147 | 147 | ||
148 | global_flush_tlb(); | ||
148 | if (!addr) | 149 | if (!addr) |
149 | return NULL; | 150 | return NULL; |
150 | 151 | ||
@@ -160,6 +161,7 @@ static void ali_destroy_page(void * addr) | |||
160 | if (addr) { | 161 | if (addr) { |
161 | global_cache_flush(); /* is this really needed? --hch */ | 162 | global_cache_flush(); /* is this really needed? --hch */ |
162 | agp_generic_destroy_page(addr); | 163 | agp_generic_destroy_page(addr); |
164 | global_flush_tlb(); | ||
163 | } | 165 | } |
164 | } | 166 | } |
165 | 167 | ||
diff --git a/drivers/char/agp/alpha-agp.c b/drivers/char/agp/alpha-agp.c index b0acf41c0db9..aa8f3a39a704 100644 --- a/drivers/char/agp/alpha-agp.c +++ b/drivers/char/agp/alpha-agp.c | |||
@@ -173,7 +173,7 @@ alpha_core_agp_setup(void) | |||
173 | /* | 173 | /* |
174 | * Build a fake pci_dev struct | 174 | * Build a fake pci_dev struct |
175 | */ | 175 | */ |
176 | pdev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL); | 176 | pdev = alloc_pci_dev(); |
177 | if (!pdev) | 177 | if (!pdev) |
178 | return -ENOMEM; | 178 | return -ENOMEM; |
179 | pdev->vendor = 0xffff; | 179 | pdev->vendor = 0xffff; |
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 485720486d60..c9f0f250d78f 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/agp_backend.h> | 14 | #include <linux/agp_backend.h> |
15 | #include <linux/mmzone.h> | 15 | #include <linux/mmzone.h> |
16 | #include <asm/page.h> /* PAGE_SIZE */ | 16 | #include <asm/page.h> /* PAGE_SIZE */ |
17 | #include <asm/e820.h> | ||
17 | #include <asm/k8.h> | 18 | #include <asm/k8.h> |
18 | #include "agp.h" | 19 | #include "agp.h" |
19 | 20 | ||
@@ -259,7 +260,6 @@ static const struct agp_bridge_driver amd_8151_driver = { | |||
259 | /* Some basic sanity checks for the aperture. */ | 260 | /* Some basic sanity checks for the aperture. */ |
260 | static int __devinit aperture_valid(u64 aper, u32 size) | 261 | static int __devinit aperture_valid(u64 aper, u32 size) |
261 | { | 262 | { |
262 | u32 pfn, c; | ||
263 | if (aper == 0) { | 263 | if (aper == 0) { |
264 | printk(KERN_ERR PFX "No aperture\n"); | 264 | printk(KERN_ERR PFX "No aperture\n"); |
265 | return 0; | 265 | return 0; |
@@ -272,14 +272,9 @@ static int __devinit aperture_valid(u64 aper, u32 size) | |||
272 | printk(KERN_ERR PFX "Aperture out of bounds\n"); | 272 | printk(KERN_ERR PFX "Aperture out of bounds\n"); |
273 | return 0; | 273 | return 0; |
274 | } | 274 | } |
275 | pfn = aper >> PAGE_SHIFT; | 275 | if (e820_any_mapped(aper, aper + size, E820_RAM)) { |
276 | for (c = 0; c < size/PAGE_SIZE; c++) { | 276 | printk(KERN_ERR PFX "Aperture pointing to RAM\n"); |
277 | if (!pfn_valid(pfn + c)) | 277 | return 0; |
278 | break; | ||
279 | if (!PageReserved(pfn_to_page(pfn + c))) { | ||
280 | printk(KERN_ERR PFX "Aperture pointing to RAM\n"); | ||
281 | return 0; | ||
282 | } | ||
283 | } | 278 | } |
284 | 279 | ||
285 | /* Request the Aperture. This catches cases when someone else | 280 | /* Request the Aperture. This catches cases when someone else |
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index f902d71947ba..45aeb917ec63 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c | |||
@@ -51,28 +51,6 @@ int agp_memory_reserved; | |||
51 | */ | 51 | */ |
52 | EXPORT_SYMBOL_GPL(agp_memory_reserved); | 52 | EXPORT_SYMBOL_GPL(agp_memory_reserved); |
53 | 53 | ||
54 | #if defined(CONFIG_X86) | ||
55 | int map_page_into_agp(struct page *page) | ||
56 | { | ||
57 | int i; | ||
58 | i = change_page_attr(page, 1, PAGE_KERNEL_NOCACHE); | ||
59 | /* Caller's responsibility to call global_flush_tlb() for | ||
60 | * performance reasons */ | ||
61 | return i; | ||
62 | } | ||
63 | EXPORT_SYMBOL_GPL(map_page_into_agp); | ||
64 | |||
65 | int unmap_page_from_agp(struct page *page) | ||
66 | { | ||
67 | int i; | ||
68 | i = change_page_attr(page, 1, PAGE_KERNEL); | ||
69 | /* Caller's responsibility to call global_flush_tlb() for | ||
70 | * performance reasons */ | ||
71 | return i; | ||
72 | } | ||
73 | EXPORT_SYMBOL_GPL(unmap_page_from_agp); | ||
74 | #endif | ||
75 | |||
76 | /* | 54 | /* |
77 | * Generic routines for handling agp_memory structures - | 55 | * Generic routines for handling agp_memory structures - |
78 | * They use the basic page allocation routines to do the brunt of the work. | 56 | * They use the basic page allocation routines to do the brunt of the work. |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 55392a45a14b..9c69f2e761f5 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -186,8 +186,9 @@ static void *i8xx_alloc_pages(void) | |||
186 | return NULL; | 186 | return NULL; |
187 | 187 | ||
188 | if (change_page_attr(page, 4, PAGE_KERNEL_NOCACHE) < 0) { | 188 | if (change_page_attr(page, 4, PAGE_KERNEL_NOCACHE) < 0) { |
189 | change_page_attr(page, 4, PAGE_KERNEL); | ||
189 | global_flush_tlb(); | 190 | global_flush_tlb(); |
190 | __free_page(page); | 191 | __free_pages(page, 2); |
191 | return NULL; | 192 | return NULL; |
192 | } | 193 | } |
193 | global_flush_tlb(); | 194 | global_flush_tlb(); |
@@ -209,7 +210,7 @@ static void i8xx_destroy_pages(void *addr) | |||
209 | global_flush_tlb(); | 210 | global_flush_tlb(); |
210 | put_page(page); | 211 | put_page(page); |
211 | unlock_page(page); | 212 | unlock_page(page); |
212 | free_pages((unsigned long)addr, 2); | 213 | __free_pages(page, 2); |
213 | atomic_dec(&agp_bridge->current_memory_agp); | 214 | atomic_dec(&agp_bridge->current_memory_agp); |
214 | } | 215 | } |
215 | 216 | ||
@@ -315,9 +316,6 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type) | |||
315 | struct agp_memory *new; | 316 | struct agp_memory *new; |
316 | void *addr; | 317 | void *addr; |
317 | 318 | ||
318 | if (pg_count != 1 && pg_count != 4) | ||
319 | return NULL; | ||
320 | |||
321 | switch (pg_count) { | 319 | switch (pg_count) { |
322 | case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge); | 320 | case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge); |
323 | global_flush_tlb(); | 321 | global_flush_tlb(); |
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index 0c9dab557c94..6cd7373dcdf4 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c | |||
@@ -320,11 +320,11 @@ static int __devinit agp_nvidia_probe(struct pci_dev *pdev, | |||
320 | u8 cap_ptr; | 320 | u8 cap_ptr; |
321 | 321 | ||
322 | nvidia_private.dev_1 = | 322 | nvidia_private.dev_1 = |
323 | pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 1)); | 323 | pci_get_bus_and_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 1)); |
324 | nvidia_private.dev_2 = | 324 | nvidia_private.dev_2 = |
325 | pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 2)); | 325 | pci_get_bus_and_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 2)); |
326 | nvidia_private.dev_3 = | 326 | nvidia_private.dev_3 = |
327 | pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(30, 0)); | 327 | pci_get_bus_and_slot((unsigned int)pdev->bus->number, PCI_DEVFN(30, 0)); |
328 | 328 | ||
329 | if (!nvidia_private.dev_1 || !nvidia_private.dev_2 || !nvidia_private.dev_3) { | 329 | if (!nvidia_private.dev_1 || !nvidia_private.dev_2 || !nvidia_private.dev_3) { |
330 | printk(KERN_INFO PFX "Detected an NVIDIA nForce/nForce2 " | 330 | printk(KERN_INFO PFX "Detected an NVIDIA nForce/nForce2 " |
@@ -443,6 +443,9 @@ static int __init agp_nvidia_init(void) | |||
443 | static void __exit agp_nvidia_cleanup(void) | 443 | static void __exit agp_nvidia_cleanup(void) |
444 | { | 444 | { |
445 | pci_unregister_driver(&agp_nvidia_pci_driver); | 445 | pci_unregister_driver(&agp_nvidia_pci_driver); |
446 | pci_dev_put(nvidia_private.dev_1); | ||
447 | pci_dev_put(nvidia_private.dev_2); | ||
448 | pci_dev_put(nvidia_private.dev_3); | ||
446 | } | 449 | } |
447 | 450 | ||
448 | module_init(agp_nvidia_init); | 451 | module_init(agp_nvidia_init); |
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c index 3d83b461ccad..f4562cc22343 100644 --- a/drivers/char/agp/parisc-agp.c +++ b/drivers/char/agp/parisc-agp.c | |||
@@ -329,7 +329,7 @@ parisc_agp_setup(void __iomem *ioc_hpa, void __iomem *lba_hpa) | |||
329 | struct agp_bridge_data *bridge; | 329 | struct agp_bridge_data *bridge; |
330 | int error = 0; | 330 | int error = 0; |
331 | 331 | ||
332 | fake_bridge_dev = kmalloc(sizeof (struct pci_dev), GFP_KERNEL); | 332 | fake_bridge_dev = alloc_pci_dev(); |
333 | if (!fake_bridge_dev) { | 333 | if (!fake_bridge_dev) { |
334 | error = -ENOMEM; | 334 | error = -ENOMEM; |
335 | goto fail; | 335 | goto fail; |
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c index ee8f50edde1b..cda608c42bea 100644 --- a/drivers/char/agp/sgi-agp.c +++ b/drivers/char/agp/sgi-agp.c | |||
@@ -47,9 +47,8 @@ static void *sgi_tioca_alloc_page(struct agp_bridge_data *bridge) | |||
47 | 47 | ||
48 | nid = info->ca_closest_node; | 48 | nid = info->ca_closest_node; |
49 | page = alloc_pages_node(nid, GFP_KERNEL, 0); | 49 | page = alloc_pages_node(nid, GFP_KERNEL, 0); |
50 | if (page == NULL) { | 50 | if (!page) |
51 | return 0; | 51 | return NULL; |
52 | } | ||
53 | 52 | ||
54 | get_page(page); | 53 | get_page(page); |
55 | SetPageLocked(page); | 54 | SetPageLocked(page); |
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c index 125f4282d955..eb1a1c738190 100644 --- a/drivers/char/agp/sis-agp.c +++ b/drivers/char/agp/sis-agp.c | |||
@@ -143,96 +143,6 @@ static struct agp_bridge_driver sis_driver = { | |||
143 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 143 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
144 | }; | 144 | }; |
145 | 145 | ||
146 | static struct agp_device_ids sis_agp_device_ids[] __devinitdata = | ||
147 | { | ||
148 | { | ||
149 | .device_id = PCI_DEVICE_ID_SI_5591_AGP, | ||
150 | .chipset_name = "5591", | ||
151 | }, | ||
152 | { | ||
153 | .device_id = PCI_DEVICE_ID_SI_530, | ||
154 | .chipset_name = "530", | ||
155 | }, | ||
156 | { | ||
157 | .device_id = PCI_DEVICE_ID_SI_540, | ||
158 | .chipset_name = "540", | ||
159 | }, | ||
160 | { | ||
161 | .device_id = PCI_DEVICE_ID_SI_550, | ||
162 | .chipset_name = "550", | ||
163 | }, | ||
164 | { | ||
165 | .device_id = PCI_DEVICE_ID_SI_620, | ||
166 | .chipset_name = "620", | ||
167 | }, | ||
168 | { | ||
169 | .device_id = PCI_DEVICE_ID_SI_630, | ||
170 | .chipset_name = "630", | ||
171 | }, | ||
172 | { | ||
173 | .device_id = PCI_DEVICE_ID_SI_635, | ||
174 | .chipset_name = "635", | ||
175 | }, | ||
176 | { | ||
177 | .device_id = PCI_DEVICE_ID_SI_645, | ||
178 | .chipset_name = "645", | ||
179 | }, | ||
180 | { | ||
181 | .device_id = PCI_DEVICE_ID_SI_646, | ||
182 | .chipset_name = "646", | ||
183 | }, | ||
184 | { | ||
185 | .device_id = PCI_DEVICE_ID_SI_648, | ||
186 | .chipset_name = "648", | ||
187 | }, | ||
188 | { | ||
189 | .device_id = PCI_DEVICE_ID_SI_650, | ||
190 | .chipset_name = "650", | ||
191 | }, | ||
192 | { | ||
193 | .device_id = PCI_DEVICE_ID_SI_651, | ||
194 | .chipset_name = "651", | ||
195 | }, | ||
196 | { | ||
197 | .device_id = PCI_DEVICE_ID_SI_655, | ||
198 | .chipset_name = "655", | ||
199 | }, | ||
200 | { | ||
201 | .device_id = PCI_DEVICE_ID_SI_661, | ||
202 | .chipset_name = "661", | ||
203 | }, | ||
204 | { | ||
205 | .device_id = PCI_DEVICE_ID_SI_730, | ||
206 | .chipset_name = "730", | ||
207 | }, | ||
208 | { | ||
209 | .device_id = PCI_DEVICE_ID_SI_735, | ||
210 | .chipset_name = "735", | ||
211 | }, | ||
212 | { | ||
213 | .device_id = PCI_DEVICE_ID_SI_740, | ||
214 | .chipset_name = "740", | ||
215 | }, | ||
216 | { | ||
217 | .device_id = PCI_DEVICE_ID_SI_741, | ||
218 | .chipset_name = "741", | ||
219 | }, | ||
220 | { | ||
221 | .device_id = PCI_DEVICE_ID_SI_745, | ||
222 | .chipset_name = "745", | ||
223 | }, | ||
224 | { | ||
225 | .device_id = PCI_DEVICE_ID_SI_746, | ||
226 | .chipset_name = "746", | ||
227 | }, | ||
228 | { | ||
229 | .device_id = PCI_DEVICE_ID_SI_760, | ||
230 | .chipset_name = "760", | ||
231 | }, | ||
232 | { }, /* dummy final entry, always present */ | ||
233 | }; | ||
234 | |||
235 | |||
236 | // chipsets that require the 'delay hack' | 146 | // chipsets that require the 'delay hack' |
237 | static int sis_broken_chipsets[] __devinitdata = { | 147 | static int sis_broken_chipsets[] __devinitdata = { |
238 | PCI_DEVICE_ID_SI_648, | 148 | PCI_DEVICE_ID_SI_648, |
@@ -269,29 +179,15 @@ static void __devinit sis_get_driver(struct agp_bridge_data *bridge) | |||
269 | static int __devinit agp_sis_probe(struct pci_dev *pdev, | 179 | static int __devinit agp_sis_probe(struct pci_dev *pdev, |
270 | const struct pci_device_id *ent) | 180 | const struct pci_device_id *ent) |
271 | { | 181 | { |
272 | struct agp_device_ids *devs = sis_agp_device_ids; | ||
273 | struct agp_bridge_data *bridge; | 182 | struct agp_bridge_data *bridge; |
274 | u8 cap_ptr; | 183 | u8 cap_ptr; |
275 | int j; | ||
276 | 184 | ||
277 | cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); | 185 | cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); |
278 | if (!cap_ptr) | 186 | if (!cap_ptr) |
279 | return -ENODEV; | 187 | return -ENODEV; |
280 | 188 | ||
281 | /* probe for known chipsets */ | ||
282 | for (j = 0; devs[j].chipset_name; j++) { | ||
283 | if (pdev->device == devs[j].device_id) { | ||
284 | printk(KERN_INFO PFX "Detected SiS %s chipset\n", | ||
285 | devs[j].chipset_name); | ||
286 | goto found; | ||
287 | } | ||
288 | } | ||
289 | |||
290 | printk(KERN_ERR PFX "Unsupported SiS chipset (device id: %04x)\n", | ||
291 | pdev->device); | ||
292 | return -ENODEV; | ||
293 | 189 | ||
294 | found: | 190 | printk(KERN_INFO PFX "Detected SiS chipset - id:%i\n", pdev->device); |
295 | bridge = agp_alloc_bridge(); | 191 | bridge = agp_alloc_bridge(); |
296 | if (!bridge) | 192 | if (!bridge) |
297 | return -ENOMEM; | 193 | return -ENOMEM; |
@@ -320,12 +216,172 @@ static void __devexit agp_sis_remove(struct pci_dev *pdev) | |||
320 | 216 | ||
321 | static struct pci_device_id agp_sis_pci_table[] = { | 217 | static struct pci_device_id agp_sis_pci_table[] = { |
322 | { | 218 | { |
323 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | 219 | .class = (PCI_CLASS_BRIDGE_HOST << 8), |
324 | .class_mask = ~0, | 220 | .class_mask = ~0, |
325 | .vendor = PCI_VENDOR_ID_SI, | 221 | .vendor = PCI_VENDOR_ID_SI, |
326 | .device = PCI_ANY_ID, | 222 | .device = PCI_DEVICE_ID_SI_5591_AGP, |
327 | .subvendor = PCI_ANY_ID, | 223 | .subvendor = PCI_ANY_ID, |
328 | .subdevice = PCI_ANY_ID, | 224 | .subdevice = PCI_ANY_ID, |
225 | }, | ||
226 | { | ||
227 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
228 | .class_mask = ~0, | ||
229 | .vendor = PCI_VENDOR_ID_SI, | ||
230 | .device = PCI_DEVICE_ID_SI_530, | ||
231 | .subvendor = PCI_ANY_ID, | ||
232 | .subdevice = PCI_ANY_ID, | ||
233 | }, | ||
234 | { | ||
235 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
236 | .class_mask = ~0, | ||
237 | .vendor = PCI_VENDOR_ID_SI, | ||
238 | .device = PCI_DEVICE_ID_SI_540, | ||
239 | .subvendor = PCI_ANY_ID, | ||
240 | .subdevice = PCI_ANY_ID, | ||
241 | }, | ||
242 | { | ||
243 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
244 | .class_mask = ~0, | ||
245 | .vendor = PCI_VENDOR_ID_SI, | ||
246 | .device = PCI_DEVICE_ID_SI_550, | ||
247 | .subvendor = PCI_ANY_ID, | ||
248 | .subdevice = PCI_ANY_ID, | ||
249 | }, | ||
250 | { | ||
251 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
252 | .class_mask = ~0, | ||
253 | .vendor = PCI_VENDOR_ID_SI, | ||
254 | .device = PCI_DEVICE_ID_SI_620, | ||
255 | .subvendor = PCI_ANY_ID, | ||
256 | .subdevice = PCI_ANY_ID, | ||
257 | }, | ||
258 | { | ||
259 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
260 | .class_mask = ~0, | ||
261 | .vendor = PCI_VENDOR_ID_SI, | ||
262 | .device = PCI_DEVICE_ID_SI_630, | ||
263 | .subvendor = PCI_ANY_ID, | ||
264 | .subdevice = PCI_ANY_ID, | ||
265 | }, | ||
266 | { | ||
267 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
268 | .class_mask = ~0, | ||
269 | .vendor = PCI_VENDOR_ID_SI, | ||
270 | .device = PCI_DEVICE_ID_SI_635, | ||
271 | .subvendor = PCI_ANY_ID, | ||
272 | .subdevice = PCI_ANY_ID, | ||
273 | }, | ||
274 | { | ||
275 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
276 | .class_mask = ~0, | ||
277 | .vendor = PCI_VENDOR_ID_SI, | ||
278 | .device = PCI_DEVICE_ID_SI_645, | ||
279 | .subvendor = PCI_ANY_ID, | ||
280 | .subdevice = PCI_ANY_ID, | ||
281 | }, | ||
282 | { | ||
283 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
284 | .class_mask = ~0, | ||
285 | .vendor = PCI_VENDOR_ID_SI, | ||
286 | .device = PCI_DEVICE_ID_SI_646, | ||
287 | .subvendor = PCI_ANY_ID, | ||
288 | .subdevice = PCI_ANY_ID, | ||
289 | }, | ||
290 | { | ||
291 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
292 | .class_mask = ~0, | ||
293 | .vendor = PCI_VENDOR_ID_SI, | ||
294 | .device = PCI_DEVICE_ID_SI_648, | ||
295 | .subvendor = PCI_ANY_ID, | ||
296 | .subdevice = PCI_ANY_ID, | ||
297 | }, | ||
298 | { | ||
299 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
300 | .class_mask = ~0, | ||
301 | .vendor = PCI_VENDOR_ID_SI, | ||
302 | .device = PCI_DEVICE_ID_SI_650, | ||
303 | .subvendor = PCI_ANY_ID, | ||
304 | .subdevice = PCI_ANY_ID, | ||
305 | }, | ||
306 | { | ||
307 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
308 | .class_mask = ~0, | ||
309 | .vendor = PCI_VENDOR_ID_SI, | ||
310 | .device = PCI_DEVICE_ID_SI_651, | ||
311 | .subvendor = PCI_ANY_ID, | ||
312 | .subdevice = PCI_ANY_ID, | ||
313 | }, | ||
314 | { | ||
315 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
316 | .class_mask = ~0, | ||
317 | .vendor = PCI_VENDOR_ID_SI, | ||
318 | .device = PCI_DEVICE_ID_SI_655, | ||
319 | .subvendor = PCI_ANY_ID, | ||
320 | .subdevice = PCI_ANY_ID, | ||
321 | }, | ||
322 | { | ||
323 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
324 | .class_mask = ~0, | ||
325 | .vendor = PCI_VENDOR_ID_SI, | ||
326 | .device = PCI_DEVICE_ID_SI_661, | ||
327 | .subvendor = PCI_ANY_ID, | ||
328 | .subdevice = PCI_ANY_ID, | ||
329 | }, | ||
330 | { | ||
331 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
332 | .class_mask = ~0, | ||
333 | .vendor = PCI_VENDOR_ID_SI, | ||
334 | .device = PCI_DEVICE_ID_SI_730, | ||
335 | .subvendor = PCI_ANY_ID, | ||
336 | .subdevice = PCI_ANY_ID, | ||
337 | }, | ||
338 | { | ||
339 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
340 | .class_mask = ~0, | ||
341 | .vendor = PCI_VENDOR_ID_SI, | ||
342 | .device = PCI_DEVICE_ID_SI_735, | ||
343 | .subvendor = PCI_ANY_ID, | ||
344 | .subdevice = PCI_ANY_ID, | ||
345 | }, | ||
346 | { | ||
347 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
348 | .class_mask = ~0, | ||
349 | .vendor = PCI_VENDOR_ID_SI, | ||
350 | .device = PCI_DEVICE_ID_SI_740, | ||
351 | .subvendor = PCI_ANY_ID, | ||
352 | .subdevice = PCI_ANY_ID, | ||
353 | }, | ||
354 | { | ||
355 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
356 | .class_mask = ~0, | ||
357 | .vendor = PCI_VENDOR_ID_SI, | ||
358 | .device = PCI_DEVICE_ID_SI_741, | ||
359 | .subvendor = PCI_ANY_ID, | ||
360 | .subdevice = PCI_ANY_ID, | ||
361 | }, | ||
362 | { | ||
363 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
364 | .class_mask = ~0, | ||
365 | .vendor = PCI_VENDOR_ID_SI, | ||
366 | .device = PCI_DEVICE_ID_SI_745, | ||
367 | .subvendor = PCI_ANY_ID, | ||
368 | .subdevice = PCI_ANY_ID, | ||
369 | }, | ||
370 | { | ||
371 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
372 | .class_mask = ~0, | ||
373 | .vendor = PCI_VENDOR_ID_SI, | ||
374 | .device = PCI_DEVICE_ID_SI_746, | ||
375 | .subvendor = PCI_ANY_ID, | ||
376 | .subdevice = PCI_ANY_ID, | ||
377 | }, | ||
378 | { | ||
379 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
380 | .class_mask = ~0, | ||
381 | .vendor = PCI_VENDOR_ID_SI, | ||
382 | .device = PCI_DEVICE_ID_SI_760, | ||
383 | .subvendor = PCI_ANY_ID, | ||
384 | .subdevice = PCI_ANY_ID, | ||
329 | }, | 385 | }, |
330 | { } | 386 | { } |
331 | }; | 387 | }; |
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index 55212a3811fd..551ef25063ef 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c | |||
@@ -455,15 +455,6 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev, | |||
455 | u32 temp, temp2; | 455 | u32 temp, temp2; |
456 | u8 cap_ptr = 0; | 456 | u8 cap_ptr = 0; |
457 | 457 | ||
458 | /* Everything is on func 1 here so we are hardcoding function one */ | ||
459 | bridge_dev = pci_find_slot((unsigned int)pdev->bus->number, | ||
460 | PCI_DEVFN(0, 1)); | ||
461 | if (!bridge_dev) { | ||
462 | printk(KERN_INFO PFX "Detected a Serverworks chipset " | ||
463 | "but could not find the secondary device.\n"); | ||
464 | return -ENODEV; | ||
465 | } | ||
466 | |||
467 | cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); | 458 | cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); |
468 | 459 | ||
469 | switch (pdev->device) { | 460 | switch (pdev->device) { |
@@ -483,6 +474,15 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev, | |||
483 | return -ENODEV; | 474 | return -ENODEV; |
484 | } | 475 | } |
485 | 476 | ||
477 | /* Everything is on func 1 here so we are hardcoding function one */ | ||
478 | bridge_dev = pci_get_bus_and_slot((unsigned int)pdev->bus->number, | ||
479 | PCI_DEVFN(0, 1)); | ||
480 | if (!bridge_dev) { | ||
481 | printk(KERN_INFO PFX "Detected a Serverworks chipset " | ||
482 | "but could not find the secondary device.\n"); | ||
483 | return -ENODEV; | ||
484 | } | ||
485 | |||
486 | serverworks_private.svrwrks_dev = bridge_dev; | 486 | serverworks_private.svrwrks_dev = bridge_dev; |
487 | serverworks_private.gart_addr_ofs = 0x10; | 487 | serverworks_private.gart_addr_ofs = 0x10; |
488 | 488 | ||
@@ -515,7 +515,7 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev, | |||
515 | 515 | ||
516 | bridge->driver = &sworks_driver; | 516 | bridge->driver = &sworks_driver; |
517 | bridge->dev_private_data = &serverworks_private, | 517 | bridge->dev_private_data = &serverworks_private, |
518 | bridge->dev = pdev; | 518 | bridge->dev = pci_dev_get(pdev); |
519 | 519 | ||
520 | pci_set_drvdata(pdev, bridge); | 520 | pci_set_drvdata(pdev, bridge); |
521 | return agp_add_bridge(bridge); | 521 | return agp_add_bridge(bridge); |
@@ -525,8 +525,11 @@ static void __devexit agp_serverworks_remove(struct pci_dev *pdev) | |||
525 | { | 525 | { |
526 | struct agp_bridge_data *bridge = pci_get_drvdata(pdev); | 526 | struct agp_bridge_data *bridge = pci_get_drvdata(pdev); |
527 | 527 | ||
528 | pci_dev_put(bridge->dev); | ||
528 | agp_remove_bridge(bridge); | 529 | agp_remove_bridge(bridge); |
529 | agp_put_bridge(bridge); | 530 | agp_put_bridge(bridge); |
531 | pci_dev_put(serverworks_private.svrwrks_dev); | ||
532 | serverworks_private.svrwrks_dev = NULL; | ||
530 | } | 533 | } |
531 | 534 | ||
532 | static struct pci_device_id agp_serverworks_pci_table[] = { | 535 | static struct pci_device_id agp_serverworks_pci_table[] = { |
diff --git a/drivers/char/drm/README.drm b/drivers/char/drm/README.drm index 6441e01e587c..af74cd79a279 100644 --- a/drivers/char/drm/README.drm +++ b/drivers/char/drm/README.drm | |||
@@ -1,6 +1,6 @@ | |||
1 | ************************************************************ | 1 | ************************************************************ |
2 | * For the very latest on DRI development, please see: * | 2 | * For the very latest on DRI development, please see: * |
3 | * http://dri.sourceforge.net/ * | 3 | * http://dri.freedesktop.org/ * |
4 | ************************************************************ | 4 | ************************************************************ |
5 | 5 | ||
6 | The Direct Rendering Manager (drm) is a device-independent kernel-level | 6 | The Direct Rendering Manager (drm) is a device-independent kernel-level |
@@ -26,21 +26,19 @@ ways: | |||
26 | 26 | ||
27 | 27 | ||
28 | Documentation on the DRI is available from: | 28 | Documentation on the DRI is available from: |
29 | http://precisioninsight.com/piinsights.html | 29 | http://dri.freedesktop.org/wiki/Documentation |
30 | http://sourceforge.net/project/showfiles.php?group_id=387 | ||
31 | http://dri.sourceforge.net/doc/ | ||
30 | 32 | ||
31 | For specific information about kernel-level support, see: | 33 | For specific information about kernel-level support, see: |
32 | 34 | ||
33 | The Direct Rendering Manager, Kernel Support for the Direct Rendering | 35 | The Direct Rendering Manager, Kernel Support for the Direct Rendering |
34 | Infrastructure | 36 | Infrastructure |
35 | http://precisioninsight.com/dr/drm.html | 37 | http://dri.sourceforge.net/doc/drm_low_level.html |
36 | 38 | ||
37 | Hardware Locking for the Direct Rendering Infrastructure | 39 | Hardware Locking for the Direct Rendering Infrastructure |
38 | http://precisioninsight.com/dr/locking.html | 40 | http://dri.sourceforge.net/doc/hardware_locking_low_level.html |
39 | 41 | ||
40 | A Security Analysis of the Direct Rendering Infrastructure | 42 | A Security Analysis of the Direct Rendering Infrastructure |
41 | http://precisioninsight.com/dr/security.html | 43 | http://dri.sourceforge.net/doc/security_low_level.html |
42 | 44 | ||
43 | ************************************************************ | ||
44 | * For the very latest on DRI development, please see: * | ||
45 | * http://dri.sourceforge.net/ * | ||
46 | ************************************************************ | ||
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h index 8db9041e306c..089198491f16 100644 --- a/drivers/char/drm/drm.h +++ b/drivers/char/drm/drm.h | |||
@@ -654,11 +654,13 @@ typedef struct drm_set_version { | |||
654 | 654 | ||
655 | /** | 655 | /** |
656 | * Device specific ioctls should only be in their respective headers | 656 | * Device specific ioctls should only be in their respective headers |
657 | * The device specific ioctl range is from 0x40 to 0x79. | 657 | * The device specific ioctl range is from 0x40 to 0x99. |
658 | * Generic IOCTLS restart at 0xA0. | ||
658 | * | 659 | * |
659 | * \sa drmCommandNone(), drmCommandRead(), drmCommandWrite(), and | 660 | * \sa drmCommandNone(), drmCommandRead(), drmCommandWrite(), and |
660 | * drmCommandReadWrite(). | 661 | * drmCommandReadWrite(). |
661 | */ | 662 | */ |
662 | #define DRM_COMMAND_BASE 0x40 | 663 | #define DRM_COMMAND_BASE 0x40 |
664 | #define DRM_COMMAND_END 0xA0 | ||
663 | 665 | ||
664 | #endif | 666 | #endif |
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 85d99e21e188..80041d5b792d 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -414,6 +414,10 @@ typedef struct drm_lock_data { | |||
414 | struct file *filp; /**< File descr of lock holder (0=kernel) */ | 414 | struct file *filp; /**< File descr of lock holder (0=kernel) */ |
415 | wait_queue_head_t lock_queue; /**< Queue of blocked processes */ | 415 | wait_queue_head_t lock_queue; /**< Queue of blocked processes */ |
416 | unsigned long lock_time; /**< Time of last lock in jiffies */ | 416 | unsigned long lock_time; /**< Time of last lock in jiffies */ |
417 | spinlock_t spinlock; | ||
418 | uint32_t kernel_waiters; | ||
419 | uint32_t user_waiters; | ||
420 | int idle_has_lock; | ||
417 | } drm_lock_data_t; | 421 | } drm_lock_data_t; |
418 | 422 | ||
419 | /** | 423 | /** |
@@ -590,6 +594,8 @@ struct drm_driver { | |||
590 | void (*reclaim_buffers) (struct drm_device * dev, struct file * filp); | 594 | void (*reclaim_buffers) (struct drm_device * dev, struct file * filp); |
591 | void (*reclaim_buffers_locked) (struct drm_device *dev, | 595 | void (*reclaim_buffers_locked) (struct drm_device *dev, |
592 | struct file *filp); | 596 | struct file *filp); |
597 | void (*reclaim_buffers_idlelocked) (struct drm_device *dev, | ||
598 | struct file * filp); | ||
593 | unsigned long (*get_map_ofs) (drm_map_t * map); | 599 | unsigned long (*get_map_ofs) (drm_map_t * map); |
594 | unsigned long (*get_reg_ofs) (struct drm_device * dev); | 600 | unsigned long (*get_reg_ofs) (struct drm_device * dev); |
595 | void (*set_version) (struct drm_device * dev, drm_set_version_t * sv); | 601 | void (*set_version) (struct drm_device * dev, drm_set_version_t * sv); |
@@ -764,7 +770,7 @@ static __inline__ int drm_core_check_feature(struct drm_device *dev, | |||
764 | } | 770 | } |
765 | 771 | ||
766 | #ifdef __alpha__ | 772 | #ifdef __alpha__ |
767 | #define drm_get_pci_domain(dev) dev->hose->bus->number | 773 | #define drm_get_pci_domain(dev) dev->hose->index |
768 | #else | 774 | #else |
769 | #define drm_get_pci_domain(dev) 0 | 775 | #define drm_get_pci_domain(dev) 0 |
770 | #endif | 776 | #endif |
@@ -915,9 +921,18 @@ extern int drm_lock(struct inode *inode, struct file *filp, | |||
915 | unsigned int cmd, unsigned long arg); | 921 | unsigned int cmd, unsigned long arg); |
916 | extern int drm_unlock(struct inode *inode, struct file *filp, | 922 | extern int drm_unlock(struct inode *inode, struct file *filp, |
917 | unsigned int cmd, unsigned long arg); | 923 | unsigned int cmd, unsigned long arg); |
918 | extern int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context); | 924 | extern int drm_lock_take(drm_lock_data_t *lock_data, unsigned int context); |
919 | extern int drm_lock_free(drm_device_t * dev, | 925 | extern int drm_lock_free(drm_lock_data_t *lock_data, unsigned int context); |
920 | __volatile__ unsigned int *lock, unsigned int context); | 926 | extern void drm_idlelock_take(drm_lock_data_t *lock_data); |
927 | extern void drm_idlelock_release(drm_lock_data_t *lock_data); | ||
928 | |||
929 | /* | ||
930 | * These are exported to drivers so that they can implement fencing using | ||
931 | * DMA quiscent + idle. DMA quiescent usually requires the hardware lock. | ||
932 | */ | ||
933 | |||
934 | extern int drm_i_have_hw_lock(struct file *filp); | ||
935 | extern int drm_kernel_take_hw_lock(struct file *filp); | ||
921 | 936 | ||
922 | /* Buffer management support (drm_bufs.h) */ | 937 | /* Buffer management support (drm_bufs.h) */ |
923 | extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request); | 938 | extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request); |
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index a6828cc14e58..c11345856ffe 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c | |||
@@ -57,7 +57,8 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev, | |||
57 | list_for_each(list, &dev->maplist->head) { | 57 | list_for_each(list, &dev->maplist->head) { |
58 | drm_map_list_t *entry = list_entry(list, drm_map_list_t, head); | 58 | drm_map_list_t *entry = list_entry(list, drm_map_list_t, head); |
59 | if (entry->map && map->type == entry->map->type && | 59 | if (entry->map && map->type == entry->map->type && |
60 | entry->map->offset == map->offset) { | 60 | ((entry->map->offset == map->offset) || |
61 | (map->type == _DRM_SHM && map->flags==_DRM_CONTAINS_LOCK))) { | ||
61 | return entry; | 62 | return entry; |
62 | } | 63 | } |
63 | } | 64 | } |
@@ -180,8 +181,20 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, | |||
180 | if (map->type == _DRM_REGISTERS) | 181 | if (map->type == _DRM_REGISTERS) |
181 | map->handle = ioremap(map->offset, map->size); | 182 | map->handle = ioremap(map->offset, map->size); |
182 | break; | 183 | break; |
183 | |||
184 | case _DRM_SHM: | 184 | case _DRM_SHM: |
185 | list = drm_find_matching_map(dev, map); | ||
186 | if (list != NULL) { | ||
187 | if(list->map->size != map->size) { | ||
188 | DRM_DEBUG("Matching maps of type %d with " | ||
189 | "mismatched sizes, (%ld vs %ld)\n", | ||
190 | map->type, map->size, list->map->size); | ||
191 | list->map->size = map->size; | ||
192 | } | ||
193 | |||
194 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | ||
195 | *maplist = list; | ||
196 | return 0; | ||
197 | } | ||
185 | map->handle = vmalloc_user(map->size); | 198 | map->handle = vmalloc_user(map->size); |
186 | DRM_DEBUG("%lu %d %p\n", | 199 | DRM_DEBUG("%lu %d %p\n", |
187 | map->size, drm_order(map->size), map->handle); | 200 | map->size, drm_order(map->size), map->handle); |
@@ -200,15 +213,45 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, | |||
200 | dev->sigdata.lock = dev->lock.hw_lock = map->handle; /* Pointer to lock */ | 213 | dev->sigdata.lock = dev->lock.hw_lock = map->handle; /* Pointer to lock */ |
201 | } | 214 | } |
202 | break; | 215 | break; |
203 | case _DRM_AGP: | 216 | case _DRM_AGP: { |
204 | if (drm_core_has_AGP(dev)) { | 217 | drm_agp_mem_t *entry; |
218 | int valid = 0; | ||
219 | |||
220 | if (!drm_core_has_AGP(dev)) { | ||
221 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | ||
222 | return -EINVAL; | ||
223 | } | ||
205 | #ifdef __alpha__ | 224 | #ifdef __alpha__ |
206 | map->offset += dev->hose->mem_space->start; | 225 | map->offset += dev->hose->mem_space->start; |
207 | #endif | 226 | #endif |
208 | map->offset += dev->agp->base; | 227 | /* Note: dev->agp->base may actually be 0 when the DRM |
209 | map->mtrr = dev->agp->agp_mtrr; /* for getmap */ | 228 | * is not in control of AGP space. But if user space is |
229 | * it should already have added the AGP base itself. | ||
230 | */ | ||
231 | map->offset += dev->agp->base; | ||
232 | map->mtrr = dev->agp->agp_mtrr; /* for getmap */ | ||
233 | |||
234 | /* This assumes the DRM is in total control of AGP space. | ||
235 | * It's not always the case as AGP can be in the control | ||
236 | * of user space (i.e. i810 driver). So this loop will get | ||
237 | * skipped and we double check that dev->agp->memory is | ||
238 | * actually set as well as being invalid before EPERM'ing | ||
239 | */ | ||
240 | for (entry = dev->agp->memory; entry; entry = entry->next) { | ||
241 | if ((map->offset >= entry->bound) && | ||
242 | (map->offset + map->size <= entry->bound + entry->pages * PAGE_SIZE)) { | ||
243 | valid = 1; | ||
244 | break; | ||
245 | } | ||
210 | } | 246 | } |
247 | if (dev->agp->memory && !valid) { | ||
248 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | ||
249 | return -EPERM; | ||
250 | } | ||
251 | DRM_DEBUG("AGP offset = 0x%08lx, size = 0x%08lx\n", map->offset, map->size); | ||
252 | |||
211 | break; | 253 | break; |
254 | } | ||
212 | case _DRM_SCATTER_GATHER: | 255 | case _DRM_SCATTER_GATHER: |
213 | if (!dev->sg) { | 256 | if (!dev->sg) { |
214 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 257 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); |
@@ -267,7 +310,7 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, | |||
267 | 310 | ||
268 | *maplist = list; | 311 | *maplist = list; |
269 | return 0; | 312 | return 0; |
270 | } | 313 | } |
271 | 314 | ||
272 | int drm_addmap(drm_device_t * dev, unsigned int offset, | 315 | int drm_addmap(drm_device_t * dev, unsigned int offset, |
273 | unsigned int size, drm_map_type_t type, | 316 | unsigned int size, drm_map_type_t type, |
@@ -519,6 +562,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) | |||
519 | { | 562 | { |
520 | drm_device_dma_t *dma = dev->dma; | 563 | drm_device_dma_t *dma = dev->dma; |
521 | drm_buf_entry_t *entry; | 564 | drm_buf_entry_t *entry; |
565 | drm_agp_mem_t *agp_entry; | ||
522 | drm_buf_t *buf; | 566 | drm_buf_t *buf; |
523 | unsigned long offset; | 567 | unsigned long offset; |
524 | unsigned long agp_offset; | 568 | unsigned long agp_offset; |
@@ -529,7 +573,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) | |||
529 | int page_order; | 573 | int page_order; |
530 | int total; | 574 | int total; |
531 | int byte_count; | 575 | int byte_count; |
532 | int i; | 576 | int i, valid; |
533 | drm_buf_t **temp_buflist; | 577 | drm_buf_t **temp_buflist; |
534 | 578 | ||
535 | if (!dma) | 579 | if (!dma) |
@@ -560,6 +604,19 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) | |||
560 | if (dev->queue_count) | 604 | if (dev->queue_count) |
561 | return -EBUSY; /* Not while in use */ | 605 | return -EBUSY; /* Not while in use */ |
562 | 606 | ||
607 | /* Make sure buffers are located in AGP memory that we own */ | ||
608 | valid = 0; | ||
609 | for (agp_entry = dev->agp->memory; agp_entry; agp_entry = agp_entry->next) { | ||
610 | if ((agp_offset >= agp_entry->bound) && | ||
611 | (agp_offset + total * count <= agp_entry->bound + agp_entry->pages * PAGE_SIZE)) { | ||
612 | valid = 1; | ||
613 | break; | ||
614 | } | ||
615 | } | ||
616 | if (dev->agp->memory && !valid) { | ||
617 | DRM_DEBUG("zone invalid\n"); | ||
618 | return -EINVAL; | ||
619 | } | ||
563 | spin_lock(&dev->count_lock); | 620 | spin_lock(&dev->count_lock); |
564 | if (dev->buf_use) { | 621 | if (dev->buf_use) { |
565 | spin_unlock(&dev->count_lock); | 622 | spin_unlock(&dev->count_lock); |
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c index f5b9b2480c14..26bec30ee86e 100644 --- a/drivers/char/drm/drm_drv.c +++ b/drivers/char/drm/drm_drv.c | |||
@@ -496,11 +496,14 @@ int drm_ioctl(struct inode *inode, struct file *filp, | |||
496 | (long)old_encode_dev(priv->head->device), | 496 | (long)old_encode_dev(priv->head->device), |
497 | priv->authenticated); | 497 | priv->authenticated); |
498 | 498 | ||
499 | if (nr < DRIVER_IOCTL_COUNT) | 499 | if ((nr >= DRIVER_IOCTL_COUNT) && |
500 | ioctl = &drm_ioctls[nr]; | 500 | ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END))) |
501 | else if ((nr >= DRM_COMMAND_BASE) | 501 | goto err_i1; |
502 | if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) | ||
502 | && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) | 503 | && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) |
503 | ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; | 504 | ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; |
505 | else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) | ||
506 | ioctl = &drm_ioctls[nr]; | ||
504 | else | 507 | else |
505 | goto err_i1; | 508 | goto err_i1; |
506 | 509 | ||
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c index 898f47dafec0..3b159cab3bc8 100644 --- a/drivers/char/drm/drm_fops.c +++ b/drivers/char/drm/drm_fops.c | |||
@@ -46,6 +46,7 @@ static int drm_setup(drm_device_t * dev) | |||
46 | drm_local_map_t *map; | 46 | drm_local_map_t *map; |
47 | int i; | 47 | int i; |
48 | int ret; | 48 | int ret; |
49 | u32 sareapage; | ||
49 | 50 | ||
50 | if (dev->driver->firstopen) { | 51 | if (dev->driver->firstopen) { |
51 | ret = dev->driver->firstopen(dev); | 52 | ret = dev->driver->firstopen(dev); |
@@ -56,7 +57,8 @@ static int drm_setup(drm_device_t * dev) | |||
56 | dev->magicfree.next = NULL; | 57 | dev->magicfree.next = NULL; |
57 | 58 | ||
58 | /* prebuild the SAREA */ | 59 | /* prebuild the SAREA */ |
59 | i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, _DRM_CONTAINS_LOCK, &map); | 60 | sareapage = max_t(unsigned, SAREA_MAX, PAGE_SIZE); |
61 | i = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK, &map); | ||
60 | if (i != 0) | 62 | if (i != 0) |
61 | return i; | 63 | return i; |
62 | 64 | ||
@@ -84,7 +86,7 @@ static int drm_setup(drm_device_t * dev) | |||
84 | INIT_LIST_HEAD(&dev->ctxlist->head); | 86 | INIT_LIST_HEAD(&dev->ctxlist->head); |
85 | 87 | ||
86 | dev->vmalist = NULL; | 88 | dev->vmalist = NULL; |
87 | dev->sigdata.lock = dev->lock.hw_lock = NULL; | 89 | dev->sigdata.lock = NULL; |
88 | init_waitqueue_head(&dev->lock.lock_queue); | 90 | init_waitqueue_head(&dev->lock.lock_queue); |
89 | dev->queue_count = 0; | 91 | dev->queue_count = 0; |
90 | dev->queue_reserved = 0; | 92 | dev->queue_reserved = 0; |
@@ -354,58 +356,56 @@ int drm_release(struct inode *inode, struct file *filp) | |||
354 | current->pid, (long)old_encode_dev(priv->head->device), | 356 | current->pid, (long)old_encode_dev(priv->head->device), |
355 | dev->open_count); | 357 | dev->open_count); |
356 | 358 | ||
357 | if (priv->lock_count && dev->lock.hw_lock && | 359 | if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) { |
358 | _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && | 360 | if (drm_i_have_hw_lock(filp)) { |
359 | dev->lock.filp == filp) { | ||
360 | DRM_DEBUG("File %p released, freeing lock for context %d\n", | ||
361 | filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); | ||
362 | |||
363 | if (dev->driver->reclaim_buffers_locked) | ||
364 | dev->driver->reclaim_buffers_locked(dev, filp); | 361 | dev->driver->reclaim_buffers_locked(dev, filp); |
365 | 362 | } else { | |
366 | drm_lock_free(dev, &dev->lock.hw_lock->lock, | 363 | unsigned long _end=jiffies + 3*DRM_HZ; |
367 | _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); | 364 | int locked = 0; |
368 | 365 | ||
369 | /* FIXME: may require heavy-handed reset of | 366 | drm_idlelock_take(&dev->lock); |
370 | hardware at this point, possibly | 367 | |
371 | processed via a callback to the X | 368 | /* |
372 | server. */ | 369 | * Wait for a while. |
373 | } else if (dev->driver->reclaim_buffers_locked && priv->lock_count | 370 | */ |
374 | && dev->lock.hw_lock) { | 371 | |
375 | /* The lock is required to reclaim buffers */ | 372 | do{ |
376 | DECLARE_WAITQUEUE(entry, current); | 373 | spin_lock(&dev->lock.spinlock); |
377 | 374 | locked = dev->lock.idle_has_lock; | |
378 | add_wait_queue(&dev->lock.lock_queue, &entry); | 375 | spin_unlock(&dev->lock.spinlock); |
379 | for (;;) { | 376 | if (locked) |
380 | __set_current_state(TASK_INTERRUPTIBLE); | 377 | break; |
381 | if (!dev->lock.hw_lock) { | 378 | schedule(); |
382 | /* Device has been unregistered */ | 379 | } while (!time_after_eq(jiffies, _end)); |
383 | retcode = -EINTR; | 380 | |
384 | break; | 381 | if (!locked) { |
382 | DRM_ERROR("reclaim_buffers_locked() deadlock. Please rework this\n" | ||
383 | "\tdriver to use reclaim_buffers_idlelocked() instead.\n" | ||
384 | "\tI will go on reclaiming the buffers anyway.\n"); | ||
385 | } | 385 | } |
386 | if (drm_lock_take(&dev->lock.hw_lock->lock, | 386 | |
387 | DRM_KERNEL_CONTEXT)) { | ||
388 | dev->lock.filp = filp; | ||
389 | dev->lock.lock_time = jiffies; | ||
390 | atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); | ||
391 | break; /* Got lock */ | ||
392 | } | ||
393 | /* Contention */ | ||
394 | schedule(); | ||
395 | if (signal_pending(current)) { | ||
396 | retcode = -ERESTARTSYS; | ||
397 | break; | ||
398 | } | ||
399 | } | ||
400 | __set_current_state(TASK_RUNNING); | ||
401 | remove_wait_queue(&dev->lock.lock_queue, &entry); | ||
402 | if (!retcode) { | ||
403 | dev->driver->reclaim_buffers_locked(dev, filp); | 387 | dev->driver->reclaim_buffers_locked(dev, filp); |
404 | drm_lock_free(dev, &dev->lock.hw_lock->lock, | 388 | drm_idlelock_release(&dev->lock); |
405 | DRM_KERNEL_CONTEXT); | ||
406 | } | 389 | } |
407 | } | 390 | } |
408 | 391 | ||
392 | if (dev->driver->reclaim_buffers_idlelocked && dev->lock.hw_lock) { | ||
393 | |||
394 | drm_idlelock_take(&dev->lock); | ||
395 | dev->driver->reclaim_buffers_idlelocked(dev, filp); | ||
396 | drm_idlelock_release(&dev->lock); | ||
397 | |||
398 | } | ||
399 | |||
400 | if (drm_i_have_hw_lock(filp)) { | ||
401 | DRM_DEBUG("File %p released, freeing lock for context %d\n", | ||
402 | filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); | ||
403 | |||
404 | drm_lock_free(&dev->lock, | ||
405 | _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); | ||
406 | } | ||
407 | |||
408 | |||
409 | if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && | 409 | if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && |
410 | !dev->driver->reclaim_buffers_locked) { | 410 | !dev->driver->reclaim_buffers_locked) { |
411 | dev->driver->reclaim_buffers(dev, filp); | 411 | dev->driver->reclaim_buffers(dev, filp); |
diff --git a/drivers/char/drm/drm_hashtab.c b/drivers/char/drm/drm_hashtab.c index a0b2d6802ae4..31acb621dcce 100644 --- a/drivers/char/drm/drm_hashtab.c +++ b/drivers/char/drm/drm_hashtab.c | |||
@@ -43,7 +43,16 @@ int drm_ht_create(drm_open_hash_t *ht, unsigned int order) | |||
43 | ht->size = 1 << order; | 43 | ht->size = 1 << order; |
44 | ht->order = order; | 44 | ht->order = order; |
45 | ht->fill = 0; | 45 | ht->fill = 0; |
46 | ht->table = vmalloc(ht->size*sizeof(*ht->table)); | 46 | ht->table = NULL; |
47 | ht->use_vmalloc = ((ht->size * sizeof(*ht->table)) > PAGE_SIZE); | ||
48 | if (!ht->use_vmalloc) { | ||
49 | ht->table = drm_calloc(ht->size, sizeof(*ht->table), | ||
50 | DRM_MEM_HASHTAB); | ||
51 | } | ||
52 | if (!ht->table) { | ||
53 | ht->use_vmalloc = 1; | ||
54 | ht->table = vmalloc(ht->size*sizeof(*ht->table)); | ||
55 | } | ||
47 | if (!ht->table) { | 56 | if (!ht->table) { |
48 | DRM_ERROR("Out of memory for hash table\n"); | 57 | DRM_ERROR("Out of memory for hash table\n"); |
49 | return -ENOMEM; | 58 | return -ENOMEM; |
@@ -183,7 +192,11 @@ int drm_ht_remove_item(drm_open_hash_t *ht, drm_hash_item_t *item) | |||
183 | void drm_ht_remove(drm_open_hash_t *ht) | 192 | void drm_ht_remove(drm_open_hash_t *ht) |
184 | { | 193 | { |
185 | if (ht->table) { | 194 | if (ht->table) { |
186 | vfree(ht->table); | 195 | if (ht->use_vmalloc) |
196 | vfree(ht->table); | ||
197 | else | ||
198 | drm_free(ht->table, ht->size * sizeof(*ht->table), | ||
199 | DRM_MEM_HASHTAB); | ||
187 | ht->table = NULL; | 200 | ht->table = NULL; |
188 | } | 201 | } |
189 | } | 202 | } |
diff --git a/drivers/char/drm/drm_hashtab.h b/drivers/char/drm/drm_hashtab.h index 40afec05bff8..613091c970af 100644 --- a/drivers/char/drm/drm_hashtab.h +++ b/drivers/char/drm/drm_hashtab.h | |||
@@ -47,6 +47,7 @@ typedef struct drm_open_hash{ | |||
47 | unsigned int order; | 47 | unsigned int order; |
48 | unsigned int fill; | 48 | unsigned int fill; |
49 | struct hlist_head *table; | 49 | struct hlist_head *table; |
50 | int use_vmalloc; | ||
50 | } drm_open_hash_t; | 51 | } drm_open_hash_t; |
51 | 52 | ||
52 | 53 | ||
diff --git a/drivers/char/drm/drm_irq.c b/drivers/char/drm/drm_irq.c index 9d00c51fe2c4..2e75331fd83e 100644 --- a/drivers/char/drm/drm_irq.c +++ b/drivers/char/drm/drm_irq.c | |||
@@ -424,7 +424,7 @@ static void drm_locked_tasklet_func(unsigned long data) | |||
424 | spin_lock_irqsave(&dev->tasklet_lock, irqflags); | 424 | spin_lock_irqsave(&dev->tasklet_lock, irqflags); |
425 | 425 | ||
426 | if (!dev->locked_tasklet_func || | 426 | if (!dev->locked_tasklet_func || |
427 | !drm_lock_take(&dev->lock.hw_lock->lock, | 427 | !drm_lock_take(&dev->lock, |
428 | DRM_KERNEL_CONTEXT)) { | 428 | DRM_KERNEL_CONTEXT)) { |
429 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); | 429 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); |
430 | return; | 430 | return; |
@@ -435,7 +435,7 @@ static void drm_locked_tasklet_func(unsigned long data) | |||
435 | 435 | ||
436 | dev->locked_tasklet_func(dev); | 436 | dev->locked_tasklet_func(dev); |
437 | 437 | ||
438 | drm_lock_free(dev, &dev->lock.hw_lock->lock, | 438 | drm_lock_free(&dev->lock, |
439 | DRM_KERNEL_CONTEXT); | 439 | DRM_KERNEL_CONTEXT); |
440 | 440 | ||
441 | dev->locked_tasklet_func = NULL; | 441 | dev->locked_tasklet_func = NULL; |
diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c index e9993ba461a2..befd1af19dfe 100644 --- a/drivers/char/drm/drm_lock.c +++ b/drivers/char/drm/drm_lock.c | |||
@@ -35,9 +35,6 @@ | |||
35 | 35 | ||
36 | #include "drmP.h" | 36 | #include "drmP.h" |
37 | 37 | ||
38 | static int drm_lock_transfer(drm_device_t * dev, | ||
39 | __volatile__ unsigned int *lock, | ||
40 | unsigned int context); | ||
41 | static int drm_notifier(void *priv); | 38 | static int drm_notifier(void *priv); |
42 | 39 | ||
43 | /** | 40 | /** |
@@ -80,6 +77,9 @@ int drm_lock(struct inode *inode, struct file *filp, | |||
80 | return -EINVAL; | 77 | return -EINVAL; |
81 | 78 | ||
82 | add_wait_queue(&dev->lock.lock_queue, &entry); | 79 | add_wait_queue(&dev->lock.lock_queue, &entry); |
80 | spin_lock(&dev->lock.spinlock); | ||
81 | dev->lock.user_waiters++; | ||
82 | spin_unlock(&dev->lock.spinlock); | ||
83 | for (;;) { | 83 | for (;;) { |
84 | __set_current_state(TASK_INTERRUPTIBLE); | 84 | __set_current_state(TASK_INTERRUPTIBLE); |
85 | if (!dev->lock.hw_lock) { | 85 | if (!dev->lock.hw_lock) { |
@@ -87,7 +87,7 @@ int drm_lock(struct inode *inode, struct file *filp, | |||
87 | ret = -EINTR; | 87 | ret = -EINTR; |
88 | break; | 88 | break; |
89 | } | 89 | } |
90 | if (drm_lock_take(&dev->lock.hw_lock->lock, lock.context)) { | 90 | if (drm_lock_take(&dev->lock, lock.context)) { |
91 | dev->lock.filp = filp; | 91 | dev->lock.filp = filp; |
92 | dev->lock.lock_time = jiffies; | 92 | dev->lock.lock_time = jiffies; |
93 | atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); | 93 | atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); |
@@ -101,12 +101,14 @@ int drm_lock(struct inode *inode, struct file *filp, | |||
101 | break; | 101 | break; |
102 | } | 102 | } |
103 | } | 103 | } |
104 | spin_lock(&dev->lock.spinlock); | ||
105 | dev->lock.user_waiters--; | ||
106 | spin_unlock(&dev->lock.spinlock); | ||
104 | __set_current_state(TASK_RUNNING); | 107 | __set_current_state(TASK_RUNNING); |
105 | remove_wait_queue(&dev->lock.lock_queue, &entry); | 108 | remove_wait_queue(&dev->lock.lock_queue, &entry); |
106 | 109 | ||
107 | DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock"); | 110 | DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" ); |
108 | if (ret) | 111 | if (ret) return ret; |
109 | return ret; | ||
110 | 112 | ||
111 | sigemptyset(&dev->sigmask); | 113 | sigemptyset(&dev->sigmask); |
112 | sigaddset(&dev->sigmask, SIGSTOP); | 114 | sigaddset(&dev->sigmask, SIGSTOP); |
@@ -127,14 +129,12 @@ int drm_lock(struct inode *inode, struct file *filp, | |||
127 | } | 129 | } |
128 | } | 130 | } |
129 | 131 | ||
130 | /* dev->driver->kernel_context_switch isn't used by any of the x86 | ||
131 | * drivers but is used by the Sparc driver. | ||
132 | */ | ||
133 | if (dev->driver->kernel_context_switch && | 132 | if (dev->driver->kernel_context_switch && |
134 | dev->last_context != lock.context) { | 133 | dev->last_context != lock.context) { |
135 | dev->driver->kernel_context_switch(dev, dev->last_context, | 134 | dev->driver->kernel_context_switch(dev, dev->last_context, |
136 | lock.context); | 135 | lock.context); |
137 | } | 136 | } |
137 | |||
138 | return 0; | 138 | return 0; |
139 | } | 139 | } |
140 | 140 | ||
@@ -184,12 +184,8 @@ int drm_unlock(struct inode *inode, struct file *filp, | |||
184 | if (dev->driver->kernel_context_switch_unlock) | 184 | if (dev->driver->kernel_context_switch_unlock) |
185 | dev->driver->kernel_context_switch_unlock(dev); | 185 | dev->driver->kernel_context_switch_unlock(dev); |
186 | else { | 186 | else { |
187 | drm_lock_transfer(dev, &dev->lock.hw_lock->lock, | 187 | if (drm_lock_free(&dev->lock,lock.context)) { |
188 | DRM_KERNEL_CONTEXT); | 188 | /* FIXME: Should really bail out here. */ |
189 | |||
190 | if (drm_lock_free(dev, &dev->lock.hw_lock->lock, | ||
191 | DRM_KERNEL_CONTEXT)) { | ||
192 | DRM_ERROR("\n"); | ||
193 | } | 189 | } |
194 | } | 190 | } |
195 | 191 | ||
@@ -206,18 +202,26 @@ int drm_unlock(struct inode *inode, struct file *filp, | |||
206 | * | 202 | * |
207 | * Attempt to mark the lock as held by the given context, via the \p cmpxchg instruction. | 203 | * Attempt to mark the lock as held by the given context, via the \p cmpxchg instruction. |
208 | */ | 204 | */ |
209 | int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context) | 205 | int drm_lock_take(drm_lock_data_t *lock_data, |
206 | unsigned int context) | ||
210 | { | 207 | { |
211 | unsigned int old, new, prev; | 208 | unsigned int old, new, prev; |
209 | volatile unsigned int *lock = &lock_data->hw_lock->lock; | ||
212 | 210 | ||
211 | spin_lock(&lock_data->spinlock); | ||
213 | do { | 212 | do { |
214 | old = *lock; | 213 | old = *lock; |
215 | if (old & _DRM_LOCK_HELD) | 214 | if (old & _DRM_LOCK_HELD) |
216 | new = old | _DRM_LOCK_CONT; | 215 | new = old | _DRM_LOCK_CONT; |
217 | else | 216 | else { |
218 | new = context | _DRM_LOCK_HELD; | 217 | new = context | _DRM_LOCK_HELD | |
218 | ((lock_data->user_waiters + lock_data->kernel_waiters > 1) ? | ||
219 | _DRM_LOCK_CONT : 0); | ||
220 | } | ||
219 | prev = cmpxchg(lock, old, new); | 221 | prev = cmpxchg(lock, old, new); |
220 | } while (prev != old); | 222 | } while (prev != old); |
223 | spin_unlock(&lock_data->spinlock); | ||
224 | |||
221 | if (_DRM_LOCKING_CONTEXT(old) == context) { | 225 | if (_DRM_LOCKING_CONTEXT(old) == context) { |
222 | if (old & _DRM_LOCK_HELD) { | 226 | if (old & _DRM_LOCK_HELD) { |
223 | if (context != DRM_KERNEL_CONTEXT) { | 227 | if (context != DRM_KERNEL_CONTEXT) { |
@@ -227,7 +231,8 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context) | |||
227 | return 0; | 231 | return 0; |
228 | } | 232 | } |
229 | } | 233 | } |
230 | if (new == (context | _DRM_LOCK_HELD)) { | 234 | |
235 | if ((_DRM_LOCKING_CONTEXT(new)) == context && (new & _DRM_LOCK_HELD)) { | ||
231 | /* Have lock */ | 236 | /* Have lock */ |
232 | return 1; | 237 | return 1; |
233 | } | 238 | } |
@@ -246,13 +251,13 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context) | |||
246 | * Resets the lock file pointer. | 251 | * Resets the lock file pointer. |
247 | * Marks the lock as held by the given context, via the \p cmpxchg instruction. | 252 | * Marks the lock as held by the given context, via the \p cmpxchg instruction. |
248 | */ | 253 | */ |
249 | static int drm_lock_transfer(drm_device_t * dev, | 254 | static int drm_lock_transfer(drm_lock_data_t *lock_data, |
250 | __volatile__ unsigned int *lock, | ||
251 | unsigned int context) | 255 | unsigned int context) |
252 | { | 256 | { |
253 | unsigned int old, new, prev; | 257 | unsigned int old, new, prev; |
258 | volatile unsigned int *lock = &lock_data->hw_lock->lock; | ||
254 | 259 | ||
255 | dev->lock.filp = NULL; | 260 | lock_data->filp = NULL; |
256 | do { | 261 | do { |
257 | old = *lock; | 262 | old = *lock; |
258 | new = context | _DRM_LOCK_HELD; | 263 | new = context | _DRM_LOCK_HELD; |
@@ -272,23 +277,32 @@ static int drm_lock_transfer(drm_device_t * dev, | |||
272 | * Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task | 277 | * Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task |
273 | * waiting on the lock queue. | 278 | * waiting on the lock queue. |
274 | */ | 279 | */ |
275 | int drm_lock_free(drm_device_t * dev, | 280 | int drm_lock_free(drm_lock_data_t *lock_data, unsigned int context) |
276 | __volatile__ unsigned int *lock, unsigned int context) | ||
277 | { | 281 | { |
278 | unsigned int old, new, prev; | 282 | unsigned int old, new, prev; |
283 | volatile unsigned int *lock = &lock_data->hw_lock->lock; | ||
284 | |||
285 | spin_lock(&lock_data->spinlock); | ||
286 | if (lock_data->kernel_waiters != 0) { | ||
287 | drm_lock_transfer(lock_data, 0); | ||
288 | lock_data->idle_has_lock = 1; | ||
289 | spin_unlock(&lock_data->spinlock); | ||
290 | return 1; | ||
291 | } | ||
292 | spin_unlock(&lock_data->spinlock); | ||
279 | 293 | ||
280 | dev->lock.filp = NULL; | ||
281 | do { | 294 | do { |
282 | old = *lock; | 295 | old = *lock; |
283 | new = 0; | 296 | new = _DRM_LOCKING_CONTEXT(old); |
284 | prev = cmpxchg(lock, old, new); | 297 | prev = cmpxchg(lock, old, new); |
285 | } while (prev != old); | 298 | } while (prev != old); |
299 | |||
286 | if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) { | 300 | if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) { |
287 | DRM_ERROR("%d freed heavyweight lock held by %d\n", | 301 | DRM_ERROR("%d freed heavyweight lock held by %d\n", |
288 | context, _DRM_LOCKING_CONTEXT(old)); | 302 | context, _DRM_LOCKING_CONTEXT(old)); |
289 | return 1; | 303 | return 1; |
290 | } | 304 | } |
291 | wake_up_interruptible(&dev->lock.lock_queue); | 305 | wake_up_interruptible(&lock_data->lock_queue); |
292 | return 0; | 306 | return 0; |
293 | } | 307 | } |
294 | 308 | ||
@@ -322,3 +336,67 @@ static int drm_notifier(void *priv) | |||
322 | } while (prev != old); | 336 | } while (prev != old); |
323 | return 0; | 337 | return 0; |
324 | } | 338 | } |
339 | |||
340 | /** | ||
341 | * This function returns immediately and takes the hw lock | ||
342 | * with the kernel context if it is free, otherwise it gets the highest priority when and if | ||
343 | * it is eventually released. | ||
344 | * | ||
345 | * This guarantees that the kernel will _eventually_ have the lock _unless_ it is held | ||
346 | * by a blocked process. (In the latter case an explicit wait for the hardware lock would cause | ||
347 | * a deadlock, which is why the "idlelock" was invented). | ||
348 | * | ||
349 | * This should be sufficient to wait for GPU idle without | ||
350 | * having to worry about starvation. | ||
351 | */ | ||
352 | |||
353 | void drm_idlelock_take(drm_lock_data_t *lock_data) | ||
354 | { | ||
355 | int ret = 0; | ||
356 | |||
357 | spin_lock(&lock_data->spinlock); | ||
358 | lock_data->kernel_waiters++; | ||
359 | if (!lock_data->idle_has_lock) { | ||
360 | |||
361 | spin_unlock(&lock_data->spinlock); | ||
362 | ret = drm_lock_take(lock_data, DRM_KERNEL_CONTEXT); | ||
363 | spin_lock(&lock_data->spinlock); | ||
364 | |||
365 | if (ret == 1) | ||
366 | lock_data->idle_has_lock = 1; | ||
367 | } | ||
368 | spin_unlock(&lock_data->spinlock); | ||
369 | } | ||
370 | EXPORT_SYMBOL(drm_idlelock_take); | ||
371 | |||
372 | void drm_idlelock_release(drm_lock_data_t *lock_data) | ||
373 | { | ||
374 | unsigned int old, prev; | ||
375 | volatile unsigned int *lock = &lock_data->hw_lock->lock; | ||
376 | |||
377 | spin_lock(&lock_data->spinlock); | ||
378 | if (--lock_data->kernel_waiters == 0) { | ||
379 | if (lock_data->idle_has_lock) { | ||
380 | do { | ||
381 | old = *lock; | ||
382 | prev = cmpxchg(lock, old, DRM_KERNEL_CONTEXT); | ||
383 | } while (prev != old); | ||
384 | wake_up_interruptible(&lock_data->lock_queue); | ||
385 | lock_data->idle_has_lock = 0; | ||
386 | } | ||
387 | } | ||
388 | spin_unlock(&lock_data->spinlock); | ||
389 | } | ||
390 | EXPORT_SYMBOL(drm_idlelock_release); | ||
391 | |||
392 | |||
393 | int drm_i_have_hw_lock(struct file *filp) | ||
394 | { | ||
395 | DRM_DEVICE; | ||
396 | |||
397 | return (priv->lock_count && dev->lock.hw_lock && | ||
398 | _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && | ||
399 | dev->lock.filp == filp); | ||
400 | } | ||
401 | |||
402 | EXPORT_SYMBOL(drm_i_have_hw_lock); | ||
diff --git a/drivers/char/drm/drm_mm.c b/drivers/char/drm/drm_mm.c index 9b46b85027d0..2ec1d9f26264 100644 --- a/drivers/char/drm/drm_mm.c +++ b/drivers/char/drm/drm_mm.c | |||
@@ -274,7 +274,6 @@ int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size) | |||
274 | return drm_mm_create_tail_node(mm, start, size); | 274 | return drm_mm_create_tail_node(mm, start, size); |
275 | } | 275 | } |
276 | 276 | ||
277 | EXPORT_SYMBOL(drm_mm_init); | ||
278 | 277 | ||
279 | void drm_mm_takedown(drm_mm_t * mm) | 278 | void drm_mm_takedown(drm_mm_t * mm) |
280 | { | 279 | { |
@@ -295,4 +294,3 @@ void drm_mm_takedown(drm_mm_t * mm) | |||
295 | drm_free(entry, sizeof(*entry), DRM_MEM_MM); | 294 | drm_free(entry, sizeof(*entry), DRM_MEM_MM); |
296 | } | 295 | } |
297 | 296 | ||
298 | EXPORT_SYMBOL(drm_mm_takedown); | ||
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index ad54b845978b..01cf482d2d00 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h | |||
@@ -230,10 +230,10 @@ | |||
230 | {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 230 | {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
231 | {0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 231 | {0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
232 | {0x1106, 0x3304, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 232 | {0x1106, 0x3304, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
233 | {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | ||
234 | {0x1106, 0x3344, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 233 | {0x1106, 0x3344, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
235 | {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 234 | {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
236 | {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \ | 235 | {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \ |
236 | {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \ | ||
237 | {0, 0, 0} | 237 | {0, 0, 0} |
238 | 238 | ||
239 | #define i810_PCI_IDS \ | 239 | #define i810_PCI_IDS \ |
@@ -296,5 +296,6 @@ | |||
296 | {0x8086, 0x2982, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 296 | {0x8086, 0x2982, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
297 | {0x8086, 0x2992, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 297 | {0x8086, 0x2992, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
298 | {0x8086, 0x29a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 298 | {0x8086, 0x29a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
299 | {0x8086, 0x2a02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | ||
299 | {0, 0, 0} | 300 | {0, 0, 0} |
300 | 301 | ||
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c index 7fd0da712142..b204498d1a28 100644 --- a/drivers/char/drm/drm_proc.c +++ b/drivers/char/drm/drm_proc.c | |||
@@ -72,7 +72,7 @@ static struct drm_proc_list { | |||
72 | #endif | 72 | #endif |
73 | }; | 73 | }; |
74 | 74 | ||
75 | #define DRM_PROC_ENTRIES (sizeof(drm_proc_list)/sizeof(drm_proc_list[0])) | 75 | #define DRM_PROC_ENTRIES ARRAY_SIZE(drm_proc_list) |
76 | 76 | ||
77 | /** | 77 | /** |
78 | * Initialize the DRI proc filesystem for a device. | 78 | * Initialize the DRI proc filesystem for a device. |
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c index 120d10256feb..19408adcc775 100644 --- a/drivers/char/drm/drm_stub.c +++ b/drivers/char/drm/drm_stub.c | |||
@@ -62,6 +62,7 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, | |||
62 | spin_lock_init(&dev->count_lock); | 62 | spin_lock_init(&dev->count_lock); |
63 | spin_lock_init(&dev->drw_lock); | 63 | spin_lock_init(&dev->drw_lock); |
64 | spin_lock_init(&dev->tasklet_lock); | 64 | spin_lock_init(&dev->tasklet_lock); |
65 | spin_lock_init(&dev->lock.spinlock); | ||
65 | init_timer(&dev->timer); | 66 | init_timer(&dev->timer); |
66 | mutex_init(&dev->struct_mutex); | 67 | mutex_init(&dev->struct_mutex); |
67 | mutex_init(&dev->ctxlist_mutex); | 68 | mutex_init(&dev->ctxlist_mutex); |
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c index 54a632848955..35540cfb43dd 100644 --- a/drivers/char/drm/drm_vm.c +++ b/drivers/char/drm/drm_vm.c | |||
@@ -41,6 +41,30 @@ | |||
41 | static void drm_vm_open(struct vm_area_struct *vma); | 41 | static void drm_vm_open(struct vm_area_struct *vma); |
42 | static void drm_vm_close(struct vm_area_struct *vma); | 42 | static void drm_vm_close(struct vm_area_struct *vma); |
43 | 43 | ||
44 | static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma) | ||
45 | { | ||
46 | pgprot_t tmp = vm_get_page_prot(vma->vm_flags); | ||
47 | |||
48 | #if defined(__i386__) || defined(__x86_64__) | ||
49 | if (boot_cpu_data.x86 > 3 && map_type != _DRM_AGP) { | ||
50 | pgprot_val(tmp) |= _PAGE_PCD; | ||
51 | pgprot_val(tmp) &= ~_PAGE_PWT; | ||
52 | } | ||
53 | #elif defined(__powerpc__) | ||
54 | pgprot_val(tmp) |= _PAGE_NO_CACHE; | ||
55 | if (map_type == _DRM_REGISTERS) | ||
56 | pgprot_val(tmp) |= _PAGE_GUARDED; | ||
57 | #endif | ||
58 | #if defined(__ia64__) | ||
59 | if (efi_range_is_wc(vma->vm_start, vma->vm_end - | ||
60 | vma->vm_start)) | ||
61 | tmp = pgprot_writecombine(tmp); | ||
62 | else | ||
63 | tmp = pgprot_noncached(tmp); | ||
64 | #endif | ||
65 | return tmp; | ||
66 | } | ||
67 | |||
44 | /** | 68 | /** |
45 | * \c nopage method for AGP virtual memory. | 69 | * \c nopage method for AGP virtual memory. |
46 | * | 70 | * |
@@ -151,8 +175,7 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma, | |||
151 | 175 | ||
152 | offset = address - vma->vm_start; | 176 | offset = address - vma->vm_start; |
153 | i = (unsigned long)map->handle + offset; | 177 | i = (unsigned long)map->handle + offset; |
154 | page = (map->type == _DRM_CONSISTENT) ? | 178 | page = vmalloc_to_page((void *)i); |
155 | virt_to_page((void *)i) : vmalloc_to_page((void *)i); | ||
156 | if (!page) | 179 | if (!page) |
157 | return NOPAGE_SIGBUS; | 180 | return NOPAGE_SIGBUS; |
158 | get_page(page); | 181 | get_page(page); |
@@ -389,7 +412,7 @@ static struct vm_operations_struct drm_vm_sg_ops = { | |||
389 | * Create a new drm_vma_entry structure as the \p vma private data entry and | 412 | * Create a new drm_vma_entry structure as the \p vma private data entry and |
390 | * add it to drm_device::vmalist. | 413 | * add it to drm_device::vmalist. |
391 | */ | 414 | */ |
392 | static void drm_vm_open(struct vm_area_struct *vma) | 415 | static void drm_vm_open_locked(struct vm_area_struct *vma) |
393 | { | 416 | { |
394 | drm_file_t *priv = vma->vm_file->private_data; | 417 | drm_file_t *priv = vma->vm_file->private_data; |
395 | drm_device_t *dev = priv->head->dev; | 418 | drm_device_t *dev = priv->head->dev; |
@@ -401,15 +424,23 @@ static void drm_vm_open(struct vm_area_struct *vma) | |||
401 | 424 | ||
402 | vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS); | 425 | vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS); |
403 | if (vma_entry) { | 426 | if (vma_entry) { |
404 | mutex_lock(&dev->struct_mutex); | ||
405 | vma_entry->vma = vma; | 427 | vma_entry->vma = vma; |
406 | vma_entry->next = dev->vmalist; | 428 | vma_entry->next = dev->vmalist; |
407 | vma_entry->pid = current->pid; | 429 | vma_entry->pid = current->pid; |
408 | dev->vmalist = vma_entry; | 430 | dev->vmalist = vma_entry; |
409 | mutex_unlock(&dev->struct_mutex); | ||
410 | } | 431 | } |
411 | } | 432 | } |
412 | 433 | ||
434 | static void drm_vm_open(struct vm_area_struct *vma) | ||
435 | { | ||
436 | drm_file_t *priv = vma->vm_file->private_data; | ||
437 | drm_device_t *dev = priv->head->dev; | ||
438 | |||
439 | mutex_lock(&dev->struct_mutex); | ||
440 | drm_vm_open_locked(vma); | ||
441 | mutex_unlock(&dev->struct_mutex); | ||
442 | } | ||
443 | |||
413 | /** | 444 | /** |
414 | * \c close method for all virtual memory types. | 445 | * \c close method for all virtual memory types. |
415 | * | 446 | * |
@@ -460,7 +491,6 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) | |||
460 | drm_device_dma_t *dma; | 491 | drm_device_dma_t *dma; |
461 | unsigned long length = vma->vm_end - vma->vm_start; | 492 | unsigned long length = vma->vm_end - vma->vm_start; |
462 | 493 | ||
463 | lock_kernel(); | ||
464 | dev = priv->head->dev; | 494 | dev = priv->head->dev; |
465 | dma = dev->dma; | 495 | dma = dev->dma; |
466 | DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", | 496 | DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", |
@@ -468,10 +498,8 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) | |||
468 | 498 | ||
469 | /* Length must match exact page count */ | 499 | /* Length must match exact page count */ |
470 | if (!dma || (length >> PAGE_SHIFT) != dma->page_count) { | 500 | if (!dma || (length >> PAGE_SHIFT) != dma->page_count) { |
471 | unlock_kernel(); | ||
472 | return -EINVAL; | 501 | return -EINVAL; |
473 | } | 502 | } |
474 | unlock_kernel(); | ||
475 | 503 | ||
476 | if (!capable(CAP_SYS_ADMIN) && | 504 | if (!capable(CAP_SYS_ADMIN) && |
477 | (dma->flags & _DRM_DMA_USE_PCI_RO)) { | 505 | (dma->flags & _DRM_DMA_USE_PCI_RO)) { |
@@ -494,7 +522,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) | |||
494 | vma->vm_flags |= VM_RESERVED; /* Don't swap */ | 522 | vma->vm_flags |= VM_RESERVED; /* Don't swap */ |
495 | 523 | ||
496 | vma->vm_file = filp; /* Needed for drm_vm_open() */ | 524 | vma->vm_file = filp; /* Needed for drm_vm_open() */ |
497 | drm_vm_open(vma); | 525 | drm_vm_open_locked(vma); |
498 | return 0; | 526 | return 0; |
499 | } | 527 | } |
500 | 528 | ||
@@ -529,7 +557,7 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs); | |||
529 | * according to the mapping type and remaps the pages. Finally sets the file | 557 | * according to the mapping type and remaps the pages. Finally sets the file |
530 | * pointer and calls vm_open(). | 558 | * pointer and calls vm_open(). |
531 | */ | 559 | */ |
532 | int drm_mmap(struct file *filp, struct vm_area_struct *vma) | 560 | static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) |
533 | { | 561 | { |
534 | drm_file_t *priv = filp->private_data; | 562 | drm_file_t *priv = filp->private_data; |
535 | drm_device_t *dev = priv->head->dev; | 563 | drm_device_t *dev = priv->head->dev; |
@@ -565,7 +593,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) | |||
565 | return -EPERM; | 593 | return -EPERM; |
566 | 594 | ||
567 | /* Check for valid size. */ | 595 | /* Check for valid size. */ |
568 | if (map->size != vma->vm_end - vma->vm_start) | 596 | if (map->size < vma->vm_end - vma->vm_start) |
569 | return -EINVAL; | 597 | return -EINVAL; |
570 | 598 | ||
571 | if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) { | 599 | if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) { |
@@ -600,37 +628,16 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) | |||
600 | /* fall through to _DRM_FRAME_BUFFER... */ | 628 | /* fall through to _DRM_FRAME_BUFFER... */ |
601 | case _DRM_FRAME_BUFFER: | 629 | case _DRM_FRAME_BUFFER: |
602 | case _DRM_REGISTERS: | 630 | case _DRM_REGISTERS: |
603 | #if defined(__i386__) || defined(__x86_64__) | ||
604 | if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) { | ||
605 | pgprot_val(vma->vm_page_prot) |= _PAGE_PCD; | ||
606 | pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT; | ||
607 | } | ||
608 | #elif defined(__powerpc__) | ||
609 | pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; | ||
610 | if (map->type == _DRM_REGISTERS) | ||
611 | pgprot_val(vma->vm_page_prot) |= _PAGE_GUARDED; | ||
612 | #endif | ||
613 | vma->vm_flags |= VM_IO; /* not in core dump */ | ||
614 | #if defined(__ia64__) | ||
615 | if (efi_range_is_wc(vma->vm_start, vma->vm_end - vma->vm_start)) | ||
616 | vma->vm_page_prot = | ||
617 | pgprot_writecombine(vma->vm_page_prot); | ||
618 | else | ||
619 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
620 | #endif | ||
621 | offset = dev->driver->get_reg_ofs(dev); | 631 | offset = dev->driver->get_reg_ofs(dev); |
632 | vma->vm_flags |= VM_IO; /* not in core dump */ | ||
633 | vma->vm_page_prot = drm_io_prot(map->type, vma); | ||
622 | #ifdef __sparc__ | 634 | #ifdef __sparc__ |
623 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 635 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
636 | #endif | ||
624 | if (io_remap_pfn_range(vma, vma->vm_start, | 637 | if (io_remap_pfn_range(vma, vma->vm_start, |
625 | (map->offset + offset) >> PAGE_SHIFT, | 638 | (map->offset + offset) >> PAGE_SHIFT, |
626 | vma->vm_end - vma->vm_start, | 639 | vma->vm_end - vma->vm_start, |
627 | vma->vm_page_prot)) | 640 | vma->vm_page_prot)) |
628 | #else | ||
629 | if (io_remap_pfn_range(vma, vma->vm_start, | ||
630 | (map->offset + offset) >> PAGE_SHIFT, | ||
631 | vma->vm_end - vma->vm_start, | ||
632 | vma->vm_page_prot)) | ||
633 | #endif | ||
634 | return -EAGAIN; | 641 | return -EAGAIN; |
635 | DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx," | 642 | DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx," |
636 | " offset = 0x%lx\n", | 643 | " offset = 0x%lx\n", |
@@ -638,10 +645,15 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) | |||
638 | vma->vm_start, vma->vm_end, map->offset + offset); | 645 | vma->vm_start, vma->vm_end, map->offset + offset); |
639 | vma->vm_ops = &drm_vm_ops; | 646 | vma->vm_ops = &drm_vm_ops; |
640 | break; | 647 | break; |
641 | case _DRM_SHM: | ||
642 | case _DRM_CONSISTENT: | 648 | case _DRM_CONSISTENT: |
643 | /* Consistent memory is really like shared memory. It's only | 649 | /* Consistent memory is really like shared memory. But |
644 | * allocate in a different way */ | 650 | * it's allocated in a different way, so avoid nopage */ |
651 | if (remap_pfn_range(vma, vma->vm_start, | ||
652 | page_to_pfn(virt_to_page(map->handle)), | ||
653 | vma->vm_end - vma->vm_start, vma->vm_page_prot)) | ||
654 | return -EAGAIN; | ||
655 | /* fall through to _DRM_SHM */ | ||
656 | case _DRM_SHM: | ||
645 | vma->vm_ops = &drm_vm_shm_ops; | 657 | vma->vm_ops = &drm_vm_shm_ops; |
646 | vma->vm_private_data = (void *)map; | 658 | vma->vm_private_data = (void *)map; |
647 | /* Don't let this area swap. Change when | 659 | /* Don't let this area swap. Change when |
@@ -659,8 +671,20 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) | |||
659 | vma->vm_flags |= VM_RESERVED; /* Don't swap */ | 671 | vma->vm_flags |= VM_RESERVED; /* Don't swap */ |
660 | 672 | ||
661 | vma->vm_file = filp; /* Needed for drm_vm_open() */ | 673 | vma->vm_file = filp; /* Needed for drm_vm_open() */ |
662 | drm_vm_open(vma); | 674 | drm_vm_open_locked(vma); |
663 | return 0; | 675 | return 0; |
664 | } | 676 | } |
665 | 677 | ||
678 | int drm_mmap(struct file *filp, struct vm_area_struct *vma) | ||
679 | { | ||
680 | drm_file_t *priv = filp->private_data; | ||
681 | drm_device_t *dev = priv->head->dev; | ||
682 | int ret; | ||
683 | |||
684 | mutex_lock(&dev->struct_mutex); | ||
685 | ret = drm_mmap_locked(filp, vma); | ||
686 | mutex_unlock(&dev->struct_mutex); | ||
687 | |||
688 | return ret; | ||
689 | } | ||
666 | EXPORT_SYMBOL(drm_mmap); | 690 | EXPORT_SYMBOL(drm_mmap); |
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c index 9354ce3b0093..1ba15d9a171a 100644 --- a/drivers/char/drm/i915_dma.c +++ b/drivers/char/drm/i915_dma.c | |||
@@ -34,7 +34,8 @@ | |||
34 | #define IS_I965G(dev) (dev->pci_device == 0x2972 || \ | 34 | #define IS_I965G(dev) (dev->pci_device == 0x2972 || \ |
35 | dev->pci_device == 0x2982 || \ | 35 | dev->pci_device == 0x2982 || \ |
36 | dev->pci_device == 0x2992 || \ | 36 | dev->pci_device == 0x2992 || \ |
37 | dev->pci_device == 0x29A2) | 37 | dev->pci_device == 0x29A2 || \ |
38 | dev->pci_device == 0x2A02) | ||
38 | 39 | ||
39 | /* Really want an OS-independent resettable timer. Would like to have | 40 | /* Really want an OS-independent resettable timer. Would like to have |
40 | * this loop run for (eg) 3 sec, but have the timer reset every time | 41 | * this loop run for (eg) 3 sec, but have the timer reset every time |
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 5ed965688293..c1850ecac302 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c | |||
@@ -1560,8 +1560,8 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1560 | if (dev_priv->flags & RADEON_IS_AGP) { | 1560 | if (dev_priv->flags & RADEON_IS_AGP) { |
1561 | base = dev->agp->base; | 1561 | base = dev->agp->base; |
1562 | /* Check if valid */ | 1562 | /* Check if valid */ |
1563 | if ((base + dev_priv->gart_size) > dev_priv->fb_location && | 1563 | if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location && |
1564 | base < (dev_priv->fb_location + dev_priv->fb_size)) { | 1564 | base < (dev_priv->fb_location + dev_priv->fb_size - 1)) { |
1565 | DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n", | 1565 | DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n", |
1566 | dev->agp->base); | 1566 | dev->agp->base); |
1567 | base = 0; | 1567 | base = 0; |
@@ -1571,8 +1571,8 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1571 | /* If not or if AGP is at 0 (Macs), try to put it elsewhere */ | 1571 | /* If not or if AGP is at 0 (Macs), try to put it elsewhere */ |
1572 | if (base == 0) { | 1572 | if (base == 0) { |
1573 | base = dev_priv->fb_location + dev_priv->fb_size; | 1573 | base = dev_priv->fb_location + dev_priv->fb_size; |
1574 | if (((base + dev_priv->gart_size) & 0xfffffffful) | 1574 | if (base < dev_priv->fb_location || |
1575 | < base) | 1575 | ((base + dev_priv->gart_size) & 0xfffffffful) < base) |
1576 | base = dev_priv->fb_location | 1576 | base = dev_priv->fb_location |
1577 | - dev_priv->gart_size; | 1577 | - dev_priv->gart_size; |
1578 | } | 1578 | } |
diff --git a/drivers/char/drm/sis_drv.c b/drivers/char/drm/sis_drv.c index 3d5b3218b6ff..690e0af8e7c2 100644 --- a/drivers/char/drm/sis_drv.c +++ b/drivers/char/drm/sis_drv.c | |||
@@ -71,7 +71,7 @@ static struct drm_driver driver = { | |||
71 | .context_dtor = NULL, | 71 | .context_dtor = NULL, |
72 | .dma_quiescent = sis_idle, | 72 | .dma_quiescent = sis_idle, |
73 | .reclaim_buffers = NULL, | 73 | .reclaim_buffers = NULL, |
74 | .reclaim_buffers_locked = sis_reclaim_buffers_locked, | 74 | .reclaim_buffers_idlelocked = sis_reclaim_buffers_locked, |
75 | .lastclose = sis_lastclose, | 75 | .lastclose = sis_lastclose, |
76 | .get_map_ofs = drm_core_get_map_ofs, | 76 | .get_map_ofs = drm_core_get_map_ofs, |
77 | .get_reg_ofs = drm_core_get_reg_ofs, | 77 | .get_reg_ofs = drm_core_get_reg_ofs, |
diff --git a/drivers/char/drm/via_drv.c b/drivers/char/drm/via_drv.c index bb9dde8b1911..2d4957ab256a 100644 --- a/drivers/char/drm/via_drv.c +++ b/drivers/char/drm/via_drv.c | |||
@@ -52,7 +52,8 @@ static struct drm_driver driver = { | |||
52 | .dma_quiescent = via_driver_dma_quiescent, | 52 | .dma_quiescent = via_driver_dma_quiescent, |
53 | .dri_library_name = dri_library_name, | 53 | .dri_library_name = dri_library_name, |
54 | .reclaim_buffers = drm_core_reclaim_buffers, | 54 | .reclaim_buffers = drm_core_reclaim_buffers, |
55 | .reclaim_buffers_locked = via_reclaim_buffers_locked, | 55 | .reclaim_buffers_locked = NULL, |
56 | .reclaim_buffers_idlelocked = via_reclaim_buffers_locked, | ||
56 | .lastclose = via_lastclose, | 57 | .lastclose = via_lastclose, |
57 | .get_map_ofs = drm_core_get_map_ofs, | 58 | .get_map_ofs = drm_core_get_map_ofs, |
58 | .get_reg_ofs = drm_core_get_reg_ofs, | 59 | .get_reg_ofs = drm_core_get_reg_ofs, |
diff --git a/drivers/char/drm/via_mm.h b/drivers/char/drm/via_mm.h deleted file mode 100644 index d57efda57c76..000000000000 --- a/drivers/char/drm/via_mm.h +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. | ||
4 | * | ||
5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
6 | * copy of this software and associated documentation files (the "Software"), | ||
7 | * to deal in the Software without restriction, including without limitation | ||
8 | * the rights to use, copy, modify, merge, publish, distribute, sub license, | ||
9 | * and/or sell copies of the Software, and to permit persons to whom the | ||
10 | * Software is furnished to do so, subject to the following conditions: | ||
11 | * | ||
12 | * The above copyright notice and this permission notice (including the | ||
13 | * next paragraph) shall be included in all copies or substantial portions | ||
14 | * of the Software. | ||
15 | * | ||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | ||
19 | * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
22 | * DEALINGS IN THE SOFTWARE. | ||
23 | */ | ||
24 | #ifndef _via_drm_mm_h_ | ||
25 | #define _via_drm_mm_h_ | ||
26 | |||
27 | typedef struct { | ||
28 | unsigned int context; | ||
29 | unsigned int size; | ||
30 | unsigned long offset; | ||
31 | unsigned long free; | ||
32 | } drm_via_mm_t; | ||
33 | |||
34 | typedef struct { | ||
35 | unsigned int size; | ||
36 | unsigned long handle; | ||
37 | void *virtual; | ||
38 | } drm_via_dma_t; | ||
39 | |||
40 | #endif | ||
diff --git a/drivers/char/hw_random/via-rng.c b/drivers/char/hw_random/via-rng.c index 9ebf84d18655..ec435cb25c4f 100644 --- a/drivers/char/hw_random/via-rng.c +++ b/drivers/char/hw_random/via-rng.c | |||
@@ -26,7 +26,6 @@ | |||
26 | 26 | ||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
29 | #include <linux/pci.h> | ||
30 | #include <linux/hw_random.h> | 29 | #include <linux/hw_random.h> |
31 | #include <asm/io.h> | 30 | #include <asm/io.h> |
32 | #include <asm/msr.h> | 31 | #include <asm/msr.h> |
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index cb8d691576da..c06e86ad1dab 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <linux/input.h> | 41 | #include <linux/input.h> |
42 | #include <linux/reboot.h> | 42 | #include <linux/reboot.h> |
43 | 43 | ||
44 | static void kbd_disconnect(struct input_handle *handle); | ||
45 | extern void ctrl_alt_del(void); | 44 | extern void ctrl_alt_del(void); |
46 | 45 | ||
47 | /* | 46 | /* |
@@ -159,65 +158,41 @@ static int sysrq_alt_use; | |||
159 | static int sysrq_alt; | 158 | static int sysrq_alt; |
160 | 159 | ||
161 | /* | 160 | /* |
162 | * Translation of scancodes to keycodes. We set them on only the first attached | 161 | * Translation of scancodes to keycodes. We set them on only the first |
163 | * keyboard - for per-keyboard setting, /dev/input/event is more useful. | 162 | * keyboard in the list that accepts the scancode and keycode. |
163 | * Explanation for not choosing the first attached keyboard anymore: | ||
164 | * USB keyboards for example have two event devices: one for all "normal" | ||
165 | * keys and one for extra function keys (like "volume up", "make coffee", | ||
166 | * etc.). So this means that scancodes for the extra function keys won't | ||
167 | * be valid for the first event device, but will be for the second. | ||
164 | */ | 168 | */ |
165 | int getkeycode(unsigned int scancode) | 169 | int getkeycode(unsigned int scancode) |
166 | { | 170 | { |
167 | struct list_head *node; | 171 | struct input_handle *handle; |
168 | struct input_dev *dev = NULL; | 172 | int keycode; |
173 | int error = -ENODEV; | ||
169 | 174 | ||
170 | list_for_each(node, &kbd_handler.h_list) { | 175 | list_for_each_entry(handle, &kbd_handler.h_list, h_node) { |
171 | struct input_handle *handle = to_handle_h(node); | 176 | error = handle->dev->getkeycode(handle->dev, scancode, &keycode); |
172 | if (handle->dev->keycodesize) { | 177 | if (!error) |
173 | dev = handle->dev; | 178 | return keycode; |
174 | break; | ||
175 | } | ||
176 | } | 179 | } |
177 | 180 | ||
178 | if (!dev) | 181 | return error; |
179 | return -ENODEV; | ||
180 | |||
181 | if (scancode >= dev->keycodemax) | ||
182 | return -EINVAL; | ||
183 | |||
184 | return INPUT_KEYCODE(dev, scancode); | ||
185 | } | 182 | } |
186 | 183 | ||
187 | int setkeycode(unsigned int scancode, unsigned int keycode) | 184 | int setkeycode(unsigned int scancode, unsigned int keycode) |
188 | { | 185 | { |
189 | struct list_head *node; | 186 | struct input_handle *handle; |
190 | struct input_dev *dev = NULL; | 187 | int error = -ENODEV; |
191 | unsigned int i, oldkey; | ||
192 | 188 | ||
193 | list_for_each(node, &kbd_handler.h_list) { | 189 | list_for_each_entry(handle, &kbd_handler.h_list, h_node) { |
194 | struct input_handle *handle = to_handle_h(node); | 190 | error = handle->dev->setkeycode(handle->dev, scancode, keycode); |
195 | if (handle->dev->keycodesize) { | 191 | if (!error) |
196 | dev = handle->dev; | ||
197 | break; | 192 | break; |
198 | } | ||
199 | } | 193 | } |
200 | 194 | ||
201 | if (!dev) | 195 | return error; |
202 | return -ENODEV; | ||
203 | |||
204 | if (scancode >= dev->keycodemax) | ||
205 | return -EINVAL; | ||
206 | if (keycode < 0 || keycode > KEY_MAX) | ||
207 | return -EINVAL; | ||
208 | if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8))) | ||
209 | return -EINVAL; | ||
210 | |||
211 | oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode); | ||
212 | |||
213 | clear_bit(oldkey, dev->keybit); | ||
214 | set_bit(keycode, dev->keybit); | ||
215 | |||
216 | for (i = 0; i < dev->keycodemax; i++) | ||
217 | if (INPUT_KEYCODE(dev,i) == oldkey) | ||
218 | set_bit(oldkey, dev->keybit); | ||
219 | |||
220 | return 0; | ||
221 | } | 196 | } |
222 | 197 | ||
223 | /* | 198 | /* |
@@ -225,10 +200,9 @@ int setkeycode(unsigned int scancode, unsigned int keycode) | |||
225 | */ | 200 | */ |
226 | static void kd_nosound(unsigned long ignored) | 201 | static void kd_nosound(unsigned long ignored) |
227 | { | 202 | { |
228 | struct list_head *node; | 203 | struct input_handle *handle; |
229 | 204 | ||
230 | list_for_each(node, &kbd_handler.h_list) { | 205 | list_for_each_entry(handle, &kbd_handler.h_list, h_node) { |
231 | struct input_handle *handle = to_handle_h(node); | ||
232 | if (test_bit(EV_SND, handle->dev->evbit)) { | 206 | if (test_bit(EV_SND, handle->dev->evbit)) { |
233 | if (test_bit(SND_TONE, handle->dev->sndbit)) | 207 | if (test_bit(SND_TONE, handle->dev->sndbit)) |
234 | input_inject_event(handle, EV_SND, SND_TONE, 0); | 208 | input_inject_event(handle, EV_SND, SND_TONE, 0); |
@@ -1161,7 +1135,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) | |||
1161 | 1135 | ||
1162 | if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw) | 1136 | if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw) |
1163 | if (emulate_raw(vc, keycode, !down << 7)) | 1137 | if (emulate_raw(vc, keycode, !down << 7)) |
1164 | if (keycode < BTN_MISC) | 1138 | if (keycode < BTN_MISC && printk_ratelimit()) |
1165 | printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode); | 1139 | printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode); |
1166 | 1140 | ||
1167 | #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */ | 1141 | #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */ |
@@ -1285,11 +1259,11 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type, | |||
1285 | * likes it, it can open it and get events from it. In this (kbd_connect) | 1259 | * likes it, it can open it and get events from it. In this (kbd_connect) |
1286 | * function, we should decide which VT to bind that keyboard to initially. | 1260 | * function, we should decide which VT to bind that keyboard to initially. |
1287 | */ | 1261 | */ |
1288 | static struct input_handle *kbd_connect(struct input_handler *handler, | 1262 | static int kbd_connect(struct input_handler *handler, struct input_dev *dev, |
1289 | struct input_dev *dev, | 1263 | const struct input_device_id *id) |
1290 | const struct input_device_id *id) | ||
1291 | { | 1264 | { |
1292 | struct input_handle *handle; | 1265 | struct input_handle *handle; |
1266 | int error; | ||
1293 | int i; | 1267 | int i; |
1294 | 1268 | ||
1295 | for (i = KEY_RESERVED; i < BTN_MISC; i++) | 1269 | for (i = KEY_RESERVED; i < BTN_MISC; i++) |
@@ -1297,24 +1271,37 @@ static struct input_handle *kbd_connect(struct input_handler *handler, | |||
1297 | break; | 1271 | break; |
1298 | 1272 | ||
1299 | if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit)) | 1273 | if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit)) |
1300 | return NULL; | 1274 | return -ENODEV; |
1301 | 1275 | ||
1302 | handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); | 1276 | handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); |
1303 | if (!handle) | 1277 | if (!handle) |
1304 | return NULL; | 1278 | return -ENOMEM; |
1305 | 1279 | ||
1306 | handle->dev = dev; | 1280 | handle->dev = dev; |
1307 | handle->handler = handler; | 1281 | handle->handler = handler; |
1308 | handle->name = "kbd"; | 1282 | handle->name = "kbd"; |
1309 | 1283 | ||
1310 | input_open_device(handle); | 1284 | error = input_register_handle(handle); |
1285 | if (error) | ||
1286 | goto err_free_handle; | ||
1287 | |||
1288 | error = input_open_device(handle); | ||
1289 | if (error) | ||
1290 | goto err_unregister_handle; | ||
1291 | |||
1292 | return 0; | ||
1311 | 1293 | ||
1312 | return handle; | 1294 | err_unregister_handle: |
1295 | input_unregister_handle(handle); | ||
1296 | err_free_handle: | ||
1297 | kfree(handle); | ||
1298 | return error; | ||
1313 | } | 1299 | } |
1314 | 1300 | ||
1315 | static void kbd_disconnect(struct input_handle *handle) | 1301 | static void kbd_disconnect(struct input_handle *handle) |
1316 | { | 1302 | { |
1317 | input_close_device(handle); | 1303 | input_close_device(handle); |
1304 | input_unregister_handle(handle); | ||
1318 | kfree(handle); | 1305 | kfree(handle); |
1319 | } | 1306 | } |
1320 | 1307 | ||
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 157b1d09ab55..13808f6083a0 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -42,7 +42,6 @@ | |||
42 | #include <linux/timer.h> | 42 | #include <linux/timer.h> |
43 | #include <linux/time.h> | 43 | #include <linux/time.h> |
44 | #include <linux/interrupt.h> | 44 | #include <linux/interrupt.h> |
45 | #include <linux/pci.h> | ||
46 | #include <linux/tty.h> | 45 | #include <linux/tty.h> |
47 | #include <linux/tty_flip.h> | 46 | #include <linux/tty_flip.h> |
48 | #include <linux/serial.h> | 47 | #include <linux/serial.h> |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index bb9a43c6cf3d..9f273f032b0f 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -19,7 +19,6 @@ | |||
19 | * | 19 | * |
20 | */ | 20 | */ |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/pci.h> | ||
23 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
24 | #include <linux/fs.h> | 23 | #include <linux/fs.h> |
25 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 7a32df594907..389da364e6b6 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -3720,11 +3720,10 @@ int tty_register_driver(struct tty_driver *driver) | |||
3720 | if (driver->flags & TTY_DRIVER_INSTALLED) | 3720 | if (driver->flags & TTY_DRIVER_INSTALLED) |
3721 | return 0; | 3721 | return 0; |
3722 | 3722 | ||
3723 | if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM)) { | 3723 | if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) { |
3724 | p = kmalloc(driver->num * 3 * sizeof(void *), GFP_KERNEL); | 3724 | p = kzalloc(driver->num * 3 * sizeof(void *), GFP_KERNEL); |
3725 | if (!p) | 3725 | if (!p) |
3726 | return -ENOMEM; | 3726 | return -ENOMEM; |
3727 | memset(p, 0, driver->num * 3 * sizeof(void *)); | ||
3728 | } | 3727 | } |
3729 | 3728 | ||
3730 | if (!driver->major) { | 3729 | if (!driver->major) { |
diff --git a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c index 1e4a8d751a71..2f7ba7a514fe 100644 --- a/drivers/char/watchdog/sc1200wdt.c +++ b/drivers/char/watchdog/sc1200wdt.c | |||
@@ -38,7 +38,6 @@ | |||
38 | #include <linux/init.h> | 38 | #include <linux/init.h> |
39 | #include <linux/pnp.h> | 39 | #include <linux/pnp.h> |
40 | #include <linux/fs.h> | 40 | #include <linux/fs.h> |
41 | #include <linux/pci.h> | ||
42 | 41 | ||
43 | #include <asm/semaphore.h> | 42 | #include <asm/semaphore.h> |
44 | #include <asm/io.h> | 43 | #include <asm/io.h> |
diff --git a/drivers/char/watchdog/scx200_wdt.c b/drivers/char/watchdog/scx200_wdt.c index fc0e0347f9d2..d4fd0fa2f176 100644 --- a/drivers/char/watchdog/scx200_wdt.c +++ b/drivers/char/watchdog/scx200_wdt.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/notifier.h> | 25 | #include <linux/notifier.h> |
26 | #include <linux/reboot.h> | 26 | #include <linux/reboot.h> |
27 | #include <linux/fs.h> | 27 | #include <linux/fs.h> |
28 | #include <linux/pci.h> | 28 | #include <linux/ioport.h> |
29 | #include <linux/scx200.h> | 29 | #include <linux/scx200.h> |
30 | 30 | ||
31 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |