diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-09-15 07:18:31 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-10-20 23:06:13 -0400 |
commit | c37db91fd0d42d27141b6c49b768070df29e1c5e (patch) | |
tree | 3be1129ac4c71177ceca8a888ef9fc232e69df05 | |
parent | ca960bfe136844952041d2e7dc030a6d4d5c7469 (diff) |
V4L/DVB: bttv: fix driver lock and remove explicit calls to BKL
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/bt8xx/bttv-driver.c | 201 |
1 files changed, 143 insertions, 58 deletions
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index d74dfa6d1a55..056888cbc8e7 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -1859,21 +1859,25 @@ static int bttv_s_std(struct file *file, void *priv, v4l2_std_id *id) | |||
1859 | unsigned int i; | 1859 | unsigned int i; |
1860 | int err; | 1860 | int err; |
1861 | 1861 | ||
1862 | mutex_lock(&btv->lock); | ||
1862 | err = v4l2_prio_check(&btv->prio, fh->prio); | 1863 | err = v4l2_prio_check(&btv->prio, fh->prio); |
1863 | if (0 != err) | 1864 | if (err) |
1864 | return err; | 1865 | goto err; |
1865 | 1866 | ||
1866 | for (i = 0; i < BTTV_TVNORMS; i++) | 1867 | for (i = 0; i < BTTV_TVNORMS; i++) |
1867 | if (*id & bttv_tvnorms[i].v4l2_id) | 1868 | if (*id & bttv_tvnorms[i].v4l2_id) |
1868 | break; | 1869 | break; |
1869 | if (i == BTTV_TVNORMS) | 1870 | if (i == BTTV_TVNORMS) { |
1870 | return -EINVAL; | 1871 | err = -EINVAL; |
1872 | goto err; | ||
1873 | } | ||
1871 | 1874 | ||
1872 | mutex_lock(&btv->lock); | ||
1873 | set_tvnorm(btv, i); | 1875 | set_tvnorm(btv, i); |
1876 | |||
1877 | err: | ||
1874 | mutex_unlock(&btv->lock); | 1878 | mutex_unlock(&btv->lock); |
1875 | 1879 | ||
1876 | return 0; | 1880 | return err; |
1877 | } | 1881 | } |
1878 | 1882 | ||
1879 | static int bttv_querystd(struct file *file, void *f, v4l2_std_id *id) | 1883 | static int bttv_querystd(struct file *file, void *f, v4l2_std_id *id) |
@@ -1893,10 +1897,13 @@ static int bttv_enum_input(struct file *file, void *priv, | |||
1893 | { | 1897 | { |
1894 | struct bttv_fh *fh = priv; | 1898 | struct bttv_fh *fh = priv; |
1895 | struct bttv *btv = fh->btv; | 1899 | struct bttv *btv = fh->btv; |
1896 | int n; | 1900 | int rc = 0; |
1897 | 1901 | ||
1898 | if (i->index >= bttv_tvcards[btv->c.type].video_inputs) | 1902 | mutex_lock(&btv->lock); |
1899 | return -EINVAL; | 1903 | if (i->index >= bttv_tvcards[btv->c.type].video_inputs) { |
1904 | rc = -EINVAL; | ||
1905 | goto err; | ||
1906 | } | ||
1900 | 1907 | ||
1901 | i->type = V4L2_INPUT_TYPE_CAMERA; | 1908 | i->type = V4L2_INPUT_TYPE_CAMERA; |
1902 | i->audioset = 1; | 1909 | i->audioset = 1; |
@@ -1919,10 +1926,12 @@ static int bttv_enum_input(struct file *file, void *priv, | |||
1919 | i->status |= V4L2_IN_ST_NO_H_LOCK; | 1926 | i->status |= V4L2_IN_ST_NO_H_LOCK; |
1920 | } | 1927 | } |
1921 | 1928 | ||
1922 | for (n = 0; n < BTTV_TVNORMS; n++) | 1929 | i->std = BTTV_NORMS; |
1923 | i->std |= bttv_tvnorms[n].v4l2_id; | ||
1924 | 1930 | ||
1925 | return 0; | 1931 | err: |
1932 | mutex_unlock(&btv->lock); | ||
1933 | |||
1934 | return rc; | ||
1926 | } | 1935 | } |
1927 | 1936 | ||
1928 | static int bttv_g_input(struct file *file, void *priv, unsigned int *i) | 1937 | static int bttv_g_input(struct file *file, void *priv, unsigned int *i) |
@@ -1930,7 +1939,10 @@ static int bttv_g_input(struct file *file, void *priv, unsigned int *i) | |||
1930 | struct bttv_fh *fh = priv; | 1939 | struct bttv_fh *fh = priv; |
1931 | struct bttv *btv = fh->btv; | 1940 | struct bttv *btv = fh->btv; |
1932 | 1941 | ||
1942 | mutex_lock(&btv->lock); | ||
1933 | *i = btv->input; | 1943 | *i = btv->input; |
1944 | mutex_unlock(&btv->lock); | ||
1945 | |||
1934 | return 0; | 1946 | return 0; |
1935 | } | 1947 | } |
1936 | 1948 | ||
@@ -1941,15 +1953,19 @@ static int bttv_s_input(struct file *file, void *priv, unsigned int i) | |||
1941 | 1953 | ||
1942 | int err; | 1954 | int err; |
1943 | 1955 | ||
1956 | mutex_lock(&btv->lock); | ||
1944 | err = v4l2_prio_check(&btv->prio, fh->prio); | 1957 | err = v4l2_prio_check(&btv->prio, fh->prio); |
1945 | if (0 != err) | 1958 | if (unlikely(err)) |
1946 | return err; | 1959 | goto err; |
1947 | 1960 | ||
1948 | if (i > bttv_tvcards[btv->c.type].video_inputs) | 1961 | if (i > bttv_tvcards[btv->c.type].video_inputs) { |
1949 | return -EINVAL; | 1962 | err = -EINVAL; |
1963 | goto err; | ||
1964 | } | ||
1950 | 1965 | ||
1951 | mutex_lock(&btv->lock); | ||
1952 | set_input(btv, i, btv->tvnorm); | 1966 | set_input(btv, i, btv->tvnorm); |
1967 | |||
1968 | err: | ||
1953 | mutex_unlock(&btv->lock); | 1969 | mutex_unlock(&btv->lock); |
1954 | return 0; | 1970 | return 0; |
1955 | } | 1971 | } |
@@ -1961,22 +1977,25 @@ static int bttv_s_tuner(struct file *file, void *priv, | |||
1961 | struct bttv *btv = fh->btv; | 1977 | struct bttv *btv = fh->btv; |
1962 | int err; | 1978 | int err; |
1963 | 1979 | ||
1964 | err = v4l2_prio_check(&btv->prio, fh->prio); | 1980 | if (unlikely(0 != t->index)) |
1965 | if (0 != err) | ||
1966 | return err; | ||
1967 | |||
1968 | if (btv->tuner_type == TUNER_ABSENT) | ||
1969 | return -EINVAL; | ||
1970 | |||
1971 | if (0 != t->index) | ||
1972 | return -EINVAL; | 1981 | return -EINVAL; |
1973 | 1982 | ||
1974 | mutex_lock(&btv->lock); | 1983 | mutex_lock(&btv->lock); |
1984 | if (unlikely(btv->tuner_type == TUNER_ABSENT)) { | ||
1985 | err = -EINVAL; | ||
1986 | goto err; | ||
1987 | } | ||
1988 | |||
1989 | err = v4l2_prio_check(&btv->prio, fh->prio); | ||
1990 | if (unlikely(err)) | ||
1991 | goto err; | ||
1992 | |||
1975 | bttv_call_all(btv, tuner, s_tuner, t); | 1993 | bttv_call_all(btv, tuner, s_tuner, t); |
1976 | 1994 | ||
1977 | if (btv->audio_mode_gpio) | 1995 | if (btv->audio_mode_gpio) |
1978 | btv->audio_mode_gpio(btv, t, 1); | 1996 | btv->audio_mode_gpio(btv, t, 1); |
1979 | 1997 | ||
1998 | err: | ||
1980 | mutex_unlock(&btv->lock); | 1999 | mutex_unlock(&btv->lock); |
1981 | 2000 | ||
1982 | return 0; | 2001 | return 0; |
@@ -1988,8 +2007,10 @@ static int bttv_g_frequency(struct file *file, void *priv, | |||
1988 | struct bttv_fh *fh = priv; | 2007 | struct bttv_fh *fh = priv; |
1989 | struct bttv *btv = fh->btv; | 2008 | struct bttv *btv = fh->btv; |
1990 | 2009 | ||
2010 | mutex_lock(&btv->lock); | ||
1991 | f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | 2011 | f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; |
1992 | f->frequency = btv->freq; | 2012 | f->frequency = btv->freq; |
2013 | mutex_unlock(&btv->lock); | ||
1993 | 2014 | ||
1994 | return 0; | 2015 | return 0; |
1995 | } | 2016 | } |
@@ -2001,21 +2022,26 @@ static int bttv_s_frequency(struct file *file, void *priv, | |||
2001 | struct bttv *btv = fh->btv; | 2022 | struct bttv *btv = fh->btv; |
2002 | int err; | 2023 | int err; |
2003 | 2024 | ||
2004 | err = v4l2_prio_check(&btv->prio, fh->prio); | ||
2005 | if (0 != err) | ||
2006 | return err; | ||
2007 | |||
2008 | if (unlikely(f->tuner != 0)) | 2025 | if (unlikely(f->tuner != 0)) |
2009 | return -EINVAL; | 2026 | return -EINVAL; |
2010 | if (unlikely(f->type != (btv->radio_user | 2027 | |
2011 | ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV))) | ||
2012 | return -EINVAL; | ||
2013 | mutex_lock(&btv->lock); | 2028 | mutex_lock(&btv->lock); |
2029 | err = v4l2_prio_check(&btv->prio, fh->prio); | ||
2030 | if (unlikely(err)) | ||
2031 | goto err; | ||
2032 | |||
2033 | if (unlikely(f->type != (btv->radio_user | ||
2034 | ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV))) { | ||
2035 | err = -EINVAL; | ||
2036 | goto err; | ||
2037 | } | ||
2014 | btv->freq = f->frequency; | 2038 | btv->freq = f->frequency; |
2015 | bttv_call_all(btv, tuner, s_frequency, f); | 2039 | bttv_call_all(btv, tuner, s_frequency, f); |
2016 | if (btv->has_matchbox && btv->radio_user) | 2040 | if (btv->has_matchbox && btv->radio_user) |
2017 | tea5757_set_freq(btv, btv->freq); | 2041 | tea5757_set_freq(btv, btv->freq); |
2042 | err: | ||
2018 | mutex_unlock(&btv->lock); | 2043 | mutex_unlock(&btv->lock); |
2044 | |||
2019 | return 0; | 2045 | return 0; |
2020 | } | 2046 | } |
2021 | 2047 | ||
@@ -2257,7 +2283,9 @@ verify_window_lock (struct bttv_fh * fh, | |||
2257 | if (V4L2_FIELD_ANY == field) { | 2283 | if (V4L2_FIELD_ANY == field) { |
2258 | __s32 height2; | 2284 | __s32 height2; |
2259 | 2285 | ||
2286 | mutex_lock(&fh->btv->lock); | ||
2260 | height2 = fh->btv->crop[!!fh->do_crop].rect.height >> 1; | 2287 | height2 = fh->btv->crop[!!fh->do_crop].rect.height >> 1; |
2288 | mutex_unlock(&fh->btv->lock); | ||
2261 | field = (win->w.height > height2) | 2289 | field = (win->w.height > height2) |
2262 | ? V4L2_FIELD_INTERLACED | 2290 | ? V4L2_FIELD_INTERLACED |
2263 | : V4L2_FIELD_TOP; | 2291 | : V4L2_FIELD_TOP; |
@@ -2332,6 +2360,8 @@ static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv, | |||
2332 | return -EFAULT; | 2360 | return -EFAULT; |
2333 | } | 2361 | } |
2334 | } | 2362 | } |
2363 | |||
2364 | mutex_lock(&fh->cap.vb_lock); | ||
2335 | /* clip against screen */ | 2365 | /* clip against screen */ |
2336 | if (NULL != btv->fbuf.base) | 2366 | if (NULL != btv->fbuf.base) |
2337 | n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height, | 2367 | n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height, |
@@ -2354,7 +2384,6 @@ static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv, | |||
2354 | BUG(); | 2384 | BUG(); |
2355 | } | 2385 | } |
2356 | 2386 | ||
2357 | mutex_lock(&fh->cap.vb_lock); | ||
2358 | kfree(fh->ov.clips); | 2387 | kfree(fh->ov.clips); |
2359 | fh->ov.clips = clips; | 2388 | fh->ov.clips = clips; |
2360 | fh->ov.nclips = n; | 2389 | fh->ov.nclips = n; |
@@ -2362,6 +2391,14 @@ static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv, | |||
2362 | fh->ov.w = win->w; | 2391 | fh->ov.w = win->w; |
2363 | fh->ov.field = win->field; | 2392 | fh->ov.field = win->field; |
2364 | fh->ov.setup_ok = 1; | 2393 | fh->ov.setup_ok = 1; |
2394 | |||
2395 | /* | ||
2396 | * FIXME: btv is protected by btv->lock mutex, while btv->init | ||
2397 | * is protected by fh->cap.vb_lock. This seems to open the | ||
2398 | * possibility for some race situations. Maybe the better would | ||
2399 | * be to unify those locks or to use another way to store the | ||
2400 | * init values that will be consumed by videobuf callbacks | ||
2401 | */ | ||
2365 | btv->init.ov.w.width = win->w.width; | 2402 | btv->init.ov.w.width = win->w.width; |
2366 | btv->init.ov.w.height = win->w.height; | 2403 | btv->init.ov.w.height = win->w.height; |
2367 | btv->init.ov.field = win->field; | 2404 | btv->init.ov.field = win->field; |
@@ -2490,7 +2527,9 @@ static int bttv_try_fmt_vid_cap(struct file *file, void *priv, | |||
2490 | if (V4L2_FIELD_ANY == field) { | 2527 | if (V4L2_FIELD_ANY == field) { |
2491 | __s32 height2; | 2528 | __s32 height2; |
2492 | 2529 | ||
2530 | mutex_lock(&btv->lock); | ||
2493 | height2 = btv->crop[!!fh->do_crop].rect.height >> 1; | 2531 | height2 = btv->crop[!!fh->do_crop].rect.height >> 1; |
2532 | mutex_unlock(&btv->lock); | ||
2494 | field = (f->fmt.pix.height > height2) | 2533 | field = (f->fmt.pix.height > height2) |
2495 | ? V4L2_FIELD_INTERLACED | 2534 | ? V4L2_FIELD_INTERLACED |
2496 | : V4L2_FIELD_BOTTOM; | 2535 | : V4L2_FIELD_BOTTOM; |
@@ -2651,11 +2690,15 @@ static int bttv_querycap(struct file *file, void *priv, | |||
2651 | V4L2_CAP_VBI_CAPTURE | | 2690 | V4L2_CAP_VBI_CAPTURE | |
2652 | V4L2_CAP_READWRITE | | 2691 | V4L2_CAP_READWRITE | |
2653 | V4L2_CAP_STREAMING; | 2692 | V4L2_CAP_STREAMING; |
2654 | if (btv->has_saa6588) | ||
2655 | cap->capabilities |= V4L2_CAP_RDS_CAPTURE; | ||
2656 | if (no_overlay <= 0) | 2693 | if (no_overlay <= 0) |
2657 | cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; | 2694 | cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; |
2658 | 2695 | ||
2696 | /* | ||
2697 | * No need to lock here: those vars are initialized during board | ||
2698 | * probe and remains untouched during the rest of the driver lifecycle | ||
2699 | */ | ||
2700 | if (btv->has_saa6588) | ||
2701 | cap->capabilities |= V4L2_CAP_RDS_CAPTURE; | ||
2659 | if (btv->tuner_type != TUNER_ABSENT) | 2702 | if (btv->tuner_type != TUNER_ABSENT) |
2660 | cap->capabilities |= V4L2_CAP_TUNER; | 2703 | cap->capabilities |= V4L2_CAP_TUNER; |
2661 | return 0; | 2704 | return 0; |
@@ -2730,16 +2773,22 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on) | |||
2730 | struct bttv_fh *fh = f; | 2773 | struct bttv_fh *fh = f; |
2731 | struct bttv *btv = fh->btv; | 2774 | struct bttv *btv = fh->btv; |
2732 | struct bttv_buffer *new; | 2775 | struct bttv_buffer *new; |
2733 | int retval; | 2776 | int retval = 0; |
2734 | 2777 | ||
2735 | if (on) { | 2778 | if (on) { |
2779 | mutex_lock(&fh->cap.vb_lock); | ||
2736 | /* verify args */ | 2780 | /* verify args */ |
2737 | if (NULL == btv->fbuf.base) | 2781 | if (unlikely(!btv->fbuf.base)) { |
2782 | mutex_unlock(&fh->cap.vb_lock); | ||
2738 | return -EINVAL; | 2783 | return -EINVAL; |
2739 | if (!fh->ov.setup_ok) { | 2784 | } |
2785 | if (unlikely(!fh->ov.setup_ok)) { | ||
2740 | dprintk("bttv%d: overlay: !setup_ok\n", btv->c.nr); | 2786 | dprintk("bttv%d: overlay: !setup_ok\n", btv->c.nr); |
2741 | return -EINVAL; | 2787 | retval = -EINVAL; |
2742 | } | 2788 | } |
2789 | if (retval) | ||
2790 | return retval; | ||
2791 | mutex_unlock(&fh->cap.vb_lock); | ||
2743 | } | 2792 | } |
2744 | 2793 | ||
2745 | if (!check_alloc_btres_lock(btv, fh, RESOURCE_OVERLAY)) | 2794 | if (!check_alloc_btres_lock(btv, fh, RESOURCE_OVERLAY)) |
@@ -2907,6 +2956,7 @@ static int bttv_queryctrl(struct file *file, void *priv, | |||
2907 | c->id >= V4L2_CID_PRIVATE_LASTP1)) | 2956 | c->id >= V4L2_CID_PRIVATE_LASTP1)) |
2908 | return -EINVAL; | 2957 | return -EINVAL; |
2909 | 2958 | ||
2959 | mutex_lock(&btv->lock); | ||
2910 | if (!btv->volume_gpio && (c->id == V4L2_CID_AUDIO_VOLUME)) | 2960 | if (!btv->volume_gpio && (c->id == V4L2_CID_AUDIO_VOLUME)) |
2911 | *c = no_ctl; | 2961 | *c = no_ctl; |
2912 | else { | 2962 | else { |
@@ -2914,6 +2964,7 @@ static int bttv_queryctrl(struct file *file, void *priv, | |||
2914 | 2964 | ||
2915 | *c = (NULL != ctrl) ? *ctrl : no_ctl; | 2965 | *c = (NULL != ctrl) ? *ctrl : no_ctl; |
2916 | } | 2966 | } |
2967 | mutex_unlock(&btv->lock); | ||
2917 | 2968 | ||
2918 | return 0; | 2969 | return 0; |
2919 | } | 2970 | } |
@@ -2924,8 +2975,11 @@ static int bttv_g_parm(struct file *file, void *f, | |||
2924 | struct bttv_fh *fh = f; | 2975 | struct bttv_fh *fh = f; |
2925 | struct bttv *btv = fh->btv; | 2976 | struct bttv *btv = fh->btv; |
2926 | 2977 | ||
2978 | mutex_lock(&btv->lock); | ||
2927 | v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id, | 2979 | v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id, |
2928 | &parm->parm.capture.timeperframe); | 2980 | &parm->parm.capture.timeperframe); |
2981 | mutex_unlock(&btv->lock); | ||
2982 | |||
2929 | return 0; | 2983 | return 0; |
2930 | } | 2984 | } |
2931 | 2985 | ||
@@ -2961,7 +3015,9 @@ static int bttv_g_priority(struct file *file, void *f, enum v4l2_priority *p) | |||
2961 | struct bttv_fh *fh = f; | 3015 | struct bttv_fh *fh = f; |
2962 | struct bttv *btv = fh->btv; | 3016 | struct bttv *btv = fh->btv; |
2963 | 3017 | ||
3018 | mutex_lock(&btv->lock); | ||
2964 | *p = v4l2_prio_max(&btv->prio); | 3019 | *p = v4l2_prio_max(&btv->prio); |
3020 | mutex_unlock(&btv->lock); | ||
2965 | 3021 | ||
2966 | return 0; | 3022 | return 0; |
2967 | } | 3023 | } |
@@ -2971,8 +3027,13 @@ static int bttv_s_priority(struct file *file, void *f, | |||
2971 | { | 3027 | { |
2972 | struct bttv_fh *fh = f; | 3028 | struct bttv_fh *fh = f; |
2973 | struct bttv *btv = fh->btv; | 3029 | struct bttv *btv = fh->btv; |
3030 | int rc; | ||
3031 | |||
3032 | mutex_lock(&btv->lock); | ||
3033 | rc = v4l2_prio_change(&btv->prio, &fh->prio, prio); | ||
3034 | mutex_unlock(&btv->lock); | ||
2974 | 3035 | ||
2975 | return v4l2_prio_change(&btv->prio, &fh->prio, prio); | 3036 | return rc; |
2976 | } | 3037 | } |
2977 | 3038 | ||
2978 | static int bttv_cropcap(struct file *file, void *priv, | 3039 | static int bttv_cropcap(struct file *file, void *priv, |
@@ -2985,7 +3046,9 @@ static int bttv_cropcap(struct file *file, void *priv, | |||
2985 | cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) | 3046 | cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) |
2986 | return -EINVAL; | 3047 | return -EINVAL; |
2987 | 3048 | ||
3049 | mutex_lock(&btv->lock); | ||
2988 | *cap = bttv_tvnorms[btv->tvnorm].cropcap; | 3050 | *cap = bttv_tvnorms[btv->tvnorm].cropcap; |
3051 | mutex_unlock(&btv->lock); | ||
2989 | 3052 | ||
2990 | return 0; | 3053 | return 0; |
2991 | } | 3054 | } |
@@ -3003,7 +3066,9 @@ static int bttv_g_crop(struct file *file, void *f, struct v4l2_crop *crop) | |||
3003 | inconsistent with fh->width or fh->height and apps | 3066 | inconsistent with fh->width or fh->height and apps |
3004 | do not expect a change here. */ | 3067 | do not expect a change here. */ |
3005 | 3068 | ||
3069 | mutex_lock(&btv->lock); | ||
3006 | crop->c = btv->crop[!!fh->do_crop].rect; | 3070 | crop->c = btv->crop[!!fh->do_crop].rect; |
3071 | mutex_unlock(&btv->lock); | ||
3007 | 3072 | ||
3008 | return 0; | 3073 | return 0; |
3009 | } | 3074 | } |
@@ -3024,14 +3089,15 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop) | |||
3024 | crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) | 3089 | crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) |
3025 | return -EINVAL; | 3090 | return -EINVAL; |
3026 | 3091 | ||
3027 | retval = v4l2_prio_check(&btv->prio, fh->prio); | ||
3028 | if (0 != retval) | ||
3029 | return retval; | ||
3030 | |||
3031 | /* Make sure tvnorm, vbi_end and the current cropping | 3092 | /* Make sure tvnorm, vbi_end and the current cropping |
3032 | parameters remain consistent until we're done. Note | 3093 | parameters remain consistent until we're done. Note |
3033 | read() may change vbi_end in check_alloc_btres_lock(). */ | 3094 | read() may change vbi_end in check_alloc_btres_lock(). */ |
3034 | mutex_lock(&btv->lock); | 3095 | mutex_lock(&btv->lock); |
3096 | retval = v4l2_prio_check(&btv->prio, fh->prio); | ||
3097 | if (0 != retval) { | ||
3098 | mutex_unlock(&btv->lock); | ||
3099 | return retval; | ||
3100 | } | ||
3035 | 3101 | ||
3036 | retval = -EBUSY; | 3102 | retval = -EBUSY; |
3037 | 3103 | ||
@@ -3219,21 +3285,32 @@ static int bttv_open(struct file *file) | |||
3219 | return -ENODEV; | 3285 | return -ENODEV; |
3220 | } | 3286 | } |
3221 | 3287 | ||
3222 | lock_kernel(); | ||
3223 | |||
3224 | dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n", | 3288 | dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n", |
3225 | btv->c.nr,v4l2_type_names[type]); | 3289 | btv->c.nr,v4l2_type_names[type]); |
3226 | 3290 | ||
3227 | /* allocate per filehandle data */ | 3291 | /* allocate per filehandle data */ |
3228 | fh = kmalloc(sizeof(*fh),GFP_KERNEL); | 3292 | fh = kmalloc(sizeof(*fh), GFP_KERNEL); |
3229 | if (NULL == fh) { | 3293 | if (unlikely(!fh)) |
3230 | unlock_kernel(); | ||
3231 | return -ENOMEM; | 3294 | return -ENOMEM; |
3232 | } | ||
3233 | file->private_data = fh; | 3295 | file->private_data = fh; |
3296 | |||
3297 | /* | ||
3298 | * btv is protected by btv->lock mutex, while btv->init and other | ||
3299 | * streaming vars are protected by fh->cap.vb_lock. We need to take | ||
3300 | * care of both locks to avoid troubles. However, vb_lock is used also | ||
3301 | * inside videobuf, without calling buf->lock. So, it is a very bad | ||
3302 | * idea to hold both locks at the same time. | ||
3303 | * Let's first copy btv->init at fh, holding cap.vb_lock, and then work | ||
3304 | * with the rest of init, holding btv->lock. | ||
3305 | */ | ||
3306 | mutex_lock(&fh->cap.vb_lock); | ||
3234 | *fh = btv->init; | 3307 | *fh = btv->init; |
3308 | mutex_unlock(&fh->cap.vb_lock); | ||
3309 | |||
3235 | fh->type = type; | 3310 | fh->type = type; |
3236 | fh->ov.setup_ok = 0; | 3311 | fh->ov.setup_ok = 0; |
3312 | |||
3313 | mutex_lock(&btv->lock); | ||
3237 | v4l2_prio_open(&btv->prio, &fh->prio); | 3314 | v4l2_prio_open(&btv->prio, &fh->prio); |
3238 | 3315 | ||
3239 | videobuf_queue_sg_init(&fh->cap, &bttv_video_qops, | 3316 | videobuf_queue_sg_init(&fh->cap, &bttv_video_qops, |
@@ -3270,7 +3347,7 @@ static int bttv_open(struct file *file) | |||
3270 | bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm); | 3347 | bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm); |
3271 | 3348 | ||
3272 | bttv_field_count(btv); | 3349 | bttv_field_count(btv); |
3273 | unlock_kernel(); | 3350 | mutex_unlock(&btv->lock); |
3274 | return 0; | 3351 | return 0; |
3275 | } | 3352 | } |
3276 | 3353 | ||
@@ -3279,6 +3356,7 @@ static int bttv_release(struct file *file) | |||
3279 | struct bttv_fh *fh = file->private_data; | 3356 | struct bttv_fh *fh = file->private_data; |
3280 | struct bttv *btv = fh->btv; | 3357 | struct bttv *btv = fh->btv; |
3281 | 3358 | ||
3359 | mutex_lock(&btv->lock); | ||
3282 | /* turn off overlay */ | 3360 | /* turn off overlay */ |
3283 | if (check_btres(fh, RESOURCE_OVERLAY)) | 3361 | if (check_btres(fh, RESOURCE_OVERLAY)) |
3284 | bttv_switch_overlay(btv,fh,NULL); | 3362 | bttv_switch_overlay(btv,fh,NULL); |
@@ -3303,8 +3381,15 @@ static int bttv_release(struct file *file) | |||
3303 | } | 3381 | } |
3304 | 3382 | ||
3305 | /* free stuff */ | 3383 | /* free stuff */ |
3384 | |||
3385 | /* | ||
3386 | * videobuf uses cap.vb_lock - we should avoid holding btv->lock, | ||
3387 | * otherwise we may have dead lock conditions | ||
3388 | */ | ||
3389 | mutex_unlock(&btv->lock); | ||
3306 | videobuf_mmap_free(&fh->cap); | 3390 | videobuf_mmap_free(&fh->cap); |
3307 | videobuf_mmap_free(&fh->vbi); | 3391 | videobuf_mmap_free(&fh->vbi); |
3392 | mutex_lock(&btv->lock); | ||
3308 | v4l2_prio_close(&btv->prio, fh->prio); | 3393 | v4l2_prio_close(&btv->prio, fh->prio); |
3309 | file->private_data = NULL; | 3394 | file->private_data = NULL; |
3310 | kfree(fh); | 3395 | kfree(fh); |
@@ -3314,6 +3399,7 @@ static int bttv_release(struct file *file) | |||
3314 | 3399 | ||
3315 | if (!btv->users) | 3400 | if (!btv->users) |
3316 | audio_mute(btv, 1); | 3401 | audio_mute(btv, 1); |
3402 | mutex_unlock(&btv->lock); | ||
3317 | 3403 | ||
3318 | return 0; | 3404 | return 0; |
3319 | } | 3405 | } |
@@ -3410,21 +3496,19 @@ static int radio_open(struct file *file) | |||
3410 | 3496 | ||
3411 | dprintk("bttv: open dev=%s\n", video_device_node_name(vdev)); | 3497 | dprintk("bttv: open dev=%s\n", video_device_node_name(vdev)); |
3412 | 3498 | ||
3413 | lock_kernel(); | ||
3414 | |||
3415 | dprintk("bttv%d: open called (radio)\n",btv->c.nr); | 3499 | dprintk("bttv%d: open called (radio)\n",btv->c.nr); |
3416 | 3500 | ||
3417 | /* allocate per filehandle data */ | 3501 | /* allocate per filehandle data */ |
3418 | fh = kmalloc(sizeof(*fh), GFP_KERNEL); | 3502 | fh = kmalloc(sizeof(*fh), GFP_KERNEL); |
3419 | if (NULL == fh) { | 3503 | if (unlikely(!fh)) |
3420 | unlock_kernel(); | ||
3421 | return -ENOMEM; | 3504 | return -ENOMEM; |
3422 | } | ||
3423 | file->private_data = fh; | 3505 | file->private_data = fh; |
3506 | mutex_lock(&fh->cap.vb_lock); | ||
3424 | *fh = btv->init; | 3507 | *fh = btv->init; |
3425 | v4l2_prio_open(&btv->prio, &fh->prio); | 3508 | mutex_unlock(&fh->cap.vb_lock); |
3426 | 3509 | ||
3427 | mutex_lock(&btv->lock); | 3510 | mutex_lock(&btv->lock); |
3511 | v4l2_prio_open(&btv->prio, &fh->prio); | ||
3428 | 3512 | ||
3429 | btv->radio_user++; | 3513 | btv->radio_user++; |
3430 | 3514 | ||
@@ -3432,7 +3516,6 @@ static int radio_open(struct file *file) | |||
3432 | audio_input(btv,TVAUDIO_INPUT_RADIO); | 3516 | audio_input(btv,TVAUDIO_INPUT_RADIO); |
3433 | 3517 | ||
3434 | mutex_unlock(&btv->lock); | 3518 | mutex_unlock(&btv->lock); |
3435 | unlock_kernel(); | ||
3436 | return 0; | 3519 | return 0; |
3437 | } | 3520 | } |
3438 | 3521 | ||
@@ -3442,6 +3525,7 @@ static int radio_release(struct file *file) | |||
3442 | struct bttv *btv = fh->btv; | 3525 | struct bttv *btv = fh->btv; |
3443 | struct rds_command cmd; | 3526 | struct rds_command cmd; |
3444 | 3527 | ||
3528 | mutex_lock(&btv->lock); | ||
3445 | v4l2_prio_close(&btv->prio, fh->prio); | 3529 | v4l2_prio_close(&btv->prio, fh->prio); |
3446 | file->private_data = NULL; | 3530 | file->private_data = NULL; |
3447 | kfree(fh); | 3531 | kfree(fh); |
@@ -3449,6 +3533,7 @@ static int radio_release(struct file *file) | |||
3449 | btv->radio_user--; | 3533 | btv->radio_user--; |
3450 | 3534 | ||
3451 | bttv_call_all(btv, core, ioctl, RDS_CMD_CLOSE, &cmd); | 3535 | bttv_call_all(btv, core, ioctl, RDS_CMD_CLOSE, &cmd); |
3536 | mutex_unlock(&btv->lock); | ||
3452 | 3537 | ||
3453 | return 0; | 3538 | return 0; |
3454 | } | 3539 | } |