aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ieee1394/raw1394.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ieee1394/raw1394.c')
-rw-r--r--drivers/ieee1394/raw1394.c138
1 files changed, 80 insertions, 58 deletions
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 571ea68c0cf2..5ec4f5eb6b19 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -44,14 +44,15 @@
44#include <linux/compat.h> 44#include <linux/compat.h>
45 45
46#include "csr1212.h" 46#include "csr1212.h"
47#include "highlevel.h"
48#include "hosts.h"
47#include "ieee1394.h" 49#include "ieee1394.h"
48#include "ieee1394_types.h"
49#include "ieee1394_core.h" 50#include "ieee1394_core.h"
50#include "nodemgr.h" 51#include "ieee1394_hotplug.h"
51#include "hosts.h"
52#include "highlevel.h"
53#include "iso.h"
54#include "ieee1394_transactions.h" 52#include "ieee1394_transactions.h"
53#include "ieee1394_types.h"
54#include "iso.h"
55#include "nodemgr.h"
55#include "raw1394.h" 56#include "raw1394.h"
56#include "raw1394-private.h" 57#include "raw1394-private.h"
57 58
@@ -66,7 +67,7 @@
66#define DBGMSG(fmt, args...) \ 67#define DBGMSG(fmt, args...) \
67printk(KERN_INFO "raw1394:" fmt "\n" , ## args) 68printk(KERN_INFO "raw1394:" fmt "\n" , ## args)
68#else 69#else
69#define DBGMSG(fmt, args...) 70#define DBGMSG(fmt, args...) do {} while (0)
70#endif 71#endif
71 72
72static LIST_HEAD(host_info_list); 73static LIST_HEAD(host_info_list);
@@ -132,10 +133,9 @@ static void free_pending_request(struct pending_request *req)
132static void __queue_complete_req(struct pending_request *req) 133static void __queue_complete_req(struct pending_request *req)
133{ 134{
134 struct file_info *fi = req->file_info; 135 struct file_info *fi = req->file_info;
135 list_move_tail(&req->list, &fi->req_complete);
136 136
137 up(&fi->complete_sem); 137 list_move_tail(&req->list, &fi->req_complete);
138 wake_up_interruptible(&fi->poll_wait_complete); 138 wake_up(&fi->wait_complete);
139} 139}
140 140
141static void queue_complete_req(struct pending_request *req) 141static void queue_complete_req(struct pending_request *req)
@@ -463,13 +463,36 @@ raw1394_compat_read(const char __user *buf, struct raw1394_request *r)
463 463
464#endif 464#endif
465 465
466/* get next completed request (caller must hold fi->reqlists_lock) */
467static inline struct pending_request *__next_complete_req(struct file_info *fi)
468{
469 struct list_head *lh;
470 struct pending_request *req = NULL;
471
472 if (!list_empty(&fi->req_complete)) {
473 lh = fi->req_complete.next;
474 list_del(lh);
475 req = list_entry(lh, struct pending_request, list);
476 }
477 return req;
478}
479
480/* atomically get next completed request */
481static struct pending_request *next_complete_req(struct file_info *fi)
482{
483 unsigned long flags;
484 struct pending_request *req;
485
486 spin_lock_irqsave(&fi->reqlists_lock, flags);
487 req = __next_complete_req(fi);
488 spin_unlock_irqrestore(&fi->reqlists_lock, flags);
489 return req;
490}
466 491
467static ssize_t raw1394_read(struct file *file, char __user * buffer, 492static ssize_t raw1394_read(struct file *file, char __user * buffer,
468 size_t count, loff_t * offset_is_ignored) 493 size_t count, loff_t * offset_is_ignored)
469{ 494{
470 unsigned long flags;
471 struct file_info *fi = (struct file_info *)file->private_data; 495 struct file_info *fi = (struct file_info *)file->private_data;
472 struct list_head *lh;
473 struct pending_request *req; 496 struct pending_request *req;
474 ssize_t ret; 497 ssize_t ret;
475 498
@@ -487,22 +510,21 @@ static ssize_t raw1394_read(struct file *file, char __user * buffer,
487 } 510 }
488 511
489 if (file->f_flags & O_NONBLOCK) { 512 if (file->f_flags & O_NONBLOCK) {
490 if (down_trylock(&fi->complete_sem)) { 513 if (!(req = next_complete_req(fi)))
491 return -EAGAIN; 514 return -EAGAIN;
492 }
493 } else { 515 } else {
494 if (down_interruptible(&fi->complete_sem)) { 516 /*
517 * NB: We call the macro wait_event_interruptible() with a
518 * condition argument with side effect. This is only possible
519 * because the side effect does not occur until the condition
520 * became true, and wait_event_interruptible() won't evaluate
521 * the condition again after that.
522 */
523 if (wait_event_interruptible(fi->wait_complete,
524 (req = next_complete_req(fi))))
495 return -ERESTARTSYS; 525 return -ERESTARTSYS;
496 }
497 } 526 }
498 527
499 spin_lock_irqsave(&fi->reqlists_lock, flags);
500 lh = fi->req_complete.next;
501 list_del(lh);
502 spin_unlock_irqrestore(&fi->reqlists_lock, flags);
503
504 req = list_entry(lh, struct pending_request, list);
505
506 if (req->req.length) { 528 if (req->req.length) {
507 if (copy_to_user(int2ptr(req->req.recvb), req->data, 529 if (copy_to_user(int2ptr(req->req.recvb), req->data,
508 req->req.length)) { 530 req->req.length)) {
@@ -1752,6 +1774,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
1752 addr->notification_options |= addr->client_transactions; 1774 addr->notification_options |= addr->client_transactions;
1753 addr->recvb = req->req.recvb; 1775 addr->recvb = req->req.recvb;
1754 addr->rec_length = (u16) ((req->req.misc >> 16) & 0xFFFF); 1776 addr->rec_length = (u16) ((req->req.misc >> 16) & 0xFFFF);
1777
1755 spin_lock_irqsave(&host_info_lock, flags); 1778 spin_lock_irqsave(&host_info_lock, flags);
1756 hi = find_host_info(fi->host); 1779 hi = find_host_info(fi->host);
1757 same_host = 0; 1780 same_host = 0;
@@ -1777,9 +1800,9 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
1777 } 1800 }
1778 if (same_host) { 1801 if (same_host) {
1779 /* addressrange occupied by same host */ 1802 /* addressrange occupied by same host */
1803 spin_unlock_irqrestore(&host_info_lock, flags);
1780 vfree(addr->addr_space_buffer); 1804 vfree(addr->addr_space_buffer);
1781 kfree(addr); 1805 kfree(addr);
1782 spin_unlock_irqrestore(&host_info_lock, flags);
1783 return (-EALREADY); 1806 return (-EALREADY);
1784 } 1807 }
1785 /* another host with valid address-entry containing same addressrange */ 1808 /* another host with valid address-entry containing same addressrange */
@@ -1807,6 +1830,8 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
1807 } 1830 }
1808 } 1831 }
1809 } 1832 }
1833 spin_unlock_irqrestore(&host_info_lock, flags);
1834
1810 if (another_host) { 1835 if (another_host) {
1811 DBGMSG("another hosts entry is valid -> SUCCESS"); 1836 DBGMSG("another hosts entry is valid -> SUCCESS");
1812 if (copy_to_user(int2ptr(req->req.recvb), 1837 if (copy_to_user(int2ptr(req->req.recvb),
@@ -1815,11 +1840,11 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
1815 " address-range-entry is invalid -> EFAULT !!!\n"); 1840 " address-range-entry is invalid -> EFAULT !!!\n");
1816 vfree(addr->addr_space_buffer); 1841 vfree(addr->addr_space_buffer);
1817 kfree(addr); 1842 kfree(addr);
1818 spin_unlock_irqrestore(&host_info_lock, flags);
1819 return (-EFAULT); 1843 return (-EFAULT);
1820 } 1844 }
1821 free_pending_request(req); /* immediate success or fail */ 1845 free_pending_request(req); /* immediate success or fail */
1822 /* INSERT ENTRY */ 1846 /* INSERT ENTRY */
1847 spin_lock_irqsave(&host_info_lock, flags);
1823 list_add_tail(&addr->addr_list, &fi->addr_list); 1848 list_add_tail(&addr->addr_list, &fi->addr_list);
1824 spin_unlock_irqrestore(&host_info_lock, flags); 1849 spin_unlock_irqrestore(&host_info_lock, flags);
1825 return sizeof(struct raw1394_request); 1850 return sizeof(struct raw1394_request);
@@ -1830,15 +1855,15 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
1830 req->req.address + req->req.length); 1855 req->req.address + req->req.length);
1831 if (retval) { 1856 if (retval) {
1832 /* INSERT ENTRY */ 1857 /* INSERT ENTRY */
1858 spin_lock_irqsave(&host_info_lock, flags);
1833 list_add_tail(&addr->addr_list, &fi->addr_list); 1859 list_add_tail(&addr->addr_list, &fi->addr_list);
1860 spin_unlock_irqrestore(&host_info_lock, flags);
1834 } else { 1861 } else {
1835 DBGMSG("arm_register failed errno: %d \n", retval); 1862 DBGMSG("arm_register failed errno: %d \n", retval);
1836 vfree(addr->addr_space_buffer); 1863 vfree(addr->addr_space_buffer);
1837 kfree(addr); 1864 kfree(addr);
1838 spin_unlock_irqrestore(&host_info_lock, flags);
1839 return (-EALREADY); 1865 return (-EALREADY);
1840 } 1866 }
1841 spin_unlock_irqrestore(&host_info_lock, flags);
1842 free_pending_request(req); /* immediate success or fail */ 1867 free_pending_request(req); /* immediate success or fail */
1843 return sizeof(struct raw1394_request); 1868 return sizeof(struct raw1394_request);
1844} 1869}
@@ -1904,10 +1929,10 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req)
1904 if (another_host) { 1929 if (another_host) {
1905 DBGMSG("delete entry from list -> success"); 1930 DBGMSG("delete entry from list -> success");
1906 list_del(&addr->addr_list); 1931 list_del(&addr->addr_list);
1932 spin_unlock_irqrestore(&host_info_lock, flags);
1907 vfree(addr->addr_space_buffer); 1933 vfree(addr->addr_space_buffer);
1908 kfree(addr); 1934 kfree(addr);
1909 free_pending_request(req); /* immediate success or fail */ 1935 free_pending_request(req); /* immediate success or fail */
1910 spin_unlock_irqrestore(&host_info_lock, flags);
1911 return sizeof(struct raw1394_request); 1936 return sizeof(struct raw1394_request);
1912 } 1937 }
1913 retval = 1938 retval =
@@ -1949,23 +1974,19 @@ static int arm_get_buf(struct file_info *fi, struct pending_request *req)
1949 (arm_addr->end > req->req.address)) { 1974 (arm_addr->end > req->req.address)) {
1950 if (req->req.address + req->req.length <= arm_addr->end) { 1975 if (req->req.address + req->req.length <= arm_addr->end) {
1951 offset = req->req.address - arm_addr->start; 1976 offset = req->req.address - arm_addr->start;
1977 spin_unlock_irqrestore(&host_info_lock, flags);
1952 1978
1953 DBGMSG 1979 DBGMSG
1954 ("arm_get_buf copy_to_user( %08X, %p, %u )", 1980 ("arm_get_buf copy_to_user( %08X, %p, %u )",
1955 (u32) req->req.recvb, 1981 (u32) req->req.recvb,
1956 arm_addr->addr_space_buffer + offset, 1982 arm_addr->addr_space_buffer + offset,
1957 (u32) req->req.length); 1983 (u32) req->req.length);
1958
1959 if (copy_to_user 1984 if (copy_to_user
1960 (int2ptr(req->req.recvb), 1985 (int2ptr(req->req.recvb),
1961 arm_addr->addr_space_buffer + offset, 1986 arm_addr->addr_space_buffer + offset,
1962 req->req.length)) { 1987 req->req.length))
1963 spin_unlock_irqrestore(&host_info_lock,
1964 flags);
1965 return (-EFAULT); 1988 return (-EFAULT);
1966 }
1967 1989
1968 spin_unlock_irqrestore(&host_info_lock, flags);
1969 /* We have to free the request, because we 1990 /* We have to free the request, because we
1970 * queue no response, and therefore nobody 1991 * queue no response, and therefore nobody
1971 * will free it. */ 1992 * will free it. */
@@ -2005,24 +2026,23 @@ static int arm_set_buf(struct file_info *fi, struct pending_request *req)
2005 (arm_addr->end > req->req.address)) { 2026 (arm_addr->end > req->req.address)) {
2006 if (req->req.address + req->req.length <= arm_addr->end) { 2027 if (req->req.address + req->req.length <= arm_addr->end) {
2007 offset = req->req.address - arm_addr->start; 2028 offset = req->req.address - arm_addr->start;
2029 spin_unlock_irqrestore(&host_info_lock, flags);
2008 2030
2009 DBGMSG 2031 DBGMSG
2010 ("arm_set_buf copy_from_user( %p, %08X, %u )", 2032 ("arm_set_buf copy_from_user( %p, %08X, %u )",
2011 arm_addr->addr_space_buffer + offset, 2033 arm_addr->addr_space_buffer + offset,
2012 (u32) req->req.sendb, 2034 (u32) req->req.sendb,
2013 (u32) req->req.length); 2035 (u32) req->req.length);
2014
2015 if (copy_from_user 2036 if (copy_from_user
2016 (arm_addr->addr_space_buffer + offset, 2037 (arm_addr->addr_space_buffer + offset,
2017 int2ptr(req->req.sendb), 2038 int2ptr(req->req.sendb),
2018 req->req.length)) { 2039 req->req.length))
2019 spin_unlock_irqrestore(&host_info_lock,
2020 flags);
2021 return (-EFAULT); 2040 return (-EFAULT);
2022 }
2023 2041
2024 spin_unlock_irqrestore(&host_info_lock, flags); 2042 /* We have to free the request, because we
2025 free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ 2043 * queue no response, and therefore nobody
2044 * will free it. */
2045 free_pending_request(req);
2026 return sizeof(struct raw1394_request); 2046 return sizeof(struct raw1394_request);
2027 } else { 2047 } else {
2028 DBGMSG("arm_set_buf request exceeded mapping"); 2048 DBGMSG("arm_set_buf request exceeded mapping");
@@ -2744,7 +2764,7 @@ static unsigned int raw1394_poll(struct file *file, poll_table * pt)
2744 unsigned int mask = POLLOUT | POLLWRNORM; 2764 unsigned int mask = POLLOUT | POLLWRNORM;
2745 unsigned long flags; 2765 unsigned long flags;
2746 2766
2747 poll_wait(file, &fi->poll_wait_complete, pt); 2767 poll_wait(file, &fi->wait_complete, pt);
2748 2768
2749 spin_lock_irqsave(&fi->reqlists_lock, flags); 2769 spin_lock_irqsave(&fi->reqlists_lock, flags);
2750 if (!list_empty(&fi->req_complete)) { 2770 if (!list_empty(&fi->req_complete)) {
@@ -2769,9 +2789,8 @@ static int raw1394_open(struct inode *inode, struct file *file)
2769 fi->state = opened; 2789 fi->state = opened;
2770 INIT_LIST_HEAD(&fi->req_pending); 2790 INIT_LIST_HEAD(&fi->req_pending);
2771 INIT_LIST_HEAD(&fi->req_complete); 2791 INIT_LIST_HEAD(&fi->req_complete);
2772 sema_init(&fi->complete_sem, 0);
2773 spin_lock_init(&fi->reqlists_lock); 2792 spin_lock_init(&fi->reqlists_lock);
2774 init_waitqueue_head(&fi->poll_wait_complete); 2793 init_waitqueue_head(&fi->wait_complete);
2775 INIT_LIST_HEAD(&fi->addr_list); 2794 INIT_LIST_HEAD(&fi->addr_list);
2776 2795
2777 file->private_data = fi; 2796 file->private_data = fi;
@@ -2784,7 +2803,7 @@ static int raw1394_release(struct inode *inode, struct file *file)
2784 struct file_info *fi = file->private_data; 2803 struct file_info *fi = file->private_data;
2785 struct list_head *lh; 2804 struct list_head *lh;
2786 struct pending_request *req; 2805 struct pending_request *req;
2787 int done = 0, i, fail = 0; 2806 int i, fail;
2788 int retval = 0; 2807 int retval = 0;
2789 struct list_head *entry; 2808 struct list_head *entry;
2790 struct arm_addr *addr = NULL; 2809 struct arm_addr *addr = NULL;
@@ -2864,25 +2883,28 @@ static int raw1394_release(struct inode *inode, struct file *file)
2864 "error(s) occurred \n"); 2883 "error(s) occurred \n");
2865 } 2884 }
2866 2885
2867 while (!done) { 2886 for (;;) {
2887 /* This locked section guarantees that neither
2888 * complete nor pending requests exist once i!=0 */
2868 spin_lock_irqsave(&fi->reqlists_lock, flags); 2889 spin_lock_irqsave(&fi->reqlists_lock, flags);
2869 2890 while ((req = __next_complete_req(fi)))
2870 while (!list_empty(&fi->req_complete)) {
2871 lh = fi->req_complete.next;
2872 list_del(lh);
2873
2874 req = list_entry(lh, struct pending_request, list);
2875
2876 free_pending_request(req); 2891 free_pending_request(req);
2877 }
2878
2879 if (list_empty(&fi->req_pending))
2880 done = 1;
2881 2892
2893 i = list_empty(&fi->req_pending);
2882 spin_unlock_irqrestore(&fi->reqlists_lock, flags); 2894 spin_unlock_irqrestore(&fi->reqlists_lock, flags);
2883 2895
2884 if (!done) 2896 if (i)
2885 down_interruptible(&fi->complete_sem); 2897 break;
2898 /*
2899 * Sleep until more requests can be freed.
2900 *
2901 * NB: We call the macro wait_event() with a condition argument
2902 * with side effect. This is only possible because the side
2903 * effect does not occur until the condition became true, and
2904 * wait_event() won't evaluate the condition again after that.
2905 */
2906 wait_event(fi->wait_complete, (req = next_complete_req(fi)));
2907 free_pending_request(req);
2886 } 2908 }
2887 2909
2888 /* Remove any sub-trees left by user space programs */ 2910 /* Remove any sub-trees left by user space programs */