diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2015-02-10 03:39:45 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-03-01 22:37:00 -0500 |
commit | 928fa6664b362aad70c16f04483414f60743e15e (patch) | |
tree | f5238a6600c7b3921572c8efe41fd1a3499b4198 /drivers/misc | |
parent | 03b8d3419fdfc02d1984a0db51c8b74426e12605 (diff) |
mei: simplify io callback disposal
Simplify disposal of io callback by removing the callback
implicitly from its lookup list inside mei_io_cb_free
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.c | 24 | ||||
-rw-r--r-- | drivers/misc/mei/bus.c | 22 | ||||
-rw-r--r-- | drivers/misc/mei/client.c | 88 | ||||
-rw-r--r-- | drivers/misc/mei/hbm.c | 2 | ||||
-rw-r--r-- | drivers/misc/mei/interrupt.c | 3 | ||||
-rw-r--r-- | drivers/misc/mei/main.c | 29 |
6 files changed, 63 insertions, 105 deletions
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 3fdd22395b9f..7b6ed0bbfc9c 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c | |||
@@ -196,16 +196,16 @@ int mei_amthif_read(struct mei_device *dev, struct file *file, | |||
196 | if (time_after(jiffies, timeout)) { | 196 | if (time_after(jiffies, timeout)) { |
197 | dev_dbg(dev->dev, "amthif Time out\n"); | 197 | dev_dbg(dev->dev, "amthif Time out\n"); |
198 | /* 15 sec for the message has expired */ | 198 | /* 15 sec for the message has expired */ |
199 | list_del(&cb->list); | 199 | list_del_init(&cb->list); |
200 | rets = -ETIME; | 200 | rets = -ETIME; |
201 | goto free; | 201 | goto free; |
202 | } | 202 | } |
203 | /* if the whole message will fit remove it from the list */ | 203 | /* if the whole message will fit remove it from the list */ |
204 | if (cb->buf_idx >= *offset && length >= (cb->buf_idx - *offset)) | 204 | if (cb->buf_idx >= *offset && length >= (cb->buf_idx - *offset)) |
205 | list_del(&cb->list); | 205 | list_del_init(&cb->list); |
206 | else if (cb->buf_idx > 0 && cb->buf_idx <= *offset) { | 206 | else if (cb->buf_idx > 0 && cb->buf_idx <= *offset) { |
207 | /* end of the message has been reached */ | 207 | /* end of the message has been reached */ |
208 | list_del(&cb->list); | 208 | list_del_init(&cb->list); |
209 | rets = 0; | 209 | rets = 0; |
210 | goto free; | 210 | goto free; |
211 | } | 211 | } |
@@ -504,26 +504,22 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb) | |||
504 | static bool mei_clear_list(struct mei_device *dev, | 504 | static bool mei_clear_list(struct mei_device *dev, |
505 | const struct file *file, struct list_head *mei_cb_list) | 505 | const struct file *file, struct list_head *mei_cb_list) |
506 | { | 506 | { |
507 | struct mei_cl_cb *cb_pos = NULL; | 507 | struct mei_cl *cl = &dev->iamthif_cl; |
508 | struct mei_cl_cb *cb_next = NULL; | 508 | struct mei_cl_cb *cb, *next; |
509 | bool removed = false; | 509 | bool removed = false; |
510 | 510 | ||
511 | /* list all list member */ | 511 | /* list all list member */ |
512 | list_for_each_entry_safe(cb_pos, cb_next, mei_cb_list, list) { | 512 | list_for_each_entry_safe(cb, next, mei_cb_list, list) { |
513 | /* check if list member associated with a file */ | 513 | /* check if list member associated with a file */ |
514 | if (file == cb_pos->file_object) { | 514 | if (file == cb->file_object) { |
515 | /* remove member from the list */ | ||
516 | list_del(&cb_pos->list); | ||
517 | /* check if cb equal to current iamthif cb */ | 515 | /* check if cb equal to current iamthif cb */ |
518 | if (dev->iamthif_current_cb == cb_pos) { | 516 | if (dev->iamthif_current_cb == cb) { |
519 | dev->iamthif_current_cb = NULL; | 517 | dev->iamthif_current_cb = NULL; |
520 | /* send flow control to iamthif client */ | 518 | /* send flow control to iamthif client */ |
521 | mei_hbm_cl_flow_control_req(dev, | 519 | mei_hbm_cl_flow_control_req(dev, cl); |
522 | &dev->iamthif_cl); | ||
523 | } | 520 | } |
524 | /* free all allocated buffers */ | 521 | /* free all allocated buffers */ |
525 | mei_io_cb_free(cb_pos); | 522 | mei_io_cb_free(cb); |
526 | cb_pos = NULL; | ||
527 | removed = true; | 523 | removed = true; |
528 | } | 524 | } |
529 | } | 525 | } |
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 3e6ffed9402a..b5385372693d 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c | |||
@@ -311,13 +311,13 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length) | |||
311 | mutex_lock(&dev->device_lock); | 311 | mutex_lock(&dev->device_lock); |
312 | } | 312 | } |
313 | 313 | ||
314 | cb = cl->read_cb; | ||
315 | 314 | ||
316 | if (cl->reading_state != MEI_READ_COMPLETE) { | 315 | if (cl->reading_state != MEI_READ_COMPLETE) { |
317 | rets = 0; | 316 | rets = 0; |
318 | goto out; | 317 | goto out; |
319 | } | 318 | } |
320 | 319 | ||
320 | cb = cl->read_cb; | ||
321 | if (cb->status) { | 321 | if (cb->status) { |
322 | rets = cb->status; | 322 | rets = cb->status; |
323 | goto free; | 323 | goto free; |
@@ -329,8 +329,8 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length) | |||
329 | 329 | ||
330 | free: | 330 | free: |
331 | mei_io_cb_free(cb); | 331 | mei_io_cb_free(cb); |
332 | cl->reading_state = MEI_IDLE; | ||
333 | cl->read_cb = NULL; | 332 | cl->read_cb = NULL; |
333 | cl->reading_state = MEI_IDLE; | ||
334 | 334 | ||
335 | out: | 335 | out: |
336 | mutex_unlock(&dev->device_lock); | 336 | mutex_unlock(&dev->device_lock); |
@@ -486,23 +486,7 @@ int mei_cl_disable_device(struct mei_cl_device *device) | |||
486 | 486 | ||
487 | /* Flush queues and remove any pending read */ | 487 | /* Flush queues and remove any pending read */ |
488 | mei_cl_flush_queues(cl); | 488 | mei_cl_flush_queues(cl); |
489 | 489 | mei_io_cb_free(cl->read_cb); | |
490 | if (cl->read_cb) { | ||
491 | struct mei_cl_cb *cb = NULL; | ||
492 | |||
493 | cb = mei_cl_find_read_cb(cl); | ||
494 | /* Remove entry from read list */ | ||
495 | if (cb) | ||
496 | list_del(&cb->list); | ||
497 | |||
498 | cb = cl->read_cb; | ||
499 | cl->read_cb = NULL; | ||
500 | |||
501 | if (cb) { | ||
502 | mei_io_cb_free(cb); | ||
503 | cb = NULL; | ||
504 | } | ||
505 | } | ||
506 | 490 | ||
507 | device->event_cb = NULL; | 491 | device->event_cb = NULL; |
508 | 492 | ||
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index e263c0713a6d..624bf0182a50 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c | |||
@@ -321,6 +321,47 @@ static inline bool mei_cl_cmp_id(const struct mei_cl *cl1, | |||
321 | } | 321 | } |
322 | 322 | ||
323 | /** | 323 | /** |
324 | * mei_io_cb_free - free mei_cb_private related memory | ||
325 | * | ||
326 | * @cb: mei callback struct | ||
327 | */ | ||
328 | void mei_io_cb_free(struct mei_cl_cb *cb) | ||
329 | { | ||
330 | if (cb == NULL) | ||
331 | return; | ||
332 | |||
333 | list_del(&cb->list); | ||
334 | kfree(cb->buf.data); | ||
335 | kfree(cb); | ||
336 | } | ||
337 | |||
338 | /** | ||
339 | * mei_io_cb_init - allocate and initialize io callback | ||
340 | * | ||
341 | * @cl: mei client | ||
342 | * @type: operation type | ||
343 | * @fp: pointer to file structure | ||
344 | * | ||
345 | * Return: mei_cl_cb pointer or NULL; | ||
346 | */ | ||
347 | struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, enum mei_cb_file_ops type, | ||
348 | struct file *fp) | ||
349 | { | ||
350 | struct mei_cl_cb *cb; | ||
351 | |||
352 | cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); | ||
353 | if (!cb) | ||
354 | return NULL; | ||
355 | |||
356 | INIT_LIST_HEAD(&cb->list); | ||
357 | cb->file_object = fp; | ||
358 | cb->cl = cl; | ||
359 | cb->buf_idx = 0; | ||
360 | cb->fop_type = type; | ||
361 | return cb; | ||
362 | } | ||
363 | |||
364 | /** | ||
324 | * __mei_io_list_flush - removes and frees cbs belonging to cl. | 365 | * __mei_io_list_flush - removes and frees cbs belonging to cl. |
325 | * | 366 | * |
326 | * @list: an instance of our list structure | 367 | * @list: an instance of our list structure |
@@ -330,13 +371,12 @@ static inline bool mei_cl_cmp_id(const struct mei_cl *cl1, | |||
330 | static void __mei_io_list_flush(struct mei_cl_cb *list, | 371 | static void __mei_io_list_flush(struct mei_cl_cb *list, |
331 | struct mei_cl *cl, bool free) | 372 | struct mei_cl *cl, bool free) |
332 | { | 373 | { |
333 | struct mei_cl_cb *cb; | 374 | struct mei_cl_cb *cb, *next; |
334 | struct mei_cl_cb *next; | ||
335 | 375 | ||
336 | /* enable removing everything if no cl is specified */ | 376 | /* enable removing everything if no cl is specified */ |
337 | list_for_each_entry_safe(cb, next, &list->list, list) { | 377 | list_for_each_entry_safe(cb, next, &list->list, list) { |
338 | if (!cl || mei_cl_cmp_id(cl, cb->cl)) { | 378 | if (!cl || mei_cl_cmp_id(cl, cb->cl)) { |
339 | list_del(&cb->list); | 379 | list_del_init(&cb->list); |
340 | if (free) | 380 | if (free) |
341 | mei_io_cb_free(cb); | 381 | mei_io_cb_free(cb); |
342 | } | 382 | } |
@@ -354,7 +394,6 @@ void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl) | |||
354 | __mei_io_list_flush(list, cl, false); | 394 | __mei_io_list_flush(list, cl, false); |
355 | } | 395 | } |
356 | 396 | ||
357 | |||
358 | /** | 397 | /** |
359 | * mei_io_list_free - removes cb belonging to cl and free them | 398 | * mei_io_list_free - removes cb belonging to cl and free them |
360 | * | 399 | * |
@@ -367,47 +406,6 @@ static inline void mei_io_list_free(struct mei_cl_cb *list, struct mei_cl *cl) | |||
367 | } | 406 | } |
368 | 407 | ||
369 | /** | 408 | /** |
370 | * mei_io_cb_free - free mei_cb_private related memory | ||
371 | * | ||
372 | * @cb: mei callback struct | ||
373 | */ | ||
374 | void mei_io_cb_free(struct mei_cl_cb *cb) | ||
375 | { | ||
376 | if (cb == NULL) | ||
377 | return; | ||
378 | |||
379 | kfree(cb->buf.data); | ||
380 | kfree(cb); | ||
381 | } | ||
382 | |||
383 | /** | ||
384 | * mei_io_cb_init - allocate and initialize io callback | ||
385 | * | ||
386 | * @cl: mei client | ||
387 | * @type: operation type | ||
388 | * @fp: pointer to file structure | ||
389 | * | ||
390 | * Return: mei_cl_cb pointer or NULL; | ||
391 | */ | ||
392 | struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, enum mei_cb_file_ops type, | ||
393 | struct file *fp) | ||
394 | { | ||
395 | struct mei_cl_cb *cb; | ||
396 | |||
397 | cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); | ||
398 | if (!cb) | ||
399 | return NULL; | ||
400 | |||
401 | mei_io_list_init(cb); | ||
402 | |||
403 | cb->file_object = fp; | ||
404 | cb->cl = cl; | ||
405 | cb->buf_idx = 0; | ||
406 | cb->fop_type = type; | ||
407 | return cb; | ||
408 | } | ||
409 | |||
410 | /** | ||
411 | * mei_io_cb_alloc_buf - allocate callback buffer | 409 | * mei_io_cb_alloc_buf - allocate callback buffer |
412 | * | 410 | * |
413 | * @cb: io callback structure | 411 | * @cb: io callback structure |
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 2c581dcaf3b1..58da92565c5e 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c | |||
@@ -639,7 +639,7 @@ static void mei_hbm_cl_res(struct mei_device *dev, | |||
639 | continue; | 639 | continue; |
640 | 640 | ||
641 | if (mei_hbm_cl_addr_equal(cl, rs)) { | 641 | if (mei_hbm_cl_addr_equal(cl, rs)) { |
642 | list_del(&cb->list); | 642 | list_del_init(&cb->list); |
643 | break; | 643 | break; |
644 | } | 644 | } |
645 | } | 645 | } |
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 60469a0053bb..1e2f3c774853 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c | |||
@@ -202,7 +202,6 @@ static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb, | |||
202 | 202 | ||
203 | cl->state = MEI_FILE_DISCONNECTED; | 203 | cl->state = MEI_FILE_DISCONNECTED; |
204 | cl->status = 0; | 204 | cl->status = 0; |
205 | list_del(&cb->list); | ||
206 | mei_io_cb_free(cb); | 205 | mei_io_cb_free(cb); |
207 | 206 | ||
208 | return ret; | 207 | return ret; |
@@ -320,7 +319,7 @@ static int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb, | |||
320 | if (ret) { | 319 | if (ret) { |
321 | cl->status = ret; | 320 | cl->status = ret; |
322 | cb->buf_idx = 0; | 321 | cb->buf_idx = 0; |
323 | list_del(&cb->list); | 322 | list_del_init(&cb->list); |
324 | return ret; | 323 | return ret; |
325 | } | 324 | } |
326 | 325 | ||
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 10fc3a6a1574..c34853be963f 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c | |||
@@ -94,7 +94,6 @@ err_unlock: | |||
94 | static int mei_release(struct inode *inode, struct file *file) | 94 | static int mei_release(struct inode *inode, struct file *file) |
95 | { | 95 | { |
96 | struct mei_cl *cl = file->private_data; | 96 | struct mei_cl *cl = file->private_data; |
97 | struct mei_cl_cb *cb; | ||
98 | struct mei_device *dev; | 97 | struct mei_device *dev; |
99 | int rets = 0; | 98 | int rets = 0; |
100 | 99 | ||
@@ -118,23 +117,11 @@ static int mei_release(struct inode *inode, struct file *file) | |||
118 | 117 | ||
119 | mei_cl_unlink(cl); | 118 | mei_cl_unlink(cl); |
120 | 119 | ||
121 | 120 | mei_io_cb_free(cl->read_cb); | |
122 | /* free read cb */ | 121 | cl->read_cb = NULL; |
123 | cb = NULL; | ||
124 | if (cl->read_cb) { | ||
125 | cb = mei_cl_find_read_cb(cl); | ||
126 | /* Remove entry from read list */ | ||
127 | if (cb) | ||
128 | list_del(&cb->list); | ||
129 | |||
130 | cb = cl->read_cb; | ||
131 | cl->read_cb = NULL; | ||
132 | } | ||
133 | 122 | ||
134 | file->private_data = NULL; | 123 | file->private_data = NULL; |
135 | 124 | ||
136 | mei_io_cb_free(cb); | ||
137 | |||
138 | kfree(cl); | 125 | kfree(cl); |
139 | out: | 126 | out: |
140 | mutex_unlock(&dev->device_lock); | 127 | mutex_unlock(&dev->device_lock); |
@@ -156,7 +143,6 @@ static ssize_t mei_read(struct file *file, char __user *ubuf, | |||
156 | size_t length, loff_t *offset) | 143 | size_t length, loff_t *offset) |
157 | { | 144 | { |
158 | struct mei_cl *cl = file->private_data; | 145 | struct mei_cl *cl = file->private_data; |
159 | struct mei_cl_cb *cb_pos = NULL; | ||
160 | struct mei_cl_cb *cb = NULL; | 146 | struct mei_cl_cb *cb = NULL; |
161 | struct mei_device *dev; | 147 | struct mei_device *dev; |
162 | int rets; | 148 | int rets; |
@@ -279,13 +265,10 @@ copy_buffer: | |||
279 | goto out; | 265 | goto out; |
280 | 266 | ||
281 | free: | 267 | free: |
282 | cb_pos = mei_cl_find_read_cb(cl); | ||
283 | /* Remove entry from read list */ | ||
284 | if (cb_pos) | ||
285 | list_del(&cb_pos->list); | ||
286 | mei_io_cb_free(cb); | 268 | mei_io_cb_free(cb); |
287 | cl->reading_state = MEI_IDLE; | ||
288 | cl->read_cb = NULL; | 269 | cl->read_cb = NULL; |
270 | |||
271 | cl->reading_state = MEI_IDLE; | ||
289 | out: | 272 | out: |
290 | dev_dbg(dev->dev, "end mei read rets= %d\n", rets); | 273 | dev_dbg(dev->dev, "end mei read rets= %d\n", rets); |
291 | mutex_unlock(&dev->device_lock); | 274 | mutex_unlock(&dev->device_lock); |
@@ -355,7 +338,6 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, | |||
355 | if (time_after(jiffies, timeout) || | 338 | if (time_after(jiffies, timeout) || |
356 | cl->reading_state == MEI_READ_COMPLETE) { | 339 | cl->reading_state == MEI_READ_COMPLETE) { |
357 | *offset = 0; | 340 | *offset = 0; |
358 | list_del(&write_cb->list); | ||
359 | mei_io_cb_free(write_cb); | 341 | mei_io_cb_free(write_cb); |
360 | write_cb = NULL; | 342 | write_cb = NULL; |
361 | } | 343 | } |
@@ -367,11 +349,10 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, | |||
367 | *offset = 0; | 349 | *offset = 0; |
368 | write_cb = mei_cl_find_read_cb(cl); | 350 | write_cb = mei_cl_find_read_cb(cl); |
369 | if (write_cb) { | 351 | if (write_cb) { |
370 | list_del(&write_cb->list); | ||
371 | mei_io_cb_free(write_cb); | 352 | mei_io_cb_free(write_cb); |
372 | write_cb = NULL; | 353 | write_cb = NULL; |
373 | cl->reading_state = MEI_IDLE; | ||
374 | cl->read_cb = NULL; | 354 | cl->read_cb = NULL; |
355 | cl->reading_state = MEI_IDLE; | ||
375 | } | 356 | } |
376 | } else if (cl->reading_state == MEI_IDLE) | 357 | } else if (cl->reading_state == MEI_IDLE) |
377 | *offset = 0; | 358 | *offset = 0; |