diff options
author | Dongxiao Xu <dongxiao.xu@intel.com> | 2009-05-31 02:44:01 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-19 14:00:55 -0400 |
commit | afcf462a1fd78cc372aefd9fe352e2dc2f237937 (patch) | |
tree | ec346ebfcf6ad5e44be0cf9aedafc6cb2b86eb89 | |
parent | 8d1c50e9829442be5bc88979d587af2a5ff07e32 (diff) |
Staging: heci: fix the problem that file_ext->state should be protected by device_lock
While access file_ext->state, we should use device_lock to protect it. The
original codes miss this in some places.
Signed-off-by: Dongxiao Xu <dongxiao.xu@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/staging/heci/heci_init.c | 9 | ||||
-rw-r--r-- | drivers/staging/heci/heci_main.c | 15 | ||||
-rw-r--r-- | drivers/staging/heci/io_heci.c | 8 |
3 files changed, 26 insertions, 6 deletions
diff --git a/drivers/staging/heci/heci_init.c b/drivers/staging/heci/heci_init.c index 427f55d7b262..31fd891c099d 100644 --- a/drivers/staging/heci/heci_init.c +++ b/drivers/staging/heci/heci_init.c | |||
@@ -998,8 +998,12 @@ int heci_disconnect_host_client(struct iamt_heci_device *dev, | |||
998 | if ((!dev) || (!file_ext)) | 998 | if ((!dev) || (!file_ext)) |
999 | return -ENODEV; | 999 | return -ENODEV; |
1000 | 1000 | ||
1001 | if (file_ext->state != HECI_FILE_DISCONNECTING) | 1001 | spin_lock_bh(&dev->device_lock); |
1002 | if (file_ext->state != HECI_FILE_DISCONNECTING) { | ||
1003 | spin_unlock_bh(&dev->device_lock); | ||
1002 | return 0; | 1004 | return 0; |
1005 | } | ||
1006 | spin_unlock_bh(&dev->device_lock); | ||
1003 | 1007 | ||
1004 | priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL); | 1008 | priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL); |
1005 | if (!priv_cb) | 1009 | if (!priv_cb) |
@@ -1031,6 +1035,8 @@ int heci_disconnect_host_client(struct iamt_heci_device *dev, | |||
1031 | err = wait_event_timeout(dev->wait_recvd_msg, | 1035 | err = wait_event_timeout(dev->wait_recvd_msg, |
1032 | (HECI_FILE_DISCONNECTED == file_ext->state), | 1036 | (HECI_FILE_DISCONNECTED == file_ext->state), |
1033 | timeout * HZ); | 1037 | timeout * HZ); |
1038 | |||
1039 | spin_lock_bh(&dev->device_lock); | ||
1034 | if (HECI_FILE_DISCONNECTED == file_ext->state) { | 1040 | if (HECI_FILE_DISCONNECTED == file_ext->state) { |
1035 | rets = 0; | 1041 | rets = 0; |
1036 | DBG("successfully disconnected from fw client.\n"); | 1042 | DBG("successfully disconnected from fw client.\n"); |
@@ -1045,7 +1051,6 @@ int heci_disconnect_host_client(struct iamt_heci_device *dev, | |||
1045 | DBG("failed to disconnect from fw client.\n"); | 1051 | DBG("failed to disconnect from fw client.\n"); |
1046 | } | 1052 | } |
1047 | 1053 | ||
1048 | spin_lock_bh(&dev->device_lock); | ||
1049 | heci_flush_list(&dev->ctrl_rd_list, file_ext); | 1054 | heci_flush_list(&dev->ctrl_rd_list, file_ext); |
1050 | heci_flush_list(&dev->ctrl_wr_list, file_ext); | 1055 | heci_flush_list(&dev->ctrl_wr_list, file_ext); |
1051 | spin_unlock_bh(&dev->device_lock); | 1056 | spin_unlock_bh(&dev->device_lock); |
diff --git a/drivers/staging/heci/heci_main.c b/drivers/staging/heci/heci_main.c index 1197803fda85..ddf48227e358 100644 --- a/drivers/staging/heci/heci_main.c +++ b/drivers/staging/heci/heci_main.c | |||
@@ -751,7 +751,9 @@ static int heci_open(struct inode *inode, struct file *file) | |||
751 | (1 << (file_ext->host_client_id % 8)); | 751 | (1 << (file_ext->host_client_id % 8)); |
752 | spin_unlock_bh(&dev->device_lock); | 752 | spin_unlock_bh(&dev->device_lock); |
753 | spin_lock(&file_ext->file_lock); | 753 | spin_lock(&file_ext->file_lock); |
754 | spin_lock_bh(&dev->device_lock); | ||
754 | file_ext->state = HECI_FILE_INITIALIZING; | 755 | file_ext->state = HECI_FILE_INITIALIZING; |
756 | spin_unlock_bh(&dev->device_lock); | ||
755 | file_ext->sm_state = 0; | 757 | file_ext->sm_state = 0; |
756 | 758 | ||
757 | file->private_data = file_ext; | 759 | file->private_data = file_ext; |
@@ -785,8 +787,10 @@ static int heci_release(struct inode *inode, struct file *file) | |||
785 | 787 | ||
786 | if (file_ext != &dev->iamthif_file_ext) { | 788 | if (file_ext != &dev->iamthif_file_ext) { |
787 | spin_lock(&file_ext->file_lock); | 789 | spin_lock(&file_ext->file_lock); |
790 | spin_lock_bh(&dev->device_lock); | ||
788 | if (file_ext->state == HECI_FILE_CONNECTED) { | 791 | if (file_ext->state == HECI_FILE_CONNECTED) { |
789 | file_ext->state = HECI_FILE_DISCONNECTING; | 792 | file_ext->state = HECI_FILE_DISCONNECTING; |
793 | spin_unlock_bh(&dev->device_lock); | ||
790 | spin_unlock(&file_ext->file_lock); | 794 | spin_unlock(&file_ext->file_lock); |
791 | DBG("disconnecting client host client = %d, " | 795 | DBG("disconnecting client host client = %d, " |
792 | "ME client = %d\n", | 796 | "ME client = %d\n", |
@@ -794,8 +798,8 @@ static int heci_release(struct inode *inode, struct file *file) | |||
794 | file_ext->me_client_id); | 798 | file_ext->me_client_id); |
795 | rets = heci_disconnect_host_client(dev, file_ext); | 799 | rets = heci_disconnect_host_client(dev, file_ext); |
796 | spin_lock(&file_ext->file_lock); | 800 | spin_lock(&file_ext->file_lock); |
801 | spin_lock_bh(&dev->device_lock); | ||
797 | } | 802 | } |
798 | spin_lock_bh(&dev->device_lock); | ||
799 | heci_flush_queues(dev, file_ext); | 803 | heci_flush_queues(dev, file_ext); |
800 | DBG("remove client host client = %d, ME client = %d\n", | 804 | DBG("remove client host client = %d, ME client = %d\n", |
801 | file_ext->host_client_id, | 805 | file_ext->host_client_id, |
@@ -983,12 +987,15 @@ static ssize_t heci_read(struct file *file, char __user *ubuf, | |||
983 | return -ERESTARTSYS; | 987 | return -ERESTARTSYS; |
984 | } | 988 | } |
985 | 989 | ||
990 | spin_lock_bh(&dev->device_lock); | ||
986 | if (HECI_FILE_INITIALIZING == file_ext->state || | 991 | if (HECI_FILE_INITIALIZING == file_ext->state || |
987 | HECI_FILE_DISCONNECTED == file_ext->state || | 992 | HECI_FILE_DISCONNECTED == file_ext->state || |
988 | HECI_FILE_DISCONNECTING == file_ext->state) { | 993 | HECI_FILE_DISCONNECTING == file_ext->state) { |
994 | spin_unlock_bh(&dev->device_lock); | ||
989 | rets = -EBUSY; | 995 | rets = -EBUSY; |
990 | goto out; | 996 | goto out; |
991 | } | 997 | } |
998 | spin_unlock_bh(&dev->device_lock); | ||
992 | spin_lock_bh(&file_ext->read_io_lock); | 999 | spin_lock_bh(&file_ext->read_io_lock); |
993 | } | 1000 | } |
994 | 1001 | ||
@@ -1225,6 +1232,7 @@ static ssize_t heci_write(struct file *file, const char __user *ubuf, | |||
1225 | priv_write_cb->request_buffer.size = length; | 1232 | priv_write_cb->request_buffer.size = length; |
1226 | 1233 | ||
1227 | spin_lock(&file_ext->write_io_lock); | 1234 | spin_lock(&file_ext->write_io_lock); |
1235 | spin_lock_bh(&dev->device_lock); | ||
1228 | DBG("host client = %d, ME client = %d\n", | 1236 | DBG("host client = %d, ME client = %d\n", |
1229 | file_ext->host_client_id, file_ext->me_client_id); | 1237 | file_ext->host_client_id, file_ext->me_client_id); |
1230 | if (file_ext->state != HECI_FILE_CONNECTED) { | 1238 | if (file_ext->state != HECI_FILE_CONNECTED) { |
@@ -1232,7 +1240,7 @@ static ssize_t heci_write(struct file *file, const char __user *ubuf, | |||
1232 | DBG("host client = %d, is not connected to ME client = %d", | 1240 | DBG("host client = %d, is not connected to ME client = %d", |
1233 | file_ext->host_client_id, | 1241 | file_ext->host_client_id, |
1234 | file_ext->me_client_id); | 1242 | file_ext->me_client_id); |
1235 | 1243 | spin_unlock_bh(&dev->device_lock); | |
1236 | goto unlock; | 1244 | goto unlock; |
1237 | } | 1245 | } |
1238 | for (i = 0; i < dev->num_heci_me_clients; i++) { | 1246 | for (i = 0; i < dev->num_heci_me_clients; i++) { |
@@ -1243,15 +1251,16 @@ static ssize_t heci_write(struct file *file, const char __user *ubuf, | |||
1243 | BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id); | 1251 | BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id); |
1244 | if (i == dev->num_heci_me_clients) { | 1252 | if (i == dev->num_heci_me_clients) { |
1245 | rets = -ENODEV; | 1253 | rets = -ENODEV; |
1254 | spin_unlock_bh(&dev->device_lock); | ||
1246 | goto unlock; | 1255 | goto unlock; |
1247 | } | 1256 | } |
1248 | if (length > dev->me_clients[i].props.max_msg_length || length <= 0) { | 1257 | if (length > dev->me_clients[i].props.max_msg_length || length <= 0) { |
1249 | rets = -EINVAL; | 1258 | rets = -EINVAL; |
1259 | spin_unlock_bh(&dev->device_lock); | ||
1250 | goto unlock; | 1260 | goto unlock; |
1251 | } | 1261 | } |
1252 | priv_write_cb->file_private = file_ext; | 1262 | priv_write_cb->file_private = file_ext; |
1253 | 1263 | ||
1254 | spin_lock_bh(&dev->device_lock); | ||
1255 | if (flow_ctrl_creds(dev, file_ext) && | 1264 | if (flow_ctrl_creds(dev, file_ext) && |
1256 | dev->host_buffer_is_empty) { | 1265 | dev->host_buffer_is_empty) { |
1257 | spin_unlock_bh(&dev->device_lock); | 1266 | spin_unlock_bh(&dev->device_lock); |
diff --git a/drivers/staging/heci/io_heci.c b/drivers/staging/heci/io_heci.c index 0d7f31bed566..1a6faf88e16c 100644 --- a/drivers/staging/heci/io_heci.c +++ b/drivers/staging/heci/io_heci.c | |||
@@ -297,6 +297,7 @@ int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num, | |||
297 | if (!heci_connect(dev, file_ext)) { | 297 | if (!heci_connect(dev, file_ext)) { |
298 | rets = -ENODEV; | 298 | rets = -ENODEV; |
299 | spin_unlock_bh(&dev->device_lock); | 299 | spin_unlock_bh(&dev->device_lock); |
300 | spin_unlock(&file_ext->file_lock); | ||
300 | goto end; | 301 | goto end; |
301 | } else { | 302 | } else { |
302 | file_ext->timer_count = HECI_CONNECT_TIMEOUT; | 303 | file_ext->timer_count = HECI_CONNECT_TIMEOUT; |
@@ -320,7 +321,9 @@ int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num, | |||
320 | || HECI_FILE_DISCONNECTED == file_ext->state), | 321 | || HECI_FILE_DISCONNECTED == file_ext->state), |
321 | timeout * HZ); | 322 | timeout * HZ); |
322 | 323 | ||
324 | spin_lock_bh(&dev->device_lock); | ||
323 | if (HECI_FILE_CONNECTED == file_ext->state) { | 325 | if (HECI_FILE_CONNECTED == file_ext->state) { |
326 | spin_unlock_bh(&dev->device_lock); | ||
324 | DBG("successfully connected to FW client.\n"); | 327 | DBG("successfully connected to FW client.\n"); |
325 | rets = file_ext->status; | 328 | rets = file_ext->status; |
326 | /* now copy the data to user space */ | 329 | /* now copy the data to user space */ |
@@ -337,6 +340,7 @@ int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num, | |||
337 | } else { | 340 | } else { |
338 | DBG("failed to connect to FW client.file_ext->state = %d.\n", | 341 | DBG("failed to connect to FW client.file_ext->state = %d.\n", |
339 | file_ext->state); | 342 | file_ext->state); |
343 | spin_unlock_bh(&dev->device_lock); | ||
340 | if (!err) { | 344 | if (!err) { |
341 | DBG("wait_event_interruptible_timeout failed on client" | 345 | DBG("wait_event_interruptible_timeout failed on client" |
342 | " connect message fw response message.\n"); | 346 | " connect message fw response message.\n"); |
@@ -637,11 +641,13 @@ int heci_start_read(struct iamt_heci_device *dev, int if_num, | |||
637 | DBG("received wrong function input param.\n"); | 641 | DBG("received wrong function input param.\n"); |
638 | return -ENODEV; | 642 | return -ENODEV; |
639 | } | 643 | } |
644 | |||
645 | spin_lock_bh(&dev->device_lock); | ||
640 | if (file_ext->state != HECI_FILE_CONNECTED) { | 646 | if (file_ext->state != HECI_FILE_CONNECTED) { |
647 | spin_unlock_bh(&dev->device_lock); | ||
641 | return -ENODEV; | 648 | return -ENODEV; |
642 | } | 649 | } |
643 | 650 | ||
644 | spin_lock_bh(&dev->device_lock); | ||
645 | if (dev->heci_state != HECI_ENABLED) { | 651 | if (dev->heci_state != HECI_ENABLED) { |
646 | spin_unlock_bh(&dev->device_lock); | 652 | spin_unlock_bh(&dev->device_lock); |
647 | return -ENODEV; | 653 | return -ENODEV; |