aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/IR/lirc_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/IR/lirc_dev.c')
-rw-r--r--drivers/media/IR/lirc_dev.c133
1 files changed, 89 insertions, 44 deletions
diff --git a/drivers/media/IR/lirc_dev.c b/drivers/media/IR/lirc_dev.c
index 202581808bdc..8418b14ee4d2 100644
--- a/drivers/media/IR/lirc_dev.c
+++ b/drivers/media/IR/lirc_dev.c
@@ -57,13 +57,12 @@ struct irctl {
57 57
58 struct task_struct *task; 58 struct task_struct *task;
59 long jiffies_to_wait; 59 long jiffies_to_wait;
60
61 struct cdev cdev;
62}; 60};
63 61
64static DEFINE_MUTEX(lirc_dev_lock); 62static DEFINE_MUTEX(lirc_dev_lock);
65 63
66static struct irctl *irctls[MAX_IRCTL_DEVICES]; 64static struct irctl *irctls[MAX_IRCTL_DEVICES];
65static struct cdev cdevs[MAX_IRCTL_DEVICES];
67 66
68/* Only used for sysfs but defined to void otherwise */ 67/* Only used for sysfs but defined to void otherwise */
69static struct class *lirc_class; 68static struct class *lirc_class;
@@ -71,15 +70,13 @@ static struct class *lirc_class;
71/* helper function 70/* helper function
72 * initializes the irctl structure 71 * initializes the irctl structure
73 */ 72 */
74static void init_irctl(struct irctl *ir) 73static void lirc_irctl_init(struct irctl *ir)
75{ 74{
76 dev_dbg(ir->d.dev, LOGHEAD "initializing irctl\n",
77 ir->d.name, ir->d.minor);
78 mutex_init(&ir->irctl_lock); 75 mutex_init(&ir->irctl_lock);
79 ir->d.minor = NOPLUG; 76 ir->d.minor = NOPLUG;
80} 77}
81 78
82static void cleanup(struct irctl *ir) 79static void lirc_irctl_cleanup(struct irctl *ir)
83{ 80{
84 dev_dbg(ir->d.dev, LOGHEAD "cleaning up\n", ir->d.name, ir->d.minor); 81 dev_dbg(ir->d.dev, LOGHEAD "cleaning up\n", ir->d.name, ir->d.minor);
85 82
@@ -96,7 +93,7 @@ static void cleanup(struct irctl *ir)
96 * reads key codes from driver and puts them into buffer 93 * reads key codes from driver and puts them into buffer
97 * returns 0 on success 94 * returns 0 on success
98 */ 95 */
99static int add_to_buf(struct irctl *ir) 96static int lirc_add_to_buf(struct irctl *ir)
100{ 97{
101 if (ir->d.add_to_buf) { 98 if (ir->d.add_to_buf) {
102 int res = -ENODATA; 99 int res = -ENODATA;
@@ -139,7 +136,7 @@ static int lirc_thread(void *irctl)
139 } 136 }
140 if (kthread_should_stop()) 137 if (kthread_should_stop())
141 break; 138 break;
142 if (!add_to_buf(ir)) 139 if (!lirc_add_to_buf(ir))
143 wake_up_interruptible(&ir->buf->wait_poll); 140 wake_up_interruptible(&ir->buf->wait_poll);
144 } else { 141 } else {
145 set_current_state(TASK_INTERRUPTIBLE); 142 set_current_state(TASK_INTERRUPTIBLE);
@@ -154,12 +151,15 @@ static int lirc_thread(void *irctl)
154} 151}
155 152
156 153
157static struct file_operations fops = { 154static struct file_operations lirc_dev_fops = {
158 .owner = THIS_MODULE, 155 .owner = THIS_MODULE,
159 .read = lirc_dev_fop_read, 156 .read = lirc_dev_fop_read,
160 .write = lirc_dev_fop_write, 157 .write = lirc_dev_fop_write,
161 .poll = lirc_dev_fop_poll, 158 .poll = lirc_dev_fop_poll,
162 .unlocked_ioctl = lirc_dev_fop_ioctl, 159 .unlocked_ioctl = lirc_dev_fop_ioctl,
160#ifdef CONFIG_COMPAT
161 .compat_ioctl = lirc_dev_fop_ioctl,
162#endif
163 .open = lirc_dev_fop_open, 163 .open = lirc_dev_fop_open,
164 .release = lirc_dev_fop_close, 164 .release = lirc_dev_fop_close,
165 .llseek = noop_llseek, 165 .llseek = noop_llseek,
@@ -169,19 +169,20 @@ static int lirc_cdev_add(struct irctl *ir)
169{ 169{
170 int retval; 170 int retval;
171 struct lirc_driver *d = &ir->d; 171 struct lirc_driver *d = &ir->d;
172 struct cdev *cdev = &cdevs[d->minor];
172 173
173 if (d->fops) { 174 if (d->fops) {
174 cdev_init(&ir->cdev, d->fops); 175 cdev_init(cdev, d->fops);
175 ir->cdev.owner = d->owner; 176 cdev->owner = d->owner;
176 } else { 177 } else {
177 cdev_init(&ir->cdev, &fops); 178 cdev_init(cdev, &lirc_dev_fops);
178 ir->cdev.owner = THIS_MODULE; 179 cdev->owner = THIS_MODULE;
179 } 180 }
180 kobject_set_name(&ir->cdev.kobj, "lirc%d", d->minor); 181 kobject_set_name(&cdev->kobj, "lirc%d", d->minor);
181 182
182 retval = cdev_add(&ir->cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1); 183 retval = cdev_add(cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1);
183 if (retval) 184 if (retval)
184 kobject_put(&ir->cdev.kobj); 185 kobject_put(&cdev->kobj);
185 186
186 return retval; 187 return retval;
187} 188}
@@ -202,6 +203,12 @@ int lirc_register_driver(struct lirc_driver *d)
202 goto out; 203 goto out;
203 } 204 }
204 205
206 if (!d->dev) {
207 printk(KERN_ERR "%s: dev pointer not filled in!\n", __func__);
208 err = -EINVAL;
209 goto out;
210 }
211
205 if (MAX_IRCTL_DEVICES <= d->minor) { 212 if (MAX_IRCTL_DEVICES <= d->minor) {
206 dev_err(d->dev, "lirc_dev: lirc_register_driver: " 213 dev_err(d->dev, "lirc_dev: lirc_register_driver: "
207 "\"minor\" must be between 0 and %d (%d)!\n", 214 "\"minor\" must be between 0 and %d (%d)!\n",
@@ -277,7 +284,7 @@ int lirc_register_driver(struct lirc_driver *d)
277 err = -ENOMEM; 284 err = -ENOMEM;
278 goto out_lock; 285 goto out_lock;
279 } 286 }
280 init_irctl(ir); 287 lirc_irctl_init(ir);
281 irctls[minor] = ir; 288 irctls[minor] = ir;
282 d->minor = minor; 289 d->minor = minor;
283 290
@@ -316,7 +323,6 @@ int lirc_register_driver(struct lirc_driver *d)
316 d->features = LIRC_CAN_REC_LIRCCODE; 323 d->features = LIRC_CAN_REC_LIRCCODE;
317 324
318 ir->d = *d; 325 ir->d = *d;
319 ir->d.minor = minor;
320 326
321 device_create(lirc_class, ir->d.dev, 327 device_create(lirc_class, ir->d.dev,
322 MKDEV(MAJOR(lirc_base_dev), ir->d.minor), NULL, 328 MKDEV(MAJOR(lirc_base_dev), ir->d.minor), NULL,
@@ -357,21 +363,28 @@ EXPORT_SYMBOL(lirc_register_driver);
357int lirc_unregister_driver(int minor) 363int lirc_unregister_driver(int minor)
358{ 364{
359 struct irctl *ir; 365 struct irctl *ir;
366 struct cdev *cdev;
360 367
361 if (minor < 0 || minor >= MAX_IRCTL_DEVICES) { 368 if (minor < 0 || minor >= MAX_IRCTL_DEVICES) {
362 printk(KERN_ERR "lirc_dev: lirc_unregister_driver: " 369 printk(KERN_ERR "lirc_dev: %s: minor (%d) must be between "
363 "\"minor (%d)\" must be between 0 and %d!\n", 370 "0 and %d!\n", __func__, minor, MAX_IRCTL_DEVICES-1);
364 minor, MAX_IRCTL_DEVICES-1);
365 return -EBADRQC; 371 return -EBADRQC;
366 } 372 }
367 373
368 ir = irctls[minor]; 374 ir = irctls[minor];
375 if (!ir) {
376 printk(KERN_ERR "lirc_dev: %s: failed to get irctl struct "
377 "for minor %d!\n", __func__, minor);
378 return -ENOENT;
379 }
380
381 cdev = &cdevs[minor];
369 382
370 mutex_lock(&lirc_dev_lock); 383 mutex_lock(&lirc_dev_lock);
371 384
372 if (ir->d.minor != minor) { 385 if (ir->d.minor != minor) {
373 printk(KERN_ERR "lirc_dev: lirc_unregister_driver: " 386 printk(KERN_ERR "lirc_dev: %s: minor (%d) device not "
374 "minor (%d) device not registered!", minor); 387 "registered!\n", __func__, minor);
375 mutex_unlock(&lirc_dev_lock); 388 mutex_unlock(&lirc_dev_lock);
376 return -ENOENT; 389 return -ENOENT;
377 } 390 }
@@ -390,12 +403,11 @@ int lirc_unregister_driver(int minor)
390 wake_up_interruptible(&ir->buf->wait_poll); 403 wake_up_interruptible(&ir->buf->wait_poll);
391 mutex_lock(&ir->irctl_lock); 404 mutex_lock(&ir->irctl_lock);
392 ir->d.set_use_dec(ir->d.data); 405 ir->d.set_use_dec(ir->d.data);
393 module_put(ir->d.owner); 406 module_put(cdev->owner);
394 mutex_unlock(&ir->irctl_lock); 407 mutex_unlock(&ir->irctl_lock);
395 cdev_del(&ir->cdev);
396 } else { 408 } else {
397 cleanup(ir); 409 lirc_irctl_cleanup(ir);
398 cdev_del(&ir->cdev); 410 cdev_del(cdev);
399 kfree(ir); 411 kfree(ir);
400 irctls[minor] = NULL; 412 irctls[minor] = NULL;
401 } 413 }
@@ -409,6 +421,7 @@ EXPORT_SYMBOL(lirc_unregister_driver);
409int lirc_dev_fop_open(struct inode *inode, struct file *file) 421int lirc_dev_fop_open(struct inode *inode, struct file *file)
410{ 422{
411 struct irctl *ir; 423 struct irctl *ir;
424 struct cdev *cdev;
412 int retval = 0; 425 int retval = 0;
413 426
414 if (iminor(inode) >= MAX_IRCTL_DEVICES) { 427 if (iminor(inode) >= MAX_IRCTL_DEVICES) {
@@ -425,7 +438,6 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file)
425 retval = -ENODEV; 438 retval = -ENODEV;
426 goto error; 439 goto error;
427 } 440 }
428 file->private_data = ir;
429 441
430 dev_dbg(ir->d.dev, LOGHEAD "open called\n", ir->d.name, ir->d.minor); 442 dev_dbg(ir->d.dev, LOGHEAD "open called\n", ir->d.name, ir->d.minor);
431 443
@@ -439,13 +451,14 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file)
439 goto error; 451 goto error;
440 } 452 }
441 453
442 if (try_module_get(ir->d.owner)) { 454 cdev = &cdevs[iminor(inode)];
443 ++ir->open; 455 if (try_module_get(cdev->owner)) {
456 ir->open++;
444 retval = ir->d.set_use_inc(ir->d.data); 457 retval = ir->d.set_use_inc(ir->d.data);
445 458
446 if (retval) { 459 if (retval) {
447 module_put(ir->d.owner); 460 module_put(cdev->owner);
448 --ir->open; 461 ir->open--;
449 } else { 462 } else {
450 lirc_buffer_clear(ir->buf); 463 lirc_buffer_clear(ir->buf);
451 } 464 }
@@ -469,17 +482,24 @@ EXPORT_SYMBOL(lirc_dev_fop_open);
469int lirc_dev_fop_close(struct inode *inode, struct file *file) 482int lirc_dev_fop_close(struct inode *inode, struct file *file)
470{ 483{
471 struct irctl *ir = irctls[iminor(inode)]; 484 struct irctl *ir = irctls[iminor(inode)];
485 struct cdev *cdev = &cdevs[iminor(inode)];
486
487 if (!ir) {
488 printk(KERN_ERR "%s: called with invalid irctl\n", __func__);
489 return -EINVAL;
490 }
472 491
473 dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor); 492 dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor);
474 493
475 WARN_ON(mutex_lock_killable(&lirc_dev_lock)); 494 WARN_ON(mutex_lock_killable(&lirc_dev_lock));
476 495
477 --ir->open; 496 ir->open--;
478 if (ir->attached) { 497 if (ir->attached) {
479 ir->d.set_use_dec(ir->d.data); 498 ir->d.set_use_dec(ir->d.data);
480 module_put(ir->d.owner); 499 module_put(cdev->owner);
481 } else { 500 } else {
482 cleanup(ir); 501 lirc_irctl_cleanup(ir);
502 cdev_del(cdev);
483 irctls[ir->d.minor] = NULL; 503 irctls[ir->d.minor] = NULL;
484 kfree(ir); 504 kfree(ir);
485 } 505 }
@@ -495,6 +515,11 @@ unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait)
495 struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)]; 515 struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
496 unsigned int ret; 516 unsigned int ret;
497 517
518 if (!ir) {
519 printk(KERN_ERR "%s: called with invalid irctl\n", __func__);
520 return POLLERR;
521 }
522
498 dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor); 523 dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor);
499 524
500 if (!ir->attached) { 525 if (!ir->attached) {
@@ -521,9 +546,14 @@ EXPORT_SYMBOL(lirc_dev_fop_poll);
521 546
522long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 547long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
523{ 548{
524 unsigned long mode; 549 __u32 mode;
525 int result = 0; 550 int result = 0;
526 struct irctl *ir = file->private_data; 551 struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
552
553 if (!ir) {
554 printk(KERN_ERR "lirc_dev: %s: no irctl found!\n", __func__);
555 return -ENODEV;
556 }
527 557
528 dev_dbg(ir->d.dev, LOGHEAD "ioctl called (0x%x)\n", 558 dev_dbg(ir->d.dev, LOGHEAD "ioctl called (0x%x)\n",
529 ir->d.name, ir->d.minor, cmd); 559 ir->d.name, ir->d.minor, cmd);
@@ -538,7 +568,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
538 568
539 switch (cmd) { 569 switch (cmd) {
540 case LIRC_GET_FEATURES: 570 case LIRC_GET_FEATURES:
541 result = put_user(ir->d.features, (unsigned long *)arg); 571 result = put_user(ir->d.features, (__u32 *)arg);
542 break; 572 break;
543 case LIRC_GET_REC_MODE: 573 case LIRC_GET_REC_MODE:
544 if (!(ir->d.features & LIRC_CAN_REC_MASK)) { 574 if (!(ir->d.features & LIRC_CAN_REC_MASK)) {
@@ -548,7 +578,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
548 578
549 result = put_user(LIRC_REC2MODE 579 result = put_user(LIRC_REC2MODE
550 (ir->d.features & LIRC_CAN_REC_MASK), 580 (ir->d.features & LIRC_CAN_REC_MASK),
551 (unsigned long *)arg); 581 (__u32 *)arg);
552 break; 582 break;
553 case LIRC_SET_REC_MODE: 583 case LIRC_SET_REC_MODE:
554 if (!(ir->d.features & LIRC_CAN_REC_MASK)) { 584 if (!(ir->d.features & LIRC_CAN_REC_MASK)) {
@@ -556,7 +586,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
556 break; 586 break;
557 } 587 }
558 588
559 result = get_user(mode, (unsigned long *)arg); 589 result = get_user(mode, (__u32 *)arg);
560 if (!result && !(LIRC_MODE2REC(mode) & ir->d.features)) 590 if (!result && !(LIRC_MODE2REC(mode) & ir->d.features))
561 result = -EINVAL; 591 result = -EINVAL;
562 /* 592 /*
@@ -565,7 +595,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
565 */ 595 */
566 break; 596 break;
567 case LIRC_GET_LENGTH: 597 case LIRC_GET_LENGTH:
568 result = put_user(ir->d.code_length, (unsigned long *)arg); 598 result = put_user(ir->d.code_length, (__u32 *)arg);
569 break; 599 break;
570 case LIRC_GET_MIN_TIMEOUT: 600 case LIRC_GET_MIN_TIMEOUT:
571 if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || 601 if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
@@ -574,7 +604,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
574 break; 604 break;
575 } 605 }
576 606
577 result = put_user(ir->d.min_timeout, (unsigned long *)arg); 607 result = put_user(ir->d.min_timeout, (__u32 *)arg);
578 break; 608 break;
579 case LIRC_GET_MAX_TIMEOUT: 609 case LIRC_GET_MAX_TIMEOUT:
580 if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || 610 if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
@@ -583,7 +613,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
583 break; 613 break;
584 } 614 }
585 615
586 result = put_user(ir->d.max_timeout, (unsigned long *)arg); 616 result = put_user(ir->d.max_timeout, (__u32 *)arg);
587 break; 617 break;
588 default: 618 default:
589 result = -EINVAL; 619 result = -EINVAL;
@@ -604,12 +634,21 @@ ssize_t lirc_dev_fop_read(struct file *file,
604 loff_t *ppos) 634 loff_t *ppos)
605{ 635{
606 struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)]; 636 struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
607 unsigned char buf[ir->chunk_size]; 637 unsigned char *buf;
608 int ret = 0, written = 0; 638 int ret = 0, written = 0;
609 DECLARE_WAITQUEUE(wait, current); 639 DECLARE_WAITQUEUE(wait, current);
610 640
641 if (!ir) {
642 printk(KERN_ERR "%s: called with invalid irctl\n", __func__);
643 return -ENODEV;
644 }
645
611 dev_dbg(ir->d.dev, LOGHEAD "read called\n", ir->d.name, ir->d.minor); 646 dev_dbg(ir->d.dev, LOGHEAD "read called\n", ir->d.name, ir->d.minor);
612 647
648 buf = kzalloc(ir->chunk_size, GFP_KERNEL);
649 if (!buf)
650 return -ENOMEM;
651
613 if (mutex_lock_interruptible(&ir->irctl_lock)) 652 if (mutex_lock_interruptible(&ir->irctl_lock))
614 return -ERESTARTSYS; 653 return -ERESTARTSYS;
615 if (!ir->attached) { 654 if (!ir->attached) {
@@ -681,6 +720,7 @@ ssize_t lirc_dev_fop_read(struct file *file,
681 mutex_unlock(&ir->irctl_lock); 720 mutex_unlock(&ir->irctl_lock);
682 721
683out_unlocked: 722out_unlocked:
723 kfree(buf);
684 dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n", 724 dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n",
685 ir->d.name, ir->d.minor, ret ? "-EFAULT" : "OK", ret); 725 ir->d.name, ir->d.minor, ret ? "-EFAULT" : "OK", ret);
686 726
@@ -709,6 +749,11 @@ ssize_t lirc_dev_fop_write(struct file *file, const char *buffer,
709{ 749{
710 struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)]; 750 struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
711 751
752 if (!ir) {
753 printk(KERN_ERR "%s: called with invalid irctl\n", __func__);
754 return -ENODEV;
755 }
756
712 dev_dbg(ir->d.dev, LOGHEAD "write called\n", ir->d.name, ir->d.minor); 757 dev_dbg(ir->d.dev, LOGHEAD "write called\n", ir->d.name, ir->d.minor);
713 758
714 if (!ir->attached) 759 if (!ir->attached)