diff options
author | Dean Anderson <dean@sensoray.com> | 2010-04-08 22:38:07 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-19 11:57:22 -0400 |
commit | ff7e22dfa1b8c291f154db990ff686adbe334448 (patch) | |
tree | fed9ab8c7bc0b65fe68eed30f75be628cbb41c88 /drivers/media/video/s2255drv.c | |
parent | f5e20c34e9c1bcf9e92f2634411bffd98511fc48 (diff) |
V4L/DVB: s2255drv: cleanup of driver disconnect code
simplifies use of kref in driver
Signed-off-by: Dean Anderson <dean@sensoray.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/s2255drv.c')
-rw-r--r-- | drivers/media/video/s2255drv.c | 266 |
1 files changed, 109 insertions, 157 deletions
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 5ecd41b3bf3e..1d8c6b4364dd 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c | |||
@@ -226,7 +226,6 @@ struct s2255_fmt; /*forward declaration */ | |||
226 | 226 | ||
227 | struct s2255_dev { | 227 | struct s2255_dev { |
228 | int frames; | 228 | int frames; |
229 | int users[MAX_CHANNELS]; | ||
230 | struct mutex lock; | 229 | struct mutex lock; |
231 | struct mutex open_lock; | 230 | struct mutex open_lock; |
232 | int resources[MAX_CHANNELS]; | 231 | int resources[MAX_CHANNELS]; |
@@ -367,7 +366,6 @@ static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf, | |||
367 | static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn, | 366 | static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn, |
368 | struct s2255_mode *mode); | 367 | struct s2255_mode *mode); |
369 | static int s2255_board_shutdown(struct s2255_dev *dev); | 368 | static int s2255_board_shutdown(struct s2255_dev *dev); |
370 | static void s2255_exit_v4l(struct s2255_dev *dev); | ||
371 | static void s2255_fwload_start(struct s2255_dev *dev, int reset); | 369 | static void s2255_fwload_start(struct s2255_dev *dev, int reset); |
372 | static void s2255_destroy(struct kref *kref); | 370 | static void s2255_destroy(struct kref *kref); |
373 | static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req, | 371 | static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req, |
@@ -606,7 +604,6 @@ unlock: | |||
606 | return 0; | 604 | return 0; |
607 | } | 605 | } |
608 | 606 | ||
609 | |||
610 | static const struct s2255_fmt *format_by_fourcc(int fourcc) | 607 | static const struct s2255_fmt *format_by_fourcc(int fourcc) |
611 | { | 608 | { |
612 | unsigned int i; | 609 | unsigned int i; |
@@ -620,9 +617,6 @@ static const struct s2255_fmt *format_by_fourcc(int fourcc) | |||
620 | return NULL; | 617 | return NULL; |
621 | } | 618 | } |
622 | 619 | ||
623 | |||
624 | |||
625 | |||
626 | /* video buffer vmalloc implementation based partly on VIVI driver which is | 620 | /* video buffer vmalloc implementation based partly on VIVI driver which is |
627 | * Copyright (c) 2006 by | 621 | * Copyright (c) 2006 by |
628 | * Mauro Carvalho Chehab <mchehab--a.t--infradead.org> | 622 | * Mauro Carvalho Chehab <mchehab--a.t--infradead.org> |
@@ -849,7 +843,6 @@ static int vidioc_querymenu(struct file *file, void *priv, | |||
849 | return v4l2_ctrl_query_menu(qmenu, NULL, NULL); | 843 | return v4l2_ctrl_query_menu(qmenu, NULL, NULL); |
850 | } | 844 | } |
851 | 845 | ||
852 | |||
853 | static int vidioc_querycap(struct file *file, void *priv, | 846 | static int vidioc_querycap(struct file *file, void *priv, |
854 | struct v4l2_capability *cap) | 847 | struct v4l2_capability *cap) |
855 | { | 848 | { |
@@ -1759,31 +1752,26 @@ static int s2255_open(struct file *file) | |||
1759 | int i = 0; | 1752 | int i = 0; |
1760 | int cur_channel = -1; | 1753 | int cur_channel = -1; |
1761 | int state; | 1754 | int state; |
1762 | |||
1763 | dprintk(1, "s2255: open called (dev=%s)\n", | 1755 | dprintk(1, "s2255: open called (dev=%s)\n", |
1764 | video_device_node_name(vdev)); | 1756 | video_device_node_name(vdev)); |
1765 | |||
1766 | lock_kernel(); | 1757 | lock_kernel(); |
1767 | 1758 | for (i = 0; i < MAX_CHANNELS; i++) | |
1768 | for (i = 0; i < MAX_CHANNELS; i++) { | ||
1769 | if (dev->vdev[i] == vdev) { | 1759 | if (dev->vdev[i] == vdev) { |
1770 | cur_channel = i; | 1760 | cur_channel = i; |
1771 | break; | 1761 | break; |
1772 | } | 1762 | } |
1773 | } | 1763 | /* |
1774 | 1764 | * open lock necessary to prevent multiple instances | |
1775 | if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_DISCONNECTING) { | 1765 | * of v4l-conf (or other programs) from simultaneously |
1766 | * reloading firmware. | ||
1767 | */ | ||
1768 | mutex_lock(&dev->open_lock); | ||
1769 | state = atomic_read(&dev->fw_data->fw_state); | ||
1770 | switch (state) { | ||
1771 | case S2255_FW_DISCONNECTING: | ||
1772 | mutex_unlock(&dev->open_lock); | ||
1776 | unlock_kernel(); | 1773 | unlock_kernel(); |
1777 | printk(KERN_INFO "disconnecting\n"); | ||
1778 | return -ENODEV; | 1774 | return -ENODEV; |
1779 | } | ||
1780 | kref_get(&dev->kref); | ||
1781 | mutex_lock(&dev->open_lock); | ||
1782 | |||
1783 | dev->users[cur_channel]++; | ||
1784 | dprintk(4, "s2255: open_handles %d\n", dev->users[cur_channel]); | ||
1785 | |||
1786 | switch (atomic_read(&dev->fw_data->fw_state)) { | ||
1787 | case S2255_FW_FAILED: | 1775 | case S2255_FW_FAILED: |
1788 | s2255_dev_err(&dev->udev->dev, | 1776 | s2255_dev_err(&dev->udev->dev, |
1789 | "firmware load failed. retrying.\n"); | 1777 | "firmware load failed. retrying.\n"); |
@@ -1794,6 +1782,8 @@ static int s2255_open(struct file *file) | |||
1794 | (atomic_read(&dev->fw_data->fw_state) | 1782 | (atomic_read(&dev->fw_data->fw_state) |
1795 | == S2255_FW_DISCONNECTING)), | 1783 | == S2255_FW_DISCONNECTING)), |
1796 | msecs_to_jiffies(S2255_LOAD_TIMEOUT)); | 1784 | msecs_to_jiffies(S2255_LOAD_TIMEOUT)); |
1785 | /* state may have changed, re-read */ | ||
1786 | state = atomic_read(&dev->fw_data->fw_state); | ||
1797 | break; | 1787 | break; |
1798 | case S2255_FW_NOTLOADED: | 1788 | case S2255_FW_NOTLOADED: |
1799 | case S2255_FW_LOADED_DSPWAIT: | 1789 | case S2255_FW_LOADED_DSPWAIT: |
@@ -1806,52 +1796,44 @@ static int s2255_open(struct file *file) | |||
1806 | (atomic_read(&dev->fw_data->fw_state) | 1796 | (atomic_read(&dev->fw_data->fw_state) |
1807 | == S2255_FW_DISCONNECTING)), | 1797 | == S2255_FW_DISCONNECTING)), |
1808 | msecs_to_jiffies(S2255_LOAD_TIMEOUT)); | 1798 | msecs_to_jiffies(S2255_LOAD_TIMEOUT)); |
1799 | /* state may have changed, re-read */ | ||
1800 | state = atomic_read(&dev->fw_data->fw_state); | ||
1809 | break; | 1801 | break; |
1810 | case S2255_FW_SUCCESS: | 1802 | case S2255_FW_SUCCESS: |
1811 | default: | 1803 | default: |
1812 | break; | 1804 | break; |
1813 | } | 1805 | } |
1814 | state = atomic_read(&dev->fw_data->fw_state); | 1806 | mutex_unlock(&dev->open_lock); |
1815 | if (state != S2255_FW_SUCCESS) { | 1807 | /* state may have changed in above switch statement */ |
1816 | int rc; | 1808 | switch (state) { |
1817 | switch (state) { | 1809 | case S2255_FW_SUCCESS: |
1818 | case S2255_FW_FAILED: | 1810 | break; |
1819 | printk(KERN_INFO "2255 FW load failed. %d\n", state); | 1811 | case S2255_FW_FAILED: |
1820 | rc = -ENODEV; | 1812 | printk(KERN_INFO "2255 firmware load failed.\n"); |
1821 | break; | 1813 | unlock_kernel(); |
1822 | case S2255_FW_DISCONNECTING: | 1814 | return -ENODEV; |
1823 | printk(KERN_INFO "%s: disconnecting\n", __func__); | 1815 | case S2255_FW_DISCONNECTING: |
1824 | rc = -ENODEV; | 1816 | printk(KERN_INFO "%s: disconnecting\n", __func__); |
1825 | break; | 1817 | unlock_kernel(); |
1826 | case S2255_FW_LOADED_DSPWAIT: | 1818 | return -ENODEV; |
1827 | case S2255_FW_NOTLOADED: | 1819 | case S2255_FW_LOADED_DSPWAIT: |
1828 | printk(KERN_INFO "%s: firmware not loaded yet" | 1820 | case S2255_FW_NOTLOADED: |
1829 | "please try again later\n", | 1821 | printk(KERN_INFO "%s: firmware not loaded yet" |
1830 | __func__); | 1822 | "please try again later\n", |
1831 | rc = -EAGAIN; | 1823 | __func__); |
1832 | break; | 1824 | unlock_kernel(); |
1833 | default: | 1825 | return -EAGAIN; |
1834 | printk(KERN_INFO "%s: unknown state\n", __func__); | 1826 | default: |
1835 | rc = -EFAULT; | 1827 | printk(KERN_INFO "%s: unknown state\n", __func__); |
1836 | break; | ||
1837 | } | ||
1838 | dev->users[cur_channel]--; | ||
1839 | mutex_unlock(&dev->open_lock); | ||
1840 | kref_put(&dev->kref, s2255_destroy); | ||
1841 | unlock_kernel(); | 1828 | unlock_kernel(); |
1842 | return rc; | 1829 | return -EFAULT; |
1843 | } | 1830 | } |
1844 | |||
1845 | /* allocate + initialize per filehandle data */ | 1831 | /* allocate + initialize per filehandle data */ |
1846 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 1832 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
1847 | if (NULL == fh) { | 1833 | if (NULL == fh) { |
1848 | dev->users[cur_channel]--; | ||
1849 | mutex_unlock(&dev->open_lock); | ||
1850 | kref_put(&dev->kref, s2255_destroy); | ||
1851 | unlock_kernel(); | 1834 | unlock_kernel(); |
1852 | return -ENOMEM; | 1835 | return -ENOMEM; |
1853 | } | 1836 | } |
1854 | |||
1855 | file->private_data = fh; | 1837 | file->private_data = fh; |
1856 | fh->dev = dev; | 1838 | fh->dev = dev; |
1857 | fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1839 | fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
@@ -1866,9 +1848,8 @@ static int s2255_open(struct file *file) | |||
1866 | s2255_set_mode(dev, cur_channel, &fh->mode); | 1848 | s2255_set_mode(dev, cur_channel, &fh->mode); |
1867 | dev->chn_configured[cur_channel] = 1; | 1849 | dev->chn_configured[cur_channel] = 1; |
1868 | } | 1850 | } |
1869 | dprintk(1, "s2255drv: open dev=%s type=%s users=%d\n", | 1851 | dprintk(1, "s2255drv: open dev=%s type=%s\n", |
1870 | video_device_node_name(vdev), v4l2_type_names[type], | 1852 | video_device_node_name(vdev), v4l2_type_names[type]); |
1871 | dev->users[cur_channel]); | ||
1872 | dprintk(2, "s2255drv: open: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", | 1853 | dprintk(2, "s2255drv: open: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", |
1873 | (unsigned long)fh, (unsigned long)dev, | 1854 | (unsigned long)fh, (unsigned long)dev, |
1874 | (unsigned long)&dev->vidq[cur_channel]); | 1855 | (unsigned long)&dev->vidq[cur_channel]); |
@@ -1880,8 +1861,6 @@ static int s2255_open(struct file *file) | |||
1880 | fh->type, | 1861 | fh->type, |
1881 | V4L2_FIELD_INTERLACED, | 1862 | V4L2_FIELD_INTERLACED, |
1882 | sizeof(struct s2255_buffer), fh); | 1863 | sizeof(struct s2255_buffer), fh); |
1883 | |||
1884 | mutex_unlock(&dev->open_lock); | ||
1885 | unlock_kernel(); | 1864 | unlock_kernel(); |
1886 | return 0; | 1865 | return 0; |
1887 | } | 1866 | } |
@@ -1904,28 +1883,10 @@ static unsigned int s2255_poll(struct file *file, | |||
1904 | static void s2255_destroy(struct kref *kref) | 1883 | static void s2255_destroy(struct kref *kref) |
1905 | { | 1884 | { |
1906 | struct s2255_dev *dev = to_s2255_dev(kref); | 1885 | struct s2255_dev *dev = to_s2255_dev(kref); |
1907 | int i; | ||
1908 | if (!dev) { | ||
1909 | printk(KERN_ERR "s2255drv: kref problem\n"); | ||
1910 | return; | ||
1911 | } | ||
1912 | atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING); | ||
1913 | wake_up(&dev->fw_data->wait_fw); | ||
1914 | for (i = 0; i < MAX_CHANNELS; i++) { | ||
1915 | dev->setmode_ready[i] = 1; | ||
1916 | wake_up(&dev->wait_setmode[i]); | ||
1917 | dev->vidstatus_ready[i] = 1; | ||
1918 | wake_up(&dev->wait_vidstatus[i]); | ||
1919 | } | ||
1920 | mutex_lock(&dev->open_lock); | ||
1921 | /* reset the DSP so firmware can be reload next time */ | ||
1922 | s2255_reset_dsppower(dev); | ||
1923 | s2255_exit_v4l(dev); | ||
1924 | /* board shutdown stops the read pipe if it is running */ | 1886 | /* board shutdown stops the read pipe if it is running */ |
1925 | s2255_board_shutdown(dev); | 1887 | s2255_board_shutdown(dev); |
1926 | /* make sure firmware still not trying to load */ | 1888 | /* make sure firmware still not trying to load */ |
1927 | del_timer(&dev->timer); /* only started in .probe and .open */ | 1889 | del_timer(&dev->timer); /* only started in .probe and .open */ |
1928 | |||
1929 | if (dev->fw_data->fw_urb) { | 1890 | if (dev->fw_data->fw_urb) { |
1930 | dprintk(2, "kill fw_urb\n"); | 1891 | dprintk(2, "kill fw_urb\n"); |
1931 | usb_kill_urb(dev->fw_data->fw_urb); | 1892 | usb_kill_urb(dev->fw_data->fw_urb); |
@@ -1936,24 +1897,22 @@ static void s2255_destroy(struct kref *kref) | |||
1936 | release_firmware(dev->fw_data->fw); | 1897 | release_firmware(dev->fw_data->fw); |
1937 | kfree(dev->fw_data->pfw_data); | 1898 | kfree(dev->fw_data->pfw_data); |
1938 | kfree(dev->fw_data); | 1899 | kfree(dev->fw_data); |
1900 | /* reset the DSP so firmware can be reloaded next time */ | ||
1901 | s2255_reset_dsppower(dev); | ||
1902 | mutex_destroy(&dev->open_lock); | ||
1903 | mutex_destroy(&dev->lock); | ||
1939 | usb_put_dev(dev->udev); | 1904 | usb_put_dev(dev->udev); |
1940 | dprintk(1, "%s", __func__); | 1905 | dprintk(1, "%s", __func__); |
1941 | |||
1942 | mutex_unlock(&dev->open_lock); | ||
1943 | kfree(dev); | 1906 | kfree(dev); |
1944 | } | 1907 | } |
1945 | 1908 | ||
1946 | static int s2255_close(struct file *file) | 1909 | static int s2255_release(struct file *file) |
1947 | { | 1910 | { |
1948 | struct s2255_fh *fh = file->private_data; | 1911 | struct s2255_fh *fh = file->private_data; |
1949 | struct s2255_dev *dev = fh->dev; | 1912 | struct s2255_dev *dev = fh->dev; |
1950 | struct video_device *vdev = video_devdata(file); | 1913 | struct video_device *vdev = video_devdata(file); |
1951 | |||
1952 | if (!dev) | 1914 | if (!dev) |
1953 | return -ENODEV; | 1915 | return -ENODEV; |
1954 | |||
1955 | mutex_lock(&dev->open_lock); | ||
1956 | |||
1957 | /* turn off stream */ | 1916 | /* turn off stream */ |
1958 | if (res_check(fh)) { | 1917 | if (res_check(fh)) { |
1959 | if (dev->b_acquire[fh->channel]) | 1918 | if (dev->b_acquire[fh->channel]) |
@@ -1961,15 +1920,8 @@ static int s2255_close(struct file *file) | |||
1961 | videobuf_streamoff(&fh->vb_vidq); | 1920 | videobuf_streamoff(&fh->vb_vidq); |
1962 | res_free(dev, fh); | 1921 | res_free(dev, fh); |
1963 | } | 1922 | } |
1964 | |||
1965 | videobuf_mmap_free(&fh->vb_vidq); | 1923 | videobuf_mmap_free(&fh->vb_vidq); |
1966 | dev->users[fh->channel]--; | 1924 | dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev)); |
1967 | |||
1968 | mutex_unlock(&dev->open_lock); | ||
1969 | |||
1970 | kref_put(&dev->kref, s2255_destroy); | ||
1971 | dprintk(1, "s2255: close called (dev=%s, users=%d)\n", | ||
1972 | video_device_node_name(vdev), dev->users[fh->channel]); | ||
1973 | kfree(fh); | 1925 | kfree(fh); |
1974 | return 0; | 1926 | return 0; |
1975 | } | 1927 | } |
@@ -1995,7 +1947,7 @@ static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma) | |||
1995 | static const struct v4l2_file_operations s2255_fops_v4l = { | 1947 | static const struct v4l2_file_operations s2255_fops_v4l = { |
1996 | .owner = THIS_MODULE, | 1948 | .owner = THIS_MODULE, |
1997 | .open = s2255_open, | 1949 | .open = s2255_open, |
1998 | .release = s2255_close, | 1950 | .release = s2255_release, |
1999 | .poll = s2255_poll, | 1951 | .poll = s2255_poll, |
2000 | .ioctl = video_ioctl2, /* V4L2 ioctl handler */ | 1952 | .ioctl = video_ioctl2, /* V4L2 ioctl handler */ |
2001 | .mmap = s2255_mmap_v4l, | 1953 | .mmap = s2255_mmap_v4l, |
@@ -2031,11 +1983,19 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = { | |||
2031 | .vidioc_enum_frameintervals = vidioc_enum_frameintervals, | 1983 | .vidioc_enum_frameintervals = vidioc_enum_frameintervals, |
2032 | }; | 1984 | }; |
2033 | 1985 | ||
1986 | static void s2255_video_device_release(struct video_device *vdev) | ||
1987 | { | ||
1988 | struct s2255_dev *dev = video_get_drvdata(vdev); | ||
1989 | video_device_release(vdev); | ||
1990 | kref_put(&dev->kref, s2255_destroy); | ||
1991 | return; | ||
1992 | } | ||
1993 | |||
2034 | static struct video_device template = { | 1994 | static struct video_device template = { |
2035 | .name = "s2255v", | 1995 | .name = "s2255v", |
2036 | .fops = &s2255_fops_v4l, | 1996 | .fops = &s2255_fops_v4l, |
2037 | .ioctl_ops = &s2255_ioctl_ops, | 1997 | .ioctl_ops = &s2255_ioctl_ops, |
2038 | .release = video_device_release, | 1998 | .release = s2255_video_device_release, |
2039 | .tvnorms = S2255_NORMS, | 1999 | .tvnorms = S2255_NORMS, |
2040 | .current_norm = V4L2_STD_NTSC_M, | 2000 | .current_norm = V4L2_STD_NTSC_M, |
2041 | }; | 2001 | }; |
@@ -2079,21 +2039,6 @@ static int s2255_probe_v4l(struct s2255_dev *dev) | |||
2079 | return ret; | 2039 | return ret; |
2080 | } | 2040 | } |
2081 | 2041 | ||
2082 | static void s2255_exit_v4l(struct s2255_dev *dev) | ||
2083 | { | ||
2084 | |||
2085 | int i; | ||
2086 | for (i = 0; i < MAX_CHANNELS; i++) { | ||
2087 | if (video_is_registered(dev->vdev[i])) { | ||
2088 | video_unregister_device(dev->vdev[i]); | ||
2089 | printk(KERN_INFO "s2255 unregistered\n"); | ||
2090 | } else { | ||
2091 | video_device_release(dev->vdev[i]); | ||
2092 | printk(KERN_INFO "s2255 released\n"); | ||
2093 | } | ||
2094 | } | ||
2095 | } | ||
2096 | |||
2097 | /* this function moves the usb stream read pipe data | 2042 | /* this function moves the usb stream read pipe data |
2098 | * into the system buffers. | 2043 | * into the system buffers. |
2099 | * returns 0 on success, EAGAIN if more data to process( call this | 2044 | * returns 0 on success, EAGAIN if more data to process( call this |
@@ -2408,9 +2353,7 @@ static int s2255_board_init(struct s2255_dev *dev) | |||
2408 | dprintk(1, "out of memory!\n"); | 2353 | dprintk(1, "out of memory!\n"); |
2409 | return -ENOMEM; | 2354 | return -ENOMEM; |
2410 | } | 2355 | } |
2411 | |||
2412 | } | 2356 | } |
2413 | |||
2414 | /* query the firmware */ | 2357 | /* query the firmware */ |
2415 | fw_ver = s2255_get_fx2fw(dev); | 2358 | fw_ver = s2255_get_fx2fw(dev); |
2416 | 2359 | ||
@@ -2447,7 +2390,6 @@ static int s2255_board_init(struct s2255_dev *dev) | |||
2447 | static int s2255_board_shutdown(struct s2255_dev *dev) | 2390 | static int s2255_board_shutdown(struct s2255_dev *dev) |
2448 | { | 2391 | { |
2449 | u32 i; | 2392 | u32 i; |
2450 | |||
2451 | dprintk(1, "S2255: board shutdown: %p", dev); | 2393 | dprintk(1, "S2255: board shutdown: %p", dev); |
2452 | 2394 | ||
2453 | for (i = 0; i < MAX_CHANNELS; i++) { | 2395 | for (i = 0; i < MAX_CHANNELS; i++) { |
@@ -2640,7 +2582,6 @@ static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn) | |||
2640 | static void s2255_stop_readpipe(struct s2255_dev *dev) | 2582 | static void s2255_stop_readpipe(struct s2255_dev *dev) |
2641 | { | 2583 | { |
2642 | int j; | 2584 | int j; |
2643 | |||
2644 | if (dev == NULL) { | 2585 | if (dev == NULL) { |
2645 | s2255_dev_err(&dev->udev->dev, "invalid device\n"); | 2586 | s2255_dev_err(&dev->udev->dev, "invalid device\n"); |
2646 | return; | 2587 | return; |
@@ -2654,7 +2595,6 @@ static void s2255_stop_readpipe(struct s2255_dev *dev) | |||
2654 | pipe_info->state = 0; | 2595 | pipe_info->state = 0; |
2655 | } | 2596 | } |
2656 | } | 2597 | } |
2657 | |||
2658 | for (j = 0; j < MAX_PIPE_BUFFERS; j++) { | 2598 | for (j = 0; j < MAX_PIPE_BUFFERS; j++) { |
2659 | struct s2255_pipeinfo *pipe_info = &dev->pipes[j]; | 2599 | struct s2255_pipeinfo *pipe_info = &dev->pipes[j]; |
2660 | if (pipe_info->stream_urb) { | 2600 | if (pipe_info->stream_urb) { |
@@ -2703,24 +2643,22 @@ static int s2255_probe(struct usb_interface *interface, | |||
2703 | dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL); | 2643 | dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL); |
2704 | if (dev == NULL) { | 2644 | if (dev == NULL) { |
2705 | s2255_dev_err(&interface->dev, "out of memory\n"); | 2645 | s2255_dev_err(&interface->dev, "out of memory\n"); |
2706 | goto error; | 2646 | return -ENOMEM; |
2707 | } | 2647 | } |
2648 | kref_init(&dev->kref); | ||
2708 | dev->pid = id->idProduct; | 2649 | dev->pid = id->idProduct; |
2709 | dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL); | 2650 | dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL); |
2710 | if (!dev->fw_data) | 2651 | if (!dev->fw_data) |
2711 | goto error; | 2652 | goto errorFWDATA1; |
2712 | |||
2713 | mutex_init(&dev->lock); | 2653 | mutex_init(&dev->lock); |
2714 | mutex_init(&dev->open_lock); | 2654 | mutex_init(&dev->open_lock); |
2715 | |||
2716 | /* grab usb_device and save it */ | 2655 | /* grab usb_device and save it */ |
2717 | dev->udev = usb_get_dev(interface_to_usbdev(interface)); | 2656 | dev->udev = usb_get_dev(interface_to_usbdev(interface)); |
2718 | if (dev->udev == NULL) { | 2657 | if (dev->udev == NULL) { |
2719 | dev_err(&interface->dev, "null usb device\n"); | 2658 | dev_err(&interface->dev, "null usb device\n"); |
2720 | retval = -ENODEV; | 2659 | retval = -ENODEV; |
2721 | goto error; | 2660 | goto errorUDEV; |
2722 | } | 2661 | } |
2723 | kref_init(&dev->kref); | ||
2724 | dprintk(1, "dev: %p, kref: %p udev %p interface %p\n", dev, &dev->kref, | 2662 | dprintk(1, "dev: %p, kref: %p udev %p interface %p\n", dev, &dev->kref, |
2725 | dev->udev, interface); | 2663 | dev->udev, interface); |
2726 | dev->interface = interface; | 2664 | dev->interface = interface; |
@@ -2737,14 +2675,11 @@ static int s2255_probe(struct usb_interface *interface, | |||
2737 | 2675 | ||
2738 | if (!dev->read_endpoint) { | 2676 | if (!dev->read_endpoint) { |
2739 | dev_err(&interface->dev, "Could not find bulk-in endpoint\n"); | 2677 | dev_err(&interface->dev, "Could not find bulk-in endpoint\n"); |
2740 | goto error; | 2678 | goto errorEP; |
2741 | } | 2679 | } |
2742 | |||
2743 | /* set intfdata */ | 2680 | /* set intfdata */ |
2744 | usb_set_intfdata(interface, dev); | 2681 | usb_set_intfdata(interface, dev); |
2745 | |||
2746 | dprintk(100, "after intfdata %p\n", dev); | 2682 | dprintk(100, "after intfdata %p\n", dev); |
2747 | |||
2748 | init_timer(&dev->timer); | 2683 | init_timer(&dev->timer); |
2749 | dev->timer.function = s2255_timer; | 2684 | dev->timer.function = s2255_timer; |
2750 | dev->timer.data = (unsigned long)dev->fw_data; | 2685 | dev->timer.data = (unsigned long)dev->fw_data; |
@@ -2756,21 +2691,21 @@ static int s2255_probe(struct usb_interface *interface, | |||
2756 | } | 2691 | } |
2757 | 2692 | ||
2758 | dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL); | 2693 | dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL); |
2759 | |||
2760 | if (!dev->fw_data->fw_urb) { | 2694 | if (!dev->fw_data->fw_urb) { |
2761 | dev_err(&interface->dev, "out of memory!\n"); | 2695 | dev_err(&interface->dev, "out of memory!\n"); |
2762 | goto error; | 2696 | goto errorFWURB; |
2763 | } | 2697 | } |
2698 | |||
2764 | dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL); | 2699 | dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL); |
2765 | if (!dev->fw_data->pfw_data) { | 2700 | if (!dev->fw_data->pfw_data) { |
2766 | dev_err(&interface->dev, "out of memory!\n"); | 2701 | dev_err(&interface->dev, "out of memory!\n"); |
2767 | goto error; | 2702 | goto errorFWDATA2; |
2768 | } | 2703 | } |
2769 | /* load the first chunk */ | 2704 | /* load the first chunk */ |
2770 | if (request_firmware(&dev->fw_data->fw, | 2705 | if (request_firmware(&dev->fw_data->fw, |
2771 | FIRMWARE_FILE_NAME, &dev->udev->dev)) { | 2706 | FIRMWARE_FILE_NAME, &dev->udev->dev)) { |
2772 | printk(KERN_ERR "sensoray 2255 failed to get firmware\n"); | 2707 | printk(KERN_ERR "sensoray 2255 failed to get firmware\n"); |
2773 | goto error; | 2708 | goto errorREQFW; |
2774 | } | 2709 | } |
2775 | /* check the firmware is valid */ | 2710 | /* check the firmware is valid */ |
2776 | fw_size = dev->fw_data->fw->size; | 2711 | fw_size = dev->fw_data->fw->size; |
@@ -2779,7 +2714,7 @@ static int s2255_probe(struct usb_interface *interface, | |||
2779 | if (*pdata != S2255_FW_MARKER) { | 2714 | if (*pdata != S2255_FW_MARKER) { |
2780 | printk(KERN_INFO "Firmware invalid.\n"); | 2715 | printk(KERN_INFO "Firmware invalid.\n"); |
2781 | retval = -ENODEV; | 2716 | retval = -ENODEV; |
2782 | goto error; | 2717 | goto errorFWMARKER; |
2783 | } else { | 2718 | } else { |
2784 | /* make sure firmware is the latest */ | 2719 | /* make sure firmware is the latest */ |
2785 | __le32 *pRel; | 2720 | __le32 *pRel; |
@@ -2789,26 +2724,53 @@ static int s2255_probe(struct usb_interface *interface, | |||
2789 | if (*pRel < S2255_CUR_DSP_FWVER) | 2724 | if (*pRel < S2255_CUR_DSP_FWVER) |
2790 | printk(KERN_INFO "s2255: f2255usb.bin out of date.\n"); | 2725 | printk(KERN_INFO "s2255: f2255usb.bin out of date.\n"); |
2791 | if (dev->pid == 0x2257 && *pRel < S2255_MIN_DSP_COLORFILTER) | 2726 | if (dev->pid == 0x2257 && *pRel < S2255_MIN_DSP_COLORFILTER) |
2792 | printk(KERN_WARNING "s2255: 2257 requires firmware 8 or above.\n"); | 2727 | printk(KERN_WARNING "s2255: 2257 requires firmware %d" |
2728 | "or above.\n", S2255_MIN_DSP_COLORFILTER); | ||
2793 | } | 2729 | } |
2794 | /* loads v4l specific */ | ||
2795 | s2255_probe_v4l(dev); | ||
2796 | usb_reset_device(dev->udev); | 2730 | usb_reset_device(dev->udev); |
2797 | /* load 2255 board specific */ | 2731 | /* load 2255 board specific */ |
2798 | retval = s2255_board_init(dev); | 2732 | retval = s2255_board_init(dev); |
2799 | if (retval) | 2733 | if (retval) |
2800 | goto error; | 2734 | goto errorBOARDINIT; |
2801 | |||
2802 | dprintk(4, "before probe done %p\n", dev); | 2735 | dprintk(4, "before probe done %p\n", dev); |
2803 | spin_lock_init(&dev->slock); | 2736 | spin_lock_init(&dev->slock); |
2804 | |||
2805 | s2255_fwload_start(dev, 0); | 2737 | s2255_fwload_start(dev, 0); |
2738 | /* kref for each vdev. Released on video_device_release callback */ | ||
2739 | for (i = 0; i < MAX_CHANNELS; i++) | ||
2740 | kref_get(&dev->kref); | ||
2741 | /* loads v4l specific */ | ||
2742 | retval = s2255_probe_v4l(dev); | ||
2743 | if (retval) | ||
2744 | goto errorV4L; | ||
2806 | dev_info(&interface->dev, "Sensoray 2255 detected\n"); | 2745 | dev_info(&interface->dev, "Sensoray 2255 detected\n"); |
2807 | return 0; | 2746 | return 0; |
2808 | error: | 2747 | errorV4L: |
2748 | for (i = 0; i < MAX_CHANNELS; i++) | ||
2749 | if (dev->vdev[i] && video_is_registered(dev->vdev[i])) | ||
2750 | video_unregister_device(dev->vdev[i]); | ||
2751 | errorBOARDINIT: | ||
2752 | s2255_board_shutdown(dev); | ||
2753 | errorFWMARKER: | ||
2754 | release_firmware(dev->fw_data->fw); | ||
2755 | errorREQFW: | ||
2756 | kfree(dev->fw_data->pfw_data); | ||
2757 | errorFWDATA2: | ||
2758 | usb_free_urb(dev->fw_data->fw_urb); | ||
2759 | errorFWURB: | ||
2760 | del_timer(&dev->timer); | ||
2761 | errorEP: | ||
2762 | usb_put_dev(dev->udev); | ||
2763 | errorUDEV: | ||
2764 | kfree(dev->fw_data); | ||
2765 | mutex_destroy(&dev->open_lock); | ||
2766 | mutex_destroy(&dev->lock); | ||
2767 | errorFWDATA1: | ||
2768 | kfree(dev); | ||
2769 | printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x\n", retval); | ||
2809 | return retval; | 2770 | return retval; |
2810 | } | 2771 | } |
2811 | 2772 | ||
2773 | |||
2812 | /* disconnect routine. when board is removed physically or with rmmod */ | 2774 | /* disconnect routine. when board is removed physically or with rmmod */ |
2813 | static void s2255_disconnect(struct usb_interface *interface) | 2775 | static void s2255_disconnect(struct usb_interface *interface) |
2814 | { | 2776 | { |
@@ -2816,11 +2778,11 @@ static void s2255_disconnect(struct usb_interface *interface) | |||
2816 | int i; | 2778 | int i; |
2817 | dprintk(1, "s2255: disconnect interface %p\n", interface); | 2779 | dprintk(1, "s2255: disconnect interface %p\n", interface); |
2818 | dev = usb_get_intfdata(interface); | 2780 | dev = usb_get_intfdata(interface); |
2819 | 2781 | /* unregister each video device. */ | |
2820 | /* | 2782 | for (i = 0; i < MAX_CHANNELS; i++) |
2821 | * wake up any of the timers to allow open_lock to be | 2783 | if (video_is_registered(dev->vdev[i])) |
2822 | * acquired sooner | 2784 | video_unregister_device(dev->vdev[i]); |
2823 | */ | 2785 | /* wake up any of our timers */ |
2824 | atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING); | 2786 | atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING); |
2825 | wake_up(&dev->fw_data->wait_fw); | 2787 | wake_up(&dev->fw_data->wait_fw); |
2826 | for (i = 0; i < MAX_CHANNELS; i++) { | 2788 | for (i = 0; i < MAX_CHANNELS; i++) { |
@@ -2829,16 +2791,9 @@ static void s2255_disconnect(struct usb_interface *interface) | |||
2829 | dev->vidstatus_ready[i] = 1; | 2791 | dev->vidstatus_ready[i] = 1; |
2830 | wake_up(&dev->wait_vidstatus[i]); | 2792 | wake_up(&dev->wait_vidstatus[i]); |
2831 | } | 2793 | } |
2832 | |||
2833 | mutex_lock(&dev->open_lock); | ||
2834 | usb_set_intfdata(interface, NULL); | 2794 | usb_set_intfdata(interface, NULL); |
2835 | mutex_unlock(&dev->open_lock); | 2795 | kref_put(&dev->kref, s2255_destroy); |
2836 | 2796 | dev_info(&interface->dev, "%s\n", __func__); | |
2837 | if (dev) { | ||
2838 | kref_put(&dev->kref, s2255_destroy); | ||
2839 | dprintk(1, "s2255drv: disconnect\n"); | ||
2840 | dev_info(&interface->dev, "s2255usb now disconnected\n"); | ||
2841 | } | ||
2842 | } | 2797 | } |
2843 | 2798 | ||
2844 | static struct usb_driver s2255_driver = { | 2799 | static struct usb_driver s2255_driver = { |
@@ -2851,15 +2806,12 @@ static struct usb_driver s2255_driver = { | |||
2851 | static int __init usb_s2255_init(void) | 2806 | static int __init usb_s2255_init(void) |
2852 | { | 2807 | { |
2853 | int result; | 2808 | int result; |
2854 | |||
2855 | /* register this driver with the USB subsystem */ | 2809 | /* register this driver with the USB subsystem */ |
2856 | result = usb_register(&s2255_driver); | 2810 | result = usb_register(&s2255_driver); |
2857 | |||
2858 | if (result) | 2811 | if (result) |
2859 | pr_err(KBUILD_MODNAME | 2812 | pr_err(KBUILD_MODNAME |
2860 | ": usb_register failed. Error number %d\n", result); | 2813 | ": usb_register failed. Error number %d\n", result); |
2861 | 2814 | dprintk(2, "%s\n", __func__); | |
2862 | dprintk(2, "s2255_init: done\n"); | ||
2863 | return result; | 2815 | return result; |
2864 | } | 2816 | } |
2865 | 2817 | ||