USB audio.c: make trigger semantics more OSS compliant

From: Thomas Sailer (sailer@scs.ch)
Date: Fri Jul 11 2003 - 08:40:07 EST


This patch should make USB audio trigger semantics more OSS compliant.
It is against Redhat's current 2.4 kernel, but should apply also to
other kernels as USB audio.c didn't change a lot the last year or so.

Tom


--- audio.c.original 2003-06-30 16:45:59.000000000 +0200
+++ audio.c 2003-06-30 17:08:26.000000000 +0200
@@ -105,6 +105,8 @@
  * functionality. Tested and used in production with the emagic emi 2|6
  * on PPC and Intel. Also fixed a few logic 'crash and burn' corner
  * cases.
+ * 2003-06-30: Thomas Sailer
+ * Fix SETTRIGGER non OSS API conformity
  */
 
 /*
@@ -279,23 +281,24 @@
         unsigned int srate;
         /* physical buffer */
         unsigned char *sgbuf[NRSGBUF];
- unsigned bufsize;
- unsigned numfrag;
- unsigned fragshift;
- unsigned wrptr, rdptr;
- unsigned total_bytes;
+ unsigned int bufsize;
+ unsigned int numfrag;
+ unsigned int fragshift;
+ unsigned int wrptr, rdptr;
+ unsigned int total_bytes;
         int count;
- unsigned error; /* over/underrun */
+ unsigned int error; /* over/underrun */
         wait_queue_head_t wait;
         /* redundant, but makes calculations easier */
- unsigned fragsize;
- unsigned dmasize;
+ unsigned int fragsize;
+ unsigned int dmasize;
         /* OSS stuff */
- unsigned mapped:1;
- unsigned ready:1;
- unsigned ossfragshift;
+ unsigned int mapped:1;
+ unsigned int ready:1;
+ unsigned int enabled:1;
+ unsigned int ossfragshift;
         int ossmaxfrags;
- unsigned subdivision;
+ unsigned int subdivision;
 };
 
 struct usb_audio_state;
@@ -562,6 +565,7 @@
                         break;
         }
         db->bufsize = nr << PAGE_SHIFT;
+ db->enabled = 1;
         db->ready = 1;
         dprintk((KERN_DEBUG "usbaudio: dmabuf_init bytepersec %d bufs %d ossfragshift %d ossmaxfrags %d "
                  "fragshift %d fragsize %d numfrag %d dmasize %d bufsize %d fmt 0x%x srate %d\n",
@@ -2299,7 +2303,7 @@
                 if (cnt > count)
                         cnt = count;
                 if (cnt <= 0) {
- if (usbin_start(as)) {
+ if (as->usbin.dma.enabled && usbin_start(as)) {
                                 if (!ret)
                                         ret = -ENODEV;
                                 break;
@@ -2332,6 +2336,11 @@
                 count -= cnt;
                 buffer += cnt;
                 ret += cnt;
+ if (as->usbin.dma.enabled && usbin_start(as)) {
+ if (!ret)
+ ret = -ENODEV;
+ break;
+ }
         }
         __set_current_state(TASK_RUNNING);
         remove_wait_queue(&as->usbin.dma.wait, &wait);
@@ -2378,7 +2387,7 @@
                 if (cnt > count)
                         cnt = count;
                 if (cnt <= 0) {
- if (usbout_start(as)) {
+ if (as->usbout.dma.enabled && usbout_start(as)) {
                                 if (!ret)
                                         ret = -ENODEV;
                                 break;
@@ -2411,7 +2420,7 @@
                 count -= cnt;
                 buffer += cnt;
                 ret += cnt;
- if (as->usbout.dma.count >= start_thr && usbout_start(as)) {
+ if (as->usbout.dma.enabled && as->usbout.dma.count >= start_thr && usbout_start(as)) {
                         if (!ret)
                                 ret = -ENODEV;
                         break;
@@ -2616,19 +2625,25 @@
                         if (val & PCM_ENABLE_INPUT) {
                                 if (!as->usbin.dma.ready && (ret = prog_dmabuf_in(as)))
                                         return ret;
+ as->usbin.dma.enabled = 1;
                                 if (usbin_start(as))
                                         return -ENODEV;
- } else
+ } else {
+ as->usbin.dma.enabled = 0;
                                 usbin_stop(as);
+ }
                 }
                 if (file->f_mode & FMODE_WRITE) {
                         if (val & PCM_ENABLE_OUTPUT) {
                                 if (!as->usbout.dma.ready && (ret = prog_dmabuf_out(as)))
                                         return ret;
+ as->usbout.dma.enabled = 1;
                                 if (usbout_start(as))
                                         return -ENODEV;
- } else
+ } else {
+ as->usbout.dma.enabled = 0;
                                 usbout_stop(as);
+ }
                 }
                 return 0;
 
@@ -2827,10 +2842,14 @@
                 if (signal_pending(current))
                         return -ERESTARTSYS;
         }
- if (file->f_mode & FMODE_READ)
+ if (file->f_mode & FMODE_READ) {
                 as->usbin.dma.ossfragshift = as->usbin.dma.ossmaxfrags = as->usbin.dma.subdivision = 0;
- if (file->f_mode & FMODE_WRITE)
+ as->usbin.dma.enabled = 1;
+ }
+ if (file->f_mode & FMODE_WRITE) {
                 as->usbout.dma.ossfragshift = as->usbout.dma.ossmaxfrags = as->usbout.dma.subdivision = 0;
+ as->usbout.dma.enabled = 1;
+ }
         if (set_format(as, file->f_mode, ((minor & 0xf) == SND_DEV_DSP16) ? AFMT_S16_LE : AFMT_U8 /* AFMT_ULAW */, 8000)) {
                 up(&open_sem);
                 return -EIO;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Jul 15 2003 - 22:00:39 EST