struct hisi_zip_req {
        struct acomp_req *req;
-       struct scatterlist *src;
-       struct scatterlist *dst;
-       size_t slen;
-       size_t dlen;
+       int sskip;
+       int dskip;
        struct hisi_acc_hw_sgl *hw_src;
        struct hisi_acc_hw_sgl *hw_dst;
        dma_addr_t dma_src;
 
 static void hisi_zip_fill_sqe(struct hisi_zip_sqe *sqe, u8 req_type,
                              dma_addr_t s_addr, dma_addr_t d_addr, u32 slen,
-                             u32 dlen)
+                             u32 dlen, int sskip, int dskip)
 {
        memset(sqe, 0, sizeof(struct hisi_zip_sqe));
 
-       sqe->input_data_length = slen;
+       sqe->input_data_length = slen - sskip;
+       sqe->dw7 = FIELD_PREP(HZIP_IN_SGE_DATA_OFFSET_M, sskip);
+       sqe->dw8 = FIELD_PREP(HZIP_OUT_SGE_DATA_OFFSET_M, dskip);
        sqe->dw9 = FIELD_PREP(HZIP_REQ_TYPE_M, req_type);
-       sqe->dest_avail_out = dlen;
+       sqe->dest_avail_out = dlen - dskip;
        sqe->source_addr_l = lower_32_bits(s_addr);
        sqe->source_addr_h = upper_32_bits(s_addr);
        sqe->dest_addr_l = lower_32_bits(d_addr);
 {
        struct hisi_zip_req_q *req_q = &qp_ctx->req_q;
 
-       if (qp_ctx->qp->alg_type == HZIP_ALG_TYPE_COMP)
-               kfree(req->dst);
-       else
-               kfree(req->src);
-
        write_lock(&req_q->req_lock);
        clear_bit(req->req_id, req_q->req_bitmap);
        memset(req, 0, sizeof(struct hisi_zip_req));
        }
        dlen = sqe->produced;
 
-       hisi_acc_sg_buf_unmap(dev, req->src, req->hw_src);
-       hisi_acc_sg_buf_unmap(dev, req->dst, req->hw_dst);
+       hisi_acc_sg_buf_unmap(dev, acomp_req->src, req->hw_src);
+       hisi_acc_sg_buf_unmap(dev, acomp_req->dst, req->hw_dst);
 
        head_size = (qp->alg_type == 0) ? TO_HEAD_SIZE(qp->req_type) : 0;
        acomp_req->dlen = dlen + head_size;
        }
 }
 
-static int get_sg_skip_bytes(struct scatterlist *sgl, size_t bytes,
-                            size_t remains, struct scatterlist **out)
-{
-#define SPLIT_NUM 2
-       size_t split_sizes[SPLIT_NUM];
-       int out_mapped_nents[SPLIT_NUM];
-
-       split_sizes[0] = bytes;
-       split_sizes[1] = remains;
-
-       return sg_split(sgl, 0, 0, SPLIT_NUM, split_sizes, out,
-                       out_mapped_nents, GFP_KERNEL);
-}
-
 static struct hisi_zip_req *hisi_zip_create_req(struct acomp_req *req,
                                                struct hisi_zip_qp_ctx *qp_ctx,
                                                size_t head_size, bool is_comp)
        struct hisi_zip_req_q *req_q = &qp_ctx->req_q;
        struct hisi_zip_req *q = req_q->q;
        struct hisi_zip_req *req_cache;
-       struct scatterlist *out[2];
-       struct scatterlist *sgl;
-       size_t len;
-       int ret, req_id;
-
-       /*
-        * remove/add zlib/gzip head, as hardware operations do not include
-        * comp head. so split req->src to get sgl without heads in acomp, or
-        * add comp head to req->dst ahead of that hardware output compressed
-        * data in sgl splited from req->dst without comp head.
-        */
-       if (is_comp) {
-               sgl = req->dst;
-               len = req->dlen - head_size;
-       } else {
-               sgl = req->src;
-               len = req->slen - head_size;
-       }
-
-       ret = get_sg_skip_bytes(sgl, head_size, len, out);
-       if (ret)
-               return ERR_PTR(ret);
-
-       /* sgl for comp head is useless, so free it now */
-       kfree(out[0]);
+       int req_id;
 
        write_lock(&req_q->req_lock);
 
        if (req_id >= req_q->size) {
                write_unlock(&req_q->req_lock);
                dev_dbg(&qp_ctx->qp->qm->pdev->dev, "req cache is full!\n");
-               kfree(out[1]);
                return ERR_PTR(-EBUSY);
        }
        set_bit(req_id, req_q->req_bitmap);
        req_cache = q + req_id;
        req_cache->req_id = req_id;
        req_cache->req = req;
+
        if (is_comp) {
-               req_cache->src = req->src;
-               req_cache->dst = out[1];
-               req_cache->slen = req->slen;
-               req_cache->dlen = req->dlen - head_size;
+               req_cache->sskip = 0;
+               req_cache->dskip = head_size;
        } else {
-               req_cache->src = out[1];
-               req_cache->dst = req->dst;
-               req_cache->slen = req->slen - head_size;
-               req_cache->dlen = req->dlen;
+               req_cache->sskip = head_size;
+               req_cache->dskip = 0;
        }
 
        write_unlock(&req_q->req_lock);
                            struct hisi_zip_qp_ctx *qp_ctx)
 {
        struct hisi_zip_sqe *zip_sqe = &qp_ctx->zip_sqe;
+       struct acomp_req *a_req = req->req;
        struct hisi_qp *qp = qp_ctx->qp;
        struct device *dev = &qp->qm->pdev->dev;
        struct hisi_acc_sgl_pool *pool = qp_ctx->sgl_pool;
        dma_addr_t output;
        int ret;
 
-       if (!req->src || !req->slen || !req->dst || !req->dlen)
+       if (!a_req->src || !a_req->slen || !a_req->dst || !a_req->dlen)
                return -EINVAL;
 
-       req->hw_src = hisi_acc_sg_buf_map_to_hw_sgl(dev, req->src, pool,
+       req->hw_src = hisi_acc_sg_buf_map_to_hw_sgl(dev, a_req->src, pool,
                                                    req->req_id << 1, &input);
        if (IS_ERR(req->hw_src))
                return PTR_ERR(req->hw_src);
        req->dma_src = input;
 
-       req->hw_dst = hisi_acc_sg_buf_map_to_hw_sgl(dev, req->dst, pool,
+       req->hw_dst = hisi_acc_sg_buf_map_to_hw_sgl(dev, a_req->dst, pool,
                                                    (req->req_id << 1) + 1,
                                                    &output);
        if (IS_ERR(req->hw_dst)) {
        }
        req->dma_dst = output;
 
-       hisi_zip_fill_sqe(zip_sqe, qp->req_type, input, output, req->slen,
-                         req->dlen);
+       hisi_zip_fill_sqe(zip_sqe, qp->req_type, input, output, a_req->slen,
+                         a_req->dlen, req->sskip, req->dskip);
        hisi_zip_config_buf_type(zip_sqe, HZIP_SGL);
        hisi_zip_config_tag(zip_sqe, req->req_id);
 
        return -EINPROGRESS;
 
 err_unmap_output:
-       hisi_acc_sg_buf_unmap(dev, req->dst, req->hw_dst);
+       hisi_acc_sg_buf_unmap(dev, a_req->dst, req->hw_dst);
 err_unmap_input:
-       hisi_acc_sg_buf_unmap(dev, req->src, req->hw_src);
+       hisi_acc_sg_buf_unmap(dev, a_req->src, req->hw_src);
        return ret;
 }