static void stk1160_isoc_irq(struct urb *urb)
 {
        int i, rc;
-       struct stk1160 *dev = urb->context;
+       struct stk1160_urb *stk_urb = urb->context;
+       struct stk1160 *dev = stk_urb->dev;
+       struct device *dma_dev = stk1160_get_dmadev(dev);
 
        switch (urb->status) {
        case 0:
                return;
        }
 
+       invalidate_kernel_vmap_range(stk_urb->transfer_buffer,
+                                    urb->transfer_buffer_length);
+       dma_sync_sgtable_for_cpu(dma_dev, stk_urb->sgt, DMA_FROM_DEVICE);
+
        stk1160_process_isoc(dev, urb);
 
        /* Reset urb buffers */
                urb->iso_frame_desc[i].actual_length = 0;
        }
 
+       dma_sync_sgtable_for_device(dma_dev, stk_urb->sgt, DMA_FROM_DEVICE);
        rc = usb_submit_urb(urb, GFP_ATOMIC);
        if (rc)
                stk1160_err("urb re-submit failed (%d)\n", rc);
        stk1160_dbg("all urbs killed\n");
 }
 
+static void stk_free_urb(struct stk1160 *dev, struct stk1160_urb *stk_urb)
+{
+       struct device *dma_dev = stk1160_get_dmadev(dev);
+
+       dma_vunmap_noncontiguous(dma_dev, stk_urb->transfer_buffer);
+       dma_free_noncontiguous(dma_dev, stk_urb->urb->transfer_buffer_length,
+                              stk_urb->sgt, DMA_FROM_DEVICE);
+       usb_free_urb(stk_urb->urb);
+
+       stk_urb->transfer_buffer = NULL;
+       stk_urb->sgt = NULL;
+       stk_urb->urb = NULL;
+       stk_urb->dev = NULL;
+       stk_urb->dma = 0;
+}
+
 /*
  * Releases urb and transfer buffers
  * Obviusly, associated urb must be killed before releasing it.
  */
 void stk1160_free_isoc(struct stk1160 *dev)
 {
-       struct urb *urb;
        int i, num_bufs = dev->isoc_ctl.num_bufs;
 
        stk1160_dbg("freeing %d urb buffers...\n", num_bufs);
 
-       for (i = 0; i < num_bufs; i++) {
-
-               urb = dev->isoc_ctl.urb_ctl[i].urb;
-               if (urb) {
-
-                       if (dev->isoc_ctl.urb_ctl[i].transfer_buffer) {
-#ifndef CONFIG_DMA_NONCOHERENT
-                               usb_free_coherent(dev->udev,
-                                       urb->transfer_buffer_length,
-                                       dev->isoc_ctl.urb_ctl[i].transfer_buffer,
-                                       urb->transfer_dma);
-#else
-                               kfree(dev->isoc_ctl.urb_ctl[i].transfer_buffer);
-#endif
-                       }
-                       usb_free_urb(urb);
-                       dev->isoc_ctl.urb_ctl[i].urb = NULL;
-               }
-               dev->isoc_ctl.urb_ctl[i].transfer_buffer = NULL;
-       }
+       for (i = 0; i < num_bufs; i++)
+               stk_free_urb(dev, &dev->isoc_ctl.urb_ctl[i]);
 
        dev->isoc_ctl.num_bufs = 0;
 
        stk1160_free_isoc(dev);
 }
 
+static int stk1160_fill_urb(struct stk1160 *dev, struct stk1160_urb *stk_urb,
+                           int sb_size, int max_packets)
+{
+       struct device *dma_dev = stk1160_get_dmadev(dev);
+
+       stk_urb->urb = usb_alloc_urb(max_packets, GFP_KERNEL);
+       if (!stk_urb->urb)
+               return -ENOMEM;
+       stk_urb->sgt = dma_alloc_noncontiguous(dma_dev, sb_size,
+                                              DMA_FROM_DEVICE, GFP_KERNEL, 0);
+
+       /*
+        * If the buffer allocation failed, we exit but return 0 since
+        * we allow the driver working with less buffers
+        */
+       if (!stk_urb->sgt)
+               goto free_urb;
+
+       stk_urb->transfer_buffer = dma_vmap_noncontiguous(dma_dev, sb_size,
+                                                         stk_urb->sgt);
+       if (!stk_urb->transfer_buffer)
+               goto free_sgt;
+
+       stk_urb->dma = stk_urb->sgt->sgl->dma_address;
+       stk_urb->dev = dev;
+       return 0;
+free_sgt:
+       dma_free_noncontiguous(dma_dev, sb_size, stk_urb->sgt, DMA_FROM_DEVICE);
+       stk_urb->sgt = NULL;
+free_urb:
+       usb_free_urb(stk_urb->urb);
+       stk_urb->urb = NULL;
+
+       return 0;
+}
 /*
  * Allocate URBs
  */
 {
        struct urb *urb;
        int i, j, k, sb_size, max_packets, num_bufs;
+       int ret;
 
        /*
         * It may be necessary to release isoc here,
        /* allocate urbs and transfer buffers */
        for (i = 0; i < num_bufs; i++) {
 
-               urb = usb_alloc_urb(max_packets, GFP_KERNEL);
-               if (!urb)
+               ret = stk1160_fill_urb(dev, &dev->isoc_ctl.urb_ctl[i],
+                                      sb_size, max_packets);
+               if (ret)
                        goto free_i_bufs;
-               dev->isoc_ctl.urb_ctl[i].urb = urb;
-
-#ifndef CONFIG_DMA_NONCOHERENT
-               dev->isoc_ctl.urb_ctl[i].transfer_buffer =
-                       usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL,
-                                          &urb->transfer_dma);
-#else
-               dev->isoc_ctl.urb_ctl[i].transfer_buffer =
-                       kmalloc(sb_size, GFP_KERNEL);
-#endif
-               if (!dev->isoc_ctl.urb_ctl[i].transfer_buffer) {
-                       stk1160_err("cannot alloc %d bytes for tx[%d] buffer\n",
-                               sb_size, i);
 
+               urb = dev->isoc_ctl.urb_ctl[i].urb;
+
+               if (!urb) {
                        /* Not enough transfer buffers, so just give up */
                        if (i < STK1160_MIN_BUFS)
                                goto free_i_bufs;
                urb->transfer_buffer = dev->isoc_ctl.urb_ctl[i].transfer_buffer;
                urb->transfer_buffer_length = sb_size;
                urb->complete = stk1160_isoc_irq;
-               urb->context = dev;
+               urb->context = &dev->isoc_ctl.urb_ctl[i];
                urb->interval = 1;
                urb->start_frame = 0;
                urb->number_of_packets = max_packets;
-#ifndef CONFIG_DMA_NONCOHERENT
                urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
-#else
-               urb->transfer_flags = URB_ISO_ASAP;
-#endif
+               urb->transfer_dma = dev->isoc_ctl.urb_ctl[i].dma;
 
                k = 0;
                for (j = 0; j < max_packets; j++) {
         * enough to work fine, so we just free the extra urb,
         * store the allocated count and keep going, fingers crossed!
         */
-       usb_free_urb(dev->isoc_ctl.urb_ctl[i].urb);
-       dev->isoc_ctl.urb_ctl[i].urb = NULL;
 
        stk1160_warn("%d urbs allocated. Trying to continue...\n", i);