patch-1.3.34 linux/drivers/sound/gus_wave.c

Next file: linux/drivers/sound/ics2101.c
Previous file: linux/drivers/sound/gus_vol.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.33/linux/drivers/sound/gus_wave.c linux/drivers/sound/gus_wave.c
@@ -76,7 +76,7 @@
 
 extern int      gus_base;
 extern int      gus_irq, gus_dma;
-static int      gusmax_dma = -1;
+static int      gus_dma2 = -1;
 static int      dual_dma_mode = 0;
 static long     gus_mem_size = 0;
 static long     free_mem_ptr = 0;
@@ -88,6 +88,7 @@
 static int      gus_recmask = SOUND_MASK_MIC;
 static int      recording_active = 0;
 static int      only_read_access = 0;
+static int      only_8_bits = 0;
 
 int             gus_wave_volume = 60;
 int             gus_pcm_volume = 80;
@@ -95,6 +96,8 @@
 static int      gus_line_vol = 100, gus_mic_vol = 0;
 static unsigned char mix_image = 0x00;
 
+int             gus_timer_enabled = 0;
+
 /*
  * Current version of this driver doesn't allow synth and PCM functions
  * at the same time. The active_device specifies the active driver
@@ -109,7 +112,9 @@
 static int      gus_sampling_channels;
 static int      gus_sampling_bits;
 
-DEFINE_WAIT_QUEUE (dram_sleeper, dram_sleep_flag);
+static struct wait_queue *dram_sleeper = NULL;
+static volatile struct snd_wait dram_sleep_flag =
+{0};
 
 /*
  * Variables and buffers for PCM output
@@ -128,6 +133,8 @@
 static int      pcm_current_count;
 static int      pcm_current_intrflag;
 
+extern sound_os_info *gus_osp;
+
 struct voice_info voices[32];
 
 static int      freq_div_table[] =
@@ -157,6 +164,7 @@
 static long     sample_ptrs[MAX_SAMPLE + 1];
 static int      sample_map[32];
 static int      free_sample;
+static int      mixer_type = 0;
 
 
 static int      patch_table[MAX_PATCH];
@@ -172,6 +180,7 @@
 static void     compute_volume (int voice, int volume);
 static void     do_volume_irq (int voice);
 static void     set_input_volumes (void);
+static void     gus_tmr_install (int io_base);
 
 #define	INSTANT_RAMP		-1	/* Instant change. No ramping */
 #define FAST_RAMP		0	/* Fastest possible ramp */
@@ -204,7 +213,7 @@
   int             i;
 
   for (i = 0; i < 7; i++)
-    INB (u_DRAMIO);
+    inb (u_DRAMIO);
 }
 
 static void
@@ -212,15 +221,16 @@
 {				/* Writes a byte to the DRAM */
   unsigned long   flags;
 
-  DISABLE_INTR (flags);
-  OUTB (0x43, u_Command);
-  OUTB (addr & 0xff, u_DataLo);
-  OUTB ((addr >> 8) & 0xff, u_DataHi);
-
-  OUTB (0x44, u_Command);
-  OUTB ((addr >> 16) & 0xff, u_DataHi);
-  OUTB (data, u_DRAMIO);
-  RESTORE_INTR (flags);
+  save_flags (flags);
+  cli ();
+  outb (0x43, u_Command);
+  outb (addr & 0xff, u_DataLo);
+  outb ((addr >> 8) & 0xff, u_DataHi);
+
+  outb (0x44, u_Command);
+  outb ((addr >> 16) & 0xff, u_DataHi);
+  outb (data, u_DRAMIO);
+  restore_flags (flags);
 }
 
 static unsigned char
@@ -229,15 +239,16 @@
   unsigned long   flags;
   unsigned char   tmp;
 
-  DISABLE_INTR (flags);
-  OUTB (0x43, u_Command);
-  OUTB (addr & 0xff, u_DataLo);
-  OUTB ((addr >> 8) & 0xff, u_DataHi);
-
-  OUTB (0x44, u_Command);
-  OUTB ((addr >> 16) & 0xff, u_DataHi);
-  tmp = INB (u_DRAMIO);
-  RESTORE_INTR (flags);
+  save_flags (flags);
+  cli ();
+  outb (0x43, u_Command);
+  outb (addr & 0xff, u_DataLo);
+  outb ((addr >> 8) & 0xff, u_DataHi);
+
+  outb (0x44, u_Command);
+  outb ((addr >> 16) & 0xff, u_DataHi);
+  tmp = inb (u_DRAMIO);
+  restore_flags (flags);
 
   return tmp;
 }
@@ -247,12 +258,13 @@
 {				/* Writes to an indirect register (8 bit) */
   unsigned long   flags;
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
 
-  OUTB (reg, u_Command);
-  OUTB ((unsigned char) (data & 0xff), u_DataHi);
+  outb (reg, u_Command);
+  outb ((unsigned char) (data & 0xff), u_DataHi);
 
-  RESTORE_INTR (flags);
+  restore_flags (flags);
 }
 
 unsigned char
@@ -261,10 +273,11 @@
   unsigned long   flags;
   unsigned char   val;
 
-  DISABLE_INTR (flags);
-  OUTB (reg | 0x80, u_Command);
-  val = INB (u_DataHi);
-  RESTORE_INTR (flags);
+  save_flags (flags);
+  cli ();
+  outb (reg | 0x80, u_Command);
+  val = inb (u_DataHi);
+  restore_flags (flags);
 
   return val;
 }
@@ -275,10 +288,11 @@
   unsigned long   flags;
   unsigned char   val;
 
-  DISABLE_INTR (flags);
-  OUTB (reg, u_Command);
-  val = INB (u_DataHi);
-  RESTORE_INTR (flags);
+  save_flags (flags);
+  cli ();
+  outb (reg, u_Command);
+  val = inb (u_DataHi);
+  restore_flags (flags);
 
   return val;
 }
@@ -288,14 +302,15 @@
 {				/* Writes to an indirect register (16 bit) */
   unsigned long   flags;
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
 
-  OUTB (reg, u_Command);
+  outb (reg, u_Command);
 
-  OUTB ((unsigned char) (data & 0xff), u_DataLo);
-  OUTB ((unsigned char) ((data >> 8) & 0xff), u_DataHi);
+  outb ((unsigned char) (data & 0xff), u_DataLo);
+  outb ((unsigned char) ((data >> 8) & 0xff), u_DataHi);
 
-  RESTORE_INTR (flags);
+  restore_flags (flags);
 }
 
 unsigned short
@@ -304,14 +319,15 @@
   unsigned long   flags;
   unsigned char   hi, lo;
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
 
-  OUTB (reg | 0x80, u_Command);
+  outb (reg | 0x80, u_Command);
 
-  lo = INB (u_DataLo);
-  hi = INB (u_DataHi);
+  lo = inb (u_DataLo);
+  hi = inb (u_DataHi);
 
-  RESTORE_INTR (flags);
+  restore_flags (flags);
 
   return ((hi << 8) & 0xff00) | lo;
 }
@@ -322,7 +338,8 @@
   unsigned long   hold_address;
   unsigned long   flags;
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
   if (is16bit)
     {
       /*
@@ -341,7 +358,7 @@
   gus_delay ();
   gus_write16 (reg, (unsigned short) ((address >> 7) & 0xffff));
   gus_write16 (reg + 1, (unsigned short) ((address << 9) & 0xffff));
-  RESTORE_INTR (flags);
+  restore_flags (flags);
 }
 
 static void
@@ -350,7 +367,7 @@
   if (voice < 0 || voice > 31)
     return;
 
-  OUTB (voice, u_Voice);
+  outb (voice, u_Voice);
 }
 
 static void
@@ -475,7 +492,8 @@
 {
   unsigned long   flags;
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
   gus_select_voice (voice);
   gus_voice_volume (0);
   gus_voice_off ();
@@ -484,7 +502,7 @@
   gus_write8 (0x0d, 0x03);	/* Ramping off */
   voice_alloc->map[voice] = 0;
   voice_alloc->alloc_times[voice] = 0;
-  RESTORE_INTR (flags);
+  restore_flags (flags);
 
 }
 
