vm audit: add VM_DONTEXPAND to mmap for drivers that need it
[sfrench/cifs-2.6.git] / sound / usb / usx2y / usx2yhwdeppcm.c
index fe67a92e2a1a355ccbd36acb1ce2c6dcab7b2777..117946f2debb3a04891d87de9327c16d8f27f7fe 100644 (file)
@@ -226,7 +226,7 @@ static inline int usX2Y_usbpcm_usbframe_complete(struct snd_usX2Y_substream *cap
 }
 
 
-static void i_usX2Y_usbpcm_urb_complete(struct urb *urb, struct pt_regs *regs)
+static void i_usX2Y_usbpcm_urb_complete(struct urb *urb)
 {
        struct snd_usX2Y_substream *subs = urb->context;
        struct usX2Ydev *usX2Y = subs->usX2Y;
@@ -243,7 +243,7 @@ static void i_usX2Y_usbpcm_urb_complete(struct urb *urb, struct pt_regs *regs)
                usX2Y_error_urb_status(usX2Y, subs, urb);
                return;
        }
-       if (likely((0xFFFF & urb->start_frame) == usX2Y->wait_iso_frame))
+       if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF)))
                subs->completed_urb = urb;
        else {
                usX2Y_error_sequence(usX2Y, subs, urb);
@@ -256,13 +256,9 @@ static void i_usX2Y_usbpcm_urb_complete(struct urb *urb, struct pt_regs *regs)
        if (capsubs->completed_urb && atomic_read(&capsubs->state) >= state_PREPARED &&
            (NULL == capsubs2 || capsubs2->completed_urb) &&
            (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < state_PREPARED)) {
-               if (!usX2Y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame)) {
-                       if (nr_of_packs() <= urb->start_frame &&
-                           urb->start_frame <= (2 * nr_of_packs() - 1))        // uhci and ohci
-                               usX2Y->wait_iso_frame = urb->start_frame - nr_of_packs();
-                       else
-                               usX2Y->wait_iso_frame +=  nr_of_packs();
-               } else {
+               if (!usX2Y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame))
+                       usX2Y->wait_iso_frame += nr_of_packs();
+               else {
                        snd_printdd("\n");
                        usX2Y_clients_stop(usX2Y);
                }
@@ -294,7 +290,7 @@ static void usX2Y_usbpcm_subs_startup_finish(struct usX2Ydev * usX2Y)
        usX2Y->prepare_subs = NULL;
 }
 
-static void i_usX2Y_usbpcm_subs_startup(struct urb *urb, struct pt_regs *regs)
+static void i_usX2Y_usbpcm_subs_startup(struct urb *urb)
 {
        struct snd_usX2Y_substream *subs = urb->context;
        struct usX2Ydev *usX2Y = subs->usX2Y;
@@ -311,7 +307,7 @@ static void i_usX2Y_usbpcm_subs_startup(struct urb *urb, struct pt_regs *regs)
                wake_up(&usX2Y->prepare_wait_queue);
        }
 
-       i_usX2Y_usbpcm_urb_complete(urb, regs);
+       i_usX2Y_usbpcm_urb_complete(urb);
 }
 
 /*
@@ -433,7 +429,6 @@ static int usX2Y_usbpcm_urbs_start(struct snd_usX2Y_substream *subs)
                if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
                        goto start;
        }
-       usX2Y->wait_iso_frame = -1;
 
  start:
        usX2Y_usbpcm_subs_startup(subs);
@@ -459,7 +454,7 @@ static int usX2Y_usbpcm_urbs_start(struct snd_usX2Y_substream *subs)
                                                goto cleanup;
                                        }  else {
                                                snd_printdd("%i\n", urb->start_frame);
-                                               if (0 > usX2Y->wait_iso_frame)
+                                               if (u == 0)
                                                        usX2Y->wait_iso_frame = urb->start_frame;
                                        }
                                        urb->transfer_flags = 0;
@@ -632,7 +627,7 @@ static int usX2Y_pcms_lock_check(struct snd_card *card)
                for (s = 0; s < 2; ++s) {
                        struct snd_pcm_substream *substream;
                        substream = pcm->streams[s].substream;
-                       if (substream && substream->ffile != NULL)
+                       if (substream && SUBSTREAM_BUSY(substream))
                                err = -EBUSY;
                }
        }
@@ -688,30 +683,24 @@ static void snd_usX2Y_hwdep_pcm_vm_close(struct vm_area_struct *area)
 }
 
 
-static struct page * snd_usX2Y_hwdep_pcm_vm_nopage(struct vm_area_struct *area, unsigned long address, int *type)
+static int snd_usX2Y_hwdep_pcm_vm_fault(struct vm_area_struct *area,
+                                       struct vm_fault *vmf)
 {
        unsigned long offset;
-       struct page *page;
        void *vaddr;
 
-       offset = area->vm_pgoff << PAGE_SHIFT;
-       offset += address - area->vm_start;
-       snd_assert((offset % PAGE_SIZE) == 0, return NOPAGE_OOM);
+       offset = vmf->pgoff << PAGE_SHIFT;
        vaddr = (char*)((struct usX2Ydev *)area->vm_private_data)->hwdep_pcm_shm + offset;
-       page = virt_to_page(vaddr);
-       get_page(page);
-
-       if (type)
-               *type = VM_FAULT_MINOR;
-
-       return page;
+       vmf->page = virt_to_page(vaddr);
+       get_page(vmf->page);
+       return 0;
 }
 
 
 static struct vm_operations_struct snd_usX2Y_hwdep_pcm_vm_ops = {
        .open = snd_usX2Y_hwdep_pcm_vm_open,
        .close = snd_usX2Y_hwdep_pcm_vm_close,
-       .nopage = snd_usX2Y_hwdep_pcm_vm_nopage,
+       .fault = snd_usX2Y_hwdep_pcm_vm_fault,
 };
 
 
@@ -733,7 +722,7 @@ static int snd_usX2Y_hwdep_pcm_mmap(struct snd_hwdep * hw, struct file *filp, st
                return -ENODEV;
        }
        area->vm_ops = &snd_usX2Y_hwdep_pcm_vm_ops;
-       area->vm_flags |= VM_RESERVED;
+       area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
        area->vm_private_data = hw->private_data;
        return 0;
 }