2 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
3 * Copyright (C) 2017 Linaro Ltd.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 and
7 * only version 2 as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <linux/hash.h>
16 #include <linux/list.h>
17 #include <linux/slab.h>
18 #include <media/videobuf2-v4l2.h>
22 #include "hfi_helper.h"
24 #include "hfi_parser.h"
26 static void event_seq_changed(struct venus_core
*core
, struct venus_inst
*inst
,
27 struct hfi_msg_event_notify_pkt
*pkt
)
29 enum hfi_version ver
= core
->res
->hfi_version
;
30 struct hfi_event_data event
= {0};
31 int num_properties_changed
;
32 struct hfi_framesize
*frame_sz
;
33 struct hfi_profile_level
*profile_level
;
34 struct hfi_bit_depth
*pixel_depth
;
35 struct hfi_pic_struct
*pic_struct
;
36 struct hfi_colour_space
*colour_info
;
37 struct hfi_buffer_requirements
*bufreq
;
38 struct hfi_extradata_input_crop
*crop
;
42 inst
->error
= HFI_ERR_NONE
;
44 switch (pkt
->event_data1
) {
45 case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUF_RESOURCES
:
46 case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES
:
49 inst
->error
= HFI_ERR_SESSION_INVALID_PARAMETER
;
53 event
.event_type
= pkt
->event_data1
;
55 num_properties_changed
= pkt
->event_data2
;
56 if (!num_properties_changed
) {
57 inst
->error
= HFI_ERR_SESSION_INSUFFICIENT_RESOURCES
;
61 data_ptr
= (u8
*)&pkt
->ext_event_data
[0];
63 ptype
= *((u32
*)data_ptr
);
65 case HFI_PROPERTY_PARAM_FRAME_SIZE
:
66 data_ptr
+= sizeof(u32
);
67 frame_sz
= (struct hfi_framesize
*)data_ptr
;
68 event
.width
= frame_sz
->width
;
69 event
.height
= frame_sz
->height
;
70 data_ptr
+= sizeof(*frame_sz
);
72 case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT
:
73 data_ptr
+= sizeof(u32
);
74 profile_level
= (struct hfi_profile_level
*)data_ptr
;
75 event
.profile
= profile_level
->profile
;
76 event
.level
= profile_level
->level
;
77 data_ptr
+= sizeof(*profile_level
);
79 case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH
:
80 data_ptr
+= sizeof(u32
);
81 pixel_depth
= (struct hfi_bit_depth
*)data_ptr
;
82 event
.bit_depth
= pixel_depth
->bit_depth
;
83 data_ptr
+= sizeof(*pixel_depth
);
85 case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT
:
86 data_ptr
+= sizeof(u32
);
87 pic_struct
= (struct hfi_pic_struct
*)data_ptr
;
88 event
.pic_struct
= pic_struct
->progressive_only
;
89 data_ptr
+= sizeof(*pic_struct
);
91 case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE
:
92 data_ptr
+= sizeof(u32
);
93 colour_info
= (struct hfi_colour_space
*)data_ptr
;
94 event
.colour_space
= colour_info
->colour_space
;
95 data_ptr
+= sizeof(*colour_info
);
97 case HFI_PROPERTY_CONFIG_VDEC_ENTROPY
:
98 data_ptr
+= sizeof(u32
);
99 event
.entropy_mode
= *(u32
*)data_ptr
;
100 data_ptr
+= sizeof(u32
);
102 case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS
:
103 data_ptr
+= sizeof(u32
);
104 bufreq
= (struct hfi_buffer_requirements
*)data_ptr
;
105 event
.buf_count
= HFI_BUFREQ_COUNT_MIN(bufreq
, ver
);
106 data_ptr
+= sizeof(*bufreq
);
108 case HFI_INDEX_EXTRADATA_INPUT_CROP
:
109 data_ptr
+= sizeof(u32
);
110 crop
= (struct hfi_extradata_input_crop
*)data_ptr
;
111 event
.input_crop
.left
= crop
->left
;
112 event
.input_crop
.top
= crop
->top
;
113 event
.input_crop
.width
= crop
->width
;
114 event
.input_crop
.height
= crop
->height
;
115 data_ptr
+= sizeof(*crop
);
120 num_properties_changed
--;
121 } while (num_properties_changed
> 0);
124 inst
->ops
->event_notify(inst
, EVT_SYS_EVENT_CHANGE
, &event
);
127 static void event_release_buffer_ref(struct venus_core
*core
,
128 struct venus_inst
*inst
,
129 struct hfi_msg_event_notify_pkt
*pkt
)
131 struct hfi_event_data event
= {0};
132 struct hfi_msg_event_release_buffer_ref_pkt
*data
;
134 data
= (struct hfi_msg_event_release_buffer_ref_pkt
*)
137 event
.event_type
= HFI_EVENT_RELEASE_BUFFER_REFERENCE
;
138 event
.packet_buffer
= data
->packet_buffer
;
139 event
.extradata_buffer
= data
->extradata_buffer
;
140 event
.tag
= data
->output_tag
;
142 inst
->error
= HFI_ERR_NONE
;
143 inst
->ops
->event_notify(inst
, EVT_SYS_EVENT_CHANGE
, &event
);
146 static void event_sys_error(struct venus_core
*core
, u32 event
,
147 struct hfi_msg_event_notify_pkt
*pkt
)
151 "sys error (session id:%x, data1:%x, data2:%x)\n",
152 pkt
->shdr
.session_id
, pkt
->event_data1
,
155 core
->core_ops
->event_notify(core
, event
);
159 event_session_error(struct venus_core
*core
, struct venus_inst
*inst
,
160 struct hfi_msg_event_notify_pkt
*pkt
)
162 struct device
*dev
= core
->dev
;
164 dev_dbg(dev
, "session error: event id:%x, session id:%x\n",
165 pkt
->event_data1
, pkt
->shdr
.session_id
);
170 switch (pkt
->event_data1
) {
171 /* non fatal session errors */
172 case HFI_ERR_SESSION_INVALID_SCALE_FACTOR
:
173 case HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE
:
174 case HFI_ERR_SESSION_UNSUPPORTED_SETTING
:
175 case HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED
:
176 inst
->error
= HFI_ERR_NONE
;
179 dev_err(dev
, "session error: event id:%x (%x), session id:%x\n",
180 pkt
->event_data1
, pkt
->event_data2
,
181 pkt
->shdr
.session_id
);
183 inst
->error
= pkt
->event_data1
;
184 inst
->ops
->event_notify(inst
, EVT_SESSION_ERROR
, NULL
);
189 static void hfi_event_notify(struct venus_core
*core
, struct venus_inst
*inst
,
192 struct hfi_msg_event_notify_pkt
*pkt
= packet
;
197 switch (pkt
->event_id
) {
198 case HFI_EVENT_SYS_ERROR
:
199 event_sys_error(core
, EVT_SYS_ERROR
, pkt
);
201 case HFI_EVENT_SESSION_ERROR
:
202 event_session_error(core
, inst
, pkt
);
204 case HFI_EVENT_SESSION_SEQUENCE_CHANGED
:
205 event_seq_changed(core
, inst
, pkt
);
207 case HFI_EVENT_RELEASE_BUFFER_REFERENCE
:
208 event_release_buffer_ref(core
, inst
, pkt
);
210 case HFI_EVENT_SESSION_PROPERTY_CHANGED
:
217 static void hfi_sys_init_done(struct venus_core
*core
, struct venus_inst
*inst
,
220 struct hfi_msg_sys_init_done_pkt
*pkt
= packet
;
224 error
= pkt
->error_type
;
225 if (error
!= HFI_ERR_NONE
)
228 if (!pkt
->num_properties
) {
229 error
= HFI_ERR_SYS_INVALID_PARAMETER
;
233 rem_bytes
= pkt
->hdr
.size
- sizeof(*pkt
) + sizeof(u32
);
234 if (rem_bytes
<= 0) {
235 /* missing property data */
236 error
= HFI_ERR_SYS_INSUFFICIENT_RESOURCES
;
240 error
= hfi_parser(core
, inst
, pkt
->data
, rem_bytes
);
244 complete(&core
->done
);
248 sys_get_prop_image_version(struct device
*dev
,
249 struct hfi_msg_sys_property_info_pkt
*pkt
)
253 req_bytes
= pkt
->hdr
.size
- sizeof(*pkt
);
255 if (req_bytes
< 128 || !pkt
->data
[1] || pkt
->num_properties
> 1)
259 dev_dbg(dev
, "F/W version: %s\n", (u8
*)&pkt
->data
[1]);
262 static void hfi_sys_property_info(struct venus_core
*core
,
263 struct venus_inst
*inst
, void *packet
)
265 struct hfi_msg_sys_property_info_pkt
*pkt
= packet
;
266 struct device
*dev
= core
->dev
;
268 if (!pkt
->num_properties
) {
269 dev_dbg(dev
, "%s: no properties\n", __func__
);
273 switch (pkt
->data
[0]) {
274 case HFI_PROPERTY_SYS_IMAGE_VERSION
:
275 sys_get_prop_image_version(dev
, pkt
);
278 dev_dbg(dev
, "%s: unknown property data\n", __func__
);
283 static void hfi_sys_rel_resource_done(struct venus_core
*core
,
284 struct venus_inst
*inst
,
287 struct hfi_msg_sys_release_resource_done_pkt
*pkt
= packet
;
289 core
->error
= pkt
->error_type
;
290 complete(&core
->done
);
293 static void hfi_sys_ping_done(struct venus_core
*core
, struct venus_inst
*inst
,
296 struct hfi_msg_sys_ping_ack_pkt
*pkt
= packet
;
298 core
->error
= HFI_ERR_NONE
;
300 if (pkt
->client_data
!= 0xbeef)
301 core
->error
= HFI_ERR_SYS_FATAL
;
303 complete(&core
->done
);
306 static void hfi_sys_idle_done(struct venus_core
*core
, struct venus_inst
*inst
,
309 dev_dbg(core
->dev
, "sys idle\n");
312 static void hfi_sys_pc_prepare_done(struct venus_core
*core
,
313 struct venus_inst
*inst
, void *packet
)
315 struct hfi_msg_sys_pc_prep_done_pkt
*pkt
= packet
;
317 dev_dbg(core
->dev
, "pc prepare done (error %x)\n", pkt
->error_type
);
321 session_get_prop_profile_level(struct hfi_msg_session_property_info_pkt
*pkt
,
322 struct hfi_profile_level
*profile_level
)
324 struct hfi_profile_level
*hfi
;
327 req_bytes
= pkt
->shdr
.hdr
.size
- sizeof(*pkt
);
329 if (!req_bytes
|| req_bytes
% sizeof(struct hfi_profile_level
))
331 return HFI_ERR_SESSION_INVALID_PARAMETER
;
333 hfi
= (struct hfi_profile_level
*)&pkt
->data
[1];
334 profile_level
->profile
= hfi
->profile
;
335 profile_level
->level
= hfi
->level
;
341 session_get_prop_buf_req(struct hfi_msg_session_property_info_pkt
*pkt
,
342 struct hfi_buffer_requirements
*bufreq
)
344 struct hfi_buffer_requirements
*buf_req
;
346 unsigned int idx
= 0;
348 req_bytes
= pkt
->shdr
.hdr
.size
- sizeof(*pkt
);
350 if (!req_bytes
|| req_bytes
% sizeof(*buf_req
) || !pkt
->data
[1])
352 return HFI_ERR_SESSION_INVALID_PARAMETER
;
354 buf_req
= (struct hfi_buffer_requirements
*)&pkt
->data
[1];
356 return HFI_ERR_SESSION_INVALID_PARAMETER
;
359 memcpy(&bufreq
[idx
], buf_req
, sizeof(*bufreq
));
362 if (idx
> HFI_BUFFER_TYPE_MAX
)
363 return HFI_ERR_SESSION_INVALID_PARAMETER
;
365 req_bytes
-= sizeof(struct hfi_buffer_requirements
);
372 static void hfi_session_prop_info(struct venus_core
*core
,
373 struct venus_inst
*inst
, void *packet
)
375 struct hfi_msg_session_property_info_pkt
*pkt
= packet
;
376 struct device
*dev
= core
->dev
;
377 union hfi_get_property
*hprop
= &inst
->hprop
;
378 unsigned int error
= HFI_ERR_NONE
;
380 if (!pkt
->num_properties
) {
381 error
= HFI_ERR_SESSION_INVALID_PARAMETER
;
382 dev_err(dev
, "%s: no properties\n", __func__
);
386 switch (pkt
->data
[0]) {
387 case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS
:
388 memset(hprop
->bufreq
, 0, sizeof(hprop
->bufreq
));
389 error
= session_get_prop_buf_req(pkt
, hprop
->bufreq
);
391 case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT
:
392 memset(&hprop
->profile_level
, 0, sizeof(hprop
->profile_level
));
393 error
= session_get_prop_profile_level(pkt
,
394 &hprop
->profile_level
);
396 case HFI_PROPERTY_CONFIG_VDEC_ENTROPY
:
399 dev_dbg(dev
, "%s: unknown property id:%x\n", __func__
,
406 complete(&inst
->done
);
409 static void hfi_session_init_done(struct venus_core
*core
,
410 struct venus_inst
*inst
, void *packet
)
412 struct hfi_msg_session_init_done_pkt
*pkt
= packet
;
416 error
= pkt
->error_type
;
417 if (error
!= HFI_ERR_NONE
)
423 rem_bytes
= pkt
->shdr
.hdr
.size
- sizeof(*pkt
) + sizeof(u32
);
424 if (rem_bytes
<= 0) {
425 error
= HFI_ERR_SESSION_INSUFFICIENT_RESOURCES
;
429 error
= hfi_parser(core
, inst
, pkt
->data
, rem_bytes
);
432 complete(&inst
->done
);
435 static void hfi_session_load_res_done(struct venus_core
*core
,
436 struct venus_inst
*inst
, void *packet
)
438 struct hfi_msg_session_load_resources_done_pkt
*pkt
= packet
;
440 inst
->error
= pkt
->error_type
;
441 complete(&inst
->done
);
444 static void hfi_session_flush_done(struct venus_core
*core
,
445 struct venus_inst
*inst
, void *packet
)
447 struct hfi_msg_session_flush_done_pkt
*pkt
= packet
;
449 inst
->error
= pkt
->error_type
;
450 complete(&inst
->done
);
453 static void hfi_session_etb_done(struct venus_core
*core
,
454 struct venus_inst
*inst
, void *packet
)
456 struct hfi_msg_session_empty_buffer_done_pkt
*pkt
= packet
;
458 inst
->error
= pkt
->error_type
;
459 inst
->ops
->buf_done(inst
, HFI_BUFFER_INPUT
, pkt
->input_tag
,
460 pkt
->filled_len
, pkt
->offset
, 0, 0, 0);
463 static void hfi_session_ftb_done(struct venus_core
*core
,
464 struct venus_inst
*inst
, void *packet
)
466 u32 session_type
= inst
->session_type
;
467 u64 timestamp_us
= 0;
468 u32 timestamp_hi
= 0, timestamp_lo
= 0;
470 u32 flags
= 0, hfi_flags
= 0, offset
= 0, filled_len
= 0;
471 u32 pic_type
= 0, buffer_type
= 0, output_tag
= -1;
473 if (session_type
== VIDC_SESSION_TYPE_ENC
) {
474 struct hfi_msg_session_fbd_compressed_pkt
*pkt
= packet
;
476 timestamp_hi
= pkt
->time_stamp_hi
;
477 timestamp_lo
= pkt
->time_stamp_lo
;
478 hfi_flags
= pkt
->flags
;
479 offset
= pkt
->offset
;
480 filled_len
= pkt
->filled_len
;
481 pic_type
= pkt
->picture_type
;
482 output_tag
= pkt
->output_tag
;
483 buffer_type
= HFI_BUFFER_OUTPUT
;
485 error
= pkt
->error_type
;
486 } else if (session_type
== VIDC_SESSION_TYPE_DEC
) {
487 struct hfi_msg_session_fbd_uncompressed_plane0_pkt
*pkt
=
490 timestamp_hi
= pkt
->time_stamp_hi
;
491 timestamp_lo
= pkt
->time_stamp_lo
;
492 hfi_flags
= pkt
->flags
;
493 offset
= pkt
->offset
;
494 filled_len
= pkt
->filled_len
;
495 pic_type
= pkt
->picture_type
;
496 output_tag
= pkt
->output_tag
;
498 if (pkt
->stream_id
== 0)
499 buffer_type
= HFI_BUFFER_OUTPUT
;
500 else if (pkt
->stream_id
== 1)
501 buffer_type
= HFI_BUFFER_OUTPUT2
;
503 error
= pkt
->error_type
;
505 error
= HFI_ERR_SESSION_INVALID_PARAMETER
;
508 if (buffer_type
!= HFI_BUFFER_OUTPUT
&&
509 buffer_type
!= HFI_BUFFER_OUTPUT2
)
512 if (hfi_flags
& HFI_BUFFERFLAG_EOS
)
513 flags
|= V4L2_BUF_FLAG_LAST
;
516 case HFI_PICTURE_IDR
:
518 flags
|= V4L2_BUF_FLAG_KEYFRAME
;
521 flags
|= V4L2_BUF_FLAG_PFRAME
;
524 flags
|= V4L2_BUF_FLAG_BFRAME
;
526 case HFI_FRAME_NOTCODED
:
527 case HFI_UNUSED_PICT
:
533 if (!(hfi_flags
& HFI_BUFFERFLAG_TIMESTAMPINVALID
) && filled_len
) {
534 timestamp_us
= timestamp_hi
;
535 timestamp_us
= (timestamp_us
<< 32) | timestamp_lo
;
540 inst
->ops
->buf_done(inst
, buffer_type
, output_tag
, filled_len
,
541 offset
, flags
, hfi_flags
, timestamp_us
);
544 static void hfi_session_start_done(struct venus_core
*core
,
545 struct venus_inst
*inst
, void *packet
)
547 struct hfi_msg_session_start_done_pkt
*pkt
= packet
;
549 inst
->error
= pkt
->error_type
;
550 complete(&inst
->done
);
553 static void hfi_session_stop_done(struct venus_core
*core
,
554 struct venus_inst
*inst
, void *packet
)
556 struct hfi_msg_session_stop_done_pkt
*pkt
= packet
;
558 inst
->error
= pkt
->error_type
;
559 complete(&inst
->done
);
562 static void hfi_session_rel_res_done(struct venus_core
*core
,
563 struct venus_inst
*inst
, void *packet
)
565 struct hfi_msg_session_release_resources_done_pkt
*pkt
= packet
;
567 inst
->error
= pkt
->error_type
;
568 complete(&inst
->done
);
571 static void hfi_session_rel_buf_done(struct venus_core
*core
,
572 struct venus_inst
*inst
, void *packet
)
574 struct hfi_msg_session_release_buffers_done_pkt
*pkt
= packet
;
576 inst
->error
= pkt
->error_type
;
577 complete(&inst
->done
);
580 static void hfi_session_end_done(struct venus_core
*core
,
581 struct venus_inst
*inst
, void *packet
)
583 struct hfi_msg_session_end_done_pkt
*pkt
= packet
;
585 inst
->error
= pkt
->error_type
;
586 complete(&inst
->done
);
589 static void hfi_session_abort_done(struct venus_core
*core
,
590 struct venus_inst
*inst
, void *packet
)
592 struct hfi_msg_sys_session_abort_done_pkt
*pkt
= packet
;
594 inst
->error
= pkt
->error_type
;
595 complete(&inst
->done
);
598 static void hfi_session_get_seq_hdr_done(struct venus_core
*core
,
599 struct venus_inst
*inst
, void *packet
)
601 struct hfi_msg_session_get_sequence_hdr_done_pkt
*pkt
= packet
;
603 inst
->error
= pkt
->error_type
;
604 complete(&inst
->done
);
607 struct hfi_done_handler
{
611 void (*done
)(struct venus_core
*, struct venus_inst
*, void *);
615 static const struct hfi_done_handler handlers
[] = {
616 {.pkt
= HFI_MSG_EVENT_NOTIFY
,
617 .pkt_sz
= sizeof(struct hfi_msg_event_notify_pkt
),
618 .done
= hfi_event_notify
,
620 {.pkt
= HFI_MSG_SYS_INIT
,
621 .pkt_sz
= sizeof(struct hfi_msg_sys_init_done_pkt
),
622 .done
= hfi_sys_init_done
,
625 {.pkt
= HFI_MSG_SYS_PROPERTY_INFO
,
626 .pkt_sz
= sizeof(struct hfi_msg_sys_property_info_pkt
),
627 .done
= hfi_sys_property_info
,
630 {.pkt
= HFI_MSG_SYS_RELEASE_RESOURCE
,
631 .pkt_sz
= sizeof(struct hfi_msg_sys_release_resource_done_pkt
),
632 .done
= hfi_sys_rel_resource_done
,
635 {.pkt
= HFI_MSG_SYS_PING_ACK
,
636 .pkt_sz
= sizeof(struct hfi_msg_sys_ping_ack_pkt
),
637 .done
= hfi_sys_ping_done
,
640 {.pkt
= HFI_MSG_SYS_IDLE
,
641 .pkt_sz
= sizeof(struct hfi_msg_sys_idle_pkt
),
642 .done
= hfi_sys_idle_done
,
645 {.pkt
= HFI_MSG_SYS_PC_PREP
,
646 .pkt_sz
= sizeof(struct hfi_msg_sys_pc_prep_done_pkt
),
647 .done
= hfi_sys_pc_prepare_done
,
650 {.pkt
= HFI_MSG_SYS_SESSION_INIT
,
651 .pkt_sz
= sizeof(struct hfi_msg_session_init_done_pkt
),
652 .done
= hfi_session_init_done
,
654 {.pkt
= HFI_MSG_SYS_SESSION_END
,
655 .pkt_sz
= sizeof(struct hfi_msg_session_end_done_pkt
),
656 .done
= hfi_session_end_done
,
658 {.pkt
= HFI_MSG_SESSION_LOAD_RESOURCES
,
659 .pkt_sz
= sizeof(struct hfi_msg_session_load_resources_done_pkt
),
660 .done
= hfi_session_load_res_done
,
662 {.pkt
= HFI_MSG_SESSION_START
,
663 .pkt_sz
= sizeof(struct hfi_msg_session_start_done_pkt
),
664 .done
= hfi_session_start_done
,
666 {.pkt
= HFI_MSG_SESSION_STOP
,
667 .pkt_sz
= sizeof(struct hfi_msg_session_stop_done_pkt
),
668 .done
= hfi_session_stop_done
,
670 {.pkt
= HFI_MSG_SYS_SESSION_ABORT
,
671 .pkt_sz
= sizeof(struct hfi_msg_sys_session_abort_done_pkt
),
672 .done
= hfi_session_abort_done
,
674 {.pkt
= HFI_MSG_SESSION_EMPTY_BUFFER
,
675 .pkt_sz
= sizeof(struct hfi_msg_session_empty_buffer_done_pkt
),
676 .done
= hfi_session_etb_done
,
678 {.pkt
= HFI_MSG_SESSION_FILL_BUFFER
,
679 .pkt_sz
= sizeof(struct hfi_msg_session_fbd_uncompressed_plane0_pkt
),
680 .pkt_sz2
= sizeof(struct hfi_msg_session_fbd_compressed_pkt
),
681 .done
= hfi_session_ftb_done
,
683 {.pkt
= HFI_MSG_SESSION_FLUSH
,
684 .pkt_sz
= sizeof(struct hfi_msg_session_flush_done_pkt
),
685 .done
= hfi_session_flush_done
,
687 {.pkt
= HFI_MSG_SESSION_PROPERTY_INFO
,
688 .pkt_sz
= sizeof(struct hfi_msg_session_property_info_pkt
),
689 .done
= hfi_session_prop_info
,
691 {.pkt
= HFI_MSG_SESSION_RELEASE_RESOURCES
,
692 .pkt_sz
= sizeof(struct hfi_msg_session_release_resources_done_pkt
),
693 .done
= hfi_session_rel_res_done
,
695 {.pkt
= HFI_MSG_SESSION_GET_SEQUENCE_HEADER
,
696 .pkt_sz
= sizeof(struct hfi_msg_session_get_sequence_hdr_done_pkt
),
697 .done
= hfi_session_get_seq_hdr_done
,
699 {.pkt
= HFI_MSG_SESSION_RELEASE_BUFFERS
,
700 .pkt_sz
= sizeof(struct hfi_msg_session_release_buffers_done_pkt
),
701 .done
= hfi_session_rel_buf_done
,
705 void hfi_process_watchdog_timeout(struct venus_core
*core
)
707 event_sys_error(core
, EVT_SYS_WATCHDOG_TIMEOUT
, NULL
);
710 static struct venus_inst
*to_instance(struct venus_core
*core
, u32 session_id
)
712 struct venus_inst
*inst
;
714 mutex_lock(&core
->lock
);
715 list_for_each_entry(inst
, &core
->instances
, list
)
716 if (hash32_ptr(inst
) == session_id
) {
717 mutex_unlock(&core
->lock
);
720 mutex_unlock(&core
->lock
);
725 u32
hfi_process_msg_packet(struct venus_core
*core
, struct hfi_pkt_hdr
*hdr
)
727 const struct hfi_done_handler
*handler
;
728 struct device
*dev
= core
->dev
;
729 struct venus_inst
*inst
;
733 for (i
= 0; i
< ARRAY_SIZE(handlers
); i
++) {
734 handler
= &handlers
[i
];
735 if (handler
->pkt
!= hdr
->pkt_type
)
742 return hdr
->pkt_type
;
744 if (hdr
->size
&& hdr
->size
< handler
->pkt_sz
&&
745 hdr
->size
< handler
->pkt_sz2
) {
746 dev_err(dev
, "bad packet size (%d should be %d, pkt type:%x)\n",
747 hdr
->size
, handler
->pkt_sz
, hdr
->pkt_type
);
749 return hdr
->pkt_type
;
752 if (handler
->is_sys_pkt
) {
755 struct hfi_session_pkt
*pkt
;
757 pkt
= (struct hfi_session_pkt
*)hdr
;
758 inst
= to_instance(core
, pkt
->shdr
.session_id
);
761 dev_warn(dev
, "no valid instance(pkt session_id:%x, pkt:%x)\n",
762 pkt
->shdr
.session_id
,
763 handler
? handler
->pkt
: 0);
766 * Event of type HFI_EVENT_SYS_ERROR will not have any session
769 if (!inst
&& hdr
->pkt_type
!= HFI_MSG_EVENT_NOTIFY
) {
770 dev_err(dev
, "got invalid session id:%x\n",
771 pkt
->shdr
.session_id
);
772 goto invalid_session
;
776 handler
->done(core
, inst
, hdr
);
779 return hdr
->pkt_type
;