Advertisement
Guest User

Untitled

a guest
Dec 6th, 2010
213
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 26.96 KB | None | 0 0
  1. /*
  2. * LIRC base driver
  3. *
  4. * (L) by Artur Lipowski <alipowski@interia.pl>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. *
  20. * $Id: lirc_dev.c,v 1.105 2010/05/13 15:45:48 lirc Exp $
  21. *
  22. */
  23.  
  24. #ifdef HAVE_CONFIG_H
  25. # include <config.h>
  26. #endif
  27.  
  28. #include <linux/version.h>
  29. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
  30. #error "**********************************************************"
  31. #error " Sorry, this driver needs kernel version 2.2.18 or higher "
  32. #error "**********************************************************"
  33. #endif
  34.  
  35. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)
  36. #include <linux/autoconf.h>
  37. #else
  38. #include <generated/autoconf.h>
  39. #endif
  40. #include <linux/module.h>
  41. #include <linux/kernel.h>
  42. #include <linux/sched.h>
  43. #include <linux/errno.h>
  44. #include <linux/ioctl.h>
  45. #include <linux/fs.h>
  46. #include <linux/poll.h>
  47. #include <linux/smp_lock.h>
  48. #include <linux/completion.h>
  49. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
  50. #include <asm/uaccess.h>
  51. #include <asm/errno.h>
  52. #else
  53. #include <linux/uaccess.h>
  54. #include <linux/errno.h>
  55. #endif
  56. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
  57. #include <linux/wrapper.h>
  58. #endif
  59. #define __KERNEL_SYSCALLS__
  60. #include <linux/unistd.h>
  61. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
  62. #include <linux/kthread.h>
  63. #endif
  64. #ifdef CONFIG_COMPAT
  65. #include <linux/compat.h>
  66. #endif
  67.  
  68. #include "drivers/kcompat.h"
  69.  
  70. /* SysFS header */
  71. #if defined(LIRC_HAVE_SYSFS)
  72. #include <linux/device.h>
  73. #endif
  74.  
  75. #include "drivers/lirc.h"
  76. #include "lirc_dev.h"
  77.  
  78. static int debug;
  79. #define dprintk(fmt, args...) \
  80. do { \
  81. if (debug) \
  82. printk(KERN_DEBUG fmt, ## args); \
  83. } while (0)
  84.  
  85. #define IRCTL_DEV_NAME "BaseRemoteCtl"
  86. #define NOPLUG -1
  87. #define LOGHEAD "lirc_dev (%s[%d]): "
  88.  
  89. struct irctl {
  90. struct lirc_driver d;
  91. int attached;
  92. int open;
  93.  
  94. struct mutex buffer_lock;
  95. struct lirc_buffer *buf;
  96. unsigned int chunk_size;
  97.  
  98. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
  99. int tpid;
  100. struct completion *t_notify;
  101. struct completion *t_notify2;
  102. int shutdown;
  103. #else
  104. struct task_struct *task;
  105. #endif
  106. long jiffies_to_wait;
  107.  
  108. #ifdef LIRC_HAVE_DEVFS_24
  109. devfs_handle_t devfs_handle;
  110. #endif
  111. };
  112.  
  113. static DEFINE_MUTEX(lirc_dev_lock);
  114.  
  115. static struct irctl *irctls[MAX_IRCTL_DEVICES];
  116. static struct file_operations fops;
  117.  
  118. /* Only used for sysfs but defined to void otherwise */
  119. static lirc_class_t *lirc_class;
  120.  
  121. /* helper function
  122. * initializes the irctl structure
  123. */
  124. static void init_irctl(struct irctl *ir)
  125. {
  126. mutex_init(&ir->buffer_lock);
  127. ir->d.minor = NOPLUG;
  128. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
  129. ir->tpid = -1;
  130. #endif
  131. }
  132.  
  133. static void cleanup(struct irctl *ir)
  134. {
  135. dprintk(LOGHEAD "cleaning up\n", ir->d.name, ir->d.minor);
  136.  
  137. if (ir->buf != ir->d.rbuf) {
  138. lirc_buffer_free(ir->buf);
  139. kfree(ir->buf);
  140. }
  141. ir->buf = NULL;
  142. }
  143.  
  144. /* helper function
  145. * reads key codes from driver and puts them into buffer
  146. * returns 0 on success
  147. */
  148. static int add_to_buf(struct irctl *ir)
  149. {
  150. if (ir->d.add_to_buf) {
  151. int res = -ENODATA;
  152. int got_data = 0;
  153.  
  154. /*
  155. * service the device as long as it is returning
  156. * data and we have space
  157. */
  158. while ((res = ir->d.add_to_buf(ir->d.data, ir->buf)) == 0) {
  159. got_data++;
  160. }
  161.  
  162. if (res == -ENODEV)
  163. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
  164. ir->shutdown = 1;
  165. #else
  166. kthread_stop(ir->task);
  167. #endif
  168.  
  169. return got_data ? 0 : res;
  170. }
  171.  
  172. return 0;
  173. }
  174.  
  175. /* main function of the polling thread */
  176. static int lirc_thread(void *irctl)
  177. {
  178. struct irctl *ir = irctl;
  179.  
  180. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
  181. /*
  182. * This thread doesn't need any user-level access, so get rid
  183. * of all our resources
  184. */
  185. daemonize("lirc_dev");
  186.  
  187. if (ir->t_notify != NULL)
  188. complete(ir->t_notify);
  189.  
  190. #endif
  191. dprintk(LOGHEAD "poll thread started\n", ir->d.name, ir->d.minor);
  192.  
  193. do {
  194. if (ir->open) {
  195. if (ir->jiffies_to_wait) {
  196. set_current_state(TASK_INTERRUPTIBLE);
  197. schedule_timeout(ir->jiffies_to_wait);
  198. #ifndef LIRC_REMOVE_DURING_EXPORT
  199. } else {
  200. interruptible_sleep_on(
  201. ir->d.get_queue(ir->d.data));
  202. #endif
  203. }
  204. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
  205. if (ir->shutdown)
  206. #else
  207. if (kthread_should_stop())
  208. #endif
  209. break;
  210. if (!add_to_buf(ir))
  211. wake_up_interruptible(&ir->buf->wait_poll);
  212. } else {
  213. set_current_state(TASK_INTERRUPTIBLE);
  214. schedule();
  215. }
  216. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
  217. } while (!ir->shutdown);
  218.  
  219. if (ir->t_notify2 != NULL)
  220. wait_for_completion(ir->t_notify2);
  221.  
  222. ir->tpid = -1;
  223. if (ir->t_notify != NULL)
  224. complete(ir->t_notify);
  225. #else
  226. } while (!kthread_should_stop());
  227. #endif
  228.  
  229. dprintk(LOGHEAD "poll thread ended\n", ir->d.name, ir->d.minor);
  230.  
  231. return 0;
  232. }
  233.  
  234. int lirc_register_driver(struct lirc_driver *d)
  235. {
  236. struct irctl *ir;
  237. int minor;
  238. int bytes_in_key;
  239. unsigned int buffer_size;
  240. int err;
  241. #ifdef LIRC_HAVE_DEVFS_24
  242. char name[16];
  243. #endif
  244. DECLARE_COMPLETION(tn);
  245.  
  246. if (!d) {
  247. printk(KERN_ERR "lirc_dev: lirc_register_driver: "
  248. "driver pointer must be not NULL!\n");
  249. err = -EBADRQC;
  250. goto out;
  251. }
  252.  
  253. if (MAX_IRCTL_DEVICES <= d->minor) {
  254. printk(KERN_ERR "lirc_dev: lirc_register_driver: "
  255. "\"minor\" must be between 0 and %d (%d)!\n",
  256. MAX_IRCTL_DEVICES-1, d->minor);
  257. err = -EBADRQC;
  258. goto out;
  259. }
  260.  
  261. if (1 > d->code_length || (BUFLEN * 8) < d->code_length) {
  262. printk(KERN_ERR "lirc_dev: lirc_register_driver: "
  263. "code length in bits for minor (%d) "
  264. "must be less than %d!\n",
  265. d->minor, BUFLEN * 8);
  266. err = -EBADRQC;
  267. goto out;
  268. }
  269.  
  270. printk(KERN_INFO "lirc_dev: lirc_register_driver: sample_rate: %d\n",
  271. d->sample_rate);
  272. if (d->sample_rate) {
  273. if (2 > d->sample_rate || HZ < d->sample_rate) {
  274. printk(KERN_ERR "lirc_dev: lirc_register_driver: "
  275. "sample_rate must be between 2 and %d!\n", HZ);
  276. err = -EBADRQC;
  277. goto out;
  278. }
  279. if (!d->add_to_buf) {
  280. printk(KERN_ERR "lirc_dev: lirc_register_driver: "
  281. "add_to_buf cannot be NULL when "
  282. "sample_rate is set\n");
  283. err = -EBADRQC;
  284. goto out;
  285. }
  286. #ifndef LIRC_REMOVE_DURING_EXPORT
  287. } else if (!(d->fops && d->fops->read) && !d->get_queue && !d->rbuf) {
  288. #else
  289. } else if (!(d->fops && d->fops->read) && !d->rbuf) {
  290. #endif
  291. printk(KERN_ERR "lirc_dev: lirc_register_driver: "
  292. #ifndef LIRC_REMOVE_DURING_EXPORT
  293. "fops->read, get_queue and rbuf "
  294. #else
  295. "fops->read and rbuf "
  296. #endif
  297. "cannot all be NULL!\n");
  298. err = -EBADRQC;
  299. goto out;
  300. #ifndef LIRC_REMOVE_DURING_EXPORT
  301. } else if (!d->get_queue && !d->rbuf) {
  302. #else
  303. } else if (!d->rbuf) {
  304. #endif
  305. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
  306. if (!(d->fops && d->fops->read && d->fops->poll &&
  307. d->fops->ioctl)) {
  308. #else
  309. if (!(d->fops && d->fops->read && d->fops->poll &&
  310. d->fops->unlocked_ioctl)) {
  311. #endif
  312. printk(KERN_ERR "lirc_dev: lirc_register_driver: "
  313. "neither read, poll nor ioctl can be NULL!\n");
  314. err = -EBADRQC;
  315. goto out;
  316. }
  317. }
  318.  
  319. mutex_lock(&lirc_dev_lock);
  320.  
  321. minor = d->minor;
  322.  
  323. if (minor < 0) {
  324. /* find first free slot for driver */
  325. for (minor = 0; minor < MAX_IRCTL_DEVICES; minor++)
  326. if (!irctls[minor])
  327. break;
  328. if (MAX_IRCTL_DEVICES == minor) {
  329. printk(KERN_ERR "lirc_dev: lirc_register_driver: "
  330. "no free slots for drivers!\n");
  331. err = -ENOMEM;
  332. goto out_lock;
  333. }
  334. } else if (irctls[minor]) {
  335. printk(KERN_ERR "lirc_dev: lirc_register_driver: "
  336. "minor (%d) just registered!\n", minor);
  337. err = -EBUSY;
  338. goto out_lock;
  339. }
  340.  
  341. ir = kzalloc(sizeof(struct irctl), GFP_KERNEL);
  342. if (!ir) {
  343. err = -ENOMEM;
  344. goto out_lock;
  345. }
  346. init_irctl(ir);
  347. irctls[minor] = ir;
  348.  
  349. if (d->sample_rate) {
  350. ir->jiffies_to_wait = HZ / d->sample_rate;
  351. } else {
  352. /* it means - wait for external event in task queue */
  353. ir->jiffies_to_wait = 0;
  354. }
  355.  
  356. /* some safety check 8-) */
  357. d->name[sizeof(d->name)-1] = '\0';
  358.  
  359. bytes_in_key = d->code_length/8 + (d->code_length%8 ? 1 : 0);
  360. buffer_size = d->buffer_size ? d->buffer_size : BUFLEN / bytes_in_key;
  361.  
  362. if (d->rbuf) {
  363. ir->buf = d->rbuf;
  364. } else {
  365. ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
  366. if (!ir->buf) {
  367. err = -ENOMEM;
  368. goto out_lock;
  369. }
  370. err = lirc_buffer_init(ir->buf, bytes_in_key, buffer_size);
  371. if (err) {
  372. kfree(ir->buf);
  373. goto out_lock;
  374. }
  375. }
  376. ir->chunk_size = ir->buf->chunk_size;
  377.  
  378. if (d->features == 0)
  379. d->features = LIRC_CAN_REC_LIRCCODE;
  380.  
  381. ir->d = *d;
  382. ir->d.minor = minor;
  383.  
  384. #if defined(LIRC_HAVE_DEVFS_24)
  385. sprintf(name, DEV_LIRC "/%d", ir->d.minor);
  386. ir->devfs_handle = devfs_register(NULL, name, DEVFS_FL_DEFAULT,
  387. IRCTL_DEV_MAJOR, ir->d.minor,
  388. S_IFCHR | S_IRUSR | S_IWUSR,
  389. &fops, NULL);
  390. #elif defined(LIRC_HAVE_DEVFS_26)
  391. devfs_mk_cdev(MKDEV(IRCTL_DEV_MAJOR, ir->d.minor),
  392. S_IFCHR|S_IRUSR|S_IWUSR,
  393. DEV_LIRC "/%u", ir->d.minor);
  394. #endif
  395. (void) lirc_device_create(lirc_class, ir->d.dev,
  396. MKDEV(IRCTL_DEV_MAJOR, ir->d.minor), NULL,
  397. "lirc%u", ir->d.minor);
  398.  
  399. #ifndef LIRC_REMOVE_DURING_EXPORT
  400. if (d->sample_rate || d->get_queue) {
  401. #else
  402. if (d->sample_rate) {
  403. #endif
  404. /* try to fire up polling thread */
  405. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
  406. ir->t_notify = &tn;
  407. ir->tpid = kernel_thread(lirc_thread, (void *)ir, 0);
  408. if (ir->tpid < 0) {
  409. #else
  410. ir->task = kthread_run(lirc_thread, (void *)ir, "lirc_dev");
  411. if (IS_ERR(ir->task)) {
  412. #endif
  413. printk(KERN_ERR "lirc_dev: lirc_register_driver: "
  414. "cannot run poll thread for minor = %d\n",
  415. d->minor);
  416. err = -ECHILD;
  417. goto out_sysfs;
  418. }
  419. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
  420. wait_for_completion(&tn);
  421. ir->t_notify = NULL;
  422. #endif
  423. }
  424. ir->attached = 1;
  425. mutex_unlock(&lirc_dev_lock);
  426.  
  427. /*
  428. * Recent kernels should handle this autmatically by increasing/decreasing
  429. * use count when a dependant module is loaded/unloaded.
  430. */
  431. #ifndef KERNEL_2_5
  432. MOD_INC_USE_COUNT;
  433. #endif
  434. dprintk("lirc_dev: driver %s registered at minor number = %d\n",
  435. ir->d.name, ir->d.minor);
  436. d->minor = minor;
  437. return minor;
  438.  
  439. out_sysfs:
  440. lirc_device_destroy(lirc_class,
  441. MKDEV(IRCTL_DEV_MAJOR, ir->d.minor));
  442. #ifdef LIRC_HAVE_DEVFS_24
  443. devfs_unregister(ir->devfs_handle);
  444. #endif
  445. #ifdef LIRC_HAVE_DEVFS_26
  446. devfs_remove(DEV_LIRC "/%i", ir->d.minor);
  447. #endif
  448. out_lock:
  449. mutex_unlock(&lirc_dev_lock);
  450. out:
  451. return err;
  452. }
  453. EXPORT_SYMBOL(lirc_register_driver);
  454.  
  455. int lirc_unregister_driver(int minor)
  456. {
  457. struct irctl *ir;
  458. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
  459. DECLARE_COMPLETION(tn);
  460. DECLARE_COMPLETION(tn2);
  461. #endif
  462.  
  463. if (minor < 0 || minor >= MAX_IRCTL_DEVICES) {
  464. printk(KERN_ERR "lirc_dev: lirc_unregister_driver: "
  465. "\"minor\" must be between 0 and %d!\n",
  466. MAX_IRCTL_DEVICES-1);
  467. return -EBADRQC;
  468. }
  469.  
  470. ir = irctls[minor];
  471.  
  472. mutex_lock(&lirc_dev_lock);
  473.  
  474. if (ir->d.minor != minor) {
  475. printk(KERN_ERR "lirc_dev: lirc_unregister_driver: "
  476. "minor (%d) device not registered!", minor);
  477. mutex_unlock(&lirc_dev_lock);
  478. return -ENOENT;
  479. }
  480.  
  481. /* end up polling thread */
  482. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
  483. if (ir->tpid >= 0) {
  484. ir->t_notify = &tn;
  485. ir->t_notify2 = &tn2;
  486. ir->shutdown = 1;
  487. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
  488. {
  489. struct task_struct *p;
  490.  
  491. p = find_task_by_pid(ir->tpid);
  492. wake_up_process(p);
  493. }
  494. #else
  495. /* 2.2.x does not export wake_up_process() */
  496. wake_up_interruptible(ir->d.get_queue(ir->d.data));
  497. #endif
  498. complete(&tn2);
  499. wait_for_completion(&tn);
  500. ir->t_notify = NULL;
  501. ir->t_notify2 = NULL;
  502. }
  503. #else /* kernel >= 2.6.23 */
  504. if (ir->task)
  505. kthread_stop(ir->task);
  506. #endif
  507.  
  508. dprintk("lirc_dev: driver %s unregistered from minor number = %d\n",
  509. ir->d.name, ir->d.minor);
  510.  
  511. ir->attached = 0;
  512. if (ir->open) {
  513. dprintk(LOGHEAD "releasing opened driver\n",
  514. ir->d.name, ir->d.minor);
  515. wake_up_interruptible(&ir->buf->wait_poll);
  516. mutex_lock(&ir->buffer_lock);
  517. ir->d.set_use_dec(ir->d.data);
  518. module_put(ir->d.owner);
  519. mutex_unlock(&ir->buffer_lock);
  520. } else {
  521. cleanup(ir);
  522. irctls[minor] = NULL;
  523. kfree(ir);
  524. }
  525.  
  526. #ifdef LIRC_HAVE_DEVFS_24
  527. devfs_unregister(ir->devfs_handle);
  528. #endif
  529. #ifdef LIRC_HAVE_DEVFS_26
  530. devfs_remove(DEV_LIRC "/%u", ir->d.minor);
  531. #endif
  532. lirc_device_destroy(lirc_class,
  533. MKDEV(IRCTL_DEV_MAJOR, ir->d.minor));
  534.  
  535. mutex_unlock(&lirc_dev_lock);
  536.  
  537. /*
  538. * Recent kernels should handle this autmatically by increasing/decreasing
  539. * use count when a dependant module is loaded/unloaded.
  540. */
  541. #ifndef KERNEL_2_5
  542. MOD_DEC_USE_COUNT;
  543. #endif
  544.  
  545. return 0;
  546. }
  547. EXPORT_SYMBOL(lirc_unregister_driver);
  548.  
  549. static int irctl_open(struct inode *inode, struct file *file)
  550. {
  551. struct irctl *ir;
  552. int retval = 0;
  553.  
  554. if (iminor(inode) >= MAX_IRCTL_DEVICES || !irctls[iminor(inode)]) {
  555. dprintk("lirc_dev [%d]: open result = -ENODEV\n",
  556. iminor(inode));
  557. return -ENODEV;
  558. }
  559.  
  560. ir = irctls[iminor(inode)];
  561.  
  562. dprintk(LOGHEAD "open called\n", ir->d.name, ir->d.minor);
  563.  
  564. /* if the driver has an open function use it instead */
  565. if (ir->d.fops && ir->d.fops->open)
  566. return ir->d.fops->open(inode, file);
  567.  
  568. if (mutex_lock_interruptible(&lirc_dev_lock))
  569. return -ERESTARTSYS;
  570.  
  571. if (ir->d.minor == NOPLUG) {
  572. retval = -ENODEV;
  573. goto error;
  574. }
  575.  
  576. if (ir->open) {
  577. retval = -EBUSY;
  578. goto error;
  579. }
  580.  
  581. if (try_module_get(ir->d.owner)) {
  582. ++ir->open;
  583. retval = ir->d.set_use_inc(ir->d.data);
  584.  
  585. if (retval) {
  586. module_put(ir->d.owner);
  587. --ir->open;
  588. } else {
  589. lirc_buffer_clear(ir->buf);
  590. }
  591. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
  592. if (ir->tpid >= 0) {
  593. struct task_struct *p;
  594.  
  595. p = find_task_by_pid(ir->tpid);
  596. wake_up_process(p);
  597. }
  598. #else
  599. if (ir->task)
  600. wake_up_process(ir->task);
  601. #endif
  602. } else {
  603. retval = -ENODEV;
  604. }
  605. error:
  606. if (ir)
  607. dprintk(LOGHEAD "open result = %d\n", ir->d.name, ir->d.minor,
  608. retval);
  609.  
  610. mutex_unlock(&lirc_dev_lock);
  611.  
  612. return retval;
  613. }
  614.  
  615. static int irctl_close(struct inode *inode, struct file *file)
  616. {
  617. struct irctl *ir = irctls[iminor(inode)];
  618.  
  619. dprintk(LOGHEAD "close called\n", ir->d.name, ir->d.minor);
  620.  
  621. /* if the driver has a close function use it instead */
  622. if (ir->d.fops && ir->d.fops->release)
  623. return ir->d.fops->release(inode, file);
  624.  
  625. if (mutex_lock_interruptible(&lirc_dev_lock))
  626. return -ERESTARTSYS;
  627.  
  628. --ir->open;
  629. if (ir->attached) {
  630. ir->d.set_use_dec(ir->d.data);
  631. module_put(ir->d.owner);
  632. } else {
  633. cleanup(ir);
  634. irctls[ir->d.minor] = NULL;
  635. kfree(ir);
  636. }
  637.  
  638. mutex_unlock(&lirc_dev_lock);
  639.  
  640. return 0;
  641. }
  642.  
  643. static unsigned int irctl_poll(struct file *file, poll_table *wait)
  644. {
  645. struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
  646. unsigned int ret;
  647.  
  648. dprintk(LOGHEAD "poll called\n", ir->d.name, ir->d.minor);
  649.  
  650. /* if the driver has a poll function use it instead */
  651. if (ir->d.fops && ir->d.fops->poll)
  652. return ir->d.fops->poll(file, wait);
  653.  
  654. mutex_lock(&ir->buffer_lock);
  655. if (!ir->attached) {
  656. mutex_unlock(&ir->buffer_lock);
  657. return POLLERR;
  658. }
  659.  
  660. poll_wait(file, &ir->buf->wait_poll, wait);
  661.  
  662. dprintk(LOGHEAD "poll result = %s\n",
  663. ir->d.name, ir->d.minor,
  664. lirc_buffer_empty(ir->buf) ? "0" : "POLLIN|POLLRDNORM");
  665.  
  666. ret = lirc_buffer_empty(ir->buf) ? 0 : (POLLIN|POLLRDNORM);
  667.  
  668. mutex_unlock(&ir->buffer_lock);
  669. return ret;
  670. }
  671.  
  672. /*
  673. *
  674. */
  675. static int irctl_ioctl(struct inode *inode, struct file *file,
  676. unsigned int cmd, unsigned long arg)
  677. {
  678. unsigned long mode;
  679. int result;
  680. struct irctl *ir = irctls[iminor(inode)];
  681.  
  682. dprintk(LOGHEAD "ioctl called (0x%x)\n",
  683. ir->d.name, ir->d.minor, cmd);
  684.  
  685. /* if the driver has a ioctl function use it instead */
  686. if (ir->d.fops && ir->d.fops->ioctl) {
  687. result = ir->d.fops->ioctl(inode, file, cmd, arg);
  688. if (result != -ENOIOCTLCMD)
  689. return result;
  690. }
  691.  
  692. if (ir->d.minor == NOPLUG || !ir->attached) {
  693. dprintk(LOGHEAD "ioctl result = -ENODEV\n",
  694. ir->d.name, ir->d.minor);
  695. return -ENODEV;
  696. }
  697.  
  698. /* The driver can't handle cmd */
  699. result = 0;
  700.  
  701. switch (cmd) {
  702. case LIRC_GET_FEATURES:
  703. result = put_user(ir->d.features, (unsigned long *)arg);
  704. break;
  705. case LIRC_GET_LENGTH:
  706. result = put_user(ir->d.code_length, (unsigned long *) arg);
  707. break;
  708. case LIRC_GET_MIN_TIMEOUT:
  709. if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
  710. ir->d.min_timeout == 0)
  711. return -ENOSYS;
  712.  
  713. result = put_user(ir->d.min_timeout, (lirc_t *) arg);
  714. break;
  715. case LIRC_GET_MAX_TIMEOUT:
  716. if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
  717. ir->d.max_timeout == 0)
  718. return -ENOSYS;
  719.  
  720. result = put_user(ir->d.max_timeout, (lirc_t *) arg);
  721. break;
  722. case LIRC_GET_REC_MODE:
  723. if (!(ir->d.features & LIRC_CAN_REC_MASK))
  724. return -ENOSYS;
  725.  
  726. result = put_user(LIRC_REC2MODE
  727. (ir->d.features & LIRC_CAN_REC_MASK),
  728. (unsigned long *)arg);
  729. break;
  730. case LIRC_GET_SEND_MODE:
  731. if (!(ir->d.features & LIRC_CAN_SEND_MASK))
  732. return -ENOSYS;
  733.  
  734. result = put_user(LIRC_SEND2MODE
  735. (ir->d.features & LIRC_CAN_SEND_MASK),
  736. (unsigned long *)arg);
  737. break;
  738.  
  739. /*obsolete */
  740. case LIRC_SET_REC_MODE:
  741. if (!(ir->d.features & LIRC_CAN_REC_MASK))
  742. return -ENOSYS;
  743.  
  744. result = get_user(mode, (unsigned long *)arg);
  745. if (!result && !(LIRC_MODE2REC(mode) & ir->d.features))
  746. result = -EINVAL;
  747. break;
  748. case LIRC_SET_SEND_MODE:
  749. if (!(ir->d.features & LIRC_CAN_SEND_MASK))
  750. return -ENOSYS;
  751.  
  752. result = get_user(mode, (unsigned long *)arg);
  753. if (!result && !(LIRC_MODE2SEND(mode) & ir->d.features))
  754. result = -EINVAL;
  755. break;
  756. default:
  757. result = -EINVAL;
  758. }
  759.  
  760. switch (cmd) {
  761. case LIRC_SET_REC_MODE:
  762. case LIRC_SET_SEND_MODE:
  763. printk(KERN_NOTICE LOGHEAD "userspace uses outdated ioctl "
  764. "please update your lirc installation\n",
  765. ir->d.name, ir->d.minor);
  766. break;
  767. default:
  768. break;
  769. }
  770.  
  771. dprintk(LOGHEAD "ioctl result = %d\n",
  772. ir->d.name, ir->d.minor, result);
  773.  
  774. return result;
  775. }
  776.  
  777. #ifdef CONFIG_COMPAT
  778. #define LIRC_GET_FEATURES_COMPAT32 _IOR('i', 0x00000000, __u32)
  779.  
  780. #define LIRC_GET_SEND_MODE_COMPAT32 _IOR('i', 0x00000001, __u32)
  781. #define LIRC_GET_REC_MODE_COMPAT32 _IOR('i', 0x00000002, __u32)
  782.  
  783. #define LIRC_GET_LENGTH_COMPAT32 _IOR('i', 0x0000000f, __u32)
  784.  
  785. #define LIRC_SET_SEND_MODE_COMPAT32 _IOW('i', 0x00000011, __u32)
  786. #define LIRC_SET_REC_MODE_COMPAT32 _IOW('i', 0x00000012, __u32)
  787.  
  788. static long irctl_compat_ioctl(struct file *file,
  789. unsigned int cmd32,
  790. unsigned long arg)
  791. {
  792. mm_segment_t old_fs;
  793. int ret;
  794. unsigned long val;
  795. unsigned int cmd;
  796.  
  797. switch (cmd32) {
  798. case LIRC_GET_FEATURES_COMPAT32:
  799. case LIRC_GET_SEND_MODE_COMPAT32:
  800. case LIRC_GET_REC_MODE_COMPAT32:
  801. case LIRC_GET_LENGTH_COMPAT32:
  802. case LIRC_SET_SEND_MODE_COMPAT32:
  803. case LIRC_SET_REC_MODE_COMPAT32:
  804. /*
  805. * These commands expect (unsigned long *) arg
  806. * but the 32-bit app supplied (__u32 *).
  807. * Conversion is required.
  808. */
  809. if (get_user(val, (__u32 *)compat_ptr(arg)))
  810. return -EFAULT;
  811. lock_kernel();
  812. /*
  813. * tell irctl_ioctl that it's safe to use the pointer
  814. * to val which is in kernel address space and not in
  815. * user address space
  816. */
  817. old_fs = get_fs();
  818. set_fs(KERNEL_DS);
  819.  
  820. cmd = _IOC(_IOC_DIR(cmd32), _IOC_TYPE(cmd32), _IOC_NR(cmd32),
  821. (_IOC_TYPECHECK(unsigned long)));
  822. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
  823. ret = irctl_ioctl(file->f_dentry->d_inode, file,
  824. cmd, (unsigned long)(&val));
  825. #else
  826. ret = irctl_ioctl(file, cmd, (unsigned long)(&val));
  827. #endif
  828.  
  829. set_fs(old_fs);
  830. unlock_kernel();
  831. switch (cmd) {
  832. case LIRC_GET_FEATURES:
  833. case LIRC_GET_SEND_MODE:
  834. case LIRC_GET_REC_MODE:
  835. case LIRC_GET_LENGTH:
  836. if (!ret && put_user(val, (__u32 *)compat_ptr(arg)))
  837. return -EFAULT;
  838. break;
  839. }
  840. return ret;
  841.  
  842. case LIRC_GET_SEND_CARRIER:
  843. case LIRC_GET_REC_CARRIER:
  844. case LIRC_GET_SEND_DUTY_CYCLE:
  845. case LIRC_GET_REC_DUTY_CYCLE:
  846. case LIRC_GET_REC_RESOLUTION:
  847. case LIRC_GET_MIN_TIMEOUT:
  848. case LIRC_GET_MAX_TIMEOUT:
  849. case LIRC_GET_MIN_FILTER_PULSE:
  850. case LIRC_GET_MAX_FILTER_PULSE:
  851. case LIRC_GET_MIN_FILTER_SPACE:
  852. case LIRC_GET_MAX_FILTER_SPACE:
  853. case LIRC_SET_SEND_CARRIER:
  854. case LIRC_SET_REC_CARRIER:
  855. case LIRC_SET_SEND_DUTY_CYCLE:
  856. case LIRC_SET_REC_DUTY_CYCLE:
  857. case LIRC_SET_TRANSMITTER_MASK:
  858. case LIRC_SET_REC_TIMEOUT:
  859. case LIRC_SET_REC_TIMEOUT_REPORTS:
  860. case LIRC_SET_REC_FILTER_PULSE:
  861. case LIRC_SET_REC_FILTER_SPACE:
  862. case LIRC_SET_REC_FILTER:
  863. case LIRC_SET_MEASURE_CARRIER_MODE:
  864. case LIRC_SET_REC_DUTY_CYCLE_RANGE:
  865. case LIRC_SET_REC_CARRIER_RANGE:
  866. case LIRC_NOTIFY_DECODE:
  867. case LIRC_SETUP_START:
  868. case LIRC_SETUP_END:
  869. /*
  870. * These commands expect (unsigned int *) or (lirc_t *)
  871. * arg so no problems here. Just handle the locking.
  872. */
  873. lock_kernel();
  874. cmd = cmd32;
  875. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
  876. ret = irctl_ioctl(file->f_dentry->d_inode,
  877. file, cmd, arg);
  878. #else
  879. ret = irctl_ioctl(file, cmd, arg);
  880. #endif
  881. unlock_kernel();
  882. return ret;
  883. default:
  884. /* unknown */
  885. printk(KERN_ERR "lirc_dev: %s(%s:%d): Unknown cmd %08x\n",
  886. __func__, current->comm, current->pid, cmd32);
  887. return -ENOIOCTLCMD;
  888. }
  889. }
  890. #endif
  891.  
  892. static ssize_t irctl_read(struct file *file,
  893. char *buffer,
  894. size_t length,
  895. loff_t *ppos)
  896. {
  897. struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
  898. unsigned char buf[ir->chunk_size];
  899. int ret = 0, written = 0;
  900. int unlock = 1;
  901. DECLARE_WAITQUEUE(wait, current);
  902.  
  903. dprintk(LOGHEAD "read called\n", ir->d.name, ir->d.minor);
  904.  
  905. /* if the driver has a specific read function use it instead */
  906. if (ir->d.fops && ir->d.fops->read)
  907. return ir->d.fops->read(file, buffer, length, ppos);
  908.  
  909. if (mutex_lock_interruptible(&ir->buffer_lock))
  910. return -ERESTARTSYS;
  911. if (!ir->attached) {
  912. mutex_unlock(&ir->buffer_lock);
  913. return -ENODEV;
  914. }
  915.  
  916. if (length % ir->buf->chunk_size) {
  917. dprintk(LOGHEAD "read result = -EINVAL\n",
  918. ir->d.name, ir->d.minor);
  919. mutex_unlock(&ir->buffer_lock);
  920. return -EINVAL;
  921. }
  922.  
  923. /*
  924. * we add ourselves to the task queue before buffer check
  925. * to avoid losing scan code (in case when queue is awaken somewhere
  926. * between while condition checking and scheduling)
  927. */
  928. add_wait_queue(&ir->buf->wait_poll, &wait);
  929. set_current_state(TASK_INTERRUPTIBLE);
  930.  
  931. /*
  932. * while we didn't provide 'length' bytes, device is opened in blocking
  933. * mode and 'copy_to_user' is happy, wait for data.
  934. */
  935. while (written < length && ret == 0) {
  936. if (lirc_buffer_empty(ir->buf)) {
  937. /* According to the read(2) man page, 'written' can be
  938. * returned as less than 'length', instead of blocking
  939. * again, returning -EWOULDBLOCK, or returning
  940. * -ERESTARTSYS */
  941. if (written)
  942. break;
  943. if (file->f_flags & O_NONBLOCK) {
  944. ret = -EWOULDBLOCK;
  945. break;
  946. }
  947. if (signal_pending(current)) {
  948. ret = -ERESTARTSYS;
  949. break;
  950. }
  951.  
  952. mutex_unlock(&ir->buffer_lock);
  953. schedule();
  954. set_current_state(TASK_INTERRUPTIBLE);
  955.  
  956. if (mutex_lock_interruptible(&ir->buffer_lock)) {
  957. unlock = 0;
  958. ret = -ERESTARTSYS;
  959. break;
  960. }
  961.  
  962. if (!ir->attached) {
  963. ret = -ENODEV;
  964. break;
  965. }
  966. } else {
  967. lirc_buffer_read(ir->buf, buf);
  968. ret = copy_to_user((void *)buffer+written, buf,
  969. ir->buf->chunk_size);
  970. written += ir->buf->chunk_size;
  971. }
  972. }
  973.  
  974. remove_wait_queue(&ir->buf->wait_poll, &wait);
  975. set_current_state(TASK_RUNNING);
  976. if(unlock) mutex_unlock(&ir->buffer_lock);
  977.  
  978. dprintk(LOGHEAD "read result = %s (%d)\n",
  979. ir->d.name, ir->d.minor, ret ? "-EFAULT" : "OK", ret);
  980.  
  981. return ret ? ret : written;
  982. }
  983.  
  984.  
  985. void *lirc_get_pdata(struct file *file)
  986. {
  987. void *data = NULL;
  988.  
  989. if (file && file->f_dentry && file->f_dentry->d_inode &&
  990. file->f_dentry->d_inode->i_rdev) {
  991. struct irctl *ir;
  992. ir = irctls[iminor(file->f_dentry->d_inode)];
  993. data = ir->d.data;
  994. }
  995.  
  996. return data;
  997. }
  998. EXPORT_SYMBOL(lirc_get_pdata);
  999.  
  1000.  
  1001. static ssize_t irctl_write(struct file *file, const char *buffer,
  1002. size_t length, loff_t *ppos)
  1003. {
  1004. struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
  1005.  
  1006. dprintk(LOGHEAD "write called\n", ir->d.name, ir->d.minor);
  1007.  
  1008. /* if the driver has a specific read function use it instead */
  1009. if (ir->d.fops && ir->d.fops->write)
  1010. return ir->d.fops->write(file, buffer, length, ppos);
  1011.  
  1012. if (!ir->attached)
  1013. return -ENODEV;
  1014.  
  1015. return -EINVAL;
  1016. }
  1017.  
  1018.  
  1019. static struct file_operations fops = {
  1020. .owner = THIS_MODULE,
  1021. .read = irctl_read,
  1022. .write = irctl_write,
  1023. .poll = irctl_poll,
  1024. .ioctl = irctl_ioctl,
  1025. #ifdef CONFIG_COMPAT
  1026. .compat_ioctl = irctl_compat_ioctl,
  1027. #endif
  1028. .open = irctl_open,
  1029. .release = irctl_close
  1030. };
  1031.  
  1032. /* For now don't try to use it as a static version ! */
  1033. #ifdef MODULE
  1034.  
  1035. static int __init lirc_dev_init(void)
  1036. {
  1037. if (register_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME, &fops)) {
  1038. printk(KERN_ERR "lirc_dev: register_chrdev failed\n");
  1039. goto out;
  1040. }
  1041.  
  1042. lirc_class = class_create(THIS_MODULE, "lirc");
  1043. if (IS_ERR(lirc_class)) {
  1044. printk(KERN_ERR "lirc_dev: class_create failed\n");
  1045. goto out_unregister;
  1046. }
  1047.  
  1048. printk(KERN_INFO "lirc_dev: IR Remote Control driver registered, "
  1049. "major %d \n", IRCTL_DEV_MAJOR);
  1050.  
  1051. return 0;
  1052.  
  1053. out_unregister:
  1054. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
  1055. if (unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME))
  1056. printk(KERN_ERR "lirc_dev: unregister_chrdev failed!\n");
  1057. #else
  1058. /* unregister_chrdev returns void now */
  1059. unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME);
  1060. #endif
  1061. out:
  1062. return -1;
  1063. }
  1064.  
  1065. static void __exit lirc_dev_exit(void)
  1066. {
  1067. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
  1068. int ret;
  1069.  
  1070. ret = unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME);
  1071. class_destroy(lirc_class);
  1072.  
  1073. if (ret)
  1074. printk(KERN_ERR "lirc_dev: error in "
  1075. "module_unregister_chrdev: %d\n", ret);
  1076. else
  1077. dprintk("lirc_dev: module successfully unloaded\n");
  1078. #else
  1079. /* unregister_chrdev returns void now */
  1080. unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME);
  1081. class_destroy(lirc_class);
  1082. dprintk("lirc_dev: module unloaded\n");
  1083. #endif
  1084. }
  1085.  
  1086. module_init(lirc_dev_init);
  1087. module_exit(lirc_dev_exit);
  1088.  
  1089. MODULE_DESCRIPTION("LIRC base driver module");
  1090. MODULE_AUTHOR("Artur Lipowski");
  1091. MODULE_LICENSE("GPL");
  1092. MODULE_ALIAS_CHARDEV_MAJOR(IRCTL_DEV_MAJOR);
  1093.  
  1094. module_param(debug, bool, S_IRUGO | S_IWUSR);
  1095. MODULE_PARM_DESC(debug, "Enable debugging messages");
  1096.  
  1097. #endif /* MODULE */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement