aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2012-11-11 10:38:01 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-11-15 18:34:18 -0500
commita562d5c25aa48c23774ab8d60bfd3bbcbca4bf1d (patch)
treea9a990d28b42502b2a6fe7e5ab56128707b42f86 /drivers/misc
parent4b8960b492360c115f8214ec116f469338ac2734 (diff)
mei: move amthif specific release code to amithif
Move amthif code part into separate function mei_amthif_release. Also helper functions mei_clear_list and mei_clear_lists are moved along Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/mei/amthif.c114
-rw-r--r--drivers/misc/mei/main.c176
-rw-r--r--drivers/misc/mei/mei_dev.h2
3 files changed, 154 insertions, 138 deletions
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index 34d37a9c31a1..8f4373aa9e24 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -596,4 +596,118 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb)
596 wake_up_interruptible(&dev->iamthif_cl.wait); 596 wake_up_interruptible(&dev->iamthif_cl.wait);
597} 597}
598 598
599/**
600 * mei_clear_list - removes all callbacks associated with file
601 * from mei_cb_list
602 *
603 * @dev: device structure.
604 * @file: file structure
605 * @mei_cb_list: callbacks list
606 *
607 * mei_clear_list is called to clear resources associated with file
608 * when application calls close function or Ctrl-C was pressed
609 *
610 * returns true if callback removed from the list, false otherwise
611 */
612static bool mei_clear_list(struct mei_device *dev,
613 const struct file *file, struct list_head *mei_cb_list)
614{
615 struct mei_cl_cb *cb_pos = NULL;
616 struct mei_cl_cb *cb_next = NULL;
617 bool removed = false;
618
619 /* list all list member */
620 list_for_each_entry_safe(cb_pos, cb_next, mei_cb_list, list) {
621 /* check if list member associated with a file */
622 if (file == cb_pos->file_object) {
623 /* remove member from the list */
624 list_del(&cb_pos->list);
625 /* check if cb equal to current iamthif cb */
626 if (dev->iamthif_current_cb == cb_pos) {
627 dev->iamthif_current_cb = NULL;
628 /* send flow control to iamthif client */
629 mei_send_flow_control(dev, &dev->iamthif_cl);
630 }
631 /* free all allocated buffers */
632 mei_io_cb_free(cb_pos);
633 cb_pos = NULL;
634 removed = true;
635 }
636 }
637 return removed;
638}
639
640/**
641 * mei_clear_lists - removes all callbacks associated with file
642 *
643 * @dev: device structure
644 * @file: file structure
645 *
646 * mei_clear_lists is called to clear resources associated with file
647 * when application calls close function or Ctrl-C was pressed
648 *
649 * returns true if callback removed from the list, false otherwise
650 */
651static bool mei_clear_lists(struct mei_device *dev, struct file *file)
652{
653 bool removed = false;
654
655 /* remove callbacks associated with a file */
656 mei_clear_list(dev, file, &dev->amthif_cmd_list.list);
657 if (mei_clear_list(dev, file, &dev->amthif_rd_complete_list.list))
658 removed = true;
599 659
660 mei_clear_list(dev, file, &dev->ctrl_rd_list.list);
661
662 if (mei_clear_list(dev, file, &dev->ctrl_wr_list.list))
663 removed = true;
664
665 if (mei_clear_list(dev, file, &dev->write_waiting_list.list))
666 removed = true;
667
668 if (mei_clear_list(dev, file, &dev->write_list.list))
669 removed = true;
670
671 /* check if iamthif_current_cb not NULL */
672 if (dev->iamthif_current_cb && !removed) {
673 /* check file and iamthif current cb association */
674 if (dev->iamthif_current_cb->file_object == file) {
675 /* remove cb */
676 mei_io_cb_free(dev->iamthif_current_cb);
677 dev->iamthif_current_cb = NULL;
678 removed = true;
679 }
680 }
681 return removed;
682}
683
684/**
685* mei_amthif_release - the release function
686*
687* @inode: pointer to inode structure
688* @file: pointer to file structure
689*
690* returns 0 on success, <0 on error
691*/
692int mei_amthif_release(struct mei_device *dev, struct file *file)
693{
694 if (dev->open_handle_count > 0)
695 dev->open_handle_count--;
696
697 if (dev->iamthif_file_object == file &&
698 dev->iamthif_state != MEI_IAMTHIF_IDLE) {
699
700 dev_dbg(&dev->pdev->dev, "amthi canceled iamthif state %d\n",
701 dev->iamthif_state);
702 dev->iamthif_canceled = true;
703 if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) {
704 dev_dbg(&dev->pdev->dev, "run next amthi iamthif cb\n");
705 mei_amthif_run_next_cmd(dev);
706 }
707 }
708
709 if (mei_clear_lists(dev, file))
710 dev->iamthif_state = MEI_IAMTHIF_IDLE;
711
712 return 0;
713}
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 57bf96cf7ff9..43512e517952 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -90,90 +90,6 @@ static DEFINE_MUTEX(mei_mutex);
90 90
91 91
92/** 92/**
93 * mei_clear_list - removes all callbacks associated with file
94 * from mei_cb_list
95 *
96 * @dev: device structure.
97 * @file: file structure
98 * @mei_cb_list: callbacks list
99 *
100 * mei_clear_list is called to clear resources associated with file
101 * when application calls close function or Ctrl-C was pressed
102 *
103 * returns true if callback removed from the list, false otherwise
104 */
105static bool mei_clear_list(struct mei_device *dev,
106 const struct file *file, struct list_head *mei_cb_list)
107{
108 struct mei_cl_cb *cb_pos = NULL;
109 struct mei_cl_cb *cb_next = NULL;
110 bool removed = false;
111
112 /* list all list member */
113 list_for_each_entry_safe(cb_pos, cb_next, mei_cb_list, list) {
114 /* check if list member associated with a file */
115 if (file == cb_pos->file_object) {
116 /* remove member from the list */
117 list_del(&cb_pos->list);
118 /* check if cb equal to current iamthif cb */
119 if (dev->iamthif_current_cb == cb_pos) {
120 dev->iamthif_current_cb = NULL;
121 /* send flow control to iamthif client */
122 mei_send_flow_control(dev, &dev->iamthif_cl);
123 }
124 /* free all allocated buffers */
125 mei_io_cb_free(cb_pos);
126 cb_pos = NULL;
127 removed = true;
128 }
129 }
130 return removed;
131}
132
133/**
134 * mei_clear_lists - removes all callbacks associated with file
135 *
136 * @dev: device structure
137 * @file: file structure
138 *
139 * mei_clear_lists is called to clear resources associated with file
140 * when application calls close function or Ctrl-C was pressed
141 *
142 * returns true if callback removed from the list, false otherwise
143 */
144static bool mei_clear_lists(struct mei_device *dev, struct file *file)
145{
146 bool removed = false;
147
148 /* remove callbacks associated with a file */
149 mei_clear_list(dev, file, &dev->amthif_cmd_list.list);
150 if (mei_clear_list(dev, file, &dev->amthif_rd_complete_list.list))
151 removed = true;
152
153 mei_clear_list(dev, file, &dev->ctrl_rd_list.list);
154
155 if (mei_clear_list(dev, file, &dev->ctrl_wr_list.list))
156 removed = true;
157
158 if (mei_clear_list(dev, file, &dev->write_waiting_list.list))
159 removed = true;
160
161 if (mei_clear_list(dev, file, &dev->write_list.list))
162 removed = true;
163
164 /* check if iamthif_current_cb not NULL */
165 if (dev->iamthif_current_cb && !removed) {
166 /* check file and iamthif current cb association */
167 if (dev->iamthif_current_cb->file_object == file) {
168 /* remove cb */
169 mei_io_cb_free(dev->iamthif_current_cb);
170 dev->iamthif_current_cb = NULL;
171 removed = true;
172 }
173 }
174 return removed;
175}
176/**
177 * find_read_list_entry - find read list entry 93 * find_read_list_entry - find read list entry
178 * 94 *
179 * @dev: device structure 95 * @dev: device structure
@@ -289,67 +205,51 @@ static int mei_release(struct inode *inode, struct file *file)
289 dev = cl->dev; 205 dev = cl->dev;
290 206
291 mutex_lock(&dev->device_lock); 207 mutex_lock(&dev->device_lock);
292 if (cl != &dev->iamthif_cl) { 208 if (cl == &dev->iamthif_cl) {
293 if (cl->state == MEI_FILE_CONNECTED) { 209 rets = mei_amthif_release(dev, file);
294 cl->state = MEI_FILE_DISCONNECTING; 210 goto out;
295 dev_dbg(&dev->pdev->dev, 211 }
296 "disconnecting client host client = %d, " 212 if (cl->state == MEI_FILE_CONNECTED) {
297 "ME client = %d\n", 213 cl->state = MEI_FILE_DISCONNECTING;
298 cl->host_client_id, 214 dev_dbg(&dev->pdev->dev,
299 cl->me_client_id); 215 "disconnecting client host client = %d, "
300 rets = mei_disconnect_host_client(dev, cl); 216 "ME client = %d\n",
301 }
302 mei_cl_flush_queues(cl);
303 dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n",
304 cl->host_client_id, 217 cl->host_client_id,
305 cl->me_client_id); 218 cl->me_client_id);
219 rets = mei_disconnect_host_client(dev, cl);
220 }
221 mei_cl_flush_queues(cl);
222 dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n",
223 cl->host_client_id,
224 cl->me_client_id);
225
226 if (dev->open_handle_count > 0) {
227 clear_bit(cl->host_client_id, dev->host_clients_map);
228 dev->open_handle_count--;
229 }
230 mei_remove_client_from_file_list(dev, cl->host_client_id);
306 231
307 if (dev->open_handle_count > 0) { 232 /* free read cb */
308 clear_bit(cl->host_client_id, dev->host_clients_map); 233 cb = NULL;
309 dev->open_handle_count--; 234 if (cl->read_cb) {
310 } 235 cb = find_read_list_entry(dev, cl);
311 mei_remove_client_from_file_list(dev, cl->host_client_id); 236 /* Remove entry from read list */
312 237 if (cb)
313 /* free read cb */ 238 list_del(&cb->list);
314 cb = NULL;
315 if (cl->read_cb) {
316 cb = find_read_list_entry(dev, cl);
317 /* Remove entry from read list */
318 if (cb)
319 list_del(&cb->list);
320
321 cb = cl->read_cb;
322 cl->read_cb = NULL;
323 }
324
325 file->private_data = NULL;
326
327 if (cb) {
328 mei_io_cb_free(cb);
329 cb = NULL;
330 }
331 239
332 kfree(cl); 240 cb = cl->read_cb;
333 } else { 241 cl->read_cb = NULL;
334 if (dev->open_handle_count > 0) 242 }
335 dev->open_handle_count--;
336
337 if (dev->iamthif_file_object == file &&
338 dev->iamthif_state != MEI_IAMTHIF_IDLE) {
339
340 dev_dbg(&dev->pdev->dev, "amthi canceled iamthif state %d\n",
341 dev->iamthif_state);
342 dev->iamthif_canceled = true;
343 if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) {
344 dev_dbg(&dev->pdev->dev, "run next amthi iamthif cb\n");
345 mei_amthif_run_next_cmd(dev);
346 }
347 }
348 243
349 if (mei_clear_lists(dev, file)) 244 file->private_data = NULL;
350 dev->iamthif_state = MEI_IAMTHIF_IDLE;
351 245
246 if (cb) {
247 mei_io_cb_free(cb);
248 cb = NULL;
352 } 249 }
250
251 kfree(cl);
252out:
353 mutex_unlock(&dev->device_lock); 253 mutex_unlock(&dev->device_lock);
354 return rets; 254 return rets;
355} 255}
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 59e94c24690b..bdad35e7aa54 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -389,6 +389,8 @@ int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *priv_cb);
389int mei_amthif_read(struct mei_device *dev, struct file *file, 389int mei_amthif_read(struct mei_device *dev, struct file *file,
390 char __user *ubuf, size_t length, loff_t *offset); 390 char __user *ubuf, size_t length, loff_t *offset);
391 391
392int mei_amthif_release(struct mei_device *dev, struct file *file);
393
392struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev, 394struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev,
393 struct file *file); 395 struct file *file);
394 396