if (dst != src) {
                if (src_nents)
                        dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
-               dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
+               if (dst_nents)
+                       dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
        } else {
                dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
        }
        out_options = in_options;
 
        if (unlikely(req->src != req->dst)) {
-               if (edesc->dst_nents == 1) {
+               if (!edesc->dst_nents) {
+                       dst_dma = 0;
+               } else if (edesc->dst_nents == 1) {
                        dst_dma = sg_dma_address(req->dst);
                } else {
                        dst_dma = edesc->sec4_sg_dma +
                        mapped_src_nents = 0;
                }
 
-               mapped_dst_nents = dma_map_sg(jrdev, req->dst, dst_nents,
-                                             DMA_FROM_DEVICE);
-               if (unlikely(!mapped_dst_nents)) {
-                       dev_err(jrdev, "unable to map destination\n");
-                       dma_unmap_sg(jrdev, req->src, src_nents, DMA_TO_DEVICE);
-                       return ERR_PTR(-ENOMEM);
+               /* Cover also the case of null (zero length) output data */
+               if (dst_nents) {
+                       mapped_dst_nents = dma_map_sg(jrdev, req->dst,
+                                                     dst_nents,
+                                                     DMA_FROM_DEVICE);
+                       if (unlikely(!mapped_dst_nents)) {
+                               dev_err(jrdev, "unable to map destination\n");
+                               dma_unmap_sg(jrdev, req->src, src_nents,
+                                            DMA_TO_DEVICE);
+                               return ERR_PTR(-ENOMEM);
+                       }
+               } else {
+                       mapped_dst_nents = 0;
                }
        }
 
 
        if (dst != src) {
                if (src_nents)
                        dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
-               dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
+               if (dst_nents)
+                       dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
        } else {
                dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
        }
                        mapped_src_nents = 0;
                }
 
-               mapped_dst_nents = dma_map_sg(qidev, req->dst, dst_nents,
-                                             DMA_FROM_DEVICE);
-               if (unlikely(!mapped_dst_nents)) {
-                       dev_err(qidev, "unable to map destination\n");
-                       dma_unmap_sg(qidev, req->src, src_nents, DMA_TO_DEVICE);
-                       qi_cache_free(edesc);
-                       return ERR_PTR(-ENOMEM);
+               if (dst_nents) {
+                       mapped_dst_nents = dma_map_sg(qidev, req->dst,
+                                                     dst_nents,
+                                                     DMA_FROM_DEVICE);
+                       if (unlikely(!mapped_dst_nents)) {
+                               dev_err(qidev, "unable to map destination\n");
+                               dma_unmap_sg(qidev, req->src, src_nents,
+                                            DMA_TO_DEVICE);
+                               qi_cache_free(edesc);
+                               return ERR_PTR(-ENOMEM);
+                       }
+               } else {
+                       mapped_dst_nents = 0;
                }
        }
 
 
        if (dst != src) {
                if (src_nents)
                        dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
-               dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
+               if (dst_nents)
+                       dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
        } else {
                dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
        }
                        mapped_src_nents = 0;
                }
 
-               mapped_dst_nents = dma_map_sg(dev, req->dst, dst_nents,
-                                             DMA_FROM_DEVICE);
-               if (unlikely(!mapped_dst_nents)) {
-                       dev_err(dev, "unable to map destination\n");
-                       dma_unmap_sg(dev, req->src, src_nents, DMA_TO_DEVICE);
-                       qi_cache_free(edesc);
-                       return ERR_PTR(-ENOMEM);
+               if (dst_nents) {
+                       mapped_dst_nents = dma_map_sg(dev, req->dst, dst_nents,
+                                                     DMA_FROM_DEVICE);
+                       if (unlikely(!mapped_dst_nents)) {
+                               dev_err(dev, "unable to map destination\n");
+                               dma_unmap_sg(dev, req->src, src_nents,
+                                            DMA_TO_DEVICE);
+                               qi_cache_free(edesc);
+                               return ERR_PTR(-ENOMEM);
+                       }
+               } else {
+                       mapped_dst_nents = 0;
                }
        } else {
                src_nents = sg_nents_for_len(req->src, req->assoclen +