]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/dream/qdsp5/adsp_vfe_verify_cmd.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ecryptfs...
[net-next-2.6.git] / drivers / staging / dream / qdsp5 / adsp_vfe_verify_cmd.c
CommitLineData
caff4cae
IM
1/* arch/arm/mach-msm/qdsp5/adsp_vfe_verify_cmd.c
2 *
3 * Verification code for aDSP VFE packets from userspace.
4 *
5 * Copyright (c) 2008 QUALCOMM Incorporated
6 * Copyright (C) 2008 Google, Inc.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <mach/qdsp5/qdsp5vfecmdi.h>
20#include "adsp.h"
21
22static uint32_t size1_y, size2_y, size1_cbcr, size2_cbcr;
23static uint32_t af_size = 4228;
24static uint32_t awb_size = 8196;
25
26static inline int verify_cmd_op_ack(struct msm_adsp_module *module,
27 void *cmd_data, size_t cmd_size)
28{
29 vfe_cmd_op1_ack *cmd = (vfe_cmd_op1_ack *)cmd_data;
30 void **addr_y = (void **)&cmd->op1_buf_y_addr;
31 void **addr_cbcr = (void **)(&cmd->op1_buf_cbcr_addr);
32
33 if (cmd_size != sizeof(vfe_cmd_op1_ack))
34 return -1;
35 if ((*addr_y && adsp_pmem_fixup(module, addr_y, size1_y)) ||
36 (*addr_cbcr && adsp_pmem_fixup(module, addr_cbcr, size1_cbcr)))
37 return -1;
38 return 0;
39}
40
41static inline int verify_cmd_stats_autofocus_cfg(struct msm_adsp_module *module,
42 void *cmd_data, size_t cmd_size)
43{
44 int i;
45 vfe_cmd_stats_autofocus_cfg *cmd =
46 (vfe_cmd_stats_autofocus_cfg *)cmd_data;
47
48 if (cmd_size != sizeof(vfe_cmd_stats_autofocus_cfg))
49 return -1;
50
51 for (i = 0; i < 3; i++) {
52 void **addr = (void **)(&cmd->af_stats_op_buf[i]);
53 if (*addr && adsp_pmem_fixup(module, addr, af_size))
54 return -1;
55 }
56 return 0;
57}
58
59static inline int verify_cmd_stats_wb_exp_cfg(struct msm_adsp_module *module,
60 void *cmd_data, size_t cmd_size)
61{
62 vfe_cmd_stats_wb_exp_cfg *cmd =
63 (vfe_cmd_stats_wb_exp_cfg *)cmd_data;
64 int i;
65
66 if (cmd_size != sizeof(vfe_cmd_stats_wb_exp_cfg))
67 return -1;
68
69 for (i = 0; i < 3; i++) {
70 void **addr = (void **)(&cmd->wb_exp_stats_op_buf[i]);
71 if (*addr && adsp_pmem_fixup(module, addr, awb_size))
72 return -1;
73 }
74 return 0;
75}
76
77static inline int verify_cmd_stats_af_ack(struct msm_adsp_module *module,
78 void *cmd_data, size_t cmd_size)
79{
80 vfe_cmd_stats_af_ack *cmd = (vfe_cmd_stats_af_ack *)cmd_data;
81 void **addr = (void **)&cmd->af_stats_op_buf;
82
83 if (cmd_size != sizeof(vfe_cmd_stats_af_ack))
84 return -1;
85
86 if (*addr && adsp_pmem_fixup(module, addr, af_size))
87 return -1;
88 return 0;
89}
90
91static inline int verify_cmd_stats_wb_exp_ack(struct msm_adsp_module *module,
92 void *cmd_data, size_t cmd_size)
93{
94 vfe_cmd_stats_wb_exp_ack *cmd =
95 (vfe_cmd_stats_wb_exp_ack *)cmd_data;
96 void **addr = (void **)&cmd->wb_exp_stats_op_buf;
97
98 if (cmd_size != sizeof(vfe_cmd_stats_wb_exp_ack))
99 return -1;
100
101 if (*addr && adsp_pmem_fixup(module, addr, awb_size))
102 return -1;
103 return 0;
104}
105
106static int verify_vfe_command(struct msm_adsp_module *module,
107 void *cmd_data, size_t cmd_size)
108{
109 uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
110 switch (cmd_id) {
111 case VFE_CMD_OP1_ACK:
112 return verify_cmd_op_ack(module, cmd_data, cmd_size);
113 case VFE_CMD_OP2_ACK:
114 return verify_cmd_op_ack(module, cmd_data, cmd_size);
115 case VFE_CMD_STATS_AUTOFOCUS_CFG:
116 return verify_cmd_stats_autofocus_cfg(module, cmd_data,
117 cmd_size);
118 case VFE_CMD_STATS_WB_EXP_CFG:
119 return verify_cmd_stats_wb_exp_cfg(module, cmd_data, cmd_size);
120 case VFE_CMD_STATS_AF_ACK:
121 return verify_cmd_stats_af_ack(module, cmd_data, cmd_size);
122 case VFE_CMD_STATS_WB_EXP_ACK:
123 return verify_cmd_stats_wb_exp_ack(module, cmd_data, cmd_size);
124 default:
125 if (cmd_id > 29) {
126 printk(KERN_ERR "adsp: module %s: invalid VFE command id %d\n", module->name, cmd_id);
127 return -1;
128 }
129 }
130 return 0;
131}
132
133static int verify_vfe_command_scale(struct msm_adsp_module *module,
134 void *cmd_data, size_t cmd_size)
135{
136 uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
137 // FIXME: check the size
138 if (cmd_id > 1) {
139 printk(KERN_ERR "adsp: module %s: invalid VFE SCALE command id %d\n", module->name, cmd_id);
140 return -1;
141 }
142 return 0;
143}
144
145
146static uint32_t get_size(uint32_t hw)
147{
148 uint32_t height, width;
149 uint32_t height_mask = 0x3ffc;
150 uint32_t width_mask = 0x3ffc000;
151
152 height = (hw & height_mask) >> 2;
153 width = (hw & width_mask) >> 14 ;
154 return height * width;
155}
156
157static int verify_vfe_command_table(struct msm_adsp_module *module,
158 void *cmd_data, size_t cmd_size)
159{
160 uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
161 int i;
162
163 switch (cmd_id) {
164 case VFE_CMD_AXI_IP_CFG:
165 {
166 vfe_cmd_axi_ip_cfg *cmd = (vfe_cmd_axi_ip_cfg *)cmd_data;
167 uint32_t size;
168 if (cmd_size != sizeof(vfe_cmd_axi_ip_cfg)) {
169 printk(KERN_ERR "adsp: module %s: invalid VFE TABLE (VFE_CMD_AXI_IP_CFG) command size %d\n",
170 module->name, cmd_size);
171 return -1;
172 }
173 size = get_size(cmd->ip_cfg_part2);
174
175 for (i = 0; i < 8; i++) {
176 void **addr = (void **)
177 &cmd->ip_buf_addr[i];
178 if (*addr && adsp_pmem_fixup(module, addr, size))
179 return -1;
180 }
181 }
182 case VFE_CMD_AXI_OP_CFG:
183 {
184 vfe_cmd_axi_op_cfg *cmd = (vfe_cmd_axi_op_cfg *)cmd_data;
185 void **addr1_y, **addr2_y, **addr1_cbcr, **addr2_cbcr;
186
187 if (cmd_size != sizeof(vfe_cmd_axi_op_cfg)) {
188 printk(KERN_ERR "adsp: module %s: invalid VFE TABLE (VFE_CMD_AXI_OP_CFG) command size %d\n",
189 module->name, cmd_size);
190 return -1;
191 }
192 size1_y = get_size(cmd->op1_y_cfg_part2);
193 size1_cbcr = get_size(cmd->op1_cbcr_cfg_part2);
194 size2_y = get_size(cmd->op2_y_cfg_part2);
195 size2_cbcr = get_size(cmd->op2_cbcr_cfg_part2);
196 for (i = 0; i < 8; i++) {
197 addr1_y = (void **)(&cmd->op1_buf1_addr[2*i]);
198 addr1_cbcr = (void **)(&cmd->op1_buf1_addr[2*i+1]);
199 addr2_y = (void **)(&cmd->op2_buf1_addr[2*i]);
200 addr2_cbcr = (void **)(&cmd->op2_buf1_addr[2*i+1]);
201/*
202 printk("module %s: [%d] %p %p %p %p\n",
203 module->name, i,
204 *addr1_y, *addr1_cbcr, *addr2_y, *addr2_cbcr);
205*/
206 if ((*addr1_y && adsp_pmem_fixup(module, addr1_y, size1_y)) ||
207 (*addr1_cbcr && adsp_pmem_fixup(module, addr1_cbcr, size1_cbcr)) ||
208 (*addr2_y && adsp_pmem_fixup(module, addr2_y, size2_y)) ||
209 (*addr2_cbcr && adsp_pmem_fixup(module, addr2_cbcr, size2_cbcr)))
210 return -1;
211 }
212 }
213 default:
214 if (cmd_id > 4) {
215 printk(KERN_ERR "adsp: module %s: invalid VFE TABLE command id %d\n",
216 module->name, cmd_id);
217 return -1;
218 }
219 }
220 return 0;
221}
222
223int adsp_vfe_verify_cmd(struct msm_adsp_module *module,
224 unsigned int queue_id, void *cmd_data,
225 size_t cmd_size)
226{
227 switch (queue_id) {
228 case QDSP_vfeCommandQueue:
229 return verify_vfe_command(module, cmd_data, cmd_size);
230 case QDSP_vfeCommandScaleQueue:
231 return verify_vfe_command_scale(module, cmd_data, cmd_size);
232 case QDSP_vfeCommandTableQueue:
233 return verify_vfe_command_table(module, cmd_data, cmd_size);
234 default:
235 printk(KERN_ERR "adsp: module %s: unknown queue id %d\n",
236 module->name, queue_id);
237 return -1;
238 }
239}