aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/uwb/wlp/messages.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/uwb/wlp/messages.c')
-rw-r--r--drivers/uwb/wlp/messages.c106
1 files changed, 61 insertions, 45 deletions
diff --git a/drivers/uwb/wlp/messages.c b/drivers/uwb/wlp/messages.c
index aa42fcee4c4f..75164866c2d8 100644
--- a/drivers/uwb/wlp/messages.c
+++ b/drivers/uwb/wlp/messages.c
@@ -259,6 +259,63 @@ out:
259} 259}
260 260
261 261
262static ssize_t wlp_get_attribute(struct wlp *wlp, u16 type_code,
263 struct wlp_attr_hdr *attr_hdr, void *value, ssize_t value_len,
264 ssize_t buflen)
265{
266 struct device *dev = &wlp->rc->uwb_dev.dev;
267 ssize_t attr_len = sizeof(*attr_hdr) + value_len;
268 if (buflen < 0)
269 return -EINVAL;
270 if (buflen < attr_len) {
271 dev_err(dev, "WLP: Not enough space in buffer to parse"
272 " attribute field. Need %d, received %zu\n",
273 (int)attr_len, buflen);
274 return -EIO;
275 }
276 if (wlp_check_attr_hdr(wlp, attr_hdr, type_code, value_len) < 0) {
277 dev_err(dev, "WLP: Header verification failed. \n");
278 return -EINVAL;
279 }
280 memcpy(value, (void *)attr_hdr + sizeof(*attr_hdr), value_len);
281 return attr_len;
282}
283
284static ssize_t wlp_vget_attribute(struct wlp *wlp, u16 type_code,
285 struct wlp_attr_hdr *attr_hdr, void *value, ssize_t max_value_len,
286 ssize_t buflen)
287{
288 struct device *dev = &wlp->rc->uwb_dev.dev;
289 size_t len;
290 if (buflen < 0)
291 return -EINVAL;
292 if (buflen < sizeof(*attr_hdr)) {
293 dev_err(dev, "WLP: Not enough space in buffer to parse"
294 " header.\n");
295 return -EIO;
296 }
297 if (le16_to_cpu(attr_hdr->type) != type_code) {
298 dev_err(dev, "WLP: Unexpected attribute type. Got %u, "
299 "expected %u.\n", le16_to_cpu(attr_hdr->type),
300 type_code);
301 return -EINVAL;
302 }
303 len = le16_to_cpu(attr_hdr->length);
304 if (len > max_value_len) {
305 dev_err(dev, "WLP: Attribute larger than maximum "
306 "allowed. Received %zu, max is %d.\n", len,
307 (int)max_value_len);
308 return -EFBIG;
309 }
310 if (buflen < sizeof(*attr_hdr) + len) {
311 dev_err(dev, "WLP: Not enough space in buffer to parse "
312 "variable data.\n");
313 return -EIO;
314 }
315 memcpy(value, (void *)attr_hdr + sizeof(*attr_hdr), len);
316 return sizeof(*attr_hdr) + len;
317}
318
262/** 319/**
263 * Get value of attribute from fixed size attribute field. 320 * Get value of attribute from fixed size attribute field.
264 * 321 *
@@ -274,22 +331,8 @@ out:
274ssize_t wlp_get_##name(struct wlp *wlp, struct wlp_attr_##name *attr, \ 331ssize_t wlp_get_##name(struct wlp *wlp, struct wlp_attr_##name *attr, \
275 type *value, ssize_t buflen) \ 332 type *value, ssize_t buflen) \
276{ \ 333{ \
277 struct device *dev = &wlp->rc->uwb_dev.dev; \ 334 return wlp_get_attribute(wlp, (type_code), &attr->hdr, \
278 if (buflen < 0) \ 335 value, sizeof(*value), buflen); \
279 return -EINVAL; \
280 if (buflen < sizeof(*attr)) { \
281 dev_err(dev, "WLP: Not enough space in buffer to parse" \
282 " attribute field. Need %d, received %zu\n", \
283 (int)sizeof(*attr), buflen); \
284 return -EIO; \
285 } \
286 if (wlp_check_attr_hdr(wlp, &attr->hdr, type_code, \
287 sizeof(attr->name)) < 0) { \
288 dev_err(dev, "WLP: Header verification failed. \n"); \
289 return -EINVAL; \
290 } \
291 *value = attr->name; \
292 return sizeof(*attr); \
293} 336}
294 337
295#define wlp_get_sparse(type, type_code, name) \ 338#define wlp_get_sparse(type, type_code, name) \
@@ -313,35 +356,8 @@ static ssize_t wlp_get_##name(struct wlp *wlp, \
313 struct wlp_attr_##name *attr, \ 356 struct wlp_attr_##name *attr, \
314 type_val *value, ssize_t buflen) \ 357 type_val *value, ssize_t buflen) \
315{ \ 358{ \
316 struct device *dev = &wlp->rc->uwb_dev.dev; \ 359 return wlp_vget_attribute(wlp, (type_code), &attr->hdr, \
317 size_t len; \ 360 value, (max), buflen); \
318 if (buflen < 0) \
319 return -EINVAL; \
320 if (buflen < sizeof(*attr)) { \
321 dev_err(dev, "WLP: Not enough space in buffer to parse" \
322 " header.\n"); \
323 return -EIO; \
324 } \
325 if (le16_to_cpu(attr->hdr.type) != type_code) { \
326 dev_err(dev, "WLP: Unexpected attribute type. Got %u, " \
327 "expected %u.\n", le16_to_cpu(attr->hdr.type), \
328 type_code); \
329 return -EINVAL; \
330 } \
331 len = le16_to_cpu(attr->hdr.length); \
332 if (len > max) { \
333 dev_err(dev, "WLP: Attribute larger than maximum " \
334 "allowed. Received %zu, max is %d.\n", len, \
335 (int)max); \
336 return -EFBIG; \
337 } \
338 if (buflen < sizeof(*attr) + len) { \
339 dev_err(dev, "WLP: Not enough space in buffer to parse "\
340 "variable data.\n"); \
341 return -EIO; \
342 } \
343 memcpy(value, (void *) attr + sizeof(*attr), len); \
344 return sizeof(*attr) + len; \
345} 361}
346 362
347wlp_get(u8, WLP_ATTR_WLP_VER, version) 363wlp_get(u8, WLP_ATTR_WLP_VER, version)