@@ -519,10 +537,11 @@
 
   if (voices[voice].mode & WAVE_SUSTAIN_ON && voices[voice].env_phase == 2)
     {
-      DISABLE_INTR (flags);
+      save_flags (flags);
+      cli ();
       gus_select_voice (voice);
       gus_rampoff ();
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       return;
       /*
        * Sustain phase begins. Continue envelope after receiving note off.
@@ -541,7 +560,8 @@
   vol = voices[voice].initial_volume * voices[voice].env_offset[phase] / 255;
   rate = voices[voice].env_rate[phase];
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
   gus_select_voice (voice);
 
   gus_voice_volume (prev_vol);
@@ -553,7 +573,7 @@
 
   if (((vol - prev_vol) / 64) == 0)	/* No significant volume change */
     {
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       step_envelope (voice);	/* Continue the envelope on the next step */
       return;
     }
@@ -573,7 +593,7 @@
       gus_rampon (0x60);	/* Decreasing volume, with IRQ */
     }
   voices[voice].current_volume = vol;
-  RESTORE_INTR (flags);
+  restore_flags (flags);
 }
 
 static void
@@ -599,7 +619,7 @@
 
   voices[voice].mode &= ~WAVE_SUSTAIN_ON;
   gus_rampoff ();
-  RESTORE_INTR (flags);
+  restore_flags (flags);
   step_envelope (voice);
 }
 
@@ -609,14 +629,15 @@
   int             instr_no = sample_map[voice], is16bits;
   long int        flags;
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
   gus_select_voice (voice);
 
   if (instr_no < 0 || instr_no > MAX_SAMPLE)
     {
       gus_write8 (0x00, 0x03);	/* Hard stop */
       voice_alloc->map[voice] = 0;
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       return;
     }
 
@@ -643,7 +664,7 @@
   gus_ramp_rate (2, 4);
   gus_rampon (0x40 | 0x20);	/* Down, once, with IRQ */
   voices[voice].volume_irq_mode = VMODE_HALT;
-  RESTORE_INTR (flags);
+  restore_flags (flags);
 }
 
 static void
@@ -662,7 +683,7 @@
       gus_voice_init2 (i);
     }
 
-  INB (u_Status);		/* Touch the status register */
+  inb (u_Status);		/* Touch the status register */
 
   gus_look8 (0x41);		/* Clear any pending DMA IRQs */
   gus_look8 (0x49);		/* Clear any pending sample IRQs */
@@ -683,7 +704,8 @@
   static unsigned char gus_dma_map[8] =
   {0, 1, 0, 2, 0, 3, 4, 5};
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
   gus_write8 (0x4c, 0);		/* Reset GF1 */
   gus_delay ();
   gus_delay ();
@@ -702,7 +724,7 @@
 
   gus_select_max_voices (24);
 
-  INB (u_Status);		/* Touch the status register */
+  inb (u_Status);		/* Touch the status register */
 
   gus_look8 (0x41);		/* Clear any pending DMA IRQs */
   gus_look8 (0x49);		/* Clear any pending sample IRQs */
@@ -720,14 +742,14 @@
    * Set up for Digital ASIC
    */
 
-  OUTB (0x05, gus_base + 0x0f);
+  outb (0x05, gus_base + 0x0f);
 
   mix_image |= 0x02;		/* Disable line out (for a moment) */
-  OUTB (mix_image, u_Mixer);
+  outb (mix_image, u_Mixer);
 
-  OUTB (0x00, u_IRQDMAControl);
+  outb (0x00, u_IRQDMAControl);
 
-  OUTB (0x00, gus_base + 0x0f);
+  outb (0x00, gus_base + 0x0f);
 
   /*
    * Now set up the DMA and IRQ interface
@@ -747,7 +769,7 @@
   irq_image |= 0x40;		/* Combine IRQ1 (GF1) and IRQ2 (Midi) */
 
   dual_dma_mode = 1;
-  if (!have_gus_max || gusmax_dma == gus_dma || gusmax_dma == -1)
+  if (gus_dma2 == gus_dma || gus_dma2 == -1)
     {
       dual_dma_mode = 0;
       dma_image = 0x40;		/* Combine DMA1 (DRAM) and IRQ2 (ADC) */
@@ -765,7 +787,7 @@
       if (!dma_image)
 	printk ("Warning! GUS DMA not selected\n");
 
-      tmp = gus_dma_map[gusmax_dma] << 3;
+      tmp = gus_dma_map[gus_dma2] << 3;
       if (!tmp)
 	{
 	  printk ("Warning! Invalid GUS MAX DMA\n");
@@ -784,35 +806,35 @@
    * Doing it first time
    */
 
-  OUTB (mix_image, u_Mixer);	/* Select DMA control */
-  OUTB (dma_image | 0x80, u_IRQDMAControl);	/* Set DMA address */
+  outb (mix_image, u_Mixer);	/* Select DMA control */
+  outb (dma_image | 0x80, u_IRQDMAControl);	/* Set DMA address */
 
-  OUTB (mix_image | 0x40, u_Mixer);	/* Select IRQ control */
-  OUTB (irq_image, u_IRQDMAControl);	/* Set IRQ address */
+  outb (mix_image | 0x40, u_Mixer);	/* Select IRQ control */
+  outb (irq_image, u_IRQDMAControl);	/* Set IRQ address */
 
   /*
    * Doing it second time
    */
 
-  OUTB (mix_image, u_Mixer);	/* Select DMA control */
-  OUTB (dma_image, u_IRQDMAControl);	/* Set DMA address */
+  outb (mix_image, u_Mixer);	/* Select DMA control */
+  outb (dma_image, u_IRQDMAControl);	/* Set DMA address */
 
-  OUTB (mix_image | 0x40, u_Mixer);	/* Select IRQ control */
-  OUTB (irq_image, u_IRQDMAControl);	/* Set IRQ address */
+  outb (mix_image | 0x40, u_Mixer);	/* Select IRQ control */
+  outb (irq_image, u_IRQDMAControl);	/* Set IRQ address */
 
   gus_select_voice (0);		/* This disables writes to IRQ/DMA reg */
 
   mix_image &= ~0x02;		/* Enable line out */
   mix_image |= 0x08;		/* Enable IRQ */
-  OUTB (mix_image, u_Mixer);	/*
+  outb (mix_image, u_Mixer);	/*
 				 * Turn mixer channels on
 				 * Note! Mic in is left off.
 				 */
 
   gus_select_voice (0);		/* This disables writes to IRQ/DMA reg */
 
-  gusintr (INT_HANDLER_CALL (0));	/* Serve pending interrupts */
-  RESTORE_INTR (flags);
+  gusintr (0, NULL);		/* Serve pending interrupts */
+  restore_flags (flags);
 }
 
 int
@@ -867,14 +889,14 @@
 
 static int
 guswave_ioctl (int dev,
-	       unsigned int cmd, unsigned int arg)
+	       unsigned int cmd, ioctl_arg arg)
 {
 
   switch (cmd)
     {
     case SNDCTL_SYNTH_INFO:
       gus_info.nr_voices = nr_voices;
-      IOCTL_TO_USER ((char *) arg, 0, &gus_info, sizeof (gus_info));
+      memcpy_tofs (&(((char *) arg)[0]), (&gus_info), (sizeof (gus_info)));
       return 0;
       break;
 
@@ -891,7 +913,7 @@
       return gus_mem_size - free_mem_ptr - 32;
 
     default:
-      return RET_ERROR (EINVAL);
+      return -EINVAL;
     }
 }
 
@@ -901,10 +923,10 @@
   int             sample_no;
 
   if (instr_no < 0 || instr_no > MAX_PATCH)
-    return RET_ERROR (EINVAL);
+    return -EINVAL;
 
   if (voice < 0 || voice > 31)
