diff options
author | Chris Pascoe <c.pascoe@itee.uq.edu.au> | 2007-11-19 02:45:38 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-01-25 16:02:24 -0500 |
commit | aa501be989f5df58c4732d5eb1989e5ca6479d90 (patch) | |
tree | 45f79c5b2d9c2462234c5c3b180572a84b3e5ef2 /drivers/media/video/tuner-xc2028.c | |
parent | 91240dd92474d4124f80b00e6200052b275a99a1 (diff) |
V4L/DVB (6636): xc2028: protect device list
Protect refcount changes and modifications to xc2028_list with a mutex.
Signed-off-by: Chris Pascoe <c.pascoe@itee.uq.edu.au>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/tuner-xc2028.c')
-rw-r--r-- | drivers/media/video/tuner-xc2028.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/media/video/tuner-xc2028.c b/drivers/media/video/tuner-xc2028.c index a01231a0410d..ac7f3e1d32f4 100644 --- a/drivers/media/video/tuner-xc2028.c +++ b/drivers/media/video/tuner-xc2028.c | |||
@@ -44,6 +44,8 @@ MODULE_PARM_DESC(audio_std, | |||
44 | "NICAM/B\n"); | 44 | "NICAM/B\n"); |
45 | 45 | ||
46 | static LIST_HEAD(xc2028_list); | 46 | static LIST_HEAD(xc2028_list); |
47 | static DEFINE_MUTEX(xc2028_list_mutex); | ||
48 | |||
47 | /* struct for storing firmware table */ | 49 | /* struct for storing firmware table */ |
48 | struct firmware_description { | 50 | struct firmware_description { |
49 | unsigned int type; | 51 | unsigned int type; |
@@ -854,6 +856,8 @@ static int xc2028_dvb_release(struct dvb_frontend *fe) | |||
854 | 856 | ||
855 | tuner_dbg("%s called\n", __FUNCTION__); | 857 | tuner_dbg("%s called\n", __FUNCTION__); |
856 | 858 | ||
859 | mutex_lock(&xc2028_list_mutex); | ||
860 | |||
857 | priv->count--; | 861 | priv->count--; |
858 | 862 | ||
859 | if (!priv->count) { | 863 | if (!priv->count) { |
@@ -865,6 +869,8 @@ static int xc2028_dvb_release(struct dvb_frontend *fe) | |||
865 | kfree(priv); | 869 | kfree(priv); |
866 | } | 870 | } |
867 | 871 | ||
872 | mutex_unlock(&xc2028_list_mutex); | ||
873 | |||
868 | return 0; | 874 | return 0; |
869 | } | 875 | } |
870 | 876 | ||
@@ -940,6 +946,8 @@ void *xc2028_attach(struct dvb_frontend *fe, struct xc2028_config *cfg) | |||
940 | 946 | ||
941 | video_dev = cfg->video_dev; | 947 | video_dev = cfg->video_dev; |
942 | 948 | ||
949 | mutex_lock(&xc2028_list_mutex); | ||
950 | |||
943 | list_for_each_entry(priv, &xc2028_list, xc2028_list) { | 951 | list_for_each_entry(priv, &xc2028_list, xc2028_list) { |
944 | if (priv->video_dev == cfg->video_dev) { | 952 | if (priv->video_dev == cfg->video_dev) { |
945 | video_dev = NULL; | 953 | video_dev = NULL; |
@@ -949,8 +957,10 @@ void *xc2028_attach(struct dvb_frontend *fe, struct xc2028_config *cfg) | |||
949 | 957 | ||
950 | if (video_dev) { | 958 | if (video_dev) { |
951 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 959 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
952 | if (priv == NULL) | 960 | if (priv == NULL) { |
961 | mutex_unlock(&xc2028_list_mutex); | ||
953 | return NULL; | 962 | return NULL; |
963 | } | ||
954 | 964 | ||
955 | priv->bandwidth = BANDWIDTH_6_MHZ; | 965 | priv->bandwidth = BANDWIDTH_6_MHZ; |
956 | priv->need_load_generic = 1; | 966 | priv->need_load_generic = 1; |
@@ -974,6 +984,8 @@ void *xc2028_attach(struct dvb_frontend *fe, struct xc2028_config *cfg) | |||
974 | 984 | ||
975 | tuner_info("type set to %s\n", "XCeive xc2028/xc3028 tuner"); | 985 | tuner_info("type set to %s\n", "XCeive xc2028/xc3028 tuner"); |
976 | 986 | ||
987 | mutex_unlock(&xc2028_list_mutex); | ||
988 | |||
977 | return fe; | 989 | return fe; |
978 | } | 990 | } |
979 | 991 | ||