ARM: tizen_tm1_defconfig: Enable missing features related with CGROUPS
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / kernel / swap / wsp / wsp_msg.c
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15  *
16  * Copyright (C) Samsung Electronics, 2016
17  *
18  * 2015         Vyacheslav Cherkashin <v.cherkashin@samsung.com>
19  *
20  */
21
22
23 #include <linux/sched.h>
24 #include <linux/string.h>
25 #include <writer/swap_msg.h>
26 #include "wsp_msg.h"
27
28
29 /*
30  * MSG_WSP (payload):
31  * +-------------+----------+----------+
32  * | name        | type     | lenght   |
33  * +-------------+----------+----------+
34  * | PID         | int      |      4   |
35  * | wsp_id      | int      |      4   |
36  * | wsp_payload | variable | variable |
37  * +-------------+----------+----------+
38
39  * wsp_id:
40  *   - WSP_RES_LOAD_BEGIN = 0x0001
41  *   - WSP_RES_LOAD_END   = 0x0002
42  *   - WSP_RES_PROC_BEGIN = 0x0003
43  *   - WSP_RES_PROC_END   = 0x0004
44  *   - WSP_DRAW_BEGIN     = 0x0005
45  *   - WSP_DRAW_END       = 0x0006
46  *
47  * wsp_payload:
48  *
49  * 1. WSP_RES_LOAD_BEGIN:
50  *         +--------+--------+----------+
51  *         | name   | type   |  lenght  |
52  *         +--------+--------+----------+
53  *         | res_id | int    |     4    |
54  *         | path   | string | variable |
55  *         +--------+--------+----------+
56  *
57  * 2. WSP_RES_LOAD_END, WSP_RES_PROC_BEGIN, WSP_RES_PROC_END:
58  *         +--------+--------+----------+
59  *         | name   | type   |  lenght  |
60  *         +--------+--------+----------+
61  *         | res_id | int    |     4    |
62  *         +--------+--------+----------+
63  *
64  * 3. WSP_DRAW_BEGIN, WSP_DRAW_END:
65  *         no wsp_payload
66  */
67
68 static int pack_wsp_msg(void *data, size_t size, enum wsp_id id,
69                         u32 res_id, const char *path)
70 {
71         size_t len;
72         const size_t old_size = size;
73
74         /* write PID */
75         *(u32 *)data = (u32)current->tgid;
76         data += 4;
77         size -= 4;
78
79         /* write wsp_id */
80         *(u32 *)data = (u32)id;
81         data += 4;
82         size -= 4;
83
84         /* pack wsp_payload */
85         switch (id) {
86         case WSP_RES_LOAD_BEGIN:
87                 len = strlen(path) + 1;
88                 if (size < len + 4)
89                         return -ENOMEM;
90
91                 /* '+ 4' - skip space for res_id */
92                 memcpy(data + 4, path, len);
93                 size -= len;
94         case WSP_RES_LOAD_END:
95         case WSP_RES_PROC_BEGIN:
96         case WSP_RES_PROC_END:
97                 /* write res_id */
98                 *(u32 *)data = res_id;
99                 size -= 4;
100                 break;
101
102         case WSP_DRAW_BEGIN:
103         case WSP_DRAW_END:
104                 break;
105
106         default:
107                 printk(KERN_ERR "unknown wsp_id: id=%u\n", (unsigned)id);
108                 return -EINVAL;
109         }
110
111         return old_size - size;
112 }
113
114 void wsp_msg(enum wsp_id id, u32 res_id, const char *path)
115 {
116         int ret;
117         void *data;
118         size_t size;
119         struct swap_msg *m;
120
121         m = swap_msg_get(MSG_WSP);
122         data = swap_msg_payload(m);
123         size = swap_msg_size(m);
124         ret = pack_wsp_msg(data, size, id, res_id, path);
125         if (ret < 0) {
126                 printk(KERN_ERR "error MSG_WSP packing, ret=%d\n", ret);
127                 goto put_msg;
128         }
129
130         swap_msg_flush(m, ret);
131
132 put_msg:
133         swap_msg_put(m);
134 }