-    return RET_ERROR (EINVAL);
+    return -EINVAL;
 
   if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
     {
@@ -918,14 +940,14 @@
   if (sample_no < 0)
     {
       printk ("GUS: Undefined patch %d for voice %d\n", instr_no, voice);
-      return RET_ERROR (EINVAL);	/* Patch not defined */
+      return -EINVAL;		/* Patch not defined */
     }
 
   if (sample_ptrs[sample_no] == -1)	/* Sample not loaded */
     {
       printk ("GUS: Sample #%d not loaded for patch %d (voice %d)\n",
 	      sample_no, instr_no, voice);
-      return RET_ERROR (EINVAL);
+      return -EINVAL;
     }
 
   sample_map[voice] = sample_no;
@@ -938,63 +960,27 @@
 {
   unsigned long   flags;
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
   /* voice_alloc->map[voice] = 0xffff; */
   if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
     {
       voices[voice].kill_pending = 1;
-      RESTORE_INTR (flags);
+      restore_flags (flags);
     }
   else
     {
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       gus_voice_fade (voice);
     }
 
-  RESTORE_INTR (flags);
+  restore_flags (flags);
   return 0;
 }
 
 static void
 guswave_aftertouch (int dev, int voice, int pressure)
 {
-#if 0
-  short           lo_limit, hi_limit;
-  unsigned long   flags;
-
-  if (voice < 0 || voice > 31)
-    return;
-
-  if (voices[voice].mode & WAVE_ENVELOPES && voices[voice].env_phase != 2)
-    return;			/* Don't mix with envelopes */
-
-  if (pressure < 32)
-    {
-      DISABLE_INTR (flags);
-      gus_select_voice (voice);
-      gus_rampoff ();
-      compute_and_set_volume (voice, 255, 0);	/* Back to original volume */
-      RESTORE_INTR (flags);
-      return;
-    }
-
-  hi_limit = voices[voice].current_volume;
-  lo_limit = hi_limit * 99 / 100;
-  if (lo_limit < 65)
-    lo_limit = 65;
-
-  DISABLE_INTR (flags);
-  gus_select_voice (voice);
-  if (hi_limit > (4095 - 65))
-    {
-      hi_limit = 4095 - 65;
-      gus_voice_volume (hi_limit);
-    }
-  gus_ramp_range (lo_limit, hi_limit);
-  gus_ramp_rate (3, 8);
-  gus_rampon (0x58);		/* Bidirectional, dow, loop */
-  RESTORE_INTR (flags);
-#endif /* 0 */
 }
 
 static void
@@ -1049,7 +1035,8 @@
   compute_volume (voice, volume);
   voices[voice].current_volume = voices[voice].initial_volume;
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
   /*
      * CAUTION! Interrupts disabled. Enable them before returning
    */
@@ -1063,7 +1050,7 @@
     {
       gus_rampoff ();
       gus_voice_volume (target);
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       return;
     }
 
@@ -1077,7 +1064,7 @@
     {
       gus_rampoff ();
       gus_voice_volume (target);
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       return;
     }
 
@@ -1096,7 +1083,7 @@
       gus_ramp_range (target, current);
       gus_rampon (0x40);	/* Ramp down, once, no irq */
     }
-  RESTORE_INTR (flags);
+  restore_flags (flags);
 }
 
 static void
@@ -1105,10 +1092,11 @@
   unsigned char   status;
   unsigned long   flags;
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
   gus_select_voice (voice);
   status = gus_read8 (0x00);	/* Get voice status */
-  RESTORE_INTR (flags);
+  restore_flags (flags);
 
   if (status & 0x03)
     return;			/* Voice was not running */
@@ -1123,10 +1111,11 @@
    * Voice is running and has envelopes.
    */
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
   gus_select_voice (voice);
   status = gus_read8 (0x0d);	/* Ramping status */
-  RESTORE_INTR (flags);
+  restore_flags (flags);
 
   if (status & 0x03)		/* Sustain phase? */
     {
@@ -1161,10 +1150,11 @@
 				   voices[voice].bender_range);
 	  voices[voice].current_freq = freq;
 
-	  DISABLE_INTR (flags);
+	  save_flags (flags);
+	  cli ();
 	  gus_select_voice (voice);
 	  gus_voice_freq (freq);
-	  RESTORE_INTR (flags);
+	  restore_flags (flags);
 	}
       break;
 
@@ -1211,7 +1201,7 @@
   if (voice < 0 || voice > 31)
     {
       printk ("GUS: Invalid voice\n");
-      return RET_ERROR (EINVAL);
+      return -EINVAL;
     }
 
   if (note_num == 255)
@@ -1229,12 +1219,12 @@
 
   if ((patch = patch_map[voice]) == -1)
     {
-      return RET_ERROR (EINVAL);
+      return -EINVAL;
     }
 
   if ((samplep = patch_table[patch]) == -1)
     {
-      return RET_ERROR (EINVAL);
+      return -EINVAL;
     }
 
   note_freq = note_to_freq (note_num);
@@ -1326,12 +1316,13 @@
    *    CAUTION!        Interrupts disabled. Don't return before enabling
    *************************************************************************/
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
   gus_select_voice (voice);
   gus_voice_off ();
   gus_rampoff ();
 
-  RESTORE_INTR (flags);
+  restore_flags (flags);
 
   if (voices[voice].mode & WAVE_ENVELOPES)
     {
@@ -1341,7 +1332,8 @@
   else
     compute_and_set_volume (voice, volume, 0);
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
   gus_select_voice (voice);
 
   if (samples[sample].mode & WAVE_LOOP_BACK)
@@ -1384,7 +1376,7 @@
   gus_voice_freq (freq);
   gus_voice_balance (pan);
   gus_voice_on (mode);
-  RESTORE_INTR (flags);
+  restore_flags (flags);
 
   return 0;
 }
@@ -1402,7 +1394,8 @@
   int             mode;
   int             ret_val = 0;
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
   if (note_num == 255)
     {
       if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
@@ -1426,11 +1419,12 @@
 
       if (voices[voice].sample_pending >= 0)
 	{
-	  RESTORE_INTR (flags);	/* Run temporarily with interrupts enabled */
+	  restore_flags (flags);	/* Run temporarily with interrupts enabled */
 	  guswave_set_instr (voices[voice].dev_pending, voice,
 			     voices[voice].sample_pending);
 	  voices[voice].sample_pending = -1;
-	  DISABLE_INTR (flags);
+	  save_flags (flags);
+	  cli ();
 	  gus_select_voice (voice);	/* Reselect the voice (just to be sure) */
 	}
 
@@ -1451,7 +1445,7 @@
 	  gus_rampon (0x20 | 0x40);	/* Ramp down, once, irq */
 	}
     }
-  RESTORE_INTR (flags);
+  restore_flags (flags);
   return ret_val;
 }
 
@@ -1473,17 +1467,23 @@
   int             err;
 
   if (gus_busy)
-    return RET_ERROR (EBUSY);
+    return -EBUSY;
 
   gus_initialize ();
   voice_alloc->timestamp = 0;
 
   if ((err = DMAbuf_open_dma (gus_devnum)) < 0)
-    gus_no_dma = 1;		/* Upload samples using PIO */
+    {
+      printk ("GUS: Loading saples without DMA\n");
+      gus_no_dma = 1;		/* Upload samples using PIO */
+    }
   else
     gus_no_dma = 0;
 
-  RESET_WAIT_QUEUE (dram_sleeper, dram_sleep_flag);
+  {
+    dram_sleep_flag.aborting = 0;
+    dram_sleep_flag.mode = WK_NONE;
+  };
   gus_busy = 1;
   active_device = GUS_DEV_WAVE;
 
@@ -1504,7 +1504,7 @@
 }
 
 static int
-guswave_load_patch (int dev, int format, snd_rw_buf * addr,
+guswave_load_patch (int dev, int format, const snd_rw_buf * addr,
 		    int offs, int count, int pmgr_flag)
 {
   struct patch_info patch;
@@ -1518,13 +1518,13 @@
   if (format != GUS_PATCH)
     {
       printk ("GUS Error: Invalid patch format (key) 0x%x\n", format);
-      return RET_ERROR (EINVAL);
+      return -EINVAL;
     }
 
   if (count < sizeof_patch)
     {
       printk ("GUS Error: Patch header too short\n");
-      return RET_ERROR (EINVAL);
+      return -EINVAL;
     }
 
   count -= sizeof_patch;
@@ -1532,7 +1532,7 @@
   if (free_sample >= MAX_SAMPLE)
     {
       printk ("GUS: Sample table full\n");
-      return RET_ERROR (ENOSPC);
+      return -ENOSPC;
     }
 
   /*
@@ -1540,14 +1540,14 @@
    * been transferred already.
    */
 
-  COPY_FROM_USER (&((char *) &patch)[offs], addr, offs, sizeof_patch - offs);
+  memcpy_fromfs ((&((char *) &patch)[offs]), &((addr)[offs]), (sizeof_patch - offs));
 
   instr = patch.instr_no;
 
   if (instr < 0 || instr > MAX_PATCH)
     {
       printk ("GUS: Invalid patch number %d\n", instr);
-      return RET_ERROR (EINVAL);
+      return -EINVAL;
     }
 
   if (count < patch.len)
@@ -1560,7 +1560,7 @@
   if (patch.len <= 0 || patch.len > gus_mem_size)
     {
       printk ("GUS: Invalid sample length %d\n", (int) patch.len);
-      return RET_ERROR (EINVAL);
+      return -EINVAL;
     }
 
   if (patch.mode & WAVE_LOOPING)
@@ -1568,13 +1568,13 @@
       if (patch.loop_start < 0 || patch.loop_start >= patch.len)
 	{
 	  printk ("GUS: Invalid loop start\n");
-	  return RET_ERROR (EINVAL);
+	  return -EINVAL;
 	}
 
       if (patch.loop_end < patch.loop_start || patch.loop_end > patch.len)
 	{
 	  printk ("GUS: Invalid loop end\n");
-	  return RET_ERROR (EINVAL);
+	  return -EINVAL;
 	}
     }
 
@@ -1590,7 +1590,7 @@
       if (patch.len >= GUS_BANK_SIZE)
 	{
 	  printk ("GUS: Sample (16 bit) too long %d\n", (int) patch.len);
-	  return RET_ERROR (ENOSPC);
+	  return -ENOSPC;
 	}
 
       if ((free_mem_ptr / GUS_BANK_SIZE) !=
@@ -1600,14 +1600,14 @@
 	  ((free_mem_ptr / GUS_BANK_SIZE) + 1) * GUS_BANK_SIZE;
 
 	  if ((tmp_mem + patch.len) > gus_mem_size)
-	    return RET_ERROR (ENOSPC);
+	    return -ENOSPC;
 
 	  free_mem_ptr = tmp_mem;	/* This leaves unusable memory */
 	}
     }
 
   if ((free_mem_ptr + patch.len) > gus_mem_size)
-    return RET_ERROR (ENOSPC);
+    return -ENOSPC;
 
   sample_ptrs[free_sample] = free_mem_ptr;
 
@@ -1637,7 +1637,8 @@
 
   while (left)			/* Not completely transferred yet */
     {
-      blk_size = audio_devs[gus_devnum]->buffsize;
+      /* blk_size = audio_devs[gus_devnum]->buffsize; */
+      blk_size = audio_devs[gus_devnum]->dmap_out->bytes_in_use;
       if (blk_size > left)
 	blk_size = left;
 
@@ -1661,9 +1662,10 @@
 	  long            i;
 	  unsigned char   data;
 
+
 	  for (i = 0; i < blk_size; i++)
 	    {
-	      GET_BYTE_FROM_USER (data, addr, sizeof_patch + i);
+	      data = get_fs_byte (&((addr)[sizeof_patch + i]));
 	      if (patch.mode & WAVE_UNSIGNED)
 
 		if (!(patch.mode & WAVE_16_BITS) || (i & 0x01))
@@ -1681,15 +1683,14 @@
 	   * OK, move now. First in and then out.
 	   */
 
-	  COPY_FROM_USER (audio_devs[gus_devnum]->dmap->raw_buf[0],
-			  addr, sizeof_patch + src_offs,
-			  blk_size);
+	  memcpy_fromfs ((audio_devs[gus_devnum]->dmap_out->raw_buf), &((addr)[sizeof_patch + src_offs]), (blk_size));
 
-	  DISABLE_INTR (flags);
+	  save_flags (flags);
+	  cli ();
 /******** INTERRUPTS DISABLED NOW ********/
 	  gus_write8 (0x41, 0);	/* Disable GF1 DMA */
 	  DMAbuf_start_dma (gus_devnum,
-			    audio_devs[gus_devnum]->dmap->raw_buf_phys[0],
+			    audio_devs[gus_devnum]->dmap_out->raw_buf_phys,
 			    blk_size, DMA_MODE_WRITE);
 
 	  /*
@@ -1698,7 +1699,7 @@
 
 	  address = target;
 
-	  if (audio_devs[gus_devnum]->dmachan > 3)
+	  if (audio_devs[gus_devnum]->dmachan1 > 3)
 	    {
 	      hold_address = address;
 	      address = address >> 1;
@@ -1717,7 +1718,7 @@
 	    dma_command |= 0x80;	/* Invert MSB */
 	  if (patch.mode & WAVE_16_BITS)
 	    dma_command |= 0x40;	/* 16 bit _DATA_ */
-	  if (audio_devs[gus_devnum]->dmachan > 3)
+	  if (audio_devs[gus_devnum]->dmachan1 > 3)
 	    dma_command |= 0x04;	/* 16 bit DMA _channel_ */
 
 	  gus_write8 (0x41, dma_command);	/* Lets bo luteet (=bugs) */
@@ -1727,10 +1728,28 @@
 	   */
 	  active_device = GUS_DEV_WAVE;
 
-	  DO_SLEEP (dram_sleeper, dram_sleep_flag, HZ);
-	  if (TIMED_OUT (dram_sleeper, dram_sleep_flag))
+
+	  {
+	    unsigned long   tl;
+
+	    if (HZ)
+	      tl = current->timeout = jiffies + (HZ);
+	    else
+	      tl = 0xffffffff;
+	    dram_sleep_flag.mode = WK_SLEEP;
+	    interruptible_sleep_on (&dram_sleeper);
+	    if (!(dram_sleep_flag.mode & WK_WAKEUP))
+	      {
+		if (current->signal & ~current->blocked)
+		  dram_sleep_flag.aborting = 1;
+		else if (jiffies >= tl)
+		  dram_sleep_flag.mode |= WK_TIMEOUT;
+	      }
+	    dram_sleep_flag.mode &= ~WK_SLEEP;
+	  };
+	  if ((dram_sleep_flag.mode & WK_TIMEOUT))
 	    printk ("GUS: DMA Transfer timed out\n");
-	  RESTORE_INTR (flags);
+	  restore_flags (flags);
 	}
 
       /*
@@ -1773,10 +1792,11 @@
     {
 
     case _GUS_NUMVOICES:
-      DISABLE_INTR (flags);
+      save_flags (flags);
+      cli ();
       gus_select_voice (voice);
       gus_select_max_voices (p1);
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       break;
 
     case _GUS_VOICESAMPLE:
@@ -1784,18 +1804,20 @@
       break;
 
     case _GUS_VOICEON:
-      DISABLE_INTR (flags);
+      save_flags (flags);
+      cli ();
       gus_select_voice (voice);
       p1 &= ~0x20;		/* Don't allow interrupts */
       gus_voice_on (p1);
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       break;
 
     case _GUS_VOICEOFF:
-      DISABLE_INTR (flags);
+      save_flags (flags);
+      cli ();
       gus_select_voice (voice);
       gus_voice_off ();
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       break;
 
     case _GUS_VOICEFADE:
@@ -1803,32 +1825,36 @@
       break;
 
     case _GUS_VOICEMODE:
-      DISABLE_INTR (flags);
+      save_flags (flags);
+      cli ();
       gus_select_voice (voice);
       p1 &= ~0x20;		/* Don't allow interrupts */
       gus_voice_mode (p1);
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       break;
 
     case _GUS_VOICEBALA:
-      DISABLE_INTR (flags);
+      save_flags (flags);
+      cli ();
       gus_select_voice (voice);
       gus_voice_balance (p1);
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       break;
 
     case _GUS_VOICEFREQ:
-      DISABLE_INTR (flags);
+      save_flags (flags);
+      cli ();
       gus_select_voice (voice);
       gus_voice_freq (plong);
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       break;
 
     case _GUS_VOICEVOL:
-      DISABLE_INTR (flags);
+      save_flags (flags);
+      cli ();
       gus_select_voice (voice);
       gus_voice_volume (p1);
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       break;
 
     case _GUS_VOICEVOL2:	/* Just update the software voice level */
@@ -1839,48 +1865,53 @@
     case _GUS_RAMPRANGE:
       if (voices[voice].mode & WAVE_ENVELOPES)
 	break;			/* NO-NO */
-      DISABLE_INTR (flags);
+      save_flags (flags);
+      cli ();
       gus_select_voice (voice);
       gus_ramp_range (p1, p2);
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       break;
 
     case _GUS_RAMPRATE:
       if (voices[voice].mode & WAVE_ENVELOPES)
 	break;			/* NJET-NJET */
-      DISABLE_INTR (flags);
+      save_flags (flags);
+      cli ();
       gus_select_voice (voice);
       gus_ramp_rate (p1, p2);
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       break;
 
     case _GUS_RAMPMODE:
       if (voices[voice].mode & WAVE_ENVELOPES)
 	break;			/* NO-NO */
-      DISABLE_INTR (flags);
+      save_flags (flags);
+      cli ();
       gus_select_voice (voice);
       p1 &= ~0x20;		/* Don't allow interrupts */
       gus_ramp_mode (p1);
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       break;
 
     case _GUS_RAMPON:
       if (voices[voice].mode & WAVE_ENVELOPES)
 	break;			/* EI-EI */
-      DISABLE_INTR (flags);
+      save_flags (flags);
+      cli ();
       gus_select_voice (voice);
       p1 &= ~0x20;		/* Don't allow interrupts */
       gus_rampon (p1);
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       break;
 
     case _GUS_RAMPOFF:
       if (voices[voice].mode & WAVE_ENVELOPES)
 	break;			/* NEJ-NEJ */
-      DISABLE_INTR (flags);
+      save_flags (flags);
+      cli ();
       gus_select_voice (voice);
       gus_rampoff ();
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       break;
 
     case _GUS_VOLUME_SCALE:
@@ -1889,10 +1920,11 @@
       break;
 
     case _GUS_VOICE_POS:
-      DISABLE_INTR (flags);
+      save_flags (flags);
+      cli ();
       gus_select_voice (voice);
       gus_set_voice_pos (voice, plong);
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       break;
 
     default:;
@@ -1946,66 +1978,69 @@
   if (bits != 8 && bits != 16)
     bits = 8;
 
+  if (only_8_bits)
+    bits = 8;
+
   gus_sampling_bits = bits;
   return bits;
 }
 
 static int
