diff options
author | Bernd Porr <berndporr@f2s.com> | 2011-11-08 16:23:03 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-11-26 21:34:14 -0500 |
commit | 3ffab428f40849ed5f21bcfd7285bdef7902f9ca (patch) | |
tree | 2b9613bd348ea6317e0048367ae1f1bb98a69d50 | |
parent | 8b78607fc4a26c2e26c4a614ff0bbd3380abc402 (diff) |
staging: comedi: fix oops for USB DAQ devices.
This fixes kernel oops when an USB DAQ device is plugged out while it's
communicating with the userspace software.
Signed-off-by: Bernd Porr <berndporr@f2s.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/staging/comedi/comedi_fops.c | 71 |
1 files changed, 53 insertions, 18 deletions
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 21d8c1c16cd8..156622a6f162 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c | |||
@@ -1452,9 +1452,6 @@ static struct vm_operations_struct comedi_vm_ops = { | |||
1452 | static int comedi_mmap(struct file *file, struct vm_area_struct *vma) | 1452 | static int comedi_mmap(struct file *file, struct vm_area_struct *vma) |
1453 | { | 1453 | { |
1454 | const unsigned minor = iminor(file->f_dentry->d_inode); | 1454 | const unsigned minor = iminor(file->f_dentry->d_inode); |
1455 | struct comedi_device_file_info *dev_file_info = | ||
1456 | comedi_get_device_file_info(minor); | ||
1457 | struct comedi_device *dev = dev_file_info->device; | ||
1458 | struct comedi_async *async = NULL; | 1455 | struct comedi_async *async = NULL; |
1459 | unsigned long start = vma->vm_start; | 1456 | unsigned long start = vma->vm_start; |
1460 | unsigned long size; | 1457 | unsigned long size; |
@@ -1462,6 +1459,15 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) | |||
1462 | int i; | 1459 | int i; |
1463 | int retval; | 1460 | int retval; |
1464 | struct comedi_subdevice *s; | 1461 | struct comedi_subdevice *s; |
1462 | struct comedi_device_file_info *dev_file_info; | ||
1463 | struct comedi_device *dev; | ||
1464 | |||
1465 | dev_file_info = comedi_get_device_file_info(minor); | ||
1466 | if (dev_file_info == NULL) | ||
1467 | return -ENODEV; | ||
1468 | dev = dev_file_info->device; | ||
1469 | if (dev == NULL) | ||
1470 | return -ENODEV; | ||
1465 | 1471 | ||
1466 | mutex_lock(&dev->mutex); | 1472 | mutex_lock(&dev->mutex); |
1467 | if (!dev->attached) { | 1473 | if (!dev->attached) { |
@@ -1528,11 +1534,17 @@ static unsigned int comedi_poll(struct file *file, poll_table * wait) | |||
1528 | { | 1534 | { |
1529 | unsigned int mask = 0; | 1535 | unsigned int mask = 0; |
1530 | const unsigned minor = iminor(file->f_dentry->d_inode); | 1536 | const unsigned minor = iminor(file->f_dentry->d_inode); |
1531 | struct comedi_device_file_info *dev_file_info = | ||
1532 | comedi_get_device_file_info(minor); | ||
1533 | struct comedi_device *dev = dev_file_info->device; | ||
1534 | struct comedi_subdevice *read_subdev; | 1537 | struct comedi_subdevice *read_subdev; |
1535 | struct comedi_subdevice *write_subdev; | 1538 | struct comedi_subdevice *write_subdev; |
1539 | struct comedi_device_file_info *dev_file_info; | ||
1540 | struct comedi_device *dev; | ||
1541 | dev_file_info = comedi_get_device_file_info(minor); | ||
1542 | |||
1543 | if (dev_file_info == NULL) | ||
1544 | return -ENODEV; | ||
1545 | dev = dev_file_info->device; | ||
1546 | if (dev == NULL) | ||
1547 | return -ENODEV; | ||
1536 | 1548 | ||
1537 | mutex_lock(&dev->mutex); | 1549 | mutex_lock(&dev->mutex); |
1538 | if (!dev->attached) { | 1550 | if (!dev->attached) { |
@@ -1578,9 +1590,15 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, | |||
1578 | int n, m, count = 0, retval = 0; | 1590 | int n, m, count = 0, retval = 0; |
1579 | DECLARE_WAITQUEUE(wait, current); | 1591 | DECLARE_WAITQUEUE(wait, current); |
1580 | const unsigned minor = iminor(file->f_dentry->d_inode); | 1592 | const unsigned minor = iminor(file->f_dentry->d_inode); |
1581 | struct comedi_device_file_info *dev_file_info = | 1593 | struct comedi_device_file_info *dev_file_info; |
1582 | comedi_get_device_file_info(minor); | 1594 | struct comedi_device *dev; |
1583 | struct comedi_device *dev = dev_file_info->device; | 1595 | dev_file_info = comedi_get_device_file_info(minor); |
1596 | |||
1597 | if (dev_file_info == NULL) | ||
1598 | return -ENODEV; | ||
1599 | dev = dev_file_info->device; | ||
1600 | if (dev == NULL) | ||
1601 | return -ENODEV; | ||
1584 | 1602 | ||
1585 | if (!dev->attached) { | 1603 | if (!dev->attached) { |
1586 | DPRINTK("no driver configured on comedi%i\n", dev->minor); | 1604 | DPRINTK("no driver configured on comedi%i\n", dev->minor); |
@@ -1683,9 +1701,15 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, | |||
1683 | int n, m, count = 0, retval = 0; | 1701 | int n, m, count = 0, retval = 0; |
1684 | DECLARE_WAITQUEUE(wait, current); | 1702 | DECLARE_WAITQUEUE(wait, current); |
1685 | const unsigned minor = iminor(file->f_dentry->d_inode); | 1703 | const unsigned minor = iminor(file->f_dentry->d_inode); |
1686 | struct comedi_device_file_info *dev_file_info = | 1704 | struct comedi_device_file_info *dev_file_info; |
1687 | comedi_get_device_file_info(minor); | 1705 | struct comedi_device *dev; |
1688 | struct comedi_device *dev = dev_file_info->device; | 1706 | dev_file_info = comedi_get_device_file_info(minor); |
1707 | |||
1708 | if (dev_file_info == NULL) | ||
1709 | return -ENODEV; | ||
1710 | dev = dev_file_info->device; | ||
1711 | if (dev == NULL) | ||
1712 | return -ENODEV; | ||
1689 | 1713 | ||
1690 | if (!dev->attached) { | 1714 | if (!dev->attached) { |
1691 | DPRINTK("no driver configured on comedi%i\n", dev->minor); | 1715 | DPRINTK("no driver configured on comedi%i\n", dev->minor); |
@@ -1885,11 +1909,17 @@ ok: | |||
1885 | static int comedi_close(struct inode *inode, struct file *file) | 1909 | static int comedi_close(struct inode *inode, struct file *file) |
1886 | { | 1910 | { |
1887 | const unsigned minor = iminor(inode); | 1911 | const unsigned minor = iminor(inode); |
1888 | struct comedi_device_file_info *dev_file_info = | ||
1889 | comedi_get_device_file_info(minor); | ||
1890 | struct comedi_device *dev = dev_file_info->device; | ||
1891 | struct comedi_subdevice *s = NULL; | 1912 | struct comedi_subdevice *s = NULL; |
1892 | int i; | 1913 | int i; |
1914 | struct comedi_device_file_info *dev_file_info; | ||
1915 | struct comedi_device *dev; | ||
1916 | dev_file_info = comedi_get_device_file_info(minor); | ||
1917 | |||
1918 | if (dev_file_info == NULL) | ||
1919 | return -ENODEV; | ||
1920 | dev = dev_file_info->device; | ||
1921 | if (dev == NULL) | ||
1922 | return -ENODEV; | ||
1893 | 1923 | ||
1894 | mutex_lock(&dev->mutex); | 1924 | mutex_lock(&dev->mutex); |
1895 | 1925 | ||
@@ -1923,10 +1953,15 @@ static int comedi_close(struct inode *inode, struct file *file) | |||
1923 | static int comedi_fasync(int fd, struct file *file, int on) | 1953 | static int comedi_fasync(int fd, struct file *file, int on) |
1924 | { | 1954 | { |
1925 | const unsigned minor = iminor(file->f_dentry->d_inode); | 1955 | const unsigned minor = iminor(file->f_dentry->d_inode); |
1926 | struct comedi_device_file_info *dev_file_info = | 1956 | struct comedi_device_file_info *dev_file_info; |
1927 | comedi_get_device_file_info(minor); | 1957 | struct comedi_device *dev; |
1958 | dev_file_info = comedi_get_device_file_info(minor); | ||
1928 | 1959 | ||
1929 | struct comedi_device *dev = dev_file_info->device; | 1960 | if (dev_file_info == NULL) |
1961 | return -ENODEV; | ||
1962 | dev = dev_file_info->device; | ||
1963 | if (dev == NULL) | ||
1964 | return -ENODEV; | ||
1930 | 1965 | ||
1931 | return fasync_helper(fd, file, on, &dev->async_queue); | 1966 | return fasync_helper(fd, file, on, &dev->async_queue); |
1932 | } | 1967 | } |