To: linux-m68k@lists.linux-m68k.org
Subject: L68K: 2.1.105
X-Yow: Yow!  I'm having a quadraphonic sensation of two winos
 alone in a steel mill!
From: Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
Date: 12 Jun 1998 10:21:21 +0200
Sender: owner-linux-m68k@phil.uni-sb.de

Here are some patches for 2.1.105:

- m68k_ksyms.c: remove unused includes.
- ll_rw_blk.c: avoid NULL access.
- atari_SCC.h: merge SCC_ACCESS_INIT macros.
- mem.c, dmasound.c: converted to use sound_core.
- n_tty.c, tty_ioctl.c, tty.h: make shared read_cnt atomic.
- ext2/inode.c: fix permission test (already reported to maintainer long
  ago, but he didn't answer yet).
- binfmt_aout.c: fix resource leak.
- scsi_proc.c: fix use of kmalloc (in unused function).

Andreas.

----------------------------------------------------------------------
--- linux-2.1.105/arch/m68k/kernel/m68k_ksyms.c.~1~	Wed Jun 10 17:57:50 1998
+++ linux-2.1.105/arch/m68k/kernel/m68k_ksyms.c	Mon May 18 17:44:13 1998
@@ -1,4 +1,3 @@
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/linkage.h>
 #include <linux/sched.h>
@@ -8,7 +7,6 @@
 #include <linux/elfcore.h>
 #include <linux/in6.h>
 #include <linux/interrupt.h>
-#include <linux/pci.h>
 
 #include <asm/setup.h>
 #include <asm/machdep.h>
--- linux-2.1.105/drivers/block/ll_rw_blk.c.~1~	Wed Jun 10 17:58:28 1998
+++ linux-2.1.105/drivers/block/ll_rw_blk.c	Wed Jun 10 19:10:56 1998
@@ -583,7 +583,9 @@
 
 	/* Verify requested block sizes.  */
 	for (i = 0; i < nr; i++) {
-		if (bh[i] && bh[i]->b_size != correct_size) {
+		if (!bh[i])
+			continue;
+		if (bh[i]->b_size != correct_size) {
 			printk(KERN_NOTICE "ll_rw_block: device %s: "
 			       "only %d-char blocks implemented (%lu)\n",
 			       kdevname(bh[0]->b_dev),
--- linux-2.1.105/drivers/char/atari_SCC.h.~1~	Wed Jun 10 17:58:52 1998
+++ linux-2.1.105/drivers/char/atari_SCC.h	Wed Jun 10 19:17:37 1998
@@ -594,27 +594,13 @@
 
 /*
  * The BVME6000 maps the two halves of the SCC 8 bytes apart rather than 4.
- * My first attempt at doing this in assembler didn't work, so I've done it
- * the easy way for now.  Richard.
  */
 
-#ifdef CONFIG_BVME6000
-
-#define SCC_ACCESS_INIT(info)					\
-	volatile struct PARTIAL_SCC *_SCC_p =			\
-		(volatile struct PARTIAL_SCC *)info->port;	\
-	unsigned char *_SCC_shadow = SCC_shadow[0] +		\
-		(MACH_IS_BVME6000 ? ((u32)_SCC_p & 8) * 2 : ((u32)_SCC_p & 4) * 4)
-
-#else
-
 #define SCC_ACCESS_INIT(info)						\
 	volatile struct PARTIAL_SCC *_SCC_p =				\
 		(volatile struct PARTIAL_SCC *)info->port;		\
 	unsigned char *_SCC_shadow =					\
-		&SCC_shadow[(info->port >> 2) & 1][0]
-
-#endif
+		&SCC_shadow[(info->port >> (MACH_IS_BVME6000 ? 3 : 2)) & 1][0]
 
 #define	SCCwrite(reg,val)		_SCCwrite(_SCC_p,_SCC_shadow,scc_del,(reg),(val),1)
 #define	SCCwrite_NB(reg,val)	_SCCwrite(_SCC_p,_SCC_shadow,scc_del,(reg),(val),0)
--- linux-2.1.105/drivers/char/mem.c.~1~	Wed Jun 10 17:59:21 1998
+++ linux-2.1.105/drivers/char/mem.c	Wed Jun 10 23:02:03 1998
@@ -27,8 +27,14 @@
 #include <asm/pgtable.h>
 
 #ifdef CONFIG_SOUND
+void soundcore_init(void);
+#ifdef CONFIG_SOUND_OSS
 void soundcard_init(void);
 #endif
+#ifdef CONFIG_DMASOUND
+void dmasound_init(void);
+#endif
+#endif
 #ifdef CONFIG_ISDN
 int isdn_init(void);
 #endif
@@ -606,6 +612,9 @@
 	soundcore_init();
 #ifdef CONFIG_SOUND_OSS	
 	soundcard_init();
+#endif	
+#ifdef CONFIG_DMASOUND
+	dmasound_init();
 #endif	
 #endif
 #ifdef CONFIG_JOYSTICK
--- linux-2.1.105/drivers/char/n_tty.c.~1~	Wed Mar 18 19:45:51 1998
+++ linux-2.1.105/drivers/char/n_tty.c	Sun May 10 16:13:59 1998
@@ -59,10 +59,10 @@
 
 static inline void put_tty_queue(unsigned char c, struct tty_struct *tty)
 {
-	if (tty->read_cnt < N_TTY_BUF_SIZE) {
+	if (atomic_read(&tty->read_cnt) < N_TTY_BUF_SIZE) {
 		tty->read_buf[tty->read_head] = c;
 		tty->read_head = (tty->read_head + 1) & (N_TTY_BUF_SIZE-1);
-		tty->read_cnt++;
+		atomic_inc(&tty->read_cnt);
 	}
 }
 
@@ -85,7 +85,8 @@
  */
 static void reset_buffer_flags(struct tty_struct *tty)
 {
-	tty->read_head = tty->read_tail = tty->read_cnt = 0;
+	tty->read_head = tty->read_tail = 0;
+	atomic_set(&tty->read_cnt, 0);
 	tty->canon_head = tty->canon_data = tty->erasing = 0;
 	memset(&tty->read_flags, 0, sizeof tty->read_flags);
 	check_unthrottle(tty);
@@ -120,7 +121,7 @@
 			tty->canon_head - tty->read_tail :
 			tty->canon_head + (N_TTY_BUF_SIZE - tty->read_tail);
 	}
-	return tty->read_cnt;
+	return atomic_read(&tty->read_cnt);
 }
 
 /*
@@ -293,14 +294,16 @@
 		kill_type = WERASE;
 	else {
 		if (!L_ECHO(tty)) {
-			tty->read_cnt -= ((tty->read_head - tty->canon_head) &
-					  (N_TTY_BUF_SIZE - 1));
+			atomic_sub(((tty->read_head - tty->canon_head) &
+				    (N_TTY_BUF_SIZE - 1)),
+				   &tty->read_cnt);
 			tty->read_head = tty->canon_head;
 			return;
 		}
 		if (!L_ECHOK(tty) || !L_ECHOKE(tty) || !L_ECHOE(tty)) {
-			tty->read_cnt -= ((tty->read_head - tty->canon_head) &
-					  (N_TTY_BUF_SIZE - 1));
+			atomic_sub(((tty->read_head - tty->canon_head) &
+				    (N_TTY_BUF_SIZE - 1)),
+				   &tty->read_cnt);
 			tty->read_head = tty->canon_head;
 			finish_erasing(tty);
 			echo_char(KILL_CHAR(tty), tty);
@@ -324,7 +327,7 @@
 				break;
 		}
 		tty->read_head = head;
-		tty->read_cnt--;
+		atomic_dec(&tty->read_cnt);
 		if (L_ECHO(tty)) {
 			if (L_ECHOPRT(tty)) {
 				if (!tty->erasing) {
@@ -482,7 +485,7 @@
 		finish_erasing(tty);
 		tty->lnext = 0;
 		if (L_ECHO(tty)) {
-			if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
+			if (atomic_read(&tty->read_cnt) >= N_TTY_BUF_SIZE-1) {
 				put_char('\a', tty); /* beep if no space */
 				return;
 			}
@@ -561,7 +564,7 @@
 		}
 		if (c == '\n') {
 			if (L_ECHO(tty) || L_ECHONL(tty)) {
-				if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
+				if (atomic_read(&tty->read_cnt) >= N_TTY_BUF_SIZE-1) {
 					put_char('\a', tty);
 					return;
 				}
@@ -581,7 +584,7 @@
 			 * XXX are EOL_CHAR and EOL2_CHAR echoed?!?
 			 */
 			if (L_ECHO(tty)) {
-				if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
+				if (atomic_read(&tty->read_cnt) >= N_TTY_BUF_SIZE-1) {
 					put_char('\a', tty);
 					return;
 				}
@@ -612,7 +615,7 @@
 	
 	finish_erasing(tty);
 	if (L_ECHO(tty)) {
-		if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
+		if (atomic_read(&tty->read_cnt) >= N_TTY_BUF_SIZE-1) {
 			put_char('\a', tty); /* beep if no space */
 			return;
 		}
@@ -634,7 +637,7 @@
 
 static int n_tty_receive_room(struct tty_struct *tty)
 {
-	int	left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
+	int	left = N_TTY_BUF_SIZE - atomic_read(&tty->read_cnt) - 1;
 
 	/*
 	 * If we are doing input canonicalization, and there are no
@@ -662,19 +665,20 @@
 		return;
 
 	if (tty->real_raw) {
-		i = MIN(count, MIN(N_TTY_BUF_SIZE - tty->read_cnt,
+		int read_cnt = atomic_read(&tty->read_cnt);
+		i = MIN(count, MIN(N_TTY_BUF_SIZE - read_cnt,
 				   N_TTY_BUF_SIZE - tty->read_head));
 		memcpy(tty->read_buf + tty->read_head, cp, i);
 		tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
-		tty->read_cnt += i;
+		read_cnt += i;
 		cp += i;
 		count -= i;
 
-		i = MIN(count, MIN(N_TTY_BUF_SIZE - tty->read_cnt,
+		i = MIN(count, MIN(N_TTY_BUF_SIZE - read_cnt,
 			       N_TTY_BUF_SIZE - tty->read_head));
 		memcpy(tty->read_buf + tty->read_head, cp, i);
 		tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
-		tty->read_cnt += i;
+		atomic_set(&tty->read_cnt, read_cnt + i);
 	} else {
 		for (i=count, p = cp, f = fp; i; i--, p++) {
 			if (f)
@@ -703,7 +707,7 @@
 			tty->driver.flush_chars(tty);
 	}
 
-	if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) {
+	if (!tty->icanon && (atomic_read(&tty->read_cnt) >= tty->minimum_to_wake)) {
 		if (tty->fasync)
 			kill_fasync(tty->fasync, SIGIO);
 		if (tty->read_wait)
@@ -828,7 +832,7 @@
 	if (tty->icanon) {
 		if (tty->canon_data)
 			return 1;
-	} else if (tty->read_cnt >= (amt ? amt : 1))
+	} else if (atomic_read(&tty->read_cnt) >= (amt ? amt : 1))
 		return 1;
 
 	return 0;
@@ -848,14 +852,16 @@
 
 {
 	ssize_t n;
+	int read_cnt = atomic_read(&tty->read_cnt);
 
-	n = MIN(*nr, MIN(tty->read_cnt, N_TTY_BUF_SIZE - tty->read_tail));
+	n = MIN(*nr, MIN(read_cnt, N_TTY_BUF_SIZE - tty->read_tail));
 	if (!n)
 		return;
 	/* N.B. copy_to_user may work only partially */
 	n -= copy_to_user(*b, &tty->read_buf[tty->read_tail], n);
 	tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1);
-	tty->read_cnt -= n;
+	/* tty->read_cnt may have changed while we slept. */
+	atomic_sub(n, &tty->read_cnt);
 	*b += n;
 	*nr -= n;
 }
@@ -973,7 +979,7 @@
 
 		if (tty->icanon) {
 			/* N.B. avoid overrun if nr == 0 */
-			while (nr && tty->read_cnt) {
+			while (nr && atomic_read(&tty->read_cnt)) {
  				int eol;
 
 				eol = test_and_clear_bit(tty->read_tail,
@@ -981,7 +987,7 @@
 				c = tty->read_buf[tty->read_tail];
 				tty->read_tail = ((tty->read_tail+1) &
 						  (N_TTY_BUF_SIZE-1));
-				tty->read_cnt--;
+				atomic_dec(&tty->read_cnt);
 
 				if (!eol || (c != __DISABLED_CHAR)) {
 					put_user(c, b++);
--- linux-2.1.105/drivers/char/tty_ioctl.c.~1~	Wed Mar 18 19:49:37 1998
+++ linux-2.1.105/drivers/char/tty_ioctl.c	Sun May 10 16:27:05 1998
@@ -120,7 +120,7 @@
 		tty->erasing = 0;
 	}
 	sti();
-	if (canon_change && !L_ICANON(tty) && tty->read_cnt)
+	if (canon_change && !L_ICANON(tty) && atomic_read(&tty->read_cnt))
 		/* Get characters left over from canonical mode. */
 		wake_up_interruptible(&tty->read_wait);
 
@@ -477,7 +477,7 @@
 					tty->driver.chars_in_buffer(tty) : 0,
 					(int *) arg);
 		case TIOCINQ:
-			retval = tty->read_cnt;
+			retval = atomic_read(&tty->read_cnt);
 			if (L_ICANON(tty))
 				retval = inq_canon(tty);
 			return put_user(retval, (unsigned int *) arg);
--- linux-2.1.105/drivers/scsi/scsi_proc.c.~1~	Mon Mar 23 18:26:14 1998
+++ linux-2.1.105/drivers/scsi/scsi_proc.c	Mon Feb 23 18:40:04 1998
@@ -184,9 +184,9 @@
     
     if (!buf || !cmdList)                           /* bad input ?     */
 	return(NULL);
-    if ((handle = (parseHandle*) kmalloc(sizeof(parseHandle), 1)) == 0)
+    if ((handle = (parseHandle*) kmalloc(sizeof(parseHandle), GFP_KERNEL)) == 0)
 	return(NULL);                               /* out of memory   */
-    if ((handle->cmdPos = (char**) kmalloc(sizeof(int), cmdNum)) == 0) {
+    if ((handle->cmdPos = (char**) kmalloc(sizeof(int) * cmdNum, GFP_KERNEL)) == 0) {
 	kfree(handle);
 	return(NULL);                               /* out of memory   */
     }
--- linux-2.1.105/drivers/sound/Makefile.~1~	Mon Jun  8 17:30:18 1998
+++ linux-2.1.105/drivers/sound/Makefile	Wed Jun 10 23:04:13 1998
@@ -41,7 +41,7 @@
 
 ifeq ($(ARCH),m68k)
 
-obj-$(CONFIG_DMASOUND)		+= dmasound.o
+obj-$(CONFIG_DMASOUND)		+= dmasound.o sound_core.o
 
 else
 
--- linux-2.1.105/drivers/sound/dmasound.c.~1~	Wed Jun 10 18:03:03 1998
+++ linux-2.1.105/drivers/sound/dmasound.c	Thu Jun 11 00:43:20 1998
@@ -73,6 +73,8 @@
 
 1996/9/25	++geert: modularization
 
+1998-06-10	++andreas: converted to use sound_core
+
 */
 
 
@@ -85,6 +87,7 @@
 #include <linux/errno.h>
 #include <linux/mm.h>
 #include <linux/malloc.h>
+#include <linux/sound.h>
 
 #ifdef __mc68000__
 #include <asm/setup.h>
@@ -121,8 +124,10 @@
 
 #define HAS_8BIT_TABLES
 
+static int sq_unit = -1;
+static int mixer_unit = -1;
+static int state_unit = -1;
 #ifdef MODULE
-static int chrdev_registered = 0;
 static int irq_installed = 0;
 #endif /* MODULE */
 static char **sound_buffers = NULL;
@@ -510,74 +515,105 @@
 
 
 #ifdef CONFIG_ATARI
-static long ata_ct_law(const u_char *userPtr, unsigned long userCount,
-		       u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ct_s8(const u_char *userPtr, unsigned long userCount,
-		      u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ct_u8(const u_char *userPtr, unsigned long userCount,
-		      u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ct_s16be(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ct_u16be(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ct_s16le(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ct_u16le(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ctx_law(const u_char *userPtr, unsigned long userCount,
-			u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ctx_s8(const u_char *userPtr, unsigned long userCount,
-		       u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ctx_u8(const u_char *userPtr, unsigned long userCount,
-		       u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ctx_s16be(const u_char *userPtr, unsigned long userCount,
-			  u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ctx_u16be(const u_char *userPtr, unsigned long userCount,
-			  u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ctx_s16le(const u_char *userPtr, unsigned long userCount,
-			  u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ctx_u16le(const u_char *userPtr, unsigned long userCount,
-			  u_char frame[], long *frameUsed, long frameLeft);
+static ssize_t ata_ct_law(const u_char *userPtr, size_t userCount,
+			  u_char frame[], ssize_t *frameUsed,
+			  ssize_t frameLeft);
+static ssize_t ata_ct_s8(const u_char *userPtr, size_t userCount,
+			 u_char frame[], ssize_t *frameUsed,
+			 ssize_t frameLeft);
+static ssize_t ata_ct_u8(const u_char *userPtr, size_t userCount,
+			 u_char frame[], ssize_t *frameUsed,
+			 ssize_t frameLeft);
+static ssize_t ata_ct_s16be(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft);
+static ssize_t ata_ct_u16be(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft);
+static ssize_t ata_ct_s16le(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft);
+static ssize_t ata_ct_u16le(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft);
+static ssize_t ata_ctx_law(const u_char *userPtr, size_t userCount,
+			   u_char frame[], ssize_t *frameUsed,
+			   ssize_t frameLeft);
+static ssize_t ata_ctx_s8(const u_char *userPtr, size_t userCount,
+			  u_char frame[], ssize_t *frameUsed,
+			  ssize_t frameLeft);
+static ssize_t ata_ctx_u8(const u_char *userPtr, size_t userCount,
+			  u_char frame[], ssize_t *frameUsed,
+			  ssize_t frameLeft);
+static ssize_t ata_ctx_s16be(const u_char *userPtr, size_t userCount,
+			     u_char frame[], ssize_t *frameUsed,
+			     ssize_t frameLeft);
+static ssize_t ata_ctx_u16be(const u_char *userPtr, size_t userCount,
+			     u_char frame[], ssize_t *frameUsed,
+			     ssize_t frameLeft);
+static ssize_t ata_ctx_s16le(const u_char *userPtr, size_t userCount,
+			     u_char frame[], ssize_t *frameUsed,
+			     ssize_t frameLeft);
+static ssize_t ata_ctx_u16le(const u_char *userPtr, size_t userCount,
+			     u_char frame[], ssize_t *frameUsed,
+			     ssize_t frameLeft);
 #endif /* CONFIG_ATARI */
 
 #ifdef CONFIG_AMIGA
-static long ami_ct_law(const u_char *userPtr, unsigned long userCount,
-		       u_char frame[], long *frameUsed, long frameLeft);
-static long ami_ct_s8(const u_char *userPtr, unsigned long userCount,
-		      u_char frame[], long *frameUsed, long frameLeft);
-static long ami_ct_u8(const u_char *userPtr, unsigned long userCount,
-		      u_char frame[], long *frameUsed, long frameLeft);
-static long ami_ct_s16be(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft);
-static long ami_ct_u16be(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft);
-static long ami_ct_s16le(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft);
-static long ami_ct_u16le(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft);
+static ssize_t ami_ct_law(const u_char *userPtr, size_t userCount,
+			  u_char frame[], ssize_t *frameUsed,
+			  ssize_t frameLeft);
+static ssize_t ami_ct_s8(const u_char *userPtr, size_t userCount,
+			 u_char frame[], ssize_t *frameUsed,
+			 ssize_t frameLeft);
+static ssize_t ami_ct_u8(const u_char *userPtr, size_t userCount,
+			 u_char frame[], ssize_t *frameUsed,
+			 ssize_t frameLeft);
+static ssize_t ami_ct_s16be(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft);
+static ssize_t ami_ct_u16be(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft);
+static ssize_t ami_ct_s16le(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft);
+static ssize_t ami_ct_u16le(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft);
 #endif /* CONFIG_AMIGA */
 
 #ifdef CONFIG_PMAC
-static long pmac_ct_law(const u_char *userPtr, unsigned long userCount,
-			u_char frame[], long *frameUsed, long frameLeft);
-static long pmac_ct_s8(const u_char *userPtr, unsigned long userCount,
-		       u_char frame[], long *frameUsed, long frameLeft);
-static long pmac_ct_u8(const u_char *userPtr, unsigned long userCount,
-		       u_char frame[], long *frameUsed, long frameLeft);
-static long pmac_ct_s16(const u_char *userPtr, unsigned long userCount,
-			u_char frame[], long *frameUsed, long frameLeft);
-static long pmac_ct_u16(const u_char *userPtr, unsigned long userCount,
-			u_char frame[], long *frameUsed, long frameLeft);
-static long pmac_ctx_law(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft);
-static long pmac_ctx_s8(const u_char *userPtr, unsigned long userCount,
-			u_char frame[], long *frameUsed, long frameLeft);
-static long pmac_ctx_u8(const u_char *userPtr, unsigned long userCount,
-			u_char frame[], long *frameUsed, long frameLeft);
-static long pmac_ctx_s16(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft);
-static long pmac_ctx_u16(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft);
+static ssize_t pmac_ct_law(const u_char *userPtr, size_t userCount,
+			   u_char frame[], ssize_t *frameUsed,
+			   ssize_t frameLeft);
+static ssize_t pmac_ct_s8(const u_char *userPtr, size_t userCount,
+			  u_char frame[], ssize_t *frameUsed,
+			  ssize_t frameLeft);
+static ssize_t pmac_ct_u8(const u_char *userPtr, size_t userCount,
+			  u_char frame[], ssize_t *frameUsed,
+			  ssize_t frameLeft);
+static ssize_t pmac_ct_s16(const u_char *userPtr, size_t userCount,
+			   u_char frame[], ssize_t *frameUsed,
+			   ssize_t frameLeft);
+static ssize_t pmac_ct_u16(const u_char *userPtr, size_t userCount,
+			   u_char frame[], ssize_t *frameUsed,
+			   ssize_t frameLeft);
+static ssize_t pmac_ctx_law(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft);
+static ssize_t pmac_ctx_s8(const u_char *userPtr, size_t userCount,
+			   u_char frame[], ssize_t *frameUsed,
+			   ssize_t frameLeft);
+static ssize_t pmac_ctx_u8(const u_char *userPtr, size_t userCount,
+			   u_char frame[], ssize_t *frameUsed,
+			   ssize_t frameLeft);
+static ssize_t pmac_ctx_s16(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft);
+static ssize_t pmac_ctx_u16(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft);
 #endif /* CONFIG_PMAC */
 
 /*** Machine definitions *****************************************************/
@@ -613,14 +649,14 @@
 } SETTINGS;
 
 typedef struct {
-	long (*ct_ulaw)(const u_char *, unsigned long, u_char *, long *, long);
-	long (*ct_alaw)(const u_char *, unsigned long, u_char *, long *, long);
-	long (*ct_s8)(const u_char *, unsigned long, u_char *, long *, long);
-	long (*ct_u8)(const u_char *, unsigned long, u_char *, long *, long);
-	long (*ct_s16be)(const u_char *, unsigned long, u_char *, long *, long);
-	long (*ct_u16be)(const u_char *, unsigned long, u_char *, long *, long);
-	long (*ct_s16le)(const u_char *, unsigned long, u_char *, long *, long);
-	long (*ct_u16le)(const u_char *, unsigned long, u_char *, long *, long);
+	ssize_t (*ct_ulaw)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
+	ssize_t (*ct_alaw)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
+	ssize_t (*ct_s8)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
+	ssize_t (*ct_u8)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
+	ssize_t (*ct_s16be)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
+	ssize_t (*ct_u16be)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
+	ssize_t (*ct_s16le)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
+	ssize_t (*ct_u16le)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
 } TRANS;
 
 struct sound_settings {
@@ -720,10 +756,10 @@
 #if defined(CONFIG_ATARI) || defined(CONFIG_AMIGA)
 static int sound_set_treble(int treble);
 #endif /* CONFIG_ATARI || CONFIG_AMIGA */
-static long sound_copy_translate(const u_char *userPtr,
-				 unsigned long userCount,
-				 u_char frame[], long *frameUsed,
-				 long frameLeft);
+static ssize_t sound_copy_translate(const u_char *userPtr,
+				    size_t userCount,
+				    u_char frame[], ssize_t *frameUsed,
+				    ssize_t frameLeft);
 
 
 /*
@@ -736,13 +772,6 @@
 
 static struct sound_mixer mixer;
 
-static void mixer_init(void);
-static int mixer_open(int open_mode);
-static int mixer_release(void);
-static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
-		       u_long arg);
-
-
 /*
  * Sound queue stuff, the heart of the driver
  */
@@ -787,16 +816,6 @@
 	interruptible_sleep_on(&queue);
 #define WAKE_UP(queue)	(wake_up_interruptible(&queue))
 
-static void sq_init(int numBufs, int bufSize, char **buffers);
-static void sq_play(void);
-static long sq_write(const char *src, unsigned long uLeft);
-static int sq_open(int open_mode);
-static void sq_reset(void);
-static int sq_sync(void);
-static int sq_release(void);
-static void init_settings(void);
-
-
 /*
  * /dev/sndstat
  */
@@ -809,23 +828,9 @@
 
 static struct sound_state state;
 
-static void state_init(void);
-static int state_open(int open_mode);
-static int state_release(void);
-static long state_read(char *dest, unsigned long count);
+/*** Common stuff ********************************************************/
 
-
-/*** High level stuff ********************************************************/
-
-
-static int sound_open(struct inode *inode, struct file *file);
-static int sound_fsync(struct file *filp, struct dentry *dentry);
-static int sound_release(struct inode *inode, struct file *file);
 static long long sound_lseek(struct file *file, long long offset, int orig);
-static ssize_t sound_read(struct file *file, char *buf, size_t count,
-			  loff_t *ppos);
-static ssize_t sound_write(struct file *file, const char *buf, size_t count,
-			   loff_t *ppos);
 static inline int ioctl_return(int *addr, int value)
 {
 	if (value < 0)
@@ -833,15 +838,12 @@
 
 	return put_user(value, addr)? -EFAULT: 0;
 }
-static int unknown_minor_dev(char *fname, int dev);
-static int sound_ioctl(struct inode *inode, struct file *file, u_int cmd,
-		       u_long arg);
 
 
 /*** Config & Setup **********************************************************/
 
 
-void soundcard_init(void);
+void dmasound_init(void);
 void dmasound_setup(char *str, int *ints);
 void sound_setup(char *str, int *ints);		/* ++Martin: stub for now */
 
@@ -874,11 +876,12 @@
  */
 
 #ifdef CONFIG_ATARI
-static long ata_ct_law(const u_char *userPtr, unsigned long userCount,
-		       u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ata_ct_law(const u_char *userPtr, size_t userCount,
+			  u_char frame[], ssize_t *frameUsed,
+			  ssize_t frameLeft)
 {
 	char *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma8 : alaw2dma8;
-	long count, used;
+	ssize_t count, used;
 	u_char *p = &frame[*frameUsed];
 
 	count = min(userCount, frameLeft);
@@ -893,14 +896,15 @@
 		count--;
 	}
 	*frameUsed += used;
-	return(used);
+	return used;
 }
 
 
-static long ata_ct_s8(const u_char *userPtr, unsigned long userCount,
-		      u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ata_ct_s8(const u_char *userPtr, size_t userCount,
+			 u_char frame[], ssize_t *frameUsed,
+			 ssize_t frameLeft)
 {
-	long count, used;
+	ssize_t count, used;
 	void *p = &frame[*frameUsed];
 
 	count = min(userCount, frameLeft);
@@ -914,10 +918,11 @@
 }
 
 
-static long ata_ct_u8(const u_char *userPtr, unsigned long userCount,
-		      u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ata_ct_u8(const u_char *userPtr, size_t userCount,
+			 u_char frame[], ssize_t *frameUsed,
+			 ssize_t frameLeft)
 {
-	long count, used;
+	ssize_t count, used;
 
 	if (!sound.soft.stereo) {
 		u_char *p = &frame[*frameUsed];
@@ -947,10 +952,11 @@
 }
 
 
-static long ata_ct_s16be(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ata_ct_s16be(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft)
 {
-	long count, used;
+	ssize_t count, used;
 	u_long data;
 
 	if (!sound.soft.stereo) {
@@ -977,10 +983,11 @@
 }
 
 
-static long ata_ct_u16be(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ata_ct_u16be(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft)
 {
-	long count, used;
+	ssize_t count, used;
 	u_long data;
 
 	if (!sound.soft.stereo) {
@@ -1012,10 +1019,11 @@
 }
 
 
-static long ata_ct_s16le(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ata_ct_s16le(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft)
 {
-	long count, used;
+	ssize_t count, used;
 	u_long data;
 
 	count = frameLeft;
@@ -1049,10 +1057,11 @@
 }
 
 
-static long ata_ct_u16le(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ata_ct_u16le(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft)
 {
-	long count, used;
+	ssize_t count, used;
 	u_long data;
 
 	count = frameLeft;
@@ -1085,15 +1094,16 @@
 }
 
 
-static long ata_ctx_law(const u_char *userPtr, unsigned long userCount,
-			u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ata_ctx_law(const u_char *userPtr, size_t userCount,
+			   u_char frame[], ssize_t *frameUsed,
+			   ssize_t frameLeft)
 {
 	char *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma8 : alaw2dma8;
 	/* this should help gcc to stuff everything into registers */
 	u_long data = sound.data;
 	long bal = sound.bal;
 	long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
-	long used, usedf;
+	ssize_t used, usedf;
 
 	used = userCount;
 	usedf = frameLeft;
@@ -1143,14 +1153,15 @@
 }
 
 
-static long ata_ctx_s8(const u_char *userPtr, unsigned long userCount,
-		       u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ata_ctx_s8(const u_char *userPtr, size_t userCount,
+			  u_char frame[], ssize_t *frameUsed,
+			  ssize_t frameLeft)
 {
 	/* this should help gcc to stuff everything into registers */
 	u_long data = sound.data;
 	long bal = sound.bal;
 	long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
-	long used, usedf;
+	ssize_t used, usedf;
 
 	used = userCount;
 	usedf = frameLeft;
@@ -1193,14 +1204,15 @@
 }
 
 
-static long ata_ctx_u8(const u_char *userPtr, unsigned long userCount,
-		       u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ata_ctx_u8(const u_char *userPtr, size_t userCount,
+			  u_char frame[], ssize_t *frameUsed,
+			  ssize_t frameLeft)
 {
 	/* this should help gcc to stuff everything into registers */
 	u_long data = sound.data;
 	long bal = sound.bal;
 	long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
-	long used, usedf;
+	ssize_t used, usedf;
 
 	used = userCount;
 	usedf = frameLeft;
@@ -1245,14 +1257,15 @@
 }
 
 
-static long ata_ctx_s16be(const u_char *userPtr, unsigned long userCount,
-			  u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ata_ctx_s16be(const u_char *userPtr, size_t userCount,
+			     u_char frame[], ssize_t *frameUsed,
+			     ssize_t frameLeft)
 {
 	/* this should help gcc to stuff everything into registers */
 	u_long data = sound.data;
 	long bal = sound.bal;
 	long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
-	long used, usedf;
+	ssize_t used, usedf;
 
 	used = userCount;
 	usedf = frameLeft;
@@ -1296,14 +1309,15 @@
 }
 
 
-static long ata_ctx_u16be(const u_char *userPtr, unsigned long userCount,
-			  u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ata_ctx_u16be(const u_char *userPtr, size_t userCount,
+			     u_char frame[], ssize_t *frameUsed,
+			     ssize_t frameLeft)
 {
 	/* this should help gcc to stuff everything into registers */
 	u_long data = sound.data;
 	long bal = sound.bal;
 	long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
-	long used, usedf;
+	ssize_t used, usedf;
 
 	used = userCount;
 	usedf = frameLeft;
@@ -1349,14 +1363,15 @@
 }
 
 
-static long ata_ctx_s16le(const u_char *userPtr, unsigned long userCount,
-			  u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ata_ctx_s16le(const u_char *userPtr, size_t userCount,
+			     u_char frame[], ssize_t *frameUsed,
+			     ssize_t frameLeft)
 {
 	/* this should help gcc to stuff everything into registers */
 	u_long data = sound.data;
 	long bal = sound.bal;
 	long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
-	long used, usedf;
+	ssize_t used, usedf;
 
 	used = userCount;
 	usedf = frameLeft;
@@ -1402,14 +1417,15 @@
 }
 
 
-static long ata_ctx_u16le(const u_char *userPtr, unsigned long userCount,
-			  u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ata_ctx_u16le(const u_char *userPtr, size_t userCount,
+			     u_char frame[], ssize_t *frameUsed,
+			     ssize_t frameLeft)
 {
 	/* this should help gcc to stuff everything into registers */
 	u_long data = sound.data;
 	long bal = sound.bal;
 	long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
-	long used, usedf;
+	ssize_t used, usedf;
 
 	used = userCount;
 	usedf = frameLeft;
@@ -1457,11 +1473,12 @@
 
 
 #ifdef CONFIG_AMIGA
-static long ami_ct_law(const u_char *userPtr, unsigned long userCount,
-		       u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ami_ct_law(const u_char *userPtr, size_t userCount,
+			  u_char frame[], ssize_t *frameUsed,
+			  ssize_t frameLeft)
 {
 	char *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma8 : alaw2dma8;
-	long count, used;
+	ssize_t count, used;
 
 	if (!sound.soft.stereo) {
 		u_char *p = &frame[*frameUsed];
@@ -1495,10 +1512,10 @@
 }
 
 
-static long ami_ct_s8(const u_char *userPtr, unsigned long userCount,
-		      u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ami_ct_s8(const u_char *userPtr, size_t userCount,
+			 u_char frame[], ssize_t *frameUsed, ssize_t frameLeft)
 {
-	long count, used;
+	ssize_t count, used;
 
 	if (!sound.soft.stereo) {
 		void *p = &frame[*frameUsed];
@@ -1523,10 +1540,10 @@
 }
 
 
-static long ami_ct_u8(const u_char *userPtr, unsigned long userCount,
-		      u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ami_ct_u8(const u_char *userPtr, size_t userCount,
+			 u_char frame[], ssize_t *frameUsed, ssize_t frameLeft)
 {
-	long count, used;
+	ssize_t count, used;
 
 	if (!sound.soft.stereo) {
 		char *p = &frame[*frameUsed];
@@ -1560,10 +1577,11 @@
 }
 
 
-static long ami_ct_s16be(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ami_ct_s16be(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft)
 {
-	long count, used;
+	ssize_t count, used;
 	u_long data;
 
 	if (!sound.soft.stereo) {
@@ -1602,10 +1620,11 @@
 }
 
 
-static long ami_ct_u16be(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ami_ct_u16be(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft)
 {
-	long count, used;
+	ssize_t count, used;
 	u_long data;
 
 	if (!sound.soft.stereo) {
@@ -1647,10 +1666,11 @@
 }
 
 
-static long ami_ct_s16le(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ami_ct_s16le(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft)
 {
-	long count, used;
+	ssize_t count, used;
 	u_long data;
 
 	if (!sound.soft.stereo) {
@@ -1692,10 +1712,11 @@
 }
 
 
-static long ami_ct_u16le(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t ami_ct_u16le(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft)
 {
-	long count, used;
+	ssize_t count, used;
 	u_long data;
 
 	if (!sound.soft.stereo) {
@@ -1738,11 +1759,12 @@
 #endif /* CONFIG_AMIGA */
 
 #ifdef CONFIG_PMAC
-static long pmac_ct_law(const u_char *userPtr, unsigned long userCount,
-			u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t pmac_ct_law(const u_char *userPtr, size_t userCount,
+			   u_char frame[], ssize_t *frameUsed,
+			   ssize_t frameLeft)
 {
 	short *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma16: alaw2dma16;
-	long count, used;
+	ssize_t count, used;
 	short *p = (short *) &frame[*frameUsed];
 	int val, stereo = sound.soft.stereo;
 
@@ -1769,10 +1791,11 @@
 }
 
 
-static long pmac_ct_s8(const u_char *userPtr, unsigned long userCount,
-		       u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t pmac_ct_s8(const u_char *userPtr, size_t userCount,
+			  u_char frame[], ssize_t *frameUsed,
+			  ssize_t frameLeft)
 {
-	long count, used;
+	ssize_t count, used;
 	short *p = (short *) &frame[*frameUsed];
 	int val, stereo = sound.soft.stereo;
 
@@ -1799,10 +1822,11 @@
 }
 
 
-static long pmac_ct_u8(const u_char *userPtr, unsigned long userCount,
-		       u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t pmac_ct_u8(const u_char *userPtr, size_t userCount,
+			  u_char frame[], ssize_t *frameUsed,
+			  ssize_t frameLeft)
 {
-	long count, used;
+	ssize_t count, used;
 	short *p = (short *) &frame[*frameUsed];
 	int val, stereo = sound.soft.stereo;
 
@@ -1829,10 +1853,11 @@
 }
 
 
-static long pmac_ct_s16(const u_char *userPtr, unsigned long userCount,
-			u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t pmac_ct_s16(const u_char *userPtr, size_t userCount,
+			   u_char frame[], ssize_t *frameUsed,
+			   ssize_t frameLeft)
 {
-	long count, used;
+	ssize_t count, used;
 	int stereo = sound.soft.stereo;
 	short *fp = (short *) &frame[*frameUsed];
 
@@ -1857,10 +1882,11 @@
 	return stereo? used * 4: used * 2;
 }
 
-static long pmac_ct_u16(const u_char *userPtr, unsigned long userCount,
-			u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t pmac_ct_u16(const u_char *userPtr, size_t userCount,
+			   u_char frame[], ssize_t *frameUsed,
+			   ssize_t frameLeft)
 {
-	long count, used;
+	ssize_t count, used;
 	int mask = (sound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
 	int stereo = sound.soft.stereo;
 	short *fp = (short *) &frame[*frameUsed];
@@ -1888,8 +1914,9 @@
 }
 
 
-static long pmac_ctx_law(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t pmac_ctx_law(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft)
 {
 	unsigned short *table = (unsigned short *)
 		(sound.soft.format == AFMT_MU_LAW ? ulaw2dma16: alaw2dma16);
@@ -1934,8 +1961,9 @@
 }
 
 
-static long pmac_ctx_s8(const u_char *userPtr, unsigned long userCount,
-			u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t pmac_ctx_s8(const u_char *userPtr, size_t userCount,
+			   u_char frame[], ssize_t *frameUsed,
+			   ssize_t frameLeft)
 {
 	unsigned int *p = (unsigned int *) &frame[*frameUsed];
 	unsigned int data = sound.data;
@@ -1978,8 +2006,9 @@
 }
 
 
-static long pmac_ctx_u8(const u_char *userPtr, unsigned long userCount,
-			u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t pmac_ctx_u8(const u_char *userPtr, size_t userCount,
+			   u_char frame[], ssize_t *frameUsed,
+			   ssize_t frameLeft)
 {
 	unsigned int *p = (unsigned int *) &frame[*frameUsed];
 	unsigned int data = sound.data;
@@ -2022,8 +2051,9 @@
 }
 
 
-static long pmac_ctx_s16(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t pmac_ctx_s16(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft)
 {
 	unsigned int *p = (unsigned int *) &frame[*frameUsed];
 	unsigned int data = sound.data;
@@ -2066,8 +2096,9 @@
 }
 
 
-static long pmac_ctx_u16(const u_char *userPtr, unsigned long userCount,
-			 u_char frame[], long *frameUsed, long frameLeft)
+static ssize_t pmac_ctx_u16(const u_char *userPtr, size_t userCount,
+			    u_char frame[], ssize_t *frameUsed,
+			    ssize_t frameLeft)
 {
 	int mask = (sound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
 	unsigned int *p = (unsigned int *) &frame[*frameUsed];
@@ -3425,12 +3456,12 @@
 #endif /* CONFIG_ATARI || CONFIG_AMIGA */
 
 
-static long sound_copy_translate(const u_char *userPtr,
-				 unsigned long userCount,
-				 u_char frame[], long *frameUsed,
-				 long frameLeft)
+static ssize_t sound_copy_translate(const u_char *userPtr,
+				    size_t userCount,
+				    u_char frame[], ssize_t *frameUsed,
+				    ssize_t frameLeft)
 {
-	long (*ct_func)(const u_char *, unsigned long, u_char *, long *, long) = NULL;
+	ssize_t (*ct_func)(const u_char *, size_t, u_char *, ssize_t *, ssize_t) = NULL;
 
 	switch (sound.soft.format) {
 	case AFMT_MU_LAW:
@@ -3459,9 +3490,9 @@
 		break;
 	}
 	if (ct_func)
-		return(ct_func(userPtr, userCount, frame, frameUsed, frameLeft));
+		return ct_func(userPtr, userCount, frame, frameUsed, frameLeft);
 	else
-		return(0);
+		return 0;
 }
 
 
@@ -3475,53 +3506,19 @@
 #define RECLEVEL_GAIN_TO_VOXWARE(v) (((v) * 20 + 2) / 3)
 
 
-static void mixer_init(void)
-{
-	mixer.busy = 0;
-	sound.treble = 0;
-	sound.bass = 0;
-	switch (sound.mach.type) {
-#ifdef CONFIG_ATARI
-	case DMASND_TT:
-		atari_microwire_cmd(MW_LM1992_VOLUME(0));
-		sound.volume_left = 0;
-		atari_microwire_cmd(MW_LM1992_BALLEFT(0));
-		sound.volume_right = 0;
-		atari_microwire_cmd(MW_LM1992_BALRIGHT(0));
-		atari_microwire_cmd(MW_LM1992_TREBLE(0));
-		atari_microwire_cmd(MW_LM1992_BASS(0));
-		break;
-	case DMASND_FALCON:
-		sound.volume_left = (tt_dmasnd.output_atten & 0xf00) >> 8;
-		sound.volume_right = (tt_dmasnd.output_atten & 0xf0) >> 4;
-		break;
-#endif /* CONFIG_ATARI */
-#ifdef CONFIG_AMIGA
-	case DMASND_AMIGA:
-		sound.volume_left = 64;
-		sound.volume_right = 64;
-		custom.aud[0].audvol = sound.volume_left;
-		custom.aud[3].audvol = 1;	/* For pseudo 14bit */
-		custom.aud[1].audvol = sound.volume_right;
-		custom.aud[2].audvol = 1;	/* For pseudo 14bit */
-		sound.treble = 50;
-		break;
-#endif /* CONFIG_AMIGA */
-	}
-}
-
-
-static int mixer_open(int open_mode)
+static int mixer_open(struct inode *inode, struct file *file)
 {
+	MOD_INC_USE_COUNT;
 	mixer.busy = 1;
-	return(0);
+	return 0;
 }
 
 
-static int mixer_release(void)
+static int mixer_release(struct inode *inode, struct file *file)
 {
 	mixer.busy = 0;
-	return(0);
+	MOD_DEC_USE_COUNT;
+	return 0;
 }
 
 
@@ -3534,17 +3531,17 @@
 	case DMASND_FALCON:
 		switch (cmd) {
 		case SOUND_MIXER_READ_DEVMASK:
-			return(IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC | SOUND_MASK_SPEAKER));
+			return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC | SOUND_MASK_SPEAKER);
 		case SOUND_MIXER_READ_RECMASK:
-			return(IOCTL_OUT(arg, SOUND_MASK_MIC));
+			return IOCTL_OUT(arg, SOUND_MASK_MIC);
 		case SOUND_MIXER_READ_STEREODEVS:
-			return(IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC));
+			return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC);
 		case SOUND_MIXER_READ_CAPS:
-			return(IOCTL_OUT(arg, SOUND_CAP_EXCL_INPUT));
+			return IOCTL_OUT(arg, SOUND_CAP_EXCL_INPUT);
 		case SOUND_MIXER_READ_VOLUME:
-			return(IOCTL_OUT(arg,
+			return IOCTL_OUT(arg,
 				VOLUME_ATT_TO_VOXWARE(sound.volume_left) |
-				VOLUME_ATT_TO_VOXWARE(sound.volume_right) << 8));
+				VOLUME_ATT_TO_VOXWARE(sound.volume_right) << 8);
 		case SOUND_MIXER_WRITE_MIC:
 			IOCTL_IN(arg, data);
 			tt_dmasnd.input_gain =
@@ -3552,9 +3549,9 @@
 				RECLEVEL_VOXWARE_TO_GAIN(data >> 8 & 0xff);
 			/* fall thru, return set value */
 		case SOUND_MIXER_READ_MIC:
-			return(IOCTL_OUT(arg,
+			return IOCTL_OUT(arg,
 				RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain >> 4 & 0xf) |
-				RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain & 0xf) << 8));
+				RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain & 0xf) << 8);
 		case SOUND_MIXER_READ_SPEAKER:
 			{
 				int porta;
@@ -3562,11 +3559,11 @@
 				sound_ym.rd_data_reg_sel = 14;
 				porta = sound_ym.rd_data_reg_sel;
 				sti();
-				return(IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
+				return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
 			}
 		case SOUND_MIXER_WRITE_VOLUME:
 			IOCTL_IN(arg, data);
-			return(IOCTL_OUT(arg, sound_set_volume(data)));
+			return IOCTL_OUT(arg, sound_set_volume(data));
 		case SOUND_MIXER_WRITE_SPEAKER:
 			{
 				int porta;
@@ -3577,7 +3574,7 @@
 					(data < 50 ? 0x40 : 0);
 				sound_ym.wd_data = porta;
 				sti();
-				return(IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
+				return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
 			}
 		}
 		break;
@@ -3585,23 +3582,23 @@
 	case DMASND_TT:
 		switch (cmd) {
 		case SOUND_MIXER_READ_DEVMASK:
-			return(IOCTL_OUT(arg,
+			return IOCTL_OUT(arg,
 					 SOUND_MASK_VOLUME | SOUND_MASK_TREBLE | SOUND_MASK_BASS |
-					 (MACH_IS_TT ? SOUND_MASK_SPEAKER : 0)));
+					 (MACH_IS_TT ? SOUND_MASK_SPEAKER : 0));
 		case SOUND_MIXER_READ_RECMASK:
-			return(IOCTL_OUT(arg, 0));
+			return IOCTL_OUT(arg, 0);
 		case SOUND_MIXER_READ_STEREODEVS:
-			return(IOCTL_OUT(arg, SOUND_MASK_VOLUME));
+			return IOCTL_OUT(arg, SOUND_MASK_VOLUME);
 		case SOUND_MIXER_READ_VOLUME:
-			return(IOCTL_OUT(arg,
+			return IOCTL_OUT(arg,
 					 VOLUME_DB_TO_VOXWARE(sound.volume_left) |
-					 (VOLUME_DB_TO_VOXWARE(sound.volume_right) << 8)));
+					 (VOLUME_DB_TO_VOXWARE(sound.volume_right) << 8));
 		case SOUND_MIXER_READ_BASS:
-			return(IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(sound.bass)));
+			return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(sound.bass));
 		case SOUND_MIXER_READ_TREBLE:
-			return(IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(sound.treble)));
+			return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(sound.treble));
 		case SOUND_MIXER_READ_OGAIN:
-			return(IOCTL_OUT(arg, GAIN_DB_TO_VOXWARE(sound.gain)));
+			return IOCTL_OUT(arg, GAIN_DB_TO_VOXWARE(sound.gain));
 		case SOUND_MIXER_READ_SPEAKER:
 			{
 				int porta;
@@ -3610,22 +3607,22 @@
 					sound_ym.rd_data_reg_sel = 14;
 					porta = sound_ym.rd_data_reg_sel;
 					sti();
-					return(IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
-				} else
-					return(-EINVAL);
+					return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
+				}
 			}
+			break;
 		case SOUND_MIXER_WRITE_VOLUME:
 			IOCTL_IN(arg, data);
-			return(IOCTL_OUT(arg, sound_set_volume(data)));
+			return IOCTL_OUT(arg, sound_set_volume(data));
 		case SOUND_MIXER_WRITE_BASS:
 			IOCTL_IN(arg, data);
-			return(IOCTL_OUT(arg, sound_set_bass(data)));
+			return IOCTL_OUT(arg, sound_set_bass(data));
 		case SOUND_MIXER_WRITE_TREBLE:
 			IOCTL_IN(arg, data);
-			return(IOCTL_OUT(arg, sound_set_treble(data)));
+			return IOCTL_OUT(arg, sound_set_treble(data));
 		case SOUND_MIXER_WRITE_OGAIN:
 			IOCTL_IN(arg, data);
-			return(IOCTL_OUT(arg, sound_set_gain(data)));
+			return IOCTL_OUT(arg, sound_set_gain(data));
 		case SOUND_MIXER_WRITE_SPEAKER:
 			if (MACH_IS_TT) {
 				int porta;
@@ -3636,9 +3633,8 @@
 					(data < 50 ? 0x40 : 0);
 				sound_ym.wd_data = porta;
 				sti();
-				return(IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
-			} else
-				return(-EINVAL);
+				return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
+			}
 		}
 		break;
 #endif /* CONFIG_ATARI */
@@ -3647,23 +3643,23 @@
 	case DMASND_AMIGA:
 		switch (cmd) {
 		case SOUND_MIXER_READ_DEVMASK:
-			return(IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_TREBLE));
+			return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_TREBLE);
 		case SOUND_MIXER_READ_RECMASK:
-			return(IOCTL_OUT(arg, 0));
+			return IOCTL_OUT(arg, 0);
 		case SOUND_MIXER_READ_STEREODEVS:
-			return(IOCTL_OUT(arg, SOUND_MASK_VOLUME));
+			return IOCTL_OUT(arg, SOUND_MASK_VOLUME);
 		case SOUND_MIXER_READ_VOLUME:
-			return(IOCTL_OUT(arg,
+			return IOCTL_OUT(arg,
 				VOLUME_AMI_TO_VOXWARE(sound.volume_left) |
-				VOLUME_AMI_TO_VOXWARE(sound.volume_right) << 8));
+				VOLUME_AMI_TO_VOXWARE(sound.volume_right) << 8);
 		case SOUND_MIXER_WRITE_VOLUME:
 			IOCTL_IN(arg, data);
-			return(IOCTL_OUT(arg, sound_set_volume(data)));
+			return IOCTL_OUT(arg, sound_set_volume(data));
 		case SOUND_MIXER_READ_TREBLE:
-			return(IOCTL_OUT(arg, sound.treble));
+			return IOCTL_OUT(arg, sound.treble);
 		case SOUND_MIXER_WRITE_TREBLE:
 			IOCTL_IN(arg, data);
-			return(IOCTL_OUT(arg, sound_set_treble(data)));
+			return IOCTL_OUT(arg, sound_set_treble(data));
 		}
 		break;
 #endif /* CONFIG_AMIGA */
@@ -3778,17 +3774,70 @@
 #endif
 	}
 
-	return(-EINVAL);
+	return -EINVAL;
 }
 
 
+static struct file_operations mixer_fops =
+{
+	sound_lseek,
+	NULL,			/* mixer_read */
+	NULL,			/* mixer_write */
+	NULL,			/* mixer_readdir */
+	NULL,			/* mixer_poll */
+	mixer_ioctl,
+	NULL,			/* mixer_mmap */
+	mixer_open,
+	mixer_release,
+};
+
+
+static void mixer_init(void)
+{
+	mixer_unit = register_sound_mixer(&mixer_fops);
+	if (mixer_unit < 0)
+		return;
+
+	mixer.busy = 0;
+	sound.treble = 0;
+	sound.bass = 0;
+	switch (sound.mach.type) {
+#ifdef CONFIG_ATARI
+	case DMASND_TT:
+		atari_microwire_cmd(MW_LM1992_VOLUME(0));
+		sound.volume_left = 0;
+		atari_microwire_cmd(MW_LM1992_BALLEFT(0));
+		sound.volume_right = 0;
+		atari_microwire_cmd(MW_LM1992_BALRIGHT(0));
+		atari_microwire_cmd(MW_LM1992_TREBLE(0));
+		atari_microwire_cmd(MW_LM1992_BASS(0));
+		break;
+	case DMASND_FALCON:
+		sound.volume_left = (tt_dmasnd.output_atten & 0xf00) >> 8;
+		sound.volume_right = (tt_dmasnd.output_atten & 0xf0) >> 4;
+		break;
+#endif /* CONFIG_ATARI */
+#ifdef CONFIG_AMIGA
+	case DMASND_AMIGA:
+		sound.volume_left = 64;
+		sound.volume_right = 64;
+		custom.aud[0].audvol = sound.volume_left;
+		custom.aud[3].audvol = 1;	/* For pseudo 14bit */
+		custom.aud[1].audvol = sound.volume_right;
+		custom.aud[2].audvol = 1;	/* For pseudo 14bit */
+		sound.treble = 50;
+		break;
+#endif /* CONFIG_AMIGA */
+	}
+}
+
 
 /*
  * Sound queue stuff, the heart of the driver
  */
 
 
-static void sq_init(int numBufs, int bufSize, char **buffers)
+static void sq_setup(int numBufs, int bufSize, char **buffers)
 {
 #ifdef CONFIG_PMAC
 	int i;
@@ -3828,47 +3877,6 @@
 #endif /* CONFIG_PMAC */
 }
 
-static void
-init_settings(void)
-{
-	/* whatever you like as startup mode for /dev/dsp,
-	 * (/dev/audio hasn't got a startup mode). note that
-	 * once changed a new open() will *not* restore these!
-	 */
-	sound.dsp.format = AFMT_U8;
-	sound.dsp.stereo = 0;
-	sound.dsp.size = 8;
-
-	/* set minimum rate possible without expanding */
-	switch (sound.mach.type) {
-#ifdef CONFIG_ATARI
-	case DMASND_TT:
-		sound.dsp.speed = 6258;
-		break;
-	case DMASND_FALCON:
-		sound.dsp.speed = 8195;
-		break;
-#endif /* CONFIG_ATARI */
-#ifdef CONFIG_AMIGA
-	case DMASND_AMIGA:
-		sound.dsp.speed = 8000;
-		break;
-#endif /* CONFIG_AMIGA */
-#ifdef CONFIG_PMAC
-	case DMASND_AWACS:
-		sound.dsp.speed = 8000;
-		break;
-#endif /* CONFIG_PMAC */
-	}
-
-	/* before the first open to /dev/dsp this wouldn't be set */
-	sound.soft = sound.dsp;
-	sound.hard = sound.dsp;
-
-	sound_silence();
-}
-
-
 static void sq_play(void)
 {
 	(*sound.mach.play)();
@@ -3877,18 +3885,19 @@
 
 /* ++TeSche: radically changed this one too */
 
-static long sq_write(const char *src, unsigned long uLeft)
+static ssize_t sq_write(struct file *file, const char *src, size_t uLeft,
+			loff_t *ppos)
 {
-	long uWritten = 0;
+	ssize_t uWritten = 0;
 	u_char *dest;
-	long uUsed, bUsed, bLeft;
+	ssize_t uUsed, bUsed, bLeft;
 
 	/* ++TeSche: Is something like this necessary?
 	 * Hey, that's an honest question! Or does any other part of the
 	 * filesystem already checks this situation? I really don't know.
 	 */
 	if (uLeft == 0)
-		return(0);
+		return 0;
 
 	/* The interrupt doesn't start to play the last, incomplete frame.
 	 * Thus we can append to it without disabling the interrupts! (Note
@@ -3911,10 +3920,10 @@
 		while (sq.count == sq.max_active) {
 			sq_play();
 			if (NON_BLOCKING(sq.open_mode))
-				return(uWritten > 0 ? uWritten : -EAGAIN);
+				return uWritten > 0 ? uWritten : -EAGAIN;
 			SLEEP(sq.write_queue, ONE_SECOND);
 			if (SIGNAL_RECEIVED)
-				return(uWritten > 0 ? uWritten : -EINTR);
+				return uWritten > 0 ? uWritten : -EINTR;
 		}
 
 		/* Here, we can avoid disabling the interrupt by first
@@ -3942,28 +3951,46 @@
 
 	sq_play();
 
-	return(uUsed < 0? uUsed: uWritten);
+	return uUsed < 0? uUsed: uWritten;
 }
 
 
-static int sq_open(int open_mode)
+static int sq_open(struct inode *inode, struct file *file)
 {
+	int rc = 0;
+
+	MOD_INC_USE_COUNT;
 	if (sq.busy) {
-		if (NON_BLOCKING(open_mode))
-			return(-EBUSY);
+		rc = -EBUSY;
+		if (NON_BLOCKING(file->f_flags))
+			goto err_out;
+		rc = -EINTR;
 		while (sq.busy) {
 			SLEEP(sq.open_queue, ONE_SECOND);
 			if (SIGNAL_RECEIVED)
-				return(-EINTR);
+				goto err_out;
 		}
+		rc = 0;
 	}
-	sq_init(numBufs, bufSize << 10, sound_buffers);
-	sq.open_mode = open_mode;
+	sq_setup(numBufs, bufSize << 10, sound_buffers);
+	sq.open_mode = file->f_flags;
 	sq.busy = 1;
 #ifdef CONFIG_ATARI
 	sq.ignore_int = 1;
 #endif /* CONFIG_ATARI */
-	return(0);
+	sound.minDev = MINOR(inode->i_rdev) & 0x0f;
+	sound.soft = sound.dsp;
+	sound.hard = sound.dsp;
+	sound_init();
+	if ((MINOR(inode->i_rdev) & 0x0f) == SND_DEV_AUDIO) {
+		sound_set_speed(8000);
+		sound_set_stereo(0);
+		sound_set_format(AFMT_MU_LAW);
+	}
+	return 0;
+err_out:
+	MOD_DEC_USE_COUNT;
+	return rc;
 }
 
 
@@ -3976,7 +4003,7 @@
 }
 
 
-static int sq_sync(void)
+static int sq_fsync(struct file *filp, struct dentry *dentry)
 {
 	int rc = 0;
 
@@ -3996,47 +4023,192 @@
 	}
 
 	sq.syncing = 0;
-	return(rc);
+	return rc;
 }
 
-
-static int sq_release(void)
+static int sq_release(struct inode *inode, struct file *file)
 {
 	int rc = 0;
 	if (sq.busy) {
-		rc = sq_sync();
+		rc = sq_fsync(file, file->f_dentry);
 		sq.busy = 0;
 		WAKE_UP(sq.open_queue);
 		/* Wake up a process waiting for the queue being released.
 		 * Note: There may be several processes waiting for a call
 		 * to open() returning. */
 	}
-	return(rc);
+	sound.soft = sound.dsp;
+	sound.hard = sound.dsp;
+	sound_silence();
+	if (rc == 0)
+		MOD_DEC_USE_COUNT;
+	return rc;
 }
 
 
+static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
+		    u_long arg)
+{
+	u_long fmt;
+	int data;
+	int size, nbufs;
 
-/*
- * /dev/sndstat
- */
+	switch (cmd) {
+	case SNDCTL_DSP_RESET:
+		sq_reset();
+		return 0;
+	case SNDCTL_DSP_POST:
+	case SNDCTL_DSP_SYNC:
+		return sq_fsync(file, file->f_dentry);
+
+		/* ++TeSche: before changing any of these it's
+		 * probably wise to wait until sound playing has
+		 * settled down. */
+	case SNDCTL_DSP_SPEED:
+		sq_fsync(file, file->f_dentry);
+		IOCTL_IN(arg, data);
+		return IOCTL_OUT(arg, sound_set_speed(data));
+	case SNDCTL_DSP_STEREO:
+		sq_fsync(file, file->f_dentry);
+		IOCTL_IN(arg, data);
+		return IOCTL_OUT(arg, sound_set_stereo(data));
+	case SOUND_PCM_WRITE_CHANNELS:
+		sq_fsync(file, file->f_dentry);
+		IOCTL_IN(arg, data);
+		return IOCTL_OUT(arg, sound_set_stereo(data-1)+1);
+	case SNDCTL_DSP_SETFMT:
+		sq_fsync(file, file->f_dentry);
+		IOCTL_IN(arg, data);
+		return IOCTL_OUT(arg, sound_set_format(data));
+	case SNDCTL_DSP_GETFMTS:
+		fmt = 0;
+		if (sound.trans) {
+			if (sound.trans->ct_ulaw)
+				fmt |= AFMT_MU_LAW;
+			if (sound.trans->ct_alaw)
+				fmt |= AFMT_A_LAW;
+			if (sound.trans->ct_s8)
+				fmt |= AFMT_S8;
+			if (sound.trans->ct_u8)
+				fmt |= AFMT_U8;
+			if (sound.trans->ct_s16be)
+				fmt |= AFMT_S16_BE;
+			if (sound.trans->ct_u16be)
+				fmt |= AFMT_U16_BE;
+			if (sound.trans->ct_s16le)
+				fmt |= AFMT_S16_LE;
+			if (sound.trans->ct_u16le)
+				fmt |= AFMT_U16_LE;
+		}
+		return IOCTL_OUT(arg, fmt);
+	case SNDCTL_DSP_GETBLKSIZE:
+		size = sq.block_size
+			* sound.soft.size * (sound.soft.stereo + 1)
+			/ (sound.hard.size * (sound.hard.stereo + 1));
+		return IOCTL_OUT(arg, size);
+	case SNDCTL_DSP_SUBDIVIDE:
+		break;
+	case SNDCTL_DSP_SETFRAGMENT:
+		if (sq.count || sq.playing || sq.syncing)
+			return -EINVAL;
+		IOCTL_IN(arg, size);
+		nbufs = size >> 16;
+		if (nbufs < 2 || nbufs > numBufs)
+			nbufs = numBufs;
+		size &= 0xffff;
+		if (size >= 8 && size <= 30) {
+			size = 1 << size;
+			size *= sound.hard.size * (sound.hard.stereo + 1);
+			size /= sound.soft.size * (sound.soft.stereo + 1);
+			if (size > (bufSize << 10))
+				size = bufSize << 10;
+		} else
+			size = bufSize << 10;
+		sq_setup(numBufs, size, sound_buffers);
+		sq.max_active = nbufs;
+		return 0;
 
+	default:
+		return mixer_ioctl(inode, file, cmd, arg);
+	}
+	return -EINVAL;
+}
 
-static void state_init(void)
+
+
+static struct file_operations sq_fops =
 {
-	state.busy = 0;
+	sound_lseek,
+	NULL,			/* sq_read */
+	sq_write,
+	NULL,			/* sq_readdir */
+	NULL,			/* sq_poll */
+	sq_ioctl,
+	NULL,			/* sq_mmap */
+	sq_open,
+	sq_release,
+};
+
+
+static void sq_init(void)
+{
+	sq_unit = register_sound_dsp(&sq_fops);
+	if (sq_unit < 0)
+		return;
+
+	/* whatever you like as startup mode for /dev/dsp,
+	 * (/dev/audio hasn't got a startup mode). note that
+	 * once changed a new open() will *not* restore these!
+	 */
+	sound.dsp.format = AFMT_U8;
+	sound.dsp.stereo = 0;
+	sound.dsp.size = 8;
+
+	/* set minimum rate possible without expanding */
+	switch (sound.mach.type) {
+#ifdef CONFIG_ATARI
+	case DMASND_TT:
+		sound.dsp.speed = 6258;
+		break;
+	case DMASND_FALCON:
+		sound.dsp.speed = 8195;
+		break;
+#endif /* CONFIG_ATARI */
+#ifdef CONFIG_AMIGA
+	case DMASND_AMIGA:
+		sound.dsp.speed = 8000;
+		break;
+#endif /* CONFIG_AMIGA */
+#ifdef CONFIG_PMAC
+	case DMASND_AWACS:
+		sound.dsp.speed = 8000;
+		break;
+#endif /* CONFIG_PMAC */
+	}
+
+	/* before the first open to /dev/dsp this wouldn't be set */
+	sound.soft = sound.dsp;
+	sound.hard = sound.dsp;
+
+	sound_silence();
 }
 
+/*
+ * /dev/sndstat
+ */
+
 
 /* state.buf should not overflow! */
 
-static int state_open(int open_mode)
+static int state_open(struct inode *inode, struct file *file)
 {
 	char *buffer = state.buf, *mach = "";
 	int len = 0;
 
 	if (state.busy)
-		return(-EBUSY);
+		return -EBUSY;
 
+	MOD_INC_USE_COUNT;
 	state.ptr = 0;
 	state.busy = 1;
 
@@ -4128,117 +4300,57 @@
 	len += sprintf(buffer+len, "\tsq.playing = %d sq.syncing = %d\n",
 		       sq.playing, sq.syncing);
 	state.len = len;
-	return(0);
+	return 0;
 }
 
 
-static int state_release(void)
+static int state_release(struct inode *inode, struct file *file)
 {
 	state.busy = 0;
-	return(0);
+	MOD_DEC_USE_COUNT;
+	return 0;
 }
 
 
-static long state_read(char *dest, unsigned long count)
+static ssize_t state_read(struct file *file, char *buf, size_t count,
+			  loff_t *ppos)
 {
-	int n = state.len-state.ptr;
+	int n = state.len - state.ptr;
 	if (n > count)
 		n = count;
 	if (n <= 0)
-		return(0);
-	if (copy_to_user(dest, &state.buf[state.ptr], n))
+		return 0;
+	if (copy_to_user(buf, &state.buf[state.ptr], n))
 		return -EFAULT;
 	state.ptr += n;
-	return(n);
+	return n;
 }
 
 
-
-/*** High level stuff ********************************************************/
-
-
-static int sound_open(struct inode *inode, struct file *file)
+static struct file_operations state_fops =
 {
-	int dev = MINOR(inode->i_rdev) & 0x0f;
-	int rc = 0;
-
-	switch (dev) {
-	case SND_DEV_STATUS:
-		rc = state_open(file->f_flags);
-		break;
-	case SND_DEV_CTL:
-		rc = mixer_open(file->f_flags);
-		break;
-	case SND_DEV_DSP:
-	case SND_DEV_AUDIO:
-		rc = sq_open(file->f_flags);
-		if (rc == 0) {
-			sound.minDev = dev;
-			sound.soft = sound.dsp;
-			sound.hard = sound.dsp;
-			sound_init();
-			if (dev == SND_DEV_AUDIO) {
-				sound_set_speed(8000);
-				sound_set_stereo(0);
-				sound_set_format(AFMT_MU_LAW);
-			}
-		}
-		break;
-	default:
-		rc = -ENXIO;
-	}
-#ifdef MODULE
-	if (rc >= 0)
-		MOD_INC_USE_COUNT;
-#endif
-	return(rc);
-}
+	sound_lseek,
+	state_read,
+	NULL,			/* state_write */
+	NULL,			/* state_readdir */
+	NULL,			/* state_poll */
+	NULL,			/* state_ioctl */
+	NULL,			/* state_mmap */
+	state_open,
+	state_release,
+};
 
 
-static int sound_fsync(struct file *filp, struct dentry *dentry)
+static void state_init(void)
 {
-	int dev = MINOR(dentry->d_inode->i_rdev) & 0x0f;
-
-	switch (dev) {
-	case SND_DEV_STATUS:
-	case SND_DEV_CTL:
-		return(0);
-	case SND_DEV_DSP:
-	case SND_DEV_AUDIO:
-		return(sq_sync());
-	default:
-		return(unknown_minor_dev("sound_fsync", dev));
-	}
+	state_unit = register_sound_special(&state_fops, SND_DEV_STATUS);
+	if (state_unit < 0)
+		return;
+	state.busy = 0;
 }
 
 
-static int sound_release(struct inode *inode, struct file *file)
-{
-	int dev = MINOR(inode->i_rdev);
-
-	switch (dev & 0x0f) {
-	case SND_DEV_STATUS:
-		state_release();
-		break;
-	case SND_DEV_CTL:
-		mixer_release();
-		break;
-	case SND_DEV_DSP:
-	case SND_DEV_AUDIO:
-		sq_release();
-		sound.soft = sound.dsp;
-		sound.hard = sound.dsp;
-		sound_silence();
-		break;
-	default:
-		return unknown_minor_dev("sound_release", dev);
-	}
-#ifdef MODULE
-	MOD_DEC_USE_COUNT;
-#endif
-	return 0;
-}
-
+/*** Common stuff ********************************************************/
 
 static long long sound_lseek(struct file *file, long long offset, int orig)
 {
@@ -4246,176 +4358,16 @@
 }
 
 
-static ssize_t sound_read(struct file *file, char *buf, size_t count,
-			  loff_t *ppos)
-{
-	struct inode *inode = file->f_dentry->d_inode;
-	int dev = MINOR(inode->i_rdev);
-
-	switch (dev & 0x0f) {
-	case SND_DEV_STATUS:
-		return(state_read(buf, count));
-	case SND_DEV_CTL:
-	case SND_DEV_DSP:
-	case SND_DEV_AUDIO:
-		return(-EPERM);
-	default:
-		return(unknown_minor_dev("sound_read", dev));
-	}
-}
-
-
-static ssize_t sound_write(struct file *file, const char *buf, size_t count,
-			   loff_t *ppos)
-{
-	struct inode *inode = file->f_dentry->d_inode;
-	int dev = MINOR(inode->i_rdev);
-
-	switch (dev & 0x0f) {
-	case SND_DEV_STATUS:
-	case SND_DEV_CTL:
-		return(-EPERM);
-	case SND_DEV_DSP:
-	case SND_DEV_AUDIO:
-		return(sq_write(buf, count));
-	default:
-		return(unknown_minor_dev("sound_write", dev));
-	}
-}
-
-
-static int unknown_minor_dev(char *fname, int dev)
-{
-	/* printk("%s: Unknown minor device %d\n", fname, dev); */
-	return(-ENXIO);
-}
-
-
-static int sound_ioctl(struct inode *inode, struct file *file, u_int cmd,
-		       u_long arg)
-{
-	int dev = MINOR(inode->i_rdev);
-	u_long fmt;
-	int data;
-	int size, nbufs;
-
-	switch (dev & 0x0f) {
-	case SND_DEV_STATUS:
-		return(-EPERM);
-	case SND_DEV_CTL:
-		return(mixer_ioctl(inode, file, cmd, arg));
-	case SND_DEV_AUDIO:
-	case SND_DEV_DSP:
-		switch (cmd) {
-		case SNDCTL_DSP_RESET:
-			sq_reset();
-			return(0);
-		case SNDCTL_DSP_POST:
-		case SNDCTL_DSP_SYNC:
-			return(sound_fsync(file, file->f_dentry));
-
-			/* ++TeSche: before changing any of these it's
-			 * probably wise to wait until sound playing has
-			 * settled down. */
-		case SNDCTL_DSP_SPEED:
-			sound_fsync(file, file->f_dentry);
-			IOCTL_IN(arg, data);
-			return(IOCTL_OUT(arg, sound_set_speed(data)));
-		case SNDCTL_DSP_STEREO:
-			sound_fsync(file, file->f_dentry);
-			IOCTL_IN(arg, data);
-			return(IOCTL_OUT(arg, sound_set_stereo(data)));
-		case SOUND_PCM_WRITE_CHANNELS:
-			sound_fsync(file, file->f_dentry);
-			IOCTL_IN(arg, data);
-			return(IOCTL_OUT(arg, sound_set_stereo(data-1)+1));
-		case SNDCTL_DSP_SETFMT:
-			sound_fsync(file, file->f_dentry);
-			IOCTL_IN(arg, data);
-			return(IOCTL_OUT(arg, sound_set_format(data)));
-		case SNDCTL_DSP_GETFMTS:
-			fmt = 0;
-			if (sound.trans) {
-				if (sound.trans->ct_ulaw)
-					fmt |= AFMT_MU_LAW;
-				if (sound.trans->ct_alaw)
-					fmt |= AFMT_A_LAW;
-				if (sound.trans->ct_s8)
-					fmt |= AFMT_S8;
-				if (sound.trans->ct_u8)
-					fmt |= AFMT_U8;
-				if (sound.trans->ct_s16be)
-					fmt |= AFMT_S16_BE;
-				if (sound.trans->ct_u16be)
-					fmt |= AFMT_U16_BE;
-				if (sound.trans->ct_s16le)
-					fmt |= AFMT_S16_LE;
-				if (sound.trans->ct_u16le)
-					fmt |= AFMT_U16_LE;
-			}
-			return(IOCTL_OUT(arg, fmt));
-		case SNDCTL_DSP_GETBLKSIZE:
-			size = sq.block_size
-				* sound.soft.size * (sound.soft.stereo + 1)
-				/ (sound.hard.size * (sound.hard.stereo + 1));
-			return(IOCTL_OUT(arg, size));
-		case SNDCTL_DSP_SUBDIVIDE:
-			break;
-		case SNDCTL_DSP_SETFRAGMENT:
-			if (sq.count || sq.playing || sq.syncing)
-				return -EINVAL;
-			IOCTL_IN(arg, size);
-			nbufs = size >> 16;
-			if (nbufs < 2 || nbufs > numBufs)
-				nbufs = numBufs;
-			size &= 0xffff;
-			if (size >= 8 && size <= 30) {
-				size = 1 << size;
-				size *= sound.hard.size * (sound.hard.stereo + 1);
-				size /= sound.soft.size * (sound.soft.stereo + 1);
-				if (size > (bufSize << 10))
-					size = bufSize << 10;
-			} else
-				size = bufSize << 10;
-			sq_init(numBufs, size, sound_buffers);
-			sq.max_active = nbufs;
-			break;
-
-		default:
-			return(mixer_ioctl(inode, file, cmd, arg));
-		}
-		break;
-
-	default:
-		return(unknown_minor_dev("sound_ioctl", dev));
-	}
-	return(-EINVAL);
-}
-
-
-static struct file_operations sound_fops =
-{
-	sound_lseek,
-	sound_read,
-	sound_write,
-	NULL,
-	NULL,                      /* select */
-	sound_ioctl,
-	NULL,
-	sound_open,
-	sound_release,
-	sound_fsync
-};
-
-
-
 /*** Config & Setup **********************************************************/
 
 
-void soundcard_init(void)
+void dmasound_init(void)
 {
 	int has_sound = 0;
 	int i;
+#ifdef CONFIG_PMAC
+	struct device_node *np;
+#endif
 
 #ifdef __mc68000__
 	switch (m68k_machtype) {
@@ -4448,8 +4400,6 @@
 #endif /* __mc68000__ */
 
 #ifdef CONFIG_PMAC
-	struct device_node *np;
-
 	np = find_devices("awacs");
 	if (np != NULL && np->n_addrs >= 3 && np->n_intrs >= 3) {
 		int vol;
@@ -4517,15 +4467,10 @@
 		}
 	}
 
-#ifndef MODULE
-	/* Register driver with the VFS. */
-	register_chrdev(SOUND_MAJOR, "sound", &sound_fops);
-#endif
-
-	sq_init(numBufs, bufSize << 10, sound_buffers);
+	sq_setup(numBufs, bufSize << 10, sound_buffers);
 
 	/* Set default settings. */
-	init_settings();
+	sq_init();
 
 	/* Set up /dev/sndstat. */
 	state_init();
@@ -4600,14 +4545,7 @@
 	if (i)
 		dmasound_setup("dmasound=", ints);
 
-	err = register_chrdev(SOUND_MAJOR, "sound", &sound_fops);
-	if (err) {
-		printk("dmasound: driver already loaded/included in kernel\n");
-		return err;
-	}
-	chrdev_registered = 1;
-	soundcard_init();
-
+	dmasound_init();
 	return 0;
 }
 
@@ -4616,12 +4554,6 @@
 {
 	int i;
 
-	if (MOD_IN_USE)
-		return;
-
-	if (chrdev_registered)
-		unregister_chrdev(SOUND_MAJOR, "sound");
-
 	if (irq_installed) {
 		sound_silence();
 		sound.mach.irqcleanup();
@@ -4632,6 +4564,13 @@
 			sound.mach.dma_free(sound_buffers[i], bufSize << 10);
 		kfree(sound_buffers);
 	}
+
+	if (mixer_unit >= 0)
+		unregister_sound_mixer(mixer_unit);
+	if (state_unit >= 0)
+		unregister_sound_special(state_unit);
+	if (sq_unit >= 0)
+		unregister_sound_dsp(sq_unit);
 }
 
 #endif /* MODULE */
--- linux-2.1.105/fs/binfmt_aout.c.~1~	Mon May  4 18:17:07 1998
+++ linux-2.1.105/fs/binfmt_aout.c	Mon Apr 20 18:48:50 1998
@@ -129,7 +129,7 @@
 	if (get_write_access(inode))
 		goto end_coredump;
 	if (init_private_file(&file, dentry, 3))
-		goto end_coredump;
+		goto end_coredump_write;
 	if (!file.f_op->write)
 		goto close_coredump;
 	has_dumped = 1;
@@ -213,6 +213,7 @@
 close_coredump:
 	if (file.f_op->release)
 		file.f_op->release(inode,&file);
+end_coredump_write:
 	put_write_access(inode);
 end_coredump:
 	set_fs(fs);
--- linux-2.1.105/fs/ext2/inode.c.~1~	Fri May 15 17:39:17 1998
+++ linux-2.1.105/fs/ext2/inode.c	Wed Jun 10 19:24:17 1998
@@ -722,10 +722,11 @@
 	unsigned int	flags;
 	
 	retval = -EPERM;
-	if ((iattr->ia_attr_flags &
-	     (ATTR_FLAG_APPEND | ATTR_FLAG_IMMUTABLE)) ^
-	    (inode->u.ext2_i.i_flags &
-	     (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL))) {
+	if (iattr->ia_valid & ATTR_ATTR_FLAG &&
+	    ((!(iattr->ia_attr_flags & ATTR_FLAG_APPEND) !=
+	      !(inode->u.ext2_i.i_flags & EXT2_APPEND_FL)) ||
+	     (!(iattr->ia_attr_flags & ATTR_FLAG_IMMUTABLE) !=
+	      !(inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_FL)))) {
 		if (!capable(CAP_LINUX_IMMUTABLE))
 			goto out;
 	} else if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
--- linux-2.1.105/include/linux/tty.h.~1~	Wed Mar 18 20:08:11 1998
+++ linux-2.1.105/include/linux/tty.h	Sun May 10 16:05:32 1998
@@ -24,6 +24,7 @@
 #include <linux/serialP.h>
 
 #include <asm/system.h>
+#include <asm/atomic.h>
 
 
 /*
@@ -254,7 +255,7 @@
 	char *read_buf;
 	int read_head;
 	int read_tail;
-	int read_cnt;
+	atomic_t read_cnt;
 	unsigned long read_flags[N_TTY_BUF_SIZE/(8*sizeof(unsigned long))];
 	int canon_data;
 	unsigned long canon_head;
--- linux-2.1.105/mm/swapfile.c.~1~	Fri May 15 17:40:54 1998
+++ linux-2.1.105/mm/swapfile.c	Fri May  8 18:52:54 1998
@@ -592,7 +592,7 @@
 	p->flags = SWP_WRITEOK;
 	p->pages = j;
 	nr_swap_pages += j;
-	printk("Adding Swap: %dk swap-space (priority %d)\n",
+	printk(KERN_INFO "Adding Swap: %dk swap-space (priority %d)\n",
 	       j<<(PAGE_SHIFT-10), p->prio);
 
 	/* insert swap space into swap_list: */
--- linux-2.1.105/net/core/dev.c.~1~	Fri May 15 17:40:59 1998
+++ linux-2.1.105/net/core/dev.c	Wed May 13 17:34:15 1998
@@ -1097,7 +1097,7 @@
 	int size;
 	
 	if (stats)
-		size = sprintf(buffer, "%6s:%8lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu %8lu %8lu %4lu %4lu %4lu %5lu %4lu %4lu\n",
+		size = sprintf(buffer, "%6s:%8lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu %8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n",
  		   dev->name,
 		   stats->rx_bytes,
 		   stats->rx_packets, stats->rx_errors,
