diff options
author | Linus Torvalds <torvalds@cc.helsinki.fi> | 1993-12-14 10:43:29 +0000 |
---|---|---|
committer | Nicolas Pitre <nico@cam.org> | 2007-08-19 14:19:22 -0400 |
commit | 59fa0b1fd08fe53a8a9294460c89dda09ee0255d (patch) | |
tree | 759418321ab216123bd9ddb1dc5494d7325e04c3 | |
parent | 8ee558f91b9940ca35f758c4f240b7b5b3ffb76a (diff) | |
download | archive-59fa0b1fd08fe53a8a9294460c89dda09ee0255d.tar.gz |
ALPHA-pl14e
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | drivers/char/mem.c | 25 | ||||
-rw-r--r-- | drivers/net/slip.c | 155 | ||||
-rw-r--r-- | drivers/net/slip.h | 1 | ||||
-rw-r--r-- | drivers/sound/gus_wave.c | 2 | ||||
-rw-r--r-- | drivers/sound/os.h | 4 | ||||
-rw-r--r-- | drivers/sound/soundcard.h | 741 | ||||
-rw-r--r-- | drivers/sound/ultrasound.h | 118 | ||||
-rw-r--r-- | include/linux/if_ether.h | 2 | ||||
-rw-r--r-- | include/linux/major.h | 2 | ||||
-rw-r--r-- | include/linux/soundcard.h | 741 | ||||
-rw-r--r-- | include/linux/ultrasound.h | 118 | ||||
-rw-r--r-- | kernel/module.c | 2 | ||||
-rw-r--r-- | net/Space.c | 12 | ||||
-rw-r--r-- | net/inet/Makefile | 1 | ||||
-rw-r--r-- | net/inet/arp.c | 9 | ||||
-rw-r--r-- | net/inet/datagram.c | 26 | ||||
-rw-r--r-- | net/inet/dev.c | 89 | ||||
-rw-r--r-- | net/inet/dev.h | 6 | ||||
-rw-r--r-- | net/inet/icmp.c | 3 | ||||
-rw-r--r-- | net/inet/ip.c | 6 | ||||
-rw-r--r-- | net/inet/proc.c | 11 | ||||
-rw-r--r-- | net/inet/raw.c | 1 | ||||
-rw-r--r-- | net/inet/route.c | 118 | ||||
-rw-r--r-- | net/inet/skbuff.c | 31 | ||||
-rw-r--r-- | net/inet/sock.c | 16 | ||||
-rw-r--r-- | net/inet/sock.h | 26 |
27 files changed, 1331 insertions, 937 deletions
@@ -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). */ |