-gus_sampling_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
+gus_sampling_ioctl (int dev, unsigned int cmd, ioctl_arg arg, int local)
 {
   switch (cmd)
     {
     case SOUND_PCM_WRITE_RATE:
       if (local)
-	return gus_sampling_set_speed (arg);
-      return IOCTL_OUT (arg, gus_sampling_set_speed (IOCTL_IN (arg)));
+	return gus_sampling_set_speed ((int) arg);
+      return snd_ioctl_return ((int *) arg, gus_sampling_set_speed (get_fs_long ((long *) arg)));
       break;
 
     case SOUND_PCM_READ_RATE:
       if (local)
 	return gus_sampling_speed;
-      return IOCTL_OUT (arg, gus_sampling_speed);
+      return snd_ioctl_return ((int *) arg, gus_sampling_speed);
       break;
 
     case SNDCTL_DSP_STEREO:
       if (local)
-	return gus_sampling_set_channels (arg + 1) - 1;
-      return IOCTL_OUT (arg, gus_sampling_set_channels (IOCTL_IN (arg) + 1) - 1);
+	return gus_sampling_set_channels ((int) arg + 1) - 1;
+      return snd_ioctl_return ((int *) arg, gus_sampling_set_channels (get_fs_long ((long *) arg) + 1) - 1);
       break;
 
     case SOUND_PCM_WRITE_CHANNELS:
       if (local)
-	return gus_sampling_set_channels (arg);
-      return IOCTL_OUT (arg, gus_sampling_set_channels (IOCTL_IN (arg)));
+	return gus_sampling_set_channels ((int) arg);
+      return snd_ioctl_return ((int *) arg, gus_sampling_set_channels (get_fs_long ((long *) arg)));
       break;
 
     case SOUND_PCM_READ_CHANNELS:
       if (local)
 	return gus_sampling_channels;
-      return IOCTL_OUT (arg, gus_sampling_channels);
+      return snd_ioctl_return ((int *) arg, gus_sampling_channels);
       break;
 
     case SNDCTL_DSP_SETFMT:
       if (local)
-	return gus_sampling_set_bits (arg);
-      return IOCTL_OUT (arg, gus_sampling_set_bits (IOCTL_IN (arg)));
+	return gus_sampling_set_bits ((int) arg);
+      return snd_ioctl_return ((int *) arg, gus_sampling_set_bits (get_fs_long ((long *) arg)));
       break;
 
     case SOUND_PCM_READ_BITS:
       if (local)
 	return gus_sampling_bits;
-      return IOCTL_OUT (arg, gus_sampling_bits);
+      return snd_ioctl_return ((int *) arg, gus_sampling_bits);
 
     case SOUND_PCM_WRITE_FILTER:	/* NOT POSSIBLE */
-      return IOCTL_OUT (arg, RET_ERROR (EINVAL));
+      return snd_ioctl_return ((int *) arg, -EINVAL);
       break;
 
     case SOUND_PCM_READ_FILTER:
-      return IOCTL_OUT (arg, RET_ERROR (EINVAL));
+      return snd_ioctl_return ((int *) arg, -EINVAL);
       break;
 
     }
-  return RET_ERROR (EINVAL);
+  return -EINVAL;
 }
 
 static void
@@ -2021,14 +2056,8 @@
 static int
 gus_sampling_open (int dev, int mode)
 {
-  if (mode & OPEN_READ && dual_dma_mode)
-    {
-      printk ("GUS: The 8 bit input device is disabled. Use GUS MAX\n");
-      return RET_ERROR (ENOTTY);
-    }
-
   if (gus_busy)
-    return RET_ERROR (EBUSY);
+    return -EBUSY;
 
   gus_initialize ();
 
@@ -2048,6 +2077,11 @@
       set_input_volumes ();
     }
   only_read_access = !(mode & OPEN_WRITE);
+  only_8_bits = mode & OPEN_READ;
+  if (only_8_bits)
+    audio_devs[dev]->format_mask = AFMT_U8;
+  else
+    audio_devs[dev]->format_mask = AFMT_U8 | AFMT_S16_LE;
 
   return 0;
 }
@@ -2078,12 +2112,13 @@
   if (pcm_active && pcm_opened)
     for (voice = 0; voice < gus_sampling_channels; voice++)
       {
-	DISABLE_INTR (flags);
+	save_flags (flags);
+	cli ();
 	gus_select_voice (voice);
 	gus_rampoff ();
 	gus_voice_volume (1530 + (25 * gus_pcm_volume));
 	gus_ramp_range (65, 1530 + (25 * gus_pcm_volume));
-	RESTORE_INTR (flags);
+	restore_flags (flags);
       }
 }
 
@@ -2134,7 +2169,8 @@
 	    ramp_mode[chn] = 0x04;	/* Enable rollover bit */
 	}
 
-      DISABLE_INTR (flags);
+      save_flags (flags);
+      cli ();
       gus_select_voice (chn);
       gus_voice_freq (speed);
 
@@ -2193,16 +2229,17 @@
 	    }
 	}
 
-      RESTORE_INTR (flags);
+      restore_flags (flags);
     }
 
   for (chn = 0; chn < gus_sampling_channels; chn++)
     {
-      DISABLE_INTR (flags);
+      save_flags (flags);
+      cli ();
       gus_select_voice (chn);
       gus_write8 (0x0d, ramp_mode[chn]);
       gus_voice_on (mode[chn]);
-      RESTORE_INTR (flags);
+      restore_flags (flags);
     }
 
   pcm_active = 1;
@@ -2226,7 +2263,8 @@
   unsigned char   dma_command;
   unsigned long   address, hold_address;
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
 
   count = total_count / gus_sampling_channels;
 
