Commit 7388b7aa authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.47

parent 4eeb9af8
......@@ -134,6 +134,12 @@ S: Computer Science Department
S: Baltimore, Maryland 21218
S: USA
N: Axel Boldt
E: boldt@math.ucsb.edu
W: http://math-www.uni-paderborn.de/~axel/
D: Configuration help text support
D: Linux CD and Support Giveaway List
N: John Boyd
E: boyd@cis.ohio-state.edu
D: Co-author of wd7000 SCSI driver
......@@ -214,7 +220,7 @@ S: United Kingdom
N: Ray Dassen
E: jdassen@wi.LeidenUniv.nl
U: http://www.wi.leidenuniv.nl/~jdassen/
W: http://www.wi.leidenuniv.nl/~jdassen/
D: Debian GNU/Linux: www.debian.org maintainer, FAQ co-maintainer,
D: packages testing, nit-picking & fixing. Enjoying BugFree (TM) kernels.
S: Zuidsingel 10A
......
This diff is collapsed.
VERSION = 1
PATCHLEVEL = 3
SUBLEVEL = 46
SUBLEVEL = 47
ARCH = i386
......
......@@ -19,9 +19,9 @@ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
if [ "$CONFIG_BINFMT_ELF" = "y" ]; then
bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF
fi
#bool 'Use -mpentium flag for Pentium-specific optimizations' CONFIG_M586
#bool 'Use Pentium-specific optimizations (does NOT work on i386)' CONFIG_M586
#if [ "$CONFIG_M586" = "n" ]; then
bool 'Use -m486 flag for 486-specific optimizations' CONFIG_M486
bool 'Use 486-specific optimizations (does NOT work on i386)' CONFIG_M486
#fi
mainmenu_option next_comment
......
......@@ -41,6 +41,7 @@ CONFIG_BLK_DEV_IDECD=y
# Networking options
#
# CONFIG_FIREWALL is not set
# CONFIG_NET_ALIAS is not set
CONFIG_INET=y
# CONFIG_IP_FORWARD is not set
# CONFIG_IP_MULTICAST is not set
......@@ -122,10 +123,6 @@ CONFIG_ISO9660_FS=y
# CONFIG_ATIXL_BUSMOUSE is not set
# CONFIG_QIC02_TAPE is not set
# CONFIG_APM is not set
# CONFIG_APM_IGNORE_USER_SUSPEND is not set
# CONFIG_APM_DO_ENABLE is not set
CONFIG_APM_CPU_IDLE=y
# CONFIG_APM_DISPLAY_BLANK is not set
#
# Sound
......
......@@ -19,7 +19,6 @@ M_OBJS :=
L_OBJS := tty_io.o n_tty.o console.o keyboard.o serial.o \
tty_ioctl.o pty.o vt.o mem.o vc_screen.o random.o \
defkeymap.o consolemap.o selection.o
SYMTAB_OBJS :=
ifeq ($(CONFIG_CYCLADES),y)
L_OBJS += cyclades.o
......@@ -98,8 +97,7 @@ L_OBJS += tpqic02.o
endif
ifdef CONFIG_APM
L_OBJS += apm_bios.o
SYMTAB_OBJS += apm_bios.o
LX_OBJS += apm_bios.o
endif
ifdef M
......
......@@ -41,6 +41,9 @@
*
* New TIOCLINUX variants added.
* -- mj@k332.feld.cvut.cz, 19-Nov-95
*
* Restrict vt switching via ioctl()
* -- grif@cs.ucr.edu, 5-Dec-95
*/
#include <linux/config.h>
......@@ -97,6 +100,7 @@ int last_console = 0;
int kmsg_redirect = 0;
struct tty_struct * redirect = NULL;
struct wait_queue * keypress_wait = NULL;
char vt_dont_switch = 0;
static void initialize_tty_struct(struct tty_struct *tty);
......@@ -523,7 +527,7 @@ void complete_change_console(unsigned int new_console)
{
unsigned char old_vc_mode;
if (new_console == fg_console)
if ((new_console == fg_console) || (vt_dont_switch))
return;
if (!vc_cons_allocated(new_console))
return;
......@@ -594,7 +598,7 @@ void complete_change_console(unsigned int new_console)
*/
void change_console(unsigned int new_console)
{
if (new_console == fg_console)
if ((new_console == fg_console) || (vt_dont_switch))
return;
if (!vc_cons_allocated(new_console))
return;
......
......@@ -5,6 +5,7 @@
*
* Dynamic diacritical handling - aeb@cwi.nl - Dec 1993
* Dynamic keymap and string allocation - aeb@cwi.nl - May 1994
* Restrict VT switching via ioctl() - grif@cs.ucr.edu - Dec 1995
*/
#include <linux/types.h>
......@@ -28,6 +29,7 @@
#include "diacr.h"
#include "selection.h"
extern char vt_dont_switch;
extern struct tty_driver console_driver;
#define VT_IS_IN_USE(i) (console_driver.table[i] && console_driver.table[i]->count)
......@@ -1094,7 +1096,16 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
return i;
return con_get_unimap(ct, &(ud->entry_ct), list);
}
case VT_LOCKSWITCH:
if (!suser())
return -EPERM;
vt_dont_switch = 1;
return 0;
case VT_UNLOCKSWITCH:
if (!suser())
return -EPERM;
vt_dont_switch = 0;
return 0;
default:
return -ENOIOCTLCMD;
}
......
......@@ -477,7 +477,12 @@ el2_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
unsigned long hdr_start = dev->mem_start + ((ring_page - EL2_MB1_START_PG)<<8);
if (dev->mem_start) { /* Use the shared memory. */
#ifdef notdef
/* Officially this is what we are doing, but the readl() is faster */
memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
#else
((unsigned int*)hdr)[0] = readl(hdr_start);
#endif
return;
}
......
......@@ -32,8 +32,6 @@ static const char *version =
Much of this code should have been cleaned up, but every attempt
has broken some clone part.
Doesn't currently work on all shared memory cards.
Sources:
The National Semiconductor LAN Databook, and the 3Com 3c503 databook.
*/
......@@ -512,8 +510,9 @@ static void ei_receive(struct device *dev)
if (rx_pkt_count > high_water_mark)
high_water_mark = rx_pkt_count;
/* Bug alert! Reset ENISR_OVER to avoid spurious overruns! */
outb_p(ENISR_RX+ENISR_RX_ERR+ENISR_OVER, e8390_base+EN0_ISR);
/* We used to also ack ENISR_OVER here, but that would sometimes mask
a real overrun, leaving the 8390 in a stopped state with rec'vr off. */
outb_p(ENISR_RX+ENISR_RX_ERR, e8390_base+EN0_ISR);
return;
}
......@@ -550,7 +549,7 @@ static void ei_rx_overrun(struct device *dev)
/* Remove packets right away. */
ei_receive(dev);
outb_p(0xff, e8390_base+EN0_ISR);
outb_p(ENISR_OVER, e8390_base+EN0_ISR);
/* Generic 8390 insns to start up again, same as in open_8390(). */
outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START, e8390_base + E8390_CMD);
outb_p(E8390_TXCONFIG, e8390_base + EN0_TXCR); /* xmit on. */
......
This diff is collapsed.
......@@ -299,7 +299,12 @@ e21_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
mem_on(ioaddr, shared_mem, ring_page);
#ifdef notdef
/* Officially this is what we are doing, but the readl() is faster */
memcpy_fromio(hdr, shared_mem, sizeof(struct e8390_pkt_hdr));
#else
((unsigned int*)hdr)[0] = readl(shared_mem);
#endif
/* Turn off memory access: we would need to reprogram the window anyway. */
mem_off(ioaddr);
......
......@@ -34,6 +34,9 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/trdevice.h>
#ifdef CONFIG_NET_ALIAS
#include <linux/net_alias.h>
#endif
/* The network devices currently exist only in the socket namespace, so these
entries are unused. The only ones that make sense are
......@@ -293,6 +296,28 @@ void unregister_netdev(struct device *dev)
/* else */
if (dev->start)
printk("ERROR '%s' busy and not MOD_IN_USE.\n", dev->name);
/*
* must jump over main_device+aliases
* avoid alias devices unregistration so that only
* net_alias module manages them
*/
#ifdef CONFIG_NET_ALIAS
if (dev_base == dev)
dev_base = net_alias_nextdev(dev);
else
{
while(d && (net_alias_nextdev(d) != dev)) /* skip aliases */
d = net_alias_nextdev(d);
if (d && (net_alias_nextdev(d) == dev))
{
/*
* critical: bypass by consider devices as blocks (maindev+aliases)
*/
net_alias_nextdev_set(d, net_alias_nextdev(dev));
}
#else
if (dev_base == dev)
dev_base = dev->next;
else
......@@ -304,6 +329,7 @@ void unregister_netdev(struct device *dev)
{
d->next = dev->next;
}
#endif
else
{
printk("unregister_netdev: '%s' not found\n", dev->name);
......
......@@ -270,7 +270,12 @@ ultra_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
unsigned long hdr_start = dev->mem_start + ((ring_page - START_PG)<<8);
outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem on */
#ifdef notdef
/* Officially this is what we are doing, but the readl() is faster */
memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
#else
((unsigned int*)hdr)[0] = readl(hdr_start);
#endif
outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem off */
}
......
......@@ -129,6 +129,13 @@ int wd_probe1(struct device *dev, int ioaddr)
dev = init_etherdev(0, 0);
}
/* Check for semi-valid mem_start/end values if supplied. */
if ((dev->mem_start % 0x2000) || (dev->mem_end % 0x2000)) {
printk(KERN_WARNING "wd.c: user supplied mem_start or mem_end not on 8kB boundary - ignored.\n");
dev->mem_start = 0;
dev->mem_end = 0;
}
if (ei_debug && version_printed++ == 0)
printk(version);
......@@ -246,7 +253,7 @@ int wd_probe1(struct device *dev, int ioaddr)
/* Snarf the interrupt now. There's no point in waiting since we cannot
share and the board will usually be enabled. */
if (request_irq(dev->irq, ei_interrupt, 0, "wd")) {
if (request_irq(dev->irq, ei_interrupt, 0, model_name)) {
printk (" unable to get IRQ %d.\n", dev->irq);
return EAGAIN;
}
......@@ -259,7 +266,7 @@ int wd_probe1(struct device *dev, int ioaddr)
}
/* OK, were are certain this is going to work. Setup the device. */
request_region(ioaddr, WD_IO_EXTENT,"wd");
request_region(ioaddr, WD_IO_EXTENT, model_name);
ei_status.name = model_name;
ei_status.word16 = word16;
......@@ -352,7 +359,12 @@ wd_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
if (ei_status.word16)
outb(ISA16 | ei_status.reg5, wd_cmdreg+WD_CMDREG5);
#ifdef notdef
/* Officially this is what we are doing, but the readl() is faster */
memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
#else
((unsigned int*)hdr)[0] = readl(hdr_start);
#endif
}
/* Block input and output are easy on shared memory ethercards, and trivial
......
......@@ -918,7 +918,7 @@ int aha152x_abort( Scsi_Cmnd *SCpnt)
ptr->host_scribble = NULL;
ptr->result = DID_ABORT << 16;
ptr->done(ptr);
ptr->scsi_done(ptr);
return SCSI_ABORT_SUCCESS;
}
......@@ -942,7 +942,7 @@ int aha152x_abort( Scsi_Cmnd *SCpnt)
/* target entered bus free before COMMAND COMPLETE, nothing to abort */
restore_flags(flags);
current_SC->result = DID_ERROR << 16;
current_SC->done(current_SC);
current_SC->scsi_done(current_SC);
current_SC = (Scsi_Cmnd *) NULL;
return SCSI_ABORT_SUCCESS;
}
......@@ -1063,7 +1063,7 @@ int aha152x_reset(Scsi_Cmnd * __unused)
{
current_SC->host_scribble = NULL;
current_SC->result = DID_RESET << 16;
current_SC->done(current_SC);
current_SC->scsi_done(current_SC);
current_SC=NULL;
}
......@@ -1083,7 +1083,7 @@ int aha152x_reset(Scsi_Cmnd * __unused)
ptr->host_scribble = NULL;
ptr->result = DID_RESET << 16;
ptr->done(ptr);
ptr->scsi_done(ptr);
ptr = next;
}
......
......@@ -23,6 +23,8 @@
#define CONST_XSENSE 0x08
#define CONST_CMND 0x10
#define CONST_MSG 0x20
#define CONST_HOST 0x40
#define CONST_DRIVER 0x80
static const char unknown[] = "UNKNOWN";
......@@ -30,7 +32,8 @@ static const char unknown[] = "UNKNOWN";
#ifdef CONSTANTS
#undef CONSTANTS
#endif
#define CONSTANTS (CONST_COMMAND | CONST_STATUS | CONST_SENSE | CONST_XSENSE | CONST_CMND | CONST_MSG)
#define CONSTANTS (CONST_COMMAND | CONST_STATUS | CONST_SENSE | CONST_XSENSE \
| CONST_CMND | CONST_MSG | CONST_HOST | CONST_DRIVER)
#endif
#if (CONSTANTS & CONST_COMMAND)
......@@ -568,6 +571,64 @@ void print_Scsi_Cmnd (Scsi_Cmnd *cmd) {
print_command (cmd->cmnd);
}
#if (CONSTANTS & CONST_HOST)
static const char * hostbyte_table[]={
"DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET",
"DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR",NULL};
void print_hostbyte(int scsiresult)
{ static int maxcode=0;
int i;
if(!maxcode) {
for(i=0;hostbyte_table[i];i++) ;
maxcode=i-1;
}
printk("Hostbyte=0x%02x",host_byte(scsiresult));
if(host_byte(scsiresult)>maxcode) {
printk("is invalid ");
return;
}
printk("(%s) ",hostbyte_table[host_byte(scsiresult)]);
}
#else
void print_hostbyte(int scsiresult)
{ printk("Hostbyte=0x%02x ",hostbyte(scsiresult));
}
#endif
#if (CONSTANTS & CONST_DRIVER)
static const char * driverbyte_table[]={
"DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR",
"DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD",NULL };
static const char * driversuggest_table[]={"SUGGEST_OK",
"SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE",
unknown,unknown,unknown, "SUGGEST_SENSE",NULL};
void print_driverbyte(int scsiresult)
{ static int driver_max=0,suggest_max=0;
int i,dr=driver_byte(scsiresult)&DRIVER_MASK,
su=(driver_byte(scsiresult)&SUGGEST_MASK)>>4;
if(!driver_max) {
for(i=0;driverbyte_table[i];i++) ;
driver_max=i;
for(i=0;driversuggest_table[i];i++) ;
suggest_max=i;
}
printk("Driverbyte=0x%02x",driver_byte(scsiresult));
printk("(%s,%s) ",
dr<driver_max ? driverbyte_table[dr]:"invalid",
su<suggest_max ? driversuggest_table[su]:"invalid");
}
#else
void print_driverbyte(int scsiresult)
{ printk("Driverbyte=0x%02x ",driver_byte(scsiresult));
}
#endif
/*
* Overrides for Emacs so that we almost follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
......
This diff is collapsed.
......@@ -89,6 +89,7 @@ extern const unsigned char scsi_command_size[8];
#define DRIVER_INVALID 0x05
#define DRIVER_TIMEOUT 0x06
#define DRIVER_HARD 0x07
#define DRIVER_SENSE 0x08
#define SUGGEST_RETRY 0x10
#define SUGGEST_ABORT 0x20
......@@ -97,8 +98,6 @@ extern const unsigned char scsi_command_size[8];
#define SUGGEST_SENSE 0x80
#define SUGGEST_IS_OK 0xff
#define DRIVER_SENSE 0x08
#define DRIVER_MASK 0x0f
#define SUGGEST_MASK 0xf0
......@@ -448,6 +447,8 @@ extern void proc_print_scsidevice(Scsi_Device *, char *, int *, int);
extern void print_command(unsigned char *);
extern void print_sense(const char *, Scsi_Cmnd *);
extern void print_driverbyte(int scsiresult);
extern void print_hostbyte(int scsiresult);
extern void scsi_mark_host_bus_reset(struct Scsi_Host *Host);
......
......@@ -59,7 +59,6 @@ struct symbol_table scsi_symbol_table = {
X(kernel_scsi_ioctl),
X(need_isa_buffer),
X(request_queueable),
X(in_scan_scsis),
#if defined(CONFIG_PROC_FS)
X(proc_print_scsidevice),
#endif
......
......@@ -1304,12 +1304,14 @@ static void sd_finish()
if (!rscsi_disks[i].capacity &&
rscsi_disks[i].device)
{
i = sd_init_onedisk(i);
if (MODULE_FLAG
&& !rscsi_disks[i].has_part_table) {
sd_sizes[i << 4] = rscsi_disks[i].capacity;
/* revalidate does sd_init_onedisk via MAYBE_REINIT*/
revalidate_scsidisk(MKDEV(MAJOR_NR, i << 4), 0);
}
else
i=sd_init_onedisk(i);
rscsi_disks[i].has_part_table = 1;
}
......
......@@ -297,7 +297,8 @@ int mem_mmap(struct inode * inode, struct file * file,
dtmp += PAGE_SIZE;
}
invalidate();
invalidate_range(vma->vm_mm, vma->vm_start, vma->vm_end);
invalidate_range(src_vma->vm_mm, src_vma->vm_start, src_vma->vm_end);
return 0;
}
......
......@@ -91,13 +91,13 @@ struct vfsmount *add_vfsmnt(kdev_t dev, const char *dev_name, const char *dir_na
lptr->mnt_sem.count = 1;
if (dev_name && !getname(dev_name, &tmp)) {
if ((lptr->mnt_devname =
(char *) kmalloc(strlen(tmp), GFP_KERNEL)) != (char *)NULL)
(char *) kmalloc(strlen(tmp)+1, GFP_KERNEL)) != (char *)NULL)
strcpy(lptr->mnt_devname, tmp);
putname(tmp);
}
if (dir_name && !getname(dir_name, &tmp)) {
if ((lptr->mnt_dirname =
(char *) kmalloc(strlen(tmp), GFP_KERNEL)) != (char *)NULL)
(char *) kmalloc(strlen(tmp)+1, GFP_KERNEL)) != (char *)NULL)
strcpy(lptr->mnt_dirname, tmp);
putname(tmp);
}
......
......@@ -26,32 +26,81 @@
* - invalidate_page(mm, vmaddr) invalidates one page
* - invalidate_range(mm, start, end) invalidates a range of pages
*
* ..but the i386 has somewhat limited invalidation capabilities.
* ..but the i386 has somewhat limited invalidation capabilities,
* and page-granular invalidates are available only on i486 and up.
*/
#define __invalidate() \
__asm__ __volatile__("movl %%cr3,%%eax\n\tmovl %%eax,%%cr3": : :"ax")
#ifdef __i486__
#define __invalidate_one(addr) \
__asm__ __volatile__("invlpg %0": :"m" (*(char *) addr))
#else
#define __invalidate_one(addr) invalidate()
#endif
#ifndef __SMP__
#define invalidate() \
__asm__ __volatile__("movl %%cr3,%%eax\n\tmovl %%eax,%%cr3": : :"ax")
#define invalidate() __invalidate()
#define invalidate_all() __invalidate()
static inline void invalidate_mm(struct mm_struct *mm)
{
if (mm == current->mm)
__invalidate();
}
static inline void invalidate_page(struct mm_struct *mm,
unsigned long addr)
{
if (mm == current->mm)
__invalidate_one(addr);
}
static inline void invalidate_range(struct mm_struct *mm,
unsigned long start, unsigned long end)
{
if (mm == current->mm)
__invalidate();
}
#else
/*
* We aren't very clever about this yet - SMP could certainly
* avoid some global invalidates..
*/
#include <asm/smp.h>
#define local_invalidate() \
__asm__ __volatile__("movl %%cr3,%%eax\n\tmovl %%eax,%%cr3": : :"ax")
__invalidate()
#define invalidate() \
smp_invalidate();
#endif
smp_invalidate()
/*
* We aren't very clever about this yet. On a 486+ we could actually do
* page-granularity invalidates for better performance in some cases.
* And SMP could certainly avoid some global invalidates..
*/
#define invalidate_all() invalidate()
#define invalidate_mm(mm_struct) \
do { if ((mm_struct) == current->mm) invalidate(); } while (0)
#define invalidate_page(mm_struct,addr) \
do { if ((mm_struct) == current->mm) invalidate(); } while (0)
#define invalidate_range(mm_struct,start,end) \
do { if ((mm_struct) == current->mm) invalidate(); } while (0)
static inline void invalidate_mm(struct mm_struct *mm)
{
invalidate();
}
static inline void invalidate_page(struct mm_struct *mm,
unsigned long addr)
{
invalidate();
}
static inline void invalidate_range(struct mm_struct *mm,
unsigned long start, unsigned long end)
{
invalidate();
}
#endif
/* Certain architectures need to do special things when pte's
* within a page table are directly modified. Thus, the following
......
#ifndef _NET_ALIAS_H
#define _NET_ALIAS_H
#include <linux/types.h>
#include <linux/if.h>
#include <linux/netdevice.h>
#include <linux/inet.h>
#include <linux/in.h> /* for default IP behavior */
/*
* max. alias slot number allowed
*/
#define NET_ALIAS_MAX_SLOT 256
struct net_alias;
struct net_alias_info;
struct net_alias_type;
/*
* main alias structure
* note that *defines* dev & devname
*/
struct net_alias
{
struct device dev; /* alias device defn*/
char name[IFNAMSIZ]; /* device name defn */
unsigned hash; /* my hash value: for quick rehash */
unsigned slot; /* slot number */
void *data; /* private data */
struct device *main_dev; /* pointer to main device */
struct net_alias_type *nat; /* alias type bound */
struct net_alias *next; /* next alias (hashed linked list) */
};
/*
* alias structure pointed by main device
* it holds main device's alias hash table
*/
struct net_alias_info
{
int n_aliases; /* num aliases */
struct device *taildev; /* my last (alias) device */
struct net_alias *hash_tab[16]; /* hashed alias table */
};
/*
* net_alias_type class
* declares a generic (AF_ independent) structure that will
* manage generic to family-specific behavior.
*/
struct net_alias_type
{
int type; /* aliasing type: address family */
int n_attach; /* number of aliases attached */
char name[16]; /* af_name */
__u32 (*get_addr32) /* get __u32 addr 'representation'*/
(struct sockaddr*);
int (*addr_chk) /* address checking func: */
(struct device *, struct sockaddr *);
int (*alias_init_1) /* called after alias creation: */
(struct net_alias *alias, struct sockaddr *sa);
int (*alias_done_1) /* called before alias deletion */
(struct net_alias *alias);
int (*alias_print_1)
(char *buf, int len, struct net_alias *alias);
struct net_alias_type *next; /* link */
};
/*
* is dev an alias?
*/
static __inline__ int
net_alias_is(struct device *dev)
{
return (dev->my_alias != 0);
}
/*
* does dev have aliases?
*/
static __inline__ int
net_alias_has(struct device *dev)
{
return (dev->alias_info != 0);
}
extern void net_alias_init(void);
extern struct device * net_alias_dev_get(char *dev_name, int aliasing_ok, int *err, struct sockaddr *sa, void *data);
extern int net_alias_rehash(struct net_alias *alias, struct sockaddr *sa);
extern int net_alias_getinfo(char *buf, char **, off_t , int , int );
extern int net_alias_types_getinfo(char *buf, char **, off_t , int , int );
extern int register_net_alias_type(struct net_alias_type *nat, int type);
extern int unregister_net_alias_type(struct net_alias_type *nat);
extern struct device * net_alias_chk(struct device *dev, struct sockaddr *sa, int flags_1, int flags_0);
extern struct device * net_alias_chk32(struct device *dev, int family, __u32 addr32, int flags_1, int flags_0);
/*
* returns MY 'true' main device
* intended for alias devices
*/
static __inline__ struct device *net_alias_main_dev(struct device *dev)
{
return (net_alias_is(dev))? dev->my_alias->main_dev : dev;
}
/*
* returns NEXT 'true' device
* intended for true devices
*/
static __inline__ struct device *
net_alias_nextdev(struct device *dev)
{
return (dev->alias_info)? dev->alias_info->taildev->next : dev->next;
}
/*
* sets NEXT 'true' device
* intended for main devices (treat main device as block: dev+aliases).
*/
static __inline__ struct device *
net_alias_nextdev_set(struct device *dev, struct device *nextdev)
{
struct device *pdev = dev;
if (net_alias_has(dev))
{
pdev = dev->alias_info->taildev; /* point to last dev alias */
}
pdev->next = nextdev;
return nextdev;
}
/*
* addr_chk wrapper: check given generic address with (UP) aliases
*/
static __inline__ struct device *
net_alias_addr_chk(struct device *dev, struct sockaddr *sa)
{
return net_alias_chk(dev, sa, IFF_UP, 0);
}
/*
* addr_chk32 wrapper: check given u32 address with (UP) aliases
*/
static __inline__ struct device *
net_alias_addr_chk32(struct device *dev, int family, __u32 addr32)
{
return net_alias_chk32(dev, family, addr32, IFF_UP, 0);
}
#endif /* _NET_ALIAS_H */
......@@ -152,6 +152,8 @@ struct device
unsigned long pkt_queue; /* Packets queued */
struct device *slave; /* Slave device */
struct net_alias_info *alias_info; /* main dev alias info */
struct net_alias *my_alias; /* alias devs */
/* Pointer to the interface buffers. */
......
......@@ -89,6 +89,8 @@ enum net_directory_inos {
PROC_NET_SOCKSTAT,
PROC_NET_RTCACHE,
PROC_NET_AX25_BPQETHER,
PROC_NET_ALIAS_TYPES,
PROC_NET_ALIASES,
PROC_NET_LAST
};
......
......@@ -44,8 +44,8 @@ struct rlimit {
long rlim_max;
};
#define PRIO_MIN (-99)
#define PRIO_MAX 14
#define PRIO_MIN (-20)
#define PRIO_MAX 20
#define PRIO_PROCESS 0
#define PRIO_PGRP 1
......
......@@ -48,5 +48,7 @@ struct vt_consize {
ushort v_ccol; /* number of pixel columns per character */
};
#define VT_RESIZEX 0x560A /* set kernel's idea of screensize + more */
#define VT_LOCKSWITCH 0x560B /* disallow vt switching */
#define VT_UNLOCKSWITCH 0x560C /* allow vt switching */
#endif /* _LINUX_VT_H */
#ifndef _IP_ALIAS_H
#define _IP_ALIAS_H
/*
* IP alias specific prototypes
*/
#include <linux/net_alias.h>
extern int ip_alias_init(void);
extern int ip_alias_done(void);
#endif /* _IP_ALIAS_H */
......@@ -445,7 +445,7 @@ static int shm_map (struct vm_area_struct *shmd)
return -ENOMEM;
set_pte(page_table, __pte(shm_sgn));
}
invalidate();
invalidate_range(shmd->vm_mm, shmd->vm_start, shmd->vm_end);
return 0;
}
......@@ -680,7 +680,7 @@ int shm_swap (int prio, unsigned long limit)
struct vm_area_struct *shmd;
unsigned long swap_nr;
unsigned long id, idx;
int loop = 0, invalid = 0;
int loop = 0;
int counter;
counter = shm_rss >> prio;
......@@ -716,8 +716,6 @@ int shm_swap (int prio, unsigned long limit)
if (--counter < 0) { /* failed */
failed:
if (invalid)
invalidate();
swap_free (swap_nr);
return 0;
}
......@@ -766,7 +764,7 @@ int shm_swap (int prio, unsigned long limit)
mem_map[MAP_NR(pte_page(pte))].count--;
if (shmd->vm_mm->rss > 0)
shmd->vm_mm->rss--;
invalid++;
invalidate_range(shmd->vm_mm, shmd->vm_start, shmd->vm_end);
/* continue looping through circular list */
} while (0);
if ((shmd = shmd->vm_next_share) == shp->attaches)
......@@ -776,8 +774,6 @@ int shm_swap (int prio, unsigned long limit)
if (mem_map[MAP_NR(pte_page(page))].count != 1)
goto check_table;
shp->shm_pages[idx] = swap_nr;
if (invalid)
invalidate();
write_swap_page (swap_nr, (char *) pte_page(page));
free_page(pte_page(page));
swap_successes++;
......
......@@ -76,6 +76,9 @@ extern void __remqu (void);
#include "../drivers/net/slhc.h"
#endif
#endif
#ifdef CONFIG_NET_ALIAS
#include <linux/net_alias.h>
#endif
#endif
#ifdef CONFIG_PCI
#include <linux/bios32.h>
......@@ -412,6 +415,10 @@ struct symbol_table symbol_table = {
/* Device callback registration */
X(register_netdevice_notifier),
X(unregister_netdevice_notifier),
#ifdef CONFIG_NET_ALIAS
X(register_net_alias_type),
X(unregister_net_alias_type),
#endif
#endif
/* support for loadable net drivers */
......@@ -452,11 +459,7 @@ struct symbol_table symbol_table = {
* So we add it here too. There is a duplicate set in scsi.c
* that is used when the entire scsi subsystem is a loadable
* module.
*
* in_scan_scsis is a hack, and should go away once the new
* memory allocation code is in the NCR driver
*/
X(in_scan_scsis),
X(scsi_register_module),
X(scsi_unregister_module),
X(scsi_free),
......
......@@ -141,7 +141,8 @@ int filemap_swapout(struct vm_area_struct * vma,
unsigned long entry = SWP_ENTRY(SHM_SWP_TYPE, MAP_NR(page));
set_pte(page_table, __pte(entry));
invalidate();
/* Yuck, perhaps a slightly modified swapout parameter set? */
invalidate_page(vma->vm_mm, (offset + vma->vm_start - vma->vm_offset));
error = filemap_write_page(vma, offset, page);
if (pte_val(*page_table) == entry)
pte_clear(page_table);
......@@ -179,13 +180,14 @@ static inline int filemap_sync_pte(pte_t * ptep, struct vm_area_struct *vma,
if (!pte_dirty(pte))
return 0;
set_pte(ptep, pte_mkclean(pte));
invalidate_page(vma->vm_mm, address);
page = pte_page(pte);
mem_map[MAP_NR(page)].count++;
} else {
if (pte_none(pte))
return 0;
pte_clear(ptep);
invalidate();
invalidate_page(vma->vm_mm, address);
if (!pte_present(pte)) {
swap_free(pte_val(pte));
return 0;
......@@ -274,7 +276,7 @@ static int filemap_sync(struct vm_area_struct * vma, unsigned long address,
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
}
invalidate();
invalidate_range(vma->vm_mm, end - size, end);
return error;
}
......
......@@ -134,7 +134,7 @@ void clear_page_tables(struct task_struct * tsk)
}
for (i = 0 ; i < USER_PTRS_PER_PGD ; i++)
free_one_pgd(page_dir + i);
invalidate();
invalidate_mm(tsk->mm);
}
/*
......@@ -153,12 +153,12 @@ void free_page_tables(struct task_struct * tsk)
printk("%s trying to free kernel page-directory: not good\n", tsk->comm);
return;
}
invalidate_mm(tsk->mm);
SET_PAGE_DIR(tsk, swapper_pg_dir);
tsk->mm->pgd = swapper_pg_dir; /* or else... */
for (i = 0 ; i < PTRS_PER_PGD ; i++)
free_one_pgd(page_dir + i);
pgd_free(page_dir);
invalidate();
}
int new_page_tables(struct task_struct * tsk)
......@@ -171,6 +171,7 @@ int new_page_tables(struct task_struct * tsk)
page_dir = pgd_offset(&init_mm, 0);
for (i = USER_PTRS_PER_PGD ; i < PTRS_PER_PGD ; i++)
new_pg[i] = page_dir[i];
invalidate_mm(tsk->mm);
SET_PAGE_DIR(tsk, new_pg);
tsk->mm->pgd = new_pg;
return 0;
......@@ -285,7 +286,9 @@ int copy_page_range(struct mm_struct *dst, struct mm_struct *src,
break;
address = (address + PGDIR_SIZE) & PGDIR_MASK;
}
invalidate();
/* Note that the src ptes get c-o-w treatment, so they change too. */
invalidate_range(src, vma->vm_start, vma->vm_end);
invalidate_range(dst, vma->vm_start, vma->vm_end);
return error;
}
......@@ -369,7 +372,7 @@ int zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long si
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
}
invalidate();
invalidate_range(mm, end - size, end);
return 0;
}
......@@ -429,7 +432,7 @@ int zeromap_page_range(unsigned long address, unsigned long size, pgprot_t prot)
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
}
invalidate();
invalidate_range(current->mm, end - size, end);
return error;
}
......@@ -499,7 +502,7 @@ int remap_page_range(unsigned long from, unsigned long offset, unsigned long siz
from = (from + PGDIR_SIZE) & PGDIR_MASK;
dir++;
}
invalidate();
invalidate_range(current->mm, from - size, from);
return error;
}
......@@ -514,7 +517,7 @@ static void put_page(pte_t * page_table, pte_t pte)
return;
}
/* no need for invalidate */
*page_table = pte;
set_pte(page_table, pte);
}
/*
......@@ -547,7 +550,7 @@ unsigned long put_dirty_page(struct task_struct * tsk, unsigned long page, unsig
if (!pte_none(*pte)) {
printk("put_dirty_page: page already exists\n");
pte_clear(pte);
invalidate();
invalidate_page(tsk->mm, address);
}
set_pte(pte, pte_mkwrite(pte_mkdirty(mk_pte(page, PAGE_COPY))));
/* no need for invalidate */
......@@ -610,17 +613,17 @@ void do_wp_page(struct task_struct * tsk, struct vm_area_struct * vma,
copy_page(old_page,new_page);
set_pte(page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
free_page(old_page);
invalidate();
invalidate_page(vma->vm_mm, address);
return;
}
set_pte(page_table, BAD_PAGE);
free_page(old_page);
oom(tsk);
invalidate();
invalidate_page(vma->vm_mm, address);
return;
}
set_pte(page_table, pte_mkdirty(pte_mkwrite(pte)));
invalidate();
invalidate_page(vma->vm_mm, address);
if (new_page)
free_page(new_page);
return;
......@@ -842,7 +845,7 @@ static int try_to_share(unsigned long to_address, struct vm_area_struct * to_are
return 1;
/* ok, need to mark it read-only, so invalidate any possible old TB entry */
set_pte(from_table, pte_wrprotect(from));
invalidate();
invalidate_page(from_area->vm_mm, from_address);
return 1;
}
......
......@@ -72,6 +72,7 @@ static inline void change_pmd_range(pgd_t * pgd, unsigned long address,
static void change_protection(unsigned long start, unsigned long end, pgprot_t newprot)
{
pgd_t *dir;
unsigned long beg = start;
dir = pgd_offset(current->mm, start);
while (start < end) {
......@@ -79,7 +80,7 @@ static void change_protection(unsigned long start, unsigned long end, pgprot_t n
start = (start + PGDIR_SIZE) & PGDIR_MASK;
dir++;
}
invalidate();
invalidate_range(current->mm, beg, end);
return;
}
......
......@@ -457,7 +457,7 @@ static inline int try_to_swap_out(struct task_struct * tsk, struct vm_area_struc
return 0;
vma->vm_mm->rss--;
set_pte(page_table, __pte(entry));
invalidate();
invalidate_page(vma->vm_mm, address);
tsk->nswap++;
write_swap_page(entry, (char *) page);
}
......@@ -472,13 +472,13 @@ static inline int try_to_swap_out(struct task_struct * tsk, struct vm_area_struc
}
vma->vm_mm->rss--;
set_pte(page_table, __pte(entry));
invalidate();
invalidate_page(vma->vm_mm, address);
free_page(page);
return 1;
}
vma->vm_mm->rss--;
pte_clear(page_table);
invalidate();
invalidate_page(vma->vm_mm, address);
entry = mem_map[MAP_NR(page)].count;
free_page(page);
return entry;
......
......@@ -105,7 +105,7 @@ static void free_area_pages(unsigned long address, unsigned long size)
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
}
invalidate();
invalidate_all();
}
static inline int alloc_area_pte(pte_t * pte, unsigned long address, unsigned long size)
......@@ -166,7 +166,7 @@ static int alloc_area_pages(unsigned long address, unsigned long size)
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
}
invalidate();
invalidate_all();
return 0;
}
......@@ -227,7 +227,7 @@ static int remap_area_pages(unsigned long address, unsigned long offset, unsigne
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
}
invalidate();
invalidate_all();
return 0;
}
......
......@@ -4,6 +4,7 @@
mainmenu_option next_comment
comment 'Networking options'
bool 'Network firewalls' CONFIG_FIREWALL
bool 'Network aliasing' CONFIG_NET_ALIAS
bool 'TCP/IP networking' CONFIG_INET
if [ "$CONFIG_INET" = "y" ]; then
source net/ipv4/Config.in
......
......@@ -19,6 +19,10 @@ ifdef CONFIG_FIREWALL
O_OBJS += firewall.o
endif
ifdef CONFIG_NET_ALIAS
O_OBJS += net_alias.o
endif
endif
include $(TOPDIR)/Rules.make
......
......@@ -70,6 +70,9 @@
#include <net/arp.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#ifdef CONFIG_NET_ALIAS
#include <linux/net_alias.h>
#endif
/*
* The list of packet types we will receive (as opposed to discard)
......@@ -356,6 +359,19 @@ void dev_queue_xmit(struct sk_buff *skb, struct device *dev, int pri)
return;
}
/*
*
* If dev is an alias, switch to its main device.
* "arp" resolution has been made with alias device, so
* arp entries refer to alias, not main.
*
*/
#ifdef CONFIG_NET_ALIAS
if (net_alias_is(dev))
skb->dev = dev = net_alias_main_dev(dev);
#endif
save_flags(flags);
cli();
if (!where) /* Always keep order. It helps other hosts
......@@ -561,7 +577,7 @@ void dev_transmit(void)
{
struct device *dev;
for (dev = dev_base; dev != NULL; dev = dev->next)
for (dev = dev_base; dev != NULL; dev = dev->next)
{
if (dev->flags != 0 && !dev->tbusy) {
/*
......@@ -753,6 +769,13 @@ void dev_tint(struct device *dev)
struct sk_buff *skb;
unsigned long flags;
/*
* aliases do not trasmit (by now :)
*/
#ifdef CONFIG_NET_ALIAS
if (net_alias_is(dev)) return;
#endif
save_flags(flags);
/*
* Work the queues in priority order
......@@ -984,9 +1007,20 @@ static int dev_ifsioc(void *arg, unsigned int getset)
* See which interface the caller is talking about.
*/
/*
*
* net_alias_dev_get(): dev_get() with added alias naming magic.
* only allow alias creation/deletion if (getset==SIOCSIFADDR)
*
*/
#ifdef CONFIG_NET_ALIAS
if ((dev = net_alias_dev_get(ifr.ifr_name, getset == SIOCSIFADDR, &err, NULL, NULL)) == NULL)
return(err);
#else
if ((dev = dev_get(ifr.ifr_name)) == NULL)
return(-ENODEV);
#endif
switch(getset)
{
case SIOCGIFFLAGS: /* Get interface flags */
......@@ -1079,6 +1113,16 @@ static int dev_ifsioc(void *arg, unsigned int getset)
}
else
{
/*
* if dev is an alias, must rehash to update
* address change
*/
#ifdef CONFIG_NET_ALIAS
if (net_alias_is(dev))
net_alias_rehash(dev->my_alias,&ifr.ifr_addr);
#endif
dev->pa_addr = (*(struct sockaddr_in *)
&ifr.ifr_addr).sin_addr.s_addr;
dev->family = ifr.ifr_addr.sa_family;
......@@ -1382,6 +1426,18 @@ int net_dev_init(void)
dev_get_info
});
/*
* Initialise net_alias engine
*
* - register net_alias device notifier
* - register proc entries: /proc/net/alias_types
* /proc/net/aliases
*/
#ifdef CONFIG_NET_ALIAS
net_alias_init();
#endif
bh_base[NET_BH].routine = net_bh;
enable_bh(NET_BH);
return 0;
......
This diff is collapsed.
......@@ -17,6 +17,9 @@ if [ "$CONFIG_IP_FORWARD" = "y" ]; then
bool 'IP: multicast routing(in progress)' CONFIG_IP_MROUTE
fi
fi
if [ "$CONFIG_NET_ALIAS" = "y" ]; then
tristate 'IP: aliasing support' CONFIG_IP_ALIAS
fi
comment '(it is safe to leave these untouched)'
bool 'IP: PC/TCP compatibility mode' CONFIG_INET_PCTCP
tristate 'IP: Reverse ARP' CONFIG_INET_RARP
......
......@@ -36,6 +36,14 @@ else
endif
endif
ifeq ($(CONFIG_IP_ALIAS),y)
IPV4_OBJS += ip_alias.o
else
ifeq ($(CONFIG_IP_ALIAS),m)
M_OBJS += ip_alias.o
endif
endif
ifdef CONFIG_INET
O_OBJS := $(IPV4_OBJS)
endif
......
......@@ -88,6 +88,9 @@
#include <net/raw.h>
#include <net/icmp.h>
#include <linux/ip_fw.h>
#ifdef CONFIG_IP_ALIAS
#include <net/ip_alias.h>
#endif
#define min(a,b) ((a)<(b)?(a):(b))
......@@ -1530,6 +1533,13 @@ void inet_proto_init(struct net_proto *pro)
ip_mr_init();
#endif
/*
* Initialise AF_INET alias type (register net_alias_type)
*/
#if defined(CONFIG_IP_ALIAS)
ip_alias_init();
#endif
/*
* Create all the /proc entries.
*/
......
......@@ -96,6 +96,9 @@
#include <net/netrom.h>
#endif
#endif
#ifdef CONFIG_NET_ALIAS
#include <linux/net_alias.h>
#endif
#include <asm/system.h>
#include <asm/segment.h>
......@@ -891,6 +894,19 @@ int arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
* cache.
*/
/*
* try to switch to alias device whose address is tip, if any
*/
#ifdef CONFIG_NET_ALIAS
if (net_alias_has(dev))
{
struct device *adev;
adev = net_alias_chk32(dev,AF_INET,tip,IFF_UP,IFF_NOARP);
if (adev != NULL) dev = adev;
}
#endif
if (arp->ar_op == htons(ARPOP_REQUEST))
{
/*
......@@ -1019,7 +1035,15 @@ int arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
entry->timer.data = (unsigned long)entry;
memcpy(entry->ha, sha, dev->addr_len);
entry->last_updated = entry->last_used = jiffies;
/*
* make entry point to 'correct' device
*/
#ifdef CONFIG_NET_ALIAS
entry->dev = dev;
#else
entry->dev = skb->dev;
#endif
skb_queue_head_init(&entry->skb);
if (arp_lock == 1)
{
......
#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/if.h>
#include <linux/inet.h>
#ifdef ALIAS_USER_LAND_DEBUG
#include "net_alias.h"
#include "ip_alias.h"
#include "user_stubs.h"
#endif
#include <linux/net_alias.h>
#include <net/ip_alias.h>
/*
* AF_INET alias init
*/
static int
ip_alias_init_1(struct net_alias *alias, struct sockaddr *sa)
{
#ifdef ALIAS_USER_LAND_DEBUG
printk("alias_init(%s) called.\n", alias->name);
#endif
MOD_INC_USE_COUNT;
return 0;
}
/*
* AF_INET alias done
*/
static int
ip_alias_done_1(struct net_alias *alias)
{
#ifdef ALIAS_USER_LAND_DEBUG
printk("alias_done(%s) called.\n", alias->name);
#endif
MOD_DEC_USE_COUNT;
return 0;
}
/*
* print address info
*/
int
ip_alias_print_1(char *buf, int len, struct net_alias *alias)
{
char *p;
p = (char *) &alias->dev.pa_addr;
return sprintf(buf, "%d.%d.%d.%d",
(p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255));
}
/*
* net_alias AF_INET type defn.
*/
struct net_alias_type ip_alias_type =
{
AF_INET, /* type */
0, /* n_attach */
"ip", /* name */
NULL, /* get_addr32() */
NULL, /* addr_chk() */
ip_alias_init_1, /* alias_init_1() */
ip_alias_done_1, /* alias_done_1() */
ip_alias_print_1, /* alias_print_1() */
NULL /* next */
};
/*
* ip_alias module initialization
*/
int ip_alias_init(void)
{
return register_net_alias_type(&ip_alias_type, AF_INET);
}
/*
* ip_alias module done
*/
int ip_alias_done(void)
{
return unregister_net_alias_type(&ip_alias_type);
}
#ifdef MODULE
int init_module(void)
{
if (ip_alias_init() != 0)
return -EIO;
return 0;
}
void cleanup_module(void)
{
if (ip_alias_done() != 0)
printk("ip_alias: can't remove module");
}
#endif /* MODULE */
......@@ -151,6 +151,9 @@
#include <linux/firewall.h>
#include <linux/mroute.h>
#include <net/netlink.h>
#ifdef CONFIG_NET_ALIAS
#include <linux/net_alias.h>
#endif
extern int last_retran;
extern void sort_send(struct sock *sk);
......@@ -313,7 +316,18 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
* function entry.
*/
/*
* also check device aliases address : will avoid
* a full lookup over device chain
*/
#ifdef CONFIG_NET_ALIAS
if ( iph->daddr == skb->dev->pa_addr ||
( net_alias_has(skb->dev) && net_alias_addr_chk32(skb->dev,AF_INET, iph->daddr )) ||
(brd = ip_chk_addr(iph->daddr)) != 0)
#else
if ( iph->daddr == skb->dev->pa_addr || (brd = ip_chk_addr(iph->daddr)) != 0)
#endif
{
if (opt && opt->srr)
{
......
......@@ -20,6 +20,8 @@
# 180995 Bernhard Kaindl (bkaindl@ping.at) - added dummy functions for
# use with a config.in modified for make menuconfig.
#
# 301195 (boldt@math.ucsb.edu) - added help text support
#
#
# Make sure we're really running bash.
......@@ -44,6 +46,37 @@ function mainmenu_name () {
:
}
#
# help prints the corresponding help text from Configure.help to stdout
#
# help variable
#
function help () {
if [ -f Documentation/Configure.help ]
then
#first escape regexp special characters in the argument:
var=$(echo "$1"|sed 's/[][\/.^$*]/\\&/g')
#now pick out the right help text:
text=$(sed -n "/^$var[ ]*\$/,\${
/^$var[ ]*\$/b
/^#.*/b;/^[ ]*\$/q
p
}" Documentation/Configure.help)
if [ -z "$text" ]
then
echo; echo " Sorry, no help available for this option yet.";echo
else
(echo; echo "$text"; echo) | more
fi
else
echo;
echo " Can't access the file Documentation/Configure.help which"
echo " should contain the help texts."
echo
fi
}
#
# readln reads a line into $ans.
#
......@@ -78,17 +111,17 @@ function comment () {
#
function define_bool () {
case "$2" in
"y" | "Y")
"y")
echo "$1=y" >>$CONFIG
echo "#define $1 1" >>$CONFIG_H
;;
"m" | "M")
"m")
echo "$1=m" >>$CONFIG
echo "#undef $1" >>$CONFIG_H
;;
"n" | "N")
"n")
echo "# $1 is not set" >>$CONFIG
echo "#undef $1" >>$CONFIG_H
;;
......@@ -102,18 +135,24 @@ function define_bool () {
# bool question define
#
function bool () {
ans=""
def=$(eval echo "\${$2:-'n'}")
case "$def" in
"y") defprompt="Y/n"
"y") defprompt="Y/n/?"
;;
"n") defprompt="N/y"
"n") defprompt="N/y/?"
;;
esac
while [ "$ans" != "y" -a "$ans" != "n" ]; do
readln "$1 ($2) [$defprompt] " "$def"
done
define_bool "$2" "$ans"
while :; do
readln "$1 ($2) [$defprompt] " "$def"
case "$ans" in
[yY] | [yY]es ) define_bool "$2" "y"
break;;
[nN] | [nN]o ) define_bool "$2" "n"
break;;
* ) help "$2"
;;
esac
done
}
#
......@@ -122,20 +161,28 @@ function bool () {
# tristate question define
#
function tristate () {
ans=""
def=$(eval echo "\${$2:-'n'}")
case "$def" in
"y") defprompt="Y/m/n"
"y") defprompt="Y/m/n/?"
;;
"m") defprompt="M/n/y"
"m") defprompt="M/n/y/?"
;;
"n") defprompt="N/y/m"
"n") defprompt="N/y/m/?"
;;
esac
while [ "$ans" != "y" -a "$ans" != "n" -a "$ans" != "m" ]; do
readln "$1 ($2) [$defprompt] " "$def"
done
define_bool "$2" "$ans"
while :; do
readln "$1 ($2) [$defprompt] " "$def"
case "$ans" in
[yY] | [yY]es ) define_bool "$2" "y"
break ;;
[nN] | [nN]o ) define_bool "$2" "n"
break ;;
[mM] ) define_bool "$2" "m"
break ;;
* ) help "$2"
;;
esac
done
}
#
......@@ -153,18 +200,32 @@ function dep_tristate () {
if [ "$3" != "m" ]; then
tristate "$1" "$2"
else
ans=""
case "$def" in
"y" | "m") defprompt="M/n"
"y" | "m") defprompt="M/n/?"
def="m"
;;
"n") defprompt="N/m"
"n") defprompt="N/m/?"
;;
esac
while [ "$ans" != "n" -a "$ans" != "m" ]; do
readln "$1 ($2) [$defprompt] " "$def"
done
define_bool "$2" "$ans"
while :; do
readln "$1 ($2) [$defprompt] " "$def"
case "$ans" in
[nN] | [nN]o ) define_bool "$2" "n"
break ;;
[mM] ) define_bool "$2" "m"
break ;;
[yY] | [yY]es ) echo
echo " This answer is not allowed, because it is not consistent with"
echo " your other choices."
echo " This driver depends on another one which you chose to compile"
echo " as a module. This means that you can either compile this one"
echo " as a module as well (with M) or leave it out altogether (N)."
echo
;;
* ) help "$2"
;;
esac
done
fi
}
......@@ -185,13 +246,17 @@ function define_int () {
# int question define default
#
function int () {
# Slimier hack to get bash to rescan a line.
ans="x"
def=$(eval echo "\${$2:-$3}")
while [ $[$ans+0] != "$ans" ]; do
readln "$1 ($2) [$def] " "$def"
done
define_int "$2" "$ans"
while :; do
readln "$1 ($2) [$def] " "$def"
case "$ans" in
[1-9] | [1-9][0-9] | [1-9][0-9][0-9] | [1-9][0-9][0-9][0-9] )
define_int "$2" "$ans"
break;;
* ) help "$2"
;;
esac
done
}
#
......@@ -216,6 +281,7 @@ function choice () {
# determine default answer:
names=""
set -- $choices
firstvar=$2
while [ -n "$2" ]; do
if [ -n "$names" ]; then
names="$names, $1"
......@@ -230,29 +296,34 @@ function choice () {
val=""
while [ -z "$val" ]; do
ambg=n
readln "$question ($names) [$def] " "$def"
ans=$(echo $ans | tr a-z A-Z)
set -- $choices
val=""
while [ -n "$1" ]; do
name=$(echo $1 | tr a-z A-Z)
case "$name" in
${ans}*)
"$ans"* )
if [ "$name" = "$ans" ]; then
val="$2"
break # stop on exact match
fi
if [ -n "$val" ]; then
echo \
echo;echo \
" Sorry, \"$ans\" is ambiguous; please enter a longer string."
echo
val=""
ambg=y
break
else
val="$2"
fi;;
esac
shift; shift
done
done
if [ "$val" = "" -a "$ambg" = "n" ]; then
help "$firstvar"
fi
done
set -- $choices
while [ -n "$2" ]; do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment