aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@cc.helsinki.fi>1993-12-14 10:43:29 +0000
committerNicolas Pitre <nico@cam.org>2007-08-19 14:19:22 -0400
commit59fa0b1fd08fe53a8a9294460c89dda09ee0255d (patch)
tree759418321ab216123bd9ddb1dc5494d7325e04c3
parent8ee558f91b9940ca35f758c4f240b7b5b3ffb76a (diff)
downloadarchive-59fa0b1fd08fe53a8a9294460c89dda09ee0255d.tar.gz
ALPHA-pl14e
-rw-r--r--Makefile2
-rw-r--r--drivers/char/mem.c25
-rw-r--r--drivers/net/slip.c155
-rw-r--r--drivers/net/slip.h1
-rw-r--r--drivers/sound/gus_wave.c2
-rw-r--r--drivers/sound/os.h4
-rw-r--r--drivers/sound/soundcard.h741
-rw-r--r--drivers/sound/ultrasound.h118
-rw-r--r--include/linux/if_ether.h2
-rw-r--r--include/linux/major.h2
-rw-r--r--include/linux/soundcard.h741
-rw-r--r--include/linux/ultrasound.h118
-rw-r--r--kernel/module.c2
-rw-r--r--net/Space.c12
-rw-r--r--net/inet/Makefile1
-rw-r--r--net/inet/arp.c9
-rw-r--r--net/inet/datagram.c26
-rw-r--r--net/inet/dev.c89
-rw-r--r--net/inet/dev.h6
-rw-r--r--net/inet/icmp.c3
-rw-r--r--net/inet/ip.c6
-rw-r--r--net/inet/proc.c11
-rw-r--r--net/inet/raw.c1
-rw-r--r--net/inet/route.c118
-rw-r--r--net/inet/skbuff.c31
-rw-r--r--net/inet/sock.c16
-rw-r--r--net/inet/sock.h26
27 files changed, 1331 insertions, 937 deletions
diff --git a/Makefile b/Makefile
index 32909df..767776a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 0.99
PATCHLEVEL = 14
-ALPHA = d
+ALPHA = e
all: Version zImage
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index f30d39f..fb46cd4 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -205,6 +205,16 @@ static int mmap_zero(struct inode * inode, struct file * file,
return 0;
}
+static int read_full(struct inode * node,struct file * file,char * buf,int count)
+{
+ return count;
+}
+
+static int write_full(struct inode * inode,struct file * file,char * buf, int count)
+{
+ return -ENOSPC;
+}
+
/*
* Special lseek() function for /dev/null and /dev/zero. Most notably, you can fopen()
* both devices with "a" now. This was previously impossible. SRB.
@@ -321,6 +331,18 @@ static struct file_operations zero_fops = {
NULL /* no special release code */
};
+static struct file_operations full_fops = {
+ memory_lseek,
+ read_full,
+ write_full,
+ NULL, /* full_readdir */
+ NULL, /* full_select */
+ NULL, /* full_ioctl */
+ NULL, /* full_mmap */
+ NULL, /* no special open code */
+ NULL /* no special release code */
+};
+
static int memory_open(struct inode * inode, struct file * filp)
{
switch (MINOR(inode->i_rdev)) {
@@ -342,6 +364,9 @@ static int memory_open(struct inode * inode, struct file * filp)
case 5:
filp->f_op = &zero_fops;
break;
+ case 7:
+ filp->f_op = &full_fops;
+ break;
default:
return -ENODEV;
}
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index bf8410a..b900956 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -17,7 +17,9 @@
* Matt Dillon : Printable slip (borrowed from NET2E)
* Pauline Middelink : Slip driver fixes.
* Alan Cox : Honours the old SL_COMPRESSED flag
+ * Alan Cox : KISS AX.25 and AXUI IP support
*/
+
#include <asm/segment.h>
#include <asm/system.h>
@@ -38,6 +40,9 @@
#include <linux/in.h>
#include "inet.h"
#include "dev.h"
+#ifdef CONFIG_AX25
+#include "ax25.h"
+#endif
#include "eth.h"
#include "ip.h"
#include "route.h"
@@ -507,6 +512,18 @@ sl_xmit(struct sk_buff *skb, struct device *dev)
/* We were not, so we are now... :-) */
if (skb != NULL) {
+#ifdef CONFIG_AX25
+ if(sl->mode & SL_MODE_AX25)
+ {
+ if(!skb->arp && dev->rebuild_header(skb+1,dev))
+ {
+ skb->dev=dev;
+ arp_queue(skb);
+ return 0;
+ }
+ skb->arp=1;
+ }
+#endif
sl_lock(sl);
sl_encaps(sl, (unsigned char *) (skb + 1), skb->len);
if (skb->free) kfree_skb(skb, FREE_WRITE);
@@ -515,10 +532,15 @@ sl_xmit(struct sk_buff *skb, struct device *dev)
}
-/* Return the frame type ID. This is always IP. */
+/* Return the frame type ID. This is normally IP but maybe be AX.25. */
static unsigned short
sl_type_trans (struct sk_buff *skb, struct device *dev)
{
+#ifdef CONFIG_AX25
+ struct slip *sl=&sl_ctrl[dev->base_addr];
+ if(sl->mode&SL_MODE_AX25)
+ return(NET16(ETH_P_AX25));
+#endif
return(NET16(ETH_P_IP));
}
@@ -528,6 +550,61 @@ static int
sl_header(unsigned char *buff, struct device *dev, unsigned short type,
unsigned long daddr, unsigned long saddr, unsigned len)
{
+#ifdef CONFIG_AX25
+ struct slip *sl=&sl_ctrl[dev->base_addr];
+ unsigned long flags;
+ if((sl->mode&SL_MODE_AX25) && type!=NET16(ETH_P_AX25))
+ {
+ /* header is an AX.25 UI frame from us to them */
+ if(chk_addr(daddr) == IS_BROADCAST)
+ {
+ *buff++=0;
+ memcpy(buff,dev->broadcast,dev->addr_len); /* QST-0 */
+ }
+ else
+ {
+ if(type!=ETH_P_IP)
+ printk("AX25 Encap: Non IP frame to encapsulate directed\n");
+ save_flags(flags);
+ cli();
+ *buff++=0; /* KISS DATA */
+ memcpy(buff,&daddr,4); /* In case arp fails */
+ if(arp_find(buff,daddr,dev, saddr))
+ {
+ memcpy(buff+7,&saddr,4);
+ buff+=14;
+ *buff++=LAPB_UI; /* UI */
+ /* Append a suitable AX.25 PID */
+ *buff++=PID_IP; /* AX25 IP */
+ restore_flags(flags);
+ return ( -dev->hard_header_len);
+ }
+ }
+ buff[6]&=~LAPB_C;
+ buff[6]&=~LAPB_E;
+ buff+=7;
+ memcpy(buff,dev->dev_addr,dev->addr_len);
+ buff[6]&=~LAPB_C;
+ buff[6]|=LAPB_E;
+ buff+=7;
+ *buff++=LAPB_UI; /* UI */
+ /* Append a suitable AX.25 PID */
+ switch(type)
+ {
+ case ETH_P_IP:
+ *buff++=PID_IP; /* AX25 IP */
+ break;
+ case ETH_P_ARP:
+ *buff++=PID_ARP;
+ break;
+ default:
+ *buff++=0;
+ }
+
+ return (17);
+ }
+#endif
+
return(0);
}
@@ -536,6 +613,12 @@ sl_header(unsigned char *buff, struct device *dev, unsigned short type,
static void
sl_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev)
{
+#ifdef CONFIG_AX25
+ struct slip *sl=&sl_ctrl[dev->base_addr];
+
+ if(sl->mode&SL_MODE_AX25)
+ arp_add(addr,((char *)(skb+1))+8,dev);
+#endif
}
@@ -543,6 +626,24 @@ sl_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev)
static int
sl_rebuild_header(void *buff, struct device *dev)
{
+#ifdef CONFIG_AX25
+ struct slip *sl=&sl_ctrl[dev->base_addr];
+
+ if(sl->mode&SL_MODE_AX25)
+ {
+ unsigned char *bp=(unsigned char *)buff;
+ long dest=*(long *)(bp+1);
+ long src=*(long *)(bp+8);
+ if(arp_find(bp+1,dest,dev,src))
+ return 1;
+ memcpy(bp+8,dev->dev_addr,7);
+ bp[7]&=~LAPB_C;
+ bp[7]&=~LAPB_E;
+ bp[14]&=~LAPB_C;
+ bp[14]|=LAPB_E;
+ return(0);
+ }
+#endif
return(0);
}
@@ -939,6 +1040,20 @@ slip_close(struct tty_struct *tty)
sl->flags |= SLF_ERROR;
}
+
+#ifdef CONFIG_AX25
+
+int sl_set_mac_address(struct device *dev, void *addr)
+{
+ int err=verify_area(VERIFY_READ,addr,7);
+ if(err)
+ return err;
+ memcpy_fromfs(dev->dev_addr,addr,7); /* addr is an AX.25 shifted ASCII mac address */
+ return 0;
+}
+#endif
+
+
/* Perform I/O control on an active SLIP channel. */
static int
slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
@@ -967,7 +1082,25 @@ slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
case SIOCSIFENCAP:
err=verify_area(VERIFY_READ,arg,sizeof(long));
sl->mode=get_fs_long((long *)arg);
+#ifdef CONFIG_AX25
+ if(sl->mode & SL_MODE_AX25)
+ {
+ sl->dev->addr_len=7; /* sizeof an AX.25 addr */
+ sl->dev->hard_header_len=17; /* We don't do digipeaters */
+ sl->dev->type=3; /* AF_AX25 not an AF_INET device */
+ }
+ else
+ {
+ sl->dev->addr_len=0; /* No mac addr in slip mode */
+ sl->dev->hard_header_len=0;
+ sl->dev->type=0;
+ }
+#endif
return(0);
+ case SIOCSIFHWADDR:
+#ifdef CONFIG_AX25
+ return sl_set_mac_address(sl->dev,arg);
+#endif
default:
return(-EINVAL);
}
@@ -981,6 +1114,10 @@ slip_init(struct device *dev)
{
struct slip *sl;
int i;
+#ifdef CONFIG_AX25
+ static char ax25_bcast[7]={'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};
+ static char ax25_test[7]={'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};
+#endif
sl = &sl_ctrl[dev->base_addr];
@@ -988,6 +1125,9 @@ slip_init(struct device *dev)
printk("SLIP: version %s (%d channels)\n",
SLIP_VERSION, SL_NRUNIT);
printk("CSLIP: code copyright 1989 Regents of the University of California\n");
+#ifdef CONFIG_AX25
+ printk("AX25: KISS encapsulation enabled\n");
+#endif
/* Fill in our LDISC request block. */
sl_ldisc.flags = 0;
sl_ldisc.open = slip_open;
@@ -997,8 +1137,8 @@ slip_init(struct device *dev)
sl_ldisc.ioctl = (int (*)(struct tty_struct *, struct file *,
unsigned int, unsigned long)) slip_ioctl;
sl_ldisc.handler = slip_recv;
- if ((i = tty_register_ldisc(N_SLIP, &sl_ldisc)) == 0) printk("OK\n");
- else printk("ERROR: %d\n", i);
+ if ((i = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0)
+ printk("ERROR: %d\n", i);
}
/* Set up the "SLIP Control Block". */
@@ -1020,9 +1160,18 @@ slip_init(struct device *dev)
dev->hard_header = sl_header;
dev->add_arp = sl_add_arp;
dev->type_trans = sl_type_trans;
+#ifdef HAVE_SET_MAC_ADDR
+#ifdef CONFIG_AX25
+ dev->set_mac_address = sl_set_mac_address;
+#endif
+#endif
dev->hard_header_len = 0;
dev->addr_len = 0;
dev->type = 0;
+#ifdef CONFIG_AX25
+ memcpy(dev->broadcast,ax25_bcast,7); /* Only activated in AX.25 mode */
+ memcpy(dev->dev_addr,ax25_test,7); /* "" "" "" "" */
+#endif
dev->queue_xmit = dev_queue_xmit;
dev->rebuild_header = sl_rebuild_header;
for (i = 0; i < DEV_NUMBUFFS; i++)
diff --git a/drivers/net/slip.h b/drivers/net/slip.h
index 6c779ab..7f04909 100644
--- a/drivers/net/slip.h
+++ b/drivers/net/slip.h
@@ -67,6 +67,7 @@ struct slip {
#define SL_MODE_CSLIP 1
#define SL_MODE_SLIP6 2 /* Matt Dillon's printable slip */
#define SL_MODE_CSLIP6 (SL_MODE_SLIP|SL_MODE_CSLIP)
+#define SL_MODE_AX25 4
int xdata,xbits; /* 6 bit slip controls */
};
diff --git a/drivers/sound/gus_wave.c b/drivers/sound/gus_wave.c
index 5be0e81..f773ddd 100644
--- a/drivers/sound/gus_wave.c
+++ b/drivers/sound/gus_wave.c
@@ -31,7 +31,7 @@
/* #define GUS_LINEAR_VOLUME */
#include "sound_config.h"
-#include "ultrasound.h"
+#include <linux/ultrasound.h>
#include "gus_hw.h"
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS)
diff --git a/drivers/sound/os.h b/drivers/sound/os.h
index 52b22a1..c7ba783 100644
--- a/drivers/sound/os.h
+++ b/drivers/sound/os.h
@@ -41,10 +41,10 @@
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/dma.h>
-#include <sys/kd.h>
+#include <linux/kd.h>
#include <linux/wait.h>
#include <linux/malloc.h>
-#include "soundcard.h"
+#include <linux/soundcard.h>
typedef char snd_rw_buf;
diff --git a/drivers/sound/soundcard.h b/drivers/sound/soundcard.h
index 9af627b..e69de29 100644
--- a/drivers/sound/soundcard.h
+++ b/drivers/sound/soundcard.h
@@ -1,741 +0,0 @@
-#ifndef SOUNDCARD_H
-#define SOUNDCARD_H
-/*
- * Copyright by Hannu Savolainen 1993
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- */
-
- /*
- * If you make modifications to this file, please contact me before
- * distributing the modified version. There is already enough
- * divercity in the world.
- *
- * Regards,
- * Hannu Savolainen
- * hsavolai@cs.helsinki.fi
- */
-
-#define SOUND_VERSION 200
-
-#include <sys/ioctl.h>
-
-/*
- * Supported card ID numbers (Should be somewhere else?)
- */
-
-#define SNDCARD_ADLIB 1
-#define SNDCARD_SB 2
-#define SNDCARD_PAS 3
-#define SNDCARD_GUS 4
-#define SNDCARD_MPU401 5
-#define SNDCARD_SB16 6
-
-/***********************************
- * IOCTL Commands for /dev/sequencer
- */
-
-#ifndef _IOWR
-/* @(#)ioctlp.h */
-
-/* Ioctl's have the command encoded in the lower word,
- * and the size of any in or out parameters in the upper
- * word. The high 2 bits of the upper word are used
- * to encode the in/out status of the parameter; for now
- * we restrict parameters to at most 128 bytes.
- */
-/* #define IOCTYPE (0xff<<8) */
-#define IOCPARM_MASK 0x7f /* parameters must be < 128 bytes */
-#define IOC_VOID 0x20000000 /* no parameters */
-#define IOC_OUT 0x40000000 /* copy out parameters */
-#define IOC_IN 0x80000000 /* copy in parameters */
-#define IOC_INOUT (IOC_IN|IOC_OUT)
-/* the 0x20000000 is so we can distinguish new ioctl's from old */
-#define _IO(x,y) ((int)(IOC_VOID|(x<<8)|y))
-#define _IOR(x,y,t) ((int)(IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y))
-#define _IOW(x,y,t) ((int)(IOC_IN|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y))
-/* this should be _IORW, but stdio got there first */
-#define _IOWR(x,y,t) ((int)(IOC_INOUT|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y))
-#endif /* !_IOWR */
-
-#define SNDCTL_SEQ_RESET _IO ('Q', 0)
-#define SNDCTL_SEQ_SYNC _IO ('Q', 1)
-#define SNDCTL_SYNTH_INFO _IOWR('Q', 2, struct synth_info)
-#define SNDCTL_SEQ_CTRLRATE _IOWR('Q', 3, int) /* Set/get timer resolution (HZ) */
-#define SNDCTL_SEQ_GETOUTCOUNT _IOR ('Q', 4, int)
-#define SNDCTL_SEQ_GETINCOUNT _IOR ('Q', 5, int)
-#define SNDCTL_SEQ_PERCMODE _IOW ('Q', 6, int)
-#define SNDCTL_FM_LOAD_INSTR _IOW ('Q', 7, struct sbi_instrument) /* Valid for FM only */
-#define SNDCTL_SEQ_TESTMIDI _IOW ('Q', 8, int)
-#define SNDCTL_SEQ_RESETSAMPLES _IOW ('Q', 9, int)
-#define SNDCTL_SEQ_NRSYNTHS _IOR ('Q',10, int)
-#define SNDCTL_SEQ_NRMIDIS _IOR ('Q',11, int)
-#define SNDCTL_MIDI_INFO _IOWR('Q',12, struct midi_info)
-#define SNDCTL_SEQ_TRESHOLD _IOW ('Q',13, int)
-#define SNDCTL_SYNTH_MEMAVL _IOWR('Q',14, int) /* in=dev#, out=memsize */
-#define SNDCTL_FM_4OP_ENABLE _IOW ('Q',15, int) /* in=dev# */
-#define SNDCTL_PMGR_ACCESS _IOWR('Q',16, struct patmgr_info)
-
-/*
- * Sample loading mechanism for internal synthesizers (/dev/sequencer)
- * The following patch_info structure has been designed to support
- * Gravis UltraSound. It tries to be universal format for uploading
- * sample based patches but is propably too limited.
- */
-
-struct patch_info {
- short key; /* Use GUS_PATCH here */
-#define GUS_PATCH 0x04fd
-#define OBSOLETE_GUS_PATCH 0x02fd
- short device_no; /* Synthesizer number */
- short instr_no; /* Midi pgm# */
-
- unsigned long mode;
-/*
- * The least significant byte has the same format than the GUS .PAT
- * files
- */
-#define WAVE_16_BITS 0x01 /* bit 0 = 8 or 16 bit wave data. */
-#define WAVE_UNSIGNED 0x02 /* bit 1 = Signed - Unsigned data. */
-#define WAVE_LOOPING 0x04 /* bit 2 = looping enabled-1. */
-#define WAVE_BIDIR_LOOP 0x08 /* bit 3 = Set is bidirectional looping. */
-#define WAVE_LOOP_BACK 0x10 /* bit 4 = Set is looping backward. */
-#define WAVE_SUSTAIN_ON 0x20 /* bit 5 = Turn sustaining on. (Env. pts. 3)*/
-#define WAVE_ENVELOPES 0x40 /* bit 6 = Enable envelopes - 1 */
- /* (use the env_rate/env_offs fields). */
-/* Linux specific bits */
-#define WAVE_VIBRATO 0x00010000 /* The vibrato info is valid */
-#define WAVE_TREMOLO 0x00020000 /* The tremolo info is valid */
-#define WAVE_SCALE 0x00040000 /* The scaling info is valid */
-/* Other bits must be zeroed */
-
- long len; /* Size of the wave data in bytes */
- long loop_start, loop_end; /* Byte offsets from the beginning */
-
-/*
- * The base_freq and base_note fields are used when computing the
- * playback speed for a note. The base_note defines the tone frequency
- * which is heard if the sample is played using the base_freq as the
- * playback speed.
- *
- * The low_note and high_note fields define the minimum and maximum note
- * frequencies for which this sample is valid. It is possible to define
- * more than one samples for a instrument number at the same time. The
- * low_note and high_note fields are used to select the most suitable one.
- *
- * The fields base_note, high_note and low_note should contain
- * the note frequency multiplied by 1000. For example value for the
- * middle A is 440*1000.
- */
-
- unsigned int base_freq;
- unsigned long base_note;
- unsigned long high_note;
- unsigned long low_note;
- int panning; /* -128=left, 127=right */
- int detuning;
-
-/* New fields introduced in version 1.99.5 */
-
- /* Envelope. Enabled by mode bit WAVE_ENVELOPES */
- unsigned char env_rate[ 6 ]; /* GUS HW ramping rate */
- unsigned char env_offset[ 6 ]; /* 255 == 100% */
-
- /*
- * The tremolo, vibrato and scale info are not supported yet.
- * Enable by setting the mode bits WAVE_TREMOLO, WAVE_VIBRATO or
- * WAVE_SCALE
- */
-
- unsigned char tremolo_sweep;
- unsigned char tremolo_rate;
- unsigned char tremolo_depth;
-
- unsigned char vibrato_sweep;
- unsigned char vibrato_rate;
- unsigned char vibrato_depth;
-
- int scale_frequency;
- unsigned int scale_factor; /* from 0 to 2048 or 0 to 2 */
-
- int volume;
- int spare[4];
- char data[1]; /* The waveform data starts here */
- };
-
-
-/*
- * Patch management interface (/dev/sequencer, /dev/patmgr#)
- * Don't use these calls if you want to maintain compatibility with
- * the future versions of the driver.
- */
-
-#define PS_NO_PATCHES 0 /* No patch support on device */
-#define PS_MGR_NOT_OK 1 /* Plain patch support (no mgr) */
-#define PS_MGR_OK 2 /* Patch manager supported */
-#define PS_MANAGED 3 /* Patch manager running */
-
-#define SNDCTL_PMGR_IFACE _IOWR('P', 1, struct patmgr_info)
-
-/*
- * The patmgr_info is a fixed size structure which is used for two
- * different purposes. The intended use is for communication between
- * the application using /dev/sequencer and the patch manager daemon
- * associated with a synthesizer device (ioctl(SNDCTL_PMGR_ACCESS)).
- *
- * This structure is also used with ioctl(SNDCTL_PGMR_IFACE) which allows
- * a patch manager daemon to read and write device parameters. This
- * ioctl available through /dev/sequencer also. Avoid using it since it's
- * extremely hardware dependent. In addition access trough /dev/sequencer
- * may confuse the patch manager daemon.
- */
-
-struct patmgr_info { /* Note! size must be < 4k since kmalloc() is used */
- unsigned long key; /* Don't worry. Reserved for communication
- between the patch manager and the driver. */
-#define PM_K_EVENT 1 /* Event from the /dev/sequencer driver */
-#define PM_K_COMMAND 2 /* Request from a application */
-#define PM_K_RESPONSE 3 /* From patmgr to application */
-#define PM_ERROR 4 /* Error returned by the patmgr */
- int device;
- int command;
-
-/*
- * Commands 0x000 to 0xfff reserved for patch manager programs
- */
-#define PM_GET_DEVTYPE 1 /* Returns type of the patch mgr interface of dev */
-#define PMTYPE_FM2 1 /* 2 OP fm */
-#define PMTYPE_FM4 2 /* Mixed 4 or 2 op FM (OPL-3) */
-#define PMTYPE_WAVE 3 /* Wave table synthesizer (GUS) */
-#define PM_GET_NRPGM 2 /* Returns max # of midi programs in parm1 */
-#define PM_GET_PGMMAP 3 /* Returns map of loaded midi programs in data8 */
-#define PM_GET_PGM_PATCHES 4 /* Return list of patches of a program (parm1) */
-#define PM_GET_PATCH 5 /* Return patch header of patch parm1 */
-#define PM_SET_PATCH 6 /* Set patch header of patch parm1 */
-#define PM_READ_PATCH 7 /* Read patch (wave) data */
-#define PM_WRITE_PATCH 8 /* Write patch (wave) data */
-
-/*
- * Commands 0x1000 to 0xffff are for communication between the patch manager
- * and the client
- */
-#define _PM_LOAD_PATCH 0x100
-
-/*
- * Commands above 0xffff reserved for device specific use
- */
-
- long parm1;
- long parm2;
- long parm3;
-
- union {
- unsigned char data8[4000];
- unsigned short data16[2000];
- unsigned long data32[1000];
- struct patch_info patch;
- } data;
- };
-
-/*
- * When a patch manager daemon is present, it will be informed by the
- * driver when something important happens. For example when the
- * /dev/sequencer is opened or closed. A record with key == PM_K_EVENT is
- * returned. The command field contains the event type:
- */
-#define PM_E_OPENED 1 /* /dev/sequencer opened */
-#define PM_E_CLOSED 2 /* /dev/sequencer closed */
-#define PM_E_PATCH_RESET 3 /* SNDCTL_RESETSAMPLES called */
-#define PM_E_PATCH_LOADED 4 /* A patch has been loaded by appl */
-
-/*
- * /dev/sequencer input events.
- *
- * The data written to the /dev/sequencer is a stream of events. Events
- * are records of 4 or 8 bytes. The first byte defines the size.
- * Any number of events can be written with a write call. There
- * is a set of macros for sending these events. Use these macros if you
- * want to maximize portability of your program.
- *
- * Events SEQ_WAIT, SEQ_MIDIPUTC and SEQ_ECHO. Are also input events.
- * (All input events are currently 4 bytes long. Be prepared to support
- * 8 byte events also. If you receive any event having first byte >= 0xf0,
- * it's a 8 byte event.
- *
- * The events are documented at the end of this file.
- *
- * Normal events (4 bytes)
- * There is also a 8 byte version of most of the 4 byte events. The
- * 8 byte one is recommended.
- */
-#define SEQ_NOTEOFF 0
-#define SEQ_FMNOTEOFF SEQ_NOTEOFF /* Just old name */
-#define SEQ_NOTEON 1
-#define SEQ_FMNOTEON SEQ_NOTEON
-#define SEQ_WAIT 2
-#define SEQ_PGMCHANGE 3
-#define SEQ_FMPGMCHANGE SEQ_PGMCHANGE
-#define SEQ_SYNCTIMER 4
-#define SEQ_MIDIPUTC 5
-#define SEQ_DRUMON 6 /*** OBSOLETE ***/
-#define SEQ_DRUMOFF 7 /*** OBSOLETE ***/
-#define SEQ_ECHO 8 /* For synching programs with output */
-#define SEQ_AFTERTOUCH 9
-#define SEQ_CONTROLLER 10
-#define CTRL_PITCH_BENDER 255
-#define CTRL_PITCH_BENDER_RANGE 254
-#define CTRL_EXPRESSION 253
-#define CTRL_MAIN_VOLUME 252
-#define SEQ_BALANCE 11
-
-/*
- * Note! SEQ_WAIT, SEQ_MIDIPUTC and SEQ_ECHO are used also as
- * input events.
- */
-
-/*
- * Event codes 0xf0 to 0xfc are reserved for future extensions.
- */
-
-#define SEQ_FULLSIZE 0xfd /* Long events */
-/*
- * SEQ_FULLSIZE events are used for loading patches/samples to the
- * synthesizer devices. These events are passed directly to the driver
- * of the associated synthesizer device. There is no limit to the size
- * of the extended events. These events are not queued but executed
- * immediately when the write() is called (execution can take several
- * seconds of time).
- *
- * When a SEQ_FULLSIZE message is written to the device, it must
- * be written using exactly one write() call. Other events cannot
- * be mixed to the same write.
- *
- * For FM synths (YM3812/OPL3) use struct sbi_instrument and write it to the
- * /dev/sequencer. Don't write other data together with the instrument structure
- * Set the key field of the structure to FM_PATCH. The device field is used to
- * route the patch to the corresponding device.
- *
- * For Gravis UltraSound use struct patch_info. Initialize the key field
- * to GUS_PATCH.
- */
-#define SEQ_PRIVATE 0xfe /* Low level HW dependent events (8 bytes) */
-#define SEQ_EXTENDED 0xff /* Extended events (8 bytes) */
-
-/*
- * Extended events for synthesizers (8 bytes)
- *
- * Format:
- *
- * b0 = SEQ_EXTENDED
- * b1 = command
- * b2 = device
- * b3-b7 = parameters
- *
- * Command b3 b4 b5 b6 b7
- * ----------------------------------------------------------------------------
- * SEQ_NOTEON voice note volume 0 0
- * SEQ_NOTEOFF voice note volume 0 0
- * SEQ_PGMCHANGE voice pgm 0 0 0
- * SEQ_DRUMON (voice) drum# volume 0 0
- * SEQ_DRUMOFF (voice) drum# volume 0 0
- */
-
-/*
- * Record for FM patches
- */
-
-typedef unsigned char sbi_instr_data[32];
-
-struct sbi_instrument {
- unsigned short key; /* Initialize to FM_PATCH or OPL3_PATCH */
-#define FM_PATCH 0x01fd
-#define OPL3_PATCH 0x03fd
- short device; /* Synth# (0-4) */
- int channel; /* Program# to be initialized */
- sbi_instr_data operators; /* Register settings for operator cells (.SBI format) */
- };
-
-struct synth_info { /* Read only */
- char name[30];
- int device; /* 0-N. INITIALIZE BEFORE CALLING */
- int synth_type;
-#define SYNTH_TYPE_FM 0
-#define SYNTH_TYPE_SAMPLE 1
-
- int synth_subtype;
-#define FM_TYPE_ADLIB 0x00
-#define FM_TYPE_OPL3 0x01
-
-#define SAMPLE_TYPE_GUS 0x10
-
- int perc_mode; /* No longer supported */
- int nr_voices;
- int nr_drums; /* Obsolete field */
- int instr_bank_size;
- unsigned long capabilities;
-#define SYNTH_CAP_PERCMODE 0x00000001 /* No longer used */
-#define SYNTH_CAP_OPL3 0x00000002 /* Set if OPL3 supported */
- int dummies[19]; /* Reserve space */
- };
-
-struct midi_info {
- char name[30];
- int device; /* 0-N. INITIALIZE BEFORE CALLING */
- unsigned long capabilities; /* To be defined later */
- int dev_type;
- int dummies[18]; /* Reserve space */
- };
-
-/********************************************
- * IOCTL commands for /dev/dsp and /dev/audio
- */
-
-#define SNDCTL_DSP_RESET _IO ('P', 0)
-#define SNDCTL_DSP_SYNC _IO ('P', 1)
-#define SNDCTL_DSP_SPEED _IOWR('P', 2, int)
-#define SNDCTL_DSP_STEREO _IOWR('P', 3, int)
-#define SNDCTL_DSP_GETBLKSIZE _IOWR('P', 4, int)
-#define SNDCTL_DSP_SAMPLESIZE _IOWR('P', 5, int) /* 8, 12 or 16 */
-#define SOUND_PCM_WRITE_CHANNELS _IOWR('P', 6, int)
-#define SOUND_PCM_WRITE_FILTER _IOWR('P', 7, int)
-#define SNDCTL_DSP_POST _IO ('P', 8)
-#define SNDCTL_DSP_SUBDIVIDE _IOWR('P', 9, int)
-
-#define SOUND_PCM_READ_RATE _IOR ('P', 2, int)
-#define SOUND_PCM_READ_CHANNELS _IOR ('P', 6, int)
-#define SOUND_PCM_READ_BITS _IOR ('P', 5, int)
-#define SOUND_PCM_READ_FILTER _IOR ('P', 7, int)
-
-/* Some alias names */
-#define SOUND_PCM_WRITE_BITS SNDCTL_DSP_SAMPLESIZE
-#define SOUND_PCM_WRITE_RATE SNDCTL_DSP_SPEED
-#define SOUND_PCM_POST SNDCTL_DSP_POST
-#define SOUND_PCM_RESET SNDCTL_DSP_RESET
-#define SOUND_PCM_SYNC SNDCTL_DSP_SYNC
-#define SOUND_PCM_SUBDIVIDE SNDCTL_DSP_SUBDIVIDE
-
-/*********************************************
- * IOCTL commands for /dev/mixer
- */
-
-/*
- * Mixer devices
- *
- * There can be up to 20 different analog mixer channels. The
- * SOUND_MIXER_NRDEVICES gives the currently supported maximum.
- * The SOUND_MIXER_READ_DEVMASK returns a bitmask which tells
- * the devices supported by the particular mixer.
- */
-
-#define SOUND_MIXER_NRDEVICES 12
-#define SOUND_MIXER_VOLUME 0
-#define SOUND_MIXER_BASS 1
-#define SOUND_MIXER_TREBLE 2
-#define SOUND_MIXER_SYNTH 3
-#define SOUND_MIXER_PCM 4
-#define SOUND_MIXER_SPEAKER 5
-#define SOUND_MIXER_LINE 6
-#define SOUND_MIXER_MIC 7
-#define SOUND_MIXER_CD 8
-#define SOUND_MIXER_IMIX 9 /* Recording monitor */
-#define SOUND_MIXER_ALTPCM 10
-#define SOUND_MIXER_RECLEV 11 /* Recording level */
-
-/* Some on/off settings (SOUND_SPECIAL_MIN - SOUND_SPECIAL_MAX) */
-/* Not counted to SOUND_MIXER_NRDEVICES, but use the same number space */
-#define SOUND_ONOFF_MIN 28
-#define SOUND_ONOFF_MAX 30
-#define SOUND_MIXER_MUTE 28 /* 0 or 1 */
-#define SOUND_MIXER_ENHANCE 29 /* Enhanced stereo (0, 40, 60 or 80) */
-#define SOUND_MIXER_LOUD 30 /* 0 or 1 */
-
-/* Note! Number 31 cannot be used since the sign bit is reserved */
-
-#define SOUND_DEVICE_LABELS {"Vol ", "Bass ", "Trebl", "Synth", "Pcm ", "Spkr ", "Line ", \
- "Mic ", "CD ", "Mix ", "Pcm2 ", "rec"}
-
-#define SOUND_DEVICE_NAMES {"vol", "bass", "treble", "synth", "pcm", "speaker", "line", \
- "mic", "cd", "mix", "pcm2", "rec"}
-
-/* Device bitmask identifiers */
-
-#define SOUND_MIXER_RECSRC 0xff /* Arg contains a bit for each recording source */
-#define SOUND_MIXER_DEVMASK 0xfe /* Arg contains a bit for each supported device */
-#define SOUND_MIXER_RECMASK 0xfd /* Arg contains a bit for each supported recording source */
-#define SOUND_MIXER_CAPS 0xfc
- #define SOUND_CAP_EXCL_INPUT 0x00000001 /* Only one recording source at a time */
-#define SOUND_MIXER_STEREODEVS 0xfb /* Mixer channels supporting stereo */
-
-/* Device mask bits */
-
-#define SOUND_MASK_VOLUME (1 << SOUND_MIXER_VOLUME)
-#define SOUND_MASK_BASS (1 << SOUND_MIXER_BASS)
-#define SOUND_MASK_TREBLE (1 << SOUND_MIXER_TREBLE)
-#define SOUND_MASK_SYNTH (1 << SOUND_MIXER_SYNTH)
-#define SOUND_MASK_PCM (1 << SOUND_MIXER_PCM)
-#define SOUND_MASK_SPEAKER (1 << SOUND_MIXER_SPEAKER)
-#define SOUND_MASK_LINE (1 << SOUND_MIXER_LINE)
-#define SOUND_MASK_MIC (1 << SOUND_MIXER_MIC)
-#define SOUND_MASK_CD (1 << SOUND_MIXER_CD)
-#define SOUND_MASK_IMIX (1 << SOUND_MIXER_IMIX)
-#define SOUND_MASK_ALTPCM (1 << SOUND_MIXER_ALTPCM)
-#define SOUND_MASK_RECLEV (1 << SOUND_MIXER_RECLEV)
-
-#define SOUND_MASK_MUTE (1 << SOUND_MIXER_MUTE)
-#define SOUND_MASK_ENHANCE (1 << SOUND_MIXER_ENHANCE)
-#define SOUND_MASK_LOUD (1 << SOUND_MIXER_LOUD)
-
-#define MIXER_READ(dev) _IOR('M', dev, int)
-#define SOUND_MIXER_READ_VOLUME MIXER_READ(SOUND_MIXER_VOLUME)
-#define SOUND_MIXER_READ_BASS MIXER_READ(SOUND_MIXER_BASS)
-#define SOUND_MIXER_READ_TREBLE MIXER_READ(SOUND_MIXER_TREBLE)
-#define SOUND_MIXER_READ_SYNTH MIXER_READ(SOUND_MIXER_SYNTH)
-#define SOUND_MIXER_READ_PCM MIXER_READ(SOUND_MIXER_PCM)
-#define SOUND_MIXER_READ_SPEAKER MIXER_READ(SOUND_MIXER_SPEAKER)
-#define SOUND_MIXER_READ_LINE MIXER_READ(SOUND_MIXER_LINE)
-#define SOUND_MIXER_READ_MIC MIXER_READ(SOUND_MIXER_MIC)
-#define SOUND_MIXER_READ_CD MIXER_READ(SOUND_MIXER_CD)
-#define SOUND_MIXER_READ_IMIX MIXER_READ(SOUND_MIXER_IMIX)
-#define SOUND_MIXER_READ_ALTPCM MIXER_READ(SOUND_MIXER_ALTPCM)
-#define SOUND_MIXER_READ_RECLEV MIXER_READ(SOUND_MIXER_RECLEV)
-#define SOUND_MIXER_READ_MUTE MIXER_READ(SOUND_MIXER_MUTE)
-#define SOUND_MIXER_READ_ENHANCE MIXER_READ(SOUND_MIXER_ENHANCE)
-#define SOUND_MIXER_READ_LOUD MIXER_READ(SOUND_MIXER_LOUD)
-
-#define SOUND_MIXER_READ_RECSRC MIXER_READ(SOUND_MIXER_RECSRC)
-#define SOUND_MIXER_READ_DEVMASK MIXER_READ(SOUND_MIXER_DEVMASK)
-#define SOUND_MIXER_READ_RECMASK MIXER_READ(SOUND_MIXER_RECMASK)
-#define SOUND_MIXER_READ_STEREODEVS MIXER_READ(SOUND_MIXER_STEREODEVS)
-#define SOUND_MIXER_READ_CAPS MIXER_READ(SOUND_MIXER_CAPS)
-
-#define MIXER_WRITE(dev) _IOWR('M', dev, int)
-#define SOUND_MIXER_WRITE_VOLUME MIXER_WRITE(SOUND_MIXER_VOLUME)
-#define SOUND_MIXER_WRITE_BASS MIXER_WRITE(SOUND_MIXER_BASS)
-#define SOUND_MIXER_WRITE_TREBLE MIXER_WRITE(SOUND_MIXER_TREBLE)
-#define SOUND_MIXER_WRITE_SYNTH MIXER_WRITE(SOUND_MIXER_SYNTH)
-#define SOUND_MIXER_WRITE_PCM MIXER_WRITE(SOUND_MIXER_PCM)
-#define SOUND_MIXER_WRITE_SPEAKER MIXER_WRITE(SOUND_MIXER_SPEAKER)
-#define SOUND_MIXER_WRITE_LINE MIXER_WRITE(SOUND_MIXER_LINE)
-#define SOUND_MIXER_WRITE_MIC MIXER_WRITE(SOUND_MIXER_MIC)
-#define SOUND_MIXER_WRITE_CD MIXER_WRITE(SOUND_MIXER_CD)
-#define SOUND_MIXER_WRITE_IMIX MIXER_WRITE(SOUND_MIXER_IMIX)
-#define SOUND_MIXER_WRITE_ALTPCM MIXER_WRITE(SOUND_MIXER_ALTPCM)
-#define SOUND_MIXER_WRITE_RECLEV MIXER_WRITE(SOUND_MIXER_RECLEV)
-#define SOUND_MIXER_WRITE_MUTE MIXER_WRITE(SOUND_MIXER_MUTE)
-#define SOUND_MIXER_WRITE_ENHANCE MIXER_WRITE(SOUND_MIXER_ENHANCE)
-#define SOUND_MIXER_WRITE_LOUD MIXER_WRITE(SOUND_MIXER_LOUD)
-
-#define SOUND_MIXER_WRITE_RECSRC MIXER_WRITE(SOUND_MIXER_RECSRC)
-
-/*
- * The following mixer ioctl calls are compatible with the BSD driver by
- * Steve Haehnichen <shaehnic@ucsd.edu>
- *
- * Since this interface is entirely SB specific, it will be dropped in the
- * near future.
- */
-
-typedef unsigned char S_BYTE;
-typedef unsigned char S_FLAG;
-struct stereo_vol
-{
- S_BYTE l; /* Left volume */
- S_BYTE r; /* Right volume */
-};
-
-#define MIXER_IOCTL_SET_LEVELS _IOW ('s', 20, struct sb_mixer_levels)
-#define MIXER_IOCTL_SET_PARAMS _IOW ('s', 21, struct sb_mixer_params)
-#define MIXER_IOCTL_READ_LEVELS _IOR ('s', 22, struct sb_mixer_levels)
-#define MIXER_IOCTL_READ_PARAMS _IOR ('s', 23, struct sb_mixer_params)
-#define MIXER_IOCTL_RESET _IO ('s', 24)
-
-/*
- * Mixer volume levels for MIXER_IOCTL_SET_VOL & MIXER_IOCTL_READ_VOL
- */
-struct sb_mixer_levels
-{
- struct stereo_vol master; /* Master volume */
- struct stereo_vol voc; /* DSP Voice volume */
- struct stereo_vol fm; /* FM volume */
- struct stereo_vol line; /* Line-in volume */
- struct stereo_vol cd; /* CD audio */
- S_BYTE mic; /* Microphone level */
-};
-
-/*
- * Mixer parameters for MIXER_IOCTL_SET_PARAMS & MIXER_IOCTL_READ_PARAMS
- */
-struct sb_mixer_params
-{
- S_BYTE record_source; /* Recording source (See SRC_xxx below) */
- S_FLAG hifreq_filter; /* Filter frequency (hi/low) */
- S_FLAG filter_input; /* ANFI input filter */
- S_FLAG filter_output; /* DNFI output filter */
- S_FLAG dsp_stereo; /* 1 if DSP is in Stereo mode */
-};
-
-#define SRC_MIC 1 /* Select Microphone recording source */
-#define SRC_CD 3 /* Select CD recording source */
-#define SRC_LINE 7 /* Use Line-in for recording source */
-
-#if !defined(KERNEL) && !defined(INKERNEL)
-/*
- * Some convenience macros to simplify programming of the
- * /dev/sequencer interface
- *
- * These macros define the API which should be used when possible.
- */
-
-void seqbuf_dump(void); /* This function must be provided by programs */
-
-/* Sample seqbuf_dump() implementation:
- *
- * SEQ_DEFINEBUF (2048); -- Defines a buffer for 2048 bytes
- *
- * int seqfd; -- The file descriptor for /dev/sequencer.
- *
- * void
- * seqbuf_dump ()
- * {
- * if (_seqbufptr)
- * if (write (seqfd, _seqbuf, _seqbufptr) == -1)
- * {
- * perror ("write /dev/sequencer");
- * exit (-1);
- * }
- * _seqbufptr = 0;
- * }
- */
-
-#define SEQ_DEFINEBUF(len) unsigned char _seqbuf[len]; int _seqbuflen = len, _seqbufptr = 0
-#define SEQ_PM_DEFINES struct patmgr_info _pm_info
-#define _SEQ_NEEDBUF(len) if ((_seqbufptr+(len)) > _seqbuflen) seqbuf_dump()
-#define _SEQ_ADVBUF(len) _seqbufptr += len
-#define SEQ_DUMPBUF seqbuf_dump
-#define PM_LOAD_PATCH(dev, bank, pgm) (SEQ_DUMPBUF(), _pm_info.command = _PM_LOAD_PATCH, \
- _pm_info.device=dev, _pm_info.data.data8[0]=pgm, \
- _pm_info.parm1 = bank, _pm_info.parm2 = 1, \
- ioctl(seqfd, SNDCTL_PMGR_ACCESS, &_pm_info))
-#define PM_LOAD_PATCHES(dev, bank, pgm) (SEQ_DUMPBUF(), _pm_info.command = _PM_LOAD_PATCH, \
- _pm_info.device=dev, memcpy(_pm_info.data.data8, pgm, 128), \
- _pm_info.parm1 = bank, _pm_info.parm2 = 128, \
- ioctl(seqfd, SNDCTL_PMGR_ACCESS, &_pm_info))
-
-#define SEQ_START_NOTE(dev, voice, note, vol) {_SEQ_NEEDBUF(8);\
- _seqbuf[_seqbufptr] = SEQ_EXTENDED;\
- _seqbuf[_seqbufptr+1] = SEQ_NOTEON;\
- _seqbuf[_seqbufptr+2] = (dev);\
- _seqbuf[_seqbufptr+3] = (voice);\
- _seqbuf[_seqbufptr+4] = (note);\
- _seqbuf[_seqbufptr+5] = (vol);\
- _seqbuf[_seqbufptr+6] = 0;\
- _seqbuf[_seqbufptr+7] = 0;\
- _SEQ_ADVBUF(8);}
-
-#define SEQ_STOP_NOTE(dev, voice, note, vol) {_SEQ_NEEDBUF(8);\
- _seqbuf[_seqbufptr] = SEQ_EXTENDED;\
- _seqbuf[_seqbufptr+1] = SEQ_NOTEOFF;\
- _seqbuf[_seqbufptr+2] = (dev);\
- _seqbuf[_seqbufptr+3] = (voice);\
- _seqbuf[_seqbufptr+4] = (note);\
- _seqbuf[_seqbufptr+5] = (vol);\
- _seqbuf[_seqbufptr+6] = 0;\
- _seqbuf[_seqbufptr+7] = 0;\
- _SEQ_ADVBUF(8);}
-
-#define SEQ_CHN_PRESSURE(dev, voice, pressure) {_SEQ_NEEDBUF(8);\
- _seqbuf[_seqbufptr] = SEQ_EXTENDED;\
- _seqbuf[_seqbufptr+1] = SEQ_AFTERTOUCH;\
- _seqbuf[_seqbufptr+2] = (dev);\
- _seqbuf[_seqbufptr+3] = (voice);\
- _seqbuf[_seqbufptr+4] = (pressure);\
- _seqbuf[_seqbufptr+5] = 0;\
- _seqbuf[_seqbufptr+6] = 0;\
- _seqbuf[_seqbufptr+7] = 0;\
- _SEQ_ADVBUF(8);}
-
-#define SEQ_PANNING(dev, voice, pos) {_SEQ_NEEDBUF(8);\
- _seqbuf[_seqbufptr] = SEQ_EXTENDED;\
- _seqbuf[_seqbufptr+1] = SEQ_BALANCE;\
- _seqbuf[_seqbufptr+2] = (dev);\
- _seqbuf[_seqbufptr+3] = (voice);\
- (char)_seqbuf[_seqbufptr+4] = (pos);\
- _seqbuf[_seqbufptr+5] = 0;\
- _seqbuf[_seqbufptr+6] = 0;\
- _seqbuf[_seqbufptr+7] = 0;\
- _SEQ_ADVBUF(8);}
-
-#define SEQ_CONTROL(dev, voice, controller, value) {_SEQ_NEEDBUF(8);\
- _seqbuf[_seqbufptr] = SEQ_EXTENDED;\
- _seqbuf[_seqbufptr+1] = SEQ_CONTROLLER;\
- _seqbuf[_seqbufptr+2] = (dev);\
- _seqbuf[_seqbufptr+3] = (voice);\
- _seqbuf[_seqbufptr+4] = (controller);\
- *(short *)&_seqbuf[_seqbufptr+5] = (value);\
- _seqbuf[_seqbufptr+7] = 0;\
- _SEQ_ADVBUF(8);}
-
-#define SEQ_PITCHBEND(dev, voice, value) SEQ_CONTROL(dev, voice, CTRL_PITCH_BENDER, value)
-#define SEQ_BENDER_RANGE(dev, voice, value) SEQ_CONTROL(dev, voice, CTRL_PITCH_BENDER_RANGE, value)
-#define SEQ_EXPRESSION(dev, voice, value) SEQ_CONTROL(dev, voice, CTRL_EXPRESSION, value)
-#define SEQ_MAIN_VOLUME(dev, voice, value) SEQ_CONTROL(dev, voice, CTRL_MAIN_VOLUME, value)
-
-#define SEQ_START_TIMER() {_SEQ_NEEDBUF(4);\
- _seqbuf[_seqbufptr] = SEQ_SYNCTIMER;\
- _seqbuf[_seqbufptr+1] = 0;\
- _seqbuf[_seqbufptr+2] = 0;\
- _seqbuf[_seqbufptr+3] = 0;\
- _SEQ_ADVBUF(4);}
-#define SEQ_SET_PATCH(dev, voice, patch) {_SEQ_NEEDBUF(8);\
- _seqbuf[_seqbufptr] = SEQ_EXTENDED;\
- _seqbuf[_seqbufptr+1] = SEQ_PGMCHANGE;\
- _seqbuf[_seqbufptr+2] = (dev);\
- _seqbuf[_seqbufptr+3] = (voice);\
- _seqbuf[_seqbufptr+4] = (patch);\
- _seqbuf[_seqbufptr+5] = 0;\
- _seqbuf[_seqbufptr+6] = 0;\
- _seqbuf[_seqbufptr+7] = 0;\
- _SEQ_ADVBUF(8);}
-
-#define SEQ_WAIT_TIME(ticks) {_SEQ_NEEDBUF(4);\
- *(unsigned long *)&_seqbuf[_seqbufptr] = SEQ_WAIT | ((ticks) << 8);\
- _SEQ_ADVBUF(4);}
-
-#define SEQ_ECHO_BACK(key) {_SEQ_NEEDBUF(4);\
- *(unsigned long *)&_seqbuf[_seqbufptr] = SEQ_ECHO | ((key) << 8);\
- _SEQ_ADVBUF(4);}
-
-#define SEQ_MIDIOUT(device, byte) {_SEQ_NEEDBUF(4);\
- _seqbuf[_seqbufptr] = SEQ_MIDIPUTC;\
- _seqbuf[_seqbufptr+1] = (byte);\
- _seqbuf[_seqbufptr+2] = (device);\
- _seqbuf[_seqbufptr+3] = 0;\
- _SEQ_ADVBUF(4);}
-#define SEQ_WRPATCH(patch, len) {if (_seqbufptr) seqbuf_dump();\
- if (write(seqfd, (char*)(patch), len)==-1) \
- perror("Write patch: /dev/sequencer");}
-
-#endif
-long soundcard_init(long mem_start);
-#endif
diff --git a/drivers/sound/ultrasound.h b/drivers/sound/ultrasound.h
index 745e007..e69de29 100644
--- a/drivers/sound/ultrasound.h
+++ b/drivers/sound/ultrasound.h
@@ -1,118 +0,0 @@
-#ifndef _ULTRASOUND_H_
-#define _ULTRASOUND_H_
-/*
- * Copyright by Hannu Savolainen 1993
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-/*
- * ultrasound.h - Macros for programming the Gravis Ultrasound
- * These macros are extremely device dependent
- * and not portable.
- */
-
-/*
- * Private events for Gravis Ultrasound (GUS)
- *
- * Format:
- * byte 0 - SEQ_PRIVATE (0xfe)
- * byte 1 - Synthesizer device number (0-N)
- * byte 2 - Command (see below)
- * byte 3 - Voice number (0-31)
- * bytes 4 and 5 - parameter P1 (unsigned short)
- * bytes 6 and 7 - parameter P2 (unsigned short)
- *
- * Commands:
- * Each command affects one voice defined in byte 3.
- * Unused parameters (P1 and/or P2 *MUST* be initialized to zero).
- * _GUS_NUMVOICES - Sets max. number of concurrent voices (P1=14-31, default 16)
- * _GUS_VOICESAMPLE- ************ OBSOLETE *************
- * _GUS_VOICEON - Starts voice (P1=voice mode)
- * _GUS_VOICEOFF - Stops voice (no parameters)
- * _GUS_VOICEFADE - Stops the voice smoothly.
- * _GUS_VOICEMODE - Alters the voice mode, don't start or stop voice (P1=voice mode)
- * _GUS_VOICEBALA - Sets voice balence (P1, 0=left, 7=middle and 15=right, default 7)
- * _GUS_VOICEFREQ - Sets voice (sample) playback frequency (P1=Hz)
- * _GUS_VOICEVOL - Sets voice volume (P1=volume, 0xfff=max, 0xeff=half, 0x000=off)
- * _GUS_VOICEVOL2 - Sets voice volume (P1=volume, 0xfff=max, 0xeff=half, 0x000=off)
- * (Like GUS_VOICEVOL but doesn't change the hw
- * volume. It just updates volume in the voice table).
- *
- * _GUS_RAMPRANGE - Sets limits for volume ramping (P1=low volume, P2=high volume)
- * _GUS_RAMPRATE - Sets the speed for volume ramping (P1=scale, P2=rate)
- * _GUS_RAMPMODE - Sets the volume ramping mode (P1=ramping mode)
- * _GUS_RAMPON - Starts volume ramping (no parameters)
- * _GUS_RAMPOFF - Stops volume ramping (no parameters)
- * _GUS_VOLUME_SCALE - Changes the volume calculation constants
- * for all voices.
- */
-
-#define _GUS_NUMVOICES 0x00
-#define _GUS_VOICESAMPLE 0x01 /* OBSOLETE */
-#define _GUS_VOICEON 0x02
-#define _GUS_VOICEOFF 0x03
-#define _GUS_VOICEMODE 0x04
-#define _GUS_VOICEBALA 0x05
-#define _GUS_VOICEFREQ 0x06
-#define _GUS_VOICEVOL 0x07
-#define _GUS_RAMPRANGE 0x08
-#define _GUS_RAMPRATE 0x09
-#define _GUS_RAMPMODE 0x0a
-#define _GUS_RAMPON 0x0b
-#define _GUS_RAMPOFF 0x0c
-#define _GUS_VOICEFADE 0x0d
-#define _GUS_VOLUME_SCALE 0x0e
-#define _GUS_VOICEVOL2 0x0f
-
-/*
- * GUS API macros
- */
-
-#define _GUS_CMD(chn, voice, cmd, p1, p2) \
- {_SEQ_NEEDBUF(8); _seqbuf[_seqbufptr] = SEQ_PRIVATE;\
- _seqbuf[_seqbufptr+1] = (chn); _seqbuf[_seqbufptr+2] = cmd;\
- _seqbuf[_seqbufptr+3] = voice;\
- *(unsigned short*)&_seqbuf[_seqbufptr+4] = p1;\
- *(unsigned short*)&_seqbuf[_seqbufptr+6] = p2;\
- _SEQ_ADVBUF(8);}
-
-#define GUS_NUMVOICES(chn, p1) _GUS_CMD(chn, 0, _GUS_NUMVOICES, (p1), 0)
-#define GUS_VOICESAMPLE(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICESAMPLE, (p1), 0) /* OBSOLETE */
-#define GUS_VOICEON(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEON, (p1), 0)
-#define GUS_VOICEOFF(chn, voice) _GUS_CMD(chn, voice, _GUS_VOICEOFF, 0, 0)
-#define GUS_VOICEFADE(chn, voice) _GUS_CMD(chn, voice, _GUS_VOICEFADE, 0, 0)
-#define GUS_VOICEMODE(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEMODE, (p1), 0)
-#define GUS_VOICEBALA(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEBALA, (p1), 0)
-#define GUS_VOICEFREQ(chn, voice, p) _GUS_CMD(chn, voice, _GUS_VOICEFREQ, \
- (p) & 0xffff, ((p) >> 16) & 0xffff)
-#define GUS_VOICEVOL(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEVOL, (p1), 0)
-#define GUS_VOICEVOL2(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEVOL2, (p1), 0)
-#define GUS_RAMPRANGE(chn, voice, low, high) _GUS_CMD(chn, voice, _GUS_RAMPRANGE, (low), (high))
-#define GUS_RAMPRATE(chn, voice, p1, p2) _GUS_CMD(chn, voice, _GUS_RAMPRATE, (p1), (p2))
-#define GUS_RAMPMODE(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_RAMPMODE, (p1), 0)
-#define GUS_RAMPON(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_RAMPON, (p1), 0)
-#define GUS_RAMPOFF(chn, voice) _GUS_CMD(chn, voice, _GUS_RAMPOFF, 0, 0)
-#define GUS_VOLUME_SCALE(chn, voice, p1, p2) _GUS_CMD(chn, voice, _GUS_VOLUME_SCALE, (p1), (p2))
-
-#endif
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index e8a3513..2d44fb1 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -32,7 +32,9 @@
#define ETH_P_IP 0x0800 /* Internet Protocol packet */
#define ETH_P_ARP 0x0806 /* Address Resolution packet */
#define ETH_P_RARP 0x0835 /* Reverse Addr Res packet */
+#define ETH_P_IPX 0x8137 /* IPX over DIX */
#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */
+#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */
/* Define the Ethernet Broadcast Address (48 bits set to "1"). */
#define ETH_A_BCAST "\377\377\377\377\377\377"
diff --git a/include/linux/major.h b/include/linux/major.h
index 463d1ae..a37d7a5 100644
--- a/include/linux/major.h
+++ b/include/linux/major.h
@@ -41,6 +41,7 @@
* 21 - scsi generic
* 22 - UNUSED
* 23 - mitsumi cdrom
+ * 24 - sony535 cdrom
*/
#define UNNAMED_MAJOR 0
@@ -66,6 +67,7 @@
#define SCSI_GENERIC_MAJOR 21
/* unused: 22 */
#define MITSUMI_CDROM_MAJOR 23
+#define SONY535_CDROM_MAJOR 24
/*
* Tests for SCSI devices.
diff --git a/include/linux/soundcard.h b/include/linux/soundcard.h
new file mode 100644
index 0000000..9af627b
--- /dev/null
+++ b/include/linux/soundcard.h
@@ -0,0 +1,741 @@
+#ifndef SOUNDCARD_H
+#define SOUNDCARD_H
+/*
+ * Copyright by Hannu Savolainen 1993
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *
+ */
+
+ /*
+ * If you make modifications to this file, please contact me before
+ * distributing the modified version. There is already enough
+ * divercity in the world.
+ *
+ * Regards,
+ * Hannu Savolainen
+ * hsavolai@cs.helsinki.fi
+ */
+
+#define SOUND_VERSION 200
+
+#include <sys/ioctl.h>
+
+/*
+ * Supported card ID numbers (Should be somewhere else?)
+ */
+
+#define SNDCARD_ADLIB 1
+#define SNDCARD_SB 2
+#define SNDCARD_PAS 3
+#define SNDCARD_GUS 4
+#define SNDCARD_MPU401 5
+#define SNDCARD_SB16 6
+
+/***********************************
+ * IOCTL Commands for /dev/sequencer
+ */
+
+#ifndef _IOWR
+/* @(#)ioctlp.h */
+
+/* Ioctl's have the command encoded in the lower word,
+ * and the size of any in or out parameters in the upper
+ * word. The high 2 bits of the upper word are used
+ * to encode the in/out status of the parameter; for now
+ * we restrict parameters to at most 128 bytes.
+ */
+/* #define IOCTYPE (0xff<<8) */
+#define IOCPARM_MASK 0x7f /* parameters must be < 128 bytes */
+#define IOC_VOID 0x20000000 /* no parameters */
+#define IOC_OUT 0x40000000 /* copy out parameters */
+#define IOC_IN 0x80000000 /* copy in parameters */
+#define IOC_INOUT (IOC_IN|IOC_OUT)
+/* the 0x20000000 is so we can distinguish new ioctl's from old */
+#define _IO(x,y) ((int)(IOC_VOID|(x<<8)|y))
+#define _IOR(x,y,t) ((int)(IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y))
+#define _IOW(x,y,t) ((int)(IOC_IN|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y))
+/* this should be _IORW, but stdio got there first */
+#define _IOWR(x,y,t) ((int)(IOC_INOUT|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y))
+#endif /* !_IOWR */
+
+#define SNDCTL_SEQ_RESET _IO ('Q', 0)
+#define SNDCTL_SEQ_SYNC _IO ('Q', 1)
+#define SNDCTL_SYNTH_INFO _IOWR('Q', 2, struct synth_info)
+#define SNDCTL_SEQ_CTRLRATE _IOWR('Q', 3, int) /* Set/get timer resolution (HZ) */
+#define SNDCTL_SEQ_GETOUTCOUNT _IOR ('Q', 4, int)
+#define SNDCTL_SEQ_GETINCOUNT _IOR ('Q', 5, int)
+#define SNDCTL_SEQ_PERCMODE _IOW ('Q', 6, int)
+#define SNDCTL_FM_LOAD_INSTR _IOW ('Q', 7, struct sbi_instrument) /* Valid for FM only */
+#define SNDCTL_SEQ_TESTMIDI _IOW ('Q', 8, int)
+#define SNDCTL_SEQ_RESETSAMPLES _IOW ('Q', 9, int)
+#define SNDCTL_SEQ_NRSYNTHS _IOR ('Q',10, int)
+#define SNDCTL_SEQ_NRMIDIS _IOR ('Q',11, int)
+#define SNDCTL_MIDI_INFO _IOWR('Q',12, struct midi_info)
+#define SNDCTL_SEQ_TRESHOLD _IOW ('Q',13, int)
+#define SNDCTL_SYNTH_MEMAVL _IOWR('Q',14, int) /* in=dev#, out=memsize */
+#define SNDCTL_FM_4OP_ENABLE _IOW ('Q',15, int) /* in=dev# */
+#define SNDCTL_PMGR_ACCESS _IOWR('Q',16, struct patmgr_info)
+
+/*
+ * Sample loading mechanism for internal synthesizers (/dev/sequencer)
+ * The following patch_info structure has been designed to support
+ * Gravis UltraSound. It tries to be universal format for uploading
+ * sample based patches but is propably too limited.
+ */
+
+struct patch_info {
+ short key; /* Use GUS_PATCH here */
+#define GUS_PATCH 0x04fd
+#define OBSOLETE_GUS_PATCH 0x02fd
+ short device_no; /* Synthesizer number */
+ short instr_no; /* Midi pgm# */
+
+ unsigned long mode;
+/*
+ * The least significant byte has the same format than the GUS .PAT
+ * files
+ */
+#define WAVE_16_BITS 0x01 /* bit 0 = 8 or 16 bit wave data. */
+#define WAVE_UNSIGNED 0x02 /* bit 1 = Signed - Unsigned data. */
+#define WAVE_LOOPING 0x04 /* bit 2 = looping enabled-1. */
+#define WAVE_BIDIR_LOOP 0x08 /* bit 3 = Set is bidirectional looping. */
+#define WAVE_LOOP_BACK 0x10 /* bit 4 = Set is looping backward. */
+#define WAVE_SUSTAIN_ON 0x20 /* bit 5 = Turn sustaining on. (Env. pts. 3)*/
+#define WAVE_ENVELOPES 0x40 /* bit 6 = Enable envelopes - 1 */
+ /* (use the env_rate/env_offs fields). */
+/* Linux specific bits */
+#define WAVE_VIBRATO 0x00010000 /* The vibrato info is valid */
+#define WAVE_TREMOLO 0x00020000 /* The tremolo info is valid */
+#define WAVE_SCALE 0x00040000 /* The scaling info is valid */
+/* Other bits must be zeroed */
+
+ long len; /* Size of the wave data in bytes */
+ long loop_start, loop_end; /* Byte offsets from the beginning */
+
+/*
+ * The base_freq and base_note fields are used when computing the
+ * playback speed for a note. The base_note defines the tone frequency
+ * which is heard if the sample is played using the base_freq as the
+ * playback speed.
+ *
+ * The low_note and high_note fields define the minimum and maximum note
+ * frequencies for which this sample is valid. It is possible to define
+ * more than one samples for a instrument number at the same time. The
+ * low_note and high_note fields are used to select the most suitable one.
+ *
+ * The fields base_note, high_note and low_note should contain
+ * the note frequency multiplied by 1000. For example value for the
+ * middle A is 440*1000.
+ */
+
+ unsigned int base_freq;
+ unsigned long base_note;
+ unsigned long high_note;
+ unsigned long low_note;
+ int panning; /* -128=left, 127=right */
+ int detuning;
+
+/* New fields introduced in version 1.99.5 */
+
+ /* Envelope. Enabled by mode bit WAVE_ENVELOPES */
+ unsigned char env_rate[ 6 ]; /* GUS HW ramping rate */
+ unsigned char env_offset[ 6 ]; /* 255 == 100% */
+
+ /*
+ * The tremolo, vibrato and scale info are not supported yet.
+ * Enable by setting the mode bits WAVE_TREMOLO, WAVE_VIBRATO or
+ * WAVE_SCALE
+ */
+
+ unsigned char tremolo_sweep;
+ unsigned char tremolo_rate;
+ unsigned char tremolo_depth;
+
+ unsigned char vibrato_sweep;
+ unsigned char vibrato_rate;
+ unsigned char vibrato_depth;
+
+ int scale_frequency;
+ unsigned int scale_factor; /* from 0 to 2048 or 0 to 2 */
+
+ int volume;
+ int spare[4];
+ char data[1]; /* The waveform data starts here */
+ };
+
+
+/*
+ * Patch management interface (/dev/sequencer, /dev/patmgr#)
+ * Don't use these calls if you want to maintain compatibility with
+ * the future versions of the driver.
+ */
+
+#define PS_NO_PATCHES 0 /* No patch support on device */
+#define PS_MGR_NOT_OK 1 /* Plain patch support (no mgr) */
+#define PS_MGR_OK 2 /* Patch manager supported */
+#define PS_MANAGED 3 /* Patch manager running */
+
+#define SNDCTL_PMGR_IFACE _IOWR('P', 1, struct patmgr_info)
+
+/*
+ * The patmgr_info is a fixed size structure which is used for two
+ * different purposes. The intended use is for communication between
+ * the application using /dev/sequencer and the patch manager daemon
+ * associated with a synthesizer device (ioctl(SNDCTL_PMGR_ACCESS)).
+ *
+ * This structure is also used with ioctl(SNDCTL_PGMR_IFACE) which allows
+ * a patch manager daemon to read and write device parameters. This
+ * ioctl available through /dev/sequencer also. Avoid using it since it's
+ * extremely hardware dependent. In addition access trough /dev/sequencer
+ * may confuse the patch manager daemon.
+ */
+
+struct patmgr_info { /* Note! size must be < 4k since kmalloc() is used */
+ unsigned long key; /* Don't worry. Reserved for communication
+ between the patch manager and the driver. */
+#define PM_K_EVENT 1 /* Event from the /dev/sequencer driver */
+#define PM_K_COMMAND 2 /* Request from a application */
+#define PM_K_RESPONSE 3 /* From patmgr to application */
+#define PM_ERROR 4 /* Error returned by the patmgr */
+ int device;
+ int command;
+
+/*
+ * Commands 0x000 to 0xfff reserved for patch manager programs
+ */
+#define PM_GET_DEVTYPE 1 /* Returns type of the patch mgr interface of dev */
+#define PMTYPE_FM2 1 /* 2 OP fm */
+#define PMTYPE_FM4 2 /* Mixed 4 or 2 op FM (OPL-3) */
+#define PMTYPE_WAVE 3 /* Wave table synthesizer (GUS) */
+#define PM_GET_NRPGM 2 /* Returns max # of midi programs in parm1 */
+#define PM_GET_PGMMAP 3 /* Returns map of loaded midi programs in data8 */
+#define PM_GET_PGM_PATCHES 4 /* Return list of patches of a program (parm1) */
+#define PM_GET_PATCH 5 /* Return patch header of patch parm1 */
+#define PM_SET_PATCH 6 /* Set patch header of patch parm1 */
+#define PM_READ_PATCH 7 /* Read patch (wave) data */
+#define PM_WRITE_PATCH 8 /* Write patch (wave) data */
+
+/*
+ * Commands 0x1000 to 0xffff are for communication between the patch manager
+ * and the client
+ */
+#define _PM_LOAD_PATCH 0x100
+
+/*
+ * Commands above 0xffff reserved for device specific use
+ */
+
+ long parm1;
+ long parm2;
+ long parm3;
+
+ union {
+ unsigned char data8[4000];
+ unsigned short data16[2000];
+ unsigned long data32[1000];
+ struct patch_info patch;
+ } data;
+ };
+
+/*
+ * When a patch manager daemon is present, it will be informed by the
+ * driver when something important happens. For example when the
+ * /dev/sequencer is opened or closed. A record with key == PM_K_EVENT is
+ * returned. The command field contains the event type:
+ */
+#define PM_E_OPENED 1 /* /dev/sequencer opened */
+#define PM_E_CLOSED 2 /* /dev/sequencer closed */
+#define PM_E_PATCH_RESET 3 /* SNDCTL_RESETSAMPLES called */
+#define PM_E_PATCH_LOADED 4 /* A patch has been loaded by appl */
+
+/*
+ * /dev/sequencer input events.
+ *
+ * The data written to the /dev/sequencer is a stream of events. Events
+ * are records of 4 or 8 bytes. The first byte defines the size.
+ * Any number of events can be written with a write call. There
+ * is a set of macros for sending these events. Use these macros if you
+ * want to maximize portability of your program.
+ *
+ * Events SEQ_WAIT, SEQ_MIDIPUTC and SEQ_ECHO. Are also input events.
+ * (All input events are currently 4 bytes long. Be prepared to support
+ * 8 byte events also. If you receive any event having first byte >= 0xf0,
+ * it's a 8 byte event.
+ *
+ * The events are documented at the end of this file.
+ *
+ * Normal events (4 bytes)
+ * There is also a 8 byte version of most of the 4 byte events. The
+ * 8 byte one is recommended.
+ */
+#define SEQ_NOTEOFF 0
+#define SEQ_FMNOTEOFF SEQ_NOTEOFF /* Just old name */
+#define SEQ_NOTEON 1
+#define SEQ_FMNOTEON SEQ_NOTEON
+#define SEQ_WAIT 2
+#define SEQ_PGMCHANGE 3
+#define SEQ_FMPGMCHANGE SEQ_PGMCHANGE
+#define SEQ_SYNCTIMER 4
+#define SEQ_MIDIPUTC 5
+#define SEQ_DRUMON 6 /*** OBSOLETE ***/
+#define SEQ_DRUMOFF 7 /*** OBSOLETE ***/
+#define SEQ_ECHO 8 /* For synching programs with output */
+#define SEQ_AFTERTOUCH 9
+#define SEQ_CONTROLLER 10
+#define CTRL_PITCH_BENDER 255
+#define CTRL_PITCH_BENDER_RANGE 254
+#define CTRL_EXPRESSION 253
+#define CTRL_MAIN_VOLUME 252
+#define SEQ_BALANCE 11
+
+/*
+ * Note! SEQ_WAIT, SEQ_MIDIPUTC and SEQ_ECHO are used also as
+ * input events.
+ */
+
+/*
+ * Event codes 0xf0 to 0xfc are reserved for future extensions.
+ */
+
+#define SEQ_FULLSIZE 0xfd /* Long events */
+/*
+ * SEQ_FULLSIZE events are used for loading patches/samples to the
+ * synthesizer devices. These events are passed directly to the driver
+ * of the associated synthesizer device. There is no limit to the size
+ * of the extended events. These events are not queued but executed
+ * immediately when the write() is called (execution can take several
+ * seconds of time).
+ *
+ * When a SEQ_FULLSIZE message is written to the device, it must
+ * be written using exactly one write() call. Other events cannot
+ * be mixed to the same write.
+ *
+ * For FM synths (YM3812/OPL3) use struct sbi_instrument and write it to the
+ * /dev/sequencer. Don't write other data together with the instrument structure
+ * Set the key field of the structure to FM_PATCH. The device field is used to
+ * route the patch to the corresponding device.
+ *
+ * For Gravis UltraSound use struct patch_info. Initialize the key field
+ * to GUS_PATCH.
+ */
+#define SEQ_PRIVATE 0xfe /* Low level HW dependent events (8 bytes) */
+#define SEQ_EXTENDED 0xff /* Extended events (8 bytes) */
+
+/*
+ * Extended events for synthesizers (8 bytes)
+ *
+ * Format:
+ *
+ * b0 = SEQ_EXTENDED
+ * b1 = command
+ * b2 = device
+ * b3-b7 = parameters
+ *
+ * Command b3 b4 b5 b6 b7
+ * ----------------------------------------------------------------------------
+ * SEQ_NOTEON voice note volume 0 0
+ * SEQ_NOTEOFF voice note volume 0 0
+ * SEQ_PGMCHANGE voice pgm 0 0 0
+ * SEQ_DRUMON (voice) drum# volume 0 0
+ * SEQ_DRUMOFF (voice) drum# volume 0 0
+ */
+
+/*
+ * Record for FM patches
+ */
+
+typedef unsigned char sbi_instr_data[32];
+
+struct sbi_instrument {
+ unsigned short key; /* Initialize to FM_PATCH or OPL3_PATCH */
+#define FM_PATCH 0x01fd
+#define OPL3_PATCH 0x03fd
+ short device; /* Synth# (0-4) */
+ int channel; /* Program# to be initialized */
+ sbi_instr_data operators; /* Register settings for operator cells (.SBI format) */
+ };
+
+struct synth_info { /* Read only */
+ char name[30];
+ int device; /* 0-N. INITIALIZE BEFORE CALLING */
+ int synth_type;
+#define SYNTH_TYPE_FM 0
+#define SYNTH_TYPE_SAMPLE 1
+
+ int synth_subtype;
+#define FM_TYPE_ADLIB 0x00
+#define FM_TYPE_OPL3 0x01
+
+#define SAMPLE_TYPE_GUS 0x10
+
+ int perc_mode; /* No longer supported */
+ int nr_voices;
+ int nr_drums; /* Obsolete field */
+ int instr_bank_size;
+ unsigned long capabilities;
+#define SYNTH_CAP_PERCMODE 0x00000001 /* No longer used */
+#define SYNTH_CAP_OPL3 0x00000002 /* Set if OPL3 supported */
+ int dummies[19]; /* Reserve space */
+ };
+
+struct midi_info {
+ char name[30];
+ int device; /* 0-N. INITIALIZE BEFORE CALLING */
+ unsigned long capabilities; /* To be defined later */
+ int dev_type;
+ int dummies[18]; /* Reserve space */
+ };
+
+/********************************************
+ * IOCTL commands for /dev/dsp and /dev/audio
+ */
+
+#define SNDCTL_DSP_RESET _IO ('P', 0)
+#define SNDCTL_DSP_SYNC _IO ('P', 1)
+#define SNDCTL_DSP_SPEED _IOWR('P', 2, int)
+#define SNDCTL_DSP_STEREO _IOWR('P', 3, int)
+#define SNDCTL_DSP_GETBLKSIZE _IOWR('P', 4, int)
+#define SNDCTL_DSP_SAMPLESIZE _IOWR('P', 5, int) /* 8, 12 or 16 */
+#define SOUND_PCM_WRITE_CHANNELS _IOWR('P', 6, int)
+#define SOUND_PCM_WRITE_FILTER _IOWR('P', 7, int)
+#define SNDCTL_DSP_POST _IO ('P', 8)
+#define SNDCTL_DSP_SUBDIVIDE _IOWR('P', 9, int)
+
+#define SOUND_PCM_READ_RATE _IOR ('P', 2, int)
+#define SOUND_PCM_READ_CHANNELS _IOR ('P', 6, int)
+#define SOUND_PCM_READ_BITS _IOR ('P', 5, int)
+#define SOUND_PCM_READ_FILTER _IOR ('P', 7, int)
+
+/* Some alias names */
+#define SOUND_PCM_WRITE_BITS SNDCTL_DSP_SAMPLESIZE
+#define SOUND_PCM_WRITE_RATE SNDCTL_DSP_SPEED
+#define SOUND_PCM_POST SNDCTL_DSP_POST
+#define SOUND_PCM_RESET SNDCTL_DSP_RESET
+#define SOUND_PCM_SYNC SNDCTL_DSP_SYNC
+#define SOUND_PCM_SUBDIVIDE SNDCTL_DSP_SUBDIVIDE
+
+/*********************************************
+ * IOCTL commands for /dev/mixer
+ */
+
+/*
+ * Mixer devices
+ *
+ * There can be up to 20 different analog mixer channels. The
+ * SOUND_MIXER_NRDEVICES gives the currently supported maximum.
+ * The SOUND_MIXER_READ_DEVMASK returns a bitmask which tells
+ * the devices supported by the particular mixer.
+ */
+
+#define SOUND_MIXER_NRDEVICES 12
+#define SOUND_MIXER_VOLUME 0
+#define SOUND_MIXER_BASS 1
+#define SOUND_MIXER_TREBLE 2
+#define SOUND_MIXER_SYNTH 3
+#define SOUND_MIXER_PCM 4
+#define SOUND_MIXER_SPEAKER 5
+#define SOUND_MIXER_LINE 6
+#define SOUND_MIXER_MIC 7
+#define SOUND_MIXER_CD 8
+#define SOUND_MIXER_IMIX 9 /* Recording monitor */
+#define SOUND_MIXER_ALTPCM 10
+#define SOUND_MIXER_RECLEV 11 /* Recording level */
+
+/* Some on/off settings (SOUND_SPECIAL_MIN - SOUND_SPECIAL_MAX) */
+/* Not counted to SOUND_MIXER_NRDEVICES, but use the same number space */
+#define SOUND_ONOFF_MIN 28
+#define SOUND_ONOFF_MAX 30
+#define SOUND_MIXER_MUTE 28 /* 0 or 1 */
+#define SOUND_MIXER_ENHANCE 29 /* Enhanced stereo (0, 40, 60 or 80) */
+#define SOUND_MIXER_LOUD 30 /* 0 or 1 */
+
+/* Note! Number 31 cannot be used since the sign bit is reserved */
+
+#define SOUND_DEVICE_LABELS {"Vol ", "Bass ", "Trebl", "Synth", "Pcm ", "Spkr ", "Line ", \
+ "Mic ", "CD ", "Mix ", "Pcm2 ", "rec"}
+
+#define SOUND_DEVICE_NAMES {"vol", "bass", "treble", "synth", "pcm", "speaker", "line", \
+ "mic", "cd", "mix", "pcm2", "rec"}
+
+/* Device bitmask identifiers */
+
+#define SOUND_MIXER_RECSRC 0xff /* Arg contains a bit for each recording source */
+#define SOUND_MIXER_DEVMASK 0xfe /* Arg contains a bit for each supported device */
+#define SOUND_MIXER_RECMASK 0xfd /* Arg contains a bit for each supported recording source */
+#define SOUND_MIXER_CAPS 0xfc
+ #define SOUND_CAP_EXCL_INPUT 0x00000001 /* Only one recording source at a time */
+#define SOUND_MIXER_STEREODEVS 0xfb /* Mixer channels supporting stereo */
+
+/* Device mask bits */
+
+#define SOUND_MASK_VOLUME (1 << SOUND_MIXER_VOLUME)
+#define SOUND_MASK_BASS (1 << SOUND_MIXER_BASS)
+#define SOUND_MASK_TREBLE (1 << SOUND_MIXER_TREBLE)
+#define SOUND_MASK_SYNTH (1 << SOUND_MIXER_SYNTH)
+#define SOUND_MASK_PCM (1 << SOUND_MIXER_PCM)
+#define SOUND_MASK_SPEAKER (1 << SOUND_MIXER_SPEAKER)
+#define SOUND_MASK_LINE (1 << SOUND_MIXER_LINE)
+#define SOUND_MASK_MIC (1 << SOUND_MIXER_MIC)
+#define SOUND_MASK_CD (1 << SOUND_MIXER_CD)
+#define SOUND_MASK_IMIX (1 << SOUND_MIXER_IMIX)
+#define SOUND_MASK_ALTPCM (1 << SOUND_MIXER_ALTPCM)
+#define SOUND_MASK_RECLEV (1 << SOUND_MIXER_RECLEV)
+
+#define SOUND_MASK_MUTE (1 << SOUND_MIXER_MUTE)
+#define SOUND_MASK_ENHANCE (1 << SOUND_MIXER_ENHANCE)
+#define SOUND_MASK_LOUD (1 << SOUND_MIXER_LOUD)
+
+#define MIXER_READ(dev) _IOR('M', dev, int)
+#define SOUND_MIXER_READ_VOLUME MIXER_READ(SOUND_MIXER_VOLUME)
+#define SOUND_MIXER_READ_BASS MIXER_READ(SOUND_MIXER_BASS)
+#define SOUND_MIXER_READ_TREBLE MIXER_READ(SOUND_MIXER_TREBLE)
+#define SOUND_MIXER_READ_SYNTH MIXER_READ(SOUND_MIXER_SYNTH)
+#define SOUND_MIXER_READ_PCM MIXER_READ(SOUND_MIXER_PCM)
+#define SOUND_MIXER_READ_SPEAKER MIXER_READ(SOUND_MIXER_SPEAKER)
+#define SOUND_MIXER_READ_LINE MIXER_READ(SOUND_MIXER_LINE)
+#define SOUND_MIXER_READ_MIC MIXER_READ(SOUND_MIXER_MIC)
+#define SOUND_MIXER_READ_CD MIXER_READ(SOUND_MIXER_CD)
+#define SOUND_MIXER_READ_IMIX MIXER_READ(SOUND_MIXER_IMIX)
+#define SOUND_MIXER_READ_ALTPCM MIXER_READ(SOUND_MIXER_ALTPCM)
+#define SOUND_MIXER_READ_RECLEV MIXER_READ(SOUND_MIXER_RECLEV)
+#define SOUND_MIXER_READ_MUTE MIXER_READ(SOUND_MIXER_MUTE)
+#define SOUND_MIXER_READ_ENHANCE MIXER_READ(SOUND_MIXER_ENHANCE)
+#define SOUND_MIXER_READ_LOUD MIXER_READ(SOUND_MIXER_LOUD)
+
+#define SOUND_MIXER_READ_RECSRC MIXER_READ(SOUND_MIXER_RECSRC)
+#define SOUND_MIXER_READ_DEVMASK MIXER_READ(SOUND_MIXER_DEVMASK)
+#define SOUND_MIXER_READ_RECMASK MIXER_READ(SOUND_MIXER_RECMASK)
+#define SOUND_MIXER_READ_STEREODEVS MIXER_READ(SOUND_MIXER_STEREODEVS)
+#define SOUND_MIXER_READ_CAPS MIXER_READ(SOUND_MIXER_CAPS)
+
+#define MIXER_WRITE(dev) _IOWR('M', dev, int)
+#define SOUND_MIXER_WRITE_VOLUME MIXER_WRITE(SOUND_MIXER_VOLUME)
+#define SOUND_MIXER_WRITE_BASS MIXER_WRITE(SOUND_MIXER_BASS)
+#define SOUND_MIXER_WRITE_TREBLE MIXER_WRITE(SOUND_MIXER_TREBLE)
+#define SOUND_MIXER_WRITE_SYNTH MIXER_WRITE(SOUND_MIXER_SYNTH)
+#define SOUND_MIXER_WRITE_PCM MIXER_WRITE(SOUND_MIXER_PCM)
+#define SOUND_MIXER_WRITE_SPEAKER MIXER_WRITE(SOUND_MIXER_SPEAKER)
+#define SOUND_MIXER_WRITE_LINE MIXER_WRITE(SOUND_MIXER_LINE)
+#define SOUND_MIXER_WRITE_MIC MIXER_WRITE(SOUND_MIXER_MIC)
+#define SOUND_MIXER_WRITE_CD MIXER_WRITE(SOUND_MIXER_CD)
+#define SOUND_MIXER_WRITE_IMIX MIXER_WRITE(SOUND_MIXER_IMIX)
+#define SOUND_MIXER_WRITE_ALTPCM MIXER_WRITE(SOUND_MIXER_ALTPCM)
+#define SOUND_MIXER_WRITE_RECLEV MIXER_WRITE(SOUND_MIXER_RECLEV)
+#define SOUND_MIXER_WRITE_MUTE MIXER_WRITE(SOUND_MIXER_MUTE)
+#define SOUND_MIXER_WRITE_ENHANCE MIXER_WRITE(SOUND_MIXER_ENHANCE)
+#define SOUND_MIXER_WRITE_LOUD MIXER_WRITE(SOUND_MIXER_LOUD)
+
+#define SOUND_MIXER_WRITE_RECSRC MIXER_WRITE(SOUND_MIXER_RECSRC)
+
+/*
+ * The following mixer ioctl calls are compatible with the BSD driver by
+ * Steve Haehnichen <shaehnic@ucsd.edu>
+ *
+ * Since this interface is entirely SB specific, it will be dropped in the
+ * near future.
+ */
+
+typedef unsigned char S_BYTE;
+typedef unsigned char S_FLAG;
+struct stereo_vol
+{
+ S_BYTE l; /* Left volume */
+ S_BYTE r; /* Right volume */
+};
+
+#define MIXER_IOCTL_SET_LEVELS _IOW ('s', 20, struct sb_mixer_levels)
+#define MIXER_IOCTL_SET_PARAMS _IOW ('s', 21, struct sb_mixer_params)
+#define MIXER_IOCTL_READ_LEVELS _IOR ('s', 22, struct sb_mixer_levels)
+#define MIXER_IOCTL_READ_PARAMS _IOR ('s', 23, struct sb_mixer_params)
+#define MIXER_IOCTL_RESET _IO ('s', 24)
+
+/*
+ * Mixer volume levels for MIXER_IOCTL_SET_VOL & MIXER_IOCTL_READ_VOL
+ */
+struct sb_mixer_levels
+{
+ struct stereo_vol master; /* Master volume */
+ struct stereo_vol voc; /* DSP Voice volume */
+ struct stereo_vol fm; /* FM volume */
+ struct stereo_vol line; /* Line-in volume */
+ struct stereo_vol cd; /* CD audio */
+ S_BYTE mic; /* Microphone level */
+};
+
+/*
+ * Mixer parameters for MIXER_IOCTL_SET_PARAMS & MIXER_IOCTL_READ_PARAMS
+ */
+struct sb_mixer_params
+{
+ S_BYTE record_source; /* Recording source (See SRC_xxx below) */
+ S_FLAG hifreq_filter; /* Filter frequency (hi/low) */
+ S_FLAG filter_input; /* ANFI input filter */
+ S_FLAG filter_output; /* DNFI output filter */
+ S_FLAG dsp_stereo; /* 1 if DSP is in Stereo mode */
+};
+
+#define SRC_MIC 1 /* Select Microphone recording source */
+#define SRC_CD 3 /* Select CD recording source */
+#define SRC_LINE 7 /* Use Line-in for recording source */
+
+#if !defined(KERNEL) && !defined(INKERNEL)
+/*
+ * Some convenience macros to simplify programming of the
+ * /dev/sequencer interface
+ *
+ * These macros define the API which should be used when possible.
+ */
+
+void seqbuf_dump(void); /* This function must be provided by programs */
+
+/* Sample seqbuf_dump() implementation:
+ *
+ * SEQ_DEFINEBUF (2048); -- Defines a buffer for 2048 bytes
+ *
+ * int seqfd; -- The file descriptor for /dev/sequencer.
+ *
+ * void
+ * seqbuf_dump ()
+ * {
+ * if (_seqbufptr)
+ * if (write (seqfd, _seqbuf, _seqbufptr) == -1)
+ * {
+ * perror ("write /dev/sequencer");
+ * exit (-1);
+ * }
+ * _seqbufptr = 0;
+ * }
+ */
+
+#define SEQ_DEFINEBUF(len) unsigned char _seqbuf[len]; int _seqbuflen = len, _seqbufptr = 0
+#define SEQ_PM_DEFINES struct patmgr_info _pm_info
+#define _SEQ_NEEDBUF(len) if ((_seqbufptr+(len)) > _seqbuflen) seqbuf_dump()
+#define _SEQ_ADVBUF(len) _seqbufptr += len
+#define SEQ_DUMPBUF seqbuf_dump
+#define PM_LOAD_PATCH(dev, bank, pgm) (SEQ_DUMPBUF(), _pm_info.command = _PM_LOAD_PATCH, \
+ _pm_info.device=dev, _pm_info.data.data8[0]=pgm, \
+ _pm_info.parm1 = bank, _pm_info.parm2 = 1, \
+ ioctl(seqfd, SNDCTL_PMGR_ACCESS, &_pm_info))
+#define PM_LOAD_PATCHES(dev, bank, pgm) (SEQ_DUMPBUF(), _pm_info.command = _PM_LOAD_PATCH, \
+ _pm_info.device=dev, memcpy(_pm_info.data.data8, pgm, 128), \
+ _pm_info.parm1 = bank, _pm_info.parm2 = 128, \
+ ioctl(seqfd, SNDCTL_PMGR_ACCESS, &_pm_info))
+
+#define SEQ_START_NOTE(dev, voice, note, vol) {_SEQ_NEEDBUF(8);\
+ _seqbuf[_seqbufptr] = SEQ_EXTENDED;\
+ _seqbuf[_seqbufptr+1] = SEQ_NOTEON;\
+ _seqbuf[_seqbufptr+2] = (dev);\
+ _seqbuf[_seqbufptr+3] = (voice);\
+ _seqbuf[_seqbufptr+4] = (note);\
+ _seqbuf[_seqbufptr+5] = (vol);\
+ _seqbuf[_seqbufptr+6] = 0;\
+ _seqbuf[_seqbufptr+7] = 0;\
+ _SEQ_ADVBUF(8);}
+
+#define SEQ_STOP_NOTE(dev, voice, note, vol) {_SEQ_NEEDBUF(8);\
+ _seqbuf[_seqbufptr] = SEQ_EXTENDED;\
+ _seqbuf[_seqbufptr+1] = SEQ_NOTEOFF;\
+ _seqbuf[_seqbufptr+2] = (dev);\
+ _seqbuf[_seqbufptr+3] = (voice);\
+ _seqbuf[_seqbufptr+4] = (note);\
+ _seqbuf[_seqbufptr+5] = (vol);\
+ _seqbuf[_seqbufptr+6] = 0;\
+ _seqbuf[_seqbufptr+7] = 0;\
+ _SEQ_ADVBUF(8);}
+
+#define SEQ_CHN_PRESSURE(dev, voice, pressure) {_SEQ_NEEDBUF(8);\
+ _seqbuf[_seqbufptr] = SEQ_EXTENDED;\
+ _seqbuf[_seqbufptr+1] = SEQ_AFTERTOUCH;\
+ _seqbuf[_seqbufptr+2] = (dev);\
+ _seqbuf[_seqbufptr+3] = (voice);\
+ _seqbuf[_seqbufptr+4] = (pressure);\
+ _seqbuf[_seqbufptr+5] = 0;\
+ _seqbuf[_seqbufptr+6] = 0;\
+ _seqbuf[_seqbufptr+7] = 0;\
+ _SEQ_ADVBUF(8);}
+
+#define SEQ_PANNING(dev, voice, pos) {_SEQ_NEEDBUF(8);\
+ _seqbuf[_seqbufptr] = SEQ_EXTENDED;\
+ _seqbuf[_seqbufptr+1] = SEQ_BALANCE;\
+ _seqbuf[_seqbufptr+2] = (dev);\
+ _seqbuf[_seqbufptr+3] = (voice);\
+ (char)_seqbuf[_seqbufptr+4] = (pos);\
+ _seqbuf[_seqbufptr+5] = 0;\
+ _seqbuf[_seqbufptr+6] = 0;\
+ _seqbuf[_seqbufptr+7] = 0;\
+ _SEQ_ADVBUF(8);}
+
+#define SEQ_CONTROL(dev, voice, controller, value) {_SEQ_NEEDBUF(8);\
+ _seqbuf[_seqbufptr] = SEQ_EXTENDED;\
+ _seqbuf[_seqbufptr+1] = SEQ_CONTROLLER;\
+ _seqbuf[_seqbufptr+2] = (dev);\
+ _seqbuf[_seqbufptr+3] = (voice);\
+ _seqbuf[_seqbufptr+4] = (controller);\
+ *(short *)&_seqbuf[_seqbufptr+5] = (value);\
+ _seqbuf[_seqbufptr+7] = 0;\
+ _SEQ_ADVBUF(8);}
+
+#define SEQ_PITCHBEND(dev, voice, value) SEQ_CONTROL(dev, voice, CTRL_PITCH_BENDER, value)
+#define SEQ_BENDER_RANGE(dev, voice, value) SEQ_CONTROL(dev, voice, CTRL_PITCH_BENDER_RANGE, value)
+#define SEQ_EXPRESSION(dev, voice, value) SEQ_CONTROL(dev, voice, CTRL_EXPRESSION, value)
+#define SEQ_MAIN_VOLUME(dev, voice, value) SEQ_CONTROL(dev, voice, CTRL_MAIN_VOLUME, value)
+
+#define SEQ_START_TIMER() {_SEQ_NEEDBUF(4);\
+ _seqbuf[_seqbufptr] = SEQ_SYNCTIMER;\
+ _seqbuf[_seqbufptr+1] = 0;\
+ _seqbuf[_seqbufptr+2] = 0;\
+ _seqbuf[_seqbufptr+3] = 0;\
+ _SEQ_ADVBUF(4);}
+#define SEQ_SET_PATCH(dev, voice, patch) {_SEQ_NEEDBUF(8);\
+ _seqbuf[_seqbufptr] = SEQ_EXTENDED;\
+ _seqbuf[_seqbufptr+1] = SEQ_PGMCHANGE;\
+ _seqbuf[_seqbufptr+2] = (dev);\
+ _seqbuf[_seqbufptr+3] = (voice);\
+ _seqbuf[_seqbufptr+4] = (patch);\
+ _seqbuf[_seqbufptr+5] = 0;\
+ _seqbuf[_seqbufptr+6] = 0;\
+ _seqbuf[_seqbufptr+7] = 0;\
+ _SEQ_ADVBUF(8);}
+
+#define SEQ_WAIT_TIME(ticks) {_SEQ_NEEDBUF(4);\
+ *(unsigned long *)&_seqbuf[_seqbufptr] = SEQ_WAIT | ((ticks) << 8);\
+ _SEQ_ADVBUF(4);}
+
+#define SEQ_ECHO_BACK(key) {_SEQ_NEEDBUF(4);\
+ *(unsigned long *)&_seqbuf[_seqbufptr] = SEQ_ECHO | ((key) << 8);\
+ _SEQ_ADVBUF(4);}
+
+#define SEQ_MIDIOUT(device, byte) {_SEQ_NEEDBUF(4);\
+ _seqbuf[_seqbufptr] = SEQ_MIDIPUTC;\
+ _seqbuf[_seqbufptr+1] = (byte);\
+ _seqbuf[_seqbufptr+2] = (device);\
+ _seqbuf[_seqbufptr+3] = 0;\
+ _SEQ_ADVBUF(4);}
+#define SEQ_WRPATCH(patch, len) {if (_seqbufptr) seqbuf_dump();\
+ if (write(seqfd, (char*)(patch), len)==-1) \
+ perror("Write patch: /dev/sequencer");}
+
+#endif
+long soundcard_init(long mem_start);
+#endif
diff --git a/include/linux/ultrasound.h b/include/linux/ultrasound.h
new file mode 100644
index 0000000..745e007
--- /dev/null
+++ b/include/linux/ultrasound.h
@@ -0,0 +1,118 @@
+#ifndef _ULTRASOUND_H_
+#define _ULTRASOUND_H_
+/*
+ * Copyright by Hannu Savolainen 1993
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+/*
+ * ultrasound.h - Macros for programming the Gravis Ultrasound
+ * These macros are extremely device dependent
+ * and not portable.
+ */
+
+/*
+ * Private events for Gravis Ultrasound (GUS)
+ *
+ * Format:
+ * byte 0 - SEQ_PRIVATE (0xfe)
+ * byte 1 - Synthesizer device number (0-N)
+ * byte 2 - Command (see below)
+ * byte 3 - Voice number (0-31)
+ * bytes 4 and 5 - parameter P1 (unsigned short)
+ * bytes 6 and 7 - parameter P2 (unsigned short)
+ *
+ * Commands:
+ * Each command affects one voice defined in byte 3.
+ * Unused parameters (P1 and/or P2 *MUST* be initialized to zero).
+ * _GUS_NUMVOICES - Sets max. number of concurrent voices (P1=14-31, default 16)
+ * _GUS_VOICESAMPLE- ************ OBSOLETE *************
+ * _GUS_VOICEON - Starts voice (P1=voice mode)
+ * _GUS_VOICEOFF - Stops voice (no parameters)
+ * _GUS_VOICEFADE - Stops the voice smoothly.
+ * _GUS_VOICEMODE - Alters the voice mode, don't start or stop voice (P1=voice mode)
+ * _GUS_VOICEBALA - Sets voice balence (P1, 0=left, 7=middle and 15=right, default 7)
+ * _GUS_VOICEFREQ - Sets voice (sample) playback frequency (P1=Hz)
+ * _GUS_VOICEVOL - Sets voice volume (P1=volume, 0xfff=max, 0xeff=half, 0x000=off)
+ * _GUS_VOICEVOL2 - Sets voice volume (P1=volume, 0xfff=max, 0xeff=half, 0x000=off)
+ * (Like GUS_VOICEVOL but doesn't change the hw
+ * volume. It just updates volume in the voice table).
+ *
+ * _GUS_RAMPRANGE - Sets limits for volume ramping (P1=low volume, P2=high volume)
+ * _GUS_RAMPRATE - Sets the speed for volume ramping (P1=scale, P2=rate)
+ * _GUS_RAMPMODE - Sets the volume ramping mode (P1=ramping mode)
+ * _GUS_RAMPON - Starts volume ramping (no parameters)
+ * _GUS_RAMPOFF - Stops volume ramping (no parameters)
+ * _GUS_VOLUME_SCALE - Changes the volume calculation constants
+ * for all voices.
+ */
+
+#define _GUS_NUMVOICES 0x00
+#define _GUS_VOICESAMPLE 0x01 /* OBSOLETE */
+#define _GUS_VOICEON 0x02
+#define _GUS_VOICEOFF 0x03
+#define _GUS_VOICEMODE 0x04
+#define _GUS_VOICEBALA 0x05
+#define _GUS_VOICEFREQ 0x06
+#define _GUS_VOICEVOL 0x07
+#define _GUS_RAMPRANGE 0x08
+#define _GUS_RAMPRATE 0x09
+#define _GUS_RAMPMODE 0x0a
+#define _GUS_RAMPON 0x0b
+#define _GUS_RAMPOFF 0x0c
+#define _GUS_VOICEFADE 0x0d
+#define _GUS_VOLUME_SCALE 0x0e
+#define _GUS_VOICEVOL2 0x0f
+
+/*
+ * GUS API macros
+ */
+
+#define _GUS_CMD(chn, voice, cmd, p1, p2) \
+ {_SEQ_NEEDBUF(8); _seqbuf[_seqbufptr] = SEQ_PRIVATE;\
+ _seqbuf[_seqbufptr+1] = (chn); _seqbuf[_seqbufptr+2] = cmd;\
+ _seqbuf[_seqbufptr+3] = voice;\
+ *(unsigned short*)&_seqbuf[_seqbufptr+4] = p1;\
+ *(unsigned short*)&_seqbuf[_seqbufptr+6] = p2;\
+ _SEQ_ADVBUF(8);}
+
+#define GUS_NUMVOICES(chn, p1) _GUS_CMD(chn, 0, _GUS_NUMVOICES, (p1), 0)
+#define GUS_VOICESAMPLE(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICESAMPLE, (p1), 0) /* OBSOLETE */
+#define GUS_VOICEON(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEON, (p1), 0)
+#define GUS_VOICEOFF(chn, voice) _GUS_CMD(chn, voice, _GUS_VOICEOFF, 0, 0)
+#define GUS_VOICEFADE(chn, voice) _GUS_CMD(chn, voice, _GUS_VOICEFADE, 0, 0)
+#define GUS_VOICEMODE(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEMODE, (p1), 0)
+#define GUS_VOICEBALA(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEBALA, (p1), 0)
+#define GUS_VOICEFREQ(chn, voice, p) _GUS_CMD(chn, voice, _GUS_VOICEFREQ, \
+ (p) & 0xffff, ((p) >> 16) & 0xffff)
+#define GUS_VOICEVOL(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEVOL, (p1), 0)
+#define GUS_VOICEVOL2(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEVOL2, (p1), 0)
+#define GUS_RAMPRANGE(chn, voice, low, high) _GUS_CMD(chn, voice, _GUS_RAMPRANGE, (low), (high))
+#define GUS_RAMPRATE(chn, voice, p1, p2) _GUS_CMD(chn, voice, _GUS_RAMPRATE, (p1), (p2))
+#define GUS_RAMPMODE(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_RAMPMODE, (p1), 0)
+#define GUS_RAMPON(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_RAMPON, (p1), 0)
+#define GUS_RAMPOFF(chn, voice) _GUS_CMD(chn, voice, _GUS_RAMPOFF, 0, 0)
+#define GUS_VOLUME_SCALE(chn, voice, p1, p2) _GUS_CMD(chn, voice, _GUS_VOLUME_SCALE, (p1), (p2))
+
+#endif
diff --git a/kernel/module.c b/kernel/module.c
index 9b0811a..f6abcc7 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -30,7 +30,7 @@ sys_create_module(char *module_name, unsigned long size)
if (!suser())
return -EPERM;
- if (name == NULL || size == 0)
+ if (module_name == NULL || size == 0)
return -EINVAL;
if ((error = get_mod_name(module_name, name)) != 0)
return error;
diff --git a/net/Space.c b/net/Space.c
index 59a3112..b2cc011 100644
--- a/net/Space.c
+++ b/net/Space.c
@@ -29,11 +29,23 @@
#ifdef CONFIG_INET
# include "inet/inet.h"
#endif
+#ifdef CONFIG_IPX
+#include "inet/ipxcall.h"
+#endif
+#ifdef CONFIG_AX25
+#include "inet/ax25call.h"
+#endif
struct ddi_proto protocols[] = {
#ifdef CONFIG_UNIX
{ "UNIX", unix_proto_init },
#endif
+#ifdef CONFIG_IPX
+ { "IPX", ipx_proto_init },
+#endif
+#ifdef CONFIG_AX25
+ { "AX.25", ax25_proto_init },
+#endif
#ifdef CONFIG_INET
{ "INET", inet_proto_init },
#endif
diff --git a/net/inet/Makefile b/net/inet/Makefile
index 5d4a675..a10caa3 100644
--- a/net/inet/Makefile
+++ b/net/inet/Makefile
@@ -18,6 +18,7 @@
OBJS = sock.o utils.o route.o proc.o timer.o protocol.o loopback.o \
eth.o packet.o arp.o dev.o ip.o raw.o icmp.o tcp.o udp.o \
datagram.o skbuff.o
+# ipx.o ax25.o ax25_in.o ax25_out.o ax25_subr.o ax25_timer.o
ifdef CONFIG_INET
diff --git a/net/inet/arp.c b/net/inet/arp.c
index 4924988..0b69e1f 100644
--- a/net/inet/arp.c
+++ b/net/inet/arp.c
@@ -34,6 +34,8 @@
* Alan Cox : 'Bad Packet' only reported on debugging
* Alan Cox : Proxy arp.
* Alan Cox : skb->link3 maintained by letting the other xmit queue kill the packet.
+ * Alan Cox : Knows about type 3 devices (AX.25) using an AX.25 protocol ID not the ethernet
+ * one.
*
* To Fix:
* : arp response allocates an skbuff to send. However there is a perfectly
@@ -482,7 +484,7 @@ arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
}
/* For now we will only deal with IP addresses. */
- if (arp->ar_pro != NET16(ETH_P_IP) || arp->ar_pln != 4)
+ if (((arp->ar_pro != NET16(0x00CC) && dev->type==3) || (arp->ar_pro != NET16(ETH_P_IP) && dev->type!=3) ) || arp->ar_pln != 4)
{
if (arp->ar_op != NET16(ARPOP_REQUEST))
DPRINTF((DBG_ARP,"ARP: Non-IP request on device \"%s\" !\n", dev->name));
@@ -601,7 +603,10 @@ arp_send(unsigned long paddr, struct device *dev, unsigned long saddr)
}
arp = (struct arphdr *) ((unsigned char *) (skb+1) + tmp);
arp->ar_hrd = htons(dev->type);
- arp->ar_pro = htons(ETH_P_IP);
+ if(dev->type!=3) /* AX.25 */
+ arp->ar_pro = htons(ETH_P_IP);
+ else
+ arp->ar_pro = htons(0xCC);
arp->ar_hln = dev->addr_len;
arp->ar_pln = 4;
arp->ar_op = htons(ARPOP_REQUEST);
diff --git a/net/inet/datagram.c b/net/inet/datagram.c
index d1991f4..931d9f3 100644
--- a/net/inet/datagram.c
+++ b/net/inet/datagram.c
@@ -11,6 +11,8 @@
* Fixes:
* Alan Cox : NULL return from skb_peek_copy() understood
* Alan Cox : Rewrote skb_read_datagram to avoid the skb_peek_copy stuff.
+ * Alan Cox : Added support for SOCK_SEQPACKET. IPX can no longer use the SO_TYPE hack but
+ * AX.25 now works right, and SPX is feasible.
*/
#include <linux/config.h>
@@ -60,6 +62,22 @@ restart:
return NULL;
}
+ if(sk->err)
+ {
+ release_sock(sk);
+ *err=-sk->err;
+ sk->err=0;
+ return NULL;
+ }
+
+ /* Sequenced packets can come disconnected. If so we report the problem */
+ if(sk->type==SOCK_SEQPACKET && sk->state!=TCP_ESTABLISHED)
+ {
+ release_sock(sk);
+ *err=-ENOTCONN;
+ return NULL;
+ }
+
/* User doesn't want to wait */
if (noblock)
{
@@ -145,6 +163,7 @@ void skb_copy_datagram(struct sk_buff *skb, int offset, char *to, int size)
/*
* Datagram select: Again totally generic. Moved from udp.c
+ * Now does seqpacket.
*/
int datagram_select(struct sock *sk, int sel_type, select_table *wait)
@@ -153,6 +172,11 @@ int datagram_select(struct sock *sk, int sel_type, select_table *wait)
switch(sel_type)
{
case SEL_IN:
+ if (sk->type==SOCK_SEQPACKET && sk->state==TCP_CLOSE)
+ {
+ /* Connection closed: Wake up */
+ return(1);
+ }
if (sk->rqueue != NULL || sk->err != 0)
{ /* This appears to be consistent
with other stacks */
@@ -168,7 +192,7 @@ int datagram_select(struct sock *sk, int sel_type, select_table *wait)
return(0);
case SEL_EX:
- if (sk->err)
+ if (sk->err)
return(1); /* Socket has gone into error state (eg icmp error) */
return(0);
}
diff --git a/net/inet/dev.c b/net/inet/dev.c
index d11d60c..6c7628d 100644
--- a/net/inet/dev.c
+++ b/net/inet/dev.c
@@ -21,6 +21,11 @@
* Alan Cox: Supports Donald Beckers new hardware
* multicast layer, but not yet multicast lists.
* Alan Cox: ip_addr_match problems with class A/B nets.
+ * C.E.Hawkins IP 0.0.0.0 and also same net route fix. [FIXME: Ought to cause ICMP_REDIRECT]
+ * Alan Cox: Removed bogus subnet check now the subnet code
+ * a) actually works for all A/B nets
+ * b) doesn't forward off the same interface.
+ * Alan Cox: Multiple extra protocols
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -52,6 +57,45 @@
#include "skbuff.h"
#include "sock.h"
#include "arp.h"
+#ifdef CONFIG_AX25
+#include "ax25.h"
+#endif
+
+
+#ifdef CONFIG_IPX
+
+static struct packet_type ipx_8023_type = {
+ NET16(ETH_P_802_3),
+ 0,
+ ipx_rcv,
+ NULL,
+ NULL
+};
+
+static struct packet_type ipx_packet_type = {
+ NET16(ETH_P_IPX),
+ 0,
+ ipx_rcv,
+ NULL,
+ &ipx_8023_type
+};
+
+#endif
+
+#ifdef CONFIG_AX25
+
+static struct packet_type ax25_packet_type = {
+ NET16(ETH_P_AX25),
+ 0,
+ ax25_rcv,
+ NULL,
+#ifdef CONFIG_IPX
+ &ipx_packet_type
+#else
+ NULL
+#endif
+};
+#endif
static struct packet_type arp_packet_type = {
@@ -59,7 +103,15 @@ static struct packet_type arp_packet_type = {
0, /* copy */
arp_rcv,
NULL,
+#ifdef CONFIG_IPX
+#ifndef CONFIG_AX25
+ &ipx_packet_type
+#else
+ &ax25_packet_type
+#endif
+#else
NULL /* next */
+#endif
};
@@ -161,14 +213,10 @@ chk_addr(unsigned long addr)
/* OK, now check the interface addresses. */
for (dev = dev_base; dev != NULL; dev = dev->next) {
- if (dev->pa_addr == 0)
- {
- if(dev->flags&IFF_PROMISC) /* This allows all addresses through */
- return(IS_MYADDR);
- else
- continue;
- }
-
+ if (!(dev->flags&IFF_UP))
+ continue;
+ if ((dev->pa_addr == 0)/* || (dev->flags&IFF_PROMISC)*/)
+ return(IS_MYADDR);
/* Is it the exact IP address? */
if (addr == dev->pa_addr) {
DPRINTF((DBG_DEV, "MYADDR\n"));
@@ -187,15 +235,30 @@ chk_addr(unsigned long addr)
return(IS_BROADCAST);
}
}
+
+ /* Nope. Check for Network broadcast. */
+ if(IN_CLASSA(dst)) {
+ if( addr == (dev->pa_addr | 0xffffff00)) {
+ DPRINTF((DBG_DEV, "CLASS A BROADCAST-1\n"));
+ return(IS_BROADCAST);
+ }
+ }
+ else if(IN_CLASSB(dst)) {
+ if( addr == (dev->pa_addr | 0xffff0000)) {
+ DPRINTF((DBG_DEV, "CLASS B BROADCAST-1\n"));
+ return(IS_BROADCAST);
+ }
+ }
+ else { /* IN_CLASSC */
+ if( addr == (dev->pa_addr | 0xff000000)) {
+ DPRINTF((DBG_DEV, "CLASS C BROADCAST-1\n"));
+ return(IS_BROADCAST);
+ }
+ }
}
DPRINTF((DBG_DEV, "NONE\n"));
- if ((addr & 0xFF) == 0xFF)
- {
- /* Wrong subnetted IS_BROADCAST */
- return(IS_INVBCAST);
- }
return(0); /* no match at all */
}
diff --git a/net/inet/dev.h b/net/inet/dev.h
index b3756b7..5514263 100644
--- a/net/inet/dev.h
+++ b/net/inet/dev.h
@@ -26,8 +26,8 @@
/* for future expansion when we will have different priorities. */
#define DEV_NUMBUFFS 3
-#define MAX_ADDR_LEN 6
-#define MAX_HEADER 14
+#define MAX_ADDR_LEN 7
+#define MAX_HEADER 18
#define IS_MYADDR 1 /* address is (one of) our own */
#define IS_LOOPBACK 2 /* address is for LOOPBACK */
@@ -135,6 +135,8 @@ struct device {
#define HAVE_MULTICAST
void (*set_multicast_list)(struct device *dev,
int num_addrs, void *addrs);
+#define HAVE_SET_MAC_ADDR
+ int (*set_mac_address)(struct device *dev, void *addr);
};
diff --git a/net/inet/icmp.c b/net/inet/icmp.c
index 5b8728b..b4d8d1a 100644
--- a/net/inet/icmp.c
+++ b/net/inet/icmp.c
@@ -13,6 +13,7 @@
*
* Fixes:
* Alan Cox : Generic queue usage.
+ * Gerhard Koerting: ICMP addressing corrected
*
*
* This program is free software; you can redistribute it and/or
@@ -106,7 +107,7 @@ icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev)
iph = (struct iphdr *) ((unsigned char *) iph + dev->hard_header_len);
/* Build Layer 2-3 headers for message back to source. */
- offset = ip_build_header(skb, iph->daddr, iph->saddr,
+ offset = ip_build_header(skb, dev->pa_addr, iph->saddr,
&dev, IPPROTO_ICMP, NULL, len);
if (offset < 0) {
skb->sk = NULL;
diff --git a/net/inet/ip.c b/net/inet/ip.c
index de901cf..3a1b1fc 100644
--- a/net/inet/ip.c
+++ b/net/inet/ip.c
@@ -29,6 +29,8 @@
* Gerhard Koerting: Forward fragmented frames correctly.
* Gerhard Koerting: Fixes to my fix of the above 8-).
* Gerhard Koerting: IP interface addressing fix.
+ * Linus Torvalds : More robustness checks
+ * Alan Cox : Even more checks: Still not as robust as it ought to be
*
* To Fix:
* IP option processing is mostly not needed. ip_forward needs to know about routing rules
@@ -1108,6 +1110,7 @@ ip_forward(struct sk_buff *skb, struct device *dev, int is_frag)
return;
}
+
/*
* Gosh. Not only is the packet valid; we even know how to
* forward it onto its final destination. Can we say this
@@ -1129,6 +1132,7 @@ ip_forward(struct sk_buff *skb, struct device *dev, int is_frag)
} else raddr = iph->daddr;
dev2 = rt->rt_dev;
+
if (dev == dev2)
return;
/*
@@ -1191,7 +1195,7 @@ ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
DPRINTF((DBG_IP, "<<\n"));
/* Is the datagram acceptable? */
- if (iph->version != 4 || ip_fast_csum((unsigned char *)iph, iph->ihl) !=0) {
+ if (skb->len<sizeof(struct iphdr) || iph->ihl<5 || iph->version != 4 || ip_fast_csum((unsigned char *)iph, iph->ihl) !=0) {
DPRINTF((DBG_IP, "\nIP: *** datagram error ***\n"));
DPRINTF((DBG_IP, " SRC = %s ", in_ntoa(iph->saddr)));
DPRINTF((DBG_IP, " DST = %s (ignored)\n", in_ntoa(iph->daddr)));
diff --git a/net/inet/proc.c b/net/inet/proc.c
index 80e80a8..d5bc16e 100644
--- a/net/inet/proc.c
+++ b/net/inet/proc.c
@@ -17,6 +17,7 @@
* Alan Cox : UDP sockets show the rxqueue/txqueue
* using hint flag for the netinfo.
* Pauline Middelink : Pidentd support
+ * Alan Cox : Make /proc safer.
*
* To Do:
* Put the creating userid in the proc/net/... files. This will
@@ -65,7 +66,13 @@ get__netinfo(struct proto *pro, char *buffer, int format)
s_array = pro->sock_array;
pos+=sprintf(pos, "sl local_address rem_address st tx_queue rx_queue tr tm->when uid\n");
+/*
+ * This was very pretty but didn't work when a socket is destroyed at the wrong moment
+ * (eg a syn recv socket getting a reset), or a memory timer destroy. Instead of playing
+ * with timers we just concede defeat and cli().
+ */
for(i = 0; i < SOCK_ARRAY_SIZE; i++) {
+ cli();
sp = s_array[i];
while(sp != NULL) {
dest = sp->daddr;
@@ -76,7 +83,6 @@ get__netinfo(struct proto *pro, char *buffer, int format)
/* Since we are Little Endian we need to swap the bytes :-( */
destp = ntohs(destp);
srcp = ntohs(srcp);
-
timer_active = del_timer(&sp->timer);
if (!timer_active)
sp->timer.expires = 0;
@@ -88,7 +94,6 @@ get__netinfo(struct proto *pro, char *buffer, int format)
SOCK_INODE(sp->socket)->i_uid);
if (timer_active)
add_timer(&sp->timer);
-
/* Is place in buffer too rare? then abort. */
if (pos > buffer+PAGE_SIZE-80) {
printk("oops, too many %s sockets for netinfo.\n",
@@ -103,6 +108,8 @@ get__netinfo(struct proto *pro, char *buffer, int format)
*/
sp = sp->next;
}
+ sti(); /* We only turn interrupts back on for a moment, but because the interrupt queues anything built up
+ before this will clear before we jump back and cli, so its not as bad as it looks */
}
return(strlen(buffer));
}
diff --git a/net/inet/raw.c b/net/inet/raw.c
index 04f3473..7533532 100644
--- a/net/inet/raw.c
+++ b/net/inet/raw.c
@@ -18,6 +18,7 @@
* library. No more peek crashes, no more backlogs
* Alan Cox : Checks sk->broadcast.
* Alan Cox : Uses skb_free_datagram/skb_copy_datagram
+ * Alan Cox : Raw passes ip options too
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/net/inet/route.c b/net/inet/route.c
index 1bdde0d..f82a097 100644
--- a/net/inet/route.c
+++ b/net/inet/route.c
@@ -70,19 +70,26 @@ rt_del(unsigned long dst)
unsigned long flags;
DPRINTF((DBG_RT, "RT: flushing for dst %s\n", in_ntoa(dst)));
- if ((r = rt_base) == NULL) return;
+ if ((r = rt_base) == NULL)
+ return;
save_flags(flags);
cli();
p = NULL;
- while(r != NULL) {
- if (r->rt_dst == dst) {
- if (p == NULL) rt_base = r->rt_next;
- else p->rt_next = r->rt_next;
+ while(r != NULL)
+ {
+ if (r->rt_dst == dst)
+ {
+ if (p == NULL)
+ rt_base = r->rt_next;
+ else
+ p->rt_next = r->rt_next;
x = r->rt_next;
kfree_s(r, sizeof(struct rtable));
r = x;
- } else {
+ }
+ else
+ {
p = r;
r = r->rt_next;
}
@@ -105,14 +112,20 @@ rt_flush(struct device *dev)
save_flags(flags);
p = NULL;
- while(r != NULL) {
- if (r->rt_dev == dev) {
- if (p == NULL) rt_base = r->rt_next;
- else p->rt_next = r->rt_next;
+ while(r != NULL)
+ {
+ if (r->rt_dev == dev)
+ {
+ if (p == NULL)
+ rt_base = r->rt_next;
+ else
+ p->rt_next = r->rt_next;
x = r->rt_next;
kfree_s(r, sizeof(struct rtable));
r = x;
- } else {
+ }
+ else
+ {
p = r;
r = r->rt_next;
}
@@ -126,7 +139,7 @@ rt_add(short flags, unsigned long dst, unsigned long gw, struct device *dev)
{
struct rtable *r, *r1;
struct rtable *rt;
- int mask;
+ int mask=0;
unsigned long cpuflags;
/* Allocate an entry. */
@@ -139,7 +152,18 @@ rt_add(short flags, unsigned long dst, unsigned long gw, struct device *dev)
/* Fill in the fields. */
memset(rt, 0, sizeof(struct rtable));
rt->rt_flags = (flags | RTF_UP);
- if (gw != 0) rt->rt_flags |= RTF_GATEWAY;
+
+ /*
+ * Gateway to our own interface is really direct
+ */
+ if (gw==dev->pa_addr || gw==dst)
+ {
+ gw=0;
+ rt->rt_flags&=~RTF_GATEWAY;
+ }
+
+ if (gw != 0)
+ rt->rt_flags |= RTF_GATEWAY;
rt->rt_dev = dev;
rt->rt_gateway = gw;
@@ -148,23 +172,31 @@ rt_add(short flags, unsigned long dst, unsigned long gw, struct device *dev)
* the TARGET if we are creating an entry for a NETWORK. Use
* an Internet class C network mask. Yuck :-(
*/
- if (flags & RTF_DYNAMIC) {
+ if (flags & RTF_DYNAMIC)
+ {
if (flags & RTF_HOST)
rt->rt_dst = dst;
- else{
+ else
+ {
+ /* Cut down to the route at interface mask level */
rt->rt_dst = (dst & dev->pa_mask);
+ mask=dev->pa_mask;
/* We don't want new routes to our own net*/
- if(rt->rt_dst == (dev->pa_addr & dev->pa_mask)){
+ if(rt->rt_dst == (dev->pa_addr & dev->pa_mask))
+ {
kfree_s(rt, sizeof(struct rtable));
/*printk("Dynamic route to my own net rejected\n");*/
return;
}
}
- } else rt->rt_dst = dst;
+ }
+ else
+ rt->rt_dst = dst;
rt_print(rt);
- if (rt_base == NULL) {
+ if (rt_base == NULL)
+ {
rt->rt_next = NULL;
rt_base = rt;
return;
@@ -175,26 +207,38 @@ rt_add(short flags, unsigned long dst, unsigned long gw, struct device *dev)
* found the first address which has the same generality
* as the one in rt. Then we can put rt in after it.
*/
- for (mask = 0xff000000L; mask != 0xffffffffL; mask = (mask >> 8) | mask) {
- if (mask & dst) {
- mask = mask << 8;
- break;
- }
+
+ if(mask==0) /* Dont figure out masks for DYNAMIC routes. The mask is (our should be!)
+ the device mask (obtained above) */
+ {
+ for (mask = 0xff000000L; mask != 0xffffffffL; mask = (mask >> 8) | mask)
+ {
+ if (mask & dst)
+ {
+ mask = mask << 8;
+ break;
+ }
+ }
+ DPRINTF((DBG_RT, "RT: mask = %X\n", mask));
}
- DPRINTF((DBG_RT, "RT: mask = %X\n", mask));
-
+
save_flags(cpuflags);
cli();
r1 = rt_base;
/* See if we are getting a duplicate. */
- for (r = rt_base; r != NULL; r = r->rt_next) {
- if (r->rt_dst == dst) {
- if (r == rt_base) {
+ for (r = rt_base; r != NULL; r = r->rt_next)
+ {
+ if (r->rt_dst == dst)
+ {
+ if (r == rt_base)
+ {
rt->rt_next = r->rt_next;
rt_base = rt;
- } else {
+ }
+ else
+ {
rt->rt_next = r->rt_next;
r1->rt_next = rt;
}
@@ -206,11 +250,16 @@ rt_add(short flags, unsigned long dst, unsigned long gw, struct device *dev)
}
r1 = rt_base;
- for (r = rt_base; r != NULL; r = r->rt_next) {
- if (! (r->rt_dst & mask)) {
+ for (r = rt_base; r != NULL; r = r->rt_next)
+ {
+ /* When we find a route more general than ourselves, and we are not a gateway or it is a gateway then use it
+ This puts gateways after direct links in the table and sorts (most) of the bit aligned subnetting out */
+ if (! (r->rt_dst & mask) && (gw==0 || r->rt_flags&RTF_GATEWAY))
+ {
DPRINTF((DBG_RT, "RT: adding before r=%X\n", r));
rt_print(r);
- if (r == rt_base) {
+ if (r == rt_base)
+ {
rt->rt_next = rt_base;
rt_base = rt;
restore_flags(cpuflags);
@@ -315,11 +364,12 @@ struct rtable *
rt_route(unsigned long daddr, struct options *opt)
{
struct rtable *rt;
+ int type;
/*
* This is a hack, I think. -FvK
*/
- if (chk_addr(daddr) == IS_MYADDR) daddr = my_addr();
+ if ((type=chk_addr(daddr)) == IS_MYADDR) daddr = my_addr();
/*
* Loop over the IP routing table to find a route suitable
@@ -342,7 +392,7 @@ rt_route(unsigned long daddr, struct options *opt)
rt->rt_use++;
return(rt);
}
- if ((rt->rt_dev->flags & IFF_BROADCAST) &&
+ if (type==IS_BROADCAST && (rt->rt_dev->flags & IFF_BROADCAST) &&
ip_addr_match(rt->rt_dev->pa_brdaddr, daddr)) {
DPRINTF((DBG_RT, "%s (BCAST %s)\n",
rt->rt_dev->name, in_ntoa(rt->rt_dev->pa_brdaddr)));
diff --git a/net/inet/skbuff.c b/net/inet/skbuff.c
index 84f1f7e..1f3299d 100644
--- a/net/inet/skbuff.c
+++ b/net/inet/skbuff.c
@@ -11,11 +11,13 @@
* Fixes:
* Alan Cox : Tracks memory and number of buffers for kernel memory report
* and memory leak hunting.
+ * Alan Cox : More generic kfree handler
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
+#include <linux/sched.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <linux/mm.h>
@@ -384,15 +386,30 @@ void kfree_skb(struct sk_buff *skb, int rw)
if(skb->list)
printk("Warning: kfree_skb passed an skb still on a list.\n");
skb->magic = 0;
- if (skb->sk) {
- if (rw) {
- skb->sk->prot->rfree(skb->sk, skb->mem_addr, skb->mem_len);
- } else {
- skb->sk->prot->wfree(skb->sk, skb->mem_addr, skb->mem_len);
+ if (skb->sk)
+ {
+ if(skb->sk->prot!=NULL)
+ {
+ if (rw)
+ skb->sk->prot->rfree(skb->sk, skb->mem_addr, skb->mem_len);
+ else
+ skb->sk->prot->wfree(skb->sk, skb->mem_addr, skb->mem_len);
+
}
- } else {
+ else
+ {
+ /* Non INET - default wmalloc/rmalloc handler */
+ if (rw)
+ skb->sk->rmem_alloc-=skb->mem_len;
+ else
+ skb->sk->wmem_alloc-=skb->mem_len;
+ if(!skb->sk->dead)
+ wake_up(skb->sk->sleep);
+ kfree_skbmem(skb->mem_addr,skb->mem_len);
+ }
+ }
+ else
kfree_skbmem(skb->mem_addr, skb->mem_len);
- }
}
/*
diff --git a/net/inet/sock.c b/net/inet/sock.c
index 2d082fa..7ad61c9 100644
--- a/net/inet/sock.c
+++ b/net/inet/sock.c
@@ -46,6 +46,8 @@
* Pauline Middelink : Pidentd support
* Alan Cox : Fixed connect() taking signals I think.
* Alan Cox : SO_LINGER supported
+ * Alan Cox : Error reporting fixes
+ * Anonymous : inet_create tidied up (sk->reuse setting)
*
* To Fix:
*
@@ -708,7 +710,7 @@ inet_create(struct socket *sock, int protocol)
if (sk == NULL)
return(-ENOMEM);
sk->num = 0;
-
+ sk->reuse = 0;
switch(sock->type) {
case SOCK_STREAM:
case SOCK_SEQPACKET:
@@ -794,7 +796,7 @@ inet_create(struct socket *sock, int protocol)
sk->intr = 0;
sk->linger = 0;
sk->destroy = 0;
- sk->reuse = 0;
+
sk->priority = 1;
sk->shutdown = 0;
sk->urg = 0;
@@ -1077,7 +1079,9 @@ inet_connect(struct socket *sock, struct sockaddr * uaddr,
{
sti();
sock->state = SS_UNCONNECTED;
- return -sk->err; /* set by tcp_err() */
+ err = -sk->err;
+ sk->err=0;
+ return err; /* set by tcp_err() */
}
}
sti();
@@ -1085,7 +1089,9 @@ inet_connect(struct socket *sock, struct sockaddr * uaddr,
if (sk->state != TCP_ESTABLISHED && sk->err) {
sock->state = SS_UNCONNECTED;
- return(-sk->err);
+ err=sk->err;
+ sk->err=0;
+ return(err);
}
return(0);
}
@@ -1773,7 +1779,7 @@ void inet_proto_init(struct ddi_proto *pro)
struct inet_protocol *p;
int i;
- printk("Swansea University Computer Society Net2Debugged [1.24]\n");
+ printk("Swansea University Computer Society Net2Debugged [1.27]\n");
/* Set up our UNIX VFS major device. */
if (register_chrdev(AF_INET_MAJOR, "af_inet", &inet_fops) < 0) {
printk("%s: cannot register major device %d!\n",
diff --git a/net/inet/sock.h b/net/inet/sock.h
index 0b7736a..cf6e2f3 100644
--- a/net/inet/sock.h
+++ b/net/inet/sock.h
@@ -36,6 +36,12 @@
#include "skbuff.h" /* struct sk_buff */
#include "protocol.h" /* struct inet_protocol */
+#ifdef CONFIG_AX25
+#include "ax25.h"
+#endif
+#ifdef CONFIG_IPX
+#include "ipx.h"
+#endif
#define SOCK_ARRAY_SIZE 64
@@ -74,7 +80,7 @@ struct sock {
ack_timed,
no_check,
exp_growth,
- zapped, /* In ipx means not linked */
+ zapped, /* In ax25 & ipx means not linked */
broadcast;
unsigned long lingertime;
int proc;
@@ -114,7 +120,23 @@ struct sock {
unsigned char debug;
unsigned short rcvbuf;
unsigned short sndbuf;
- unsigned short type; /* IPX type field */
+ unsigned short type;
+#ifdef CONFIG_IPX
+ ipx_address ipx_source_addr,ipx_dest_addr;
+ unsigned short ipx_type;
+#endif
+#ifdef CONFIG_AX25
+/* Really we want to add a per protocol private area */
+ ax25_address ax25_source_addr,ax25_dest_addr;
+ struct sk_buff *volatile ax25_retxq[8];
+ char ax25_state,ax25_vs,ax25_vr,ax25_lastrxnr,ax25_lasttxnr;
+ char ax25_condition;
+ char ax25_retxcnt;
+ char ax25_xx;
+ char ax25_retxqi;
+ char ax25_rrtimer;
+ char ax25_timer;
+#endif
struct tcphdr dummy_th;
/* This part is used for the timeout functions (timer.c). */