@@ -2249,7 +2287,7 @@
   address = this_one * pcm_bsize;
   address += chn * pcm_banksize;
 
-  if (audio_devs[dev]->dmachan > 3)
+  if (audio_devs[dev]->dmachan1 > 3)
     {
       hold_address = address;
       address = address >> 1;
@@ -2266,7 +2304,7 @@
   else
     dma_command |= 0x80;	/* Invert MSB */
 
-  if (audio_devs[dev]->dmachan > 3)
+  if (audio_devs[dev]->dmachan1 > 3)
     dma_command |= 0x04;	/* 16 bit DMA channel */
 
   gus_write8 (0x41, dma_command);	/* Kickstart */
@@ -2292,7 +2330,7 @@
       active_device = GUS_DEV_PCM_CONTINUE;
     }
 
-  RESTORE_INTR (flags);
+  restore_flags (flags);
 }
 
 static void
@@ -2313,13 +2351,14 @@
   unsigned long   flags;
   unsigned char   mode;
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
 
   DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ);
 
   mode = 0xa0;			/* DMA IRQ enabled, invert MSB */
 
-  if (audio_devs[dev]->dmachan > 3)
+  if (audio_devs[dev]->dmachan2 > 3)
     mode |= 0x04;		/* 16 bit DMA channel */
   if (gus_sampling_channels > 1)
     mode |= 0x02;		/* Stereo */
@@ -2327,7 +2366,7 @@
 
   gus_write8 (0x49, mode);
 
-  RESTORE_INTR (flags);
+  restore_flags (flags);
 }
 
 static int
@@ -2342,7 +2381,7 @@
   if (gus_sampling_bits != 8)
     {
       printk ("GUS Error: 16 bit recording not supported\n");
-      return RET_ERROR (EINVAL);
+      return -EINVAL;
     }
 
   return 0;
@@ -2387,11 +2426,11 @@
 
 static void
 gus_copy_from_user (int dev, char *localbuf, int localoffs,
-		    snd_rw_buf * userbuf, int useroffs, int len)
+		    const snd_rw_buf * userbuf, int useroffs, int len)
 {
   if (gus_sampling_channels == 1)
     {
-      COPY_FROM_USER (&localbuf[localoffs], userbuf, useroffs, len);
+      memcpy_fromfs ((&localbuf[localoffs]), &((userbuf)[useroffs]), (len));
     }
   else if (gus_sampling_bits == 8)
     {
@@ -2407,9 +2446,9 @@
 
       for (i = 0; i < len; i++)
 	{
-	  GET_BYTE_FROM_USER (*out_left++, userbuf, in_left);
+	  *out_left++ = get_fs_byte (&((userbuf)[in_left]));
 	  in_left += 2;
-	  GET_BYTE_FROM_USER (*out_right++, userbuf, in_right);
+	  *out_right++ = get_fs_byte (&((userbuf)[in_right]));
 	  in_right += 2;
 	}
     }
@@ -2428,9 +2467,9 @@
 
       for (i = 0; i < len; i++)
 	{
-	  GET_SHORT_FROM_USER (*out_left++, (short *) userbuf, in_left);
+	  *out_left++ = get_fs_word (&(((short *) userbuf)[in_left]));
 	  in_left += 2;
-	  GET_SHORT_FROM_USER (*out_right++, (short *) userbuf, in_right);
+	  *out_right++ = get_fs_word (&(((short *) userbuf)[in_right]));
 	  in_right += 2;
 	}
     }
@@ -2479,14 +2518,15 @@
   unsigned long   flags;
 
   voices[voice].bender = value - 8192;
-  freq = compute_finetune (voices[voice].orig_freq, value,
+  freq = compute_finetune (voices[voice].orig_freq, value - 8192,
 			   voices[voice].bender_range);
   voices[voice].current_freq = freq;
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
   gus_select_voice (voice);
   gus_voice_freq (freq);
-  RESTORE_INTR (flags);
+  restore_flags (flags);
 }
 
 static int
@@ -2546,7 +2586,7 @@
 	struct patch_info *pat;
 
 	if (ptr < 0 || ptr >= free_sample)
-	  return RET_ERROR (EINVAL);
+	  return -EINVAL;
 
 	memcpy (rec->data.data8, (char *) &samples[ptr],
 		sizeof (struct patch_info));
@@ -2566,12 +2606,12 @@
 	struct patch_info *pat;
 
 	if (ptr < 0 || ptr >= free_sample)
-	  return RET_ERROR (EINVAL);
+	  return -EINVAL;
 
 	pat = (struct patch_info *) rec->data.data8;
 
 	if (pat->len > samples[ptr].len)	/* Cannot expand sample */
-	  return RET_ERROR (EINVAL);
+	  return -EINVAL;
 
 	pat->key = samples[ptr].key;	/* Ensure the link is correct */
 
@@ -2591,10 +2631,10 @@
 	int             l = rec->parm3;
 
 	if (sample < 0 || sample >= free_sample)
-	  return RET_ERROR (EINVAL);
+	  return -EINVAL;
 
 	if (offs < 0 || offs >= samples[sample].len)
-	  return RET_ERROR (EINVAL);	/* Invalid offset */
+	  return -EINVAL;	/* Invalid offset */
 
 	n = samples[sample].len - offs;		/* Num of bytes left */
 
@@ -2605,9 +2645,9 @@
 	  l = sizeof (rec->data.data8);
 
 	if (l <= 0)
-	  return RET_ERROR (EINVAL);	/*
-					 * Was there a bug?
-					 */
+	  return -EINVAL;	/*
+				   * Was there a bug?
+				 */
 
 	offs += sample_ptrs[sample];	/*
 					 * Begin offsess + offset to DRAM
@@ -2632,12 +2672,12 @@
 	int             l = rec->parm3;
 
 	if (sample < 0 || sample >= free_sample)
-	  return RET_ERROR (EINVAL);
+	  return -EINVAL;
 
 	if (offs < 0 || offs >= samples[sample].len)
-	  return RET_ERROR (EINVAL);	/*
-					 * Invalid offset
-					 */
+	  return -EINVAL;	/*
+				   * Invalid offset
+				 */
 
 	n = samples[sample].len - offs;		/*
 						   * Nr of bytes left
@@ -2650,9 +2690,9 @@
 	  l = sizeof (rec->data.data8);
 
 	if (l <= 0)
-	  return RET_ERROR (EINVAL);	/*
-					 * Was there a bug?
-					 */
+	  return -EINVAL;	/*
+				   * Was there a bug?
+				 */
 
 	offs += sample_ptrs[sample];	/*
 					 * Begin offsess + offset to DRAM
@@ -2668,7 +2708,7 @@
       break;
 
     default:
-      return RET_ERROR (EINVAL);
+      return -EINVAL;
     }
 }
 
@@ -2752,7 +2792,8 @@
   if (have_gus_max)		/* Don't disturb GUS MAX */
     return;
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
 
   /*
    *    Enable channels having vol > 10%
@@ -2777,13 +2818,13 @@
 
   mix_image &= ~0x07;
   mix_image |= mask & 0x07;
-  OUTB (mix_image, u_Mixer);
+  outb (mix_image, u_Mixer);
 
-  RESTORE_INTR (flags);
+  restore_flags (flags);
 }
 
 int
-gus_default_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg)
+gus_default_mixer_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
 {
 #define MIX_DEVS	(SOUND_MASK_MIC|SOUND_MASK_LINE| \
 			 SOUND_MASK_SYNTH|SOUND_MASK_PCM)
@@ -2793,16 +2834,16 @@
 	switch (cmd & 0xff)
 	  {
 	  case SOUND_MIXER_RECSRC:
-	    gus_recmask = IOCTL_IN (arg) & MIX_DEVS;
+	    gus_recmask = get_fs_long ((long *) arg) & MIX_DEVS;
 	    if (!(gus_recmask & (SOUND_MASK_MIC | SOUND_MASK_LINE)))
 	      gus_recmask = SOUND_MASK_MIC;
 	    /* Note! Input volumes are updated during next open for recording */
