|
@@ -95,7 +95,7 @@ static int cam_ife_mgr_finish_clk_bw_update(
|
|
clk_bw_args.hw_intf = g_ife_hw_mgr.ife_devices[ctx->base[i].idx]->hw_intf;
|
|
clk_bw_args.hw_intf = g_ife_hw_mgr.ife_devices[ctx->base[i].idx]->hw_intf;
|
|
else if ((ctx->base[i].hw_type == CAM_ISP_HW_TYPE_SFE) &&
|
|
else if ((ctx->base[i].hw_type == CAM_ISP_HW_TYPE_SFE) &&
|
|
(ctx->num_acq_sfe_out || (!list_empty(&ctx->res_list_ife_in_rd))))
|
|
(ctx->num_acq_sfe_out || (!list_empty(&ctx->res_list_ife_in_rd))))
|
|
- clk_bw_args.hw_intf = g_ife_hw_mgr.sfe_devices[ctx->base[i].idx];
|
|
|
|
|
|
+ clk_bw_args.hw_intf = g_ife_hw_mgr.sfe_devices[ctx->base[i].idx]->hw_intf;
|
|
else
|
|
else
|
|
continue;
|
|
continue;
|
|
|
|
|
|
@@ -618,7 +618,7 @@ static int cam_ife_hw_mgr_notify_overflow(
|
|
if (hw_mgr_ctx->base[i].idx != evt->in_core_idx)
|
|
if (hw_mgr_ctx->base[i].idx != evt->in_core_idx)
|
|
continue;
|
|
continue;
|
|
|
|
|
|
- hw_if = g_ife_hw_mgr.sfe_devices[evt->in_core_idx];
|
|
|
|
|
|
+ hw_if = g_ife_hw_mgr.sfe_devices[evt->in_core_idx]->hw_intf;
|
|
res_id = sfe_res_id;
|
|
res_id = sfe_res_id;
|
|
} else {
|
|
} else {
|
|
continue;
|
|
continue;
|
|
@@ -2336,7 +2336,7 @@ static int cam_ife_hw_mgr_acquire_sfe_hw(
|
|
if (!ife_hw_mgr->sfe_devices[i])
|
|
if (!ife_hw_mgr->sfe_devices[i])
|
|
continue;
|
|
continue;
|
|
|
|
|
|
- hw_intf = ife_hw_mgr->sfe_devices[i];
|
|
|
|
|
|
+ hw_intf = ife_hw_mgr->sfe_devices[i]->hw_intf;
|
|
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
|
|
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
|
|
sfe_acquire,
|
|
sfe_acquire,
|
|
sizeof(struct cam_sfe_acquire_args));
|
|
sizeof(struct cam_sfe_acquire_args));
|
|
@@ -2354,7 +2354,7 @@ static int cam_ife_hw_mgr_acquire_sfe_hw(
|
|
if (!ife_hw_mgr->sfe_devices[i])
|
|
if (!ife_hw_mgr->sfe_devices[i])
|
|
continue;
|
|
continue;
|
|
|
|
|
|
- hw_intf = ife_hw_mgr->sfe_devices[i];
|
|
|
|
|
|
+ hw_intf = ife_hw_mgr->sfe_devices[i]->hw_intf;
|
|
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
|
|
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
|
|
sfe_acquire,
|
|
sfe_acquire,
|
|
sizeof(struct cam_sfe_acquire_args));
|
|
sizeof(struct cam_sfe_acquire_args));
|
|
@@ -2698,7 +2698,7 @@ static int cam_ife_hw_mgr_acquire_sfe_bus_rd(
|
|
if (!ife_hw_mgr->sfe_devices[i])
|
|
if (!ife_hw_mgr->sfe_devices[i])
|
|
continue;
|
|
continue;
|
|
|
|
|
|
- hw_intf = ife_hw_mgr->sfe_devices[i];
|
|
|
|
|
|
+ hw_intf = ife_hw_mgr->sfe_devices[i]->hw_intf;
|
|
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
|
|
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
|
|
&sfe_acquire, sizeof(struct cam_sfe_acquire_args));
|
|
&sfe_acquire, sizeof(struct cam_sfe_acquire_args));
|
|
if (rc)
|
|
if (rc)
|
|
@@ -2739,7 +2739,7 @@ acquire_successful:
|
|
if (i == sfe_rd_res->hw_res[0]->hw_intf->hw_idx)
|
|
if (i == sfe_rd_res->hw_res[0]->hw_intf->hw_idx)
|
|
continue;
|
|
continue;
|
|
|
|
|
|
- hw_intf = ife_hw_mgr->sfe_devices[i];
|
|
|
|
|
|
+ hw_intf = ife_hw_mgr->sfe_devices[i]->hw_intf;
|
|
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
|
|
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
|
|
&sfe_acquire, sizeof(sfe_acquire));
|
|
&sfe_acquire, sizeof(sfe_acquire));
|
|
if (rc)
|
|
if (rc)
|
|
@@ -3928,7 +3928,7 @@ static int cam_ife_hw_mgr_acquire_offline_res_sfe(
|
|
sfe_acquire.sfe_in.res_id = CAM_ISP_HW_SFE_IN_PIX;
|
|
sfe_acquire.sfe_in.res_id = CAM_ISP_HW_SFE_IN_PIX;
|
|
|
|
|
|
hw_intf = ife_hw_mgr->sfe_devices[
|
|
hw_intf = ife_hw_mgr->sfe_devices[
|
|
- sfe_bus_rd_res->hw_res[i]->hw_intf->hw_idx];
|
|
|
|
|
|
+ sfe_bus_rd_res->hw_res[i]->hw_intf->hw_idx]->hw_intf;
|
|
|
|
|
|
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &sfe_acquire,
|
|
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &sfe_acquire,
|
|
sizeof(struct cam_sfe_acquire_args));
|
|
sizeof(struct cam_sfe_acquire_args));
|
|
@@ -3953,7 +3953,7 @@ static int cam_ife_hw_mgr_acquire_offline_res_sfe(
|
|
|
|
|
|
sfe_acquire.sfe_in.rsrc_node = NULL;
|
|
sfe_acquire.sfe_in.rsrc_node = NULL;
|
|
hw_intf = ife_hw_mgr->sfe_devices[
|
|
hw_intf = ife_hw_mgr->sfe_devices[
|
|
- sfe_bus_rd_res->hw_res[++i]->hw_intf->hw_idx];
|
|
|
|
|
|
+ sfe_bus_rd_res->hw_res[++i]->hw_intf->hw_idx]->hw_intf;
|
|
|
|
|
|
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &sfe_acquire,
|
|
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &sfe_acquire,
|
|
sizeof(struct cam_sfe_acquire_args));
|
|
sizeof(struct cam_sfe_acquire_args));
|
|
@@ -6406,8 +6406,8 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
|
|
debug_cfg.u.dbg_cfg.sfe_debug_cfg = g_ife_hw_mgr.debug_cfg.sfe_debug;
|
|
debug_cfg.u.dbg_cfg.sfe_debug_cfg = g_ife_hw_mgr.debug_cfg.sfe_debug;
|
|
debug_cfg.u.dbg_cfg.sfe_sensor_sel = g_ife_hw_mgr.debug_cfg.sfe_sensor_diag_cfg;
|
|
debug_cfg.u.dbg_cfg.sfe_sensor_sel = g_ife_hw_mgr.debug_cfg.sfe_sensor_diag_cfg;
|
|
if (g_ife_hw_mgr.sfe_devices[i]) {
|
|
if (g_ife_hw_mgr.sfe_devices[i]) {
|
|
- rc = g_ife_hw_mgr.sfe_devices[i]->hw_ops.process_cmd(
|
|
|
|
- g_ife_hw_mgr.sfe_devices[i]->hw_priv,
|
|
|
|
|
|
+ rc = g_ife_hw_mgr.sfe_devices[i]->hw_intf->hw_ops.process_cmd(
|
|
|
|
+ g_ife_hw_mgr.sfe_devices[i]->hw_intf->hw_priv,
|
|
CAM_ISP_HW_CMD_SET_SFE_DEBUG_CFG,
|
|
CAM_ISP_HW_CMD_SET_SFE_DEBUG_CFG,
|
|
&debug_cfg,
|
|
&debug_cfg,
|
|
sizeof(debug_cfg));
|
|
sizeof(debug_cfg));
|
|
@@ -7861,7 +7861,7 @@ static int cam_isp_blob_sfe_core_cfg_update(
|
|
!ife_hw_mgr->sfe_devices[idx])
|
|
!ife_hw_mgr->sfe_devices[idx])
|
|
continue;
|
|
continue;
|
|
|
|
|
|
- hw_intf = ife_hw_mgr->sfe_devices[idx];
|
|
|
|
|
|
+ hw_intf = ife_hw_mgr->sfe_devices[idx]->hw_intf;
|
|
if (hw_intf && hw_intf->hw_ops.process_cmd) {
|
|
if (hw_intf && hw_intf->hw_ops.process_cmd) {
|
|
memcpy(&sfe_core_config.core_config,
|
|
memcpy(&sfe_core_config.core_config,
|
|
core_config,
|
|
core_config,
|
|
@@ -10467,19 +10467,51 @@ static void cam_ife_mgr_pf_dump(uint32_t res_id,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void cam_ife_mgr_pf_dump_mid_info(
|
|
|
|
+ struct cam_ife_hw_mgr_ctx *ctx,
|
|
|
|
+ struct cam_hw_cmd_args *hw_cmd_args,
|
|
|
|
+ struct cam_isp_hw_intf_data *hw_intf_data)
|
|
|
|
+{
|
|
|
|
+ struct cam_packet *packet;
|
|
|
|
+ struct cam_isp_hw_get_cmd_update cmd_update;
|
|
|
|
+ struct cam_isp_hw_get_res_for_mid get_res;
|
|
|
|
+ int rc = 0;
|
|
|
|
+
|
|
|
|
+ packet = hw_cmd_args->u.pf_args.pf_data.packet;
|
|
|
|
+ get_res.mid = hw_cmd_args->u.pf_args.mid;
|
|
|
|
+ cmd_update.cmd_type = CAM_ISP_HW_CMD_GET_RES_FOR_MID;
|
|
|
|
+ cmd_update.data = (void *) &get_res;
|
|
|
|
+
|
|
|
|
+ /* get resource id for given mid */
|
|
|
|
+ rc = hw_intf_data->hw_intf->hw_ops.process_cmd(hw_intf_data->hw_intf->hw_priv,
|
|
|
|
+ cmd_update.cmd_type, &cmd_update, sizeof(struct cam_isp_hw_get_cmd_update));
|
|
|
|
+
|
|
|
|
+ if (rc) {
|
|
|
|
+ CAM_ERR(CAM_ISP,
|
|
|
|
+ "getting mid port resource id failed ctx id:%d req id:%lld",
|
|
|
|
+ ctx->ctx_index, packet->header.request_id);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ *(hw_cmd_args->u.pf_args.resource_type) = get_res.out_res_id;
|
|
|
|
+ ctx->flags.pf_mid_found = true;
|
|
|
|
+ ctx->pf_info.mid = get_res.mid;
|
|
|
|
+ ctx->pf_info.out_port_id = get_res.out_res_id;
|
|
|
|
+ CAM_ERR(CAM_ISP,
|
|
|
|
+ "Page fault on resource id:(0x%x) ctx id:%d req id:%lld",
|
|
|
|
+ get_res.out_res_id, ctx->ctx_index, packet->header.request_id);
|
|
|
|
+}
|
|
|
|
+
|
|
static void cam_ife_mgr_dump_pf_data(
|
|
static void cam_ife_mgr_dump_pf_data(
|
|
struct cam_ife_hw_mgr *hw_mgr,
|
|
struct cam_ife_hw_mgr *hw_mgr,
|
|
struct cam_hw_cmd_args *hw_cmd_args)
|
|
struct cam_hw_cmd_args *hw_cmd_args)
|
|
{
|
|
{
|
|
- struct cam_ife_hw_mgr_ctx *ctx;
|
|
|
|
- struct cam_isp_hw_mgr_res *hw_mgr_res;
|
|
|
|
- struct cam_isp_hw_get_cmd_update cmd_update;
|
|
|
|
- struct cam_isp_hw_get_res_for_mid get_res;
|
|
|
|
|
|
+ struct cam_ife_hw_mgr_ctx *ctx;
|
|
struct cam_packet *packet;
|
|
struct cam_packet *packet;
|
|
- uint32_t hw_id;
|
|
|
|
- uint32_t *resource_type;
|
|
|
|
- bool *ctx_found, hw_id_found = false;
|
|
|
|
- int i, j, rc = 0;
|
|
|
|
|
|
+ struct cam_isp_hw_intf_data *hw_intf_data;
|
|
|
|
+ uint32_t *resource_type;
|
|
|
|
+ bool *ctx_found;
|
|
|
|
+ int i, j;
|
|
|
|
|
|
ctx = (struct cam_ife_hw_mgr_ctx *)hw_cmd_args->ctxt_to_hw_map;
|
|
ctx = (struct cam_ife_hw_mgr_ctx *)hw_cmd_args->ctxt_to_hw_map;
|
|
|
|
|
|
@@ -10493,93 +10525,49 @@ static void cam_ife_mgr_dump_pf_data(
|
|
if (ctx->flags.pf_mid_found)
|
|
if (ctx->flags.pf_mid_found)
|
|
goto outportlog;
|
|
goto outportlog;
|
|
|
|
|
|
- if (!g_ife_hw_mgr.hw_pid_support)
|
|
|
|
- goto mid_check;
|
|
|
|
|
|
+ for (i = 0; i < ctx->num_base; i++) {
|
|
|
|
+ if (ctx->base[i].hw_type == CAM_ISP_HW_TYPE_VFE)
|
|
|
|
+ hw_intf_data = g_ife_hw_mgr.ife_devices[ctx->base[i].idx];
|
|
|
|
+ else if (ctx->base[i].hw_type == CAM_ISP_HW_TYPE_SFE)
|
|
|
|
+ hw_intf_data = g_ife_hw_mgr.sfe_devices[ctx->base[i].idx];
|
|
|
|
+ else
|
|
|
|
+ continue;
|
|
|
|
|
|
- for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
|
|
|
|
- if (!hw_mgr->ife_devices[i])
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Few old targets do not have support for PID, for such targets,
|
|
|
|
+ * we need to print mid for all the bases, SFE enabled targets
|
|
|
|
+ * are expected to have PID support.
|
|
|
|
+ */
|
|
|
|
+ if (!g_ife_hw_mgr.hw_pid_support) {
|
|
|
|
+ if (ctx->base[i].split_id == CAM_ISP_HW_SPLIT_LEFT)
|
|
|
|
+ cam_ife_mgr_pf_dump_mid_info(ctx, hw_cmd_args, hw_intf_data);
|
|
continue;
|
|
continue;
|
|
|
|
+ }
|
|
|
|
|
|
- for (j = 0; j < g_ife_hw_mgr.ife_devices[i]->num_hw_pid; j++) {
|
|
|
|
- if (g_ife_hw_mgr.ife_devices[i]->hw_pid[j] ==
|
|
|
|
- hw_cmd_args->u.pf_args.pid) {
|
|
|
|
- hw_id_found = true;
|
|
|
|
- hw_id = i;
|
|
|
|
|
|
+ for (j = 0; j < hw_intf_data->num_hw_pid; j++) {
|
|
|
|
+ if (hw_intf_data->hw_pid[j] == hw_cmd_args->u.pf_args.pid) {
|
|
|
|
+ *ctx_found = true;
|
|
|
|
+ CAM_ERR(CAM_ISP, "PF found for %s%d pid: %u",
|
|
|
|
+ ctx->base[i].hw_type == CAM_ISP_HW_TYPE_VFE ? "VFE" : "SFE",
|
|
|
|
+ ctx->base[i].idx, hw_cmd_args->u.pf_args.pid);
|
|
|
|
+ cam_ife_mgr_pf_dump_mid_info(ctx, hw_cmd_args, hw_intf_data);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- if (hw_id_found)
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
|
|
|
|
- if (i == CAM_IFE_HW_NUM_MAX) {
|
|
|
|
- CAM_INFO(CAM_ISP,
|
|
|
|
- "PID:%d is not matching with any IFE HW PIDs ctx id:%d",
|
|
|
|
- hw_cmd_args->u.pf_args.pid, ctx->ctx_index);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- for (i = 0; i < ctx->num_base; i++) {
|
|
|
|
- if (ctx->base[i].idx == hw_id) {
|
|
|
|
- *ctx_found = true;
|
|
|
|
|
|
+ if (*ctx_found)
|
|
break;
|
|
break;
|
|
- }
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- if (!(*ctx_found)) {
|
|
|
|
|
|
+ if (g_ife_hw_mgr.hw_pid_support && (i == ctx->num_base || !*ctx_found))
|
|
CAM_INFO(CAM_ISP,
|
|
CAM_INFO(CAM_ISP,
|
|
- "This context does not cause pf:pid:%d hw id:%d ctx_id:%d",
|
|
|
|
- hw_cmd_args->u.pf_args.pid, hw_id, ctx->ctx_index);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-mid_check:
|
|
|
|
- for (i = 0; i < max_ife_out_res; i++) {
|
|
|
|
- hw_mgr_res = &ctx->res_list_ife_out[i];
|
|
|
|
- if (!hw_mgr_res->hw_res[0])
|
|
|
|
- continue;
|
|
|
|
-
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (i >= max_ife_out_res) {
|
|
|
|
- CAM_ERR(CAM_ISP,
|
|
|
|
- "NO valid outport resources ctx id:%d req id:%lld",
|
|
|
|
- ctx->ctx_index, packet->header.request_id);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- get_res.mid = hw_cmd_args->u.pf_args.mid;
|
|
|
|
- cmd_update.res = hw_mgr_res->hw_res[0];
|
|
|
|
- cmd_update.cmd_type = CAM_ISP_HW_CMD_GET_RES_FOR_MID;
|
|
|
|
- cmd_update.data = (void *) &get_res;
|
|
|
|
-
|
|
|
|
- /* get resource id for given mid */
|
|
|
|
- rc = hw_mgr_res->hw_res[0]->hw_intf->hw_ops.process_cmd(
|
|
|
|
- hw_mgr_res->hw_res[0]->hw_intf->hw_priv,
|
|
|
|
- cmd_update.cmd_type, &cmd_update,
|
|
|
|
- sizeof(struct cam_isp_hw_get_cmd_update));
|
|
|
|
-
|
|
|
|
- if (rc) {
|
|
|
|
- CAM_ERR(CAM_ISP,
|
|
|
|
- "getting mid port resource id failed ctx id:%d req id:%lld",
|
|
|
|
- ctx->ctx_index, packet->header.request_id);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- CAM_ERR(CAM_ISP,
|
|
|
|
- "Page fault on resource id:(0x%x) ctx id:%d req id:%lld",
|
|
|
|
- get_res.out_res_id, ctx->ctx_index, packet->header.request_id);
|
|
|
|
- *resource_type = get_res.out_res_id;
|
|
|
|
- ctx->flags.pf_mid_found = true;
|
|
|
|
- ctx->pf_info.mid = get_res.mid;
|
|
|
|
- ctx->pf_info.out_port_id = get_res.out_res_id;
|
|
|
|
- cam_ife_mgr_pf_dump(get_res.out_res_id, ctx);
|
|
|
|
|
|
+ "This context does not cause pf:pid:%d ctx_id:%d",
|
|
|
|
+ hw_cmd_args->u.pf_args.pid, ctx->ctx_index);
|
|
|
|
+ cam_ife_mgr_pf_dump(ctx->pf_info.out_port_id, ctx);
|
|
|
|
|
|
outportlog:
|
|
outportlog:
|
|
cam_ife_mgr_print_io_bufs(hw_mgr, *resource_type, packet,
|
|
cam_ife_mgr_print_io_bufs(hw_mgr, *resource_type, packet,
|
|
ctx_found, ctx);
|
|
ctx_found, ctx);
|
|
-
|
|
|
|
}
|
|
}
|
|
|
|
|
|
int cam_isp_config_csid_rup_aup(
|
|
int cam_isp_config_csid_rup_aup(
|
|
@@ -12099,7 +12087,7 @@ static int cam_ife_set_sfe_cache_debug(void *data, u64 val)
|
|
hw_idx = val & 0xF;
|
|
hw_idx = val & 0xF;
|
|
for (i = 0; i < CAM_SFE_HW_NUM_MAX; i++) {
|
|
for (i = 0; i < CAM_SFE_HW_NUM_MAX; i++) {
|
|
if ((g_ife_hw_mgr.sfe_devices[i]) && (i == hw_idx)) {
|
|
if ((g_ife_hw_mgr.sfe_devices[i]) && (i == hw_idx)) {
|
|
- hw_intf = g_ife_hw_mgr.sfe_devices[i];
|
|
|
|
|
|
+ hw_intf = g_ife_hw_mgr.sfe_devices[i]->hw_intf;
|
|
|
|
|
|
debug_cfg.u.cache_cfg.sfe_cache_dbg = (val >> 4);
|
|
debug_cfg.u.cache_cfg.sfe_cache_dbg = (val >> 4);
|
|
g_ife_hw_mgr.debug_cfg.sfe_cache_debug[i] =
|
|
g_ife_hw_mgr.debug_cfg.sfe_cache_debug[i] =
|
|
@@ -12486,7 +12474,7 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
|
|
if (!rc) {
|
|
if (!rc) {
|
|
if (j == 0) {
|
|
if (j == 0) {
|
|
struct cam_hw_intf *sfe_device =
|
|
struct cam_hw_intf *sfe_device =
|
|
- g_ife_hw_mgr.sfe_devices[i];
|
|
|
|
|
|
+ g_ife_hw_mgr.sfe_devices[i]->hw_intf;
|
|
struct cam_hw_info *sfe_hw =
|
|
struct cam_hw_info *sfe_hw =
|
|
(struct cam_hw_info *)
|
|
(struct cam_hw_info *)
|
|
sfe_device->hw_priv;
|
|
sfe_device->hw_priv;
|
|
@@ -12501,6 +12489,9 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
|
|
if (!rc)
|
|
if (!rc)
|
|
g_ife_hw_mgr.isp_bus_caps.max_sfe_out_res_type =
|
|
g_ife_hw_mgr.isp_bus_caps.max_sfe_out_res_type =
|
|
isp_bus_cap.max_out_res_type;
|
|
isp_bus_cap.max_out_res_type;
|
|
|
|
+
|
|
|
|
+ if (g_ife_hw_mgr.sfe_devices[i]->num_hw_pid)
|
|
|
|
+ g_ife_hw_mgr.hw_pid_support = true;
|
|
}
|
|
}
|
|
j++;
|
|
j++;
|
|
}
|
|
}
|