> +#ifndef CONFIG_DMA_NONCOHERENT I think you need to drop this ifdef. This code should work just fine on noncoherent mips and sh platforms. > + uvc_urb->pages = dma_alloc_noncontiguous(dma_dev, stream->urb_size, > + &uvc_urb->dma, > + gfp_flags | __GFP_NOWARN, 0); > + if (!uvc_urb->pages) > + return false; > + > + uvc_urb->buffer = vmap(uvc_urb->pages, > + PAGE_ALIGN(stream->urb_size) >> PAGE_SHIFT, > + VM_DMA_COHERENT, PAGE_KERNEL); > + if (!uvc_urb->buffer) { > + dma_free_noncontiguous(dma_dev, stream->urb_size, > + uvc_urb->pages, uvc_urb->dma); > + return false; > + } > + > + if (sg_alloc_table_from_pages(&uvc_urb->sgt, uvc_urb->pages, > + PAGE_ALIGN(stream->urb_size) >> PAGE_SHIFT, 0, > + stream->urb_size, GFP_KERNEL)) { > + vunmap(uvc_urb->buffer); > + dma_free_noncontiguous(dma_dev, stream->urb_size, > + uvc_urb->pages, uvc_urb->dma); > + return false; > + } > + > + return true; > +} I wonder if we should lift this into a helper. On the one hand I had proliferating struct scatterlist usage, on the other hand it is all over the media and drm code anyway, and duplicating this doesn't help anyone. Possibly including the fallback to the coherent allocating.