mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-07 04:12:04 -04:00
Merge 895cfcbb7a on remote branch
Change-Id: I5b8da1cd03875baabbf5d4efbf5fb0864637a52f
This commit is contained in:
commit
4605f524fd
24 changed files with 705 additions and 82 deletions
|
|
@ -265,6 +265,71 @@ Description: Specific uncompressed frame descriptors
|
|||
bmCapabilities - still image support, fixed frame-rate
|
||||
support
|
||||
|
||||
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/framebased
|
||||
Date: Oct 2025
|
||||
KernelVersion: 5.4
|
||||
Description: Framebased format descriptors
|
||||
|
||||
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/framebased/name
|
||||
Date: Oct 2025
|
||||
KernelVersion: 5.4
|
||||
Description: Specific framebased format descriptors
|
||||
|
||||
================== =======================================
|
||||
bFormatIndex unique id for this format descriptor;
|
||||
only defined after parent header is
|
||||
linked into the streaming class;
|
||||
read-only
|
||||
bmaControls this format's data for bmaControls in
|
||||
the streaming header
|
||||
bmInterlaceFlags specifies interlace information,
|
||||
read-only
|
||||
bAspectRatioY the X dimension of the picture aspect
|
||||
ratio, read-only
|
||||
bAspectRatioX the Y dimension of the picture aspect
|
||||
ratio, read-only
|
||||
bDefaultFrameIndex optimum frame index for this stream
|
||||
bBitsPerPixel number of bits per pixel used to
|
||||
specify color in the decoded video
|
||||
frame
|
||||
guidFormat globally unique id used to identify
|
||||
stream-encoding format
|
||||
================== =======================================
|
||||
|
||||
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/framebased/name/name
|
||||
Date: Sept 2024
|
||||
KernelVersion: 5.15
|
||||
Description: Specific framebased frame descriptors
|
||||
|
||||
========================= =====================================
|
||||
bFrameIndex unique id for this framedescriptor;
|
||||
only defined after parent format is
|
||||
linked into the streaming header;
|
||||
read-only
|
||||
dwFrameInterval indicates how frame interval can be
|
||||
programmed; a number of values
|
||||
separated by newline can be specified
|
||||
dwDefaultFrameInterval the frame interval the device would
|
||||
like to use as default
|
||||
dwBytesPerLine Specifies the number of bytes per line
|
||||
|
||||
of video for packed fixed frame size
|
||||
formats, allowing the receiver to
|
||||
perform stride alignment of the video.
|
||||
If the bVariableSize value (above) is
|
||||
TRUE (1), or if the format does not
|
||||
permit such alignment, this value shall
|
||||
be set to zero (0).
|
||||
dwMaxBitRate the maximum bit rate at the shortest
|
||||
frame interval in bps
|
||||
dwMinBitRate the minimum bit rate at the longest
|
||||
frame interval in bps
|
||||
wHeight height of decoded bitmap frame in px
|
||||
wWidth width of decoded bitmam frame in px
|
||||
bmCapabilities still image support, fixed frame-rate
|
||||
support
|
||||
========================= =====================================
|
||||
|
||||
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/header
|
||||
Date: Dec 2014
|
||||
KernelVersion: 4.0
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/clk/qcom.h>
|
||||
|
|
@ -2523,6 +2524,7 @@ int a6xx_perfcounter_update(struct adreno_device *adreno_dev,
|
|||
struct cpu_gpu_lock *lock = ptr;
|
||||
u32 *data = ptr + sizeof(*lock);
|
||||
int i, offset = 0;
|
||||
u32 pending_pairs = 2; /* No of pairs to add: <select,value> and <cntl,1> */
|
||||
|
||||
if (cpu_gpu_lock(lock)) {
|
||||
cpu_gpu_unlock(lock);
|
||||
|
|
@ -2546,6 +2548,13 @@ int a6xx_perfcounter_update(struct adreno_device *adreno_dev,
|
|||
offset += 2;
|
||||
}
|
||||
|
||||
/* Ensure there is enough space in the reglist buffer for new pairs */
|
||||
if ((offset + (pending_pairs * 2)) >=
|
||||
(adreno_dev->pwrup_reglist->size / sizeof(u32))) {
|
||||
cpu_gpu_unlock(lock);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
/*
|
||||
* For all targets A6XX_RBBM_PERFCTR_CNTL needs to be the last entry,
|
||||
* so overwrite the existing A6XX_RBBM_PERFCNTL_CTRL and add it back to
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
|
|
@ -135,6 +135,8 @@ static int msm_cvp_initialize_core(struct platform_device *pdev,
|
|||
INIT_LIST_HEAD(&core->instances);
|
||||
mutex_init(&core->lock);
|
||||
mutex_init(&core->clk_lock);
|
||||
mutex_init(&core->idr_mtx);
|
||||
idr_init(&core->sess_idr);
|
||||
|
||||
core->state = CVP_CORE_UNINIT;
|
||||
for (i = SYS_MSG_INDEX(SYS_MSG_START);
|
||||
|
|
@ -506,6 +508,8 @@ static int msm_cvp_remove(struct platform_device *pdev)
|
|||
msm_cvp_free_platform_resources(&core->resources);
|
||||
sysfs_remove_group(&pdev->dev.kobj, &msm_cvp_core_attr_group);
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
idr_destroy(&core->sess_idr);
|
||||
mutex_destroy(&core->idr_mtx);
|
||||
mutex_destroy(&core->lock);
|
||||
mutex_destroy(&core->clk_lock);
|
||||
kfree(core);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <asm/memory.h>
|
||||
|
|
@ -29,6 +30,7 @@
|
|||
#include "cvp_hfi_helper.h"
|
||||
#include "cvp_hfi_io.h"
|
||||
#include "msm_cvp_dsp.h"
|
||||
#include "msm_cvp.h"
|
||||
|
||||
#define FIRMWARE_SIZE 0X00A00000
|
||||
#define REG_ADDR_OFFSET_BITMASK 0x000FFFFF
|
||||
|
|
@ -469,6 +471,7 @@ static int __dsp_suspend(struct iris_hfi_device *device, bool force, u32 flags)
|
|||
{
|
||||
int rc;
|
||||
struct cvp_hal_session *temp;
|
||||
struct msm_cvp_inst *inst = NULL;
|
||||
|
||||
if (msm_cvp_dsp_disable)
|
||||
return 0;
|
||||
|
|
@ -480,9 +483,10 @@ static int __dsp_suspend(struct iris_hfi_device *device, bool force, u32 flags)
|
|||
|
||||
/* don't suspend if cvp session is not paused */
|
||||
if (!(temp->flags & SESSION_PAUSE)) {
|
||||
inst = (struct msm_cvp_inst *)temp->session_id;
|
||||
dprintk(CVP_DSP,
|
||||
"%s: cvp session %x not paused\n",
|
||||
__func__, hash32_ptr(temp));
|
||||
__func__, inst->sess_id);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
|
@ -2224,12 +2228,17 @@ static void __session_clean(struct cvp_hal_session *session)
|
|||
{
|
||||
struct cvp_hal_session *temp, *next;
|
||||
struct iris_hfi_device *device;
|
||||
struct msm_cvp_core *core = NULL;
|
||||
struct msm_cvp_inst *inst = NULL;
|
||||
void *tmp = NULL;
|
||||
|
||||
if (!session || !session->device) {
|
||||
dprintk(CVP_WARN, "%s: invalid params\n", __func__);
|
||||
return;
|
||||
}
|
||||
device = session->device;
|
||||
core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
|
||||
inst = (struct msm_cvp_inst *) session->session_id;
|
||||
dprintk(CVP_SESS, "deleted the session: %pK\n", session);
|
||||
/*
|
||||
* session might have been removed from the device list in
|
||||
|
|
@ -2241,6 +2250,13 @@ static void __session_clean(struct cvp_hal_session *session)
|
|||
break;
|
||||
}
|
||||
}
|
||||
/* Remove the IDR id assigned to this session */
|
||||
mutex_lock(&core->idr_mtx);
|
||||
tmp = idr_remove(&core->sess_idr, inst->sess_id);
|
||||
if (tmp != session)
|
||||
dprintk(CVP_WARN, "%s: session\n", __func__);
|
||||
mutex_unlock(&core->idr_mtx);
|
||||
|
||||
/* Poison the session handle with zeros */
|
||||
*session = (struct cvp_hal_session){ {0} };
|
||||
kfree(session);
|
||||
|
|
@ -2278,6 +2294,9 @@ static int iris_hfi_session_init(void *device, void *session_id,
|
|||
struct cvp_hfi_cmd_sys_session_init_packet pkt;
|
||||
struct iris_hfi_device *dev;
|
||||
struct cvp_hal_session *s;
|
||||
struct msm_cvp_core *core;
|
||||
struct msm_cvp_inst *inst;
|
||||
int id = 0;
|
||||
|
||||
if (!device || !new_session) {
|
||||
dprintk(CVP_ERR, "%s - invalid input\n", __func__);
|
||||
|
|
@ -2285,6 +2304,8 @@ static int iris_hfi_session_init(void *device, void *session_id,
|
|||
}
|
||||
|
||||
dev = device;
|
||||
core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
|
||||
inst = session_id;
|
||||
mutex_lock(&dev->lock);
|
||||
|
||||
s = kzalloc(sizeof(*s), GFP_KERNEL);
|
||||
|
|
@ -2295,15 +2316,35 @@ static int iris_hfi_session_init(void *device, void *session_id,
|
|||
|
||||
s->session_id = session_id;
|
||||
s->device = dev;
|
||||
|
||||
mutex_lock(&core->idr_mtx);
|
||||
idr_preload(GFP_KERNEL);
|
||||
|
||||
/* Need to think if we can use core->lock or dev->lock or need a
|
||||
* different new lock for this?
|
||||
*/
|
||||
id = idr_alloc(&core->sess_idr, (void *)s, 0x7FFF0000, INT_MAX, GFP_NOWAIT);
|
||||
idr_preload_end();
|
||||
mutex_unlock(&core->idr_mtx);
|
||||
if (id < 0) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: idr allocation failed for session %pK of inst %pK\n",
|
||||
__func__, s, session_id);
|
||||
goto err_session_init_fail;
|
||||
}
|
||||
|
||||
dprintk(CVP_SESS,
|
||||
"%s: inst %pK, session %pK\n", __func__, session_id, s);
|
||||
"%s: inst %pK, session %pK, idr_id = 0x%x\n", __func__, session_id, s, id);
|
||||
|
||||
list_add_tail(&s->list, &dev->sess_head);
|
||||
|
||||
__set_default_sys_properties(device);
|
||||
|
||||
inst->sess_id = id;
|
||||
|
||||
if (call_hfi_pkt_op(dev, session_init, &pkt, s)) {
|
||||
dprintk(CVP_ERR, "session_init: failed to create packet\n");
|
||||
inst->sess_id = 0x0000DEAD;
|
||||
goto err_session_init_fail;
|
||||
}
|
||||
|
||||
|
|
@ -2317,6 +2358,7 @@ static int iris_hfi_session_init(void *device, void *session_id,
|
|||
err_session_init_fail:
|
||||
if (s)
|
||||
__session_clean(s);
|
||||
inst->sess_id = 0;
|
||||
*new_session = NULL;
|
||||
mutex_unlock(&dev->lock);
|
||||
return -EINVAL;
|
||||
|
|
@ -2878,9 +2920,11 @@ static struct cvp_hal_session *__get_session(struct iris_hfi_device *device,
|
|||
u32 session_id)
|
||||
{
|
||||
struct cvp_hal_session *temp = NULL;
|
||||
struct msm_cvp_inst *inst = NULL;
|
||||
|
||||
list_for_each_entry(temp, &device->sess_head, list) {
|
||||
if (session_id == hash32_ptr(temp))
|
||||
inst = (struct msm_cvp_inst *)temp->session_id;
|
||||
if (session_id == inst->sess_id)
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
|
@ -3059,6 +3103,7 @@ static int __response_handler(struct iris_hfi_device *device)
|
|||
/* Process the packet types that we're interested in */
|
||||
process_system_msg(info, device, raw_packet);
|
||||
|
||||
/* This session_id is a double pointer to the idr_id of session */
|
||||
session_id = get_session_id(info);
|
||||
/*
|
||||
* hfi_process_msg_packet provides a session_id that's a hashed
|
||||
|
|
@ -3070,11 +3115,6 @@ static int __response_handler(struct iris_hfi_device *device)
|
|||
if (session_id) {
|
||||
struct cvp_hal_session *session = NULL;
|
||||
|
||||
if (upper_32_bits((uintptr_t)*session_id) != 0) {
|
||||
dprintk(CVP_ERR,
|
||||
"Upper 32-bits != 0 for sess_id=%pK\n",
|
||||
*session_id);
|
||||
}
|
||||
session = __get_session(device,
|
||||
(u32)(uintptr_t)*session_id);
|
||||
if (!session) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include "hfi_packetization.h"
|
||||
|
|
@ -208,7 +209,7 @@ inline int cvp_create_pkt_cmd_sys_session_init(
|
|||
|
||||
pkt->size = sizeof(struct cvp_hfi_cmd_sys_session_init_packet);
|
||||
pkt->packet_type = HFI_CMD_SYS_SESSION_INIT;
|
||||
pkt->session_id = hash32_ptr(session);
|
||||
pkt->session_id = inst->sess_id;
|
||||
pkt->session_type = inst->prop.type;
|
||||
pkt->session_kmask = inst->prop.kernel_mask;
|
||||
pkt->session_prio = inst->prop.priority;
|
||||
|
|
@ -266,13 +267,14 @@ int cvp_create_pkt_cmd_session_cmd(struct cvp_hal_session_cmd_pkt *pkt,
|
|||
int pkt_type, struct cvp_hal_session *session)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_cvp_inst *inst = session->session_id;
|
||||
|
||||
if (!pkt)
|
||||
return -EINVAL;
|
||||
|
||||
pkt->size = sizeof(struct cvp_hal_session_cmd_pkt);
|
||||
pkt->packet_type = pkt_type;
|
||||
pkt->session_id = hash32_ptr(session);
|
||||
pkt->session_id = inst->sess_id;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -305,13 +307,14 @@ int cvp_create_pkt_cmd_session_set_buffers(
|
|||
{
|
||||
int rc = 0;
|
||||
struct cvp_hfi_cmd_session_set_buffers_packet *pkt;
|
||||
struct msm_cvp_inst *inst = session->session_id;
|
||||
|
||||
if (!cmd || !session)
|
||||
if (!cmd || !session || !inst)
|
||||
return -EINVAL;
|
||||
|
||||
pkt = (struct cvp_hfi_cmd_session_set_buffers_packet *)cmd;
|
||||
pkt->packet_type = HFI_CMD_SESSION_CVP_SET_BUFFERS;
|
||||
pkt->session_id = hash32_ptr(session);
|
||||
pkt->session_id = inst->sess_id;
|
||||
pkt->buf_type.iova = iova;
|
||||
pkt->buf_type.size = size;
|
||||
pkt->size = sizeof(struct cvp_hfi_cmd_session_set_buffers_packet);
|
||||
|
|
@ -324,13 +327,14 @@ int cvp_create_pkt_cmd_session_release_buffers(
|
|||
struct cvp_hal_session *session)
|
||||
{
|
||||
struct cvp_session_release_buffers_packet *pkt;
|
||||
struct msm_cvp_inst *inst = session->session_id;
|
||||
|
||||
if (!cmd || !session)
|
||||
if (!cmd || !session || !inst)
|
||||
return -EINVAL;
|
||||
|
||||
pkt = (struct cvp_session_release_buffers_packet *)cmd;
|
||||
pkt->packet_type = HFI_CMD_SESSION_CVP_RELEASE_BUFFERS;
|
||||
pkt->session_id = hash32_ptr(session);
|
||||
pkt->session_id = inst->sess_id;
|
||||
pkt->num_buffers = 1;
|
||||
pkt->buffer_type = 0;
|
||||
pkt->size = sizeof(struct cvp_session_release_buffers_packet) +
|
||||
|
|
@ -347,6 +351,7 @@ int cvp_create_pkt_cmd_session_send(
|
|||
int def_idx;
|
||||
struct cvp_hal_session_cmd_pkt *ptr =
|
||||
(struct cvp_hal_session_cmd_pkt *)in_pkt;
|
||||
struct msm_cvp_inst *inst = session->session_id;
|
||||
|
||||
if (!out_pkt || !in_pkt || !session)
|
||||
return -EINVAL;
|
||||
|
|
@ -354,7 +359,7 @@ int cvp_create_pkt_cmd_session_send(
|
|||
if (ptr->size > MAX_HFI_PKT_SIZE * sizeof(unsigned int))
|
||||
goto error_hfi_packet;
|
||||
|
||||
if (ptr->session_id != hash32_ptr(session))
|
||||
if (ptr->session_id != inst->sess_id)
|
||||
goto error_hfi_packet;
|
||||
|
||||
def_idx = get_pkt_index(ptr);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
|
|
@ -462,7 +462,7 @@ static struct msm_cvp_inst *cvp_get_inst_from_id(struct msm_cvp_core *core,
|
|||
retry:
|
||||
if (mutex_trylock(&core->lock)) {
|
||||
list_for_each_entry(inst, &core->instances, list) {
|
||||
if (hash32_ptr(inst->session) == session_id) {
|
||||
if (inst->sess_id == session_id) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include "msm_cvp.h"
|
||||
|
|
@ -14,6 +15,47 @@ struct cvp_power_level {
|
|||
unsigned long bw_sum;
|
||||
};
|
||||
|
||||
void *get_sessObj_from_idr(struct msm_cvp_inst *inst)
|
||||
{
|
||||
void *sessObj = NULL;
|
||||
struct msm_cvp_core *core = NULL;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
dprintk(CVP_ERR, "%s: invalid params\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
core = inst->core;
|
||||
mutex_lock(&core->idr_mtx);
|
||||
sessObj = idr_find(&core->sess_idr, inst->sess_id);
|
||||
mutex_unlock(&core->idr_mtx);
|
||||
if (!sessObj)
|
||||
dprintk(CVP_ERR, "%s: Could not find the sess obj for given idr id\n",
|
||||
__func__);
|
||||
|
||||
return sessObj;
|
||||
}
|
||||
|
||||
u32 get_sessId_from_idr(void *session)
|
||||
{
|
||||
void *ptr = NULL;
|
||||
u32 sess_id = -1;
|
||||
struct msm_cvp_core *core = NULL;
|
||||
|
||||
core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
|
||||
if (!session || !core)
|
||||
return -EINVAL;
|
||||
mutex_lock(&core->idr_mtx);
|
||||
idr_for_each_entry(&core->sess_idr, ptr, sess_id) {
|
||||
if (ptr == session) {
|
||||
mutex_unlock(&core->idr_mtx);
|
||||
return sess_id;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&core->idr_mtx);
|
||||
return sess_id;
|
||||
}
|
||||
|
||||
static int msm_cvp_get_session_info(struct msm_cvp_inst *inst,
|
||||
struct cvp_kmd_session_info *session)
|
||||
{
|
||||
|
|
@ -30,7 +72,7 @@ static int msm_cvp_get_session_info(struct msm_cvp_inst *inst,
|
|||
return -ECONNRESET;
|
||||
|
||||
s->cur_cmd_type = CVP_KMD_GET_SESSION_INFO;
|
||||
session->session_id = hash32_ptr(inst->session);
|
||||
session->session_id = inst->sess_id;
|
||||
dprintk(CVP_SESS, "%s: id 0x%x\n", __func__, session->session_id);
|
||||
|
||||
s->cur_cmd_type = 0;
|
||||
|
|
@ -1227,7 +1269,7 @@ static int msm_cvp_session_stop(struct msm_cvp_inst *inst,
|
|||
sq->state = QUEUE_STOP;
|
||||
|
||||
pr_info(CVP_DBG_TAG "Stop session: %pK session_id = %d\n",
|
||||
"sess", inst, hash32_ptr(inst->session));
|
||||
"sess", inst, inst->sess_id);
|
||||
spin_unlock(&sq->lock);
|
||||
|
||||
wake_up_all(&inst->session_queue.wq);
|
||||
|
|
@ -1251,7 +1293,7 @@ int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst)
|
|||
sq->state = QUEUE_STOP;
|
||||
|
||||
dprintk(CVP_SESS, "Stop session queue: %pK session_id = %d\n",
|
||||
inst, hash32_ptr(inst->session));
|
||||
inst, inst->sess_id);
|
||||
spin_unlock(&sq->lock);
|
||||
|
||||
wake_up_all(&inst->session_queue.wq);
|
||||
|
|
@ -1551,7 +1593,7 @@ static void cvp_clean_fence_queue(struct msm_cvp_inst *inst, int synx_state)
|
|||
ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1);
|
||||
|
||||
dprintk(CVP_SYNX, "%s: (%#x) flush frame %llu %llu wait_list\n",
|
||||
__func__, hash32_ptr(inst->session), ktid, f->frame_id);
|
||||
__func__, inst->sess_id, ktid, f->frame_id);
|
||||
|
||||
list_del_init(&f->list);
|
||||
msm_cvp_unmap_frame(inst, f->pkt->client_data.kdata);
|
||||
|
|
@ -1564,7 +1606,7 @@ static void cvp_clean_fence_queue(struct msm_cvp_inst *inst, int synx_state)
|
|||
ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1);
|
||||
|
||||
dprintk(CVP_SYNX, "%s: (%#x)flush frame %llu %llu sched_list\n",
|
||||
__func__, hash32_ptr(inst->session), ktid, f->frame_id);
|
||||
__func__, inst->sess_id, ktid, f->frame_id);
|
||||
cvp_cancel_synx(inst, CVP_INPUT_SYNX, f, synx_state);
|
||||
}
|
||||
|
||||
|
|
@ -1612,14 +1654,14 @@ static int cvp_flush_all(struct msm_cvp_inst *inst)
|
|||
return -ECONNRESET;
|
||||
|
||||
dprintk(CVP_SESS, "session %llx (%#x)flush all starts\n",
|
||||
inst, hash32_ptr(inst->session));
|
||||
inst, inst->sess_id);
|
||||
q = &inst->fence_cmd_queue;
|
||||
hdev = inst->core->device;
|
||||
|
||||
cvp_clean_fence_queue(inst, SYNX_STATE_SIGNALED_CANCEL);
|
||||
|
||||
dprintk(CVP_SESS, "%s: (%#x) send flush to fw\n",
|
||||
__func__, hash32_ptr(inst->session));
|
||||
__func__, inst->sess_id);
|
||||
|
||||
/* Send flush to FW */
|
||||
rc = call_hfi_op(hdev, session_flush, (void *)inst->session);
|
||||
|
|
@ -1636,7 +1678,7 @@ static int cvp_flush_all(struct msm_cvp_inst *inst)
|
|||
__func__, rc);
|
||||
|
||||
dprintk(CVP_SESS, "%s: (%#x) received flush from fw\n",
|
||||
__func__, hash32_ptr(inst->session));
|
||||
__func__, inst->sess_id);
|
||||
|
||||
exit:
|
||||
rc = cvp_drain_fence_sched_list(inst);
|
||||
|
|
@ -1859,10 +1901,10 @@ int msm_cvp_session_deinit(struct msm_cvp_inst *inst)
|
|||
return -EINVAL;
|
||||
}
|
||||
dprintk(CVP_SESS, "%s: inst %pK (%#x)\n", __func__,
|
||||
inst, hash32_ptr(inst->session));
|
||||
inst, inst->sess_id);
|
||||
|
||||
session = (struct cvp_hal_session *)inst->session;
|
||||
if (!session)
|
||||
session = (struct cvp_hal_session *)get_sessObj_from_idr(inst);
|
||||
if (!session || session != inst->session)
|
||||
return rc;
|
||||
|
||||
rc = msm_cvp_comm_try_state(inst, MSM_CVP_CLOSE_DONE);
|
||||
|
|
@ -1883,7 +1925,7 @@ int msm_cvp_session_init(struct msm_cvp_inst *inst)
|
|||
}
|
||||
|
||||
dprintk(CVP_SESS, "%s: inst %pK (%#x)\n", __func__,
|
||||
inst, hash32_ptr(inst->session));
|
||||
inst, inst->sess_id);
|
||||
|
||||
/* set default frequency */
|
||||
inst->clk_data.core_id = 0;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef _MSM_CVP_H_
|
||||
|
|
@ -34,4 +35,6 @@ int msm_cvp_session_init(struct msm_cvp_inst *inst);
|
|||
int msm_cvp_session_deinit(struct msm_cvp_inst *inst);
|
||||
int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst);
|
||||
int cvp_stop_clean_fence_queue(struct msm_cvp_inst *inst);
|
||||
void *get_sessObj_from_idr(struct msm_cvp_inst *inst);
|
||||
u32 get_sessId_from_idr(void *session);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include "msm_cvp_common.h"
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
do { \
|
||||
clear_bit(idx, &inst->dma_cache.usage_bitmap); \
|
||||
dprintk(CVP_MEM, "clear %x bit %d dma_cache bitmap 0x%llx\n", \
|
||||
hash32_ptr(inst->session), smem->bitmap_index, \
|
||||
inst->sess_id, smem->bitmap_index, \
|
||||
inst->dma_cache.usage_bitmap); \
|
||||
} while (0)
|
||||
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
do { \
|
||||
set_bit(idx, &inst->dma_cache.usage_bitmap); \
|
||||
dprintk(CVP_MEM, "Set %x bit %d dma_cache bitmap 0x%llx\n", \
|
||||
hash32_ptr(inst->session), idx, \
|
||||
inst->sess_id, idx, \
|
||||
inst->dma_cache.usage_bitmap); \
|
||||
} while (0)
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ void print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst,
|
|||
if (smem->dma_buf) {
|
||||
dprintk(tag,
|
||||
"%s: %x : %s size %d flags %#x iova %#x idx %d ref %d",
|
||||
str, hash32_ptr(inst->session), smem->dma_buf->name,
|
||||
str, inst->sess_id, smem->dma_buf->name,
|
||||
smem->size, smem->flags, smem->device_addr,
|
||||
smem->bitmap_index, smem->refcount);
|
||||
}
|
||||
|
|
@ -51,13 +51,13 @@ static void print_internal_buffer(u32 tag, const char *str,
|
|||
if (cbuf->smem->dma_buf) {
|
||||
dprintk(tag,
|
||||
"%s: %x : fd %d off %d %s size %d iova %#x",
|
||||
str, hash32_ptr(inst->session), cbuf->fd,
|
||||
str, inst->sess_id, cbuf->fd,
|
||||
cbuf->offset, cbuf->smem->dma_buf->name, cbuf->size,
|
||||
cbuf->smem->device_addr);
|
||||
} else {
|
||||
dprintk(tag,
|
||||
"%s: %x : idx %2d fd %d off %d size %d iova %#x",
|
||||
str, hash32_ptr(inst->session), cbuf->fd,
|
||||
str, inst->sess_id, cbuf->fd,
|
||||
cbuf->offset, cbuf->size, cbuf->smem->device_addr);
|
||||
}
|
||||
}
|
||||
|
|
@ -77,7 +77,7 @@ void print_client_buffer(u32 tag, const char *str,
|
|||
|
||||
dprintk(tag,
|
||||
"%s: %x : idx %2d fd %d off %d size %d type %d flags 0x%x\n",
|
||||
str, hash32_ptr(inst->session), cbuf->index, cbuf->fd,
|
||||
str, inst->sess_id, cbuf->index, cbuf->fd,
|
||||
cbuf->offset, cbuf->size, cbuf->type, cbuf->flags);
|
||||
}
|
||||
|
||||
|
|
@ -154,7 +154,7 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct cvp_kmd_buffer *buf)
|
|||
}
|
||||
|
||||
if (buf->index) {
|
||||
rc = cvp_dsp_register_buffer(hash32_ptr(session), buf->fd,
|
||||
rc = cvp_dsp_register_buffer(inst->sess_id, buf->fd,
|
||||
smem->dma_buf->size, buf->size, buf->offset,
|
||||
buf->index, (uint32_t)smem->device_addr);
|
||||
if (rc) {
|
||||
|
|
@ -227,7 +227,7 @@ int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, struct cvp_kmd_buffer *buf)
|
|||
}
|
||||
|
||||
if (buf->index) {
|
||||
rc = cvp_dsp_deregister_buffer(hash32_ptr(session), buf->fd,
|
||||
rc = cvp_dsp_deregister_buffer(inst->sess_id, buf->fd,
|
||||
cbuf->smem->dma_buf->size, buf->size, buf->offset,
|
||||
buf->index, (uint32_t)cbuf->smem->device_addr);
|
||||
if (rc) {
|
||||
|
|
@ -545,7 +545,7 @@ void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid)
|
|||
|
||||
ktid &= (FENCE_BIT - 1);
|
||||
dprintk(CVP_MEM, "%s: (%#x) unmap frame %llu\n",
|
||||
__func__, hash32_ptr(inst->session), ktid);
|
||||
__func__, inst->sess_id, ktid);
|
||||
|
||||
found = false;
|
||||
mutex_lock(&inst->frames.lock);
|
||||
|
|
@ -587,7 +587,7 @@ int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst,
|
|||
smem = pbuf->smem;
|
||||
|
||||
dprintk(CVP_MEM, "unmap persist: %x %d %d %#x",
|
||||
hash32_ptr(inst->session), pbuf->fd,
|
||||
inst->sess_id, pbuf->fd,
|
||||
pbuf->size, smem->device_addr);
|
||||
|
||||
if (smem->bitmap_index >= MAX_DMABUF_NUMS) {
|
||||
|
|
@ -785,7 +785,7 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst)
|
|||
list_for_each_entry_safe(cbuf, dummy, &inst->cvpdspbufs.list,
|
||||
list) {
|
||||
print_internal_buffer(CVP_MEM, "remove dspbufs", inst, cbuf);
|
||||
rc = cvp_dsp_deregister_buffer(hash32_ptr(session),
|
||||
rc = cvp_dsp_deregister_buffer(inst->sess_id,
|
||||
cbuf->fd, cbuf->smem->dma_buf->size, cbuf->size,
|
||||
cbuf->offset, cbuf->index,
|
||||
(uint32_t)cbuf->smem->device_addr);
|
||||
|
|
@ -955,7 +955,7 @@ int cvp_release_arp_buffers(struct msm_cvp_inst *inst)
|
|||
if (buf->ownership == DRIVER) {
|
||||
dprintk(CVP_MEM,
|
||||
"%s: %x : fd %d %s size %d",
|
||||
"free arp", hash32_ptr(inst->session), buf->fd,
|
||||
"free arp", inst->sess_id, buf->fd,
|
||||
smem->dma_buf->name, buf->size);
|
||||
msm_cvp_smem_free(smem);
|
||||
kmem_cache_free(cvp_driver->smem_cache, smem);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/jiffies.h>
|
||||
|
|
@ -195,23 +196,31 @@ struct msm_cvp_inst *cvp_get_inst_validate(struct msm_cvp_core *core,
|
|||
{
|
||||
int rc = 0;
|
||||
struct cvp_hfi_device *hdev;
|
||||
struct msm_cvp_inst *s;
|
||||
struct msm_cvp_inst *inst;
|
||||
void *sessObj = NULL;
|
||||
|
||||
s = cvp_get_inst(core, session_id);
|
||||
if (!s) {
|
||||
dprintk(CVP_ERR, "%s session doesn't exit\n",
|
||||
inst = cvp_get_inst(core, session_id);
|
||||
if (!inst) {
|
||||
dprintk(CVP_ERR, "%s Inst doesn't exit\n",
|
||||
__builtin_return_address(0));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hdev = s->core->device;
|
||||
rc = call_hfi_op(hdev, validate_session, s->session, __func__);
|
||||
if (rc) {
|
||||
cvp_put_inst(s);
|
||||
s = NULL;
|
||||
sessObj = get_sessObj_from_idr(inst);
|
||||
if (!sessObj || sessObj != inst->session) {
|
||||
dprintk(CVP_ERR,
|
||||
"Either sessionObj is null or not matching with inst->session\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return s;
|
||||
hdev = inst->core->device;
|
||||
rc = call_hfi_op(hdev, validate_session, sessObj, __func__);
|
||||
if (rc) {
|
||||
cvp_put_inst(inst);
|
||||
inst = NULL;
|
||||
}
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
static void cvp_handle_session_cmd_done(enum hal_command_response cmd,
|
||||
|
|
@ -486,7 +495,7 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data)
|
|||
}
|
||||
|
||||
dprintk(CVP_SESS, "%s: cvp session %#x\n", __func__,
|
||||
hash32_ptr(inst->session));
|
||||
inst->sess_id);
|
||||
|
||||
signal_session_msg_receipt(cmd, inst);
|
||||
cvp_put_inst(inst);
|
||||
|
|
@ -568,7 +577,7 @@ static void handle_session_error(enum hal_command_response cmd, void *data)
|
|||
|
||||
hdev = inst->core->device;
|
||||
dprintk(CVP_ERR, "Session error received for inst %pK session %x\n",
|
||||
inst, hash32_ptr(inst->session));
|
||||
inst, inst->sess_id);
|
||||
|
||||
if (response->status == CVP_ERR_MAX_CLIENTS) {
|
||||
dprintk(CVP_WARN, "Too many clients, rejecting %pK", inst);
|
||||
|
|
@ -901,7 +910,7 @@ static int msm_comm_session_abort(struct msm_cvp_inst *inst)
|
|||
abort_completion = SESSION_MSG_INDEX(HAL_SESSION_ABORT_DONE);
|
||||
|
||||
dprintk(CVP_WARN, "%s: inst %pK session %x\n", __func__,
|
||||
inst, hash32_ptr(inst->session));
|
||||
inst, inst->sess_id);
|
||||
rc = call_hfi_op(hdev, session_abort, (void *)inst->session);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
|
|
@ -914,7 +923,7 @@ static int msm_comm_session_abort(struct msm_cvp_inst *inst)
|
|||
inst->core->resources.msm_cvp_hw_rsp_timeout));
|
||||
if (!rc) {
|
||||
dprintk(CVP_ERR, "%s: inst %pK session %x abort timed out\n",
|
||||
__func__, inst, hash32_ptr(inst->session));
|
||||
__func__, inst, inst->sess_id);
|
||||
call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
|
||||
dump_hfi_queue(hdev->hfi_device_data);
|
||||
msm_cvp_comm_generate_sys_error(inst);
|
||||
|
|
@ -1268,7 +1277,7 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state)
|
|||
}
|
||||
dprintk(CVP_SESS,
|
||||
"Trying to move inst: %pK (%#x) from: %#x to %#x\n",
|
||||
inst, hash32_ptr(inst->session), inst->state, state);
|
||||
inst, inst->sess_id, inst->state, state);
|
||||
|
||||
mutex_lock(&inst->sync_lock);
|
||||
if (inst->state == MSM_CVP_CORE_INVALID) {
|
||||
|
|
@ -1281,7 +1290,7 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state)
|
|||
flipped_state = get_flipped_state(inst->state, state);
|
||||
dprintk(CVP_SESS,
|
||||
"inst: %pK (%#x) flipped_state = %#x %x\n",
|
||||
inst, hash32_ptr(inst->session), flipped_state, state);
|
||||
inst, inst->sess_id, flipped_state, state);
|
||||
switch (flipped_state) {
|
||||
case MSM_CVP_CORE_UNINIT_DONE:
|
||||
case MSM_CVP_CORE_INIT:
|
||||
|
|
@ -1491,7 +1500,7 @@ int msm_cvp_comm_kill_session(struct msm_cvp_inst *inst)
|
|||
return 0;
|
||||
}
|
||||
dprintk(CVP_WARN, "%s: inst %pK, session %x state %d\n", __func__,
|
||||
inst, hash32_ptr(inst->session), inst->state);
|
||||
inst, inst->sess_id, inst->state);
|
||||
/*
|
||||
* We're internally forcibly killing the session, if fw is aware of
|
||||
* the session send session_abort to firmware to clean up and release
|
||||
|
|
@ -1503,7 +1512,7 @@ int msm_cvp_comm_kill_session(struct msm_cvp_inst *inst)
|
|||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: inst %pK session %x abort failed\n",
|
||||
__func__, inst, hash32_ptr(inst->session));
|
||||
__func__, inst, inst->sess_id);
|
||||
change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID);
|
||||
} else {
|
||||
change_cvp_inst_state(inst, MSM_CVP_CORE_UNINIT);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/dma-direction.h>
|
||||
|
|
@ -165,7 +166,7 @@ void *msm_cvp_open(int core_id, int session_type)
|
|||
list_for_each_entry(inst, &core->instances, list)
|
||||
dprintk(CVP_ERR, "inst %pK, cmd %d id %d\n",
|
||||
inst, inst->cur_cmd_type,
|
||||
hash32_ptr(inst->session));
|
||||
inst->sess_id);
|
||||
mutex_unlock(&core->lock);
|
||||
|
||||
return NULL;
|
||||
|
|
@ -369,7 +370,7 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst)
|
|||
synx_uninitialize(inst->synx_session_id);
|
||||
|
||||
pr_info(CVP_DBG_TAG "Closed cvp instance: %pK session_id = %d\n",
|
||||
"sess", inst, hash32_ptr(inst->session));
|
||||
"sess", inst, inst->sess_id);
|
||||
if (inst->cur_cmd_type)
|
||||
dprintk(CVP_ERR, "deleted instance has pending cmd %d\n",
|
||||
inst->cur_cmd_type);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef _MSM_CVP_INTERNAL_H_
|
||||
|
|
@ -290,6 +291,8 @@ struct msm_cvp_core {
|
|||
unsigned long curr_freq;
|
||||
struct cvp_cycle_info dyn_clk;
|
||||
atomic64_t kernel_trans_id;
|
||||
struct idr sess_idr;
|
||||
struct mutex idr_mtx;
|
||||
};
|
||||
|
||||
struct msm_cvp_inst {
|
||||
|
|
@ -301,6 +304,7 @@ struct msm_cvp_inst {
|
|||
struct cvp_session_queue session_queue_fence;
|
||||
struct cvp_session_event event_handler;
|
||||
void *session;
|
||||
u32 sess_id;
|
||||
enum instance_state state;
|
||||
struct msm_cvp_list freqs;
|
||||
struct msm_cvp_list persistbufs;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include "msm_cvp_common.h"
|
||||
|
|
@ -20,7 +21,7 @@ void cvp_dump_fence_queue(struct msm_cvp_inst *inst)
|
|||
ssid = inst->synx_session_id;
|
||||
mutex_lock(&q->lock);
|
||||
dprintk(CVP_WARN, "inst %x fence q mode %d, ssid %d\n",
|
||||
hash32_ptr(inst->session), q->mode, ssid.client_id);
|
||||
inst->sess_id, q->mode, ssid.client_id);
|
||||
|
||||
dprintk(CVP_WARN, "fence cmdq wait list:\n");
|
||||
list_for_each_entry(f, &q->wait_list, list) {
|
||||
|
|
|
|||
|
|
@ -808,9 +808,9 @@ static struct usb_function_instance *uvc_alloc_inst(void)
|
|||
cd->wObjectiveFocalLengthMax = cpu_to_le16(0);
|
||||
cd->wOcularFocalLength = cpu_to_le16(0);
|
||||
cd->bControlSize = 3;
|
||||
cd->bmControls[0] = 2;
|
||||
cd->bmControls[1] = 0;
|
||||
cd->bmControls[2] = 0;
|
||||
cd->bmControls[0] = 62;
|
||||
cd->bmControls[1] = 126;
|
||||
cd->bmControls[2] = 10;
|
||||
|
||||
pd = &opts->uvc_processing;
|
||||
pd->bLength = UVC_DT_PROCESSING_UNIT_SIZE(2);
|
||||
|
|
@ -820,8 +820,8 @@ static struct usb_function_instance *uvc_alloc_inst(void)
|
|||
pd->bSourceID = 1;
|
||||
pd->wMaxMultiplier = cpu_to_le16(16*1024);
|
||||
pd->bControlSize = 2;
|
||||
pd->bmControls[0] = 1;
|
||||
pd->bmControls[1] = 0;
|
||||
pd->bmControls[0] = 91;
|
||||
pd->bmControls[1] = 23;
|
||||
pd->iProcessing = 0;
|
||||
pd->bmVideoStandards = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -762,16 +762,19 @@ static const struct uvcg_config_group_type uvcg_control_grp_type = {
|
|||
/* -----------------------------------------------------------------------------
|
||||
* streaming/uncompressed
|
||||
* streaming/mjpeg
|
||||
* streaming/framebased
|
||||
*/
|
||||
|
||||
static const char * const uvcg_format_names[] = {
|
||||
"uncompressed",
|
||||
"mjpeg",
|
||||
"framebased"
|
||||
};
|
||||
|
||||
enum uvcg_format_type {
|
||||
UVCG_UNCOMPRESSED = 0,
|
||||
UVCG_MJPEG,
|
||||
UVCG_FRAMEBASED,
|
||||
};
|
||||
|
||||
struct uvcg_format {
|
||||
|
|
@ -1080,6 +1083,7 @@ struct uvcg_frame {
|
|||
u32 dw_max_video_frame_buffer_size;
|
||||
u32 dw_default_frame_interval;
|
||||
u8 b_frame_interval_type;
|
||||
u32 dw_bytes_perline;
|
||||
} __attribute__((packed)) frame;
|
||||
u32 *dw_frame_interval;
|
||||
};
|
||||
|
|
@ -1190,6 +1194,7 @@ UVCG_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, 32);
|
|||
UVCG_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, 32);
|
||||
UVCG_FRAME_ATTR(dw_max_video_frame_buffer_size, dwMaxVideoFrameBufferSize, 32);
|
||||
UVCG_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval, 32);
|
||||
UVCG_FRAME_ATTR(dw_bytes_perline, dwBytesPerLine, 32);
|
||||
|
||||
#undef UVCG_FRAME_ATTR
|
||||
|
||||
|
|
@ -1324,7 +1329,7 @@ end:
|
|||
|
||||
UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval);
|
||||
|
||||
static struct configfs_attribute *uvcg_frame_attrs[] = {
|
||||
static struct configfs_attribute *uvcg_frame_attrs1[] = {
|
||||
&uvcg_frame_attr_b_frame_index,
|
||||
&uvcg_frame_attr_bm_capabilities,
|
||||
&uvcg_frame_attr_w_width,
|
||||
|
|
@ -1337,12 +1342,32 @@ static struct configfs_attribute *uvcg_frame_attrs[] = {
|
|||
NULL,
|
||||
};
|
||||
|
||||
static const struct config_item_type uvcg_frame_type = {
|
||||
static struct configfs_attribute *uvcg_frame_attrs2[] = {
|
||||
&uvcg_frame_attr_b_frame_index,
|
||||
&uvcg_frame_attr_bm_capabilities,
|
||||
&uvcg_frame_attr_w_width,
|
||||
&uvcg_frame_attr_w_height,
|
||||
&uvcg_frame_attr_dw_min_bit_rate,
|
||||
&uvcg_frame_attr_dw_max_bit_rate,
|
||||
&uvcg_frame_attr_dw_max_video_frame_buffer_size,
|
||||
&uvcg_frame_attr_dw_default_frame_interval,
|
||||
&uvcg_frame_attr_dw_frame_interval,
|
||||
&uvcg_frame_attr_dw_bytes_perline,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct config_item_type uvcg_frame_type1 = {
|
||||
.ct_item_ops = &uvcg_config_item_ops,
|
||||
.ct_attrs = uvcg_frame_attrs,
|
||||
.ct_attrs = uvcg_frame_attrs1,
|
||||
.ct_owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static const struct config_item_type uvcg_frame_type2 = {
|
||||
.ct_item_ops = &uvcg_config_item_ops,
|
||||
.ct_attrs = uvcg_frame_attrs2,
|
||||
.ct_owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct config_item *uvcg_frame_make(struct config_group *group,
|
||||
const char *name)
|
||||
{
|
||||
|
|
@ -1363,6 +1388,7 @@ static struct config_item *uvcg_frame_make(struct config_group *group,
|
|||
h->frame.dw_max_bit_rate = 55296000;
|
||||
h->frame.dw_max_video_frame_buffer_size = 460800;
|
||||
h->frame.dw_default_frame_interval = 666666;
|
||||
h->frame.dw_bytes_perline = 0;
|
||||
|
||||
opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
|
||||
opts = to_f_uvc_opts(opts_item);
|
||||
|
|
@ -1375,6 +1401,9 @@ static struct config_item *uvcg_frame_make(struct config_group *group,
|
|||
} else if (fmt->type == UVCG_MJPEG) {
|
||||
h->frame.b_descriptor_subtype = UVC_VS_FRAME_MJPEG;
|
||||
h->fmt_type = UVCG_MJPEG;
|
||||
} else if (fmt->type == UVCG_FRAMEBASED) {
|
||||
h->frame.b_descriptor_subtype = UVC_VS_FRAME_FRAME_BASED;
|
||||
h->fmt_type = UVCG_FRAMEBASED;
|
||||
} else {
|
||||
mutex_unlock(&opts->lock);
|
||||
kfree(h);
|
||||
|
|
@ -1383,7 +1412,10 @@ static struct config_item *uvcg_frame_make(struct config_group *group,
|
|||
++fmt->num_frames;
|
||||
mutex_unlock(&opts->lock);
|
||||
|
||||
config_item_init_type_name(&h->item, name, &uvcg_frame_type);
|
||||
if (fmt->type == UVCG_FRAMEBASED)
|
||||
config_item_init_type_name(&h->item, name, &uvcg_frame_type2);
|
||||
else
|
||||
config_item_init_type_name(&h->item, name, &uvcg_frame_type1);
|
||||
|
||||
return &h->item;
|
||||
}
|
||||
|
|
@ -1413,9 +1445,6 @@ static void uvcg_format_set_indices(struct config_group *fmt)
|
|||
list_for_each_entry(ci, &fmt->cg_children, ci_entry) {
|
||||
struct uvcg_frame *frm;
|
||||
|
||||
if (ci->ci_type != &uvcg_frame_type)
|
||||
continue;
|
||||
|
||||
frm = to_uvcg_frame(ci);
|
||||
frm->frame.b_frame_index = i++;
|
||||
}
|
||||
|
|
@ -1856,6 +1885,260 @@ static const struct uvcg_config_group_type uvcg_mjpeg_grp_type = {
|
|||
.name = "mjpeg",
|
||||
};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* streaming/framebased/<NAME>
|
||||
*/
|
||||
|
||||
struct uvcg_framebased {
|
||||
struct uvcg_format fmt;
|
||||
struct uvc_format_framebased desc;
|
||||
};
|
||||
|
||||
static inline struct uvcg_framebased *to_uvcg_framebased(struct config_item *item)
|
||||
{
|
||||
return container_of(to_uvcg_format(item), struct uvcg_framebased, fmt);
|
||||
}
|
||||
|
||||
static struct configfs_group_operations uvcg_framebased_group_ops = {
|
||||
.make_item = uvcg_frame_make,
|
||||
.drop_item = uvcg_frame_drop,
|
||||
};
|
||||
|
||||
#define UVCG_FRAMEBASED_ATTR_RO(cname, aname, bits) \
|
||||
static ssize_t uvcg_framebased_##cname##_show(struct config_item *item, \
|
||||
char *page) \
|
||||
{ \
|
||||
struct uvcg_framebased *u = to_uvcg_framebased(item); \
|
||||
struct f_uvc_opts *opts; \
|
||||
struct config_item *opts_item; \
|
||||
struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
|
||||
int result; \
|
||||
\
|
||||
mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
|
||||
\
|
||||
opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; \
|
||||
opts = to_f_uvc_opts(opts_item); \
|
||||
\
|
||||
mutex_lock(&opts->lock); \
|
||||
result = scnprintf(page, PAGE_SIZE, "%u\n", le##bits##_to_cpu(u->desc.aname));\
|
||||
mutex_unlock(&opts->lock); \
|
||||
\
|
||||
mutex_unlock(su_mutex); \
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
UVC_ATTR_RO(uvcg_framebased_, cname, aname)
|
||||
|
||||
#define UVCG_FRAMEBASED_ATTR(cname, aname, bits) \
|
||||
static ssize_t uvcg_framebased_##cname##_show(struct config_item *item, \
|
||||
char *page) \
|
||||
{ \
|
||||
struct uvcg_framebased *u = to_uvcg_framebased(item); \
|
||||
struct f_uvc_opts *opts; \
|
||||
struct config_item *opts_item; \
|
||||
struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
|
||||
int result; \
|
||||
\
|
||||
mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
|
||||
\
|
||||
opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
|
||||
opts = to_f_uvc_opts(opts_item); \
|
||||
\
|
||||
mutex_lock(&opts->lock); \
|
||||
result = scnprintf(page, PAGE_SIZE, "%u\n", le##bits##_to_cpu(u->desc.aname));\
|
||||
mutex_unlock(&opts->lock); \
|
||||
\
|
||||
mutex_unlock(su_mutex); \
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
static ssize_t \
|
||||
uvcg_framebased_##cname##_store(struct config_item *item, \
|
||||
const char *page, size_t len) \
|
||||
{ \
|
||||
struct uvcg_framebased *u = to_uvcg_framebased(item); \
|
||||
struct f_uvc_opts *opts; \
|
||||
struct config_item *opts_item; \
|
||||
struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
|
||||
int ret; \
|
||||
u8 num; \
|
||||
\
|
||||
mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
|
||||
\
|
||||
opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
|
||||
opts = to_f_uvc_opts(opts_item); \
|
||||
\
|
||||
mutex_lock(&opts->lock); \
|
||||
if (u->fmt.linked || opts->refcnt) { \
|
||||
ret = -EBUSY; \
|
||||
goto end; \
|
||||
} \
|
||||
\
|
||||
ret = kstrtou8(page, 0, &num); \
|
||||
if (ret) \
|
||||
goto end; \
|
||||
\
|
||||
if (num > 255) { \
|
||||
ret = -EINVAL; \
|
||||
goto end; \
|
||||
} \
|
||||
u->desc.aname = num; \
|
||||
ret = len; \
|
||||
end: \
|
||||
mutex_unlock(&opts->lock); \
|
||||
mutex_unlock(su_mutex); \
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
UVC_ATTR(uvcg_framebased_, cname, aname)
|
||||
|
||||
UVCG_FRAMEBASED_ATTR_RO(b_format_index, bFormatIndex, 8);
|
||||
UVCG_FRAMEBASED_ATTR_RO(b_bits_per_pixel, bBitsPerPixel, 8);
|
||||
UVCG_FRAMEBASED_ATTR(b_default_frame_index, bDefaultFrameIndex, 8);
|
||||
UVCG_FRAMEBASED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8);
|
||||
UVCG_FRAMEBASED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8);
|
||||
UVCG_FRAMEBASED_ATTR_RO(bm_interface_flags, bmInterfaceFlags, 8);
|
||||
|
||||
#undef UVCG_FRAMEBASED_ATTR
|
||||
#undef UVCG_FRAMEBASED_ATTR_RO
|
||||
|
||||
static ssize_t uvcg_framebased_guid_format_show(struct config_item *item,
|
||||
char *page)
|
||||
{
|
||||
struct uvcg_framebased *ch = to_uvcg_framebased(item);
|
||||
struct f_uvc_opts *opts;
|
||||
struct config_item *opts_item;
|
||||
struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
|
||||
|
||||
mutex_lock(su_mutex); /* for navigating configfs hierarchy */
|
||||
|
||||
opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
|
||||
opts = to_f_uvc_opts(opts_item);
|
||||
|
||||
mutex_lock(&opts->lock);
|
||||
memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat));
|
||||
mutex_unlock(&opts->lock);
|
||||
|
||||
mutex_unlock(su_mutex);
|
||||
|
||||
return sizeof(ch->desc.guidFormat);
|
||||
}
|
||||
|
||||
static ssize_t uvcg_framebased_guid_format_store(struct config_item *item,
|
||||
const char *page, size_t len)
|
||||
{
|
||||
struct uvcg_framebased *ch = to_uvcg_framebased(item);
|
||||
struct f_uvc_opts *opts;
|
||||
struct config_item *opts_item;
|
||||
struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
|
||||
int ret;
|
||||
|
||||
mutex_lock(su_mutex); /* for navigating configfs hierarchy */
|
||||
|
||||
opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
|
||||
opts = to_f_uvc_opts(opts_item);
|
||||
|
||||
mutex_lock(&opts->lock);
|
||||
if (ch->fmt.linked || opts->refcnt) {
|
||||
ret = -EBUSY;
|
||||
goto end;
|
||||
}
|
||||
|
||||
memcpy(ch->desc.guidFormat, page,
|
||||
min(sizeof(ch->desc.guidFormat), len));
|
||||
ret = sizeof(ch->desc.guidFormat);
|
||||
|
||||
end:
|
||||
mutex_unlock(&opts->lock);
|
||||
mutex_unlock(su_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
UVC_ATTR(uvcg_framebased_, guid_format, guidFormat);
|
||||
|
||||
static inline ssize_t
|
||||
uvcg_framebased_bma_controls_show(struct config_item *item, char *page)
|
||||
{
|
||||
struct uvcg_framebased *u = to_uvcg_framebased(item);
|
||||
|
||||
return uvcg_format_bma_controls_show(&u->fmt, page);
|
||||
}
|
||||
|
||||
static inline ssize_t
|
||||
uvcg_framebased_bma_controls_store(struct config_item *item,
|
||||
const char *page, size_t len)
|
||||
{
|
||||
struct uvcg_framebased *u = to_uvcg_framebased(item);
|
||||
|
||||
return uvcg_format_bma_controls_store(&u->fmt, page, len);
|
||||
}
|
||||
|
||||
UVC_ATTR(uvcg_framebased_, bma_controls, bmaControls);
|
||||
|
||||
static struct configfs_attribute *uvcg_framebased_attrs[] = {
|
||||
&uvcg_framebased_attr_b_format_index,
|
||||
&uvcg_framebased_attr_b_default_frame_index,
|
||||
&uvcg_framebased_attr_b_bits_per_pixel,
|
||||
&uvcg_framebased_attr_b_aspect_ratio_x,
|
||||
&uvcg_framebased_attr_b_aspect_ratio_y,
|
||||
&uvcg_framebased_attr_bm_interface_flags,
|
||||
&uvcg_framebased_attr_bma_controls,
|
||||
&uvcg_framebased_attr_guid_format,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct config_item_type uvcg_framebased_type = {
|
||||
.ct_item_ops = &uvcg_config_item_ops,
|
||||
.ct_group_ops = &uvcg_framebased_group_ops,
|
||||
.ct_attrs = uvcg_framebased_attrs,
|
||||
.ct_owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct config_group *uvcg_framebased_make(struct config_group *group,
|
||||
const char *name)
|
||||
{
|
||||
static char guid[] = { /*Declear frame based as H264 format*/
|
||||
'H', '2', '6', '4', 0x00, 0x00, 0x10, 0x00,
|
||||
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
|
||||
};
|
||||
struct uvcg_framebased *h;
|
||||
|
||||
h = kzalloc(sizeof(*h), GFP_KERNEL);
|
||||
if (!h)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
h->desc.bLength = UVC_DT_FORMAT_FRAMEBASED_SIZE;
|
||||
h->desc.bDescriptorType = USB_DT_CS_INTERFACE;
|
||||
h->desc.bDescriptorSubType = UVC_VS_FORMAT_FRAME_BASED;
|
||||
memcpy(h->desc.guidFormat, guid, sizeof(guid));
|
||||
h->desc.bBitsPerPixel = 0;
|
||||
h->desc.bDefaultFrameIndex = 1;
|
||||
h->desc.bAspectRatioX = 0;
|
||||
h->desc.bAspectRatioY = 0;
|
||||
h->desc.bmInterfaceFlags = 0;
|
||||
h->desc.bCopyProtect = 0;
|
||||
h->desc.bVariableSize = 1;
|
||||
|
||||
h->fmt.type = UVCG_FRAMEBASED;
|
||||
config_group_init_type_name(&h->fmt.group, name,
|
||||
&uvcg_framebased_type);
|
||||
|
||||
return &h->fmt.group;
|
||||
}
|
||||
|
||||
static struct configfs_group_operations uvcg_framebased_grp_ops = {
|
||||
.make_group = uvcg_framebased_make,
|
||||
};
|
||||
|
||||
static const struct uvcg_config_group_type uvcg_framebased_grp_type = {
|
||||
.type = {
|
||||
.ct_item_ops = &uvcg_config_item_ops,
|
||||
.ct_group_ops = &uvcg_framebased_grp_ops,
|
||||
.ct_owner = THIS_MODULE,
|
||||
},
|
||||
.name = "framebased",
|
||||
};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* streaming/color_matching/default
|
||||
*/
|
||||
|
|
@ -2001,6 +2284,7 @@ static int __uvcg_iter_strm_cls(struct uvcg_streaming_header *h,
|
|||
if (ret)
|
||||
return ret;
|
||||
grp = &f->fmt->group;
|
||||
j = 0;
|
||||
list_for_each_entry(item, &grp->cg_children, ci_entry) {
|
||||
frm = to_uvcg_frame(item);
|
||||
ret = fun(frm, priv2, priv3, j++, UVCG_FRAME);
|
||||
|
|
@ -2049,6 +2333,11 @@ static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n,
|
|||
container_of(fmt, struct uvcg_mjpeg, fmt);
|
||||
|
||||
*size += sizeof(m->desc);
|
||||
} else if (fmt->type == UVCG_FRAMEBASED) {
|
||||
struct uvcg_framebased *f =
|
||||
container_of(fmt, struct uvcg_framebased, fmt);
|
||||
|
||||
*size += sizeof(f->desc);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -2059,6 +2348,11 @@ static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n,
|
|||
int sz = sizeof(frm->dw_frame_interval);
|
||||
|
||||
*size += sizeof(frm->frame);
|
||||
/*
|
||||
* framebased has duplicate member with uncompressed and
|
||||
* mjpeg, so minus it
|
||||
*/
|
||||
*size -= sizeof(u32);
|
||||
*size += frm->frame.b_frame_interval_type * sz;
|
||||
}
|
||||
break;
|
||||
|
|
@ -2069,6 +2363,27 @@ static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __uvcg_copy_framebased_desc(void *dest, struct uvcg_frame *frm,
|
||||
int sz)
|
||||
{
|
||||
struct uvc_frame_framebased *desc = dest;
|
||||
|
||||
desc->bLength = frm->frame.b_length;
|
||||
desc->bDescriptorType = frm->frame.b_descriptor_type;
|
||||
desc->bDescriptorSubType = frm->frame.b_descriptor_subtype;
|
||||
desc->bFrameIndex = frm->frame.b_frame_index;
|
||||
desc->bmCapabilities = frm->frame.bm_capabilities;
|
||||
desc->wWidth = frm->frame.w_width;
|
||||
desc->wHeight = frm->frame.w_height;
|
||||
desc->dwMinBitRate = frm->frame.dw_min_bit_rate;
|
||||
desc->dwMaxBitRate = frm->frame.dw_max_bit_rate;
|
||||
desc->dwDefaultFrameInterval = frm->frame.dw_default_frame_interval;
|
||||
desc->bFrameIntervalType = frm->frame.b_frame_interval_type;
|
||||
desc->dwBytesPerLine = frm->frame.dw_bytes_perline;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill an array of streaming descriptors.
|
||||
*
|
||||
|
|
@ -2123,6 +2438,15 @@ static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n,
|
|||
m->desc.bNumFrameDescriptors = fmt->num_frames;
|
||||
memcpy(*dest, &m->desc, sizeof(m->desc));
|
||||
*dest += sizeof(m->desc);
|
||||
} else if (fmt->type == UVCG_FRAMEBASED) {
|
||||
struct uvcg_framebased *f =
|
||||
container_of(fmt, struct uvcg_framebased,
|
||||
fmt);
|
||||
|
||||
f->desc.bFormatIndex = n + 1;
|
||||
f->desc.bNumFrameDescriptors = fmt->num_frames;
|
||||
memcpy(*dest, &f->desc, sizeof(f->desc));
|
||||
*dest += sizeof(f->desc);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -2132,8 +2456,11 @@ static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n,
|
|||
struct uvcg_frame *frm = priv1;
|
||||
struct uvc_descriptor_header *h = *dest;
|
||||
|
||||
sz = sizeof(frm->frame);
|
||||
memcpy(*dest, &frm->frame, sz);
|
||||
sz = sizeof(frm->frame) - 4;
|
||||
if (frm->fmt_type != UVCG_FRAMEBASED)
|
||||
memcpy(*dest, &frm->frame, sz);
|
||||
else
|
||||
__uvcg_copy_framebased_desc(*dest, frm, sz);
|
||||
*dest += sz;
|
||||
sz = frm->frame.b_frame_interval_type *
|
||||
sizeof(*frm->dw_frame_interval);
|
||||
|
|
@ -2145,6 +2472,9 @@ static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n,
|
|||
else if (frm->fmt_type == UVCG_MJPEG)
|
||||
h->bLength = UVC_DT_FRAME_MJPEG_SIZE(
|
||||
frm->frame.b_frame_interval_type);
|
||||
else if (frm->fmt_type == UVCG_FRAMEBASED)
|
||||
h->bLength = UVC_DT_FRAME_FRAMEBASED_SIZE(
|
||||
frm->frame.b_frame_interval_type);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -2357,6 +2687,7 @@ static const struct uvcg_config_group_type uvcg_streaming_grp_type = {
|
|||
&uvcg_streaming_header_grp_type,
|
||||
&uvcg_uncompressed_grp_type,
|
||||
&uvcg_mjpeg_grp_type,
|
||||
&uvcg_framebased_grp_type,
|
||||
&uvcg_color_matching_grp_type,
|
||||
&uvcg_streaming_class_grp_type,
|
||||
NULL,
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ struct uvc_format {
|
|||
static struct uvc_format uvc_formats[] = {
|
||||
{ 16, V4L2_PIX_FMT_YUYV },
|
||||
{ 0, V4L2_PIX_FMT_MJPEG },
|
||||
{ 0, V4L2_PIX_FMT_H264 },
|
||||
{ 12, V4L2_PIX_FMT_YUV420 },
|
||||
{ 8, V4L2_PIX_FMT_GREY },
|
||||
};
|
||||
|
|
|
|||
|
|
@ -162,5 +162,9 @@ extern br_notify_hook_t __rcu *br_notify_hook;
|
|||
typedef int (br_multicast_handle_hook_t)(const struct net_bridge_port *src,
|
||||
struct sk_buff *skb);
|
||||
extern br_multicast_handle_hook_t __rcu *br_multicast_handle_hook;
|
||||
typedef struct net_bridge_port *br_get_dst_hook_t(
|
||||
const struct net_bridge_port *src,
|
||||
struct sk_buff **skb);
|
||||
extern br_get_dst_hook_t __rcu *br_get_dst_hook;
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2554,6 +2554,8 @@ enum netdev_cmd {
|
|||
NETDEV_CVLAN_FILTER_DROP_INFO,
|
||||
NETDEV_SVLAN_FILTER_PUSH_INFO,
|
||||
NETDEV_SVLAN_FILTER_DROP_INFO,
|
||||
NETDEV_BR_JOIN,
|
||||
NETDEV_BR_LEAVE,
|
||||
};
|
||||
const char *netdev_cmd_to_name(enum netdev_cmd cmd);
|
||||
|
||||
|
|
|
|||
|
|
@ -597,5 +597,63 @@ struct UVC_FRAME_MJPEG(n) { \
|
|||
__le32 dwFrameInterval[n]; \
|
||||
} __attribute__ ((packed))
|
||||
|
||||
/* Frame Based Payload - 3.1.1. Frame Based Video Format Descriptor */
|
||||
struct uvc_format_framebased {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubType;
|
||||
__u8 bFormatIndex;
|
||||
__u8 bNumFrameDescriptors;
|
||||
__u8 guidFormat[16];
|
||||
__u8 bBitsPerPixel;
|
||||
__u8 bDefaultFrameIndex;
|
||||
__u8 bAspectRatioX;
|
||||
__u8 bAspectRatioY;
|
||||
__u8 bmInterfaceFlags;
|
||||
__u8 bCopyProtect;
|
||||
__u8 bVariableSize;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define UVC_DT_FORMAT_FRAMEBASED_SIZE 28
|
||||
|
||||
/* Frame Based Payload - 3.1.2. Frame Based Video Frame Descriptor */
|
||||
struct uvc_frame_framebased {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubType;
|
||||
__u8 bFrameIndex;
|
||||
__u8 bmCapabilities;
|
||||
__u16 wWidth;
|
||||
__u16 wHeight;
|
||||
__u32 dwMinBitRate;
|
||||
__u32 dwMaxBitRate;
|
||||
__u32 dwDefaultFrameInterval;
|
||||
__u8 bFrameIntervalType;
|
||||
__u32 dwBytesPerLine;
|
||||
__u32 dwFrameInterval[];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define UVC_DT_FRAME_FRAMEBASED_SIZE(n) (26+4*(n))
|
||||
|
||||
#define UVC_FRAME_FRAMEBASED(n) \
|
||||
uvc_frame_framebased_##n
|
||||
|
||||
#define DECLARE_UVC_FRAME_FRAMEBASED(n) \
|
||||
struct UVC_FRAME_FRAMEBASED(n) { \
|
||||
__u8 bLength; \
|
||||
__u8 bDescriptorType; \
|
||||
__u8 bDescriptorSubType; \
|
||||
__u8 bFrameIndex; \
|
||||
__u8 bmCapabilities; \
|
||||
__u16 wWidth; \
|
||||
__u16 wHeight; \
|
||||
__u32 dwMinBitRate; \
|
||||
__u32 dwMaxBitRate; \
|
||||
__u32 dwDefaultFrameInterval; \
|
||||
__u8 bFrameIntervalType; \
|
||||
__u32 dwBytesPerLine; \
|
||||
__u32 dwFrameInterval[n]; \
|
||||
} __attribute__ ((packed))
|
||||
|
||||
#endif /* __LINUX_USB_VIDEO_H */
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,10 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
const struct nf_br_ops *nf_ops;
|
||||
const unsigned char *dest;
|
||||
u16 vid = 0;
|
||||
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
|
||||
struct net_bridge_port *pdst;
|
||||
br_get_dst_hook_t *get_dst_hook;
|
||||
#endif
|
||||
|
||||
if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) {
|
||||
kfree_skb(skb);
|
||||
|
|
@ -82,6 +86,10 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
br_do_suppress_nd(skb, br, vid, NULL, msg);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
|
||||
get_dst_hook = rcu_dereference(br_get_dst_hook);
|
||||
#endif
|
||||
|
||||
dest = eth_hdr(skb)->h_dest;
|
||||
if (is_broadcast_ether_addr(dest)) {
|
||||
br_flood(br, skb, BR_PKT_BROADCAST, false, true);
|
||||
|
|
@ -107,11 +115,24 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
br_multicast_flood(mdst, skb, false, true);
|
||||
else
|
||||
br_flood(br, skb, BR_PKT_MULTICAST, false, true);
|
||||
} else if ((dst = br_fdb_find_rcu(br, dest, vid)) != NULL) {
|
||||
br_forward(dst->dst, skb, false, true);
|
||||
} else {
|
||||
br_flood(br, skb, BR_PKT_UNICAST, false, true);
|
||||
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
|
||||
pdst = __br_get(get_dst_hook, NULL, NULL, &skb);
|
||||
if (pdst) {
|
||||
if (!skb)
|
||||
goto out;
|
||||
br_forward(pdst, skb, false, true);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
dst = br_fdb_find_rcu(br, dest, vid);
|
||||
if (dst)
|
||||
br_forward(dst->dst, skb, false, true);
|
||||
else
|
||||
br_flood(br, skb, BR_PKT_UNICAST, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
return NETDEV_TX_OK;
|
||||
|
|
|
|||
|
|
@ -695,6 +695,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev,
|
|||
br_set_gso_limits(br);
|
||||
|
||||
kobject_uevent(&p->kobj, KOBJ_ADD);
|
||||
call_netdevice_notifiers(NETDEV_BR_JOIN, dev);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
@ -732,6 +733,8 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
|
|||
if (!p || p->br != br)
|
||||
return -EINVAL;
|
||||
|
||||
call_netdevice_notifiers(NETDEV_BR_LEAVE, dev);
|
||||
|
||||
/* Since more than one interface can be attached to a bridge,
|
||||
* there still maybe an alternate path for netconsole to use;
|
||||
* therefore there is no reason for a NETDEV_RELEASE event.
|
||||
|
|
|
|||
|
|
@ -33,6 +33,11 @@ br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb)
|
|||
/* Hook for external Multicast handler */
|
||||
br_multicast_handle_hook_t __rcu *br_multicast_handle_hook __read_mostly;
|
||||
EXPORT_SYMBOL(br_multicast_handle_hook);
|
||||
|
||||
/* Hook for external forwarding logic */
|
||||
br_get_dst_hook_t __rcu *br_get_dst_hook __read_mostly;
|
||||
EXPORT_SYMBOL_GPL(br_get_dst_hook);
|
||||
|
||||
#endif
|
||||
|
||||
int br_pass_frame_up(struct sk_buff *skb)
|
||||
|
|
@ -94,6 +99,8 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
|
|||
struct net_bridge *br;
|
||||
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
|
||||
br_multicast_handle_hook_t *multicast_handle_hook;
|
||||
struct net_bridge_port *pdst = NULL;
|
||||
br_get_dst_hook_t *get_dst_hook = rcu_dereference(br_get_dst_hook);
|
||||
#endif
|
||||
u16 vid = 0;
|
||||
|
||||
|
|
@ -168,7 +175,17 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
|
|||
}
|
||||
break;
|
||||
case BR_PKT_UNICAST:
|
||||
dst = br_fdb_find_rcu(br, eth_hdr(skb)->h_dest, vid);
|
||||
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
|
||||
pdst = __br_get(get_dst_hook, NULL, p, &skb);
|
||||
if (pdst) {
|
||||
if (!skb)
|
||||
goto out;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
dst = br_fdb_find_rcu(br, eth_hdr(skb)->h_dest, vid);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -195,6 +195,9 @@ struct net_bridge_fdb_entry {
|
|||
|
||||
struct net_bridge_fdb_key key;
|
||||
struct hlist_node fdb_node;
|
||||
unsigned char is_local:1,
|
||||
is_static:1;
|
||||
|
||||
unsigned long flags;
|
||||
unsigned char offloaded:1;
|
||||
|
||||
|
|
|
|||
|
|
@ -1521,7 +1521,7 @@ const char *netdev_cmd_to_name(enum netdev_cmd cmd)
|
|||
N(UDP_TUNNEL_DROP_INFO) N(CHANGE_TX_QUEUE_LEN)
|
||||
N(CVLAN_FILTER_PUSH_INFO) N(CVLAN_FILTER_DROP_INFO)
|
||||
N(SVLAN_FILTER_PUSH_INFO) N(SVLAN_FILTER_DROP_INFO)
|
||||
N(PRE_CHANGEADDR)
|
||||
N(PRE_CHANGEADDR) N(BR_JOIN) N(BR_LEAVE)
|
||||
}
|
||||
#undef N
|
||||
return "UNKNOWN_NETDEV_EVENT";
|
||||
|
|
|
|||
Loading…
Reference in a new issue