Bump up the SYMTAB_SPACE for LINT. It was already too small again.
[unix-history] / sys / i386 / isa / pcaudio.c
index ecdd308..68d4bf9 100644 (file)
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *     $Id: 
+ *     $Id$ 
  */
 
  */
 
-#include "param.h"
+#include "systm.h"
 #include "uio.h"
 #include "ioctl.h"
 #include "uio.h"
 #include "ioctl.h"
+#include "proc.h"
+#include "file.h"
 #include "sound/ulaw.h"
 #include "machine/cpufunc.h"
 #include "machine/pio.h"
 #include "sound/ulaw.h"
 #include "machine/cpufunc.h"
 #include "machine/pio.h"
@@ -41,7 +43,7 @@
 #include "pca.h"
 #if NPCA > 0
 
 #include "pca.h"
 #if NPCA > 0
 
-#define BUF_SIZE       8192
+#define BUF_SIZE       4*8192
 #define SAMPLE_RATE    8000
 #define INTERRUPT_RATE 16000
 
 #define SAMPLE_RATE    8000
 #define INTERRUPT_RATE 16000
 
@@ -61,6 +63,8 @@ static struct pca_status {
        char            current;        /* current buffer */
        unsigned char   oldval;         /* old timer port value */
        char            timer_on;       /* is playback running */
        char            current;        /* current buffer */
        unsigned char   oldval;         /* old timer port value */
        char            timer_on;       /* is playback running */
+       char            coll;           /* select collision */
+       pid_t           wsel;           /* pid of select'ing proc */
 } pca_status;
 
 static char buffer1[BUF_SIZE];
 } pca_status;
 
 static char buffer1[BUF_SIZE];
@@ -77,6 +81,7 @@ int pcaclose(dev_t dev, int flag);
 int pcaopen(dev_t dev, int flag);
 int pcawrite(dev_t dev, struct uio *uio, int flag);
 int pcaioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p);
 int pcaopen(dev_t dev, int flag);
 int pcawrite(dev_t dev, struct uio *uio, int flag);
 int pcaioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p);
+int pcaselect(dev_t dev, int rw, struct proc *p);
 
 struct isa_driver pcadriver = {
        pcaprobe, pcaattach, "pca",
 
 struct isa_driver pcadriver = {
        pcaprobe, pcaattach, "pca",
@@ -270,6 +275,10 @@ pcawrite(dev_t dev, struct uio *uio, int flag)
                return ENXIO;
 
        while ((count = min(BUF_SIZE, uio->uio_resid)) > 0) {
                return ENXIO;
 
        while ((count = min(BUF_SIZE, uio->uio_resid)) > 0) {
+               if (pca_status.in_use[0] && pca_status.in_use[1]) {
+                       pca_sleep = 1;
+                       tsleep((caddr_t)&pca_sleep, PZERO|PCATCH, "pca_wait",0);
+               }
                which = pca_status.in_use[0] ? 1 : 0;
                if (count && !pca_status.in_use[which]) {
                        uiomove(pca_status.buf[which], count, uio);
                which = pca_status.in_use[0] ? 1 : 0;
                if (count && !pca_status.in_use[which]) {
                        uiomove(pca_status.buf[which], count, uio);
@@ -290,10 +299,6 @@ pcawrite(dev_t dev, struct uio *uio, int flag)
                                if (pca_start()) 
                                        return EBUSY;
                }
                                if (pca_start()) 
                                        return EBUSY;
                }
-               if (pca_status.in_use[0] && pca_status.in_use[1]) {
-                       pca_sleep = 1;
-                       tsleep((caddr_t)&pca_sleep, PZERO|PCATCH, "pca_wait",0);
-               }
        } 
        return 0;
 }
        } 
        return 0;
 }
@@ -302,7 +307,7 @@ pcawrite(dev_t dev, struct uio *uio, int flag)
 int
 pcaioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
 {
 int
 pcaioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
 {
-audio_info_t *auptr;
+       audio_info_t *auptr;
 
        switch(cmd) {
 
 
        switch(cmd) {
 
@@ -366,7 +371,6 @@ void
 pcaintr(int regs)
 {
        if (pca_status.index < pca_status.in_use[pca_status.current]) {
 pcaintr(int regs)
 {
        if (pca_status.index < pca_status.in_use[pca_status.current]) {
-#if 1
                disable_intr();
                __asm__("outb %0,$0x61\n"
                        "andb $0xFE,%0\n"
                disable_intr();
                __asm__("outb %0,$0x61\n"
                        "andb $0xFE,%0\n"
@@ -377,18 +381,10 @@ pcaintr(int regs)
                        : : "a" ((char)pca_status.buffer[pca_status.index]),
                            "b" ((long)volume_table) );
                enable_intr();
                        : : "a" ((char)pca_status.buffer[pca_status.index]),
                            "b" ((long)volume_table) );
                enable_intr();
-#else
-               disable_intr();
-               outb(IO_PPI, pca_status.oldval);
-               outb(IO_PPI, pca_status.oldval & 0xFE);
-               outb(TIMER_CNTR2, 
-                       volume_table[pca_status.buffer[pca_status.index]]);
-               enable_intr();
-#endif
                pca_status.counter += pca_status.scale;
                pca_status.index = (pca_status.counter >> 8);
        }
                pca_status.counter += pca_status.scale;
                pca_status.index = (pca_status.counter >> 8);
        }
-       else {
+       if (pca_status.index >= pca_status.in_use[pca_status.current]) {
                pca_status.index = pca_status.counter = 0;
                pca_status.in_use[pca_status.current] = 0;
                pca_status.current ^= 1;
                pca_status.index = pca_status.counter = 0;
                pca_status.in_use[pca_status.current] = 0;
                pca_status.current ^= 1;
@@ -397,7 +393,38 @@ pcaintr(int regs)
                        wakeup((caddr_t)&pca_sleep);
                        pca_sleep = 0;
                }
                        wakeup((caddr_t)&pca_sleep);
                        pca_sleep = 0;
                }
+               if (pca_status.wsel) {
+                       selwakeup(pca_status.wsel, pca_status.coll);
+                       pca_status.wsel = 0;
+                       pca_status.coll = 0;
+               }
        }
 }
 
        }
 }
 
+
+int
+pcaselect(dev_t dev, int rw, struct proc *p)
+{
+       int s = spltty();
+       struct proc *p1;
+
+       switch (rw) {
+
+       case FWRITE:
+               if (!pca_status.in_use[0] || !pca_status.in_use[1]) {
+                       splx(s);
+                       return(1);
+               }
+               if (pca_status.wsel && (p1 = pfind(pca_status.wsel))
+                   && p1->p_wchan == (caddr_t)&selwait)
+                       pca_status.coll = 1;
+               else
+                       pca_status.wsel = p->p_pid;
+               splx(s);
+               return 0;
+       default:
+               splx(s);
+               return(0); 
+       }
+}
 #endif
 #endif