-	    return IOCTL_OUT (arg, gus_recmask);
+	    return snd_ioctl_return ((int *) arg, gus_recmask);
 	    break;
 
 	  case SOUND_MIXER_MIC:
 	    {
-	      int             vol = IOCTL_IN (arg) & 0xff;
+	      int             vol = get_fs_long ((long *) arg) & 0xff;
 
 	      if (vol < 0)
 		vol = 0;
@@ -2810,13 +2851,13 @@
 		vol = 100;
 	      gus_mic_vol = vol;
 	      set_input_volumes ();
-	      return IOCTL_OUT (arg, vol | (vol << 8));
+	      return snd_ioctl_return ((int *) arg, vol | (vol << 8));
 	    }
 	    break;
 
 	  case SOUND_MIXER_LINE:
 	    {
-	      int             vol = IOCTL_IN (arg) & 0xff;
+	      int             vol = get_fs_long ((long *) arg) & 0xff;
 
 	      if (vol < 0)
 		vol = 0;
@@ -2824,25 +2865,25 @@
 		vol = 100;
 	      gus_line_vol = vol;
 	      set_input_volumes ();
-	      return IOCTL_OUT (arg, vol | (vol << 8));
+	      return snd_ioctl_return ((int *) arg, vol | (vol << 8));
 	    }
 	    break;
 
 	  case SOUND_MIXER_PCM:
-	    gus_pcm_volume = IOCTL_IN (arg) & 0xff;
+	    gus_pcm_volume = get_fs_long ((long *) arg) & 0xff;
 	    if (gus_pcm_volume < 0)
 	      gus_pcm_volume = 0;
 	    if (gus_pcm_volume > 100)
 	      gus_pcm_volume = 100;
 	    gus_sampling_update_volume ();
-	    return IOCTL_OUT (arg, gus_pcm_volume | (gus_pcm_volume << 8));
+	    return snd_ioctl_return ((int *) arg, gus_pcm_volume | (gus_pcm_volume << 8));
 	    break;
 
 	  case SOUND_MIXER_SYNTH:
 	    {
 	      int             voice;
 
-	      gus_wave_volume = IOCTL_IN (arg) & 0xff;
+	      gus_wave_volume = get_fs_long ((long *) arg) & 0xff;
 
 	      if (gus_wave_volume < 0)
 		gus_wave_volume = 0;
@@ -2853,12 +2894,12 @@
 		for (voice = 0; voice < nr_voices; voice++)
 		  dynamic_volume_change (voice);	/* Apply the new vol */
 
-	      return IOCTL_OUT (arg, gus_wave_volume | (gus_wave_volume << 8));
+	      return snd_ioctl_return ((int *) arg, gus_wave_volume | (gus_wave_volume << 8));
 	    }
 	    break;
 
 	  default:
-	    return RET_ERROR (EINVAL);
+	    return -EINVAL;
 	  }
       else
 	switch (cmd & 0xff)	/*
@@ -2867,47 +2908,47 @@
 	  {
 
 	  case SOUND_MIXER_RECSRC:
-	    return IOCTL_OUT (arg, gus_recmask);
+	    return snd_ioctl_return ((int *) arg, gus_recmask);
 	    break;
 
 	  case SOUND_MIXER_DEVMASK:
-	    return IOCTL_OUT (arg, MIX_DEVS);
+	    return snd_ioctl_return ((int *) arg, MIX_DEVS);
 	    break;
 
 	  case SOUND_MIXER_STEREODEVS:
-	    return IOCTL_OUT (arg, 0);
+	    return snd_ioctl_return ((int *) arg, 0);
 	    break;
 
 	  case SOUND_MIXER_RECMASK:
-	    return IOCTL_OUT (arg, SOUND_MASK_MIC | SOUND_MASK_LINE);
+	    return snd_ioctl_return ((int *) arg, SOUND_MASK_MIC | SOUND_MASK_LINE);
 	    break;
 
 	  case SOUND_MIXER_CAPS:
-	    return IOCTL_OUT (arg, 0);
+	    return snd_ioctl_return ((int *) arg, 0);
 	    break;
 
 	  case SOUND_MIXER_MIC:
-	    return IOCTL_OUT (arg, gus_mic_vol | (gus_mic_vol << 8));
+	    return snd_ioctl_return ((int *) arg, gus_mic_vol | (gus_mic_vol << 8));
 	    break;
 
 	  case SOUND_MIXER_LINE:
-	    return IOCTL_OUT (arg, gus_line_vol | (gus_line_vol << 8));
+	    return snd_ioctl_return ((int *) arg, gus_line_vol | (gus_line_vol << 8));
 	    break;
 
 	  case SOUND_MIXER_PCM:
-	    return IOCTL_OUT (arg, gus_pcm_volume | (gus_pcm_volume << 8));
+	    return snd_ioctl_return ((int *) arg, gus_pcm_volume | (gus_pcm_volume << 8));
 	    break;
 
 	  case SOUND_MIXER_SYNTH:
-	    return IOCTL_OUT (arg, gus_wave_volume | (gus_wave_volume << 8));
+	    return snd_ioctl_return ((int *) arg, gus_wave_volume | (gus_wave_volume << 8));
 	    break;
 
 	  default:
-	    return RET_ERROR (EINVAL);
+	    return -EINVAL;
 	  }
     }
   else
-    return RET_ERROR (EINVAL);
+    return -EINVAL;
 }
 
 static struct mixer_operations gus_mixer_operations =
@@ -2933,19 +2974,20 @@
  */
       mix_image &= ~0x07;
       mix_image |= 0x04;	/* All channels enabled */
-      OUTB (mix_image, u_Mixer);
+      outb (mix_image, u_Mixer);
     }
   return mem_start;
 }
 
 long
