aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/drm_irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/drm/drm_irq.c')
-rw-r--r--drivers/char/drm/drm_irq.c89
1 files changed, 37 insertions, 52 deletions
diff --git a/drivers/char/drm/drm_irq.c b/drivers/char/drm/drm_irq.c
index 9fdc2953c73..05eae63f85b 100644
--- a/drivers/char/drm/drm_irq.c
+++ b/drivers/char/drm/drm_irq.c
@@ -50,29 +50,24 @@
50 * This IOCTL is deprecated, and will now return EINVAL for any busid not equal 50 * This IOCTL is deprecated, and will now return EINVAL for any busid not equal
51 * to that of the device that this DRM instance attached to. 51 * to that of the device that this DRM instance attached to.
52 */ 52 */
53int drm_irq_by_busid(struct inode *inode, struct drm_file *file_priv, 53int drm_irq_by_busid(struct drm_device *dev, void *data,
54 unsigned int cmd, unsigned long arg) 54 struct drm_file *file_priv)
55{ 55{
56 struct drm_device *dev = file_priv->head->dev; 56 struct drm_irq_busid *p = data;
57 struct drm_irq_busid __user *argp = (void __user *)arg;
58 struct drm_irq_busid p;
59 57
60 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) 58 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
61 return -EINVAL; 59 return -EINVAL;
62 60
63 if (copy_from_user(&p, argp, sizeof(p))) 61 if ((p->busnum >> 8) != drm_get_pci_domain(dev) ||
64 return -EFAULT; 62 (p->busnum & 0xff) != dev->pdev->bus->number ||
65 63 p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn))
66 if ((p.busnum >> 8) != drm_get_pci_domain(dev) ||
67 (p.busnum & 0xff) != dev->pdev->bus->number ||
68 p.devnum != PCI_SLOT(dev->pdev->devfn) || p.funcnum != PCI_FUNC(dev->pdev->devfn))
69 return -EINVAL; 64 return -EINVAL;
70 65
71 p.irq = dev->irq; 66 p->irq = dev->irq;
67
68 DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum,
69 p->irq);
72 70
73 DRM_DEBUG("%d:%d:%d => IRQ %d\n", p.busnum, p.devnum, p.funcnum, p.irq);
74 if (copy_to_user(argp, &p, sizeof(p)))
75 return -EFAULT;
76 return 0; 71 return 0;
77} 72}
78 73
@@ -193,23 +188,20 @@ EXPORT_SYMBOL(drm_irq_uninstall);
193 * 188 *
194 * Calls irq_install() or irq_uninstall() according to \p arg. 189 * Calls irq_install() or irq_uninstall() according to \p arg.
195 */ 190 */
196int drm_control(struct inode *inode, struct drm_file *file_priv, 191int drm_control(struct drm_device *dev, void *data,
197 unsigned int cmd, unsigned long arg) 192 struct drm_file *file_priv)
198{ 193{
199 struct drm_device *dev = file_priv->head->dev; 194 struct drm_control *ctl = data;
200 struct drm_control ctl;
201 195
202 /* if we haven't irq we fallback for compatibility reasons - this used to be a separate function in drm_dma.h */ 196 /* if we haven't irq we fallback for compatibility reasons - this used to be a separate function in drm_dma.h */
203 197
204 if (copy_from_user(&ctl, (struct drm_control __user *) arg, sizeof(ctl)))
205 return -EFAULT;
206 198
207 switch (ctl.func) { 199 switch (ctl->func) {
208 case DRM_INST_HANDLER: 200 case DRM_INST_HANDLER:
209 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) 201 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
210 return 0; 202 return 0;
211 if (dev->if_version < DRM_IF_VERSION(1, 2) && 203 if (dev->if_version < DRM_IF_VERSION(1, 2) &&
212 ctl.irq != dev->irq) 204 ctl->irq != dev->irq)
213 return -EINVAL; 205 return -EINVAL;
214 return drm_irq_install(dev); 206 return drm_irq_install(dev);
215 case DRM_UNINST_HANDLER: 207 case DRM_UNINST_HANDLER:
@@ -240,30 +232,25 @@ int drm_control(struct inode *inode, struct drm_file *file_priv,
240 * 232 *
241 * If a signal is not requested, then calls vblank_wait(). 233 * If a signal is not requested, then calls vblank_wait().
242 */ 234 */
243int drm_wait_vblank(DRM_IOCTL_ARGS) 235int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv)
244{ 236{
245 struct drm_device *dev = file_priv->head->dev; 237 union drm_wait_vblank *vblwait = data;
246 union drm_wait_vblank __user *argp = (void __user *)data;
247 union drm_wait_vblank vblwait;
248 struct timeval now; 238 struct timeval now;
249 int ret = 0; 239 int ret = 0;
250 unsigned int flags, seq; 240 unsigned int flags, seq;
251 241
252 if (!dev->irq) 242 if ((!dev->irq) || (!dev->irq_enabled))
253 return -EINVAL; 243 return -EINVAL;
254 244
255 if (copy_from_user(&vblwait, argp, sizeof(vblwait))) 245 if (vblwait->request.type &
256 return -EFAULT;
257
258 if (vblwait.request.type &
259 ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)) { 246 ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)) {
260 DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n", 247 DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n",
261 vblwait.request.type, 248 vblwait->request.type,
262 (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)); 249 (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK));
263 return -EINVAL; 250 return -EINVAL;
264 } 251 }
265 252
266 flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK; 253 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
267 254
268 if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ? 255 if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ?
269 DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL)) 256 DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL))
@@ -272,10 +259,10 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
272 seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2 259 seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2
273 : &dev->vbl_received); 260 : &dev->vbl_received);
274 261
275 switch (vblwait.request.type & _DRM_VBLANK_TYPES_MASK) { 262 switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
276 case _DRM_VBLANK_RELATIVE: 263 case _DRM_VBLANK_RELATIVE:
277 vblwait.request.sequence += seq; 264 vblwait->request.sequence += seq;
278 vblwait.request.type &= ~_DRM_VBLANK_RELATIVE; 265 vblwait->request.type &= ~_DRM_VBLANK_RELATIVE;
279 case _DRM_VBLANK_ABSOLUTE: 266 case _DRM_VBLANK_ABSOLUTE:
280 break; 267 break;
281 default: 268 default:
@@ -283,8 +270,8 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
283 } 270 }
284 271
285 if ((flags & _DRM_VBLANK_NEXTONMISS) && 272 if ((flags & _DRM_VBLANK_NEXTONMISS) &&
286 (seq - vblwait.request.sequence) <= (1<<23)) { 273 (seq - vblwait->request.sequence) <= (1<<23)) {
287 vblwait.request.sequence = seq + 1; 274 vblwait->request.sequence = seq + 1;
288 } 275 }
289 276
290 if (flags & _DRM_VBLANK_SIGNAL) { 277 if (flags & _DRM_VBLANK_SIGNAL) {
@@ -300,12 +287,13 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
300 * that case 287 * that case
301 */ 288 */
302 list_for_each_entry(vbl_sig, vbl_sigs, head) { 289 list_for_each_entry(vbl_sig, vbl_sigs, head) {
303 if (vbl_sig->sequence == vblwait.request.sequence 290 if (vbl_sig->sequence == vblwait->request.sequence
304 && vbl_sig->info.si_signo == vblwait.request.signal 291 && vbl_sig->info.si_signo ==
292 vblwait->request.signal
305 && vbl_sig->task == current) { 293 && vbl_sig->task == current) {
306 spin_unlock_irqrestore(&dev->vbl_lock, 294 spin_unlock_irqrestore(&dev->vbl_lock,
307 irqflags); 295 irqflags);
308 vblwait.reply.sequence = seq; 296 vblwait->reply.sequence = seq;
309 goto done; 297 goto done;
310 } 298 }
311 } 299 }
@@ -327,8 +315,8 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
327 315
328 memset((void *)vbl_sig, 0, sizeof(*vbl_sig)); 316 memset((void *)vbl_sig, 0, sizeof(*vbl_sig));
329 317
330 vbl_sig->sequence = vblwait.request.sequence; 318 vbl_sig->sequence = vblwait->request.sequence;
331 vbl_sig->info.si_signo = vblwait.request.signal; 319 vbl_sig->info.si_signo = vblwait->request.signal;
332 vbl_sig->task = current; 320 vbl_sig->task = current;
333 321
334 spin_lock_irqsave(&dev->vbl_lock, irqflags); 322 spin_lock_irqsave(&dev->vbl_lock, irqflags);
@@ -337,25 +325,22 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
337 325
338 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 326 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
339 327
340 vblwait.reply.sequence = seq; 328 vblwait->reply.sequence = seq;
341 } else { 329 } else {
342 if (flags & _DRM_VBLANK_SECONDARY) { 330 if (flags & _DRM_VBLANK_SECONDARY) {
343 if (dev->driver->vblank_wait2) 331 if (dev->driver->vblank_wait2)
344 ret = dev->driver->vblank_wait2(dev, &vblwait.request.sequence); 332 ret = dev->driver->vblank_wait2(dev, &vblwait->request.sequence);
345 } else if (dev->driver->vblank_wait) 333 } else if (dev->driver->vblank_wait)
346 ret = 334 ret =
347 dev->driver->vblank_wait(dev, 335 dev->driver->vblank_wait(dev,
348 &vblwait.request.sequence); 336 &vblwait->request.sequence);
349 337
350 do_gettimeofday(&now); 338 do_gettimeofday(&now);
351 vblwait.reply.tval_sec = now.tv_sec; 339 vblwait->reply.tval_sec = now.tv_sec;
352 vblwait.reply.tval_usec = now.tv_usec; 340 vblwait->reply.tval_usec = now.tv_usec;
353 } 341 }
354 342
355 done: 343 done:
356 if (copy_to_user(argp, &vblwait, sizeof(vblwait)))
357 return -EFAULT;
358
359 return ret; 344 return ret;
360} 345}
361 346