-gus_wave_init (long mem_start, int irq, int dma)
+gus_wave_init (long mem_start, struct address_info *hw_config)
 {
   unsigned long   flags;
   unsigned char   val;
   char           *model_num = "2.4";
   int             gus_type = 0x24;	/* 2.4 */
-  int             mixer_type = 0;
+
+  int             irq = hw_config->irq, dma = hw_config->dma, dma2 = hw_config->dma2;
 
   if (irq < 0 || irq > 15)
     {
@@ -2961,13 +3003,10 @@
 
   gus_irq = irq;
   gus_dma = dma;
-#ifdef GUSMAX_DMA
-  if (gusmax_dma == -1)		/* Not already set */
-    gusmax_dma = GUSMAX_DMA;
-#else
-  if (gusmax_dma == -1)
-    gusmax_dma = dma;
-#endif
+  gus_dma2 = dma2;
+
+  if (gus_dma2 == -1)
+    gus_dma2 = dma;
 
   /*
      * Try to identify the GUS model.
@@ -2975,10 +3014,11 @@
      *  Versions < 3.6 don't have the digital ASIC. Try to probe it first.
    */
 
-  DISABLE_INTR (flags);
-  OUTB (0x20, gus_base + 0x0f);
-  val = INB (gus_base + 0x0f);
-  RESTORE_INTR (flags);
+  save_flags (flags);
+  cli ();
+  outb (0x20, gus_base + 0x0f);
+  val = inb (gus_base + 0x0f);
+  restore_flags (flags);
 
   if (val != 0xff && (val & 0x06))	/* Should be 0x02?? */
     {
@@ -2987,7 +3027,7 @@
          * Next try to detect the true model.
        */
 
-      val = INB (u_MixSelect);
+      val = inb (u_MixSelect);
 
       /*
          * Value 255 means pre-3.7 which don't have mixer.
@@ -3006,6 +3046,7 @@
 	  model_num = "3.7";
 	  gus_type = 0x37;
 	  mixer_type = ICS2101;
+	  request_region (u_MixSelect, 1, "GUS mixer");
 	}
       else
 	{
@@ -3016,26 +3057,32 @@
 	  {
 	    unsigned char   max_config = 0x40;	/* Codec enable */
 
+	    if (gus_dma2 == -1)
+	      gus_dma2 = gus_dma;
+
 	    if (gus_dma > 3)
 	      max_config |= 0x10;	/* 16 bit capture DMA */
 
-	    if (gusmax_dma > 3)
+	    if (gus_dma2 > 3)
 	      max_config |= 0x20;	/* 16 bit playback DMA */
 
 	    max_config |= (gus_base >> 4) & 0x0f;	/* Extract the X from 2X0 */
 
-	    OUTB (max_config, gus_base + 0x106);	/* UltraMax control */
+	    outb (max_config, gus_base + 0x106);	/* UltraMax control */
 	  }
 
-	  if (ad1848_detect (gus_base + 0x10c))
+	  if (ad1848_detect (gus_base + 0x10c, NULL, hw_config->osp))
 	    {
+
 	      gus_mic_vol = gus_line_vol = gus_pcm_volume = 100;
 	      gus_wave_volume = 90;
 	      have_gus_max = 1;
 	      ad1848_init ("GUS MAX", gus_base + 0x10c,
 			   -irq,
-			   gusmax_dma,	/* Playback DMA */
-			   gus_dma);	/* Capture DMA */
+			   gus_dma2,	/* Playback DMA */
+			   gus_dma,	/* Capture DMA */
+			   1,	/* Share DMA channels with GF1 */
+			   hw_config->osp);
 	    }
 	  else
 	    printk ("[Where's the CS4231?]");
@@ -3063,10 +3110,20 @@
     {
       voice_alloc = &guswave_operations.alloc;
       synth_devs[num_synths++] = &guswave_operations;
+#ifndef EXCLUDE_SEQUENCER
+      gus_tmr_install (gus_base + 8);
+#endif
     }
 
-  PERMANENT_MALLOC (struct patch_info *, samples,
-	                   (MAX_SAMPLE + 1) * sizeof (*samples), mem_start);
+
+  {
+    caddr_t         ptr;
+
+    ptr = sound_mem_blocks[sound_num_blocks] = kmalloc ((MAX_SAMPLE + 1) * sizeof (*samples), GFP_KERNEL);
+    if (sound_num_blocks < 1024)
+      sound_num_blocks++;
+    samples = (struct patch_info *) ptr;
+  };
 
   reset_sample_memory ();
 
@@ -3075,9 +3132,11 @@
   if (num_audiodevs < MAX_AUDIO_DEV)
     {
       audio_devs[gus_devnum = num_audiodevs++] = &gus_sampling_operations;
-      audio_devs[gus_devnum]->dmachan = dma;
-      audio_devs[gus_devnum]->buffcount = 1;
+      audio_devs[gus_devnum]->dmachan1 = dma;
+      audio_devs[gus_devnum]->dmachan2 = dma2;
       audio_devs[gus_devnum]->buffsize = DSP_BUFFSIZE;
+      if (dma2 != dma && dma2 != -1)
+	audio_devs[gus_devnum]->flags |= DMA_DUPLEX;
     }
   else
     printk ("GUS: Too many PCM devices available\n");
@@ -3091,6 +3150,7 @@
     case ICS2101:
       gus_mic_vol = gus_line_vol = gus_pcm_volume = 100;
       gus_wave_volume = 90;
+      request_region (u_MixSelect, 1, "GUS mixer");
       return ics2101_mixer_init (mem_start);
 
     case CS4231:
@@ -3100,6 +3160,26 @@
     }
 }
 
+void
+gus_wave_unload (void)
+{
+#ifndef EXCLUDE_GUSMAX
+  if (have_gus_max)
+    {
+      ad1848_unload (gus_base + 0x10c,
+		     -gus_irq,
+		     gus_dma2,	/* Playback DMA */
+		     gus_dma,	/* Capture DMA */
+		     1);	/* Share DMA channels with GF1 */
+    }
+#endif
+
+  if (mixer_type == ICS2101)
+    {
+      release_region (u_MixSelect, 1);
+    }
+}
+
 static void
 do_loop_irq (int voice)
 {
@@ -3107,7 +3187,8 @@
   int             mode, parm;
   unsigned long   flags;
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
   gus_select_voice (voice);
 
   tmp = gus_read8 (0x00);
@@ -3192,7 +3273,7 @@
 
     default:;
     }
-  RESTORE_INTR (flags);
+  restore_flags (flags);
 }
 
 static void
@@ -3202,7 +3283,8 @@
   int             mode, parm;
   unsigned long   flags;
 
-  DISABLE_INTR (flags);
+  save_flags (flags);
+  cli ();
 
   gus_select_voice (voice);
 
@@ -3221,18 +3303,18 @@
     case VMODE_HALT:		/*
 				 * Decay phase finished
 				 */
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       gus_voice_init (voice);
       break;
 
     case VMODE_ENVELOPE:
       gus_rampoff ();
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       step_envelope (voice);
       break;
 
     case VMODE_START_NOTE:
-      RESTORE_INTR (flags);
+      restore_flags (flags);
       guswave_start_note2 (voices[voice].dev_pending, voice,
 		  voices[voice].note_pending, voices[voice].volume_pending);
       if (voices[voice].kill_pending)
@@ -3310,8 +3392,11 @@
     switch (active_device)
       {
       case GUS_DEV_WAVE:
-	if (SOMEONE_WAITING (dram_sleeper, dram_sleep_flag))
-	  WAKE_UP (dram_sleeper, dram_sleep_flag);
+	if ((dram_sleep_flag.mode & WK_SLEEP))
+	  {
+	    dram_sleep_flag.mode = WK_WAKEUP;
+	    wake_up (&dram_sleeper);
+	  };
 	break;
 
       case GUS_DEV_PCM_CONTINUE:	/* Left channel data transferred */
@@ -3346,5 +3431,109 @@
     }
 
 }
+
+#ifndef EXCLUDE_SEQUENCER
+/*
+ * Timer stuff
+ */
+
+static volatile int select_addr, data_addr;
+static volatile int curr_timer = 0;
+
+void
+gus_timer_command (unsigned int addr, unsigned int val)
+{
+  int             i;
+
+  outb ((unsigned char) (addr & 0xff), select_addr);
+
+  for (i = 0; i < 2; i++)
+    inb (select_addr);
+
+  outb ((unsigned char) (val & 0xff), data_addr);
+
+  for (i = 0; i < 2; i++)
+    inb (select_addr);
+}
+
+static void
+arm_timer (int timer, unsigned int interval)
+{
+
+  curr_timer = timer;
+
+  if (timer == 1)
+    {
+      gus_write8 (0x46, 256 - interval);	/* Set counter for timer 1 */
+      gus_write8 (0x45, 0x04);	/* Enable timer 1 IRQ */
+      gus_timer_command (0x04, 0x01);	/* Start timer 1 */
+    }
+  else
+    {
+      gus_write8 (0x47, 256 - interval);	/* Set counter for timer 2 */
+      gus_write8 (0x45, 0x08);	/* Enable timer 2 IRQ */
+      gus_timer_command (0x04, 0x02);	/* Start timer 2 */
+    }
+
+  gus_timer_enabled = 0;
+}
+
+static unsigned int
+gus_tmr_start (int dev, unsigned int usecs_per_tick)
+{
+  int             timer_no, resolution;
+  int             divisor;
+
+  if (usecs_per_tick > (256 * 80))
+    {
+      timer_no = 2;
+      resolution = 320;		/* usec */
+    }
+  else
+    {
+      timer_no = 1;
+      resolution = 80;		/* usec */
+    }
+
+  divisor = (usecs_per_tick + (resolution / 2)) / resolution;
+
+  arm_timer (timer_no, divisor);
+
+  return divisor * resolution;
+}
+
+static void
+gus_tmr_disable (int dev)
+{
+  gus_write8 (0x45, 0);		/* Disable both timers */
+  gus_timer_enabled = 0;
+}
+
+static void
+gus_tmr_restart (int dev)
+{
+  if (curr_timer == 1)
+    gus_write8 (0x45, 0x04);	/* Start timer 1 again */
+  else
+    gus_write8 (0x45, 0x08);	/* Start timer 2 again */
+}
+
+static struct sound_lowlev_timer gus_tmr =
+{
+  0,
+  gus_tmr_start,
+  gus_tmr_disable,
+  gus_tmr_restart
+};
+
+static void
+gus_tmr_install (int io_base)
+{
+  select_addr = io_base;
+  data_addr = io_base + 1;
+
+  sound_timer_init (&gus_tmr, "GUS");
+}
+#endif
 
 #endif

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this